📄 syslogd.c
字号:
/* syslogd - log system messages * * Copyright (c) 1983, 1988, 1993, 1994, 2002 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#if 0static char sccsid[] = "@(#)syslogd.c 8.3 (Berkeley) 4/4/94";#endif/* * syslogd -- log system messages * * This program implements a system log. It takes a series of lines. * Each line may have a priority, signified as "<n>" as the first * characters of the line. If this is not present, a default priority * is used. * * To kill syslogd, send a signal 15 (terminate). A signal 1 (hup) * will cause it to reread its configuration file. * * Defined Constants: * * MAXLINE -- the maximum line length that can be handled. * DEFUPRI -- the default priority for user messages * DEFSPRI -- the default priority for kernel messages * * Author: Eric Allman * extensive changes by Ralph Campbell * more extensive changes by Eric Allman (again) */#ifdef HAVE_CONFIG_H#include <config.h>#endif#define IOVCNT 6 /* size of the iovec array */#define MAXLINE 1024 /* Maximum line length. */#define MAXSVLINE 240 /* Maximum saved line length. */#define DEFUPRI (LOG_USER|LOG_NOTICE)#define DEFSPRI (LOG_KERN|LOG_CRIT)#define TIMERINTVL 30 /* Interval for checking flush, mark. */#define TTYMSGTIME 10 /* Time out passed to ttymsg. */#include <sys/param.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <sys/wait.h>#include <sys/socket.h>#include <sys/uio.h>#include <sys/un.h>#ifdef TIME_WITH_SYS_TIME# include <sys/time.h># include <time.h>#else# ifdef HAVE_SYS_TIME_H# include <sys/time.h># else# include <time.h># endif#endif#include <sys/resource.h>#include <poll.h>#ifdef HAVE_SYS_TYPES_H# include <sys/types.h>#endif#include <netinet/in.h>#include <netdb.h>#include <arpa/inet.h>#include <ctype.h>#include <errno.h>#include <fcntl.h>#include <setjmp.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <getopt.h>#ifdef HAVE_UTMP_H# include <utmp.h>#endif#ifdef UTMPX# ifdef HAVE_UTMPX_H# include <utmpx.h># endiftypedef struct utmpx UTMP;# define SETUTENT() setutxent()# define GETUTENT() getutxent()# define ENDUTENT() endutxent()#elsetypedef struct utmp UTMP;# define SETUTENT() setutent()# define GETUTENT() getutent()# define ENDUTENT() endutent()#endif#ifdef HAVE_STDARG_H# include <stdarg.h>#else# include <varargs.h>#endif#define SYSLOG_NAMES#include <syslog.h>#ifndef HAVE_SYSLOG_INTERNAL# include <syslog-int.h>#endifconst char *ConfFile = PATH_LOGCONF; /* Default Configuration file. */const char *PidFile = PATH_LOGPID; /* Default path to tuck pid. */char ctty[] = PATH_CONSOLE; /* Default console to send message info. */static int dbg_output; /* If true, print debug output in debug mode. */static int restart; /* If 1, indicates SIGHUP was dropped. *//* Unix socket family to listen. */struct funix{ const char *name; int fd;} *funix;size_t nfunix; /* Number of unix sockets in the funix array. *//* * Flags to logmsg(). */#define IGN_CONS 0x001 /* Don't print on console. */#define SYNC_FILE 0x002 /* Do fsync on file after printing. */#define ADDDATE 0x004 /* Add a date to the message. */#define MARK 0x008 /* This message is a mark. *//* This structure represents the files that will have log copies printed. */struct filed{ struct filed *f_next; /* Next in linked list. */ short f_type; /* Entry type, see below. */ short f_file; /* File descriptor. */ time_t f_time; /* Time this was last written. */ u_char f_pmask[LOG_NFACILITIES+1]; /* Priority mask. */ union { struct { int f_nusers; char **f_unames; } f_user; /* Send a message to a user. */ struct { char *f_hname; struct sockaddr_in f_addr; } f_forw; /* Forwarding address. */ char *f_fname; /* Name use for Files|Pipes|TTYs. */ } f_un; char f_prevline[MAXSVLINE]; /* Last message logged. */ char f_lasttime[16]; /* Time of last occurrence. */ char *f_prevhost; /* Host from which recd. */ int f_prevpri; /* Pri of f_prevline. */ int f_prevlen; /* Length of f_prevline. */ int f_prevcount; /* Repetition cnt of prevline. */ size_t f_repeatcount; /* Number of "repeated" msgs. */ int f_flags; /* Additional flags see below. */};struct filed *Files; /* Linked list of files to log to. */struct filed consfile; /* Console `file'. *//* Values for f_type. */#define F_UNUSED 0 /* Unused entry. */#define F_FILE 1 /* Regular file. */#define F_TTY 2 /* Terminal. */#define F_CONSOLE 3 /* Console terminal. */#define F_FORW 4 /* Remote machine. */#define F_USERS 5 /* List of users. */#define F_WALL 6 /* Everyone logged on. */#define F_FORW_SUSP 7 /* Suspended host forwarding. */#define F_FORW_UNKN 8 /* Unknown host forwarding. */#define F_PIPE 9 /* Named pipe. */const char *TypeNames[] ={ "UNUSED", "FILE", "TTY", "CONSOLE", "FORW", "USERS", "WALL", "FORW(SUSPENDED)", "FORW(UNKNOWN)", "PIPE"};/* Flags in filed.f_flags. */#define OMIT_SYNC 0x001 /* Omit fsync after printing. *//* Constants for the F_FORW_UNKN retry feature. */#define INET_SUSPEND_TIME 180 /* Number of seconds between attempts. */#define INET_RETRY_MAX 10 /* Number of times to try gethostbyname(). *//* Intervals at which we flush out "message repeated" messages, in seconds after previous message is logged. After each flush, we move to the next interval until we reach the largest. */int repeatinterval[] = { 30, 60 }; /* Number of seconds before flush. */#define MAXREPEAT ((sizeof(repeatinterval) / sizeof(repeatinterval[0])) - 1)#define REPEATTIME(f) ((f)->f_time + repeatinterval[(f)->f_repeatcount])#define BACKOFF(f) { if (++(f)->f_repeatcount > MAXREPEAT) \ (f)->f_repeatcount = MAXREPEAT; \ }/* Delimiter in arguments to command line options `-s' and `-l'. */#define LIST_DELIMITER ':'char *LocalHostName; /* Our hostname. */char *LocalDomain; /* Our local domain name. */int finet = -1; /* Internet datagram socket fd. */int fklog = -1; /* Kernel log device fd. */int LogPort; /* Port number for INET connections. */int Initialized; /* True when we are initialized. */int MarkInterval = 20 * 60; /* Interval between marks in seconds. */int MarkSeq; /* Mark sequence number. */int Debug; /* True if in debug mode. */int AcceptRemote; /* Receive messages that come via UDP. */char **StripDomains; /* Domains to be stripped before logging. */char **LocalHosts; /* Hosts to be logged by their hostname. */int NoDetach; /* Don't run in background and detach from ctty. */int NoHops = 1; /* Bounce syslog messages for other hosts. */int NoKLog; /* Don't attempt to log kernel device. */int NoUnixAF; /* Don't listen to unix sockets. */int NoForward; /* Don't forward messages. */time_t now; /* Time use for mark and forward supending. */int force_sync; /* GNU/Linux behaviour to sync on every line. This off by default. Set to 1 to enable. */extern char *localhost __P ((void));extern int waitdaemon __P ((int nochdir, int noclose, int maxwait));extern char *__progname;void cfline __P ((const char *, struct filed *));const char *cvthname __P ((struct sockaddr_in *));int decode __P ((const char *, CODE *));void die __P ((int));void domark __P ((int));void fprintlog __P ((struct filed *, const char *, int, const char *));void init __P ((int));void logerror __P ((const char *));void logmsg __P ((int, const char *, const char *, int));void printline __P ((const char *, const char *));void printsys __P ((const char *));char *ttymsg __P ((struct iovec *, int, char *, int));static void usage __P ((int));void wallmsg __P ((struct filed *, struct iovec *));char **crunch_list __P ((char **oldlist, char *list));char *textpri __P ((int pri));void dbg_toggle __P ((int));static void dbg_printf __P ((const char *, ...));void trigger_restart __P ((int));static void add_funix __P ((const char *path));static int create_unix_socket __P ((const char *path));static int create_inet_socket __P ((void));static voidusage (int err){ if (err != 0) { fprintf (stderr, "Usage: %s [OPTION] ...\n", __progname); fprintf (stderr, "Try `%s --help' for more information.\n", __progname); } else { fprintf (stdout, "Usage: %s [OPTION] ...\n", __progname); puts ("Log system messages.\n\n\ -f, --rcfile=FILE Override configuration file (default: " PATH_LOGCONF ")\n\ --pidfile=FILE Override pidfile (default: " PATH_LOGPID ")\n\ -n, --no-detach Don't enter daemon mode\n\ -d, --debug Print debug information (implies -n)\n\ -p, --socket FILE Override default unix domain socket " PATH_LOG "\n\ -a SOCKET Add unix socket to listen to (up to 19)\n\ -r, --inet Receive remote messages via internet domain socket\n\ --no-unixaf Do not listen on unix domain sockets (overrides -a and -p)\n\ -S, --sync Force a file sync on every line");#ifdef PATH_KLOG puts ("\ --no-klog Do not listen to kernel log device " PATH_KLOG);#endif puts ("\ --no-forward Do not forward any messages (overrides -h)\n\ -h, --hop Forward messages from remote hosts\n\ -m, --mark=INTVL Specify timestamp interval in logs (0 for no timestamps)\n\ -l HOSTLIST Log hosts in HOSTLIST by their hostname\n\ -s DOMAINLIST List of domains which should be stripped from the FQDN\n\ of hosts before logging their name.\n\ --help Display this help and exit\n\ -V, --version Output version information and exit"); fprintf (stdout, "\nSubmit bug reports to %s.\n", PACKAGE_BUGREPORT); } exit (err);}static const char *short_options = "a:dhf:l:m:np:rs:VS";static struct option long_options[] ={ { "debug", no_argument, 0, 'd' }, { "rcfile", required_argument, 0, 'f' }, { "pidfile", required_argument, 0, 'P' }, { "hop", no_argument, 0, 'h' }, { "mark", required_argument, 0, 'm' }, { "no-detach", no_argument, 0, 'n' }, { "socket", required_argument, 0, 'p' }, { "inet", no_argument, 0, 'r' }, { "no-klog", no_argument, 0, 'K' }, { "no-forward", no_argument, 0, 'F' }, { "no-unixaf", no_argument, 0, 'U' }, { "sync", no_argument, 0, 'S' }, { "help", no_argument, 0, '&' }, { "version", no_argument, 0, 'V' },#if 0 /* Not sure about the long name. Maybe move into conffile even. */ { "", required_argument, 0, 'a' }, { "", required_argument, 0, 's' }, { "", required_argument, 0, 'l' },#endif { 0, 0, 0, 0 }};intmain (int argc, char *argv[]){ int option; size_t i; FILE *fp; char *p; char line[MAXLINE + 1]; char kline[MAXLINE + 1]; int kline_len = 0; pid_t ppid = 0; /* We run in debug mode and didn't fork. */ struct pollfd *fdarray; unsigned long nfds = 0;#ifndef HAVE___PROGNAME __progname = argv[0];#endif /* Initiliaze PATH_LOG as the first element of the unix sockets array. */ add_funix (PATH_LOG); while ((option = getopt_long (argc, argv, short_options, long_options, 0)) != EOF) { switch(option) { case 'a': /* Add to unix socket array. */ add_funix (optarg); break; case 'd': /* Debug mode. */ Debug = 1; NoDetach = 1; break; case 'f': /* Override the default config file. */ ConfFile = optarg; break; case 'h': /* Disable forwarding. */ NoHops = 0; break; case 'l': /* Add host to be log whithout the FQDN. */ LocalHosts = crunch_list (LocalHosts, optarg); break; case 'm': /* Set the timestamp interval mark. */ MarkInterval = atoi (optarg) * 60; break; case 'n': /* Don't run in background. */ NoDetach = 1; break; case 'p': /* Overide PATH_LOG name. */ funix[0].name = optarg; funix[0].fd = -1; break; case 'r': /* Enable remote message via inet socket. */ AcceptRemote = 1; break; case 's': /* List of domain names to strip. */ StripDomains = crunch_list (StripDomains, optarg); break; case 'P': /* Override pidfile. */ PidFile = optarg; break; case 'K': /* Disable kernel logging. */ NoKLog = 1; break; case 'F': /* Disable forwarding. */ NoForward = 1; break; case 'U': /* Disable unix sockets. */ NoUnixAF = 1; break; case 'S': /* Sync on every line. */ force_sync = 1; break; case '&': /* Usage. */ usage (0); /* Not reached. */ case 'V': /* Version. */ printf ("syslogd (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); exit (0); case '?': default: usage (1); /* Not reached. */ } } /* Bail out, wrong usage */ argc -= optind; if (argc != 0) usage (1); /* Daemonise, if not, set the buffering for line buffer. */ if (!NoDetach) { /* History: According to the GNU/Linux sysklogd ChangeLogs "Wed Feb 14 12:42:09 CST 1996: Dr. Wettstein Parent process of syslogd does not exit until child process has finished initialization process. This allows rc.* startup to pause until syslogd facility is up and operating." IMO, the GNU/Linux distributors should fix there booting sequence. But we still keep the approach. */ ppid = waitdaemon (0, 0, 30); if (ppid < 0) { fprintf (stderr, "%s: could not become daemon: %s\n", __progname, strerror (errno)); exit (1); } } else { dbg_output = 1; setvbuf (stdout, 0, _IOLBF, 0); } /* Get our hostname. */ LocalHostName = localhost (); if (LocalHostName == NULL) { fprintf (stderr, "%s: can't get local host name: %s\n", __progname, strerror (errno)); exit (2); } /* Get the domainname. */ p = strchr (LocalHostName, '.'); if (p != NULL) { *p++ = '\0'; LocalDomain = p; } else { struct hostent *host_ent;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -