/*
 * Mini init implementation for busybox
 *
 *
 * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
 * Adjusted by so many folks, it's impossible to keep track.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */

#include "internal.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <termios.h>
#include <paths.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <sys/wait.h>
#include <string.h>
#include <sys/mount.h>
#include <sys/reboot.h>
#include <sys/kdaemon.h>
#include <sys/sysmacros.h>
#include <linux/serial.h>	/* for serial_struct */
#include <sys/vt.h>		/* for vt_stat */
#include <sys/ioctl.h>
#include <linux/version.h>
#ifdef BB_SYSLOGD
#include <sys/syslog.h>
#endif

#if ! defined BB_FEATURE_USE_PROCFS
#error Sorry, I depend on the /proc filesystem right now.
#endif

#ifndef KERNEL_VERSION
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
#endif


#define VT_PRIMARY      "/dev/tty1"	  /* Primary virtual console */
#define VT_SECONDARY    "/dev/tty2"	  /* Virtual console */
#define VT_LOG          "/dev/tty3"	  /* Virtual console */
#define SERIAL_CON0     "/dev/ttyS0"      /* Primary serial console */
#define SERIAL_CON1     "/dev/ttyS1"      /* Serial console */
#define SHELL           "/bin/sh"	  /* Default shell */
#define INITTAB         "/etc/inittab"	  /* inittab file location */
#ifndef INIT_SCRIPT
#define INIT_SCRIPT	"/etc/init.d/rcS" /* Default sysinit script. */
#endif

#define LOG             0x1
#define CONSOLE         0x2

/* Allowed init action types */
typedef enum {
    SYSINIT=1,
    RESPAWN,
    ASKFIRST,
    WAIT,
    ONCE
} initActionEnum;

/* And now a list of the actions we support in the version of init */
typedef struct initActionType{
    const char*	name;
    initActionEnum action;
} initActionType;

static const struct initActionType actions[] = {
    {"sysinit",     SYSINIT},
    {"respawn",     RESPAWN},
    {"askfirst",    ASKFIRST},
    {"wait",        WAIT},
    {"once",        ONCE},
    {0}
};

/* Set up a linked list of initactions, to be read from inittab */
typedef struct initActionTag initAction;
struct initActionTag {
    pid_t pid;
    char process[256];
    char console[256];
    initAction *nextPtr;
    initActionEnum action;
};
initAction* initActionList = NULL;


static char *secondConsole = VT_SECONDARY;
static char *log = VT_LOG;
static int kernelVersion = 0;
static char termType[32] = "TERM=ansi";
static char console[32] = _PATH_CONSOLE;


/* try to open up the specified device */
int device_open(char *device, int mode)
{
    int m, f, fd = -1;

    m = mode | O_NONBLOCK;

    /* Retry up to 5 times */
    for (f = 0; f < 5; f++)
	if ((fd = open(device, m)) >= 0)
	    break;
    if (fd < 0)
	return fd;
    /* Reset original flags. */
    if (m != mode)
	fcntl(fd, F_SETFL, mode);
    return fd;
}

/* print a message to the specified device:
 * device may be bitwise-or'd from LOG | CONSOLE */
void message(int device, char *fmt, ...)
{
    va_list arguments;
    int fd;

#ifdef BB_SYSLOGD

    /* Log the message to syslogd */
    if (device & LOG ) {
	char msg[1024];
	va_start(arguments, fmt);
	vsnprintf(msg, sizeof(msg), fmt, arguments);
	va_end(arguments);
	syslog(LOG_DAEMON|LOG_NOTICE, msg);
    }

#else
    static int log_fd=-1;

    /* Take full control of the log tty, and never close it.
     * It's mine, all mine!  Muhahahaha! */
    if (log_fd < 0) {
	if (log == NULL) {
	/* don't even try to log, because there is no such console */
	log_fd = -2;
	/* log to main console instead */
	device = CONSOLE;
    }
    else if ((log_fd = device_open(log, O_RDWR|O_NDELAY)) < 0) {
	    log_fd=-1;
	    fprintf(stderr, "Bummer, can't write to log on %s!\r\n", log);
	    fflush(stderr);
	    return;
	}
    }
    if ( (device & LOG) && (log_fd >= 0) ) {
	va_start(arguments, fmt);
	vdprintf(log_fd, fmt, arguments);
	va_end(arguments);
    }
#endif

    if (device & CONSOLE) {
	/* Always send console messages to /dev/console so people will see them. */
	if ((fd = device_open(_PATH_CONSOLE, O_WRONLY|O_NOCTTY|O_NDELAY)) >= 0) {
	    va_start(arguments, fmt);
	    vdprintf(fd, fmt, arguments);
	    va_end(arguments);
	    close(fd);
	} else {
	    fprintf(stderr, "Bummer, can't print: ");
	    va_start(arguments, fmt);
	    vfprintf(stderr, fmt, arguments);
	    fflush(stderr);
	    va_end(arguments);
	}
    }
}


