# 2.11BSD#431 - /usr/src/sbin/shutdown/shutdown.c

##### Functions

    doitfast          X
    finish            X
    getsdt            X
    main              X
    nolog             X
    timeout           X
    warn              X

##### Variables

    alarmbuf          X
    copyright         X
    doreboot          X
    fast              X
    fastboot          X
    halt              X
    hostname          X
    interval          X
    killflg           X
    nlflag            X
    nolog1            X
    nolog2            X
    nologin           X
    nosync            X
    nosyncflag        X
    nowtime           X
    shutter           X
    sint              X
    stogo             X
    tbuf              X
    term              X
    tpath             X
    utmp              X

##### Macros

    HALT              X
    HOURS             X
    IGNOREUSER        X
    MAXINTS           X
    MINUTES           X
    NLOG              X
    NOLOGTIME         X
    REBOOT            X
    SECONDS           X

##### struct's

    interval          X

       1: /*
       2:  * Copyright (c) 1983,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) 1983,1986 Regents of the University of California.\n\
      10:  All rights reserved.\n";
      11:
      12: static char sccsid[] = "@(#)shutdown.c	5.6.3 (2.11BSD GTE) 1997/10/3";
      13: #endif
      14:
      15: #include <stdio.h>
      16: #include <ctype.h>
      17: #include <signal.h>
      18: #include <setjmp.h>
      19: #include <utmp.h>
      20: #include <pwd.h>
      21: #include <paths.h>
      22: #include <string.h>
      23: #include <stdlib.h>
      24: #include <unistd.h>
      25: #include <sys/time.h>
      26: #include <sys/resource.h>
      27: #include <sys/param.h>
      28: #include <sys/syslog.h>
      29:
      30: /*
      31:  *	shutdown when [messages]
      32:  *
      33:  *	allow super users to tell users and remind users
      34:  *	of imminent shutdown of unix
      35:  *	and shut it down automatically
      36:  *	and even reboot or halt the machine if they desire
      37:  */
      38:
      39: #define REBOOT  "/sbin/reboot"
      40: #define HALT    "/sbin/halt"
      41: #define MAXINTS 20
      42: #define HOURS   *3600
      43: #define MINUTES *60
      44: #define SECONDS
      45: #define NLOG        600     /* no of bytes possible for message */
      46: #define NOLOGTIME   5 MINUTES
      47: #define IGNOREUSER  "sleeper"
      48:
      49: char    hostname[MAXHOSTNAMELEN];
      50:
      51: int timeout();
      52: time_t  getsdt();
      53:
      54: struct  utmp utmp;
      55: int sint;
      56: long    stogo;
      57: char    tpath[] =   "/dev/";
      58: int nlflag = 1;     /* nolog yet to be done */
      59: int killflg = 1;
      60: int doreboot = 0;
      61: int halt = 0;
      62: int     fast = 0;
      63: char    *nosync = NULL;
      64: char    nosyncflag[] = "-n";
      65: char    term[sizeof tpath + sizeof utmp.ut_line];
      66: char    tbuf[BUFSIZ];
      67: char    nolog1[] = "\n\nNO LOGINS: System going down at %5.5s\n\n";
      68: char    nolog2[NLOG+1];
      69: #ifdef  DEBUG
      70: char    nologin[] = "nologin";
      71: char    fastboot[] = "fastboot";
      72: #else
      73: char    nologin[] = _PATH_NOLOGIN;
      74: char    fastboot[] = "/fastboot";
      75: #endif
      76: time_t  nowtime;
      77: jmp_buf alarmbuf;
      78:
      79: struct interval {
      80:     int stogo;
      81:     int sint;
      82: } interval[] = {
      83:     4 HOURS,    1 HOURS,
      84:     2 HOURS,    30 MINUTES,
      85:     1 HOURS,    15 MINUTES,
      86:     30 MINUTES, 10 MINUTES,
      87:     15 MINUTES, 5 MINUTES,
      88:     10 MINUTES, 5 MINUTES,
      89:     5 MINUTES,  3 MINUTES,
      90:     2 MINUTES,  1 MINUTES,
      91:     1 MINUTES,  30 SECONDS,
      92:     0 SECONDS,  0 SECONDS
      93: };
      94:
      95: char *shutter;
      96:
      97: main(argc,argv)
      98:     int argc;
      99:     char **argv;
     100: {
     101:     register i, ufd;
     102:     register char *f;
     103:     char *ts;
     104:     time_t sdt;
     105:     int h, m;
     106:     int first;
     107:     FILE *termf;
     108:     struct passwd *pw;
     109:
     110:     shutter = getlogin();
     111:     if (shutter == 0 && (pw = getpwuid(getuid())))
     112:         shutter = pw->pw_name;
     113:     if (shutter == 0)
     114:         shutter = "???";
     115:     (void) gethostname(hostname, sizeof (hostname));
     116:     openlog("shutdown", 0, LOG_AUTH);
     117:     argc--, argv++;
     118:     while (argc > 0 && (f = argv[0], *f++ == '-')) {
     119:         while (i = *f++) switch (i) {
     120:         case 'k':
     121:             killflg = 0;
     122:             continue;
     123:         case 'n':
     124:             nosync = nosyncflag;
     125:             continue;
     126:         case 'f':
     127:             fast = 1;
     128:             continue;
     129:         case 'r':
     130:             doreboot = 1;
     131:             continue;
     132:         case 'h':
     133:             halt = 1;
     134:             continue;
     135:         default:
     136:             fprintf(stderr, "shutdown: '%c' - unknown flag\n", i);
     137:             exit(1);
     138:         }
     139:         argc--, argv++;
     140:     }
     141:     if (argc < 1) {
     142:             /* argv[0] is not available after the argument handling. */
     143:         printf("Usage: shutdown [ -krhfn ] shutdowntime [ message ]\n");
     144:         finish();
     145:     }
     146:     if (fast && (nosync == nosyncflag)) {
     147:             printf ("shutdown: Incompatible switches 'fast' & 'nosync'\n");
     148:         finish();
     149:     }
     150:     if (geteuid()) {
     151:         fprintf(stderr, "NOT super-user\n");
     152:         finish();
     153:     }
     154:     nowtime = time((long *)0);
     155:     sdt = getsdt(argv[0]);
     156:     argc--, argv++;
     157:     nolog2[0] = '\0';
     158:     while (argc-- > 0) {
     159:         (void) strcat(nolog2, " ");
     160:         (void) strcat(nolog2, *argv++);
     161:     }
     162:     m = ((stogo = sdt - nowtime) + 30)/60;
     163:     h = m/60;
     164:     m %= 60;
     165:     ts = ctime(&sdt);
     166:     printf("Shutdown at %5.5s (in ", ts+11);
     167:     if (h > 0)
     168:         printf("%d hour%s ", h, h != 1 ? "s" : "");
     169:     printf("%d minute%s) ", m, m != 1 ? "s" : "");
     170: #ifndef DEBUG
     171:     (void) signal(SIGHUP, SIG_IGN);
     172:     (void) signal(SIGQUIT, SIG_IGN);
     173:     (void) signal(SIGINT, SIG_IGN);
     174: #endif
     175:     (void) signal(SIGTTOU, SIG_IGN);
     176:     (void) signal(SIGTERM, finish);
     177:     (void) signal(SIGALRM, timeout);
     178:     (void) setpriority(PRIO_PROCESS, 0, PRIO_MIN);
     179:     (void) fflush(stdout);
     180: #ifndef DEBUG
     181:     if (i = fork()) {
     182:         printf("[pid %d]\n", i);
     183:         exit(0);
     184:     }
     185: #else
     186:     (void) putc('\n', stdout);
     187: #endif
     188:     sint = 1 HOURS;
     189:     f = "";
     190:     ufd = open(_PATH_UTMP,0);
     191:     if (ufd < 0) {
     192:         err(1, "%s", _PATH_UTMP);
     193:         /* NOTREACHED */
     194:     }
     195:     first = 1;
     196:     for (;;) {
     197:         for (i = 0; stogo <= interval[i].stogo && interval[i].sint; i++)
     198:             sint = interval[i].sint;
     199:         if (stogo > 0 && (stogo-sint) < interval[i].stogo)
     200:             sint = stogo - interval[i].stogo;
     201:         if (stogo <= NOLOGTIME && nlflag) {
     202:             nlflag = 0;
     203:             nolog(sdt);
     204:         }
     205:         if (sint >= stogo || sint == 0)
     206:             f = "FINAL ";
     207:         nowtime = time((long *)0);
     208:         (void) lseek(ufd, 0L, 0);
     209:         while (read(ufd,(char *)&utmp,sizeof utmp)==sizeof utmp)
     210:         if (utmp.ut_name[0] &&
     211:             strncmp(utmp.ut_name, IGNOREUSER, sizeof(utmp.ut_name))) {
     212:             if (setjmp(alarmbuf))
     213:                 continue;
     214:             (void) strcpy(term, tpath);
     215:             (void) strncat(term, utmp.ut_line, sizeof utmp.ut_line);
     216:             (void) alarm(3);
     217: #ifdef DEBUG
     218:             if ((termf = stdout) != NULL)
     219: #else
     220:             if ((termf = fopen(term, "w")) != NULL)
     221: #endif
     222:             {
     223:                 (void) alarm(0);
     224:                 setbuf(termf, tbuf);
     225:                 fprintf(termf, "\n\r\n");
     226:                 warn(termf, sdt, nowtime, f);
     227:                 if (first || sdt - nowtime > 1 MINUTES) {
     228:                     if (*nolog2)
     229:                         fprintf(termf, "\t...%s", nolog2);
     230:                 }
     231:                 (void) fputc('\r', termf);
     232:                 (void) fputc('\n', termf);
     233:                 (void) alarm(5);
     234: #ifdef DEBUG
     235:                 (void) fflush(termf);
     236: #else
     237:                 (void) fclose(termf);
     238: #endif
     239:                 (void) alarm(0);
     240:             }
     241:         }
     242:         if (stogo <= 0) {
     243:             printf("\n\007\007System shutdown time has arrived\007\007\n");
     244:             syslog(LOG_CRIT, "%s by %s: %s",
     245:                 doreboot ? "reboot" : halt ? "halt" : "shutdown",
     246:                 shutter, nolog2);
     247:             sleep(2);
     248:             (void) unlink(nologin);
     249:             if (!killflg) {
     250:                 printf("but you'll have to do it yourself\n");
     251:                 finish();
     252:             }
     253:             if (fast)
     254:                 doitfast();
     255: #ifndef DEBUG
     256:             if (doreboot)
     257:                 execle(REBOOT, "reboot", "-l", nosync, 0, 0);
     258:             if (halt)
     259:                 execle(HALT, "halt", "-l", nosync, 0, 0);
     260:             (void) kill(1, SIGTERM);    /* to single user */
     261: #else
     262:             if (doreboot)
     263:                 printf("REBOOT");
     264:             if (halt)
     265:                 printf(" HALT");
     266:             if (fast)
     267:                 printf(" -l %s (without fsck's)\n", nosync);
     268:             else
     269:                 printf(" -l %s\n", nosync);
     270:             else
     271:                 printf("kill -HUP 1\n");
     272:
     273: #endif
     274:             finish();
     275:         }
     276:         stogo = sdt - time((long *) 0);
     277:         if (stogo > 0 && sint > 0)
     278:             sleep((unsigned)(sint<stogo ? sint : stogo));
     279:         stogo -= sint;
     280:         first = 0;
     281:     }
     282: }
     283:
     284: time_t
     285: getsdt(s)
     286:     register char *s;
     287: {
     288:     time_t t, t1, tim;
     289:     register char c;
     290:     struct tm *lt;
     291:
     292:     if (strcmp(s, "now") == 0)
     293:         return(nowtime);
     294:     if (*s == '+') {
     295:         ++s;
     296:         t = 0;
     297:         for (;;) {
     298:             c = *s++;
     299:             if (!isdigit(c))
     300:                 break;
     301:             t = t * 10 + c - '0';
     302:         }
     303:         if (t <= 0)
     304:             t = 5;
     305:         t *= 60;
     306:         tim = time((long *) 0) + t;
     307:         return(tim);
     308:     }
     309:     t = 0;
     310:     while (strlen(s) > 2 && isdigit(*s))
     311:         t = t * 10 + *s++ - '0';
     312:     if (*s == ':')
     313:         s++;
     314:     if (t > 23)
     315:         goto badform;
     316:     tim = t*60;
     317:     t = 0;
     318:     while (isdigit(*s))
     319:         t = t * 10 + *s++ - '0';
     320:     if (t > 59)
     321:         goto badform;
     322:     tim += t;
     323:     tim *= 60;
     324:     t1 = time((long *) 0);
     325:     lt = localtime(&t1);
     326:     t = lt->tm_sec + lt->tm_min*60 + (long)lt->tm_hour*3600;
     327:     if (tim < t || tim >= ((long)24*3600)) {
     328:         /* before now or after midnight */
     329:         printf("That must be tomorrow\nCan't you wait till then?\n");
     330:         finish();
     331:     }
     332:     return (t1 + tim - t);
     333: badform:
     334:     printf("Bad time format\n");
     335:     finish();
     336:     /*NOTREACHED*/
     337: }
     338:
     339: warn(term, sdt, now, type)
     340:     FILE *term;
     341:     time_t sdt, now;
     342:     char *type;
     343: {
     344:     char *ts;
     345:     register delay = sdt - now;
     346:
     347:     if (delay > 8)
     348:         while (delay % 5)
     349:             delay++;
     350:
     351:     fprintf(term,
     352:         "\007\007\t*** %sSystem shutdown message from %s@%s ***\r\n\n",
     353:             type, shutter, hostname);
     354:
     355:     ts = ctime(&sdt);
     356:     if (delay > 10 MINUTES)
     357:         fprintf(term, "System going down at %5.5s\r\n", ts+11);
     358:     else if (delay > 95 SECONDS) {
     359:         fprintf(term, "System going down in %d minute%s\r\n",
     360:             (delay+30)/60, (delay+30)/60 != 1 ? "s" : "");
     361:     } else if (delay > 0) {
     362:         fprintf(term, "System going down in %d second%s\r\n",
     363:             delay, delay != 1 ? "s" : "");
     364:     } else
     365:         fprintf(term, "System going down IMMEDIATELY\r\n");
     366: }
     367:
     368: doitfast()
     369: {
     370:     register FILE *fastd;
     371:
     372:     if ((fastd = fopen(fastboot, "w")) != NULL) {
     373:         putc('\n', fastd);
     374:         (void) fclose(fastd);
     375:     }
     376: }
     377:
     378: nolog(sdt)
     379:     time_t sdt;
     380: {
     381:     register FILE *nologf;
     382:
     383:     (void) unlink(nologin);         /* in case linked to std file */
     384:     if ((nologf = fopen(nologin, "w")) != NULL) {
     385:         fprintf(nologf, nolog1, (ctime(&sdt)) + 11);
     386:         if (*nolog2)
     387:             fprintf(nologf, "\t%s\n", nolog2 + 1);
     388:         (void) fclose(nologf);
     389:     }
     390: }
     391:
     392: finish()
     393: {
     394:     (void) signal(SIGTERM, SIG_IGN);
     395:     (void) unlink(nologin);
     396:     exit(0);
     397: }
     398:
     399: timeout()
     400: {
     401:     longjmp(alarmbuf, 1);
     402: }

