Annotation of cci/usr/src/etc/init.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char *sccsid = "@(#)init.c      4.12 (Berkeley) 6/12/83";
                      3: #endif
                      4: 
                      5: #include <signal.h>
                      6: #include <sys/types.h>
                      7: #include <utmp.h>
                      8: #include <setjmp.h>
                      9: #include <sys/reboot.h>
                     10: #include <errno.h>
                     11: #include <sys/file.h>
                     12: #include <sys/ioctl.h>
                     13: 
                     14: #define        LINSIZ  sizeof(wtmp.ut_line)
                     15: #define        TABSIZ  150
                     16: #define        ALL     p = &itab[0]; p < &itab[TABSIZ]; p++
                     17: #define        EVER    ;;
                     18: #define SCPYN(a, b)    strncpy(a, b, sizeof(a))
                     19: #define SCMPN(a, b)    strncmp(a, b, sizeof(a))
                     20: #define        mask(s) (1 << ((s)-1))
                     21: 
                     22: char   shell[] = "/bin/sh";
                     23: char   getty[]  = "/etc/getty";
                     24: char   minus[] = "-";
                     25: char   runc[]  = "/etc/rc";
                     26: char   ifile[] = "/etc/ttys";
                     27: char   utmp[]  = "/etc/utmp";
                     28: char   wtmpf[] = "/usr/adm/wtmp";
                     29: char   ctty[]  = "/dev/console";
                     30: char   dev[]   = "/dev/";
                     31: 
                     32: struct utmp wtmp;
                     33: struct
                     34: {
                     35:        char    line[LINSIZ];
                     36:        char    comn;
                     37:        char    flag;
                     38: } line;
                     39: struct tab
                     40: {
                     41:        char    line[LINSIZ];
                     42:        char    comn;
                     43:        char    xflag;
                     44:        int     pid;
                     45:        time_t  gettytime;
                     46:        int     gettycnt;
                     47: } itab[TABSIZ];
                     48: 
                     49: int    fi;
                     50: int    fd;
                     51: int    mergflag;
                     52: char   tty[20];
                     53: jmp_buf        sjbuf, shutpass;
                     54: time_t time0;
                     55: 
                     56: int    reset();
                     57: int    idle();
                     58: char   *strcpy(), *strcat();
                     59: long   lseek();
                     60: 
                     61: struct sigvec rvec = { reset, mask(SIGHUP), 0 };
                     62: 
                     63: #if tahoe || vax
                     64: main()
                     65: {
                     66:        register int dummy;             /* because of... */
                     67:        register int r11;               /* passed thru from boot */
                     68: #else
                     69: main(argc, argv)
                     70:        char **argv;
                     71: {
                     72: #endif
                     73:        int howto, oldhowto;
                     74: 
                     75:        time0 = time(0);
                     76: #if tahoe || vax
                     77:        howto = r11;
                     78: #else
                     79:        if (argc > 1 && argv[1][0] == '-') {
                     80:                char *cp;
                     81: 
                     82:                howto = 0;
                     83:                cp = &argv[1][1];
                     84:                while (*cp) switch (*cp++) {
                     85:                case 'a':
                     86:                        howto |= RB_ASKNAME;
                     87:                        break;
                     88:                case 's':
                     89:                        howto |= RB_SINGLE;
                     90:                        break;
                     91:                }
                     92:        } else {
                     93:                howto = RB_SINGLE;
                     94:        }
                     95: #endif
                     96:        sigvec(SIGTERM, &rvec, (struct sigvec *)0);
                     97:        signal(SIGTSTP, idle);
                     98:        signal(SIGSTOP, SIG_IGN);
                     99:        signal(SIGTTIN, SIG_IGN);
                    100:        signal(SIGTTOU, SIG_IGN);
                    101:        (void) setjmp(sjbuf);
                    102:        for (EVER) {
                    103:                oldhowto = howto;
                    104:                howto = RB_SINGLE;
                    105:                if (setjmp(shutpass) == 0)
                    106:                        shutdown();
                    107:                if (oldhowto & RB_SINGLE)
                    108:                        single();
                    109:                if (runcom(oldhowto) == 0) {
                    110:                        fd = open("/dev/console", O_WRONLY);
                    111:                        write(fd, "init: /etc/rc: returned non-zero status\n", 40);
                    112:                        close(fd);
                    113:                        if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
                    114:                                ioctl(fd, TIOCNOTTY, 0);
                    115:                                close(fd);
                    116:                        }
                    117:                        continue;
                    118:                }
                    119:                merge();
                    120:                multiple();
                    121:        }
                    122: }
                    123: 
                    124: int    shutreset();
                    125: 
                    126: shutdown()
                    127: {
                    128:        register i;
                    129:        register struct tab *p;
                    130: 
                    131:        close(creat(utmp, 0644));
                    132:        signal(SIGHUP, SIG_IGN);
                    133:        for (ALL) {
                    134:                term(p);
                    135:                p->line[0] = 0;
                    136:        }
                    137:        signal(SIGALRM, shutreset);
                    138:        alarm(30);
                    139:        for (i = 0; i < 5; i++)
                    140:                kill(-1, SIGKILL);
                    141:        while (wait((int *)0) != -1)
                    142:                ;
                    143:        alarm(0);
                    144:        shutend();
                    145: }
                    146: 
                    147: char shutfailm[] = "WARNING: Something is hung (wont die); ps axl advised\n";
                    148: 
                    149: shutreset()
                    150: {
                    151:        int status;
                    152: 
                    153:        if (fork() == 0) {
                    154:                int ct = open(ctty, 1);
                    155:                write(ct, shutfailm, sizeof (shutfailm));
                    156:                sleep(5);
                    157:                exit(1);
                    158:        }
                    159:        sleep(5);
                    160:        shutend();
                    161:        longjmp(shutpass, 1);
                    162: }
                    163: 
                    164: shutend()
                    165: {
                    166:        register i, f;
                    167: 
                    168:        acct(0);
                    169:        signal(SIGALRM, SIG_DFL);
                    170:        for (i = 0; i < 10; i++)
                    171:                close(i);
                    172:        f = open(wtmpf, O_WRONLY|O_APPEND);
                    173:        if (f >= 0) {
                    174:                SCPYN(wtmp.ut_line, "~");
                    175:                SCPYN(wtmp.ut_name, "shutdown");
                    176:                SCPYN(wtmp.ut_host, "");
                    177:                time(&wtmp.ut_time);
                    178:                write(f, (char *)&wtmp, sizeof(wtmp));
                    179:                close(f);
                    180:        }
                    181:        return (1);
                    182: }
                    183: 
                    184: single()
                    185: {
                    186:        register pid;
                    187:        register xpid;
                    188:        extern  errno;
                    189: 
                    190:        do {
                    191:                pid = fork();
                    192:                if (pid == 0) {
                    193:                        signal(SIGTERM, SIG_DFL);
                    194:                        signal(SIGHUP, SIG_DFL);
                    195:                        signal(SIGALRM, SIG_DFL);
                    196:                        (void) open(ctty, O_RDWR);
                    197:                        dup2(0, 1);
                    198:                        dup2(0, 2);
                    199:                        execl(shell, minus, (char *)0);
                    200:                        fd = open("/dev/console", O_WRONLY);
                    201:                        write(fd, "init: can't exec /bin/sh\n", 25);
                    202:                        close(fd);
                    203:                        exit(0);
                    204:                }
                    205:                while ((xpid = wait((int *)0)) != pid)
                    206:                        if (xpid == -1 && errno == ECHILD)
                    207:                                break;
                    208:        } while (xpid == -1);
                    209: }
                    210: 
                    211: runcom(oldhowto)
                    212:        int oldhowto;
                    213: {
                    214:        register pid, f;
                    215:        int status;
                    216: 
                    217:        pid = fork();
                    218:        if (pid == 0) {
                    219:                (void) open("/", O_RDONLY);
                    220:                dup2(0, 1);
                    221:                dup2(0, 2);
                    222:                if (oldhowto & RB_SINGLE)
                    223:                        execl(shell, shell, runc, (char *)0);
                    224:                else
                    225:                        execl(shell, shell, runc, "autoboot", (char *)0);
                    226:                fd = open("/dev/console", O_WRONLY);
                    227:                write(fd, "init: can't exec /bin/sh\n", 25);
                    228:                close(fd);
                    229:                exit(1);
                    230:        }
                    231:        while (wait(&status) != pid)
                    232:                ;
                    233:        if (status)
                    234:                return (0);
                    235:        f = open(wtmpf, O_WRONLY|O_APPEND);
                    236:        if (f >= 0) {
                    237:                SCPYN(wtmp.ut_line, "~");
                    238:                SCPYN(wtmp.ut_name, "reboot");
                    239:                SCPYN(wtmp.ut_host, "");
                    240:                if (time0) {
                    241:                        wtmp.ut_time = time0;
                    242:                        time0 = 0;
                    243:                } else
                    244:                        time(&wtmp.ut_time);
                    245:                write(f, (char *)&wtmp, sizeof(wtmp));
                    246:                close(f);
                    247:        }
                    248:        return (1);
                    249: }
                    250: 
                    251: struct sigvec  mvec = { merge, mask(SIGTERM), 0 };
                    252: /*
                    253:  * Multi-user.  Listen for users leaving, SIGHUP's
                    254:  * which indicate ttys has changed, and SIGTERM's which
                    255:  * are used to shutdown the system.
                    256:  */
                    257: multiple()
                    258: {
                    259:        register struct tab *p;
                    260:        register pid;
                    261: 
                    262:        sigvec(SIGHUP, &mvec, (struct sigvec *)0);
                    263:        for (EVER) {
                    264:                pid = wait((int *)0);
                    265:                if (pid == -1)
                    266:                        return;
                    267:                for (ALL)
                    268:                        if (p->pid == pid || p->pid == -1) {
                    269:                                rmut(p);
                    270:                                dfork(p);
                    271:                        }
                    272:        }
                    273: }
                    274: 
                    275: /*
                    276:  * Merge current contents of ttys file
                    277:  * into in-core table of configured tty lines.
                    278:  * Entered as signal handler for SIGHUP.
                    279:  */
                    280: #define        FOUND   1
                    281: #define        CHANGE  2
                    282: 
                    283: merge()
                    284: {
                    285:        register struct tab *p;
                    286: 
                    287:        fi = open(ifile, 0);
                    288:        if (fi < 0)
                    289:                return;
                    290:        for (ALL)
                    291:                p->xflag = 0;
                    292:        while (rline()) {
                    293:                for (ALL) {
                    294:                        if (SCMPN(p->line, line.line))
                    295:                                continue;
                    296:                        p->xflag |= FOUND;
                    297:                        if (line.comn != p->comn) {
                    298:                                p->xflag |= CHANGE;
                    299:                                p->comn = line.comn;
                    300:                        }
                    301:                        goto contin1;
                    302:                }
                    303:                for (ALL) {
                    304:                        if (p->line[0] != 0)
                    305:                                continue;
                    306:                        SCPYN(p->line, line.line);
                    307:                        p->xflag |= FOUND|CHANGE;
                    308:                        p->comn = line.comn;
                    309:                        goto contin1;
                    310:                }
                    311:        contin1:
                    312:                ;
                    313:        }
                    314:        close(fi);
                    315:        for (ALL) {
                    316:                if ((p->xflag&FOUND) == 0) {
                    317:                        term(p);
                    318:                        p->line[0] = 0;
                    319:                }
                    320:                if (p->xflag&CHANGE) {
                    321:                        term(p);
                    322:                        dfork(p);
                    323:                }
                    324:        }
                    325: }
                    326: 
                    327: term(p)
                    328:        register struct tab *p;
                    329: {
                    330: 
                    331:        if (p->pid != 0) {
                    332:                rmut(p);
                    333:                kill(p->pid, SIGKILL);
                    334:        }
                    335:        p->pid = 0;
                    336: }
                    337: 
                    338: rline()
                    339: {
                    340:        register c, i;
                    341: 
                    342: loop:
                    343:        c = get();
                    344:        if (c < 0)
                    345:                return(0);
                    346:        if (c == 0)
                    347:                goto loop;
                    348:        line.flag = c;
                    349:        c = get();
                    350:        if (c <= 0)
                    351:                goto loop;
                    352:        line.comn = c;
                    353:        SCPYN(line.line, "");
                    354:        for (i = 0; i < LINSIZ; i++) {
                    355:                c = get();
                    356:                if (c <= 0)
                    357:                        break;
                    358:                line.line[i] = c;
                    359:        }
                    360:        while (c > 0)
                    361:                c = get();
                    362:        if (line.line[0] == 0)
                    363:                goto loop;
                    364:        if (line.flag == '0')
                    365:                goto loop;
                    366:        strcpy(tty, dev);
                    367:        strncat(tty, line.line, LINSIZ);
                    368:        if (access(tty, 06) < 0)
                    369:                goto loop;
                    370:        return (1);
                    371: }
                    372: 
                    373: get()
                    374: {
                    375:        char b;
                    376: 
                    377:        if (read(fi, &b, 1) != 1)
                    378:                return (-1);
                    379:        if (b == '\n')
                    380:                return (0);
                    381:        return (b);
                    382: }
                    383: 
                    384: dfork(p)
                    385:        struct tab *p;
                    386: {
                    387:        register pid;
                    388:        time_t t;
                    389:        int dowait = 0;
                    390:        extern char *sys_errlist[];
                    391: 
                    392:        time(&t);
                    393:        p->gettycnt++;
                    394:        if ((t - p->gettytime) >= 60) {
                    395:                p->gettytime = t;
                    396:                p->gettycnt = 1;
                    397:        } else {
                    398:                if (p->gettycnt >= 5) {
                    399:                        dowait = 1;
                    400:                        p->gettytime = t;
                    401:                        p->gettycnt = 1;
                    402:                }
                    403:        }
                    404:        pid = fork();
                    405:        if (pid == 0) {
                    406:                int oerrno;
                    407:                extern int errno;
                    408: 
                    409:                signal(SIGTERM, SIG_DFL);
                    410:                signal(SIGHUP, SIG_IGN);
                    411:                strcpy(tty, dev);
                    412:                strncat(tty, p->line, LINSIZ);
                    413:                if (dowait) {
                    414:                        fd = open("/dev/console", O_WRONLY);
                    415:                        write(fd, "init: \r", 7);
                    416:                        write(fd, tty, strlen(tty));
                    417:                        write(fd, ": getty failing, sleeping\n\r", 27);
                    418:                        close(fd);
                    419:                        sleep(30);
                    420:                        if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
                    421:                                ioctl(fd, TIOCNOTTY, 0);
                    422:                                close(fd);
                    423:                        }
                    424:                }
                    425:                chown(tty, 0, 0);
                    426:                chmod(tty, 0622);
                    427:                if (open(tty, O_RDWR) < 0) {
                    428:                        int repcnt = 0;
                    429:                        do {
                    430:                                oerrno = errno;
                    431:                                if (repcnt % 10 == 0) {
                    432:                                        fd = open("/dev/console", O_WRONLY);
                    433:                                        write(fd, "init: \r", 7);
                    434:                                        write(fd, tty, strlen(tty));
                    435:                                        write(fd, ": ", 2);
                    436:                                        write(fd, sys_errlist[oerrno],
                    437:                                                strlen(sys_errlist[oerrno]));
                    438:                                        write(fd, "\n", 1);
                    439:                                        close(fd);
                    440:                                        if ((fd = open("/dev/tty", 2)) >= 0) {
                    441:                                                ioctl(fd, TIOCNOTTY, 0);
                    442:                                                close(fd);
                    443:                                        }
                    444:                                }
                    445:                                repcnt++;
                    446:                                sleep(60);
                    447:                        } while (open(tty, O_RDWR) < 0);
                    448:                        exit(0);        /* have wrong control tty, start over */
                    449:                }
                    450:                vhangup();
                    451:                signal(SIGHUP, SIG_DFL);
                    452:                (void) open(tty, O_RDWR);
                    453:                close(0);
                    454:                dup(1);
                    455:                dup(0);
                    456:                tty[0] = p->comn;
                    457:                tty[1] = 0;
                    458:                execl(getty, minus, tty, (char *)0);
                    459:                fd = open("/dev/console", O_WRONLY);
                    460:                write(fd, "init: can't exec /etc/getty\n", 28);
                    461:                close(fd);
                    462:                exit(0);
                    463:        }
                    464:        p->pid = pid;
                    465: }
                    466: 
                    467: /*
                    468:  * Remove utmp entry.
                    469:  */
                    470: rmut(p)
                    471:        register struct tab *p;
                    472: {
                    473:        register f;
                    474:        int found = 0;
                    475: 
                    476:        f = open(utmp, O_RDWR);
                    477:        if (f >= 0) {
                    478:                while (read(f, (char *)&wtmp, sizeof(wtmp)) == sizeof(wtmp)) {
                    479:                        if (SCMPN(wtmp.ut_line, p->line) || wtmp.ut_name[0]==0)
                    480:                                continue;
                    481:                        lseek(f, -(long)sizeof(wtmp), 1);
                    482:                        SCPYN(wtmp.ut_name, "");
                    483:                        SCPYN(wtmp.ut_host, "");
                    484:                        time(&wtmp.ut_time);
                    485:                        write(f, (char *)&wtmp, sizeof(wtmp));
                    486:                        found++;
                    487:                }
                    488:                close(f);
                    489:        }
                    490:        if (found) {
                    491:                f = open(wtmpf, O_WRONLY|O_APPEND);
                    492:                if (f >= 0) {
                    493:                        SCPYN(wtmp.ut_line, p->line);
                    494:                        SCPYN(wtmp.ut_name, "");
                    495:                        SCPYN(wtmp.ut_host, "");
                    496:                        time(&wtmp.ut_time);
                    497:                        write(f, (char *)&wtmp, sizeof(wtmp));
                    498:                        close(f);
                    499:                }
                    500:        }
                    501: }
                    502: 
                    503: reset()
                    504: {
                    505: 
                    506:        longjmp(sjbuf, 1);
                    507: }
                    508: 
                    509: jmp_buf        idlebuf;
                    510: 
                    511: idlehup()
                    512: {
                    513: 
                    514:        longjmp(idlebuf, 1);
                    515: }
                    516: 
                    517: idle()
                    518: {
                    519:        register struct tab *p;
                    520:        register pid;
                    521: 
                    522:        signal(SIGHUP, idlehup);
                    523:        for (;;) {
                    524:                if (setjmp(idlebuf))
                    525:                        return;
                    526:                pid = wait((int *) 0);
                    527:                if (pid == -1) {
                    528:                        sigpause(0);
                    529:                        continue;
                    530:                }
                    531:                for (ALL)
                    532:                        if (p->pid == pid) {
                    533:                                rmut(p);
                    534:                                p->pid = -1;
                    535:                        }
                    536:        }
                    537: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.