/* Set terminal settings to reasonable defaults */
void set_term( int fd)
{
    struct termios tty;
    static const char control_characters[] = {
	'\003', '\034', '\177', '\025', '\004', '\0',
	'\1', '\0', '\021', '\023', '\032', '\0', '\022',
	'\017', '\027', '\026', '\0'
	};

    tcgetattr(fd, &tty);

    /* set control chars */
    memcpy(tty.c_cc, control_characters, sizeof(control_characters));

    /* use line dicipline 0 */
    tty.c_line = 0;

    /* Make it be sane */
    //tty.c_cflag &= CBAUD|CBAUDEX|CSIZE|CSTOPB|PARENB|PARODD;
    //tty.c_cflag |= HUPCL|CLOCAL;

    /* input modes */
    tty.c_iflag = ICRNL|IXON|IXOFF;

    /* output modes */
    tty.c_oflag = OPOST|ONLCR;

    /* local modes */
    tty.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK|ECHOCTL|ECHOKE|IEXTEN;

    tcsetattr(fd, TCSANOW, &tty);
}

/* How much memory does this machine have? */
static int mem_total()
{
    char s[80];
    char *p = "/proc/meminfo";
    FILE *f;
    const char pattern[] = "MemTotal:";

    if ((f = fopen(p, "r")) < 0) {
	message(LOG, "Error opening %s: %s\n", p, strerror( errno));
	return -1;
    }
    while (NULL != fgets(s, 79, f)) {
	p = strstr(s, pattern);
	if (NULL != p) {
	    fclose(f);
	    return (atoi(p + strlen(pattern)));
	}
    }
    return -1;
}

static void console_init()
{
    int fd;
    int tried_devcons = 0;
    int tried_vtprimary = 0;
    struct serial_struct sr;
    char *s;

    if ((s = getenv("TERM")) != NULL) {
	snprintf(termType,sizeof(termType)-1,"TERM=%s",s);
    }

    if ((s = getenv("CONSOLE")) != NULL) {
	snprintf(console, sizeof(console)-1, "%s",s);
    }
#if #cpu(sparc)
    /* sparc kernel supports console=tty[ab] parameter which is also 
     * passed to init, so catch it here */
    else if ((s = getenv("console")) != NULL) {*/
	/* remap tty[ab] to /dev/ttyS[01] */
	if (strcmp( s, "ttya" )==0)
	    snprintf(console, sizeof(console)-1, "%s", SERIAL_CON0);
	else if (strcmp( s, "ttyb" )==0)
	    snprintf(console, sizeof(console)-1, "%s", SERIAL_CON1);
    }
#endif
    else {
	struct vt_stat vt;

	/* 2.2 kernels: identify the real console backend and try to use it */
	if (ioctl(0, TIOCGSERIAL, &sr) == 0) {
	    /* this is a serial console */
	    snprintf(console, sizeof(console)-1, "/dev/ttyS%d", sr.line);
	}
	else if (ioctl(0, VT_GETSTATE, &vt) == 0) {
	    /* this is linux virtual tty */
	    snprintf(console, sizeof(console)-1, "/dev/tty%d", vt.v_active);
	} else {
	    snprintf(console, sizeof(console)-1, "%s", _PATH_CONSOLE);
	    tried_devcons++;
	}
    }

    while ((fd = open(console, O_RDONLY | O_NONBLOCK)) < 0) {
	/* Can't open selected console -- try /dev/console */
	if (!tried_devcons) {
	    tried_devcons++;
	    snprintf(console, sizeof(console)-1, "%s", _PATH_CONSOLE);
	    continue;
	}
	/* Can't open selected console -- try vt1 */
	if (!tried_vtprimary) {
	    tried_vtprimary++;
	    snprintf(console, sizeof(console)-1, "%s", VT_PRIMARY);
	    continue;
	}
	break;
    }
    if (fd < 0) {
	/* Perhaps we should panic here? */
	snprintf(console, sizeof(console)-1, "/dev/null");
    } else {
	/* check for serial console and disable logging to tty3 & running a
	* shell to tty2 */
	if (ioctl(0,TIOCGSERIAL,&sr) == 0) {
	    message(LOG|CONSOLE, "serial console detected.  Disabling virtual terminals.\r\n" );
	    log = NULL;
	    secondConsole = NULL;
	}
	close(fd);
    }
    message(LOG, "console=%s\n", console );
}

