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

metalog.c

Metalog is a modern replacement for syslogd and klogd. The logged messages can be dispatched accord
C
第 1 页 / 共 3 页
字号:
            klogctl(8, NULL, console_level) < 0 ||            klogctl(6, NULL, 0) < 0) {            perror("Unable to control the kernel logging device");            return -4;        }        for (;;) {            while ((s = klogctl(2, line, sizeof line)) < 0 && errno == EINTR);            t = 0;            u = 0;            while (t < s) {                if (line[t] == '\n') {                    line[t] = 0;                    towrite = (size_t) (1U + t - u);                    do {                        while ((written = write(fdpipe[1], &line[u], towrite))                               < (ssize_t) 0 && errno == EINTR);                        if (written < 0) {                            break;                        }                        if (written >= (ssize_t) towrite) {                            break;                        }                        u += written;                                                towrite -= written;                    } while (towrite > (size_t) 0U);                    u = ++t;                } else {                    t++;                }            }        }                klogctl(7, NULL, 0);        klogctl(0, NULL, 0);                return 0;    }    sockets[1] = fdpipe[0];#else                                  /* !HAVE_KLOGCTL */    {            int klogfd;                if ((klogfd = open(KLOG_FILE, O_RDONLY)) < 0) {            return 0;                  /* non-fatal */        }        sockets[1] = klogfd;    }#endif        return 0;}static int parseLogLine(const LogLineType loglinetype, char *line,                        int * const logcode, char ** const date,                        const char ** const prg, char ** const info){#ifndef HAVE_KLOGCTL    if (loglinetype != LOGLINETYPE_KLOG) {#endif        if (*line != '<') {            return -1;        }        line++;        if ((*logcode = atoi(line)) <= 0) {            return -1;        }        while (*line != '>') {            if (*line == 0) {                return -1;            }            line++;        }        line++;#ifndef HAVE_KLOGCTL    } else {        *logcode = 0;            }#endif        if (loglinetype == LOGLINETYPE_KLOG) {        const char *months[] = {                "Jan", "Feb", "Mar", "Apr", "May", "Jun",                "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"        };        const time_t now = time(NULL);        struct tm *tm;        static char datebuf[100];                *logcode |= LOG_KERN;        *prg = CF_PROGNAME_KERNEL;        *info = line;        if ((tm = localtime(&now)) == NULL) {            *datebuf = 0;        } else {            snprintf(datebuf, sizeof datebuf, "%s %2d %02d:%02d:%02d",                     months[tm->tm_mon], tm->tm_mday,                     tm->tm_hour, tm->tm_min, tm->tm_sec);        }        *date = datebuf;                         return 0;    }        *date = line;    while (*line != ':') {        if (*line == 0) {            return -1;        }        line++;    }    line++;    while (isspace(*line) == 0) {        if (*line == 0) {            return -1;        }        line++;    }    *line++ = 0;    *prg = line;    while (*line != '[' && *line != ':') {        if (*line == 0) {            return -1;        }        line++;    }    if (*line == '[') {        *line++ = 0;        while (*line != ']') {            if (*line == 0) {                return -1;            }            line++;        }        line++;        while (*line != ':') {            if (*line == 0) {                return -1;            }            line++;        }            } else {        *line = 0;    }    line++;    while (isspace(*line) != 0) {        if (*line == 0) {            return -1;        }        line++;    }    *info = line;        return 0;}static int rotateLogFiles(const char * const directory, const int maxfiles){    char path[PATH_MAX];    char old_name[PATH_MAX];    const char *name;    DIR *dir;    struct dirent *dirent;    int foundlogs;    int year, mon, mday, hour, min, sec;    int older_year, older_mon = INT_MAX, older_mday = INT_MAX,        older_hour = INT_MAX, older_min = INT_MAX, older_sec = INT_MAX;        rescan:    foundlogs = 0;    *old_name = 0;    older_year = INT_MAX;    if ((dir = opendir(directory)) == NULL) {        fprintf(stderr, "Unable to rotate [%s]\n", directory);        return -1;    }    while ((dirent = readdir(dir)) != NULL) {        name = dirent->d_name;        if (strncmp(name, OUTPUT_DIR_LOGFILES_PREFIX,                    sizeof OUTPUT_DIR_LOGFILES_PREFIX - 1U) == 0) {            if (sscanf(name, OUTPUT_DIR_LOGFILES_PREFIX "%d-%d-%d-%d:%d:%d",                       &year, &mon, &mday, &hour, &min, &sec) != 6) {                continue;            }                        foundlogs++;            if (year < older_year || (year == older_year &&               (mon  < older_mon  || (mon  == older_mon  &&               (mday < older_mday || (mday == older_mday &&               (hour < older_hour || (hour == older_hour &&               (min  < older_min  || (min  == older_min  &&               (sec  < older_sec))))))))))) {   /* yeah ! */                older_year = year;                older_mon = mon;                older_mday = mday;                older_hour = hour;                older_min = min;                older_sec = sec;                strncpy(old_name, name, sizeof old_name);                old_name[sizeof old_name - 1U] = 0;            }        }    }    closedir(dir);    if (foundlogs >= maxfiles) {        if (*old_name == 0) {            return -3;        }        if (snprintf(path, sizeof path, "%s/%s", directory, old_name) < 0) {            fprintf(stderr, "Path to long to unlink [%s/%s]\n",                     directory, old_name);            return -4;        }        if (unlink(path) < 0) {            return -2;        }        foundlogs--;        if (foundlogs >= maxfiles) {            goto rescan;        }    }            return 0;}static int writeLogLine(Output * const output, const char * const date,                        const char * const prg, const char * const info){    time_t now = time(NULL);        if (output == NULL || output->directory == NULL) {        return 0;    }    if (output->fp == NULL) {        struct stat st;        FILE *fp;        FILE *fp_ts;        time_t creatime;        char path[PATH_MAX];                    testdir:        if (stat(output->directory, &st) < 0) {            if (mkdir(output->directory, OUTPUT_DIR_PERMS) < 0) {                fprintf(stderr, "Can't create [%s]\n", output->directory);                return -1;            }                        } else if (!S_ISDIR(st.st_mode)) {            if (unlink(output->directory) < 0) {                fprintf(stderr, "Can't unlink [%s]\n", output->directory);                return -1;            }            goto testdir;        }        if (snprintf(path, sizeof path, "%s/" OUTPUT_DIR_CURRENT,                     output->directory) < 0) {            fprintf(stderr, "Path name too long for current in [%s]\n",                     output->directory);            return -2;        }        if ((fp = fopen(path, "at")) == NULL) {            fprintf(stderr, "Unable to access [%s]\n", path);            return -3;        }        if (snprintf(path, sizeof path, "%s/" OUTPUT_DIR_TIMESTAMP,                     output->directory) < 0) {            fprintf(stderr, "Path name too long for timestamp in [%s]\n",                    output->directory);            fclose(fp);            return -2;        }        if ((fp_ts = fopen(path, "rt")) == NULL) {            recreate_ts:            creatime = time(NULL);            if ((fp_ts = fopen(path, "wt")) == NULL) {                fprintf(stderr, "Unable to write the timestamp [%s]\n", path);                fclose(fp);                return -3;            }            fprintf(fp_ts, "%llu\n", (unsigned long long) creatime);        } else {            unsigned long long creatime_;                        if (fscanf(fp_ts, "%llu", &creatime_) <= 0) {                fclose(fp_ts);                goto recreate_ts;            }            creatime = (time_t) creatime_;        }        if (fclose(fp_ts) != 0) {            fprintf(stderr, "Unable to close [%s]\n", path);            return -3;        }        output->creatime = creatime;        output->size = (off_t) ftell(fp);        output->fp = fp;    }    if (output->size >= output->maxsize ||        now > (output->creatime + output->maxtime)) {        struct tm *time_gm;            char path[PATH_MAX];        char newpath[PATH_MAX];                            if (output->fp == NULL) {            fprintf(stderr, "Internal inconsistency line [%d]\n", __LINE__);            return -6;        }        if ((time_gm = gmtime(&now)) == NULL) {            fprintf(stderr, "Unable to find the current date\n");            return -4;        }        if (snprintf(newpath, sizeof newpath,                      "%s/" OUTPUT_DIR_LOGFILES_PREFIX                      "%d-%02d-%02d-%02d:%02d:%02d",                     output->directory, time_gm->tm_year + 1900,                     time_gm->tm_mon + 1, time_gm->tm_mday,                     time_gm->tm_hour + 1, time_gm->tm_min,                     time_gm->tm_sec) < 0) {            fprintf(stderr, "Path name too long for new path in [%s]\n",                     output->directory);            return -2;        }        if (snprintf(path, sizeof path, "%s/" OUTPUT_DIR_CURRENT,                     output->directory) < 0) {            fprintf(stderr, "Path name too long for current in [%s]\n",                         output->directory);            return -2;        }        rotateLogFiles(output->directory, output->maxfiles);        fclose(output->fp);        output->fp = NULL;        if (rename(path, newpath) < 0 && unlink(path) < 0) {            fprintf(stderr, "Unable to rename [%s] to [%s]\n",                    path, newpath);            return -5;        }        if (snprintf(path, sizeof path, "%s/" OUTPUT_DIR_TIMESTAMP,                     output->directory) < 0) {            fprintf(stderr, "Path name too long for timestamp in [%s]\n",                    output->directory);            return -2;        }                    unlink(path);        goto testdir;    }    fprintf(output->fp, "%s [%s] %s\n", date, prg, info);    output->size += (off_t) strlen(date);    output->size += (off_t) strlen(prg);            output->size += (off_t) strlen(info);    output->size += (off_t) 5;            if (synchronous != (sig_atomic_t) 0) {

⌨️ 快捷键说明

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