metalog.c
字号:
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 + -