static pid_t run(char* command, 
	char *terminal, int get_enter)
{
    int i, fd;
    pid_t pid;
    char* tmpCmd;
    char* cmd[255];
    static const char press_enter[] =
	"\nPlease press Enter to activate this console. ";
    char* environment[] = {
	"HOME=/",
	"PATH=/usr/bin:/bin:/usr/sbin:/sbin",
	"SHELL=/bin/sh",
	termType,
	"USER=root",
	0
    };


    if ((pid = fork()) == 0) {
	pid_t shell_pgid = getpid ();

	/* Clean up */
	close(0);
	close(1);
	close(2);
	setsid();

	/* Reset signal handlers set for parent process */
	signal(SIGUSR1, SIG_DFL);
	signal(SIGUSR2, SIG_DFL);
	signal(SIGINT, SIG_DFL);
	signal(SIGTERM, SIG_DFL);

	if ((fd = device_open(terminal, O_RDWR)) < 0) {
	    message(LOG|CONSOLE, "Bummer, can't open %s\r\n", terminal);
	    exit(1);
	}
	dup(fd);
	dup(fd);
	tcsetpgrp (0, getpgrp());
	set_term(0);

	if (get_enter==TRUE) {
	    /*
	     * Save memory by not exec-ing anything large (like a shell)
	     * before the user wants it. This is critical if swap is not
	     * enabled and the system has low memory. Generally this will
	     * be run on the second virtual console, and the first will
	     * be allowed to start a shell or whatever an init script 
	     * specifies.
	     */
	    char c;
	    message(LOG, "Waiting for enter to start '%s' (pid %d, console %s)\r\n", 
		    command, shell_pgid, terminal );
	    write(fileno(stdout), press_enter, sizeof(press_enter) - 1);
	    read(fileno(stdin), &c, 1);
	}

	/* Log the process name and args */
	message(LOG, "Starting pid %d, console %s: '", 
		shell_pgid, terminal, command);

	/* Convert command (char*) into cmd (char**, one word per string) */
	for (tmpCmd=command, i=0; (tmpCmd=strsep(&command, " \t")) != NULL;) {
	    if (*tmpCmd != '\0') {
		cmd[i] = tmpCmd;
		message(LOG, "%s ", tmpCmd);
		tmpCmd++;
		i++;
	    }
	}
	cmd[i] = NULL;
	message(LOG, "'\r\n");

	/* Now run it.  The new program will take over this PID, 
	 * so nothing further in init.c should be run. */
	execve(cmd[0], cmd, environment);

	/* We're still here?  Some error happened. */
	message(LOG|CONSOLE, "Bummer, could not run '%s': %s\n", cmd[0],
		strerror(errno));
	exit(-1);
    }
    return pid;
}

