#include <errno.h>
#include <sys/fcntl.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <unistd.h>

#include "log.h"

int handleSyslogSocket(char * rootPath) {
    int sock;
    struct sockaddr_un sockaddr;
    char buf[8192];
    int out;
    pid_t child;
    int readFd = -1;
    int rc, i, s;
    fd_set readSet;
    char * fn;

    logMessage("in handleSyslogSocket");

    if ((child = fork())) {
	/* original parent */
	waitpid(child, &out, 0);
	return 0;
    }

    logMessage("in intermediate child -- pid is %d", getpid());

    /* disassociate from parent -- init makes a find stepparent */
    if (fork()) exit(0);

    logMessage("in final child -- pid is %d", getpid());

    /* now open the syslog socket */
    fn = alloca(strlen(rootPath + 20));
    sprintf(fn, "%s/dev/log", rootPath);
    sockaddr.sun_family = AF_UNIX;
    unlink(fn);
    strcpy(sockaddr.sun_path, fn);
    sock = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sock < 0) {
	logMessage("syslog: error creating socket: %d", errno);
	exit(1);
    }
    if (bind(sock, (struct sockaddr *) &sockaddr, sizeof(sockaddr.sun_family) + 
			strlen(sockaddr.sun_path))) {
	logMessage("syslog: bind error: %d", errno);
    }
    if (listen(sock, 5)) {
	logMessage("listen error: %d", errno);
    }

    out = open("/dev/tty4", O_RDONLY);
    logMessage("out file is %d", out);

    while (sock > 0) {
	FD_ZERO(&readSet);
	FD_SET(sock, &readSet);
	if (readFd > -1) {
	    FD_SET(readFd, &readSet);
	}

	rc = select(20, &readSet, NULL, NULL, NULL);
	if (rc <= 0) continue;

	if (FD_ISSET(sock, &readSet)) {
	    s = sizeof(sockaddr);
	    /* if readFd is already set, we lose data. shucks. */
	    readFd = accept(sock, (struct sockaddr *) &sockaddr, &s);
	    if (readFd < 0) {
		logMessage("error in accept: %d", errno);
		close(sock);
		sock = -1;
	    }
	}

	if ((readFd > -1) && FD_ISSET(readFd, &readSet)) {
	    i = read(readFd, buf, sizeof(buf));
	    if (i > 0) 
		write(out, buf, i);
	    else {
		close(readFd);
		readFd = -1;
	    }
	}
    }

    logMessage("syslog() voodoo exiting");

    exit(0);
}

