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