/*
 * showreg: show the mastodon registry
 *
 *  Copyright (c) 2000 David Parsons. All rights reserved.
 *
 *  This software is released under a berkeley-style copyright; the
 *  details can be found in the file COPYRIGHT.
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include "init.h"

char *pgm;		/* the program name, for diagnostics */
char fifo[80];		/* the fifo we get the registry back from */
FILE *listf;		/* fd for the returned listing */
int okflag = -1;	/* set to zero on recipt of SIGUSR1, 1 on SIGUSR2 */


/*
 * blow away the fifo when we exit this program
 */
void
rmfifo()
{
    fclose(listf);
    unlink(fifo);
} /* rmfifo */


/*
 * die nicely if an alarm goes off
 */
void
alarmclock(int sig)
{
    fprintf(stderr, "init is not talking to us\n");
    exit(1);
} /* alarmclock */


/*
 * set the okflag depending on whether sigusr1 or sigusr2 called us
 */
void
usersig(int sig)
{
    okflag = (sig != SIGUSR1);
} /* usersig */


/*
 * wipe out the fifo, then exit
 */
void
depart(int rc)
{
    fclose(listf);
    rmfifo();
    exit(rc);
} /* depart */


main(int argc, char ** argv)
{
    register c;
    int i, status;
    int lastwas0=0;
    FILE *cmdf;

    pgm = basename(argv[0]);

    snprintf(fifo, sizeof fifo, "/tmp/.init%d", getpid());
    if (mknod(fifo, S_IFIFO | 0600 , 0) != 0) {
	perror(fifo);
	exit(1);
    }
    atexit(rmfifo);

    if ( (i = open(fifo, O_RDONLY|O_NDELAY)) == -1) {
	perror(fifo);
	depart(1);
    }
    if ( (status = fcntl(i, F_GETFL)) == -1) {
	perror(fifo);
	depart(1);
    }
    if ( (status = fcntl(i, F_SETFL, status & ~O_NDELAY)) == -1) {
	perror(fifo);
	depart(1);
    }

    if ( (listf = fdopen(i, "r")) == 0) {
	perror("fdopen");
	depart(1);
    }
 
    signal(SIGALRM, alarmclock);
    signal(SIGUSR1, usersig);
    signal(SIGUSR2, usersig);

    alarm(2);
    if ( (cmdf = openfifo(COMMAND)) == 0) {
	fprintf(stderr, "%s: init is not talking to us\n", pgm);
	depart(1);
    }
    alarm(0);
    fprintf(cmdf, "%d %c %s\n", getpid(), LIST, fifo);
    fflush(cmdf);
    fclose(cmdf);

    while (okflag == -1)
	wait(&status);

    if (okflag == 0) {
	alarm(2);

	while ( (c = getc(listf)) != EOF)
	    putchar( c ? c : '\n');
	depart(0);
    }
    fprintf(stderr, "%s: init couldn't display the registry\n", pgm);
    depart(1);
} /* showreg */
