📄 syslog.c
字号:
#ifndef lintstatic char *sccsid = "@(#)syslog.c 4.4 ULTRIX 10/16/90";#endif lint# include <syslog.h># include <sys/types.h># include <sys/stat.h># include <sgtty.h># ifdef LOG_IPC# include <sys/socket.h>#ifdef LOG_OLDIPC# include <net/in.h>#else LOG_OLDIPC# include <netinet/in.h># include <netdb.h>#endif LOG_OLDIPC# endif LOG_IPC/*static char SccsId[] = "@(#)syslog.c 4.1 7/25/83";*//*** SYSLOG -- print message on log file**** This routine looks a lot like printf, except that it** outputs to the log file instead of the standard output.** Also, it prints the module name in front of lines,** and has some other formatting types (or will sometime).** Also, it adds a newline on the end of messages.**** The output of this routine is intended to be read by** /etc/syslog, which will add timestamps.**** Parameters:** pri -- the message priority.** fmt -- the format string.** p0 -- the first of many parameters.**** Returns:** none**** Side Effects:** output to log.** EDIT HISTORY** 2-Jul-86 marc * Changes in openlog().*** Many programs which uses syslog run as daemons, and in* particular they have no process group (pgrp == 0) and* are not associated with a controlling terminal (e.g.* inetd, init, etc...). Normally, when syslog opens a* connection to the syslog daemon, this is no problem.* However, if the loopback driver is not installed, or if* syslog can't create a connection to the syslog daemon* for any reason, then syslog opens /dev/console. This* causes BIG problems, because those processes which had* no process group are now set to the process group of* /dev/console. Many wonderfully strange and nasty* things begin to happen: whenever someone logs out, the* console shell logs out too; the inetd daemon dies after* someone r'logs out of your system; and so on. The fix* (which you could call a kludge - i wouldn't argue) is* to temporarily set process groups to something* non-zero, do the open, and immedietly set back to* zero. We choose process group 2. This is the process* id of the pagedaemon and I've found that the pagedaemon* ignores any signals sent to it. This is besides the* point because the pagedaemon has no process group, process* group 2 is unused, no one has any business sending signals* to process group 2 anway. The old method employed by* programs wanting to preserve their 0-process group id* and no controlling tty, and wishing to open a tty for* writing, was to do the open (and temporarily recieve a* controlling terminal), write the message, and then do a* TIOCNOTTY on /dev/tty. This leaves a window where the* process could have recieved a signal generated by the* keyboard. I like switching process groups because* there is no window. It works perfectly, its just kind* of twisted. ANYWAY... thats why you see the setpgrp()* code in openlog()...** */# define MAXLINE 4096 /* maximum line length */# define BUFSLOP 20 /* space to allow for "extra stuff" */# define NULL 0 /* manifest */int LogFile = -1; /* fd for log */int LogStat = 0; /* status bits, set by initlog */char *LogTag = NULL; /* string to tag the entry with */int LogMask = LOG_DEBUG; /* lowest priority to be logged *//* Use local lookups, to reduce on-disk image sizes. The lookups are for * "localhost" and syslog port 514, and are always locally present. */struct servent* getservbyname_local();struct hostent* gethostbyname_local();#define getservbyname(s,p) getservbyname_local(s,p)#define gethostbyname(h) gethostbyname_local(h)# ifdef LOG_IPC#ifndef LOG_OLDIPCstruct sockaddr_in SyslogAddr;#else LOG_OLDIPCstruct sockaddr_in SyslogAddr = { AF_INET, LOG_PORT };struct sockproto SyslogProto = { PF_INET, IPPROTO_UDP };#endif LOG_OLDIPCstatic char *SyslogHost = LOG_HOST;# endif LOG_IPCsyslog(pri, fmt, p0, p1, p2, p3, p4) int pri; char *fmt;{ char buf[MAXLINE+BUFSLOP]; register char *b; char *f; register char c; register char *p; extern int errno; extern int sys_nerr; extern char *sys_errlist[]; extern char *logcvt(); char outline[MAXLINE + 1]; /* if we have no log, open it */ if (LogFile < 0) openlog(0, 0); /* see if we should just throw out this message */ if (pri > LogMask) return; f = fmt; while (*f != '\0') { /* beginning of line */ b = buf; /* insert priority code */ if (pri > 0 && (LogStat & LOG_COOLIT) == 0) { *b++ = '<'; *b++ = pri + '0'; *b++ = '>'; } /* output current process ID */ if ((LogStat & LOG_PID) != 0) { sprintf(b, "%d ", getpid()); b += strlen(b); } /* and module name */ if (LogTag != 0) { for (p = LogTag; *p != '\0'; ) *b++ = *p++; *b++ = ':'; *b++ = ' '; } while ((c = *f++) != '\0' && c != '\n') { /* output character directly if not interpolated */ if (c != '%') { *b++ = c; continue; } c = *f++; switch (c) { case 'm': /* output error code */ if (errno < 0 || errno > sys_nerr) sprintf(b, "error %d", errno); else sprintf(b, "%s", sys_errlist[errno]); b += strlen(b); break; default: *b++ = '%'; *b++ = c; break; } if (b >= &buf[MAXLINE]) break; } if (c == '\0') f--; /* add trailing newline */ *b++ = '\n'; *b = '\0'; /* output string */ sprintf(outline, buf, p0, p1, p2, p3, p4);# ifdef LOG_IPC if (LogStat & LOG_DGRAM) { register int r;#ifndef LOG_OLDIPC r = sendto(LogFile, outline, strlen(outline), 0, &SyslogAddr, sizeof SyslogAddr);#else LOG_OLDIPC r = send(LogFile, &SyslogAddr, outline, strlen(outline));#endif LOG_OLDIPC# ifdef EBUG if (r < 0) perror("syslog: send");# endif EBUG } else# endif LOG_IPC write(LogFile, outline, strlen(outline)); }}/*** OPENLOG -- open system log**** This happens automatically with reasonable defaults if you** do nothing.**** Parameters:** ident -- the name to be printed as a header for** all messages.** logstat -- a status word, interpreted as follows:** LOG_PID -- log the pid with each message.**** Returns:** 0 -- success.** -1 -- failure; logging on /dev/console instead.**** Side Effects:** Several global variables get set.**** EDIT HISTORY:** marc 2-Jul-86 -- see note at beginning of file*/openlog(ident, logstat) char *ident; int logstat;{ struct stat st; int pgrpwaszero = 0;#ifndef LOG_OLDIPC# ifdef LOG_IPC struct servent *sp; struct hostent *hp;# endif LOG_IPC#endif LOG_OLDIPC LogTag = ident; LogStat = logstat; if (LogFile >= 0) return;# ifdef LOG_IPC#ifndef LOG_OLDIPC sp = getservbyname("syslog", "udp"); hp = gethostbyname(SyslogHost); if (sp != NULL && hp != NULL) { bzero(&SyslogAddr, sizeof SyslogAddr); SyslogAddr.sin_family = AF_INET; LogFile = socket(AF_INET, SOCK_DGRAM, 0, 0); if (LogFile >= 0 && bind(LogFile, &SyslogAddr, sizeof SyslogAddr, 0) < 0) { close(LogFile); LogFile = -1; }# ifdef EBUG if (LogFile < 0) perror("syslog: socket");# endif EBUG SyslogAddr.sin_port = sp->s_port; bcopy(hp->h_addr, (char *) &SyslogAddr.sin_addr, hp->h_length); LogStat |= LOG_DGRAM; }#else LOG_OLDIPC SyslogAddr.sin_addr.s_addr = rhost(&SyslogHost); LogFile = socket(SOCK_DGRAM, &SyslogProto, 0, 0);# ifdef EBUG if (LogFile < 0) perror("syslog: socket");# endif EBUG LogStat |= LOG_DGRAM;#endif LOG_OLDIPC# else LOG_IPC LogFile = open("/dev/log", 1);# endif LOG_IPC if (LogFile < 0) { nolog: LogStat |= LOG_COOLIT; LogStat &= ~LOG_DGRAM; LogMask = LOG_CRIT;# ifdef EBUG LogFile = -1;# else EBUG /* * If the process group is zero, temporarily set it to * two. This prevents a controlling terminal from being * established when opening /dev/console. - marc */ if (!getpgrp(0)) { pgrpwaszero=1; setpgrp(0,2); } LogFile = open("/dev/console", 1); if (pgrpwaszero) setpgrp(0,0); /* set it back */# endif EBUG if (LogFile < 0) { perror("Cannot open /dev/console"); LogFile = 2; } }# ifndef LOG_IPC if (fstat(LogFile, &st) < 0) goto nolog; switch (st.st_mode & S_IFMT) { case S_IFREG: case S_IFDIR: (void) close(LogFile); goto nolog; }# ifdef FIOCLEX /* have it close automatically on exec */ ioctl(LogFile, FIOCLEX, NULL);# endif FIOCLEX# endif LOG_IPC}/*** CLOSELOG -- close the system log**** Parameters:** none.**** Returns:** none.**** Side Effects:** The system log is closed.*/closelog(){ (void) close(LogFile); LogFile = -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -