Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

logit.c

Go to the documentation of this file.
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 

Generated on Tue May 6 09:16:04 2003 for Earthworm Libs by doxygen1.3-rc3