declare merege() externally, ANSI C fix
[unix-history] / usr / src / sbin / init / init.c
index 1fa21a0..8765e27 100644 (file)
@@ -1,12 +1,11 @@
-
 /*
 /*
- * Copyright (c) 1980 Regents of the University of California.
+ * Copyright (c) 1980,1986 Regents of the University of California.
  * All rights reserved.  The Berkeley software License Agreement
  * specifies the terms and conditions for redistribution.
  */
 
 #ifndef lint
  * All rights reserved.  The Berkeley software License Agreement
  * specifies the terms and conditions for redistribution.
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)init.c     5.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)init.c     5.10 (Berkeley) %G%";
 #endif not lint
 
 #include <signal.h>
 #endif not lint
 
 #include <signal.h>
@@ -17,12 +16,12 @@ static char sccsid[] = "@(#)init.c  5.1 (Berkeley) %G%";
 #include <errno.h>
 #include <sys/file.h>
 #include <ttyent.h>
 #include <errno.h>
 #include <sys/file.h>
 #include <ttyent.h>
-#include <syslog.h>
+#include <sys/syslog.h>
+#include <sys/stat.h>
 
 #define        LINSIZ  sizeof(wtmp.ut_line)
 
 #define        LINSIZ  sizeof(wtmp.ut_line)
-#define        CMDSIZ  70      /* max string length for getty or window command*/
-#define        TABSIZ  100
-#define        ALL     p = &itab[0]; p < &itab[TABSIZ]; p++
+#define        CMDSIZ  200     /* max string length for getty or window command*/
+#define        ALL     p = itab; p ; p = p->next
 #define        EVER    ;;
 #define SCPYN(a, b)    strncpy(a, b, sizeof(a))
 #define SCMPN(a, b)    strncmp(a, b, sizeof(a))
 #define        EVER    ;;
 #define SCPYN(a, b)    strncpy(a, b, sizeof(a))
 #define SCMPN(a, b)    strncmp(a, b, sizeof(a))
@@ -30,7 +29,7 @@ static char sccsid[] = "@(#)init.c    5.1 (Berkeley) %G%";
 char   shell[] = "/bin/sh";
 char   minus[] = "-";
 char   runc[]  = "/etc/rc";
 char   shell[] = "/bin/sh";
 char   minus[] = "-";
 char   runc[]  = "/etc/rc";
-char   utmp[]  = "/etc/utmp";
+char   utmpf[] = "/etc/utmp";
 char   wtmpf[] = "/usr/adm/wtmp";
 char   ctty[]  = "/dev/console";
 
 char   wtmpf[] = "/usr/adm/wtmp";
 char   ctty[]  = "/dev/console";
 
@@ -45,7 +44,10 @@ struct       tab
        char    wcmd[CMDSIZ];   /* command to start window system process */
        time_t  gettytime;
        int     gettycnt;
        char    wcmd[CMDSIZ];   /* command to start window system process */
        time_t  gettytime;
        int     gettycnt;
-} itab[TABSIZ];
+       time_t  windtime;
+       int     windcnt;
+       struct  tab *next;
+} *itab;
 
 int    fi;
 int    mergflag;
 
 int    fi;
 int    mergflag;
@@ -60,9 +62,13 @@ long lseek();
 
 struct sigvec rvec = { reset, sigmask(SIGHUP), 0 };
 
 
 struct sigvec rvec = { reset, sigmask(SIGHUP), 0 };
 
