/* Microsyslogd that does basic syslogging. */ #include #include #include #include #include #include #include #include #include char *nodename; void logline(FILE *outfp, char *proc, char *line) { time_t now; struct tm *tm; char *d, *s; time(&now); tm = localtime(&now); d=asctime(tm); /* Trim off year and newline. */ if((s=strrchr(d, ' '))) *s = '\0'; if(s=strchr(d, ' ')) d = s+1; fprintf(outfp, "%s %s: %s\n", d, nodename, line); } void copy(int in_fd, FILE *outfp) { static char linebuf[5*1024]; int l, acc = 0; while((l=read(in_fd, linebuf, sizeof(linebuf)-2)) > 0) { char *b, *eol; int i; acc += l; for(i = 0; i < l; i++) if(linebuf[i] == '\0') linebuf[i] = ' '; if(linebuf[l-1] == '\n') l--; linebuf[l] = '\n'; linebuf[l+1] = '\0'; b = linebuf; while(eol = strchr(b, '\n')) { *eol = '\0'; logline(outfp, "kernel", b); b = eol+1; } } /* Nothing sensible happened? Avoid busy-looping. */ if(!acc) sleep(1); return; } int main(int argc, char *argv[]) { int config_fd, klog_fd, n, maxfd; char *nn; FILE *logfp; struct utsname utsname; if(uname(&utsname) < 0) { perror("uname"); return 1; } nodename = utsname.nodename; if((nn=strchr(nodename, '.'))) *nn = '\0'; if((klog_fd = open("/dev/klog", O_NONBLOCK | O_RDONLY)) < 0) { perror("/dev/klog"); return 1; } if(!(logfp = fopen("/var/log/messages", "a"))) { perror("/var/log/messages"); return 1; } maxfd = klog_fd; while(1) { fd_set fds; FD_ZERO(&fds); FD_SET(klog_fd, &fds); n = select(maxfd+1, &fds, NULL, NULL, NULL); if(n <= 0) { sleep(1); continue; } if(FD_ISSET(klog_fd, &fds)) { copy(klog_fd, logfp); } fflush(logfp); sync(); } return 0; }