/** * log_msg - Write log message into lp_diag log file * * @fmt format string to printf() * @... additional argument */ void log_msg(const char *fmt, ...) { int rc; int len = 0; char buf[LP_ERROR_LOG_MAX]; va_list ap; #ifndef LPD_DEBUG /* In order to make testing easier we will not print time in * debug version of lp_diag. */ if (lp_error_log_fd != STDOUT_FILENO) { len = insert_time(buf, LP_ERROR_LOG_MAX); len += snprintf(buf + len, LP_ERROR_LOG_MAX - len, ": "); } #endif /* Add the actual message */ va_start(ap, fmt); len += vsnprintf(buf + len, LP_ERROR_LOG_MAX - len, fmt, ap); if (len < 0 || len >= LP_ERROR_LOG_MAX) { dbg("Insufficient buffer size"); va_end(ap); return; } va_end(ap); /* Add ending punctuation */ len += snprintf(buf + len, LP_ERROR_LOG_MAX - len, "."); if (lp_error_log_fd == -1) { dbg("Log file \"%s\" is not available", lp_error_log_file); _dbg(buf); return; } _dbg(buf); /* reformat the new message */ len = reformat_msg(buf, LP_ERROR_LOG_MAX); rc = write(lp_error_log_fd, buf, len); if (rc == -1) dbg("Write to log file \"%s\" failed", lp_error_log_file); }
/** * dbg * @brief Write debug messages to stdout * * Provide utility to print debug statements if the debug flag * is specified. * * @param fmt format string a la printf() * @param ... args a la printf() */ void _dbg(const char *fmt, ...) { va_list ap; char buf[RTAS_ERROR_LOG_MAX + 8]; int len; if (debug == 0) return; memset(buf, 0, sizeof(buf)); va_start(ap, fmt); len = sprintf(buf, "DEBUG: "); len += vsnprintf(buf + len, RTAS_ERROR_LOG_MAX, fmt, ap); buf[len] = '\0'; va_end(ap); len = reformat_msg(buf); fprintf(stdout, "%s", buf); fflush(stdout); }
/** * _log_msg * @brief The real routine to write messages to rtas_errd_log * * This is a common routine for formatting messages that go to the * /var/log/rtas_errd.log file. Users should pass in a reference to * the rtas_event structure if this message is directly related a rtas * event and a formatted message a la printf() style. Please make sure * that the message passed in does not have any ending punctuation or * ends with a newline. It sould also not have any internal newlines. * * This routine will do several things to the message before printing * it out; * - Add a timestamp * - If a rtas_event reference is passed in, a sequenbce number is added * - If errno is set, the results of perror are added. * - The entire message is then formatted to fit in 80 cols. * * @param event reference to event * @param fmt formatted string a la printf() * @param ... additional args a la printf() */ static void _log_msg(struct event *event, const char *fmt, va_list ap) { struct stat sbuf; char buf[RTAS_ERROR_LOG_MAX]; int len = 0, rc; if (rtas_errd_log_fd == -1) { dbg("rtas_errd log file is not available"); vsprintf(buf, fmt, ap); _dbg(buf); return; } #ifndef DEBUG { time_t cal; /* In order to make testing easier we don't print the date * to the log file for debug versions of rtas_errd. This helps * avoid lots of ugly date munging when comparing files. */ cal = time(NULL); len = sprintf(buf, "%s ", ctime(&cal)); } #endif /* Add the sequence number */ if (event) len += sprintf(buf, "(Sequence #%d) ", event->seq_num); /* Add the actual message */ len += vsprintf(buf + len, fmt, ap); /* Add ending punctuation */ len += sprintf(buf + len, "."); _dbg(buf); /* reformat the new message */ len = reformat_msg(buf); rc = write(rtas_errd_log_fd, buf, len); if (rc == -1) dbg("rtas_errd: write to rtas_errd log failed"); /* After each write check to see if we need to to do log rotation */ rc = fstat(rtas_errd_log_fd, &sbuf); if (rc == -1) { dbg("rtas_errd: Cannot stat rtas_errd log file " "to rotate logs"); return; } if (sbuf.st_size >= RTAS_ERRD_LOGSZ) { char cmd_buf[1024]; int rc; int8_t status; close(rtas_errd_log_fd); memset(cmd_buf, 0, 1024); sprintf(cmd_buf, "rm -f %s; mv %s %s", rtas_errd_log0, rtas_errd_log, rtas_errd_log0); rc = system(cmd_buf); if (rc == -1) { status = WEXITSTATUS(rc); log_msg(NULL, "An error occured during the rotation of " "the rtas_errd logs:\n cmd = %s\nexit status: " "%d)", cmd_buf, status); } rtas_errd_log_fd = open(rtas_errd_log, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP); if (rtas_errd_log_fd == -1) dbg("Could not re-open %s", rtas_errd_log); } return; }
/** * _log_msg * @brief The real routine to write messages to rtas_errd_log * * This is a common routine for formatting messages that go to the * /var/log/rtas_errd.log file. Users should pass in a reference to * the rtas_event structure if this message is directly related a rtas * event and a formatted message a la printf() style. Please make sure * that the message passed in does not have any ending punctuation or * ends with a newline. It sould also not have any internal newlines. * * This routine will do several things to the message before printing * it out; * - Add a timestamp * - If a rtas_event reference is passed in, a sequenbce number is added * - If errno is set, the results of perror are added. * - The entire message is then formatted to fit in 80 cols. * * @param event reference to event * @param fmt formatted string a la printf() * @param ... additional args a la printf() */ static void _log_msg(struct event *event, const char *fmt, va_list ap) { struct stat sbuf; char buf[RTAS_ERROR_LOG_MAX]; int len = 0, rc; char *dir_name; char *rtas_errd_log_c; /* Both rtas_errd_log/rtas_errd_log0 are global, so make a copy. */ if (rtas_errd_log_fd == -1) { dbg("rtas_errd log file is not available"); vsprintf(buf, fmt, ap); _dbg(buf); return; } #ifndef DEBUG { time_t cal; /* In order to make testing easier we don't print the date * to the log file for debug versions of rtas_errd. This helps * avoid lots of ugly date munging when comparing files. */ cal = time(NULL); len = sprintf(buf, "%s ", ctime(&cal)); } #endif /* Add the sequence number */ if (event) len += sprintf(buf, "(Sequence #%d) ", event->seq_num); /* Add the actual message */ len += vsprintf(buf + len, fmt, ap); /* Add ending punctuation */ len += sprintf(buf + len, "."); _dbg(buf); /* reformat the new message */ len = reformat_msg(buf); rc = write(rtas_errd_log_fd, buf, len); if (rc == -1) dbg("rtas_errd: write to rtas_errd log failed"); /* After each write check to see if we need to to do log rotation */ rc = fstat(rtas_errd_log_fd, &sbuf); if (rc == -1) { dbg("rtas_errd: Cannot stat rtas_errd log file " "to rotate logs"); return; } if (sbuf.st_size >= RTAS_ERRD_LOGSZ) { int rc; /* return code */ struct stat log_file; /* file stat */ int dir_fd; /* fsync */ close(rtas_errd_log_fd); /* * Remove log file /var/log/rtas_errd.log0 */ rc = stat(rtas_errd_log0, &log_file); if (rc == 0) { rc = unlink(rtas_errd_log0); if (rc == -1) { log_msg(NULL, "An error occured during the " "rotation of the rtas_errd logs:\n " "cmd = rm %s\nexit status: %d)", rtas_errd_log0, errno); } } /* stat */ /* * rotate /var/log/rtas_errd.log to /var/log/rtas_errd.log0 */ rc = rename(rtas_errd_log, rtas_errd_log0); if (rc == -1) { log_msg(NULL, "An error occured during rotation of " "rtas_errd logs (logger alive):\n cmd = rename" " %s %s\nexit status: %d)", rtas_errd_log, rtas_errd_log0, errno); } /* * fsync /var/log/ to be on safer side. */ rtas_errd_log_c = strdup(rtas_errd_log); if (!rtas_errd_log_c) { log_msg(NULL, "%s, Memory allocation failed, %s", __func__, strerror(errno)); rtas_errd_log_fd = -1; dbg("Could not re-open %s", rtas_errd_log); return; } dir_name = dirname(rtas_errd_log_c); dir_fd = open(dir_name, O_RDONLY|O_DIRECTORY); rc = fsync(dir_fd); if (rc == -1) { log_msg(NULL, "fsync failed, on %s\nexit status: %d", dir_name, errno); } close(dir_fd); rtas_errd_log_fd = open(rtas_errd_log, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP); if (rtas_errd_log_fd == -1) dbg("Could not re-open %s", rtas_errd_log); } return; }