#### Defined functions

doitfast defined in line 368; used 1 times

- in line 254

finish defined in line 392; used 8 times

- in line 144-152(3), 176, 251, 274, 330-335(2)

getsdt defined in line 284; used 2 times

- in line 52, 155

main defined in line 97; never used
nolog defined in line 378; used 1 times

- in line 203

timeout defined in line 399; used 2 times

- in line 51, 177

warn defined in line 339; used 1 times

- in line 226

#### Defined variables

alarmbuf defined in line 77; used 2 times

- in line 212, 401

copyright defined in line 8; never used
doreboot defined in line 60; used 4 times

- in line 130, 245, 256, 262

fast defined in line 62; used 4 times

- in line 127, 146, 253, 266

fastboot defined in line 74; used 1 times

- in line 372

halt defined in line 61; used 4 times

- in line 133, 245, 258, 264

hostname defined in line 49; used 3 times

- in line 115(2), 353

interval defined in line 82; used 5 times

- in line 197-200(5)

killflg defined in line 59; used 2 times

- in line 121, 249

nlflag defined in line 58; used 2 times

- in line 201-202(2)

nolog1 defined in line 67; used 1 times

- in line 385

nolog2 defined in line 68; used 8 times

- in line 157-160(3), 228-229(2), 246, 386-387(2)

