Changeset 1200
- Timestamp:
- Feb 7, 2004, 3:58:28 AM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/emx/src/libsyslog/syslog.c
-
Property cvs2svn:cvs-rev
changed from
1.2
to1.3
r1199 r1200 33 33 34 34 #if defined(LIBC_SCCS) && !defined(lint) 35 static char sccsid[] = "@(#)syslog.c 8.8 (Berkeley) 8/30/95";35 static char sccsid[] = "@(#)syslog.c 8.5 (Berkeley) 4/29/95"; 36 36 #endif /* LIBC_SCCS and not lint */ 37 38 #include <sys/param.h> 37 #include <sys/cdefs.h> 38 __FBSDID("$FreeBSD: src/lib/libc/gen/syslog.c,v 1.29 2003/02/10 08:31:28 alfred Exp $"); 39 40 #include "namespace.h" 39 41 #include <sys/types.h> 40 42 #include <sys/socket.h> 43 #include <sys/syslog.h> 41 44 #include <sys/uio.h> 42 #include <sys/ syslog.h>45 #include <sys/un.h> 43 46 #include <netdb.h> 44 47 #ifdef __EMX__ 45 # include <netinet/in.h>48 # include <netinet/in.h> 46 49 #endif 47 50 48 51 #include <errno.h> 49 52 #include <fcntl.h> 53 #ifndef __EMX__ 54 # include <paths.h> 55 #else 56 # define _PATH_CONSOLE "/dev/con" 57 #endif 50 58 #include <stdio.h> 59 #include <stdlib.h> 51 60 #include <string.h> 52 61 #include <time.h> 53 62 #include <unistd.h> 54 63 55 #if defined(BSD4_4) && !defined(__EMX__) 56 # include <paths.h> 57 #else 58 # if defined(__EMX__) 59 # define _PATH_CONSOLE "con" 60 # endif 61 62 # ifndef _PATH_CONSOLE 63 # define _PATH_CONSOLE "/dev/console" 64 # endif 65 # ifndef _PATH_LOG 66 # define _PATH_LOG "/dev/log" 67 # endif 68 #endif 69 70 #if __STDC__ 71 # include <stdarg.h> 72 #else 73 # include <varargs.h> 74 # define const /* */ 75 #endif 76 77 #ifndef USESNPRINTF 78 # if defined(BSD4_4) || defined(__EMX__) 79 # define USESNPRINTF 1 /* has snprintf(3), vsnprintf(3), etc. */ 80 # else 81 # define USESNPRINTF 0 /* cheesy old C library */ 82 # endif 83 #endif 84 85 #ifndef LOG_PRI 86 # define LOG_PRI(p) ((p) & LOG_PRIMASK) 87 #endif 88 89 #ifndef LOG_PERROR 90 # define LOG_PERROR 0 91 #endif 92 93 #define BUFSLOP 1024 /* overflow space */ 64 #include <stdarg.h> 65 #include "un-namespace.h" 66 67 #include "libc_private.h" 94 68 95 69 static int LogFile = -1; /* fd for log */ 96 70 static int connected; /* have done connect */ 71 static int opened; /* have done openlog() */ 97 72 static int LogStat = 0; /* status bits, set by openlog() */ 98 73 static const char *LogTag = NULL; /* string to tag the entry with */ 99 74 static int LogFacility = LOG_USER; /* default facility code */ 100 75 static int LogMask = 0xff; /* mask of priorities to be logged */ 101 #if defined(BSD4_4) && !defined(__EMX__) 102 extern char *__progname; /* Program name, from crt0. */ 103 #else 104 char *__progname = NULL; 76 77 static void disconnectlog(void); /* disconnect from syslogd */ 78 static void connectlog(void); /* (re)connect to syslogd */ 79 80 #ifndef __EMX__ 81 /* 82 * Format of the magic cookie passed through the stdio hook 83 */ 84 struct bufcookie { 85 char *base; /* start of buffer */ 86 int left; 87 }; 88 89 /* 90 * stdio write hook for writing to a static string buffer 91 * XXX: Maybe one day, dynamically allocate it so that the line length 92 * is `unlimited'. 93 */ 94 static 95 int writehook(cookie, buf, len) 96 void *cookie; /* really [struct bufcookie *] */ 97 char *buf; /* characters to copy */ 98 int len; /* length to copy */ 99 { 100 struct bufcookie *h; /* private `handle' */ 101 102 h = (struct bufcookie *)cookie; 103 if (len > h->left) { 104 /* clip in case of wraparound */ 105 len = h->left; 106 } 107 if (len > 0) { 108 (void)memcpy(h->base, buf, len); /* `write' it. */ 109 h->base += len; 110 h->left -= len; 111 } 112 return 0; 113 } 105 114 #endif 106 115 … … 110 119 */ 111 120 void 112 #if __STDC__113 121 syslog(int pri, const char *fmt, ...) 114 #else115 syslog(pri, fmt, va_alist)116 int pri;117 char *fmt;118 va_dcl119 #endif120 122 { 121 123 va_list ap; 122 extern void vsyslog(); 123 124 #if __STDC__ 125 va_start(ap, fmt); 126 #else 127 va_start(ap); 128 #endif 129 vsyslog(pri, fmt, ap); 130 va_end(ap); 124 125 va_start(ap, fmt); 126 vsyslog(pri, fmt, ap); 127 va_end(ap); 131 128 } 132 129 133 130 void 134 131 vsyslog(pri, fmt, ap) 135 136 registerconst char *fmt;137 138 { 139 registerint cnt;140 register char ch, *p, *t;132 int pri; 133 const char *fmt; 134 va_list ap; 135 { 136 int cnt; 137 char ch, *p; 141 138 time_t now; 142 139 int fd, saved_errno; 143 int panic = 0; 144 static int maxsend = BUFSIZ; 145 char *stdp, fmt_cpy[1024], tbuf[BUFSIZ + BUFSLOP]; 146 extern void openlog(); 140 char *stdp, tbuf[2048], fmt_cpy[1024], timbuf[26]; 141 #ifndef __EMX__ 142 FILE *fp, *fmt_fp; 143 struct bufcookie tbuf_cookie; 144 struct bufcookie fmt_cookie; 145 #endif 147 146 148 147 #define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID … … 164 163 pri |= LogFacility; 165 164 166 /* Get connected. */ 167 if (!connected) 168 openlog(LogTag, LogStat | LOG_NDELAY, 0); 165 #ifndef __EMX__ 166 /* Create the primary stdio hook */ 167 tbuf_cookie.base = tbuf; 168 tbuf_cookie.left = sizeof(tbuf); 169 fp = fwopen(&tbuf_cookie, writehook); 170 if (fp == NULL) 171 return; 172 #endif 169 173 170 174 /* Build the message. */ 171 175 (void)time(&now); 172 sprintf(tbuf, "<%d>", pri); 173 p = tbuf + strlen(tbuf); 174 strftime(p, sizeof (tbuf) - (p - tbuf), "%h %d %T ", localtime(&now)); 175 p += strlen(p); 176 stdp = p; 176 #ifndef __EMX__ 177 (void)fprintf(fp, "<%d>", pri); 178 (void)fprintf(fp, "%.15s ", ctime_r(&now, timbuf) + 4); 179 #else 180 p = tbuf + sprintf(tbuf, "<%d>", pri); 181 p += sprintf(p, "%.15s ", ctime_r(&now, timbuf) + 4); 182 #endif 183 if (LogStat & LOG_PERROR) { 184 #ifndef __EMX__ 185 /* Transfer to string buffer */ 186 (void)fflush(fp); 187 stdp = tbuf + (sizeof(tbuf) - tbuf_cookie.left); 188 #else 189 stdp = p; 190 #endif 191 } 177 192 if (LogTag == NULL) 178 LogTag = __progname; 193 LogTag = _getprogname(); 194 if (LogTag != NULL) 195 #ifndef __EMX__ 196 (void)fprintf(fp, "%s", LogTag); 197 #else 198 p += sprintf(p, "%s", LogTag); 199 #endif 200 if (LogStat & LOG_PID) 201 #ifndef __EMX__ 202 (void)fprintf(fp, "[%d]", getpid()); 203 #else 204 p += sprintf(p, "[%d]", getpid()); 205 #endif 179 206 if (LogTag != NULL) { 180 sprintf(p, "%s", LogTag); 181 p += strlen(p); 182 } 183 if (LogStat & LOG_PID) { 184 sprintf(p, "[%d]", getpid()); 185 p += strlen(p); 186 } 187 if (LogTag != NULL) { 207 #ifndef __EMX__ 208 (void)fprintf(fp, ": "); 209 #else 188 210 *p++ = ':'; 189 211 *p++ = ' '; 212 #endif 190 213 } 191 214 192 /* Substitute error message for %m. */ 193 for (t = fmt_cpy; ch = *fmt; ++fmt) 194 if (ch == '%' && fmt[1] == 'm') { 195 ++fmt; 196 sprintf(t, "%s", strerror(saved_errno)); 197 t += strlen(t); 198 } else 199 *t++ = ch; 200 *t = '\0'; 201 202 #if USESNPRINTF 203 cnt = maxsend - (p - tbuf) + 1; 204 p += vsnprintf(p, cnt, fmt_cpy, ap); 215 /* Check to see if we can skip expanding the %m */ 216 if (strstr(fmt, "%m")) { 217 #ifndef __EMX__ 218 /* Create the second stdio hook */ 219 fmt_cookie.base = fmt_cpy; 220 fmt_cookie.left = sizeof(fmt_cpy) - 1; 221 fmt_fp = fwopen(&fmt_cookie, writehook); 222 if (fmt_fp == NULL) { 223 fclose(fp); 224 return; 225 } 226 #else 227 char *t = fmt_cpy; 228 #endif 229 230 /* 231 * Substitute error message for %m. Be careful not to 232 * molest an escaped percent "%%m". We want to pass it 233 * on untouched as the format is later parsed by vfprintf. 234 */ 235 for ( ; (ch = *fmt); ++fmt) { 236 if (ch == '%' && fmt[1] == 'm') { 237 ++fmt; 238 #ifndef __EMX__ 239 fputs(strerror(saved_errno), fmt_fp); 240 #else 241 t += sprintf(t, "%s", strerror(saved_errno)); 242 #endif 243 } else if (ch == '%' && fmt[1] == '%') { 244 ++fmt; 245 #ifndef __EMX__ 246 fputc(ch, fmt_fp); 247 fputc(ch, fmt_fp); 248 #else 249 *t++ = ch; 250 *t++ = ch; 251 #endif 252 } else { 253 #ifndef __EMX__ 254 fputc(ch, fmt_fp); 255 #else 256 *t++ = ch; 257 #endif 258 } 259 } 260 261 /* Null terminate if room */ 262 #ifndef __EMX__ 263 /* Null terminate if room */ 264 fputc(0, fmt_fp); 265 fclose(fmt_fp); 266 #else 267 *t = '\0'; 268 #endif 269 /* Guarantee null termination */ 270 fmt_cpy[sizeof(fmt_cpy) - 1] = '\0'; 271 272 fmt = fmt_cpy; 273 } 274 275 #ifndef __EMX__ 276 (void)vfprintf(fp, fmt, ap); 277 (void)fclose(fp); 278 279 cnt = sizeof(tbuf) - tbuf_cookie.left; 280 #else 205 281 cnt = p - tbuf; 206 #else 207 vsprintf(p, fmt_cpy, ap); 208 p += strlen(p); 209 cnt = p - tbuf; 210 if (cnt > sizeof tbuf) { 211 /* Panic condition. */ 212 panic = 1; 213 } 214 if (cnt > maxsend) 215 cnt = maxsend; 282 cnt += vsnprintf(p, sizeof(tbuf) - cnt - 1, fmt, ap); 216 283 #endif 217 284 … … 219 286 if (LogStat & LOG_PERROR) { 220 287 struct iovec iov[2]; 221 registerstruct iovec *v = iov;288 struct iovec *v = iov; 222 289 223 290 v->iov_base = stdp; … … 226 293 v->iov_base = "\n"; 227 294 v->iov_len = 1; 228 (void)writev(STDERR_FILENO, iov, 2);295 (void)_writev(STDERR_FILENO, iov, 2); 229 296 } 230 297 231 /* Output the message to the local logger. */ 232 for (;;) { 233 if (send(LogFile, tbuf, cnt, 0) >= 0) 234 goto done; 235 if (errno != EMSGSIZE || maxsend <= 256) 236 break; 237 238 /* Message was too large -- back it off. */ 239 do { 240 maxsend -= 128; 241 } while (cnt < maxsend && maxsend > 256); 242 cnt = maxsend; 243 } 298 /* Get connected, output the message to the local logger. */ 299 if (!opened) 300 openlog(LogTag, LogStat | LOG_NDELAY, 0); 301 connectlog(); 302 if (send(LogFile, tbuf, cnt, 0) >= 0) 303 return; 304 305 /* 306 * If the send() failed, the odds are syslogd was restarted. 307 * Make one (only) attempt to reconnect to /dev/log. 308 */ 309 disconnectlog(); 310 connectlog(); 311 if (send(LogFile, tbuf, cnt, 0) >= 0) 312 return; 244 313 245 314 /* 246 * Output the message to the console; don't worry about blocking, 247 * if console blocks everything will. Make sure the error reported 248 *is the one from the syslogd failure.315 * Output the message to the console; try not to block 316 * as a blocking console should not stop other processes. 317 * Make sure the error reported is the one from the syslogd failure. 249 318 */ 250 319 if (LogStat & LOG_CONS && 251 (fd = open(_PATH_CONSOLE, O_WRONLY, 0)) >= 0) { 252 (void)strcat(tbuf, "\r\n"); 253 cnt += 2; 320 #ifndef __EMX__ 321 (fd = _open(_PATH_CONSOLE, O_WRONLY|O_NONBLOCK, 0)) >= 0) { 322 #else 323 (fd = _open(_PATH_CONSOLE, O_WRONLY/*|O_NONBLOCK*/, 0)) >= 0) { 324 #endif 325 326 struct iovec iov[2]; 327 struct iovec *v = iov; 328 254 329 p = strchr(tbuf, '>') + 1; 255 (void)write(fd, p, cnt - (p - tbuf)); 256 (void)close(fd); 330 v->iov_base = p; 331 v->iov_len = cnt - (p - tbuf); 332 ++v; 333 v->iov_base = "\r\n"; 334 v->iov_len = 2; 335 (void)_writev(fd, iov, 2); 336 (void)_close(fd); 257 337 } 258 259 done: 260 #if !USESNPRINTF 261 /* 262 * If we had a buffer overrun, log a panic and abort. 263 * We can't return because our stack is probably toast. 264 */ 265 if (panic) { 266 syslog(LOG_EMERG, "SYSLOG BUFFER OVERRUN -- EXITING"); 267 abort(); 268 } 269 #endif 270 } 271 272 #ifdef __EMX__ 273 static struct sockaddr_in SyslogAddr; /* AF_INET address of local logger */ 274 #else 275 static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */ 276 #endif 338 } 339 static void 340 disconnectlog() 341 { 342 /* 343 * If the user closed the FD and opened another in the same slot, 344 * that's their problem. They should close it before calling on 345 * system services. 346 */ 347 if (LogFile != -1) { 348 _close(LogFile); 349 LogFile = -1; 350 } 351 connected = 0; /* retry connect */ 352 } 353 354 static void 355 connectlog() 356 { 357 #ifndef __EMX__ 358 struct sockaddr_un SyslogAddr; /* AF_UNIX address of local logger */ 359 #else 360 struct sockaddr_in SyslogAddr; /* AF_INET address of local logger */ 361 #endif 362 363 if (LogFile == -1) { 364 #ifndef __EMX__ 365 if ((LogFile = _socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) 366 #else 367 if ((LogFile = _socket(AF_INET, SOCK_DGRAM, 0)) == -1) 368 #endif 369 return; 370 (void)_fcntl(LogFile, F_SETFD, 1); 371 } 372 if (LogFile != -1 && !connected) { 373 #ifndef __EMX__ 374 SyslogAddr.sun_len = sizeof(SyslogAddr); 375 SyslogAddr.sun_family = AF_UNIX; 376 (void)strncpy(SyslogAddr.sun_path, _PATH_LOG, 377 sizeof SyslogAddr.sun_path); 378 #else 379 memset(&SyslogAddr, 0, sizeof(SyslogAddr)); 380 #ifndef TCPV40HDRS 381 SyslogAddr.sin_len = sizeof(SyslogAddr); 382 #endif 383 SyslogAddr.sin_family = AF_INET; 384 SyslogAddr.sin_port = htons(514); 385 SyslogAddr.sin_addr.s_addr = INADDR_ANY; 386 #endif 387 connected = _connect(LogFile, (struct sockaddr *)&SyslogAddr, 388 sizeof(SyslogAddr)) != -1; 389 390 #ifndef __EMX__ 391 if (!connected) { 392 /* 393 * Try the old "/dev/log" path, for backward 394 * compatibility. 395 */ 396 (void)strncpy(SyslogAddr.sun_path, _PATH_OLDLOG, 397 sizeof SyslogAddr.sun_path); 398 connected = _connect(LogFile, 399 (struct sockaddr *)&SyslogAddr, 400 sizeof(SyslogAddr)) != -1; 401 } 402 #endif 403 404 if (!connected) { 405 (void)_close(LogFile); 406 LogFile = -1; 407 } 408 } 409 } 277 410 278 411 void … … 281 414 int logstat, logfac; 282 415 { 283 if (ident != NULL) 284 LogTag = ident; 285 LogStat = logstat; 286 if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) 287 LogFacility = logfac; 288 289 if (LogFile == -1) { 290 #ifdef __EMX__ 291 memset(&SyslogAddr, 0, sizeof(SyslogAddr)); 292 SyslogAddr.sin_len = sizeof(SyslogAddr); 293 SyslogAddr.sin_family = AF_INET; 294 SyslogAddr.sin_port = htons(514); 295 SyslogAddr.sin_addr.s_addr = INADDR_ANY; 296 #else 297 SyslogAddr.sa_family = AF_UNIX; 298 (void)strncpy(SyslogAddr.sa_data, _PATH_LOG, 299 sizeof(SyslogAddr.sa_data)); 300 #endif 301 if (LogStat & LOG_NDELAY) { 302 #ifdef __EMX__ 303 if ((LogFile = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 304 #else 305 if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) 306 #endif 307 return; 308 #ifndef __EMX__ 309 (void)fcntl(LogFile, F_SETFD, 1); 310 #endif 311 } 312 } 313 if (LogFile != -1 && !connected) 314 if (connect(LogFile, (struct sockaddr*) &SyslogAddr, sizeof(SyslogAddr)) == -1) { 315 (void)close(LogFile); 316 LogFile = -1; 317 } else 318 connected = 1; 416 if (ident != NULL) 417 LogTag = ident; 418 LogStat = logstat; 419 if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) 420 LogFacility = logfac; 421 422 if (LogStat & LOG_NDELAY) /* open immediately */ 423 connectlog(); 424 425 opened = 1; /* ident and facility has been set */ 319 426 } 320 427 … … 322 429 closelog() 323 430 { 324 (void)close(LogFile);431 (void)_close(LogFile); 325 432 LogFile = -1; 433 LogTag = NULL; 326 434 connected = 0; 327 435 } … … 339 447 return (omask); 340 448 } 341 -
Property cvs2svn:cvs-rev
changed from
Note:
See TracChangeset
for help on using the changeset viewer.