metalog.c
字号:
fflush(output->fp); } return 0;}static int spawnCommand(const char * const command, const char * const date, const char * const prg, const char * const info){ struct stat st; if (command == NULL || *command == 0 || stat(command, &st) < 0 || !S_ISREG(st.st_mode)) { fprintf(stderr, "Unable to launch [%s]\n", command == NULL ? "null" : command); return -1; } command_child = fork(); if (command_child == (pid_t) 0) { execl(command, command, date, prg, info, NULL); _exit(EXIT_FAILURE); } else if (command_child != (pid_t) -1) { while (command_child != (pid_t) 0) { pause(); } } return 0;}static int processLogLine(const int logcode, const char * const date, const char * const prg, const char * const info){ ConfigBlock *block = config_blocks; const int facility = LOG_FAC(logcode); const int priority = LOG_PRI(logcode); int nb_regexes; int info_len; int ovector[16]; PCREInfo *pcre_info; info_len = strlen(info); while (block != NULL) { if (block->facilities != NULL) { int nb = block->nb_facilities; const int * const facilities = block->facilities; while (nb > 0) { nb--; if (facility == facilities[nb]) { goto facility_ok; } } goto nextblock; } facility_ok: if (priority > block->minimum) { goto nextblock; } if (block->program != NULL && strcasecmp(block->program, prg) != 0) { goto nextblock; } if ((nb_regexes = block->nb_regexes) > 0 && info_len > 0) { pcre_info = block->regexes; do { if (pcre_exec(pcre_info->pcre, pcre_info->pcre_extra, info, info_len, 0, 0, ovector, sizeof ovector / sizeof ovector[0]) >= 0) { goto regex_ok; } pcre_info++; nb_regexes--; } while (nb_regexes > 0); goto nextblock; } regex_ok: if (block->output != NULL) { writeLogLine(block->output, date, prg, info); } if (block->command != NULL) { spawnCommand(block->command, date, prg, info); } nextblock: block = block->next_block; } return 0;}static void sanitize(char * const line_){ register unsigned char *line = (unsigned char *) line_; while (*line != 0U) { if (*line < 32U) { *line = NONPRINTABLE_SUSTITUTE_CHAR; } line++; }}static int process(const int sockets[]){ struct pollfd ufds[2]; struct pollfd *ufdspnt; int nbufds = 0; int pollret; int event; ssize_t readen; char line[LINE_MAX]; int logcode; char *date; const char *prg; char *info; LogLineType loglinetype; if (sockets[0] >= 0) { ufds[0].fd = sockets[0]; ufds[0].events = POLLIN | POLLERR | POLLHUP | POLLNVAL; ufds[0].revents = 0; nbufds++; } if (sockets[1] >= 0) { ufds[nbufds].fd = sockets[1]; ufds[nbufds].events = POLLIN | POLLERR | POLLHUP | POLLNVAL; ufds[nbufds].revents = 0; nbufds++; } for (;;) { while ((pollret = poll(ufds, nbufds, -1)) < 0 && errno == EINTR); ufdspnt = ufds; while (pollret > 0) { if ((event = ufdspnt->revents) == 0) { goto nextpoll; } pollret--; ufdspnt->revents = 0; if (event != POLLIN) { sockerr: fprintf(stderr, "Socket error - aborting\n"); close(ufdspnt->fd); return -1; } readen = read(ufdspnt->fd, line, sizeof line - 1U); if (readen < 0) { goto sockerr; } if (readen == 0) { goto nextpoll; } line[readen] = 0; /* Kludge - need to be rewritten */ if (ufdspnt->fd == sockets[1]) { loglinetype = LOGLINETYPE_KLOG; } else { loglinetype = LOGLINETYPE_SYSLOG; } sanitize(line); if (parseLogLine(loglinetype, line, &logcode, &date, &prg, &info) < 0) { goto nextpoll; } processLogLine(logcode, date, prg, info); nextpoll: ufdspnt++; } } return 0;}static void exit_hook(void){ if (child > (pid_t) 0) { kill(child, SIGTERM); }}static RETSIGTYPE sigkchld(int sig){ fprintf(stderr, "Process [%u] died with signal [%d]\n", (unsigned int) getpid(), sig); exit(EXIT_FAILURE);}static RETSIGTYPE sigchld(int sig){ pid_t pid; signed char should_exit = 0; (void) sig;#ifdef HAVE_WAITPID while ((pid = waitpid((pid_t) -1, NULL, WNOHANG)) > (pid_t) 0) { if (pid == child) { fprintf(stderr, "Klog child [%u] died\n", (unsigned) pid); should_exit = 1; } else if (pid == command_child) { command_child = (pid_t) 0; } }#else while ((pid = wait3(NULL, WNOHANG, NULL)) > (pid_t) 0) { if (pid == child) { fprintf(stderr, "Klog child [%u] died\n", (unsigned) pid); should_exit = 1; } else if (pid == command_child) { command_child = (pid_t) 0; } } #endif if (should_exit != 0) { child = (pid_t) 0; exit(EXIT_FAILURE); }}static RETSIGTYPE sigusr1(int sig){ (void) sig; synchronous = (sig_atomic_t) 1;}static RETSIGTYPE sigusr2(int sig){ (void) sig; synchronous = (sig_atomic_t) 0;}static void setsignals(void){ atexit(exit_hook); signal(SIGCHLD, sigchld); signal(SIGPIPE, sigkchld); signal(SIGHUP, sigkchld); signal(SIGTERM, sigkchld); signal(SIGQUIT, sigkchld); signal(SIGINT, sigkchld); signal(SIGUSR1, sigusr1); signal(SIGUSR2, sigusr2);}static void dodaemonize(void){ pid_t child; if (daemonize) { if ((child = fork()) < (pid_t) 0) { perror("Daemonization failed - fork"); return; } else if (child != (pid_t) 0) { _exit(EXIT_SUCCESS); } else { if (setsid() == (pid_t) -1) { perror("Daemonization failed : setsid"); } chdir("/"); if (isatty(1)) { close(1); } if (isatty(2)) { close(2); } } } }static void help(void){ const struct option *options = long_options; puts("\n" PACKAGE " version " VERSION "\n"); do { printf("-%c\t--%s\t%s\n", options->val, options->name, options->has_arg ? "<opt>" : ""); options++; } while (options->name != NULL); exit(EXIT_SUCCESS); }static void parseOptions(int argc, char *argv[]){ int fodder; int option_index = 0; while ((fodder = getopt_long(argc, argv, GETOPT_OPTIONS, long_options, &option_index)) != -1) { switch (fodder) { case 'B' : daemonize = 1; break;#ifdef HAVE_KLOGCTL case 'c' : console_level = atoi(optarg); if (console_level < MIN_CONSOLE_LEVEL || console_level > MAX_CONSOLE_LEVEL) { fprintf(stderr, "Invalid console level\n"); exit(EXIT_FAILURE); } break;#endif case 'h' : help(); case 's' : synchronous = (sig_atomic_t) 1; break; default : fprintf(stderr, "Unknown option\n"); exit(EXIT_FAILURE); } }}static void checkRoot(void){ if (geteuid() != (uid_t) 0) { fprintf(stderr, "Sorry, you must be root to launch this program\n"); exit(EXIT_FAILURE); }}int main(int argc, char *argv[]){ int sockets[2];#ifndef HAVE_SETPROCTITLE prg_name = argv[0];#endif checkRoot(); parseOptions(argc, argv); if (configParser(CONFIG_FILE) < 0) { fprintf(stderr, "Bad configuration file - aborting\n"); return -1; } dodaemonize(); setsignals(); clearargs(argv); setprogname(PROGNAME_MASTER); if (getDataSources(sockets) < 0) { fprintf(stderr, "Unable to bind sockets - aborting\n"); return -1; } process(sockets); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -