/*	FIFO-based server example	*/

#include	<stdio.h>
#include	<sys/types.h>
#include	<sys/stat.h>
#include	<unistd.h>
#include	<fcntl.h>
#include	<sys/wait.h>
#include	<string.h>

#define		oracle_fifo_name	".oracle_fifo"


int	main(void)

{
int	fd_in, fd_out;
int	i, n;
char	c, buf[64];
pid_t	pid;


	umask(0);

	if (mkfifo(oracle_fifo_name, S_IRUSR | S_IWUSR | 
		S_IWGRP | S_IWOTH) == -1) 	perror("mkfifo");

	if ((fd_in = open(oracle_fifo_name, O_RDONLY)) == -1)
		perror("open");


	while (1) {			/* main loop */

		i = 0;
		while ((n = read(fd_in, &c, 1)) == 1) {	/* parse input */

			if (c >= '0' && c <= '9')
				buf[i++] = c;
			else if (c == '#') {
				buf[i] = '\0';
				break;
			}
			else 
				continue;	
		}

		switch (n) {
		case -1	:	
			perror("read");
		case 0	:	
			sleep(1);
			continue;
		}

		pid = atoi(buf);
		fprintf(stderr, "oracle: request from %d\n", pid);

		/* create feedback fifo to client */

		sprintf(buf, "%s_%d", oracle_fifo_name, pid);

		if (mkfifo(buf, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) 	
			perror("mkfifo");

		if ((fd_out = open(buf, O_WRONLY)) == -1)
			perror("open");

		switch (pid = fork()) {
		case -1	:
			perror("fork");
		case 0	:
			if (dup2(fd_out, STDOUT_FILENO) == -1)
				perror("dup2");
			close(fd_out);
			execlp("/usr/games/fortune", "fortune", (char *) 0);
			perror("exec");
		}

		close(fd_out);

		if (waitpid(pid, NULL, 0) == -1)
			perror("waitpid");

		if (unlink(buf) == -1)
			perror("unlink");
	}
}