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: char copyright[] =
   9: "@(#) Copyright (c) 1980,1986 Regents of the University of California.\n\
  10:  All rights reserved.\n";
  11: 
  12: static char sccsid[] = "@(#)reboot.c	5.5.4 (2.11BSD) 1997/10/3";
  13: #endif
  14: 
  15: /*
  16:  * Reboot ...
  17:  */
  18: 
  19: #include <stdio.h>
  20: #include <errno.h>
  21: #include <pwd.h>
  22: #include <sysexits.h>
  23: #include <unistd.h>
  24: #include <sys/syslog.h>
  25: #include <sys/file.h>
  26: #include <sys/reboot.h>
  27: #include <sys/signal.h>
  28: 
  29: #define OPTS    "lqnhdarsfRD"
  30: 
  31: main(argc, argv)
  32:     int argc;
  33:     char **argv;
  34: {
  35:     int howto;      /* reboot options argument */
  36:     int needlog = 1;    /* tell syslog what's happening */
  37:     int quickly = 0;    /* go down quickly & ungracefully */
  38:     char *myname;       /* name we were invoked as */
  39:     char args[20], *ap; /* collected arguments for syslog */
  40:     int i;
  41:     char *rindex();
  42: 
  43:     if (myname = rindex(argv[0], '/'))
  44:         myname++;
  45:     else
  46:         myname = argv[0];
  47:     if (strcmp(myname, "halt") == 0)
  48:         howto = RB_HALT;
  49:     else if (strcmp(myname, "fasthalt") == 0)
  50:         howto = RB_HALT|RB_NOFSCK;
  51:     else if (strcmp(myname, "fastboot") == 0)
  52:         howto = RB_NOFSCK;
  53:     else
  54:         howto = 0;
  55: 
  56:     ap = args;
  57:     *ap++ = '-';
  58:     *ap = '\0';
  59:     while ((i = getopt(argc, argv, OPTS)) != EOF) {
  60:         switch((char)i) {
  61:             case 'l':  needlog = 0;     break;
  62:             case 'q':  quickly++;       break;
  63:             case 'n':  howto |= RB_NOSYNC;  break;
  64:             case 'h':  howto |= RB_HALT;    break;
  65:             case 'd':  howto |= RB_DUMP;    break;
  66:             case 'a':  howto |= RB_ASKNAME; break;
  67:             case 'r':  howto |= RB_RDONLY;  break;
  68:             case 's':  howto |= RB_SINGLE;  break;
  69:             case 'f':  howto |= RB_NOFSCK;  break;
  70:             case 'R':  howto |= RB_DFLTROOT; break;
  71:             case 'D':  howto |= RB_AUTODEBUG; break;
  72:             case '?':
  73:                 fprintf(stderr,
  74:                     "usage: %s [-%s]\n", myname, OPTS);
  75:                 exit(EX_USAGE);
  76:                 /*NOTREACHED*/
  77:         }
  78:         if (index(args+1, (char)i) == 0) {
  79:             *ap++ = (char)i;
  80:             *ap = '\0';
  81:         }
  82:     }
  83: 
  84:     if ((howto & (RB_NOSYNC|RB_NOFSCK)) == (RB_NOSYNC|RB_NOFSCK)
  85:         && !(howto & RB_HALT)) {
  86:         fprintf(stderr,
  87:             "%s: no sync and no fsck are a dangerous combination; no fsck ignored.\n",
  88:             myname);
  89:         howto &= ~RB_NOFSCK;
  90:     }
  91:     if (needlog) {
  92:         char *user;
  93:         struct passwd *pw;
  94: 
  95:         user = getlogin();
  96:         if (user == (char *)0 && (pw = getpwuid(getuid())))
  97:             user = pw->pw_name;
  98:         if (user == (char *)0)
  99:             user = "root";
 100:         openlog(myname, 0, LOG_AUTH);
 101:         syslog(LOG_CRIT, "%s; %s by %s",
 102:             args, (howto&RB_HALT)?"halted":"rebooted", user);
 103:     }
 104: /*
 105:  * Do a sync early on so disks start transfers while we're killing
 106:  * processes.
 107: */
 108:     if (!(howto & RB_NOSYNC))
 109:         sync();
 110: 
 111:     (void) signal(SIGHUP, SIG_IGN); /* for remote connections */
 112:     if (kill(1, SIGTSTP) == -1) {
 113:         fprintf(stderr, "%s: can\'t idle init\n", myname);
 114:         exit(EX_NOPERM);
 115:     }
 116:     sleep(1);
 117:     (void) kill(-1, SIGTERM);   /* one chance to catch it */
 118: 
 119: /*
 120:  * After the processes receive the TERM signal start the rest of the
 121:  * buffers out to disk.  Wait five seconds between SIGTERM and SIGKILL so
 122:  * the processes have a chance to clean up and exit nicely.
 123: */
 124:     sleep(2);
 125:     if (!(howto & RB_NOSYNC))
 126:         sync();
 127:     sleep(3);
 128: 
 129:     if (!quickly)
 130:         for (i = 1; ; i++) {
 131:             if (kill(-1, SIGKILL) == -1) {
 132:                 if (errno == ESRCH)
 133:                     break;
 134:                 perror(myname);
 135:                 kill(1, SIGHUP);
 136:                 exit(EX_OSERR);
 137:             }
 138:             if (i > 5) {
 139:                 fprintf(stderr,
 140:                     "CAUTION: some process(es) wouldn't die\n");
 141:                 break;
 142:             }
 143:             sleep(2 * i);
 144:         }
 145: 
 146:     if (!quickly && (howto & RB_NOSYNC) == 0) {
 147:         markdown();
 148:         sync();
 149:         sleep(5);
 150:     }
 151:     reboot(howto);
 152:     perror(myname);
 153:     kill(1, SIGHUP);
 154:     exit(EX_OSERR);
 155: }
 156: 
 157: 
 158: /*
 159:  * Make shutdown entry in /usr/adm/utmp.
 160:  */
 161: #include <utmp.h>
 162: 
 163: #define SCPYN(a, b) strncpy(a, b, sizeof(a))
 164: #define WTMPF       "/usr/adm/wtmp"
 165: 
 166: markdown()
 167: {
 168:     struct utmp wtmp;
 169:     register int f = open(WTMPF, O_WRONLY|O_APPEND);
 170: 
 171:     if (f >= 0) {
 172:         bzero((char *)&wtmp, sizeof(wtmp));
 173:         SCPYN(wtmp.ut_line, "~");
 174:         SCPYN(wtmp.ut_name, "shutdown");
 175:         SCPYN(wtmp.ut_host, "");
 176:         (void) time(&wtmp.ut_time);
 177:         write(f, (char *)&wtmp, sizeof(wtmp));
 178:         close(f);
 179:     }
 180: }

Defined functions

main defined in line 31; never used
markdown defined in line 166; used 1 times

Defined variables

copyright defined in line 8; never used
sccsid defined in line 12; never used

Defined macros

OPTS defined in line 29; used 2 times
SCPYN defined in line 163; used 3 times
WTMPF defined in line 164; used 1 times
Last modified: 1997-10-03
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 926
Valid CSS Valid XHTML 1.0 Strict