/* * LOGPATH.C * */ #include "defs.h" Prototype void WritePath(char *path); Prototype void ClosePathLog(int dokill); FILE *PLFd = NULL; time_t PLNextCheck = 0; int PLLastInode = 0; char *PLFname = ""; int PLPid = -1; int openProg(char *prog) { int fds[2]; if (pipe(fds) < 0) { logit(LOG_ERR, "logpath unable to pipe(): %s", strerror(errno)); return(-1); } if ((PLPid = fork()) < 0) { logit(LOG_ERR, "logpath unable to fork(): %s", strerror(errno)); close(fds[0]); close(fds[1]); return(-1); } if (!PLPid) { if (dup2(fds[0], fileno(stdin)) < 0) { logit(LOG_ERR, "logpath unable to dup2(): %s", strerror(errno)); close(fds[0]); close(fds[1]); return(-1); } close(fds[0]); close(fds[1]); execl(prog, prog, NULL); logit(LOG_ERR, "logpath unable to execl(%s): %s", prog, strerror(errno)); close(fileno(stdin)); _exit(1); } /* * Only parent should reach here */ close(fds[0]); if (fcntl(fds[1], F_SETFD, 1) < 0) logit(LOG_ERR, "logpath unable to fcntl(): %s", strerror(errno)); return(fds[1]); } void WritePath(char *path) { if ((time(NULL) > PLNextCheck)) { struct stat st; if (strcmp(FPathLogPat, "NONE") == 0) { if (PLFd != NULL) { if (pclose(PLFd) == -1) fclose(PLFd); } PLFd = NULL; } else if (*FPathLogPat == '|') { if (PLFd == NULL || strcmp(PLFname, FPathLogPat) != 0) { int fd; ClosePathLog(1); if (*PLFname) free(PLFname); PLFname = strdup(FPathLogPat); fd = openProg(PLFname + 1); if (fd >= 0) PLFd = fdopen(fd, "a"); } } else { if (*PLFname) free(PLFname); PLFname = strdup(PatLogExpand(FPathLogPat)); if (stat(PLFname, &st) != 0) PLLastInode = 0; if (PLFd == NULL || !PLLastInode || (PLLastInode != st.st_ino)) { /* Need to reopen the log file */ ClosePathLog(1); PLFd = fopen(PLFname, "a"); if (PLFd == NULL) { logit(LOG_ERR, "Unable to open path log: %s (%s)", PLFname, strerror(errno)); } else if (stat(PLFname, &st) == 0) PLLastInode = st.st_ino; } } PLNextCheck = time(NULL) + 10; } /* print message itself */ if (PLFd != NULL) { if (fprintf(PLFd, "Path: %s\n", path) == 0) ClosePathLog(1); else fflush(PLFd); } } void ClosePathLog(int dokill) { if (PLFd != NULL) { if (PLPid > 0 && dokill) kill(PLPid, SIGINT); fclose(PLFd); PLFd = NULL; } }