-#ifdef vax
+
+#if defined(vax) || defined(tahoe)
 main()
 {
 main()
 {
+#if defined(tahoe)
+       register int r12;               /* make sure r11 gets bootflags */
+#endif
        register int r11;               /* passed thru from boot */
 #else
 main(argc, argv)
        register int r11;               /* passed thru from boot */
 #else
 main(argc, argv)
@@ -72,7 +78,7 @@ main(argc, argv)
        int howto, oldhowto;
 
        time0 = time(0);
        int howto, oldhowto;
 
        time0 = time(0);
-#ifdef vax
+#if defined(vax) || defined(tahoe)
        howto = r11;
 #else
        if (argc > 1 && argv[1][0] == '-') {
        howto = r11;
 #else
        if (argc > 1 && argv[1][0] == '-') {
@@ -92,7 +98,7 @@ main(argc, argv)
                howto = RB_SINGLE;
        }
 #endif
                howto = RB_SINGLE;
        }
 #endif
-       openlog("init", LOG_CONS|LOG_ODELAY, 0);
+       openlog("init", LOG_CONS|LOG_ODELAY, LOG_AUTH);
        sigvec(SIGTERM, &rvec, (struct sigvec *)0);
        signal(SIGTSTP, idle);
        signal(SIGSTOP, SIG_IGN);
        sigvec(SIGTERM, &rvec, (struct sigvec *)0);
        signal(SIGTSTP, idle);
        signal(SIGSTOP, SIG_IGN);
@@ -118,15 +124,20 @@ int       shutreset();
 shutdown()
 {
        register i;
 shutdown()
 {
        register i;
-       register struct tab *p;
+       register struct tab *p, *p1;
 
 
-       close(creat(utmp, 0644));
+       close(creat(utmpf, 0644));
        signal(SIGHUP, SIG_IGN);
        signal(SIGHUP, SIG_IGN);
-       for (ALL) {
+       for (p = itab; p ; ) {
                term(p);
                term(p);
-               p->line[0] = 0;
+               p1 = p->next;
+               free(p);
+               p = p1;
        }
        }
+       itab = (struct tab *)0;
        signal(SIGALRM, shutreset);
        signal(SIGALRM, shutreset);
+       (void) kill(-1, SIGTERM);       /* one chance to catch it */
+       sleep(5);
        alarm(30);
        for (i = 0; i < 5; i++)
                kill(-1, SIGKILL);
        alarm(30);
        for (i = 0; i < 5; i++)
                kill(-1, SIGKILL);
@@ -136,7 +147,7 @@ shutdown()
        shutend();
 }
 
        shutend();
 }
 
-char shutfailm[] = "WARNING: Something is hung (wont die); ps axl advised\n";
+char shutfailm[] = "WARNING: Something is hung (won't die); ps axl advised\n";
 
 shutreset()
 {
 
 shutreset()
 {
@@ -190,6 +201,7 @@ single()
                        dup2(0, 1);
                        dup2(0, 2);
                        execl(shell, minus, (char *)0);
                        dup2(0, 1);
                        dup2(0, 2);
                        execl(shell, minus, (char *)0);
+                       perror(shell);
                        exit(0);
                }
                while ((xpid = wait((int *)0)) != pid)
                        exit(0);
                }
                while ((xpid = wait((int *)0)) != pid)
@@ -245,12 +257,14 @@ multiple()
 {
        register struct tab *p;
        register pid;
 {
        register struct tab *p;
        register pid;
+       int omask;
 
        sigvec(SIGHUP, &mvec, (struct sigvec *)0);
        for (EVER) {
                pid = wait((int *)0);
                if (pid == -1)
                        return;
 
        sigvec(SIGHUP, &mvec, (struct sigvec *)0);
        for (EVER) {
                pid = wait((int *)0);
                if (pid == -1)
                        return;
+               omask = sigblock(sigmask(SIGHUP));
                for (ALL) {
                        /* must restart window system BEFORE emulator */
                        if (p->wpid == pid || p->wpid == -1)
                for (ALL) {
                        /* must restart window system BEFORE emulator */
                        if (p->wpid == pid || p->wpid == -1)
@@ -263,6 +277,7 @@ multiple()
                                dfork(p);
                        }
                }
                                dfork(p);
                        }
                }
+               sigsetmask(omask);
        }
 }
 
        }
 }
 
@@ -279,6 +294,7 @@ merge()
 {
        register struct tab *p;
        register struct ttyent *t;
 {
        register struct tab *p;
        register struct ttyent *t;
+       register struct tab *p1;
 
        for (ALL)
                p->xflag = 0;
 
        for (ALL)
                p->xflag = 0;
@@ -294,44 +310,66 @@ merge()
                                p->xflag |= CHANGE;
                                SCPYN(p->comn, t->ty_getty);
                        }
                                p->xflag |= CHANGE;
                                SCPYN(p->comn, t->ty_getty);
                        }
