syslog.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:5k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*
  2.  * Copyright (c) 1983, 1988 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that this notice is preserved and that due credit is given
  7.  * to the University of California at Berkeley. The name of the University
  8.  * may not be used to endorse or promote products derived from this
  9.  * software without specific prior written permission. This software
  10.  * is provided ``as is'' without express or implied warranty.
  11.  */
  12. #if defined(LIBC_SCCS) && !defined(lint)
  13. static char sccsid[] = "@(#)syslog.c 5.14 (Berkeley) 5/20/88";
  14. #endif /* LIBC_SCCS and not lint */
  15. /*
  16.  * SYSLOG -- print message on log file
  17.  *
  18.  * This routine looks a lot like printf, except that it
  19.  * outputs to the log file instead of the standard output.
  20.  * Also:
  21.  * adds a timestamp,
  22.  * prints the module name in front of the message,
  23.  * has some other formatting types (or will sometime),
  24.  * adds a newline on the end of the message.
  25.  *
  26.  * The output of this routine is intended to be read by /etc/syslogd.
  27.  *
  28.  * Author: Eric Allman
  29.  * Modified to use UNIX domain IPC by Ralph Campbell
  30.  * Modified for pthreads and made more POSIX-compliant by Greg Hudson
  31.  */
  32. #include <pthread.h>
  33. #include <sys/types.h>
  34. #include <sys/socket.h>
  35. #include <signal.h>
  36. #include <stdio.h>
  37. #include <stdarg.h>
  38. #include <string.h>
  39. #include <fcntl.h>
  40. #include <netdb.h>
  41. #include <unistd.h>
  42. #include <errno.h>
  43. #include <syslog.h>
  44. int socket();
  45. char *strerror(int); /* For systems that don't prototype it */
  46. #define MAXLINE 1024 /* max message size */
  47. #define PRIFAC(p) (((p) & LOG_FACMASK) >> 3)
  48. /* XXX should be in <syslog.h> */
  49. #define IMPORTANT  LOG_ERR
  50. static void basic_init(void);
  51. static char _log_name[] = "/dev/log";
  52. static char ctty[] = "/dev/console";
  53. static int LogFile = -1; /* fd for log */
  54. static int LogStat = 0; /* status bits, set by openlog() */
  55. static char *LogTag = "syslog"; /* string to tag the entry with */
  56. static int LogMask = 0xff; /* mask of priorities to be logged */
  57. static int LogFacility = LOG_USER; /* default facility code */
  58. static pthread_mutex_t basic_init_lock = PTHREAD_MUTEX_INITIALIZER;
  59. static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */
  60. static void basic_init()
  61. {
  62.     pthread_mutex_lock(&basic_init_lock);
  63.     if (LogFile < 0)
  64. openlog(LogTag, LogStat | LOG_NDELAY, 0);
  65.     pthread_mutex_unlock(&basic_init_lock);
  66. }
  67. void syslog(int pri, char *fmt, ...)
  68. {
  69. va_list args;
  70. va_start(args, fmt);
  71. vsyslog(pri, fmt, args);
  72. va_end(args);
  73. }
  74. void vsyslog(int pri, char *fmt, va_list args)
  75. {
  76. char buf[MAXLINE + 1], outline[MAXLINE + 1];
  77. register char *b, *f, *o;
  78. register int c;
  79. time_t now;
  80. int olderrno = errno, fd;
  81. /* Do a basic initialization if user didn't call openlog(). */
  82. if (LogFile < 0)
  83.     basic_init();
  84. /* see if we should just throw out this message */
  85. if ((unsigned) PRIFAC(pri) >= LOG_NFACILITIES ||
  86.     (LOG_MASK(pri & LOG_PRIMASK) & LogMask) == 0 ||
  87.     (pri &~ (LOG_PRIMASK|LOG_FACMASK)) != 0)
  88. return;
  89. /* set default facility if none specified */
  90. if ((pri & LOG_FACMASK) == 0)
  91. pri |= LogFacility;
  92. /* build the message */
  93. o = outline;
  94. (void)sprintf(o, "<%d>", pri);
  95. o += strlen(o);
  96. time(&now);
  97. (void)sprintf(o, "%.15s ", ctime(&now) + 4);
  98. o += strlen(o);
  99. if (LogTag) {
  100. strcpy(o, LogTag);
  101. o += strlen(o);
  102. }
  103. if (LogStat & LOG_PID) {
  104. (void)sprintf(o, "[%d]", getpid());
  105. o += strlen(o);
  106. }
  107. if (LogTag) {
  108. strcpy(o, ": ");
  109. o += 2;
  110. }
  111. b = buf;
  112. f = fmt;
  113. while ((c = *f++) != '' && c != 'n' && b < &buf[MAXLINE]) {
  114.         char *strerror();
  115. if (c != '%') {
  116. *b++ = c;
  117. continue;
  118. }
  119. if ((c = *f++) != 'm') {
  120. *b++ = '%';
  121. *b++ = c;
  122. continue;
  123. }
  124. strcpy(b, strerror(olderrno));
  125. b += strlen(b);
  126. }
  127. *b++ = 'n';
  128. *b = '';
  129. vsprintf(o, buf, args);
  130. c = strlen(outline);
  131. if (c > MAXLINE)
  132. c = MAXLINE;
  133. /* output the message to the local logger */
  134. if (sendto(LogFile, outline, c, 0, &SyslogAddr, sizeof SyslogAddr) >= 0)
  135. return;
  136. if (!(LogStat & LOG_CONS))
  137. return;
  138. /* output the message to the console */
  139. fd = open(ctty, O_WRONLY);
  140. alarm(0);
  141. strcat(o, "r");
  142. o = strchr(outline, '>') + 1;
  143. write(fd, o, c + 1 - (o - outline));
  144. close(fd);
  145. }
  146. /*
  147.  * OPENLOG -- open system log
  148.  */
  149. void openlog(char *ident, int logstat, int logfac)
  150. {
  151. int flags;
  152. if (ident != NULL)
  153. LogTag = ident;
  154. LogStat = logstat;
  155. if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
  156. LogFacility = logfac;
  157. if (LogFile >= 0)
  158. return;
  159. SyslogAddr.sa_family = AF_UNIX;
  160. strncpy(SyslogAddr.sa_data, _log_name, sizeof SyslogAddr.sa_data);
  161. if (LogStat & LOG_NDELAY) {
  162. LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
  163. flags = fcntl(LogFile, F_GETFD);
  164. fcntl(LogFile, F_SETFD, flags & O_NONBLOCK);
  165. }
  166. }
  167. /*
  168.  * CLOSELOG -- close the system log
  169.  */
  170. void closelog()
  171. {
  172. (void) close(LogFile);
  173. LogFile = -1;
  174. }
  175. /*
  176.  * SETLOGMASK -- set the log mask level
  177.  */
  178. int setlogmask(int pmask)
  179. {
  180. int omask;
  181. omask = LogMask;
  182. if (pmask != 0)
  183. LogMask = pmask;
  184. return (omask);
  185. }