Annotation of cci/usr/src/etc/init.c, revision 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.