1: /*
   2:  * Copyright (c) 1980,1986 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #if defined(DOSCCS) && !defined(lint)
   8: static char sccsid[] = "@(#)init.c	5.6.4 (2.11BSD) 1999/2/23";
   9: #endif
  10: 
  11: #include <sys/param.h>
  12: #include <sys/sysctl.h>
  13: #include <signal.h>
  14: #include <utmp.h>
  15: #include <setjmp.h>
  16: #include <sys/reboot.h>
  17: #include <errno.h>
  18: #include <sys/file.h>
  19: #include <ttyent.h>
  20: #include <sys/syslog.h>
  21: #include <sys/stat.h>
  22: #include <paths.h>
  23: 
  24: #define LINSIZ  sizeof(wtmp.ut_line)
  25: #define CMDSIZ  200 /* max string length for getty or window command*/
  26: #define ALL p = itab; p ; p = p->next
  27: #define EVER    ;;
  28: #define SCPYN(a, b) strncpy(a, b, sizeof(a))
  29: #define SCMPN(a, b) strncmp(a, b, sizeof(a))
  30: 
  31: char    shell[] = _PATH_BSHELL;
  32: char    minus[] = "-";
  33: char    runc[]  = "/etc/rc";
  34: char    utmpf[] = _PATH_UTMP;
  35: char    wtmpf[] = _PATH_WTMP;
  36: char    ctty[]  = _PATH_CONSOLE;
  37: 
  38: struct utmp wtmp;
  39: struct  tab
  40: {
  41:     char    line[LINSIZ];
  42:     char    comn[CMDSIZ];
  43:     char    xflag;
  44:     int pid;
  45:     int wpid;       /* window system pid for SIGHUP	*/
  46:     char    wcmd[CMDSIZ];   /* command to start window system process */
  47:     time_t  gettytime;
  48:     int gettycnt;
  49:     time_t  windtime;
  50:     int windcnt;
  51:     struct  tab *next;
  52: } *itab;
  53: 
  54: int fi;
  55: int mergflag;
  56: char    tty[20];
  57: jmp_buf sjbuf, shutpass;
  58: time_t  time0;
  59: 
  60: int reset();
  61: int idle();
  62: char    *strcpy(), *strcat();
  63: long    lseek();
  64: time_t  time();
  65: void    setsecuritylevel();
  66: int getsecuritylevel();
  67: int badsys();
  68: extern  int errno;
  69: 
  70: struct  sigvec rvec = { reset, sigmask(SIGHUP), 0 };
  71: 
  72: 
  73: #ifdef vax
  74: main()
  75: {
  76:     register int r11;       /* passed thru from boot */
  77: #else
  78: main(argc, argv)
  79:     char **argv;
  80: {
  81: #endif
  82:     int howto, oldhowto;
  83: 
  84:     time0 = time(0);
  85: #ifdef vax
  86:     howto = r11;
  87: #else
  88: #ifdef pdp11
  89:     if (argc > 1 && argv[1][0] == '-') {
  90:         howto = atoi(argv[1]+1);
  91:         bzero(argv[1], strlen(argv[1])); /* keep ps output clean ... */
  92:     } else
  93:         howto = RB_SINGLE;
  94: #else
  95:     if (argc > 1 && argv[1][0] == '-') {
  96:         char *cp;
  97: 
  98:         howto = 0;
  99:         cp = &argv[1][1];
 100:         while (*cp) switch (*cp++) {
 101:         case 'a':
 102:             howto |= RB_ASKNAME;
 103:             break;
 104:         case 's':
 105:             howto |= RB_SINGLE;
 106:             break;
 107:         }
 108:     } else {
 109:         howto = RB_SINGLE;
 110:     }
 111: #endif
 112: #endif
 113:     if (getuid() != 0)
 114:         exit(1);
 115:     if (getpid() != 1)
 116:         exit(1);
 117: 
 118:     openlog("init", LOG_CONS|LOG_ODELAY, LOG_AUTH);
 119: #ifdef pdp11
 120:     if (autoconfig(howto) == 0)
 121:         howto = RB_SINGLE | (howto & RB_AUTODEBUG);
 122: #endif
 123:     signal(SIGSYS, badsys);
 124:     sigvec(SIGTERM, &rvec, (struct sigvec *)0);
 125:     signal(SIGTSTP, idle);
 126:     signal(SIGSTOP, SIG_IGN);
 127:     signal(SIGTTIN, SIG_IGN);
 128:     signal(SIGTTOU, SIG_IGN);
 129:     (void) setjmp(sjbuf);
 130:     for (EVER) {
 131:         oldhowto = howto;
 132:         howto = RB_SINGLE;
 133:         if (setjmp(shutpass) == 0)
 134:             shutdown();
 135:         if (oldhowto & RB_SINGLE)
 136:             single();
 137:         if (runcom(oldhowto) == 0)
 138:             continue;
 139:         merge();
 140:         multiple();
 141:     }
 142: }
 143: 
 144: int shutreset();
 145: 
 146: shutdown()
 147: {
 148:     register i;
 149:     register struct tab *p, *p1;
 150: 
 151:     close(creat(utmpf, 0644));
 152:     signal(SIGHUP, SIG_IGN);
 153:     for (p = itab; p ; ) {
 154:         term(p);
 155:         p1 = p->next;
 156:         free(p);
 157:         p = p1;
 158:     }
 159:     itab = (struct tab *)0;
 160:     signal(SIGALRM, shutreset);
 161:     (void) kill(-1, SIGTERM);   /* one chance to catch it */
 162:     sleep(5);
 163:     alarm(30);
 164:     for (i = 0; i < 5; i++)
 165:         kill(-1, SIGKILL);
 166:     while (wait((int *)0) != -1)
 167:         ;
 168:     alarm(0);
 169:     shutend();
 170: }
 171: 
 172: char shutfailm[] = "WARNING: Something is hung (wont die); ps axl advised\n";
 173: 
 174: shutreset()
 175: {
 176:     int status;
 177: 
 178:     if (fork() == 0) {
 179:         int ct = open(ctty, 1);
 180:         write(ct, shutfailm, sizeof (shutfailm));
 181:         sleep(5);
 182:         exit(1);
 183:     }
 184:     sleep(5);
 185:     shutend();
 186:     longjmp(shutpass, 1);
 187: }
 188: 
 189: shutend()
 190: {
 191:     register i, f;
 192: 
 193:     signal(SIGALRM, SIG_DFL);
 194:     for (i = 0; i < 10; i++)
 195:         close(i);
 196:     f = open(wtmpf, O_WRONLY|O_APPEND);
 197:     if (f >= 0) {
 198:         SCPYN(wtmp.ut_line, "~");
 199:         SCPYN(wtmp.ut_name, "shutdown");
 200:         SCPYN(wtmp.ut_host, "");
 201:         time(&wtmp.ut_time);
 202:         write(f, (char *)&wtmp, sizeof(wtmp));
 203:         close(f);
 204:     }
 205:     return (1);
 206: }
 207: 
 208: /*
 209:  * Catch a SIGSYS signal.
 210:  *
 211:  * These may arise if a system does not support sysctl.
 212:  * We tolerate up to 25 of these, then throw in the towel.
 213:  */
 214: int
 215: badsys(sig)
 216:     int sig;
 217: {
 218:     static int badcount = 0;
 219: 
 220:     if (badcount++ < 25)
 221:         return;
 222:     syslog(LOG_EMERG, "fatal signal: %d", sig);
 223:     sleep(30);
 224:     _exit(sig);
 225: }
 226: 
 227: /*
 228:  * Get the security level of the kernel.
 229:  */
 230: int
 231: getsecuritylevel()
 232: {
 233: #ifdef KERN_SECURELVL
 234:     int name[2], curlevel;
 235:     size_t len;
 236: 
 237:     name[0] = CTL_KERN;
 238:     name[1] = KERN_SECURELVL;
 239:     len = sizeof curlevel;
 240:     if (sysctl(name, 2, &curlevel, &len, NULL, 0) == -1) {
 241:         syslog(LOG_EMERG, "cannot get kernel security level: %s",
 242:             strerror(errno));
 243:         return (-1);
 244:     }
 245:     return (curlevel);
 246: #else
 247:     return (-1);
 248: #endif
 249: }
 250: 
 251: /*
 252:  * Set the security level of the kernel.
 253:  */
 254: void
 255: setsecuritylevel(newlevel)
 256:     int newlevel;
 257: {
 258: #ifdef KERN_SECURELVL
 259:     int name[2], curlevel;
 260: 
 261:     curlevel = getsecuritylevel();
 262:     if (newlevel == curlevel)
 263:         return;
 264:     name[0] = CTL_KERN;
 265:     name[1] = KERN_SECURELVL;
 266:     if (sysctl(name, 2, NULL, NULL, &newlevel, sizeof newlevel) == -1) {
 267:         syslog(LOG_EMERG,
 268:             "cannot change kernel security level from %d to %d: %s",
 269:             curlevel, newlevel, strerror(errno));
 270:         return;
 271:     }
 272:     syslog(LOG_ALERT, "kernel security level changed from %d to %d",
 273:         curlevel, newlevel);
 274: #endif
 275: }
 276: 
 277: single()
 278: {
 279:     register pid;
 280:     register xpid;
 281:     int fd;
 282: 
 283:     /*
 284: 	 * If the kernel is in secure mode, downgrade it to insecure mode.
 285: 	 */
 286:     if (getsecuritylevel() > 0)
 287:         setsecuritylevel(0);
 288: 
 289:     do {
 290:         pid = fork();
 291:         if (pid == 0) {
 292:             signal(SIGTERM, SIG_DFL);
 293:             signal(SIGHUP, SIG_DFL);
 294:             signal(SIGALRM, SIG_DFL);
 295:             signal(SIGTSTP, SIG_IGN);
 296:             fd = open(ctty, O_RDWR, 0);
 297:             if  (fd)
 298:                 dup2(fd, 0);
 299:             dup2(0, 1);
 300:             dup2(0, 2);
 301:             execl(shell, minus, (char *)0);
 302:             perror(shell);
 303:             exit(0);
 304:         }
 305:         while ((xpid = wait((int *)0)) != pid)
 306:             if (xpid == -1 && errno == ECHILD)
 307:                 break;
 308:     } while (xpid == -1);
 309: }
 310: 
 311: runcom(oldhowto)
 312:     int oldhowto;
 313: {
 314:     register pid, f;
 315:     int status;
 316:     char *arg1, *arg2;
 317: 
 318:     pid = fork();
 319:     if (pid == 0) {
 320:         f = open("/", O_RDONLY);
 321:         if  (f)
 322:             dup2(f, 0);
 323:         dup2(0, 1);
 324:         dup2(0, 2);
 325: #ifdef pdp11
 326:         if (oldhowto & (RB_SINGLE|RB_NOFSCK))
 327:             arg1 = "fastboot";
 328:         else
 329:             arg1 = "autoboot";
 330:         if (oldhowto & RB_POWRFAIL)
 331:             arg2 = "powerfail";
 332:         else
 333:             arg2 = (char *)0;
 334:         execl(shell, shell, runc, arg1, arg2, (char *)0);
 335: #else
 336:         if (oldhowto & RB_SINGLE)
 337:             execl(shell, shell, runc, (char *)0);
 338:         else
 339:             execl(shell, shell, runc, "autoboot", (char *)0);
 340: #endif
 341:         exit(1);
 342:     }
 343:     while (wait(&status) != pid)
 344:         ;
 345:     if (status)
 346:         return (0);
 347:     f = open(wtmpf, O_WRONLY|O_APPEND);
 348:     if (f >= 0) {
 349:         SCPYN(wtmp.ut_line, "~");
 350:         SCPYN(wtmp.ut_name, "reboot");
 351:         SCPYN(wtmp.ut_host, "");
 352:         if (time0) {
 353:             wtmp.ut_time = time0;
 354:             time0 = 0;
 355:         } else
 356:             time(&wtmp.ut_time);
 357:         write(f, (char *)&wtmp, sizeof(wtmp));
 358:         close(f);
 359:     }
 360:     return (1);
 361: }
 362: 
 363: #ifdef pdp11
 364: int merge();
 365: #endif
 366: struct  sigvec  mvec = { merge, sigmask(SIGTERM), 0 };
 367: /*
 368:  * Multi-user.  Listen for users leaving, SIGHUP's
 369:  * which indicate ttys has changed, and SIGTERM's which
 370:  * are used to shutdown the system.
 371:  */
 372: multiple()
 373: {
 374:     register struct tab *p;
 375:     register pid;
 376:     long omask;
 377: 
 378:     /*
 379: 	 * If the administrator has not set the security level to -1
 380: 	 * to indicate that the kernel should not run multiuser in secure
 381: 	 * mode, and the run script has not set a higher level of security
 382: 	 * than level 1, then put the kernel into secure mode.
 383: 	 */
 384:     if (getsecuritylevel() == 0)
 385:         setsecuritylevel(1);
 386: 
 387:     sigvec(SIGHUP, &mvec, (struct sigvec *)0);
 388:     for (EVER) {
 389:         pid = wait((int *)0);
 390:         if (pid == -1)
 391:             return;
 392:         omask = sigblock(sigmask(SIGHUP));
 393:         for (ALL) {
 394:             /* must restart window system BEFORE emulator */
 395:             if (p->wpid == pid || p->wpid == -1)
 396:                 wstart(p);
 397:             if (p->pid == pid || p->pid == -1) {
 398:                 /* disown the window system */
 399:                 if (p->wpid)
 400:                     kill(p->wpid, SIGHUP);
 401:                 rmut(p);
 402:                 dfork(p);
 403:             }
 404:         }
 405:         sigsetmask(omask);
 406:     }
 407: }
 408: 
 409: /*
 410:  * Merge current contents of ttys file
 411:  * into in-core table of configured tty lines.
 412:  * Entered as signal handler for SIGHUP.
 413:  */
 414: #define FOUND   1
 415: #define CHANGE  2
 416: #define WCHANGE 4
 417: 
 418: merge()
 419: {
 420:     register struct tab *p;
 421:     register struct ttyent *t;
 422:     register struct tab *p1;
 423: 
 424:     for (ALL)
 425:         p->xflag = 0;
 426:     setttyent();
 427:     while (t = getttyent()) {
 428:         if ((t->ty_status & TTY_ON) == 0)
 429:             continue;
 430:         for (ALL) {
 431:             if (SCMPN(p->line, t->ty_name))
 432:                 continue;
 433:             p->xflag |= FOUND;
 434:             if (SCMPN(p->comn, t->ty_getty)) {
 435:                 p->xflag |= CHANGE;
 436:                 SCPYN(p->comn, t->ty_getty);
 437:             }
 438:             if (SCMPN(p->wcmd, t->ty_window ? t->ty_window : "")) {
 439:                 p->xflag |= WCHANGE|CHANGE;
 440:                 SCPYN(p->wcmd, t->ty_window);
 441:             }
 442:             goto contin1;
 443:         }
 444: 
 445:         /*
 446: 		 * Make space for a new one
 447: 		 */
 448:         p1 = (struct tab *)calloc(1, sizeof(*p1));
 449:         if (!p1) {
 450:             syslog(LOG_ERR, "no space for '%s' !?!", t->ty_name);
 451:             goto contin1;
 452:         }
 453:         /*
 454: 		 * Put new terminal at the end of the linked list.
 455: 		 */
 456:         if (itab) {
 457:             for (p = itab; p->next ; p = p->next)
 458:                 ;
 459:             p->next = p1;
 460:         } else
 461:             itab = p1;
 462: 
 463:         p = p1;
 464:         SCPYN(p->line, t->ty_name);
 465:         p->xflag |= FOUND|CHANGE;
 466:         SCPYN(p->comn, t->ty_getty);
 467:         if (t->ty_window && strcmp(t->ty_window, "") != 0) {
 468:             p->xflag |= WCHANGE;
 469:             SCPYN(p->wcmd, t->ty_window);
 470:         }
 471:     contin1:
 472:         ;
 473:     }
 474:     endttyent();
 475:     p1 = (struct tab *)0;
 476:     for (ALL) {
 477:         if ((p->xflag&FOUND) == 0) {
 478:             term(p);
 479:             wterm(p);
 480:             if (p1)
 481:                 p1->next = p->next;
 482:             else
 483:                 itab = p->next;
 484:             free(p);
 485:             p = p1 ? p1 : itab;
 486:         } else {
 487:             /* window system should be started first */
 488:             if (p->xflag&WCHANGE) {
 489:                 wterm(p);
 490:                 wstart(p);
 491:             }
 492:             if (p->xflag&CHANGE) {
 493:                 term(p);
 494:                 dfork(p);
 495:             }
 496:         }
 497:         p1 = p;
 498:     }
 499: }
 500: 
 501: term(p)
 502:     register struct tab *p;
 503: {
 504: 
 505:     if (p->pid != 0) {
 506:         rmut(p);
 507:         kill(p->pid, SIGKILL);
 508:     }
 509:     p->pid = 0;
 510:     /* send SIGHUP to get rid of connections */
 511:     if (p->wpid > 0)
 512:         kill(p->wpid, SIGHUP);
 513: }
 514: 
 515: dfork(p)
 516:     struct tab *p;
 517: {
 518:     register pid;
 519:     time_t t;
 520:     int dowait = 0;
 521: 
 522:     time(&t);
 523:     p->gettycnt++;
 524:     if ((t - p->gettytime) >= 60) {
 525:         p->gettytime = t;
 526:         p->gettycnt = 1;
 527:     } else if (p->gettycnt >= 5) {
 528:         dowait = 1;
 529:         p->gettytime = t;
 530:         p->gettycnt = 1;
 531:     }
 532:     pid = fork();
 533:     if (pid == 0) {
 534:         signal(SIGTERM, SIG_DFL);
 535:         signal(SIGHUP, SIG_IGN);
 536:         sigsetmask(0L); /* since can be called from masked code */
 537:         if (dowait) {
 538:             syslog(LOG_ERR, "'%s %s' failing, sleeping", p->comn, p->line);
 539:             closelog();
 540:             sleep(30);
 541:         }
 542:         execit(p->comn, p->line);
 543:         exit(0);
 544:     }
 545:     p->pid = pid;
 546: }
 547: 
 548: /*
 549:  * Remove utmp entry.
 550:  */
 551: rmut(p)
 552:     register struct tab *p;
 553: {
 554:     register f;
 555:     int found = 0;
 556:     static unsigned utmpsize;
 557:     static struct utmp *utmp;
 558:     register struct utmp *u;
 559:     int nutmp;
 560:     struct stat statbf;
 561: 
 562:     f = open(utmpf, O_RDWR);
 563:     if (f >= 0) {
 564:         fstat(f, &statbf);
 565:         if (utmpsize < statbf.st_size) {
 566:             utmpsize = statbf.st_size + 10 * sizeof(struct utmp);
 567:             if (utmp)
 568:                 utmp = (struct utmp *)realloc(utmp, utmpsize);
 569:             else
 570:                 utmp = (struct utmp *)malloc(utmpsize);
 571:             if (!utmp)
 572:                 syslog(LOG_ERR, "utmp malloc failed");
 573:         }
 574:         if (statbf.st_size && utmp) {
 575:             nutmp = read(f, utmp, (int)statbf.st_size);
 576:             nutmp /= sizeof(struct utmp);
 577:             for (u = utmp ; u < &utmp[nutmp] ; u++) {
 578:                 if (SCMPN(u->ut_line, p->line) ||
 579:                     u->ut_name[0]==0)
 580:                     continue;
 581:                 lseek(f, ((long)u)-((long)utmp), L_SET);
 582:                 SCPYN(u->ut_name, "");
 583:                 SCPYN(u->ut_host, "");
 584:                 time(&u->ut_time);
 585:                 write(f, (char *)u, sizeof(*u));
 586:                 found++;
 587:             }
 588:         }
 589:         close(f);
 590:     }
 591:     if (found) {
 592:         f = open(wtmpf, O_WRONLY|O_APPEND);
 593:         if (f >= 0) {
 594:             SCPYN(wtmp.ut_line, p->line);
 595:             SCPYN(wtmp.ut_name, "");
 596:             SCPYN(wtmp.ut_host, "");
 597:             time(&wtmp.ut_time);
 598:             write(f, (char *)&wtmp, sizeof(wtmp));
 599:             close(f);
 600:         }
 601:         /*
 602: 		 * After a proper login force reset
 603: 		 * of error detection code in dfork.
 604: 		 */
 605:         p->gettytime = 0;
 606:         p->windtime = 0;
 607:     }
 608: }
 609: 
 610: reset()
 611: {
 612: 
 613:     longjmp(sjbuf, 1);
 614: }
 615: 
 616: jmp_buf idlebuf;
 617: 
 618: idlehup()
 619: {
 620: 
 621:     longjmp(idlebuf, 1);
 622: }
 623: 
 624: idle()
 625: {
 626:     register struct tab *p;
 627:     register pid;
 628: 
 629:     signal(SIGHUP, idlehup);
 630:     for (EVER) {
 631:         if (setjmp(idlebuf))
 632:             return;
 633:         pid = wait((int *) 0);
 634:         if (pid == -1) {
 635:             sigpause(0L);
 636:             continue;
 637:         }
 638:         for (ALL) {
 639:             /* if window system dies, mark it for restart */
 640:             if (p->wpid == pid)
 641:                 p->wpid = -1;
 642:             if (p->pid == pid) {
 643:                 rmut(p);
 644:                 p->pid = -1;
 645:             }
 646:         }
 647:     }
 648: }
 649: 
 650: wterm(p)
 651:     register struct tab *p;
 652: {
 653:     if (p->wpid != 0) {
 654:         kill(p->wpid, SIGKILL);
 655:     }
 656:     p->wpid = 0;
 657: }
 658: 
 659: wstart(p)
 660:     register struct tab *p;
 661: {
 662:     register pid;
 663:     time_t t;
 664:     int dowait = 0;
 665: 
 666:     time(&t);
 667:     p->windcnt++;
 668:     if ((t - p->windtime) >= 60) {
 669:         p->windtime = t;
 670:         p->windcnt = 1;
 671:     } else if (p->windcnt >= 5) {
 672:         dowait = 1;
 673:         p->windtime = t;
 674:         p->windcnt = 1;
 675:     }
 676: 
 677:     pid = fork();
 678: 
 679:     if (pid == 0) {
 680:         signal(SIGTERM, SIG_DFL);
 681:         signal(SIGHUP,  SIG_IGN);
 682:         sigsetmask(0L); /* since can be called from masked code */
 683:         if (dowait) {
 684:             syslog(LOG_ERR, "'%s %s' failing, sleeping", p->wcmd, p->line);
 685:             closelog();
 686:             sleep(30);
 687:         }
 688:         execit(p->wcmd, p->line);
 689:         exit(0);
 690:     }
 691:     p->wpid = pid;
 692: }
 693: 
 694: #define NARGS   20  /* must be at least 4 */
 695: #define ARGLEN  512 /* total size for all the argument strings */
 696: 
 697: execit(s, arg)
 698:     char *s;
 699:     char *arg;  /* last argument on line */
 700: {
 701:     char *argv[NARGS], args[ARGLEN], *envp[1];
 702:     register char *sp = s;
 703:     register char *ap = args;
 704:     register char c;
 705:     register int i;
 706: 
 707:     /*
 708: 	 * First we have to set up the argument vector.
 709: 	 * "prog arg1 arg2" maps to exec("prog", "-", "arg1", "arg2").
 710: 	 */
 711:     for (i = 1; i < NARGS - 2; i++) {
 712:         argv[i] = ap;
 713:         for (EVER) {
 714:             if ((c = *sp++) == '\0' || ap >= &args[ARGLEN-1]) {
 715:                 *ap = '\0';
 716:                 goto done;
 717:             }
 718:             if (c == ' ') {
 719:                 *ap++ = '\0';
 720:                 while (*sp == ' ')
 721:                     sp++;
 722:                 if (*sp == '\0')
 723:                     goto done;
 724:                 break;
 725:             }
 726:             *ap++ = c;
 727:         }
 728:     }
 729: done:
 730:     argv[0] = argv[1];
 731:     argv[1] = "-";
 732:     argv[i+1] = arg;
 733:     argv[i+2] = 0;
 734:     envp[0] = 0;
 735:     execve(argv[0], &argv[1], envp);
 736:     /* report failure of exec */
 737:     syslog(LOG_ERR, "%s: %m", argv[0]);
 738:     closelog();
 739:     sleep(10);  /* prevent failures from eating machine */
 740: }
 741: 
 742: #ifdef pdp11
 743: #include <machine/autoconfig.h>
 744: 
 745: autoconfig(howto)
 746:     int howto;
 747: {
 748:     int pid, status, f;
 749:     static char config[]= "/etc/autoconfig";
 750: 
 751:     if (!(pid = fork())) {
 752:         syslog(LOG_NOTICE, "configure system\n");
 753:         f = open(ctty, O_RDWR, 0);
 754:         if  (f)
 755:             dup2(f, 0);
 756:         dup2(0, 1);
 757:         dup2(0, 2);
 758:         execl(config, "autoconfig",
 759:              howto & RB_AUTODEBUG ? "-vcd" : "-vc", 0);
 760:         syslog(LOG_ERR, "init: couldn't exec %s\n", config);
 761:         exit(AC_SETUP);
 762:     }
 763:     while (wait(&status) != pid);
 764:     if ((status & 0377) == 0)
 765:         status >>= 8;
 766:     else
 767:         status = AC_SINGLE;
 768:     switch (status) {
 769:         case AC_SETUP:
 770:             syslog(LOG_ERR, "configuration setup error\n");
 771:             return (0);
 772:         case AC_SINGLE:
 773:             syslog(LOG_ERR, "SERIOUS CONFIGURATION ERROR\7\7\7\n");
 774:             return (0);
 775:         case AC_OK:
 776:             return (1);
 777:         default:
 778:             syslog(LOG_ERR, "unrecognized return from configure\n");
 779:             return (0);
 780:     }
 781: }
 782: #endif

Defined functions

autoconfig defined in line 745; used 1 times
badsys defined in line 214; used 2 times
dfork defined in line 515; used 2 times
execit defined in line 697; used 2 times
getsecuritylevel defined in line 230; used 4 times
idle defined in line 624; used 2 times
idlehup defined in line 618; used 1 times
main defined in line 78; never used
merge defined in line 418; used 3 times
multiple defined in line 372; used 1 times
reset defined in line 610; used 2 times
rmut defined in line 551; used 3 times
runcom defined in line 311; used 1 times
setsecuritylevel defined in line 254; used 3 times
shutdown defined in line 146; used 1 times
shutend defined in line 189; used 2 times
shutreset defined in line 174; used 2 times
single defined in line 277; used 1 times
term defined in line 501; used 3 times
wstart defined in line 659; used 2 times
wterm defined in line 650; used 2 times

Defined variables

ctty defined in line 36; used 3 times
fi defined in line 54; never used
idlebuf defined in line 616; used 2 times
itab defined in line 52; used 8 times
mergflag defined in line 55; never used
minus defined in line 32; used 1 times
mvec defined in line 366; used 1 times
runc defined in line 33; used 3 times
rvec defined in line 70; used 1 times
sccsid defined in line 8; never used
shell defined in line 31; used 8 times
shutfailm defined in line 172; used 2 times
  • in line 180(2)
shutpass defined in line 57; used 2 times
sjbuf defined in line 57; used 2 times
time0 defined in line 58; used 4 times
tty defined in line 56; never used
utmpf defined in line 34; used 2 times
wtmp defined in line 38; used 20 times
wtmpf defined in line 35; used 3 times

Defined struct's

tab defined in line 39; used 28 times

Defined macros

ALL defined in line 26; used 5 times
ARGLEN defined in line 695; used 2 times
CHANGE defined in line 415; used 4 times
CMDSIZ defined in line 25; used 2 times
EVER defined in line 27; used 4 times
FOUND defined in line 414; used 3 times
LINSIZ defined in line 24; used 1 times
  • in line 41
NARGS defined in line 694; used 2 times
SCMPN defined in line 29; used 4 times
SCPYN defined in line 28; used 16 times
WCHANGE defined in line 416; used 3 times
Last modified: 1999-02-24
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 5861
Valid CSS Valid XHTML 1.0 Strict