-                       if (SCMPN(p->wcmd, t->ty_window)) {
+                       if (SCMPN(p->wcmd, t->ty_window ? t->ty_window : "")) {
                                p->xflag |= WCHANGE|CHANGE;
                                SCPYN(p->wcmd, t->ty_window);
                        }
                        goto contin1;
                }
 
                                p->xflag |= WCHANGE|CHANGE;
                                SCPYN(p->wcmd, t->ty_window);
                        }
                        goto contin1;
                }
 
-               for (ALL) {
-                       if (p->line[0] != 0)
-                               continue;
-                       SCPYN(p->line, t->ty_name);
-                       p->xflag |= FOUND|CHANGE;
-                       SCPYN(p->comn, t->ty_getty);
-                       if (strcmp(t->ty_window, "") != 0) {
-                               p->xflag |= WCHANGE;
-                               SCPYN(p->wcmd, t->ty_window);
-                       }
+               /*
+                * Make space for a new one
+                */
+               p1 = (struct tab *)calloc(1, sizeof(*p1));
+               if (!p1) {
+                       syslog(LOG_ERR, "no space for '%s' !?!", t->ty_name);
                        goto contin1;
                }
                        goto contin1;
                }
+               /*
+                * Put new terminal at the end of the linked list.
+                */
+               if (itab) {
+                       for (p = itab; p->next ; p = p->next)
+                               ;
+                       p->next = p1;
+               } else
+                       itab = p1;
+
+               p = p1;
+               SCPYN(p->line, t->ty_name);
+               p->xflag |= FOUND|CHANGE;
+               SCPYN(p->comn, t->ty_getty);
+               if (t->ty_window && strcmp(t->ty_window, "") != 0) {
+                       p->xflag |= WCHANGE;
+                       SCPYN(p->wcmd, t->ty_window);
+               }
        contin1:
                ;
        }
        endttyent();
        contin1:
                ;
        }
        endttyent();
+       p1 = (struct tab *)0;
        for (ALL) {
                if ((p->xflag&FOUND) == 0) {
                        term(p);
        for (ALL) {
                if ((p->xflag&FOUND) == 0) {
                        term(p);
-                       p->line[0] = 0;
-                       wterm(p);
-               }
-               /* window system should be started first */
-               if (p->xflag&WCHANGE) {
                        wterm(p);
                        wterm(p);
-                       wstart(p);
-               }
-               if (p->xflag&CHANGE) {
-                       term(p);
-                       dfork(p);
+                       if (p1)
+                               p1->next = p->next;
+                       else
+                               itab = p->next;
+                       free(p);
+                       p = p1 ? p1 : itab;
+               } else {
+                       /* window system should be started first */
+                       if (p->xflag&WCHANGE) {
+                               wterm(p);
+                               wstart(p);
+                       }
+                       if (p->xflag&CHANGE) {
+                               term(p);
+                               dfork(p);
+                       }
                }
                }
+               p1 = p;
        }
 }
 
        }
 }
 
@@ -349,8 +387,6 @@ term(p)
                kill(p->wpid, SIGHUP);
 }
 
                kill(p->wpid, SIGHUP);
 }
 
