⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 syslogd.c

📁 linux下记录系统日志代码以及记录内核日志代码
💻 C
📖 第 1 页 / 共 5 页
字号:
#include <arpa/inet.h>#include <resolv.h>#ifndef TESTING#include "pidfile.h"#endif#include "version.h"#if defined(__linux__)#include <paths.h>#endif#ifndef UTMP_FILE#ifdef UTMP_FILENAME#define UTMP_FILE UTMP_FILENAME#else#ifdef _PATH_UTMP#define UTMP_FILE _PATH_UTMP#else#define UTMP_FILE "/etc/utmp"#endif#endif#endif#ifndef _PATH_LOGCONF #define _PATH_LOGCONF	"/etc/syslog.conf"#endif#if defined(SYSLOGD_PIDNAME)#undef _PATH_LOGPID#if defined(FSSTND)#define _PATH_LOGPID _PATH_VARRUN SYSLOGD_PIDNAME#else#define _PATH_LOGPID "/etc/" SYSLOGD_PIDNAME#endif#else#ifndef _PATH_LOGPID#if defined(FSSTND)#define _PATH_LOGPID _PATH_VARRUN "syslogd.pid"#else#define _PATH_LOGPID "/etc/syslogd.pid"#endif#endif#endif#ifndef _PATH_DEV#define _PATH_DEV	"/dev/"#endif#ifndef _PATH_CONSOLE#define _PATH_CONSOLE	"/dev/console"#endif#ifndef _PATH_TTY#define _PATH_TTY	"/dev/tty"#endif#ifndef _PATH_LOG#define _PATH_LOG	"/dev/log"#endifchar	*ConfFile = _PATH_LOGCONF;char	*PidFile = _PATH_LOGPID;char	ctty[] = _PATH_CONSOLE;char	**parts;int inetm = 0;static int debugging_on = 0;static int nlogs = -1;static int restart = 0;#define MAXFUNIX	20int nfunix = 1;char *funixn[MAXFUNIX] = { _PATH_LOG };int funix[MAXFUNIX] = { -1, };#ifdef UT_NAMESIZE# define UNAMESZ	UT_NAMESIZE	/* length of a login name */#else# define UNAMESZ	8	/* length of a login name */#endif#define MAXUNAMES	20	/* maximum number of user names */#define MAXFNAME	200	/* max file pathname length */#define INTERNAL_NOPRI	0x10	/* the "no priority" priority */#define TABLE_NOPRI	0	/* Value to indicate no priority in f_pmask */#define TABLE_ALLPRI    0xFF    /* Value to indicate all priorities in f_pmask */#define	LOG_MARK	LOG_MAKEPRI(LOG_NFACILITIES, 0)	/* mark "facility" *//* * 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 table contains plain text for h_errno errors used by the * net subsystem. */const char *sys_h_errlist[] = {    "No problem",						/* NETDB_SUCCESS */    "Authoritative answer: host not found",			/* HOST_NOT_FOUND */    "Non-authoritative answer: host not found, or serverfail",	/* TRY_AGAIN */    "Non recoverable errors",					/* NO_RECOVERY */    "Valid name, no data record of requested type",		/* NO_DATA */    "no address, look for MX record"				/* NO_ADDRESS */ };/* * This structure represents the files that will have log * copies printed. */struct filed {#ifndef SYSV	struct	filed *f_next;		/* next in linked list */#endif	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 {		char	f_uname[MAXUNAMES][UNAMESZ+1];		struct {			char	f_hname[MAXHOSTNAMELEN+1];			struct sockaddr_in	f_addr;		} f_forw;		/* forwarding address */		char	f_fname[MAXFNAME];	} f_un;	char	f_prevline[MAXSVLINE];		/* last message logged */	char	f_lasttime[16];			/* time of last occurrence */	char	f_prevhost[MAXHOSTNAMELEN+1];	/* 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 */	int	f_repeatcount;			/* number of "repeated" msgs */	int	f_flags;			/* store some additional flags */};/* * 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 };	/* # of secs 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; \			}#ifdef SYSLOG_INET#define INET_SUSPEND_TIME 180		/* equal to 3 minutes */#define INET_RETRY_MAX 10		/* maximum of retries for gethostbyname() */#endif#define LIST_DELIMITER	':'		/* delimiter between two hosts *//* 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 */char	*TypeNames[] = {	"UNUSED",	"FILE",		"TTY",		"CONSOLE",	"FORW",		"USERS",	"WALL",		"FORW(SUSPENDED)",	"FORW(UNKNOWN)", "PIPE"};struct	filed *Files = (struct filed *) 0;struct	filed consfile;struct code {	char	*c_name;	int	c_val;};struct code	PriNames[] = {	{"alert",	LOG_ALERT},	{"crit",	LOG_CRIT},	{"debug",	LOG_DEBUG},	{"emerg",	LOG_EMERG},	{"err",		LOG_ERR},	{"error",	LOG_ERR},		/* DEPRECATED */	{"info",	LOG_INFO},	{"none",	INTERNAL_NOPRI},	/* INTERNAL */	{"notice",	LOG_NOTICE},	{"panic",	LOG_EMERG},		/* DEPRECATED */	{"warn",	LOG_WARNING},		/* DEPRECATED */	{"warning",	LOG_WARNING},	{"*",		TABLE_ALLPRI},	{NULL,		-1}};struct code	FacNames[] = {	{"auth",         LOG_AUTH},	{"authpriv",     LOG_AUTHPRIV},	{"cron",         LOG_CRON},	{"daemon",       LOG_DAEMON},	{"kern",         LOG_KERN},	{"lpr",          LOG_LPR},	{"mail",         LOG_MAIL},	{"mark",         LOG_MARK},		/* INTERNAL */	{"news",         LOG_NEWS},	{"security",     LOG_AUTH},		/* DEPRECATED */	{"syslog",       LOG_SYSLOG},	{"user",         LOG_USER},	{"uucp",         LOG_UUCP},#if defined(LOG_FTP)	{"ftp",          LOG_FTP},#endif	{"local0",       LOG_LOCAL0},	{"local1",       LOG_LOCAL1},	{"local2",       LOG_LOCAL2},	{"local3",       LOG_LOCAL3},	{"local4",       LOG_LOCAL4},	{"local5",       LOG_LOCAL5},	{"local6",       LOG_LOCAL6},	{"local7",       LOG_LOCAL7},	{NULL,           -1},};int	Debug;			/* debug flag */char	LocalHostName[MAXHOSTNAMELEN+1];	/* our hostname */char	*LocalDomain;		/* our local domain name */int	InetInuse = 0;		/* non-zero if INET sockets are being used */int	finet = -1;		/* Internet datagram socket */int	LogPort;		/* port number for INET connections */int	Initialized = 0;	/* set when we have initialized ourselves */int	MarkInterval = 20 * 60;	/* interval between marks in seconds */int	MarkSeq = 0;		/* mark sequence number */int	NoFork = 0; 		/* don't fork - don't run in daemon mode */int	AcceptRemote = 0;	/* receive messages that come via UDP */char	**StripDomains = NULL;	/* these domains may be stripped before writing logs */char	**LocalHosts = NULL;	/* these hosts are logged with their hostname */int	NoHops = 1;		/* Can we bounce syslog messages through an				   intermediate host. */extern	int errno;/* Function prototypes. */int main(int argc, char **argv);char **crunch_list(char *list);int usage(void);void untty(void);void printchopped(const char *hname, char *msg, int len, int fd);void printline(const char *hname, char *msg);void printsys(char *msg);void logmsg(int pri, char *msg, const char *from, int flags);void fprintlog(register struct filed *f, char *from, int flags, char *msg);void endtty();void wallmsg(register struct filed *f, struct iovec *iov);void reapchild();const char *cvthname(struct sockaddr_in *f);void domark();void debug_switch();void logerror(char *type);void die(int sig);#ifndef TESTINGvoid doexit(int sig);#endifvoid init();void cfline(char *line, register struct filed *f);int decode(char *name, struct code *codetab);#if defined(__GLIBC__)#define dprintf mydprintf#endif /* __GLIBC__ */static void dprintf(char *, ...);static void allocate_log(void);void sighup_handler();#ifdef SYSLOG_UNIXAFstatic int create_unix_socket(const char *path);#endif#ifdef SYSLOG_INETstatic int create_inet_socket();#endifint main(argc, argv)	int argc;	char **argv;{	register int i;	register char *p;#if !defined(__GLIBC__)	int len, num_fds;#else /* __GLIBC__ */#ifndef TESTING	size_t len;#endif	int num_fds;#endif /* __GLIBC__ */	/*	 * It took me quite some time to figure out how this is	 * supposed to work so I guess I should better write it down.	 * unixm is a list of file descriptors from which one can	 * read().  This is in contrary to readfds which is a list of	 * file descriptors where activity is monitored by select()	 * and from which one cannot read().  -Joey	 *	 * Changed: unixm is gone, since we now use datagram unix sockets.	 * Hence we recv() from unix sockets directly (rather than	 * first accept()ing connections on them), so there's no need	 * for separate book-keeping.  --okir	 */	fd_set readfds;#ifndef TESTING	int	fd;#ifdef  SYSLOG_INET	struct sockaddr_in frominet;	char *from;#endif	pid_t ppid = getpid();#endif	int ch;	struct hostent *hent;	char line[MAXLINE +1];	extern int optind;	extern char *optarg;	int maxfds;#ifndef TESTING	chdir ("/");#endif	for (i = 1; i < MAXFUNIX; i++) {		funixn[i] = "";		funix[i]  = -1;	}	while ((ch = getopt(argc, argv, "a:dhf:l:m:np:rs:v")) != EOF)		switch((char)ch) {		case 'a':			if (nfunix < MAXFUNIX)				funixn[nfunix++] = optarg;			else				fprintf(stderr, "Out of descriptors, ignoring %s\n", optarg);			break;		case 'd':		/* debug */			Debug = 1;			break;		case 'f':		/* configuration file */			ConfFile = optarg;			break;		case 'h':			NoHops = 0;			break;		case 'l':			if (LocalHosts) {				fprintf (stderr, "Only one -l argument allowed," \					"the first one is taken.\n");				break;			}			LocalHosts = crunch_list(optarg);			break;		case 'm':		/* mark interval */			MarkInterval = atoi(optarg) * 60;			break;		case 'n':		/* don't fork */			NoFork = 1;			break;		case 'p':		/* path to regular log socket */			funixn[0] = optarg;			break;		case 'r':		/* accept remote messages */			AcceptRemote = 1;			break;		case 's':			if (StripDomains) {				fprintf (stderr, "Only one -s argument allowed," \					"the first one is taken.\n");				break;			}			StripDomains = crunch_list(optarg);			break;		case 'v':			printf("syslogd %s.%s\n", VERSION, PATCHLEVEL);			exit (0);		case '?':		default:			usage();		}	if ((argc -= optind))		usage();#ifndef TESTING	if ( !(Debug || NoFork) )	{		dprintf("Checking pidfile.\n");		if (!check_pid(PidFile))		{			if (fork()) {				/*				 * Parent process				 */				signal (SIGTERM, doexit);				sleep(300);				/*				 * Not reached unless something major went wrong.  5				 * minutes should be a fair amount of time to wait.				 * Please note that this procedure is important since				 * the father must not exit before syslogd isn't				 * initialized or the klogd won't be able to flush its				 * logs.  -Joey				 */				exit(1);			}			num_fds = getdtablesize();			for (i= 0; i < num_fds; i++)				(void) close(i);			untty();		}		else		{			fputs("syslogd: Already running.\n", stderr);			exit(1);		}	}	else#endif		debugging_on = 1;#ifndef SYSV	else		setlinebuf(stdout);#endif#ifndef TESTING	/* tuck my process id away */	if ( !Debug )	{		dprintf("Writing pidfile.\n");		if (!check_pid(PidFile))		{			if (!write_pid(PidFile))			{				dprintf("Can't write pid.\n");				exit(1);			}		}		else		{			dprintf("Pidfile (and pid) already exist.\n");			exit(1);		}	} /* if ( !Debug ) */#endif	consfile.f_type = F_CONSOLE;	(void) strcpy(consfile.f_un.f_fname, ctty);	(void) gethostname(LocalHostName, sizeof(LocalHostName));	if ( (p = strchr(LocalHostName, '.')) ) {		*p++ = '\0';		LocalDomain = p;	}	else	{		LocalDomain = "";		/*		 * It's not clearly defined whether gethostname()		 * should return the simple hostname or the fqdn. A		 * good piece of software should be aware of both and		 * we want to distribute good software.  Joey		 *		 * Good software also always checks its return values...		 * If syslogd starts up before DNS is up & /etc/hosts		 * doesn't have LocalHostName listed, gethostbyname will		 * return NULL. 		 */		hent = gethostbyname(LocalHostName);		if ( hent )			snprintf(LocalHostName, sizeof(LocalHostName), "%s", hent->h_name);					if ( (p = strchr(LocalHostName, '.')) )		{			*p++ = '\0';			LocalDomain = p;		}	}	/*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -