00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifdef HAVE_CONFIG_H
00030 # include <config.h>
00031 #endif
00032
00033 #include <gwenhywfar/gwenhywfarapi.h>
00034 #include <gwenhywfar/misc.h>
00035 #include <gwenhywfar/buffer.h>
00036 #include <gwenhywfar/gui.h>
00037
00038 #include "logger_p.h"
00039
00040 #include <stdlib.h>
00041 #include <stdio.h>
00042 #include <errno.h>
00043 #ifdef HAVE_SYSLOG_H
00044 # include <syslog.h>
00045 #endif
00046 #include <string.h>
00047 #ifdef HAVE_STRINGS_H
00048 # include <strings.h>
00049 #endif
00050 #ifdef HAVE_TIME_H
00051 # include <time.h>
00052 #endif
00053 #ifdef HAVE_UNISTD_H
00054 # include <unistd.h>
00055 #endif
00056
00057
00058 static GWEN_LOGGER_DOMAIN *gwen_loggerdomains=0;
00059
00060
00061
00062 int GWEN_Logger_ModuleInit(){
00063 const char *s;
00064 GWEN_LOGGER_LEVEL ll=GWEN_LoggerLevel_Warning;
00065
00066 GWEN_Logger_Open(GWEN_LOGDOMAIN,
00067 "gwen",
00068 0,
00069 GWEN_LoggerType_Console,
00070 GWEN_LoggerFacility_User);
00071 s=getenv("GWEN_LOGLEVEL");
00072 if (s) {
00073 ll=GWEN_Logger_Name2Level(s);
00074 if (ll==GWEN_LoggerLevel_Unknown)
00075 ll=GWEN_LoggerLevel_Warning;
00076 }
00077 GWEN_Logger_SetLevel(GWEN_LOGDOMAIN, ll);
00078 return 0;
00079 }
00080
00081
00082
00083 int GWEN_Logger_ModuleFini(){
00084 GWEN_LOGGER_DOMAIN *ld;
00085
00086 while((ld=gwen_loggerdomains)) {
00087 GWEN_LoggerDomain_Del(ld);
00088 GWEN_LoggerDomain_free(ld);
00089 }
00090 return 0;
00091 }
00092
00093
00094
00095 GWEN_LOGGER_DOMAIN *GWEN_LoggerDomain_new(const char *name){
00096 GWEN_LOGGER_DOMAIN *ld;
00097
00098 assert(name);
00099 GWEN_NEW_OBJECT(GWEN_LOGGER_DOMAIN, ld);
00100 ld->name=strdup(name);
00101 return ld;
00102 }
00103
00104
00105
00106 void GWEN_LoggerDomain_free(GWEN_LOGGER_DOMAIN *ld){
00107 if (ld) {
00108 free(ld->name);
00109 GWEN_Logger_free(ld->logger);
00110 GWEN_FREE_OBJECT(ld);
00111 }
00112 }
00113
00114
00115 GWEN_LOGGER_DOMAIN *GWEN_LoggerDomain_Find(const char *name) {
00116 GWEN_LOGGER_DOMAIN *ld;
00117
00118 assert(name);
00119 ld=gwen_loggerdomains;
00120 while(ld) {
00121 if (strcasecmp(ld->name, name)==0)
00122 break;
00123 ld=ld->next;
00124 }
00125
00126 return ld;
00127 }
00128
00129
00130
00131 void GWEN_LoggerDomain_Add(GWEN_LOGGER_DOMAIN *ld){
00132 assert(ld);
00133 GWEN_LIST_INSERT(GWEN_LOGGER_DOMAIN, ld, &gwen_loggerdomains);
00134 }
00135
00136
00137
00138 void GWEN_LoggerDomain_Del(GWEN_LOGGER_DOMAIN *ld){
00139 assert(ld);
00140 GWEN_LIST_DEL(GWEN_LOGGER_DOMAIN, ld, &gwen_loggerdomains);
00141 }
00142
00143
00144
00145 GWEN_LOGGER *GWEN_LoggerDomain_GetLogger(const char *name) {
00146 GWEN_LOGGER_DOMAIN *ld;
00147
00148 if (!name)
00149 name="default";
00150
00151 ld=GWEN_LoggerDomain_Find(name);
00152 if (ld) {
00153 return ld->logger;
00154 }
00155 ld=GWEN_LoggerDomain_new(name);
00156 ld->logger=GWEN_Logger_new(ld);
00157
00158 GWEN_LoggerDomain_Add(ld);
00159 return ld->logger;
00160 }
00161
00162
00163
00164 GWEN_LOGGER *GWEN_Logger_new(GWEN_LOGGER_DOMAIN *domain){
00165 GWEN_LOGGER *lg;
00166
00167 GWEN_NEW_OBJECT(GWEN_LOGGER, lg);
00168 lg->usage=1;
00169 lg->enabled=1;
00170 lg->logType=GWEN_LoggerType_Console;
00171 lg->logLevel=GWEN_LoggerLevel_Error;
00172 lg->domain=domain;
00173 return lg;
00174 }
00175
00176
00177
00178 void GWEN_Logger_free(GWEN_LOGGER *lg){
00179 if (lg) {
00180 assert(lg->usage);
00181 if (--(lg->usage)==0) {
00182 free(lg->logFile);
00183 free(lg->logIdent);
00184 GWEN_FREE_OBJECT(lg);
00185 }
00186 }
00187 }
00188
00189
00190
00191 void GWEN_Logger_Attach(GWEN_LOGGER *lg){
00192 assert(lg);
00193 lg->usage++;
00194 }
00195
00196
00197
00198 void GWEN_Logger_AddLogger(GWEN_LOGGER *oldLogger, GWEN_LOGGER *newLogger){
00199 assert(newLogger);
00200
00201 assert(oldLogger);
00202 GWEN_LIST_ADD(GWEN_LOGGER, newLogger, &(oldLogger->next));
00203 }
00204
00205
00206
00207 void GWEN_Logger_SetDefaultLogger(GWEN_UNUSED GWEN_LOGGER *lg){
00208 fprintf(stderr, "GWEN_Logger_SetDefaultLogger: Deprecated function\n");
00209 }
00210
00211
00212
00213 int GWEN_Logger_Open(const char *logDomain,
00214 const char *ident,
00215 const char *file,
00216 GWEN_LOGGER_LOGTYPE logtype,
00217 GWEN_LOGGER_FACILITY facility){
00218 GWEN_LOGGER *lg;
00219
00220 lg=GWEN_LoggerDomain_GetLogger(logDomain);
00221 assert(lg);
00222 lg->logType=logtype;
00223
00224 GWEN_Logger_SetIdent(logDomain, ident);
00225 GWEN_Logger_SetFilename(logDomain, file);
00226
00227 if (logtype==GWEN_LoggerType_File) {
00228
00229 if (file==0) {
00230 lg->logType=GWEN_LoggerType_Console;
00231 lg->enabled=1;
00232 fprintf(stderr,"LOGGER: No filename given, will log to console.\n");
00233 }
00234 else {
00235 lg->logType=GWEN_LoggerType_File;
00236 lg->enabled=1;
00237 }
00238 }
00239 #ifdef HAVE_SYSLOG_H
00240 else if (logtype==GWEN_LoggerType_Syslog) {
00241
00242 int fac;
00243
00244 switch(facility) {
00245 case GWEN_LoggerFacility_Auth:
00246 fac=LOG_AUTH;
00247 break;
00248 case GWEN_LoggerFacility_Daemon:
00249 fac=LOG_DAEMON;
00250 break;
00251 case GWEN_LoggerFacility_Mail:
00252 fac=LOG_MAIL;
00253 break;
00254 case GWEN_LoggerFacility_News:
00255 fac=LOG_NEWS;
00256 break;
00257 case GWEN_LoggerFacility_User:
00258 case GWEN_LoggerFacility_Unknown:
00259 default:
00260 fac=LOG_USER;
00261 break;
00262 }
00263
00264 openlog(ident,
00265 LOG_CONS |
00266 LOG_PID,
00267 fac);
00268 lg->enabled=1;
00269 }
00270 #endif
00271
00272 else {
00273
00274 lg->enabled=1;
00275 }
00276
00277 lg->open=1;
00278
00279 return GWEN_Logger_Log(logDomain, GWEN_LoggerLevel_Debug, "started");
00280 }
00281
00282
00283
00284 void GWEN_Logger_Close(const char *logDomain){
00285 GWEN_LOGGER *lg;
00286
00287 lg=GWEN_LoggerDomain_GetLogger(logDomain);
00288 assert(lg);
00289 GWEN_Logger_Log(logDomain, GWEN_LoggerLevel_Debug, "stopped");
00290 lg->logType=GWEN_LoggerType_Console;
00291 lg->enabled=0;
00292 #ifdef HAVE_SYSLOG_H
00293 closelog();
00294 #endif
00295 lg->open=0;
00296
00297 GWEN_LoggerDomain_Del(lg->domain);
00298 GWEN_LoggerDomain_free(lg->domain);
00299 }
00300
00301
00302
00303 int GWEN_Logger_IsOpen(const char *logDomain){
00304 GWEN_LOGGER_DOMAIN *ld;
00305
00306 if (!logDomain)
00307 logDomain="default";
00308 ld=GWEN_LoggerDomain_Find(logDomain);
00309 if (ld)
00310 return ld->logger->open;
00311 return 0;
00312 }
00313
00314
00315 int GWEN_Logger__CreateMessage(GWEN_LOGGER *lg,
00316 GWEN_LOGGER_LEVEL priority, const char *s,
00317 GWEN_BUFFER *mbuf) {
00318 #ifdef HAVE_SNPRINTF
00319 unsigned int i;
00320 #endif
00321 #ifdef HAVE_TIME_H
00322 struct tm *t;
00323 time_t tt;
00324 #endif
00325 char buffer[256];
00326
00327 assert(lg);
00328 if (lg->logIdent) {
00329 if (strlen(lg->logIdent)+32>=sizeof(buffer)) {
00330 fprintf(stderr," LOGGER: Logbuffer too small (1).\n");
00331 return 1;
00332 }
00333 }
00334
00335 #ifdef HAVE_TIME_H
00336 tt=time(0);
00337 t=localtime(&tt);
00338
00339 # ifdef HAVE_SNPRINTF
00340 # ifdef HAVE_GETPID
00341 i=snprintf(buffer, sizeof(buffer)-1,
00342 "%d:%04d/%02d/%02d %02d-%02d-%02d:%s(%d):",priority,
00343 t->tm_year+1900, t->tm_mon+1, t->tm_mday,
00344 t->tm_hour, t->tm_min, t->tm_sec,
00345 lg->logIdent, (int)getpid());
00346 # else
00347 i=snprintf(buffer, sizeof(buffer)-1,
00348 "%d:%04d/%02d/%02d %02d-%02d-%02d:%s:",priority,
00349 t->tm_year+1900, t->tm_mon+1, t->tm_mday,
00350 t->tm_hour, t->tm_min, t->tm_sec,
00351 lg->logIdent);
00352 # endif
00353 if (i>=sizeof(buffer)) {
00354 fprintf(stderr," LOGGER: Logbuffer too small (2).\n");
00355 return 1;
00356 }
00357 # else
00358 # ifdef HAVE_GETPID
00359 sprintf(buffer,"%d:%04d/%02d/%02d %02d-%02d-%02d:%s(%d):",priority,
00360 t->tm_year+1900, t->tm_mon+1, t->tm_mday,
00361 t->tm_hour, t->tm_min, t->tm_sec,
00362 lg->logIdent, (int)getpid());
00363 # else
00364 sprintf(buffer,"%d:%04d/%02d/%02d %02d-%02d-%02d:%s:",priority,
00365 t->tm_year+1900, t->tm_mon+1, t->tm_mday,
00366 t->tm_hour, t->tm_min, t->tm_sec,
00367 lg->logIdent);
00368 # endif
00369 # endif
00370 #else
00371 # ifdef HAVE_SNPRINTF
00372 buffer[sizeof(buffer)-1]=0;
00373 i=snprintf(buffer, sizeof(buffer)-1,
00374 "%d:%s:",priority,
00375 lg->logIdent);
00376 if (i>=sizeof(buffer)) {
00377 fprintf(stderr," LOGGER: Logbuffer too small (3).\n");
00378 return 1;
00379 }
00380 # else
00381 sprintf(buffer,"%d:%s:",priority,
00382 lg->logIdent);
00383 # endif
00384 #endif
00385 GWEN_Buffer_AppendString(mbuf, buffer);
00386 GWEN_Buffer_AppendString(mbuf, s);
00387 GWEN_Buffer_AppendByte(mbuf, '\n');
00388 return 0;
00389 }
00390
00391
00392
00393 int GWEN_Logger__Log(GWEN_LOGGER *lg,
00394 GWEN_LOGGER_LEVEL priority, const char *s){
00395 while(lg) {
00396 FILE *f;
00397 #ifdef HAVE_SYSLOG_H
00398 int pri;
00399 #endif
00400 GWEN_BUFFER *mbuf;
00401 int rv;
00402
00403 assert(lg);
00404 if (priority>lg->logLevel)
00405
00406 return 0;
00407
00408 mbuf=GWEN_Buffer_new(0, 256, 0, 1);
00409 switch(lg->logType) {
00410 case GWEN_LoggerType_File:
00411 rv=GWEN_Logger__CreateMessage(lg, priority, s, mbuf);
00412 if (rv) {
00413 GWEN_Buffer_free(mbuf);
00414 return rv;
00415 }
00416
00417 f=fopen(lg->logFile,"a+");
00418 if (f==0) {
00419 fprintf(stderr,
00420 "LOGGER: Unable to open file \"%s\" (%s)\n",
00421 lg->logFile,
00422 strerror(errno));
00423 lg->logType=GWEN_LoggerType_Console;
00424 GWEN_Buffer_free(mbuf);
00425 return 1;
00426 }
00427
00428 if (fwrite(GWEN_Buffer_GetStart(mbuf),
00429 GWEN_Buffer_GetUsedBytes(mbuf), 1, f)!=1) {
00430 fprintf(stderr,
00431 "LOGGER: Unable to write to file \"%s\" (%s)\n",
00432 lg->logFile,
00433 strerror(errno));
00434 fclose(f);
00435 lg->logType=GWEN_LoggerType_Console;
00436 GWEN_Buffer_free(mbuf);
00437 return 1;
00438 }
00439 if (fclose(f)) {
00440 fprintf(stderr,
00441 "LOGGER: Unable to close file \"%s\" (%s)\n",
00442 lg->logFile,
00443 strerror(errno));
00444 lg->logType=GWEN_LoggerType_Console;
00445 GWEN_Buffer_free(mbuf);
00446 return 1;
00447 }
00448 break;
00449
00450 #ifdef HAVE_SYSLOG_H
00451 case GWEN_LoggerType_Syslog:
00452 switch(priority) {
00453 case GWEN_LoggerLevel_Emergency:
00454 pri=LOG_EMERG;
00455 break;
00456 case GWEN_LoggerLevel_Alert:
00457 pri=LOG_ALERT;
00458 break;
00459 case GWEN_LoggerLevel_Critical:
00460 pri=LOG_CRIT;
00461 break;
00462 case GWEN_LoggerLevel_Error:
00463 pri=LOG_ERR;
00464 break;
00465 case GWEN_LoggerLevel_Warning:
00466 pri=LOG_WARNING;
00467 break;
00468 case GWEN_LoggerLevel_Notice:
00469 pri=LOG_NOTICE;
00470 break;
00471 case GWEN_LoggerLevel_Info:
00472 pri=LOG_NOTICE;
00473 break;
00474
00475 case GWEN_LoggerLevel_Debug:
00476 case GWEN_LoggerLevel_Verbous:
00477 case GWEN_LoggerLevel_Unknown:
00478 default:
00479 pri=LOG_DEBUG;
00480 break;
00481 }
00482 syslog(pri,"%s",s);
00483 break;
00484 #endif
00485
00486 case GWEN_LoggerType_Function:
00487 if (lg->logFunction==0) {
00488 fprintf(stderr,
00489 "LOGGER: Logtype is \"Function\", but no function is set.\n");
00490 GWEN_Buffer_free(mbuf);
00491 return 1;
00492 }
00493 rv=GWEN_Logger__CreateMessage(lg, priority, s, mbuf);
00494 if (rv) {
00495 GWEN_Buffer_free(mbuf);
00496 return rv;
00497 }
00498 (lg->logFunction)(GWEN_Buffer_GetStart(mbuf));
00499 break;
00500
00501 case GWEN_LoggerType_Console:
00502 case GWEN_LoggerType_Unknown:
00503 default:
00504 rv=GWEN_Logger__CreateMessage(lg, priority, s, mbuf);
00505 if (rv) {
00506 GWEN_Buffer_free(mbuf);
00507 return rv;
00508 }
00509
00510 fprintf(stderr, "%s", GWEN_Buffer_GetStart(mbuf));
00511 break;
00512 }
00513 lg=lg->next;
00514 GWEN_Buffer_free(mbuf);
00515 }
00516 return 0;
00517 }
00518
00519
00520
00521 int GWEN_Logger_Log(const char *logDomain,
00522 GWEN_LOGGER_LEVEL priority, const char *s){
00523 if (!GWEN_Gui_LogHook(logDomain, priority, s)) {
00524 const char *p;
00525 int rv;
00526 unsigned int i;
00527 GWEN_BUFFER *mbuf;
00528 GWEN_LOGGER *lg;
00529
00530 lg=GWEN_LoggerDomain_GetLogger(logDomain);
00531 assert(lg);
00532
00533 if (!lg->enabled)
00534 return 1;
00535
00536 if (priority>lg->logLevel)
00537
00538 return 0;
00539
00540
00541 lg->enabled=0;
00542
00543 mbuf=GWEN_Buffer_new(0, strlen(s)+1, 0, 1);
00544 for (i=0; i<strlen(s)+1; i++) {
00545 if (s[i]=='\n') {
00546 GWEN_Buffer_AppendByte(mbuf, 0);
00547 }
00548 else
00549 GWEN_Buffer_AppendByte(mbuf, s[i]);
00550 }
00551
00552
00553 rv=0;
00554 p=GWEN_Buffer_GetStart(mbuf);
00555 while (*p) {
00556 rv|=GWEN_Logger__Log(lg, priority, p);
00557 while(*p)
00558 p++;
00559 p++;
00560 }
00561 GWEN_Buffer_free(mbuf);
00562
00563 lg->enabled=1;
00564 return rv;
00565 }
00566 else
00567 return 0;
00568 }
00569
00570
00571
00572 void GWEN_Logger_Enable(const char *logDomain, int f){
00573 GWEN_LOGGER *lg;
00574
00575 lg=GWEN_LoggerDomain_GetLogger(logDomain);
00576 assert(lg);
00577 lg->enabled=f;
00578 }
00579
00580
00581
00582 int GWEN_Logger_IsEnabled(const char *logDomain){
00583 GWEN_LOGGER *lg;
00584
00585 lg=GWEN_LoggerDomain_GetLogger(logDomain);
00586 assert(lg);
00587 return lg->enabled;
00588 }
00589
00590
00591
00592 void GWEN_Logger_SetLevel(const char *logDomain, GWEN_LOGGER_LEVEL l){
00593 GWEN_LOGGER *lg;
00594
00595 lg=GWEN_LoggerDomain_GetLogger(logDomain);
00596 assert(lg);
00597 lg->logLevel=l;
00598 }
00599
00600
00601
00602 int GWEN_Logger_GetLevel(const char *logDomain) {
00603 GWEN_LOGGER *lg;
00604
00605 lg=GWEN_LoggerDomain_GetLogger(logDomain);
00606 assert(lg);
00607
00608 return lg->logLevel;
00609 }
00610
00611
00612
00613 void GWEN_Logger_SetIdent(const char *logDomain, const char *id){
00614 GWEN_LOGGER *lg;
00615
00616 lg=GWEN_LoggerDomain_GetLogger(logDomain);
00617 assert(lg);
00618
00619 free(lg->logIdent);
00620 if (id)
00621 lg->logIdent=strdup(id);
00622 else
00623 lg->logIdent=strdup("No ident, please adjust your program");
00624 }
00625
00626
00627
00628 void GWEN_Logger_SetFilename(const char *logDomain, const char *name){
00629 GWEN_LOGGER *lg;
00630
00631 lg=GWEN_LoggerDomain_GetLogger(logDomain);
00632 assert(lg);
00633
00634 free(lg->logFile);
00635 if (name)
00636 lg->logFile=strdup(name);
00637 else
00638 lg->logFile=strdup("");
00639 }
00640
00641
00642
00643 GWEN_LOGGERFUNCTIONLOG GWEN_Logger_SetLogFunction(const char *logDomain,
00644 GWEN_LOGGERFUNCTIONLOG fn){
00645 GWEN_LOGGER *lg;
00646 GWEN_LOGGERFUNCTIONLOG oldFn;
00647
00648 lg=GWEN_LoggerDomain_GetLogger(logDomain);
00649 assert(lg);
00650 oldFn=lg->logFunction;
00651 lg->logFunction=fn;
00652 return oldFn;
00653 }
00654
00655
00656
00657 GWEN_LOGGER_LEVEL GWEN_Logger_Name2Level(const char *name) {
00658 if (strcasecmp(name, "emergency")==0)
00659 return GWEN_LoggerLevel_Emergency;
00660 else if (strcasecmp(name, "alert")==0)
00661 return GWEN_LoggerLevel_Alert;
00662 else if (strcasecmp(name, "critical")==0)
00663 return GWEN_LoggerLevel_Critical;
00664 else if (strcasecmp(name, "error")==0)
00665 return GWEN_LoggerLevel_Error;
00666 else if (strcasecmp(name, "warning")==0)
00667 return GWEN_LoggerLevel_Warning;
00668 else if (strcasecmp(name, "notice")==0)
00669 return GWEN_LoggerLevel_Notice;
00670 else if (strcasecmp(name, "info")==0)
00671 return GWEN_LoggerLevel_Info;
00672 else if (strcasecmp(name, "debug")==0)
00673 return GWEN_LoggerLevel_Debug;
00674 else if (strcasecmp(name, "verbous")==0)
00675 return GWEN_LoggerLevel_Verbous;
00676 else {
00677 return GWEN_LoggerLevel_Unknown;
00678 }
00679 }
00680
00681
00682
00683 const char *GWEN_Logger_Level2Name(GWEN_LOGGER_LEVEL level) {
00684 const char *s;
00685
00686 switch(level) {
00687 case GWEN_LoggerLevel_Emergency:
00688 s="emergency"; break;
00689 case GWEN_LoggerLevel_Alert:
00690 s="alert"; break;
00691 case GWEN_LoggerLevel_Critical:
00692 s="critical"; break;
00693 case GWEN_LoggerLevel_Error:
00694 s="error"; break;
00695 case GWEN_LoggerLevel_Warning:
00696 s="warning"; break;
00697 case GWEN_LoggerLevel_Notice:
00698 s="notice"; break;
00699 case GWEN_LoggerLevel_Info:
00700 s="info"; break;
00701 case GWEN_LoggerLevel_Debug:
00702 s="debug"; break;
00703 case GWEN_LoggerLevel_Verbous:
00704 s="verbous"; break;
00705 case GWEN_LoggerLevel_Unknown:
00706 default:
00707 s="unknown"; break;
00708 }
00709 return s;
00710 }
00711
00712
00713
00714 GWEN_LOGGER_LOGTYPE GWEN_Logger_Name2Logtype(const char *name) {
00715 if (strcasecmp(name, "console")==0)
00716 return GWEN_LoggerType_Console;
00717 else if (strcasecmp(name, "file")==0)
00718 return GWEN_LoggerType_File;
00719 else if (strcasecmp(name, "syslog")==0)
00720 return GWEN_LoggerType_Syslog;
00721 else if (strcasecmp(name, "function")==0)
00722 return GWEN_LoggerType_Function;
00723 else {
00724 return GWEN_LoggerType_Unknown;
00725 }
00726 }
00727
00728
00729
00730 const char *GWEN_Logger_Logtype2Name(GWEN_LOGGER_LOGTYPE lt) {
00731 const char *s;
00732
00733 switch(lt) {
00734 case GWEN_LoggerType_Console:
00735 s="console"; break;
00736 case GWEN_LoggerType_File:
00737 s="file"; break;
00738 case GWEN_LoggerType_Syslog:
00739 s="syslog"; break;
00740 case GWEN_LoggerType_Function:
00741 s="function"; break;
00742 case GWEN_LoggerType_Unknown:
00743 default:
00744 s="unknown"; break;
00745 }
00746 return s;
00747 }
00748
00749
00750
00751 int GWEN_Logger_Exists(const char *logDomain){
00752 assert(logDomain);
00753 return (GWEN_LoggerDomain_Find(logDomain)!=0);
00754 }
00755
00756
00757
00758
00759
00760
00761
00762