1
0
mirror of https://github.com/stefanocasazza/ULib.git synced 2025-09-28 19:05:55 +08:00

bug fixing

This commit is contained in:
stefanocasazza 2015-07-24 19:54:28 +02:00
parent 6f780f99e1
commit 488927dd47
19 changed files with 222 additions and 177 deletions

View File

@ -3994,7 +3994,7 @@ static void GET_get_config()
UHTTP::mime_index = U_know;
if (cfg.processData())
if (cfg.processData(false))
{
_body = cfg.getData();

View File

@ -128,7 +128,7 @@ public:
// EXT
bool processData();
bool processData(bool bload);
UString getData() const { return data; }
void setData(const UString& _data, bool _preprocessing) { data = _data; preprocessing = _preprocessing; }

View File

@ -1002,6 +1002,8 @@ protected:
U_INTERNAL_ASSERT(invariant())
}
void setFromData(const char** ptr, uint32_t sz, unsigned char delim);
public:
// mutable
UStringRep* rep;
@ -1765,9 +1767,6 @@ public:
va_end(argp);
}
void setFromData(const char** ptr, uint32_t sz);
void setFromData(const char** ptr, uint32_t sz, unsigned char delim);
void size_adjust() { rep->size_adjust(); }
void size_adjust_force() { rep->size_adjust_force(); }
@ -1929,6 +1928,9 @@ public:
private:
char* __append(uint32_t n);
char* __replace(uint32_t pos, uint32_t n1, uint32_t n2);
template <class T> friend class UVector;
template <class T> friend class UHashMap;
};
// operator ==

View File

@ -199,7 +199,8 @@ public:
{
U_TRACE(0, "UDataSession::getValueVar(%u,%p)", index, &value)
value = vec_var->at(index);
if (index < vec_var->size()) value = vec_var->at(index);
else value.clear();
U_INTERNAL_DUMP("value = %V", value.rep)
}

View File

@ -435,6 +435,7 @@ public:
// COOKIE
static UString* set_cookie;
static uint32_t sid_counter_gen;
static UString* set_cookie_option;
static UString* cgi_cookie_option;

View File

@ -663,12 +663,23 @@ uint32_t UHashMap<UString>::loadFromData(const char* ptr, uint32_t sz)
// U_INTERNAL_DUMP("c = %C", c)
if (c == '"') _key.setFromData(&ptr, sz, '"');
if (c == '"')
{
// NB: check if we have a string null...
if (*ptr != '"') _key.setFromData(&ptr, _end - ptr, '"');
else
{
++ptr;
_key.clear();
}
}
else
{
--ptr;
_key.setFromData(&ptr, sz);
_key.setFromData(&ptr, _end - ptr, terminator);
}
U_INTERNAL_ASSERT(_key)
@ -686,12 +697,23 @@ uint32_t UHashMap<UString>::loadFromData(const char* ptr, uint32_t sz)
// U_INTERNAL_DUMP("c = %C", c)
if (c == '"') str.setFromData(&ptr, sz, '"');
if (c == '"')
{
// NB: check if we have a string null...
if (*ptr != '"') str.setFromData(&ptr, _end - ptr, '"');
else
{
++ptr;
str.clear();
}
}
else
{
--ptr;
str.setFromData(&ptr, sz);
str.setFromData(&ptr, _end - ptr, terminator);
}
U_INTERNAL_ASSERT(str)
@ -700,9 +722,9 @@ uint32_t UHashMap<UString>::loadFromData(const char* ptr, uint32_t sz)
insert(_key, str);
}
U_INTERNAL_DUMP("ptr-_start = %lu", ptr-_start)
U_INTERNAL_DUMP("ptr - _start = %lu", ptr - _start)
U_INTERNAL_ASSERT((ptr-_start) <= sz)
U_INTERNAL_ASSERT((ptr - _start) <= sz)
sz = ptr - _start;

View File