nologin defined in line 73; used 4 times

- in line 248, 383-384(2), 395

nosync defined in line 63; used 6 times

- in line 124, 146, 257-259(2), 267-269(2)

nosyncflag defined in line 64; used 2 times

- in line 124, 146

nowtime defined in line 76; used 6 times

- in line 154, 162, 207, 226-227(2), 293

sccsid defined in line 12; never used
shutter defined in line 95; used 7 times

- in line 110-114(5), 246, 353

sint defined in line 55; used 13 times

- in line 81, 188, 197-205(7), 277-279(4)

stogo defined in line 56; used 17 times

- in line 80, 162, 197-205(9), 242, 276-279(5)

tbuf defined in line 66; used 1 times

- in line 224

term defined in line 65; used 10 times

- in line 214-220(3), 339-340(2), 351, 357-365(4)

tpath defined in line 57; used 2 times

- in line 65, 214

utmp defined in line 54; used 9 times

- in line 65, 209-215(8)

#### Defined struct's

interval defined in line 79; never used

#### Defined macros

HALT defined in line 40; used 1 times

- in line 259

HOURS defined in line 42; used 5 times

- in line 83-85(4), 188

IGNOREUSER defined in line 47; used 1 times

- in line 211

MAXINTS defined in line 41; never used
MINUTES defined in line 43; used 16 times

- in line 46, 84-91(13), 227, 356

NLOG defined in line 45; used 1 times

- in line 68

NOLOGTIME defined in line 46; used 1 times

- in line 201

REBOOT defined in line 39; used 1 times

- in line 257

SECONDS defined in line 44; used 4 times

- in line 91-92(3), 358

Last modified: 1997-10-03 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2296 |