static int waitfor(char* command, 
	char *terminal, int get_enter)
{
    int status, wpid;
    int pid = run( command, terminal, get_enter);

    while (1) {
	wpid = wait(&status);
	if (wpid > 0 ) {
	    message(LOG, "Process '%s' (pid %d) exited.\n", 
			    command, wpid);
	    break;
	}
	if (wpid == pid )
	    break;
    }
    return wpid;
}

/* Make sure there is enough memory to do something useful. *
 * Calls swapon if needed so be sure /proc is mounted. */
static void check_memory()
{
    struct stat statBuf;

    if (mem_total() > 3500)
	return;

    if (stat("/etc/fstab", &statBuf) == 0) {
	/* Try to turn on swap */
	waitfor("/bin/swapon swapon -a", log, FALSE);
	if (mem_total() < 3500)
	    goto goodnight;
    } else
	goto goodnight;
    return;

goodnight:
	message(CONSOLE, "Sorry, your computer does not have enough memory.\r\n");
	while (1) sleep(1);
}

#ifndef DEBUG_INIT
static void shutdown_system(void)
{
    /* Allow Ctrl-Alt-Del to reboot system. */
    reboot(RB_ENABLE_CAD);
    message(CONSOLE, "\r\nThe system is going down NOW !!\r\n");
    sync();

    /* Send signals to every process _except_ pid 1 */
    message(CONSOLE, "Sending SIGHUP to all processes.\r\n");
    kill(-1, SIGHUP);
    sleep(2);
    sync();

    message(CONSOLE, "Sending SIGKILL to all processes.\r\n");
    kill(-1, SIGKILL);
    sleep(1);

    message(CONSOLE, "Disabling swap.\r\n");
    waitfor( "swapoff -a", console, FALSE);
    message(CONSOLE, "Unmounting filesystems.\r\n");
    waitfor("umount -a", console, FALSE);
    sync();
    if (kernelVersion > 0 && kernelVersion <= 2 * 65536 + 2 * 256 + 11) {
	/* bdflush, kupdate not needed for kernels >2.2.11 */
	bdflush(1, 0);
	sync();
    }
}

static void halt_signal(int sig)
{
    shutdown_system();
    message(CONSOLE,
	    "The system is halted. Press CTRL-ALT-DEL or turn off power\r\n");
    sync();
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
    if (sig == SIGUSR2)
	reboot(RB_POWER_OFF);
    else
#endif
    reboot(RB_HALT_SYSTEM);
    exit(0);
}

static void reboot_signal(int sig)
{
    shutdown_system();
    message(CONSOLE, "Please stand by while rebooting the system.\r\n");
    sync();
    reboot(RB_AUTOBOOT);
    exit(0);
}

#endif

void new_initAction (initActionEnum action,
	char* process, char* cons)
{
    initAction* newAction;

    /* If BusyBox detects that a serial console is in use, 
     * then entries containing non-empty id fields will _not_ be run.
     */
    if (secondConsole == NULL && *cons != '\0') {
	return;
    }

    newAction = calloc ((size_t)(1), sizeof(initAction));
    if (!newAction) {
	message(LOG|CONSOLE,"Memory allocation failure\n");
	while (1) sleep(1);
    }
    newAction->nextPtr = initActionList;
    initActionList = newAction;
    strncpy( newAction->process, process, 255);
    newAction->action = action;
    if (*cons != '\0') {
	strncpy(newAction->console, cons, 255);
    } else
	strncpy(newAction->console, console, 255);
    newAction->pid = 0;
//    message(LOG|CONSOLE, "process='%s' action='%d' console='%s'\n",
//	    newAction->process, newAction->action, newAction->console);
}

void delete_initAction (initAction *action)
{
    initAction *a, *b=NULL;
    for( a=initActionList ; a; b=a, a=a->nextPtr) {
	if (a == action && b != NULL) {
	    b->nextPtr=a->nextPtr;
	    free( a);
	    break;
	}
    }
}

/* NOTE that if BB_FEATURE_USE_INITTAB is NOT defined,
 * then parse_inittab() simply adds in some default
 * actions(i.e runs INIT_SCRIPT and then starts a pair 
 * of "askfirst" shells).  If BB_FEATURE_USE_INITTAB 
 * _is_ defined, but /etc/inittab is missing, this 
 * results in the same set of default behaviors.
 * */