@ -1023,20 +1023,31 @@ uint32_t UVector<UString>::loadFromData(const char* ptr, uint32_t sz)
// U_INTERNAL_DUMP("c = %C", c)
if (c == '"') str.setFromData(&ptr, sz, '"');
if (c == '"')
{
// NB: check if we have a string null...
if (*ptr != '"') str.setFromData(&ptr, _end - ptr, '"');
else
{
++ptr;
str.clear();
}
}
else
{
--ptr;
str.setFromData(&ptr, sz);
str.setFromData(&ptr, _end - ptr, terminator);
}
push(str);
}
U_INTERNAL_DUMP("ptr-_start = %lu", ptr-_start)
U_INTERNAL_DUMP("ptr - _start = %lu", ptr - _start)
U_INTERNAL_ASSERT((ptr-_start) <= sz)
U_INTERNAL_ASSERT((ptr - _start) <= sz)
sz = ptr - _start;

View File

@ -49,14 +49,12 @@ UFileConfig::UFileConfig(const UString& _data, bool _preprocessing) : data(_data
preprocessing = _preprocessing;
}
bool UFileConfig::processData()
bool UFileConfig::processData(bool bload)
{
U_TRACE(0, "UFileConfig::processData()")
U_TRACE(0, "UFileConfig::processData(%b)", bload)
U_CHECK_MEMORY
bool result = false;
// manage if we need preprocessing...
#if defined(HAVE_CPP) || defined(HAVE_MCPP)
@ -126,7 +124,8 @@ bool UFileConfig::processData()
}
#endif
if (data.empty()) U_RETURN(false);
if (data.empty()) U_RETURN(false);
if (bload == false) U_RETURN(true);
_end = data.end();
_start = data.data();
@ -134,28 +133,37 @@ bool UFileConfig::processData()
if (UFile::isPath())
{
// -------------------------------------------------------------
// Loads configuration information from the file.
// The file type is determined by the file extension.
// The following extensions are supported:
// -------------------------------------------------------------
// .properties - properties file (JAVA Properties)
//------------ -------------------------------------------------------------
// Loads configuration information from the file. The file type is
// determined by the file extension. The following extensions are supported:
// -------------------------------------------------------------------------
// .ini - initialization file (Windows INI)
// -------------------------------------------------------------
// .properties - properties file (JAVA Properties)
// -------------------------------------------------------------------------
UString suffix = UFile::getSuffix();
if (suffix)
{
if (suffix.equal(U_CONSTANT_TO_PARAM("ini"))) { result = loadINI(); goto end; }
else if (suffix.equal(U_CONSTANT_TO_PARAM("properties"))) { result = loadProperties(); goto end; }
if (suffix.equal(U_CONSTANT_TO_PARAM("ini")))
{
if (loadINI()) U_RETURN(true);
U_RETURN(false);
}
if (suffix.equal(U_CONSTANT_TO_PARAM("properties")))
{
if (loadProperties()) U_RETURN(true);
U_RETURN(false);
}
}
}
result = loadSection(0, 0);
if (loadSection(0, 0)) U_RETURN(true);
end:
U_RETURN(result);
U_RETURN(false);
}
void UFileConfig::load()
@ -169,7 +177,7 @@ void UFileConfig::load()
if (UFile::open() &&
UFile::size() > 0 &&
UFile::memmap(PROT_READ, &data) &&
processData())
processData(true))
{
if (UFile::isOpen()) UFile::close();
}

View File

