00001 00002 /* 00003 * THIS FILE IS UNDER RCS - DO NOT MODIFY UNLESS YOU HAVE 00004 * CHECKED IT OUT USING THE COMMAND CHECKOUT. 00005 * 00006 * $Id: logit_8c-source.html 2161 2006-05-19 16:55:03Z paulf $ 00007 * 00008 * Revision history: 00009 * $Log$ 00009 * Revision 1.1 2006/05/19 16:55:02 paulf 00009 * first inclusion 00009 * 00010 * Revision 1.9 2001/09/24 21:51:38 patton 00011 * Added capability to change logging 00012 * level by calling logit_init again. 00013 * Part of the logit changeover. 00014 * JMP 9/24/2001 00015 * 00016 * Revision 1.8 2001/08/21 00:23:55 patton 00017 * Modified the logfile name to match the new format: 00018 * program_name_date.log. Also removed the need for mid 00019 * in logit_init, but left it in the call for backwards 00020 * compatibility reasons. JMP 8/20/2001. 00021 * 00022 * Revision 1.7 2000/07/08 19:11:42 lombard 00023 * Added value 2 to logflag argument of logit_init(), to turn off globally 00024 * logging to standard error and standard output. 00025 * 00026 * Revision 1.6 2000/06/21 16:32:29 lucky 00027 * Added html_logit: same as logit but it is suitable for routines that produce html. 00028 * 00029 * Revision 1.5 2000/06/02 21:57:51 davidk 00030 * Added logit to prevent "Message too long" errors from being logged to 00031 * stderr more than once. This should allow notification, but prevent 00032 * stderr from being flooded with messages and becoming unreadable. 00033 * 00034 * Revision 1.4 2000/06/02 21:40:39 davidk 00035 * added code to check for buffer overflow in logit(). Used vsnprintf() 00036 * to fill the buffer without overflowing it. Had to add a line to the 00037 * WINNT portion of platform.h in order to get vsnprintf() to work for NT. 00038 * 00039 * Revision 1.3 2000/06/01 00:36:10 dietz 00040 * logit_init: moved CreateSpecificMutex earlier in the function so that it's 00041 * always created regardless of the log/nolog switch value. 00042 * 00043 * Revision 1.2 2000/03/13 23:22:09 davidk 00044 * modified the LOGIT_MT ifdef so that the entire logit() function is executed as 00045 * a single critical section (mutex protected). This was done to fix a problem 00046 * experienced on a Dual-Processor Ultra 60 running ew5-getlist, where one thread 00047 * was overwriting the logit buffer of another thread before the original thread 00048 * could write the buffer out to file. 00049 * 00050 * Revision 1.1 2000/02/14 18:51:48 lucky 00051 * Initial revision 00052 * 00053 * 00054 */ 00055 00056 00057 /************************************************************* 00058 * logit.c * 00059 * * 00060 * Functions for maintaining log files. * 00061 * * 00062 * First, call logit_init. Then, call logit. * 00063 * * 00064 * If the environmental variable _LOGITMT is defined, * 00065 * the resulting object file will be MT-safe. * 00066 * * 00067 * If _LOGITMT is not defined, the program must link to * 00068 * time_ew.o. * 00069 * * 00070 * If _LOGITMT is defined, the program must link to * 00071 * time_ew.o and sema_ew.o. * 00072 * * 00073 * In Solaris, the program must also link to the posix * 00074 * library (-lposix4) * 00075 * * 00076 *************************************************************/ 00077 /* 00078 * 8/17/2001 Changed log file names to the format: programname_date.log. 00079 * Also modified logitinit so that the mid is not used. Mid was left 00080 * in the call however, for backwards compatibility purposes. 00081 * John Patton 00082 * 00083 * 7/7/99 Removed 2 lines "res.tm_year %= 100" which were causing 00084 * years 2000+ to be printed as 1900+. Lynn Dietz 00085 * 00086 * Changed lines 69-73 to allow logit to work under the Solaris Workshop 00087 * debugger: Pete Lombard, 8/5/98 00088 * 00089 * Mon Oct 26 14:22:09 MST 1998 lucky 00090 * Created a new routine get_prog_name which extracts the 00091 * name of the program by truncating the path to it as well as 00092 * any extensions 00093 * 00094 * Mon Oct 26 15:15:12 MST 1998 lucky 00095 * Y2K compliance: 00096 * - use 4 digits for years in file names 00097 * - use 4 digits for years in status messages 00098 * 00099 * Wed Oct 28 16:19:45 MST 1998 lucky 00100 * Added the YYYYMMDD date filed to the log message that 00101 * are being produced. New format is now: 00102 * 00103 * YYYYMMDD_UTC_HH:MM:SS 00104 * 00105 * 19990217 DavidK 00106 * Increased the lengths of logName, logpath, and Template to allow for 00107 * longer logfile names, based on config file names. Longest progname 00108 * accepted should now be 58, with a max path length of 127 00109 * Removed or atleast placed in and "#if EW_DEBUG" section code to 00110 * print to stderr a message that says logit_init() opened the logfile. 00111 * Changed the 2-digit year to a 4-digit year in the date printout in 00112 * the logfile. 00113 */ 00114 00115 #include <stdio.h> 00116 #include <stdlib.h> 00117 #include <string.h> 00118 #include <stdarg.h> 00119 #include <time.h> 00120 #include <time_ew.h> 00121 00122 00123 #ifndef EARTHWORM_H 00124 #include <earthworm.h> 00125 #endif 00126 00127 /* 020625 dbh -- added this to compile in C++ */ 00128 #ifdef __BORLANDC__ 00129 #ifdef getpid 00130 #undef getpid 00131 //extern "C" int getpid(); 00132 #include <process.h> // getpid() 00133 #endif 00134 #endif 00135 00136 00137 #define DATE_LEN 10 00139 static FILE *fp = NULL; 00140 static char date[DATE_LEN]; 00141 static char date_prev[DATE_LEN]; 00142 static time_t now; 00143 static char logName[256]; /* Increased 19990217 DK */ 00144 static char logpath[128]; /* Increased 19990217 DK */ 00145 static char template[64]; /* Increased 19990217 DK */ 00146 static char extension[12]; /* JMP ADDED, for .log extension */ 00147 static char *buf; 00148 static struct tm res; 00149 static int init = 0; /* 1 if logit_init has been called */ 00150 static int disk = 1; /* 1 if output goes to disk file */ 00151 static int soe = 1; /* 1 of output goes to stdout/stderr */ 00152 static int pid; 00153 00154 /* DK 2000/06/02 Added logbuffersize variable to track 00155 the size of the allocated logit buffer. 00156 *******************************************************/ 00157 static int logbuffersize; 00158 00159 /* DK 2000/06/02 Added bErrorIssuedToStderr variable to 00160 prevent the overloading of stderr with 00161 "Message Too Long" error messages. 00162 *******************************************************/ 00163 static int bErrorIssuedToStderr=0; 00164 00165 #ifdef _LOGITMT 00166 static mutex_t mutsem; 00167 #endif 00168 00169 00170 /************************************************************************* 00171 * logit_init * 00172 * * 00173 * Call this function once before the other logit routines. * 00174 * * 00175 * prog : Name of the calling program (argv[0] to main()). * 00176 * On OS2, prog has the suffix ".exe" * 00177 * * 00178 * mid : Module id number of the calling program. NOTE: No * 00179 * longer used but left in the call for backwards * 00180 * compatiblity. * 00181 * * 00182 * bufSize : Size of buffer to be allocated by logit_init. * 00183 * This buffer must be large enough to accomodate the * 00184 * largest log message to be written. * 00185 * 11/13/1998, DavidK, added the ability to write the * 00186 * process id, to the logit message, which would extend * 00187 * a message by up to 6 chars. So messages that were * 00188 * borderline length before, will now be too long, if the * 00189 * pid is included. * 00190 * * 00191 * logflag : Switch to turn disk-file and stderr/stdout logging * 00192 * on or off globally. * 00193 * * 00194 * If logit_init is called again, it will set the output flags * 00195 * according to the new value in logflag. * 00196 *************************************************************************/ 00197 00198 void logit_init( char *prog, short mid, int bufSize, int logflag ) 00199 { 00200 char *str; 00201 char progName[50]; 00202 00203 /* Set time zone using the TZ environmental variable. 00204 This is not required under Solaris. 00205 In OS2 v2 or v3.0, use _tzset(). 00206 In OS2 v3.0, use tzset(). 00207 *************************************************/ 00208 #if defined(_OS2) || defined(_WINNT) 00209 if ( getenv( "TZ" ) != NULL ) _tzset(); 00210 #endif 00211 00212 /* Truncate in front of and including "/", everything beyond and 00213 including "." in the program name 00214 *********************************/ 00215 if (get_prog_name (prog, progName) != EW_SUCCESS) 00216 { 00217 fprintf( stderr, "Call to get_prog_name failed.\n"); 00218 return; 00219 } 00220 00221 /* Set Disk logging to new level 00222 (assumes that logit_init has 00223 allready been called once) 00224 JMP 9/5/2001 00225 *******************************/ 00226 00227 /* Check init flag, if we have been 00228 already called, just reset the 00229 logflag to the new value, and 00230 return. JMP 9-18-2001 00231 *********************************/ 00232 if ( init ) 00233 { 00234 /* Check the disk log/nolog switch 00235 ***********************************/ 00236 if ( logflag == 0 ) 00237 { 00238 disk = 0; 00239 if ( fp != NULL ) 00240 { 00241 fclose( fp ); 00242 } 00243 return; 00244 } 00245 00246 /* check the SOE log/nolog switch */ 00247 if (logflag == 2) 00248 soe = 0; 00249 return; 00250 } 00251 init = 1; 00252 00253 /* DK 2000/06/02 copy the desired logit buffer size 00254 into the static "logbuffersize" variable. 00255 *******************************************************/ 00256 /* copy bufSize into the "logbuffersize" static variable */ 00257 logbuffersize=bufSize; 00258 00259 /* Allocate buffer from heap 00260 *************************/ 00261 buf = (char *) malloc( (size_t)logbuffersize ); 00262 if ( buf == (char *)NULL ) 00263 { 00264 /* DK 2000/06/02 Added the size of the malloc, to the message */ 00265 fprintf( stderr, "%s logit_init: malloc error for %d bytes. Exiting\n", 00266 progName, logbuffersize ); 00267 exit( 0 ); 00268 } 00269 00270 /* Create a mutex 00271 **************/ 00272 #ifdef _LOGITMT 00273 CreateSpecificMutex( &mutsem ); 00274 #endif 00275 00276 /* Check the disk log/nolog switch 00277 *******************************/ 00278 if ( logflag == 0 ) 00279 { 00280 disk = 0; 00281 return; 00282 } 00283 00284 /* check the SOE log/nolog switch */ 00285 if (logflag == 2) 00286 soe = 0; 00287 00288 /* Get path to log directory from environment variable EW_LOG 00289 **********************************************************/ 00290 str = getenv( "EW_LOG" ); 00291 00292 if ( str == NULL ) 00293 { 00294 fprintf( stderr, "Environment variable EW_LOG not defined; " ); 00295 fprintf( stderr, "%s exiting.\n", progName ); 00296 exit( -1 ); 00297 } 00298 00299 /* Save the log-directory path and program name. 00300 *******************************************************/ 00301 strcpy ( logpath, str ); 00302 sprintf( template, "%s_", progName ); 00303 00304 /* Build date stamp 00305 *****************/ 00306 time( &now ); 00307 gmtime_ew( &now, &res ); 00308 00309 /******************* Y2K ********************* 00310 * Add 1900 to tm_year since it represents * 00311 * number of years since 1900 * 00312 ******************* Y2K *********************/ 00313 sprintf( date, "%04d%02d%02d", (res.tm_year + TM_YEAR_CORR), 00314 (res.tm_mon + 1), res.tm_mday ); 00315 00316 /* Build extension 00317 *****************/ 00318 sprintf( extension, ".log" ); 00319 00320 /* Build logfile name 00321 *******************/ 00322 strcpy( logName, logpath ); 00323 strcat( logName, template ); 00324 strcat( logName, date ); 00325 strcat( logName, extension ); 00326 strcpy( date_prev, date ); 00327 00328 00329 #if EW_DEBUG 00330 fprintf (stderr, "Opening %s\n", logName); 00331 /* this was commented by DK on 990208, because 00332 it was writing data to the webserver on stderr, 00333 which gets processed first, and causes things to 00334 blow up, because the webserver is trying to parse 00335 a header from it. I think this should be a debug 00336 statement any way. */ 00337 #endif /* EW_DEBUG */ 00338 00339 /* Open log file 00340 *************/ 00341 fp = fopen( logName, "a" ); 00342 if ( fp == NULL ) 00343 { 00344 fprintf( stderr, "%s: Error opening log file <%s%s%s>. Exiting\n", 00345 progName, template, date, extension ); 00346 exit( 0 ); 00347 } 00348 00349 /* Print startup message to log file 00350 *********************************/ 00351 fprintf( fp, "\n-------------------------------------------------------\n" ); 00352 fprintf( fp, "%s: startup at UTC_%s_%02d:%02d:%02d\n", 00353 progName, date, res.tm_hour, res.tm_min, res.tm_sec ); 00354 00355 #ifdef _LOGITMT 00356 fprintf( fp, "This program is using the MT-Safe version of logit.\n" ); 00357 #else 00358 fprintf( fp, "This program is using the non-MT-Safe version of logit.\n" ); 00359 #endif 00360 00361 fprintf( fp, "-------------------------------------------------------\n" ); 00362 00363 fflush ( fp ); 00364 00365 /* Log a warning message 00366 *********************/ 00367 #if defined(_OS2) || defined(_WINNT) 00368 if ( getenv( "TZ" ) == NULL ) 00369 { 00370 logit( "e", "WARNING: The TZ environmental variable is not set.\n" ); 00371 logit( "e", " UTC times in log messages may be bogus.\n" ); 00372 } 00373 #endif 00374 00375 /* get the process id for use by logit("p",""); 00376 davidk 11/13/1998 */ 00377 pid=getpid(); 00378 return; 00379 } 00380 00381 00382 /***************************************************************** 00383 * logit * 00384 * * 00385 * Function to log a message to a disk file. * 00386 * * 00387 * flag: A string controlling where output is written: * 00388 * If any character is 'e', output is written to stderr. * 00389 * If any character is 'o', output is written to stdout. * 00390 * If any character is 't', output is time stamped. * 00391 * If any character is 'p', output is ProcessID stamped. * 00392 * * 00393 * The rest of calling sequence is identical to printf. * 00394 *****************************************************************/ 00395 00396 void logit( char *flag, char *format, ... ) 00397 { 00398 auto va_list ap; 00399 static char *fl; 00400 int stout = 0; /* 1 if output is also to stdout */ 00401 int sterr = 0; /* 1 if output is also to stderr */ 00402 int time_stamp = 0; /* 1 if output is time-stamped */ 00403 int pid_stamp = 0; /* 1 if output is pid-stamped */ 00404 int retcode; /* DK 2000/06/02 used to check the 00405 return code from vsnprintf() */ 00406 int basebufferlen; /* DK 2000/06/02 used to store the 00407 length of the header string 00408 prepended to the guts of the log 00409 message */ 00410 00411 /* Check init flag 00412 ***************/ 00413 if ( !init ) 00414 { 00415 fprintf( stderr, "WARNING: Call logit_init before logit.\n" ); 00416 return; 00417 } 00418 00419 #ifdef _LOGITMT 00420 RequestSpecificMutex( &mutsem ); 00421 #endif 00422 00423 /* Check flag argument 00424 *******************/ 00425 fl = flag; 00426 while ( *fl != '\0' ) 00427 { 00428 if ( *fl == 'o' && soe == 1 ) stout = 1; 00429 if ( *fl == 'e' && soe == 1 ) sterr = 1; 00430 if ( *fl == 't' ) time_stamp = 1; 00431 if ( *fl == 'd' ) pid_stamp = 1; 00432 fl++; 00433 } 00434 00435 /* Get current system time 00436 ***********************/ 00437 time( &now ); 00438 gmtime_ew( &now, &res ); 00439 00440 /******************* Y2K ********************* 00441 * Add 1900 to tm_year since it represents * 00442 * number of years since 1900 * 00443 ******************* Y2K *********************/ 00444 sprintf (date, "%4d%02d%02d", (res.tm_year + TM_YEAR_CORR), 00445 (res.tm_mon + 1), res.tm_mday); 00446 00447 00448 /* If we are writing to a disk file... 00449 ***********************************/ 00450 if ( disk ) 00451 { 00452 00453 00454 /* See if the date has changed. 00455 If so, create a new log file. 00456 *****************************/ 00457 if ( strcmp( date, date_prev ) != 0 ) 00458 { 00459 fprintf( fp, 00460 "UTC date changed; log output continues in file <%s%s%s>\n", 00461 template, date, extension ); 00462 fclose( fp ); 00463 00464 /* Build new logfile name 00465 **************************/ 00466 strcpy( logName, logpath ); 00467 strcat( logName, template ); 00468 strcat( logName, date ); 00469 strcat( logName, extension ); 00470 00471 fp = fopen( logName, "a" ); 00472 if ( fp == NULL ) 00473 { 00474 fprintf( stderr, "Error opening log file <%s%s%s>. Exiting\n", 00475 template, date, extension ); 00476 exit( 0 ); 00477 } 00478 fprintf( fp, 00479 "UTC date changed; log output continues from file <%s%s%s>\n", 00480 template, date_prev, extension ); 00481 strcpy( date_prev, date ); 00482 00483 /* Send a warning message to the new log file 00484 ******************************************/ 00485 #if defined(_OS2) || defined(_WINNT) 00486 if ( getenv( "TZ" ) == NULL ) 00487 { 00488 fprintf( fp, "WARNING: The TZ environmental variable is not set.\n" ); 00489 fprintf( fp, " UTC times in log messages may be bogus.\n" ); 00490 } 00491 #endif 00492 } 00493 } 00494 00495 /* Write UTC time and argument list to buffer 00496 * 00497 * Wed Oct 28 16:19:45 MST 1998 lucky 00498 * Added date to the log message 00499 ******************************************/ 00500 va_start( ap, format ); 00501 buf[0] = 0; /* NULL terminate the empty buf */ 00502 00503 /* DavidK 11/13/1998, changed the format of the conditionals 00504 for writing the variable argument stuff to buffer. 00505 Changed from if..else for time stamp to if(time_stamp), 00506 if(pid_stamp), then after all headers have been written, 00507 concatenate the variable argument list to end. 00508 */ 00509 /* Write UTC time stamp to buffer if desired */ 00510 if ( time_stamp ) 00511 { 00512 sprintf( buf+strlen(buf), "%s_UTC_%02d:%02d:%02d ", 00513 date, res.tm_hour, res.tm_min, res.tm_sec ); 00514 } 00515 00516 /* Write Process ID stamp to buffer if desired */ 00517 if ( pid_stamp ) 00518 { 00519 sprintf( buf+strlen(buf), "(%d) ", pid); 00520 } 00521 00522 /* Record the strlen() of the buffer after the header has been created */ 00523 basebufferlen=strlen(buf); 00524 00525 /* Write argument list to buffer */ 00526 00527 /* DK 2000/06/02 replaced the following vsprintf() call with 00528 a vsnprintf() call that puts a limit on the number of 00529 bytes written to the buffer, thus preventing buffer overflow 00530 ***************************************************************/ 00531 /* vsprintf( buf+strlen(buf), format, ap); */ 00532 00533 retcode=vsnprintf(buf+basebufferlen, logbuffersize-basebufferlen, 00534 format, ap); 00535 00536 /* check the return code from vsnprintf(). It returns the number 00537 of characters written to the buffer unless there is an error, 00538 upon error, -1 is returned. Note: on most unix systems, 00539 if the buffer is not long enough for the message, vsnprintf() 00540 will write "buffer length" characters to the buffer, and 00541 return "message length". On NT, -1 is returned if the 00542 "message length" exceeds the "buffer length". 00543 ***************************************************************/ 00544 if(retcode > logbuffersize-basebufferlen) 00545 { 00546 /* The buffer wasn't long enough for the message and we know how long 00547 the message was. 00548 *********************************************************************/ 00549 00550 if ( disk ) 00551 { 00552 fprintf( fp, "logit(%s): ERROR!!! Attempting to log too large " 00553 "of a message!!!\n Logit buffer is %d bytes, message " 00554 "is %d bytes!\n", template, logbuffersize, 00555 retcode + basebufferlen); 00556 /* If fprintf fails, we won't know it */ 00557 00558 } 00559 else 00560 { 00561 if(!bErrorIssuedToStderr) 00562 { 00563 fprintf( stderr, "logit(%s): ERROR!!! Attempting to log too large " 00564 "of a message!!!\n Logit buffer is %d bytes, message " 00565 "is %d bytes!\n", template, logbuffersize, 00566 retcode + basebufferlen); 00567 bErrorIssuedToStderr=1; 00568 } 00569 } 00570 /* DK 2000/06/02 this buffer was long, and it probably had a \n at 00571 the end that got truncated. So add one in there. Don't add it 00572 to the very end of the buffer, because that's where the null 00573 terminator goes. 00574 ***************************************************************/ 00575 buf[logbuffersize-2]='\n'; 00576 } 00577 else if(retcode == -1) 00578 { 00579 /* The buffer wasn't long enough for the message but we don't know how 00580 long the message was. 00581 *********************************************************************/ 00582 00583 if ( disk ) 00584 { 00585 fprintf( fp, "logit(%s): ERROR!!! Attempting to log too large " 00586 "of a message!!!\n Logit buffer is %d bytes, message " 00587 "is more!\n", template, logbuffersize); 00588 /* If fprintf fails, we won't know it */ 00589 } 00590 else 00591 { 00592 if(!bErrorIssuedToStderr) 00593 { 00594 fprintf( stderr, "logit(%s): ERROR!!! Attempting to log too large " 00595 "of a message!!!\n Logit buffer is %d bytes, message " 00596 "is more!\n", template, logbuffersize); 00597 bErrorIssuedToStderr=1; 00598 } 00599 } 00600 /* DK 2000/06/02 this buffer was long, and it probably had a \n at 00601 the end that got truncated. So add one in there. Don't add it 00602 to the very end of the buffer, because that's where the null 00603 terminator goes. 00604 ***************************************************************/ 00605 buf[logbuffersize-2]='\n'; 00606 } 00607 00608 /* ensure that the buffer is null terminated */ 00609 buf[logbuffersize-1]=0; 00610 00611 va_end( ap ); 00612 00613 /* Write buffer to standard output and standard error 00614 **************************************************/ 00615 if ( stout ) 00616 printf( "%s", buf ); 00617 00618 if ( sterr ) 00619 fprintf( stderr, "%s", buf ); 00620 00621 /* Write buffer to disk file 00622 *************************/ 00623 if ( disk ) 00624 { 00625 fprintf( fp, "%s", buf ); /* If fprintf fails, we won't know it */ 00626 fflush( fp ); 00627 } 00628 00629 #ifdef _LOGITMT 00630 ReleaseSpecificMutex( &mutsem ); 00631 #endif 00632 00633 return; 00634 } 00635 00636 00637 /************************************************************************* 00638 * get_prog_name * 00639 * * 00640 * extracts program name from the full path by ignoring everything * 00641 * before the first / and after the . (extension) * 00642 * * 00643 * full_name Name of the calling program (argv[0] to main()). * 00644 * On OS2, prog has the suffix ".exe" * 00645 * * 00646 * prog_name Truncated program name. Array must be allocated before * 00647 * calling this routine * 00648 * * 00649 *************************************************************************/ 00650 int get_prog_name (char *full_name, char *prog_name) 00651 { 00652 00653 char *str; 00654 00655 if ((full_name == NULL) || (prog_name == NULL)) 00656 { 00657 fprintf (stderr, "Invalid arguments passed in.\n"); 00658 return EW_FAILURE; 00659 } 00660 00661 /* Truncate in front of and including "/", everything beyond and 00662 including "." in the program name 00663 *********************************/ 00664 if ((str = strrchr (full_name, '/')) != NULL) 00665 strcpy (prog_name, str + 1); 00666 else 00667 strcpy (prog_name, full_name); 00668 00669 str = strchr (prog_name, '.'); 00670 if (str != NULL) 00671 *str = '\0'; 00672 00673 return EW_SUCCESS; 00674 00675 } 00676 00677 00678 00679 /***************************************************************** 00680 * html_logit * 00681 * * 00682 * Function to log a message to a disk file, and * 00683 * also html suitable output to stderr. * 00684 * * 00685 * flag: A string controlling where output is written: * 00686 * If any character is 't', output is time stamped. * 00687 * If any character is 'p', output is ProcessID stamped. * 00688 * * 00689 * The rest of calling sequence is identical to printf. * 00690 *****************************************************************/ 00691 00692 void html_logit( char *flag, char *format, ... ) 00693 { 00694 auto va_list ap; 00695 static char *fl; 00696 int time_stamp = 0; /* 1 if output is time-stamped */ 00697 int pid_stamp = 0; /* 1 if output is pid-stamped */ 00698 int retcode; /* DK 2000/06/02 used to check the 00699 return code from vsnprintf() */ 00700 int basebufferlen; /* DK 2000/06/02 used to store the 00701 length of the header string 00702 prepended to the guts of the log 00703 message */ 00704 00705 00706 /* Put up the initial HTML */ 00707 printf ("<CENTER><HR><PRE><STRONG><BR><BR>\n"); 00708 00709 00710 /* Check init flag 00711 ***************/ 00712 if ( !init ) 00713 { 00714 printf ("WARNING: Call logit_init before logit.\n"); 00715 goto done; 00716 } 00717 00718 #ifdef _LOGITMT 00719 RequestSpecificMutex( &mutsem ); 00720 #endif 00721 00722 /* Check flag argument 00723 *******************/ 00724 fl = flag; 00725 while ( *fl != '\0' ) 00726 { 00727 if ( *fl == 't' ) time_stamp = 1; 00728 if ( *fl == 'd' ) pid_stamp = 1; 00729 fl++; 00730 } 00731 00732 /* Get current system time 00733 ***********************/ 00734 time( &now ); 00735 gmtime_ew( &now, &res ); 00736 00737 /******************* Y2K ********************* 00738 * Add 1900 to tm_year since it represents * 00739 * number of years since 1900 * 00740 ******************* Y2K *********************/ 00741 sprintf (date, "%4d%02d%02d", (res.tm_year + TM_YEAR_CORR), 00742 (res.tm_mon + 1), res.tm_mday); 00743 00744 00745 /* If we are writing to a disk file... 00746 ***********************************/ 00747 if ( disk ) 00748 { 00749 00750 00751 /* See if the date has changed. 00752 If so, create a new log file. 00753 *****************************/ 00754 if ( strcmp( date, date_prev ) != 0 ) 00755 { 00756 fprintf( fp, 00757 "UTC date changed; log output continues in file <%s%s%s>\n", 00758 template, date, extension ); 00759 fclose( fp ); 00760 00761 /* Build new logfile name 00762 **************************/ 00763 strcpy( logName, logpath ); 00764 strcat( logName, template ); 00765 strcat( logName, date ); 00766 strcat( logName, extension ); 00767 00768 fp = fopen( logName, "a" ); 00769 if ( fp == NULL ) 00770 { 00771 fprintf( stderr, "Error opening log file <%s%s%s>. Exiting\n", 00772 template, date, extension ); 00773 exit( 0 ); 00774 } 00775 fprintf( fp, 00776 "UTC date changed; log output continues from file <%s%s%s>\n", 00777 template, date_prev, extension ); 00778 strcpy( date_prev, date ); 00779 00780 /* Send a warning message to the new log file 00781 ******************************************/ 00782 #if defined(_OS2) || defined(_WINNT) 00783 if ( getenv( "TZ" ) == NULL ) 00784 { 00785 fprintf( fp, "WARNING: The TZ environmental variable is not set.\n" ); 00786 fprintf( fp, " UTC times in log messages may be bogus.\n" ); 00787 } 00788 #endif 00789 } 00790 } 00791 00792 /* Write UTC time and argument list to buffer 00793 * 00794 * Wed Oct 28 16:19:45 MST 1998 lucky 00795 * Added date to the log message 00796 ******************************************/ 00797 va_start( ap, format ); 00798 buf[0] = 0; /* NULL terminate the empty buf */ 00799 00800 /* DavidK 11/13/1998, changed the format of the conditionals 00801 for writing the variable argument stuff to buffer. 00802 Changed from if..else for time stamp to if(time_stamp), 00803 if(pid_stamp), then after all headers have been written, 00804 concatenate the variable argument list to end. 00805 */ 00806 /* Write UTC time stamp to buffer if desired */ 00807 if ( time_stamp ) 00808 { 00809 sprintf( buf+strlen(buf), "%s_UTC_%02d:%02d:%02d ", 00810 date, res.tm_hour, res.tm_min, res.tm_sec ); 00811 } 00812 00813 /* Write Process ID stamp to buffer if desired */ 00814 if ( pid_stamp ) 00815 { 00816 sprintf( buf+strlen(buf), "(%d) ", pid); 00817 } 00818 00819 /* Record the strlen() of the buffer after the header has been created */ 00820 basebufferlen=strlen(buf); 00821 00822 /* Write argument list to buffer */ 00823 00824 /* DK 2000/06/02 replaced the following vsprintf() call with 00825 a vsnprintf() call that puts a limit on the number of 00826 bytes written to the buffer, thus preventing buffer overflow 00827 ***************************************************************/ 00828 /* vsprintf( buf+strlen(buf), format, ap); */ 00829 00830 retcode=vsnprintf(buf+basebufferlen, logbuffersize-basebufferlen, 00831 format, ap); 00832 00833 /* check the return code from vsnprintf(). It returns the number 00834 of characters written to the buffer unless there is an error, 00835 upon error, -1 is returned. Note: on most unix systems, 00836 if the buffer is not long enough for the message, vsnprintf() 00837 will write "buffer length" characters to the buffer, and 00838 return "message length". On NT, -1 is returned if the 00839 "message length" exceeds the "buffer length". 00840 ***************************************************************/ 00841 if(retcode > logbuffersize-basebufferlen) 00842 { 00843 /* The buffer wasn't long enough for the message and we know how long 00844 the message was. 00845 *********************************************************************/ 00846 00847 if ( disk ) 00848 { 00849 fprintf( fp, "logit(%s): ERROR!!! Attempting to log too large " 00850 "of a message!!!\n Logit buffer is %d bytes, message " 00851 "is %d bytes!\n", template, logbuffersize, 00852 retcode + basebufferlen); 00853 /* If fprintf fails, we won't know it */ 00854 00855 } 00856 else 00857 { 00858 if(!bErrorIssuedToStderr) 00859 { 00860 printf ("html_logit(%s): ERROR!!! Attempting to log too large " 00861 "of a message!!!\n Logit buffer is %d bytes, message " 00862 "is %d bytes!\n", template, logbuffersize, 00863 retcode + basebufferlen); 00864 00865 bErrorIssuedToStderr=1; 00866 } 00867 } 00868 /* DK 2000/06/02 this buffer was long, and it probably had a \n at 00869 the end that got truncated. So add one in there. Don't add it 00870 to the very end of the buffer, because that's where the null 00871 terminator goes. 00872 ***************************************************************/ 00873 buf[logbuffersize-2]='\n'; 00874 } 00875 else if(retcode == -1) 00876 { 00877 /* The buffer wasn't long enough for the message but we don't know how 00878 long the message was. 00879 *********************************************************************/ 00880 00881 if ( disk ) 00882 { 00883 fprintf( fp, "logit(%s): ERROR!!! Attempting to log too large " 00884 "of a message!!!\n Logit buffer is %d bytes, message " 00885 "is more!\n", template, logbuffersize); 00886 /* If fprintf fails, we won't know it */ 00887 } 00888 else 00889 { 00890 if(!bErrorIssuedToStderr) 00891 { 00892 printf ("html_logit(%s): ERROR!!! Attempting to log too large " 00893 "of a message!!!\n Logit buffer is %d bytes, message " 00894 "is more!\n", template, logbuffersize); 00895 bErrorIssuedToStderr=1; 00896 } 00897 } 00898 /* DK 2000/06/02 this buffer was long, and it probably had a \n at 00899 the end that got truncated. So add one in there. Don't add it 00900 to the very end of the buffer, because that's where the null 00901 terminator goes. 00902 ***************************************************************/ 00903 buf[logbuffersize-2]='\n'; 00904 } 00905 00906 /* ensure that the buffer is null terminated */ 00907 buf[logbuffersize-1]=0; 00908 00909 va_end( ap ); 00910 00911 /* Write buffer to html 00912 *******************************/ 00913 printf( "ERROR: %s", buf ); 00914 00915 00916 /* Write buffer to disk file 00917 *************************/ 00918 if ( disk ) 00919 { 00920 fprintf( fp, "%s", buf ); /* If fprintf fails, we won't know it */ 00921 fflush( fp ); 00922 } 00923 00924 #ifdef _LOGITMT 00925 ReleaseSpecificMutex( &mutsem ); 00926 #endif 00927 00928 done: 00929 printf ("</CENTER><HR></PRE></STRONG>\n"); 00930 return; 00931 } 00932 00933