
/*
 * 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;
    }
}