@ -347,12 +347,13 @@ bool UImapClient::list(const UString& ref, const UString& wild, UVector<ListResp
U_RETURN(false);
}
/* STATUS command representation
typedef struct StatusInfo {
long messageCount, recentCount, nextUID, uidValidity, unseenCount;
bool hasMessageCount, hasRecentCount, hasNextUID, hasUIDValidity, hasUnseenCount;
} StatusInfo;
*/
/**
* STATUS command representation
* typedef struct StatusInfo {
* long messageCount, recentCount, nextUID, uidValidity, unseenCount;
* bool hasMessageCount, hasRecentCount, hasNextUID, hasUIDValidity, hasUnseenCount;
* } StatusInfo;
*/
bool UImapClient::status(const UString& mailboxName, StatusInfo& retval, int items)
{
@ -380,35 +381,36 @@ bool UImapClient::status(const UString& mailboxName, StatusInfo& retval, int ite
uint32_t length, i = (ptr2 - ptr1);
UString x = buffer.substr(i, end - i);
UVector<UString> vec(x);
for (i = 0, length = vec.size(); i < length; ++i)
{
if (!retval.hasMessageCount &&
if (retval.hasMessageCount == false &&
vec[i].equal(U_CONSTANT_TO_PARAM("MESSAGES")))
{
retval.messageCount = vec[++i].strtol();
retval.hasMessageCount = true;
}
else if (!retval.hasRecentCount &&
else if (retval.hasRecentCount == false &&
vec[i] == *str_recent)
{
retval.recentCount = vec[++i].strtol();
retval.hasRecentCount = true;
}
else if (!retval.hasNextUID &&
else if (retval.hasNextUID == false &&
vec[i] == *str_uidnext)
{
retval.nextUID = vec[++i].strtol();
retval.hasNextUID = true;
}
else if (!retval.hasUIDValidity &&
else if (retval.hasUIDValidity == false &&
vec[i] == *str_uidvalidity)
{
retval.uidValidity = vec[++i].strtol();
retval.hasUIDValidity = true;
}
else if (!retval.hasUnseenCount &&
else if (retval.hasUnseenCount == false &&
vec[i] == *str_unseen)
{
retval.unseenCount = vec[++i].strtol();
@ -416,7 +418,7 @@ bool UImapClient::status(const UString& mailboxName, StatusInfo& retval, int ite
}
else
{
U_ERROR("Unknow tag response for STATUS command, exit..");
U_WARNING("Unknow tag response %V for STATUS command", vec[i].rep);
}
}
@ -429,28 +431,29 @@ bool UImapClient::status(const UString& mailboxName, StatusInfo& retval, int ite
U_RETURN(false);
}
/* (SELECT | EXAMINE) command representation
typedef struct MailboxInfo {
bool readWrite;
StatusInfo status;
int flags, permanentFlags;
bool flagsAvailable, permanentFlagsAvailable, readWriteAvailable;
} MailboxInfo;
enum MailboxFlag {
SEEN = 1 << 0,
ANSWERED = 1 << 1,
FLAGGED = 1 << 2,
DELETED = 1 << 3,
DRAFT = 1 << 4,
RECENT = 1 << 5,
ASTERISK = 1 << 6,
MDNSent = 1 << 7,
Junk = 1 << 8,
NonJunk = 1 << 9,
Forwarded = 1 << 10
};
*/
/**
* (SELECT | EXAMINE) command representation
* typedef struct MailboxInfo {
* bool readWrite;
* StatusInfo status;
* int flags, permanentFlags;
* bool flagsAvailable, permanentFlagsAvailable, readWriteAvailable;
* } MailboxInfo;
*
* enum MailboxFlag {
* SEEN = 1 << 0,
* ANSWERED = 1 << 1,
* FLAGGED = 1 << 2,
* DELETED = 1 << 3,
* DRAFT = 1 << 4,
* RECENT = 1 << 5,
* ASTERISK = 1 << 6,
* MDNSent = 1 << 7,
* Junk = 1 << 8,
* NonJunk = 1 << 9,
* Forwarded = 1 << 10
* };
*/
U_NO_EXPORT void UImapClient::setFlag(int& _flags, UVector<UString>& vec)
{

View File

@ -10,8 +10,8 @@ delete_cookie;
UString ses_name;
-->
<!--#code
if (name.empty()) name = ses_name;
else ses_name = name;
if (name.empty()) name = ses_name;
else ses_name = name;
if (delete_cookie) UHTTP::removeDataSession();
-->

View File

@ -111,7 +111,7 @@ public:
{
UFileConfig cfg(UStringExt::substitute(usp, U_CONSTANT_TO_PARAM("#include"), U_CONSTANT_TO_PARAM("//#include")), true);
if (cfg.processData()) usp = UStringExt::substitute(cfg.getData(), U_CONSTANT_TO_PARAM("//#include"), U_CONSTANT_TO_PARAM("#include"));
if (cfg.processData(false)) usp = UStringExt::substitute(cfg.getData(), U_CONSTANT_TO_PARAM("//#include"), U_CONSTANT_TO_PARAM("#include"));
else
{
# ifndef DEBUG

View File

@ -1784,12 +1784,12 @@ void UString::printKeyValue(const char* key, uint32_t keylen, const char* _data,
U_INTERNAL_ASSERT(invariant())
}
void UString::setFromData(const char** p, uint32_t sz)
void UString::setFromData(const char** p, uint32_t sz, unsigned char delim)
{
U_TRACE(0, "UString::setFromData(%.*S,%u)", sz, *p, sz)
U_TRACE(0, "UString::setFromData(%.*S,%u,%C)", sz, *p, sz, delim)
U_ASSERT(empty())
U_INTERNAL_ASSERT_MAJOR(sz, 0)
U_INTERNAL_ASSERT_EQUALS(rep->_length, 0)
const char* ptr = *p;
unsigned char c = *ptr;
@ -1799,22 +1799,7 @@ void UString::setFromData(const char** p, uint32_t sz)
U_INTERNAL_ASSERT_EQUALS(u__isspace(c), false)
if (LIKELY(c != '@'))
{
do {
_append(c);
if (++ptr >= pend) break;
c = *ptr;
if (u__isspace(c)) break;
}
while (true);
_append();
}
else
if (c == '@')
{
// get content pointed by string 'meta' (that start with '@')
@ -1854,6 +1839,10 @@ void UString::setFromData(const char** p, uint32_t sz)
U_WARNING("open file %S specified in configuration failed", pathname);
}
U_INTERNAL_DUMP("size = %u, str = %V", size(), rep)
U_INTERNAL_ASSERT(invariant())
return;
}
@ -1869,10 +1858,14 @@ void UString::setFromData(const char** p, uint32_t sz)
if (ptr == pend)
{
(void) append(ptr, pend-ptr);
(void) append(ptr, pend - ptr);
*p = pend;
U_INTERNAL_DUMP("size = %u, str = %V", size(), rep)
U_INTERNAL_ASSERT(invariant())
return;
}
@ -1895,85 +1888,81 @@ void UString::setFromData(const char** p, uint32_t sz)
setBuffer(sz * 4);
UEscape::decode(start, sz, *this);
U_INTERNAL_ASSERT_MAJOR(rep->_length, 0)
*p = ptr;
U_INTERNAL_DUMP("size = %u, str = %V", size(), rep)
U_INTERNAL_ASSERT(invariant())
return;
}
*p = ptr;
if (empty() == false &&
shrink() == false)
loop:
if ( delim == c ||
(delim != '"' &&
u__isspace(c)) ||
(delim == '\0' &&
(c == '}' ||
c == ']')))
{
setNullTerminated();
++ptr;
goto end;
}
U_INTERNAL_DUMP("size = %u, str = %V", size(), rep)
U_INTERNAL_ASSERT(invariant())
}
void UString::setFromData(const char** p, uint32_t sz, unsigned char delim)
{
U_TRACE(0, "UString::setFromData(%.*S,%u,%C)", sz, *p, sz, delim)
U_ASSERT(empty())
const char* ptr = *p;
U_INTERNAL_ASSERT_EQUALS(u__isspace(*ptr), false)
for (const char* pend = ptr + sz; ptr < pend; ++ptr)
if (c == '\\')
{
unsigned char c = *ptr;
c = *++ptr;
U_INTERNAL_DUMP("c (after '\\') = %C", c)
if (c != delim)
{
if (c == '\n')
{
// compress multiple white-space in a single new-line...
U_INTERNAL_DUMP("ptr+1 = %.*S", 20, ptr+1)
while (ptr < pend)
{
if (u__isspace(ptr[1]) == false) break;
++ptr;
}
U_INTERNAL_DUMP("ptr+1 = %.*S", 20, ptr+1)
}
else if (strchr("nrtbfvae", c))
{
_append('\\');
}
}
}
_append(c);
if (++ptr <= pend)
{
c = *ptr;
U_INTERNAL_DUMP("c = %C", c)
if (c == delim)
{
++ptr;
break;
}
if (c == '\\')
{
c = *++ptr;
U_INTERNAL_DUMP("c (after '\\') = %C", c)
if (c != delim)
{
if (c == '\n')
{
// compress multiple white-space in a single new-line...
U_INTERNAL_DUMP("ptr+1 = %.*S", 20, ptr+1)
while (ptr < pend)
{
if (u__isspace(ptr[1]) == false) break;
++ptr;
}
U_INTERNAL_DUMP("ptr+1 = %.*S", 20, ptr+1)
}
else if (strchr("nrtbfvae", c))
{
_append('\\');
}
}
}
_append(c);
goto loop;
}
end:
_append();
*p = ptr;
_append();
if (empty() == false &&
shrink() == false)
if (empty()) _assign(UStringRep::string_rep_null);
else
{
setNullTerminated();
if (shrink() == false) setNullTerminated();
}
U_INTERNAL_DUMP("size = %u, str = %V", size(), rep)

View File

@ -102,6 +102,7 @@ uint32_t UHTTP::range_size;
uint32_t UHTTP::range_start;
uint32_t UHTTP::old_path_len;
uint32_t UHTTP::response_code;
uint32_t UHTTP::sid_counter_gen;
uint32_t UHTTP::sid_counter_cur;
uint32_t UHTTP::usp_page_key_len;
uint32_t UHTTP::limit_request_body = U_STRING_MAX_SIZE;
@ -4402,8 +4403,6 @@ void UHTTP::setCookie(const UString& param)
{
U_TRACE(0, "UHTTP::setCookie(%V)", param.rep)
static uint32_t sid_counter_gen;
time_t expire;
uint32_t n_hours;
UVector<UString> vec(param);
@ -4926,9 +4925,13 @@ void UHTTP::putDataSession(uint32_t index, const char* value, uint32_t size)
U_INTERNAL_ASSERT_POINTER(data_session)
UString _value((void*)value, size);
if (size == 0) data_session->putValueVar(index, UString::getStringNull());
else
{
UString _value((void*)value, size);
data_session->putValueVar(index, _value);
data_session->putValueVar(index, _value);
}
putDataSession();
}
@ -4952,9 +4955,13 @@ void UHTTP::putDataStorage(uint32_t index, const char* value, uint32_t size)
U_INTERNAL_ASSERT_POINTER(db_session)
U_INTERNAL_ASSERT_POINTER(data_storage)
UString _value((void*)value, size);
if (size == 0) data_storage->putValueVar(index, UString::getStringNull());
else
{
UString _value((void*)value, size);
data_storage->putValueVar(index, _value);
data_storage->putValueVar(index, _value);
}
putDataStorage();
}

View File

@ -22,9 +22,9 @@ export ORM_DRIVER ORM_OPTION UMEMPOOL
# ----------------------------------------------------------------------------------------------------------------------------------------------------------
# PLAINTEXT
# ----------------------------------------------------------------------------------------------------------------------------------------------------------
#UMEMPOOL="982,0,0,36,9846,-24,-23,1727,1151"
#sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
#sed -i "s|LISTEN_BACKLOG .*|LISTEN_BACKLOG 16384|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
UMEMPOOL="982,0,0,36,9846,-24,-23,1727,1151"
sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
sed -i "s|LISTEN_BACKLOG .*|LISTEN_BACKLOG 16384|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
#sed -i "s|CLIENT_THRESHOLD .*|CLIENT_THRESHOLD 4000|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
#sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 8000|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
# ----------------------------------------------------------------------------------------------------------------------------------------------------------
@ -58,9 +58,9 @@ export ORM_DRIVER ORM_OPTION UMEMPOOL
# ----------------------------------------------------------------------------------------------------------------------------------------------------------
# JSON
# ----------------------------------------------------------------------------------------------------------------------------------------------------------
UMEMPOOL="56,0,0,40,150,-24,-13,-20,0"
sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
sed -i "s|LISTEN_BACKLOG .*|LISTEN_BACKLOG 256|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
#UMEMPOOL="56,0,0,40,150,-24,-13,-20,0"
#sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
#sed -i "s|LISTEN_BACKLOG .*|LISTEN_BACKLOG 256|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
#sed -i "s|CLIENT_THRESHOLD .*|CLIENT_THRESHOLD 50|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
#sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 100|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
# ----------------------------------------------------------------------------------------------------------------------------------------------------------

View File

@ -3,7 +3,7 @@ userver {
PORT 8080
PREFORK_CHILD 4
TCP_LINGER_SET 0
LISTEN_BACKLOG 256
LISTEN_BACKLOG 16384
DOCUMENT_ROOT benchmark/FrameworkBenchmarks/ULib/www
PID_FILE benchmark/FrameworkBenchmarks/ULib/userver_tcp.pid

View File

@ -12,7 +12,7 @@ chat|Chat|simple chat-program using ajax
remove|RemoveSessionCookie|you need to run this before to run the demos that use a session cookie
json|Test 1 - JSON serialization|This test exercises the framework fundamentals including keep-alive support, request routing, request header parsing, object instantiation, JSON serialization, response header generation, and request count throughput
db|Test 2 - Single database query|This test exercises the framework's object-relational mapper (ORM), random number generator, database driver, and database connection pool
queries|Test 3 - Multiple database queries|This test is a variation of Test #2 and also uses the World table. Multiple rows are fetched to more dramatically punish the database driver and connection pool. At the highest queries-per-request tested (20), this test demonstrates all frameworks' convergence toward zero requests-per-second as database activity increases
fortunes|Test 4 - Fortunes|This test exercises the ORM, database connectivity, dynamic-size collections, sorting, server-side templates, XSS countermeasures, and character encoding
updates|Test 5 - Database updates|This test is a variation of Test #3 that exercises the ORM's persistence of objects and the database driver's performance at running UPDATE statements or similar
query|Test 3 - Multiple database queries|This test is a variation of Test #2 and also uses the World table. Multiple rows are fetched to more dramatically punish the database driver and connection pool. At the highest queries-per-request tested (20), this test demonstrates all frameworks' convergence toward zero requests-per-second as database activity increases
fortune|Test 4 - Fortunes|This test exercises the ORM, database connectivity, dynamic-size collections, sorting, server-side templates, XSS countermeasures, and character encoding
update|Test 5 - Database updates|This test is a variation of Test #3 that exercises the ORM's persistence of objects and the database driver's performance at running UPDATE statements or similar
plaintext|Test 6 - Plaintext|This test is an exercise of the request-routing fundamentals only, designed to demonstrate the capacity of high-performance platforms in particular. The response payload is still small, meaning good performance is still necessary in order to saturate the gigabit Ethernet of the test environment

View File

@ -9,7 +9,7 @@ start_msg client
rm -f server.log client.log
#UTRACE="0 10M 1"
#UTRACE="0 10M -1"
#UOBJDUMP="0 1M 100"
#USIMERR="error.sim"
export UTRACE UOBJDUMP USIMERR

View File

@ -11,10 +11,11 @@ rm -f tmp/usp_compile.sh.err \
trace.*userver_*.[0-9]* object.*userver_*.[0-9]* stack.*userver_*.[0-9]* mempool.*userver_*.[0-9]* \
$DOC_ROOT/trace.*userver_*.[0-9]* $DOC_ROOT/object.*userver_*.[0-9]* $DOC_ROOT/stack.*userver_*.[0-9]* $DOC_ROOT/mempool.*userver_*.[0-9]*
UTRACE="0 130M 0"
#UOBJDUMP="0 10M 5000"
UTRACE="0 50M 0"
UTRACE_SIGNAL="0 50M -1"
#UOBJDUMP="0 10M 100"
#USIMERR="error.sim"
export UTRACE UOBJDUMP USIMERR
export UTRACE UOBJDUMP USIMERR UTRACE_SIGNAL
SOCK1=tmp/fcgi.socket

View File

@ -6,7 +6,7 @@
start_msg imap
#UTRACE="0 5M 0"
#UTRACE="0 5M -1"
#UOBJDUMP="0 100k 10"
#USIMERR="error.sim"
export UTRACE UOBJDUMP USIMERR