
/*	PLAND SOURCE						*/

/*	Pland is a daemon set up to watch a particular fifo	*/
/*	which it creates, for an access attempt. When a read	*/
/*	attempt is made, It execs a command or script given	*/
/*	as an argument at runtime. We are using it here to 	*/
/*	generate a trouble queue listing for people that	*/
/*	"finger touble@cs.colorado.edu"				*/

/* 	
/*	THIS IS THE UNPUBLISHED SOURCE CODE OF REMBO		*/
/*	The copyright notice above does not evidence any   	*/
/*	actual or intended publication of such source code.	*/
/*	So, use it if you like, but give me credit.		*/


/* 	Usage: plan program_name 			*/


/*	Description:					*/

/* 	This program takes the full pathname of an	*/
/* 	executable and runs it on a fifo in the 	*/
/*	user's home directory named .plan.  This	*/
/* 	way, when finger is executed, the output	*/
/* 	of the program goes to the fifo.		*/
	
/*	Written by:  Tony Rems 				*/

/* 	Updated 9/17/91: Josh Weinberg			*/
/*		Added the plan_path argument 		*/

/* 	Send bugs and flames to /dev/null or 		*/
/*	
/*	trouble@boulder.colorado.edu			*/


#include <sys/types.h>
#include <sys/file.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <signal.h>

/* Defines */
#define PERMS 0666
#define USAGE "%s plan_path program_name\n"
/* #define FILENAME "/hazelrah/users/weinberj/.plan" */

/* Function prototypes */
void sig_handler();

/* Global FILENAME because signal wants a function with no params */

char * FILENAME; 

main (argc, argv)
int argc;
char *argv[];
{
	int fd;
	int pid;
	int status;

	if ( argc !=3  ) {
		fprintf (stderr, USAGE, argv[0]);
		exit(1);
	}  /* if */
	FILENAME = argv[1];

/* Catch interrupts for cleanup */
	signal(SIGTERM, sig_handler);
	signal(SIGINT, sig_handler);
	signal(SIGHUP, sig_handler);

	unlink (FILENAME);

/* Make the fifo */
	if ((mknod(FILENAME, S_IFIFO | PERMS, 0)) < 0 ) {
		perror("mknod");
		exit(2);
	}  /* if */

	while (1) {
		if ((fd = open(FILENAME, O_WRONLY)) < 0 ) {
			perror("open");
			exit(3);
		} /* if */

/* Once our open completes we know that someone else has
 * opened the FIFO for reading, so we can know run our 
 * program on it.  So, we fork, exec our program and
 * wait for the child to complete.
 */
		switch (pid = fork()) {
			case -1:
				perror("fork");
				exit(4);
				break;
			case 0:
/* If we're in the child, we copy our fifo to stdout */
/* and exec the program given */
				dup2(fd, 1);
				execlp(argv[2],argv[2],(void *)NULL);
				perror("child returned");
				exit(5);
				break;
			default:
/* If we're in the parent, we close the pipe and wait */
				close(fd);
				while (wait(&status) != pid)
					;
				break;
		} /* switch */
		sleep(2);
		close(fd);
	} /* while */
} /* main */

void sig_handler()  /* cleanup */
{
	unlink(FILENAME);
	exit(0);
}