void parse_inittab(void) 
{
#ifdef BB_FEATURE_USE_INITTAB
    FILE* file;
    char buf[256], lineAsRead[256], tmpConsole[256];
    char *p, *q, *r, *s;
    const struct initActionType *a = actions;
    int foundIt;


    file = fopen(INITTAB, "r");
    if (file == NULL) {
	/* No inittab file -- set up some default behavior */
#endif
	/* Askfirst shell on tty1 */
	new_initAction( ASKFIRST, SHELL, console );
	/* Askfirst shell on tty2 */
	if (secondConsole != NULL) 
	    new_initAction( ASKFIRST, SHELL, secondConsole );
	/* sysinit */
	new_initAction( SYSINIT, INIT_SCRIPT, console );

	return;
#ifdef BB_FEATURE_USE_INITTAB
    }

    while ( fgets(buf, 255, file) != NULL) {
	foundIt=FALSE;
	for(p = buf; *p == ' ' || *p == '\t'; p++);
	if (*p == '#' || *p == '\n') continue;

	/* Trim the trailing \n */
	q = strrchr( p, '\n');
	if (q != NULL)
	    *q='\0';

	/* Keep a copy around for posterity's sake (and error msgs) */
	strcpy(lineAsRead, buf);

	/* Grab the ID field */
	s=p;
	p = strchr( p, ':');
	if ( p != NULL || *(p+1) != '\0' ) {
	    *p='\0';
	    ++p;
	}

	/* Now peal off the process field from the end
	 * of the string */
	q = strrchr( p, ':');
	if ( q == NULL || *(q+1) == '\0' ) {
	    message(LOG|CONSOLE,"Bad inittab entry: %s\n", lineAsRead);
	    continue;
	} else {
	    *q='\0';
	    ++q;
	}

	/* Now peal off the action field */
	r = strrchr( p, ':');
	if ( r == NULL || *(r+1) == '\0') {
	    message(LOG|CONSOLE,"Bad inittab entry: %s\n", lineAsRead);
	    continue;
	} else {
	    ++r;
	}

	/* Ok, now process it */
	a = actions;
	while (a->name != 0) {
	    if (strcmp(a->name, r) == 0) {
		if (*s != '\0') {
		    struct stat statBuf;
		    strcpy(tmpConsole, "/dev/");
		    strncat(tmpConsole, s, 200);
		    if (stat(tmpConsole, &statBuf) != 0) {
			message(LOG|CONSOLE, "device '%s' does not exist.  Did you read the directions?\n", tmpConsole);
			break;
		    }
		    s = tmpConsole;
		}
		new_initAction( a->action, q, s);
		foundIt=TRUE;
	    }
	    a++;
	}
	if (foundIt==TRUE)
	    continue;
	else {
	    /* Choke on an unknown action */
	    message(LOG|CONSOLE, "Bad inittab entry: %s\n", lineAsRead);
	}
    }
    return;
#endif
}

