📄 syslogd.c
字号:
static void logMessage (int pri, char *msg){ time_t now; char *timestamp; static char res[20] = ""; CODE *c_pri, *c_fac; if (pri != 0) { for (c_fac = facilitynames; c_fac->c_name && !(c_fac->c_val == LOG_FAC(pri) << 3); c_fac++); for (c_pri = prioritynames; c_pri->c_name && !(c_pri->c_val == LOG_PRI(pri)); c_pri++); if (c_fac->c_name == NULL || c_pri->c_name == NULL) snprintf(res, sizeof(res), "<%d>", pri); else snprintf(res, sizeof(res), "%s.%s", c_fac->c_name, c_pri->c_name); } if (strlen(msg) < 16 || msg[3] != ' ' || msg[6] != ' ' || msg[9] != ':' || msg[12] != ':' || msg[15] != ' ') { time(&now); timestamp = ctime(&now) + 4; timestamp[15] = '\0'; } else { timestamp = msg; timestamp[15] = '\0'; msg += 16; } /* todo: supress duplicates */#ifdef BB_FEATURE_REMOTE_LOG /* send message to remote logger */ if ( -1 != remotefd){static const int IOV_COUNT = 2; struct iovec iov[IOV_COUNT]; struct iovec *v = iov; memset(&res, 0, sizeof(res)); snprintf(res, sizeof(res), "<%d>", pri); v->iov_base = res ; v->iov_len = strlen(res); v++; v->iov_base = msg; v->iov_len = strlen(msg);writev_retry: if ( -1 == writev(remotefd,iov, IOV_COUNT)){ if (errno == EINTR) goto writev_retry; error_msg_and_die("cannot write to remote file handle on" "%s:%d",RemoteHost,RemotePort); } } if (local_logging == TRUE)#endif /* now spew out the message to wherever it is supposed to go */ message("%s %s %s %s\n", timestamp, LocalHostName, res, msg);}static void quit_signal(int sig){ logMessage(LOG_SYSLOG | LOG_INFO, "System log daemon exiting."); unlink(lfile);#ifdef BB_FEATURE_IPC_SYSLOG ipcsyslog_cleanup();#endif exit(TRUE);}static void domark(int sig){ if (MarkInterval > 0) { logMessage(LOG_SYSLOG | LOG_INFO, "-- MARK --"); alarm(MarkInterval); }}/* This must be a #define, since when DODEBUG and BUFFERS_GO_IN_BSS are * enabled, we otherwise get a "storage size isn't constant error. */static int serveConnection (char* tmpbuf, int n_read){ char *p = tmpbuf; while (p < tmpbuf + n_read) { int pri = (LOG_USER | LOG_NOTICE); char line[ MAXLINE + 1 ]; unsigned char c; char *q = line; while ( (c = *p) && q < &line[ sizeof (line) - 1 ]) { if (c == '<') { /* Parse the magic priority number. */ pri = 0; while (isdigit (*(++p))) { pri = 10 * pri + (*p - '0'); } if (pri & ~(LOG_FACMASK | LOG_PRIMASK)){ pri = (LOG_USER | LOG_NOTICE); } } else if (c == '\n') { *q++ = ' '; } else if (iscntrl (c) && (c < 0177)) { *q++ = '^'; *q++ = c ^ 0100; } else { *q++ = c; } p++; } *q = '\0'; p++; /* Now log it */ logMessage (pri, line); } return n_read;}#ifdef BB_FEATURE_REMOTE_LOGstatic void init_RemoteLog (void){ struct sockaddr_in remoteaddr; struct hostent *hostinfo; int len = sizeof(remoteaddr); memset(&remoteaddr, 0, len); remotefd = socket(AF_INET, SOCK_DGRAM, 0); if (remotefd < 0) { error_msg_and_die("cannot create socket"); } hostinfo = xgethostbyname(RemoteHost); remoteaddr.sin_family = AF_INET; remoteaddr.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list; remoteaddr.sin_port = htons(RemotePort); /* Since we are using UDP sockets, connect just sets the default host and port for future operations */ if ( 0 != (connect(remotefd, (struct sockaddr *) &remoteaddr, len))){ error_msg_and_die("cannot connect to remote host %s:%d", RemoteHost, RemotePort); }}#endifstatic void doSyslogd (void) __attribute__ ((noreturn));static void doSyslogd (void){ struct sockaddr_un sunx; socklen_t addrLength; int sock_fd; fd_set fds; /* Set up signal handlers. */ signal (SIGINT, quit_signal); signal (SIGTERM, quit_signal); signal (SIGQUIT, quit_signal); signal (SIGHUP, SIG_IGN); signal (SIGCHLD, SIG_IGN);#ifdef SIGCLD signal (SIGCLD, SIG_IGN);#endif signal (SIGALRM, domark); alarm (MarkInterval); /* Create the syslog file so realpath() can work. */ if (realpath (_PATH_LOG, lfile) != NULL) unlink (lfile); memset (&sunx, 0, sizeof (sunx)); sunx.sun_family = AF_UNIX; strncpy (sunx.sun_path, lfile, sizeof (sunx.sun_path)); if ((sock_fd = socket (AF_UNIX, SOCK_DGRAM, 0)) < 0) perror_msg_and_die ("Couldn't get file descriptor for socket " _PATH_LOG); addrLength = sizeof (sunx.sun_family) + strlen (sunx.sun_path); if (bind(sock_fd, (struct sockaddr *) &sunx, addrLength) < 0) perror_msg_and_die ("Could not connect to socket " _PATH_LOG); if (chmod (lfile, 0666) < 0) perror_msg_and_die ("Could not set permission on " _PATH_LOG);#ifdef BB_FEATURE_IPC_SYSLOG if (circular_logging == TRUE ){ ipcsyslog_init(); }#endif#ifdef BB_FEATURE_REMOTE_LOG if (doRemoteLog == TRUE){ init_RemoteLog(); }#endif logMessage (LOG_SYSLOG | LOG_INFO, "syslogd started: " BB_BANNER); for (;;) { FD_ZERO (&fds); FD_SET (sock_fd, &fds); if (select (sock_fd+1, &fds, NULL, NULL, NULL) < 0) { if (errno == EINTR) { /* alarm may have happened. */ continue; } perror_msg_and_die ("select error"); } if (FD_ISSET (sock_fd, &fds)) { int i; RESERVE_BB_BUFFER(tmpbuf, BUFSIZ + 1); memset(tmpbuf, '\0', BUFSIZ+1); if ( (i = recv(sock_fd, tmpbuf, BUFSIZ, 0)) > 0) { serveConnection(tmpbuf, i); } else { perror_msg_and_die ("UNIX socket error"); } RELEASE_BB_BUFFER (tmpbuf); }/* FD_ISSET() */ } /* for main loop */}extern int syslogd_main(int argc, char **argv){ int opt;#if ! defined(__uClinux__) int doFork = TRUE;#endif char *p; /* do normal option parsing */ while ((opt = getopt(argc, argv, "m:nO:R:LC")) > 0) { switch (opt) { case 'm': MarkInterval = atoi(optarg) * 60; break;#if ! defined(__uClinux__) case 'n': doFork = FALSE; break;#endif case 'O': logFilePath = xstrdup(optarg); break;#ifdef BB_FEATURE_REMOTE_LOG case 'R': RemoteHost = xstrdup(optarg); if ( (p = strchr(RemoteHost, ':'))){ RemotePort = atoi(p+1); *p = '\0'; } doRemoteLog = TRUE; break; case 'L': local_logging = TRUE; break;#endif#ifdef BB_FEATURE_IPC_SYSLOG case 'C': circular_logging = TRUE; break;#endif default: show_usage(); } }#ifdef BB_FEATURE_REMOTE_LOG /* If they have not specified remote logging, then log locally */ if (doRemoteLog == FALSE) local_logging = TRUE;#endif /* Store away localhost's name before the fork */ gethostname(LocalHostName, sizeof(LocalHostName)); if ((p = strchr(LocalHostName, '.'))) { *p++ = '\0'; } umask(0);#if ! defined(__uClinux__) if (doFork == TRUE) { if (daemon(0, 1) < 0) perror_msg_and_die("daemon"); }#endif doSyslogd(); return EXIT_SUCCESS;}/*Local Variablesc-file-style: "linux"c-basic-offset: 4tab-width: 4End:*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -