/* Pure Load Balancer - (C)opyleft 2003 Jedi/Sector One */ #include #include "plb.h" #include "plb_globals.h" #include "plb_log_p.h" #ifdef WITH_DMALLOC # include #endif void plb_close_log(void) { if (log_fd == -1) { return; } plb_log(LL_NOTIFY, "PLB has been shut down"); (void) fsync(log_fd); while (close(log_fd) != 0 && errno == EINTR); log_fd = -1; } int plb_open_log(const char * const log_file) { struct stat st; int already_probed = 0; int fd; open_again: if ((fd = open(log_file, O_WRONLY | O_APPEND | O_NOFOLLOW | O_CREAT, (mode_t) 0644)) == -1) { plb_log(LL_ERROR, "Unable to open/create [%s] : [%s]", log_file, strerror(errno)); plb_close_log(); return -1; } if (fstat(fd, &st) != 0) { (void) close(fd); plb_log(LL_ERROR, "Unable to stat [%s] : [%s]", log_file, strerror(errno)); plb_close_log(); return -1; } if (!S_ISREG(st.st_mode) && !S_ISFIFO(st.st_mode)) { (void) close(fd); plb_log(LL_ERROR, "Log file [%s] is not a regular file", log_file); plb_close_log(); return -1; } if (st.st_nlink > 1) { (void) close(fd); if (already_probed == 0) { plb_log(LL_ERROR, "Log file [%s] has [%u] hard links - unlinking", log_file, (unsigned int) st.st_nlink); (void) unlink(log_file); already_probed++; goto open_again; } else { plb_log(LL_ERROR, "Log file [%s] still has [%u] hard links", log_file, (unsigned int) st.st_nlink); } plb_close_log(); return -1; } log_fd = fd; return 0; } void plb_log(const LogLevel level, const char * const fmt, ...) { static char line[LINE_MAX]; va_list va; char *linepnt = line; size_t towrite; ssize_t written; if (log_level > level || log_fd == -1) { return; } va_start(va, fmt); vsnprintf(line, sizeof line - (size_t) 2U, fmt, va); if ((towrite = strlen(line)) <= (size_t) 0U) { return; } line[towrite] = '\n'; towrite++; line[towrite] = 0; towrite++; for (;;) { while ((written = write(log_fd, linepnt, towrite)) < (ssize_t) 0 && errno == EINTR); if (written < (ssize_t) 0) { while (write(log_fd, "-?-\n", (size_t) 5U) < (ssize_t) 0 && errno == EINTR); break; } towrite -= (size_t) written; if (towrite <= (size_t) 0) { break; } linepnt += written; } va_end(va); }