1 #include <ctype.h> /* ANSI C */
10 #define MAXTSTAMP 80 /* maximum length of a time stamp */
11 #define MAXMSGBUF 4096 /* maximum status/error message bytes held */
15 char *verb[NLOG] = { "ewin", "" } ;
18 int nxtoptind = 1 ; /* for communication with nextopt() */
22 /* For systems without strerror(3) */
26 extern char *sys_errlist[];
28 extern char *strerror( int i )
30 return ( i >= 0 && i < sys_nerr ) ? sys_errlist[i] : "Unknown Error" ;
35 /* Print time stamp. */
37 time_t tstamp ( time_t last, FILE *f )
40 char tbuf [ MAXTSTAMP ] ;
44 strftime ( tbuf, MAXTSTAMP, ( now - last > 600 ) ? "%c" : "%M:%S",
52 /* Return string corresponding to character c. */
54 char *cname ( uchar c )
56 #define CNAMEFMT "<0x%02x>"
58 static char *cnametab [ 256 ] = { /* character names */
59 "<NUL>","<SOH>","<STX>","<ETX>", "<EOT>","<ENQ>","<ACK>","<BEL>",
60 "<BS>", "<HT>", "<LF>", "<VT>", "<FF>", "<CR>", "<SO>", "<SI>",
61 "<DLE>","<XON>","<DC2>","<XOFF>","<DC4>","<NAK>","<SYN>","<ETB>",
62 "<CAN>","<EM>", "<SUB>","<ESC>", "<FS>", "<GS>", "<RS>", "<US>" } ;
63 static char names[ (127-32)*2 + 129*(CNAMELEN) ] ;
68 for ( i=32 ; i<256 ; i++ ) {
70 sprintf ( p, i<127 ? "%c" : CNAMEFMT, i ) ;
71 p += strlen ( p ) + 1 ;
75 return cnametab [ c ] ;
78 /* Print a message with a variable number of printf()-type
79 arguments if the first character appears in the global
80 verb[ose] string. Other leading characters and digits do
81 additional actions: + allows the message to be continued on
82 the same line, '-' buffers the message instead of printing it,
83 E, and W expand into strings, S prints the error message for
84 the most recent system error, a digit sets the return value, a
85 space ends prefix but isn't printed. Returns 0 if no prefix
88 enum msgflags { E=0x01, W=0x02, S=0x04, NOFLSH=0x08, NOLF=0x10 } ;
90 int msg ( char *fmt, ... )
93 static FILE *logfile [ NLOG ] ;
94 static char msgbuf [ NLOG ] [ MAXMSGBUF ] ;
95 static time_t logtime [ NLOG ] = { 0, 0 } ;
96 static int atcol1 [ NLOG ] = { 1, 1 } ;
98 int err=0, i, flags=0 ;
102 va_start ( ap, fmt ) ;
105 logfile[0] = stderr ;
106 logfile[1] = stdout ;
107 for ( i=0 ; i<NLOG ; i++ )
108 setvbuf ( logfile[i], msgbuf[i], _IOFBF, MAXMSGBUF ) ;
113 for ( i=0 ; i<NLOG ; i++ ) {
115 for ( p=fmt ; *p ; p++ ) {
117 case ' ': p++ ; goto print ;
118 case 'E': flags |= E ; break ;
119 case 'W': flags |= W ; break ;
120 case 'S': flags |= S ; break ;
121 case '+': flags |= NOLF ; break ;
122 case '-': flags |= NOFLSH ; break ;
124 if ( isdigit ( *p ) ) {
126 } else if ( ! isupper ( *p ) ) {
134 if ( strchr ( verb[i], tolower ( *fmt ) ) ) {
137 fprintf ( logfile[i], "%s: ", argv0 ) ;
138 logtime[i] = tstamp ( logtime[i], logfile[i] ) ;
139 fputs ( ( flags & E ) ? " Error: " :
140 ( flags & W ) ? " Warning: " :
144 vfprintf( logfile[i], p, ap ) ;
145 if ( flags & S ) fprintf ( logfile[i], " %s", strerror ( errno ) ) ;
146 if ( ! ( flags & NOLF ) ) fputs ( "\n", logfile[i] ) ;
147 atcol1[i] = flags & NOLF ? 0 : 1 ;
148 if ( ! ( flags & NOFLSH ) ) fflush ( logfile[i] ) ;
160 /* Simple (one option per argument) version of getopt(3). */
162 int nextopt( int argc, char **argv, char *args )
166 if ( nxtoptind >= argc || *(a = argv[nxtoptind]) != '-' ) return -1 ;
169 if ( ! *(a+1) || ( ( p = strchr ( args, *(a+1) ) ) == 0 ) )
170 return msg ( "Eunknown option (%s)", a ), '?' ;
172 if ( *(p+1) != ':' ) nxtoptarg = 0 ;
174 if ( *(a+2) ) nxtoptarg = a+2 ;
176 if ( nxtoptind >= argc ) return msg ( "Eno argument for (%s)", a ), '?' ;
177 else nxtoptarg = argv [ nxtoptind++ ] ;