extern int init_main(int argc, char **argv)
{
    initAction *a;
    pid_t wpid;
    int status;

#ifndef DEBUG_INIT
    /* Expect to be PID 1 iff we are run as init (not linuxrc) */
    if (getpid() != 1 && strstr(argv[0], "init")!=NULL ) {
	usage( "init\n\nInit is the parent of all processes.\n\n"
		"This version of init is designed to be run only by the kernel\n");
    }
    /* Fix up argv[0] to be certain we claim to be init */
    strncpy(argv[0], "init", strlen(argv[0]));

    /* Set up sig handlers  -- be sure to
     * clear all of these in run() */
    signal(SIGUSR1, halt_signal);
    signal(SIGUSR2, reboot_signal);
    signal(SIGINT, reboot_signal);
    signal(SIGTERM, reboot_signal);

    /* Turn off rebooting via CTL-ALT-DEL -- we get a 
     * SIGINT on CAD so we can shut things down gracefully... */
    reboot(RB_DISABLE_CAD);
#endif 

    /* Figure out where the default console should be */
    console_init();

    /* Close whatever files are open, and reset the console. */
    close(0);
    close(1);
    close(2);
    set_term(0);
    setsid();

    /* Make sure PATH is set to something sane */
    putenv(_PATH_STDPATH);

    /* Hello world */
#ifndef DEBUG_INIT
    message(LOG|CONSOLE, 
	    "init started:  BusyBox v%s (%s) multi-call binary\r\n", 
	    BB_VER, BB_BT);
#else
    message(LOG|CONSOLE, 
	    "init(%d) started:  BusyBox v%s (%s) multi-call binary\r\n", 
	    getpid(), BB_VER, BB_BT);
#endif

    
    /* Mount /proc */
    if (mount ("proc", "/proc", "proc", 0, 0) == 0) {
	message(LOG|CONSOLE, "Mounting /proc: done.\n");
	kernelVersion = get_kernel_revision();
    } else
	message(LOG|CONSOLE, "Mounting /proc: failed!\n");

    /* Make sure there is enough memory to do something useful. */
    check_memory();

    /* Check if we are supposed to be in single user mode */
    if ( argc > 1 && (!strcmp(argv[1], "single") || 
		!strcmp(argv[1], "-s") || !strcmp(argv[1], "1"))) 
    {
	/* Ask first then start a shell on tty2 */
	if (secondConsole != NULL) 
	    new_initAction( ASKFIRST, SHELL, secondConsole);
	/* Ask first then start a shell on tty1 */
	new_initAction( ASKFIRST, SHELL, console);
    } else {
	/* Not in single user mode -- see what inittab says */

	/* NOTE that if BB_FEATURE_USE_INITTAB is NOT defined,
	 * then parse_inittab() simply adds in some default
	 * actions(i.e runs INIT_SCRIPT and then starts a pair 
	 * of "askfirst" shells */
	parse_inittab();
    }

    /* Now run everything that needs to be run */

    /* First run the sysinit command */
    for( a=initActionList ; a; a=a->nextPtr) {
	if (a->action == SYSINIT) {
	    waitfor(a->process, a->console, FALSE);
	    /* Now remove the "sysinit" entry from the list */
	    delete_initAction( a);
	}
    }
    /* Next run anything that wants to block */
    for( a=initActionList ; a; a=a->nextPtr) {
	if (a->action == WAIT) {
	    waitfor(a->process, a->console, FALSE);
	    /* Now remove the "wait" entry from the list */
	    delete_initAction( a);
	}
    }
    /* Next run anything to be run only once */
    for( a=initActionList ; a; a=a->nextPtr) {
	if (a->action == ONCE) {
	    run(a->process, a->console, FALSE);
	    /* Now remove the "once" entry from the list */
	    delete_initAction( a);
	}
    }
    /* If there is nothing else to do, stop */
    if (initActionList == NULL) {
	message(LOG|CONSOLE, "No more tasks for init -- sleeping forever.\n");
	while (1) sleep(1);
    }

    /* Now run the looping stuff for the rest of forever */
    while (1) {
	for( a=initActionList ; a; a=a->nextPtr) {
	    /* Only run stuff with pid==0.  If they have
	     * a pid, that means they are still running */
	    if (a->pid == 0) {
		switch(a->action) {
		    case RESPAWN:
			/* run the respawn stuff */
			a->pid = run(a->process, a->console, FALSE);
			break;
		    case ASKFIRST:
			/* run the askfirst stuff */
			a->pid = run(a->process, a->console, TRUE);
			break;
		    /* silence the compiler's incessant whining */
		    default:
			break;
		}
	    }
	}
	/* Wait for a child process to exit */
	wpid = wait(&status);
	if (wpid > 0 ) {
	    /* Find out who died and clean up their corpse */
	    for( a=initActionList ; a; a=a->nextPtr) {
		if (a->pid==wpid) {
		    a->pid=0;
		    message(LOG, "Process '%s' (pid %d) exited.  Scheduling it for restart.\n", 
			    a->process, wpid);
		}
	    }
	}
	sleep(1);
    }
}

