#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#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 */
}
syntax highlighted by Code2HTML, v. 0.9.1