#include #include #include #include #include #include #include #include #include "iolib.h" #include "freedt.h" #include "config.h" const char *progname = "dumblog"; const char *proghelp = "Usage: dumblog [OPTIONS] logfile\n" "Log standard input to a file.\n\n" "-c Prepend a timestamp to each line\n"; int stamp_ctime = 0; char *logfile_name; int logfile; int return_code = 0; buffer line = BUFFER; buffer overflow = BUFFER; void flush_line() { if (blength(&line) > 0) { buffer out = BUFFER; if (stamp_ctime) { time_t t = time(NULL); const char *s = ctime(&t); bappendm(&out, s, strlen(s) - 1); bappendc(&out, ' '); } bappend(&out, &line); bappendc(&out, '\n'); while (1) { if (writeba(logfile, &out) >= 0) break; warn2(logfile_name, "unable to write to logfile"); reliable_sleep(5); } bfree(&out); } bfree(&line); } void open_logfile() { #if HAVE_DECL_O_SYNC const int sync = O_SYNC; #elif HAVE_DECL_O_FSYNC const int sync = O_FSYNC; #else #error No synchronous open flag found #endif logfile = open(logfile_name, O_WRONLY | O_APPEND | O_CREAT | sync, 0644); if (logfile < 0) die2(logfile_name, "unable to open logfile"); } void close_logfile() { flush_line(); while (1) { if (close(logfile) >= 0) break; warn2(logfile_name, "unable to close logfile"); reliable_sleep(5); } } void roll_handler(int dummy) { close_logfile(); open_logfile(); } void quit_handler(int dummy) { flush_line(); bappend(&line, &overflow); close_logfile(); exit(return_code); } int main(int argc, char **argv) { struct sigaction sa; while (1) { int c = getopt(argc, argv, "V?c"); if (c == -1) break; switch (c) { case 'c': stamp_ctime = 1; break; case 'V': version(); default: help(); } } if ((argc - optind) != 1) help(); logfile_name = argv[optind]; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = roll_handler; if (sigaction(SIGHUP, &sa, NULL) < 0) die("unable to install sighup handler"); sa.sa_handler = quit_handler; if (sigaction(SIGTERM, &sa, NULL) < 0) die("unable to install sigterm handler"); open_logfile(); while (1) { int rc = readlineb(fd_in, &line, 0, &overflow); if (rc < 0) { warn("unable to read from stdin"); return_code = 1; quit_handler(0); } if (rc == 0) break; flush_line(); } quit_handler(0); return 0; /* NOTREACHED */ }