1  /* LOGMSG.C - Utility procedures to minimise stderr output */
2  
3  #include <stdio.h>
4  #include <time.h>
5
dump
6  #ifdef OSK
7  #include <varargs.h>
8  #include <strings.h>
9  #else
10  #include <stdlib.h>
11  #include <string.h>
12  #endif
13  
14  #include "logmsg.h"
15
dump
16  /*
17      Define the buffer structure
18  */
19  struct logent {                       /* one buffer entry */
20                    time_t timestamp;
21                    char   msg[MAXSTRLEN];
22                };
23  struct    logent _msgbuf[BUFFLIM];    /* the circular buffer */
24  int       _msgbufptr;                 /* buffer update pointer */
25  time_t    _last_dump;                 /* time of last dump */
26  int       _first_msg;                 /* first message to dump */
27  int       _first_time  = 1;           /* initialisation control flag */
28  int       _runtype = INDIRECT_LOG;    /* selects direct or indirect output */
29  int       _fileno = STDERR_LOG;       /* selects stdout or stderr */
30  
31  #define  INCPTR(p) (p+1)%BUFFLIM
32  
33  /*
34      logsetup() - selects operational mode and output file no
35  */
36  void logsetup(r, f)
37  int    r;
38  int    f;
39  {
40      _runtype = r;
41      _fileno  = f;
42  }
43  
44  /*
45      logmsg() - handles message logging.
46  
47      If the debugging flag DIRECT_LOG is on this call is equivalent
48      to 'fprintf(stderr, format, ....)'. If it is off each message
49      is timestamped and written to a circular buffer, from where it
50      is printed by logdump().
51  */
52  #ifdef OSK
53  void logmsg(fmt, va_alist)
54  char    *fmt;
55  va_dcl
56  #else
57  void logmsg(char* fmt. ...)
58  #endif
59  {
60      va_list   apx;
61      char      linebuff[1000];
62      time_t      now;
63      struct tm *tblock;
64      int       i;
65      int       lth;
66  
67      /*
68          Set up the message to be logged and get the time
69      */
70      va_start(apx, fmt);
71      lth = vsprintf(linebuff, fmt, apx);
72      if (linebuff[lth-1] == '\n')
73          linebuff[lth-1] = NULL;
74      va_end(apx);
75  
76      now = time(NULL);
77  
78      /*
79          This code handles direct output
80      */
81      if (_runtype == DIRECT_LOG)
82      {
83          tblock = localtime(&now);
84          if (_fileno == STDOUT_LOG)
85              fprintf(stdout,
86                      "%02d:%02d:%02d %s\n",
87                      tblock->tm_hour,
88                      tblock->tm_min,
89                      tblock->tm_sec,
90                      linebuff);
91          else
92              fprintf(stderr,
93                      "%02d:%02d:%02d %s\n",
94                      tblock->tm_hour,
95                      tblock->tm_min,
96                      tblock->tm_sec,
97                      linebuff);
98          return;
99      }
100  
101      /*
102          Indirect output.
103  
104          Initialise the buffer the first time through
105      */
106      if (_first_time)
107      {
108          for (i=0; i<BUFFLIM; i++)
109              _msgbuf[i].timestamp = 0;
110          _msgbufptr = 0;
111          _last_dump = 0;
112          _first_time = 0;
113      }
114  
115      /*
116          Add the message to the buffer.
117      */
118      _msgbuf[_msgbufptr].timestamp = now;
119      strncpy(_msgbuf[_msgbufptr].msg, linebuff, MAXSTRLEN);
120      _msgbuf[_msgbufptr].msg[MAXSTRLEN] = NULL;
121  
122      /*
123          Adjust the pointers. The storage pointer is incremented
124          modulo the buffer size. If this catches up with the dump
125          pointer this is carried along with it.
126      */
127      _msgbufptr = INCPTR(_msgbufptr);
128      if (_msgbufptr == _first_msg)
129          _first_msg = INCPTR(_msgbufptr);
130  }
131  
132  /*
133      logdump() - prints the buffer set up by logmsg().
134  
135      If the debugging flag DIRECT_LOG is on this function does nothing.
136      If it is off all unprinted messages in the buffer are printed.
137  */
138  void logdump()
139  {
140      struct tm *tblock;
141      int     i;
142      int        last;
143  
144      /*
145          Do nothing if nothing has been logged or the
146          direct output flag is on
147      */
148      if (_runtype == DIRECT_LOG || _first_time)
149          return;
150  
151      /*
152          Scan the buffer, outputting all unprinted messages
153          in order of arrival. Keep track of the last message
154          output.
155      */
156      i = _first_msg;
157      do {
158          if (_msgbuf[i].timestamp > 0
159              && _msgbuf[i].timestamp >= _last_dump) {
160              tblock = localtime(&_msgbuf[i].timestamp);
161              if (_fileno == STDOUT_LOG )
162                  fprintf(stdout,
163                          "%02d:%02d:%02d %s\n",
164                          tblock->tm_hour,
165                          tblock->tm_min,
166                          tblock->tm_sec,
167                          _msgbuf[i].msg);
168              else
169                  fprintf(stderr,
170                          "%02d:%02d:%02d %s\n",
171                          tblock->tm_hour,
172                          tblock->tm_min,
173                          tblock->tm_sec,
174                          _msgbuf[i].msg);
175              last = i;
176          }
177          i = INCPTR(i);
178      }
179      while (i != _msgbufptr);
180  
181      /*
182          Reset the dump starting pointer and dump time.
183      */
184      _first_msg = INCPTR(last);
185      _last_dump = time(NULL);
186  }