-#include <sys/ioctl.h>
-
 dfork(p)
        struct tab *p;
 {
 dfork(p)
        struct tab *p;
 {
@@ -372,6 +408,7 @@ dfork(p)
        if (pid == 0) {
                signal(SIGTERM, SIG_DFL);
                signal(SIGHUP, SIG_IGN);
        if (pid == 0) {
                signal(SIGTERM, SIG_DFL);
                signal(SIGHUP, SIG_IGN);
+               sigsetmask(0);  /* since can be called from masked code */
                if (dowait) {
                        syslog(LOG_ERR, "'%s %s' failing, sleeping", p->comn, p->line);
                        closelog();
                if (dowait) {
                        syslog(LOG_ERR, "'%s %s' failing, sleeping", p->comn, p->line);
                        closelog();
@@ -391,18 +428,38 @@ rmut(p)
 {
        register f;
        int found = 0;
 {
        register f;
        int found = 0;
+       static unsigned utmpsize;
+       static struct utmp *utmp;
+       register struct utmp *u;
+       int nutmp;
+       struct stat statbf;
 
 
-       f = open(utmp, O_RDWR);
+       f = open(utmpf, O_RDWR);
        if (f >= 0) {
        if (f >= 0) {
-               while (read(f, (char *)&wtmp, sizeof(wtmp)) == sizeof(wtmp)) {
-                       if (SCMPN(wtmp.ut_line, p->line) || wtmp.ut_name[0]==0)
-                               continue;
-                       lseek(f, -(long)sizeof(wtmp), 1);
-                       SCPYN(wtmp.ut_name, "");
-                       SCPYN(wtmp.ut_host, "");
-                       time(&wtmp.ut_time);
-                       write(f, (char *)&wtmp, sizeof(wtmp));
-                       found++;
+               fstat(f, &statbf);
+               if (utmpsize < statbf.st_size) {
+                       utmpsize = statbf.st_size + 10 * sizeof(struct utmp);
+                       if (utmp)
+                               utmp = (struct utmp *)realloc(utmp, utmpsize);
+                       else
+                               utmp = (struct utmp *)malloc(utmpsize);
+                       if (!utmp)
+                               syslog(LOG_ERR, "utmp malloc failed");
+               }
+               if (statbf.st_size && utmp) {
+                       nutmp = read(f, utmp, statbf.st_size);
+                       nutmp /= sizeof(struct utmp);
+                       for (u = utmp ; u < &utmp[nutmp] ; u++) {
+                               if (u->ut_name[0] == 0 ||
+                                   SCMPN(u->ut_line, p->line))
+                                       continue;
+                               lseek(f, ((long)u)-((long)utmp), L_SET);
+                               SCPYN(u->ut_name, "");
+                               SCPYN(u->ut_host, "");
+                               time(&u->ut_time);
+                               write(f, (char *)u, sizeof(*u));
+                               found++;
+                       }
                }
                close(f);
        }
                }
                close(f);
        }
@@ -421,6 +478,7 @@ rmut(p)
                 * of error detection code in dfork.
                 */
                p->gettytime = 0;
                 * of error detection code in dfork.
                 */
                p->gettytime = 0;
+               p->windtime = 0;
        }
 }
 
        }
 }
 
@@ -476,22 +534,39 @@ wterm(p)
 wstart(p)
        register struct tab *p;
 {
 wstart(p)
        register struct tab *p;
 {
-       int npid = fork();
+       register pid;
+       time_t t;
+       int dowait = 0;
 
 
-       if (npid == 0) {
-/*
+       time(&t);
+       p->windcnt++;
+       if ((t - p->windtime) >= 60) {
+               p->windtime = t;
+               p->windcnt = 1;
+       } else if (p->windcnt >= 5) {
+               dowait = 1;
+               p->windtime = t;
+               p->windcnt = 1;
+       }
+
+       pid = fork();
+
+       if (pid == 0) {
                signal(SIGTERM, SIG_DFL);
                signal(SIGTERM, SIG_DFL);
-               signal(SIGHUP,  SIG_DFL);
-               signal(SIGALRM, SIG_DFL);
-               signal(SIGTSTP, SIG_IGN);
-*/
+               signal(SIGHUP,  SIG_IGN);
+               sigsetmask(0);  /* since can be called from masked code */
+               if (dowait) {
+                       syslog(LOG_ERR, "'%s %s' failing, sleeping", p->wcmd, p->line);
+                       closelog();
+                       sleep(30);
+               }
                execit(p->wcmd, p->line);
                exit(0);
        }
                execit(p->wcmd, p->line);
                exit(0);
        }
-       p->wpid = npid;
+       p->wpid = pid;
 }
 
 }
 
-#define NARGS  20      /* must be at lease 4 */
+#define NARGS  20      /* must be at least 4 */
 #define ARGLEN 512     /* total size for all the argument strings */
 
 execit(s, arg)
 #define ARGLEN 512     /* total size for all the argument strings */
 
 execit(s, arg)