欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

metalog.c

Metalog is a modern replacement for syslogd and klogd. The logged messages can be dispatched accord
C
第 1 页 / 共 3 页
字号:
        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 + -