/*
 * common stuff for init
 *
 *  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.
 */
#ifndef __INIT_D
#define __INIT_D

#include <stdio.h>
#include <unistd.h>

#ifndef PREFIX
#define PREFIX ""
#endif

#define INITTAB	PREFIX "/etc/inittab"
#define CONSOLE	"/dev/console"

/*
 * magic constants for catching bad inittab entries
 *
 * WAKEUP_TIME is how often the unsuspend process is run
 * RUNDELAY is the minimum time that a process can run without
 *          being counted as a looping process
 * RETRIES  is the number of times a looping process can start
 *          before it's suspended
 * SUSPTIME is how long a process remains suspended before it's awakened
 */
#define WAKEUP_TIME	15
#define RUNDELAY	15
#define RETRIES		20
#define SUSPTIME	300	/* 5 minutes */

/*
 * the COMMAND fifo is used for giving commands to init;
 * command format is <pid> <cmd> [args] \n.  init will
 * signal <pid> with SIGUSR1 on success, SIGUSR2 on failure.
 *
 * commands are
 * G <runlevel>		-- go to the given runlevel
 * R <token>		-- register this program
 * L <fifo>		-- list registered programs to <fifo>
 * U <token>		-- unregister this program
 *
 * commands that write to a fifo send SIGUSR1 _first_, then dump the output
 * to the given fifo.
 */
#define GO		'G'	/* USR1:  Ok, USR2: no */
#define	REGISTER	'R'	/* USR1:  Ok, USR2: already registered */
#define LIST		'L'	/* USR1:  Ok, USR2: no */
#define UNREGISTER	'U'	/* USR1:  Ok, USR2: not registered */

#define COMMAND	PREFIX "/etc/.command"

/* standard runlevels: b is only run when the machine starts up,
 * and RUNLEVELS are the user-accessable ones that anyone can
 * play with
 */
#define	RUNLEVELS	"smhr"

#define BOOT		'b'
#define	AT_BOOT		0x0001
#define	SINGLE		's'
#define	AT_SINGLE	0x0002
#define S_SINGLE	SIGUSR2
#define	MULTI		'm'
#define	AT_MULTI	0x0004
#define S_MULTI		SIGUSR1
#define	HALT		'h'
#define	AT_HALT		0x0008
#define S_HALT		SIGTERM
#define	REBOOT		'r'
#define	AT_REBOOT	0x0010
#define S_REBOOT	SIGQUIT

/*
 * an inittab line is
 *     runlevel:command
 *
 * a rcm-style inittab would be like
 *
 *     m:initdefault:
 *     *:once:/etc/rc.d/rc
 *     m:again:/sbin/getty tty0
 *     m:again:/sbin/getty tty1
 *     m:again:/sbin/getty tty2
 *     m:again:/sbin/getty tty3
 *     m:again:/sbin/getty tty4
 *     m:again:/sbin/getty tty5
 *
 */
struct cmd {
    struct cmd *next;
    unsigned int when;	/* runlevels that this program can run in (bitmask) */
    enum { ONCE, AGAIN, CAD, DEFAULT, ZOMBIE } how;
		/* how to run this program?
		 * CAD      -- when a ctrl-alt-del signal comes in
		 * DEFAULT  -- the default init level
		 * ONCE     -- run it once, then continue on
		 * AGAIN    -- run it over and over and over and over
		 * ZOMBIE   -- orphaned process while re-reading inittab
		 */

    enum { QUEUE, ALIVE, DEAD, SUSPENDED } status;
		/* what's the current status of this program? 
		 * QUEUE     -- in the queue, not running yet.
		 * ALIVE     -- currently running
		 * DEAD      -- finished running
		 * SUSPENDED -- sleeping because it's restarting too fast
		 */
    pid_t pid;		/* process id of running command */
    time_t started;	/* when did the job start */
    int retries;	/* how many times has it died in the last 5 minutes? */
    time_t window;	/* end of 5 minute retry window */
    unsigned int chksum;/* checksum (for comparing lists after kill -HUP 1) */
    int flags;		/* flags for rereading the inittab */
#define TAG		0x01

    int    argc;	/* the command, broken into an argument vector */
    char **argv;
    char command[200];	/* the command line, unmangled */
} ;


/*
 * requirements registry (mastodon-specific)
 */
struct registry {
    char *token;		/* the string we're registering */
    struct registry *next;	/* next item in the list */
} ;

extern char *get_runlevel();
extern FILE *openfifo(char*);

#endif/*__INIT_D*/
