[BACK]Return to shutdown.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sbin / shutdown

Annotation of src/sbin/shutdown/shutdown.c, Revision 1.55

1.55    ! joerg       1: /*     $NetBSD: shutdown.c,v 1.54 2011/02/16 19:33:48 wiz Exp $        */
1.9       cgd         2:
1.1       cgd         3: /*
1.7       mycroft     4:  * Copyright (c) 1988, 1990, 1993
                      5:  *     The Regents of the University of California.  All rights reserved.
1.1       cgd         6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
1.40      agc        15:  * 3. Neither the name of the University nor the names of its contributors
1.1       cgd        16:  *    may be used to endorse or promote products derived from this software
                     17:  *    without specific prior written permission.
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     20:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     21:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     22:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     23:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     24:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     25:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     26:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     27:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     28:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     29:  * SUCH DAMAGE.
                     30:  */
                     31:
1.14      lukem      32: #include <sys/cdefs.h>
1.1       cgd        33: #ifndef lint
1.51      lukem      34: __COPYRIGHT("@(#) Copyright (c) 1988, 1990, 1993\
                     35:  The Regents of the University of California.  All rights reserved.");
1.1       cgd        36: #endif /* not lint */
                     37:
                     38: #ifndef lint
1.9       cgd        39: #if 0
1.15      lukem      40: static char sccsid[] = "@(#)shutdown.c 8.4 (Berkeley) 4/28/95";
1.9       cgd        41: #else
1.55    ! joerg      42: __RCSID("$NetBSD: shutdown.c,v 1.54 2011/02/16 19:33:48 wiz Exp $");
1.9       cgd        43: #endif
1.1       cgd        44: #endif /* not lint */
                     45:
                     46: #include <sys/param.h>
                     47: #include <sys/time.h>
                     48: #include <sys/resource.h>
                     49: #include <sys/syslog.h>
1.7       mycroft    50:
                     51: #include <ctype.h>
1.19      mycroft    52: #include <err.h>
1.7       mycroft    53: #include <fcntl.h>
                     54: #include <pwd.h>
1.1       cgd        55: #include <setjmp.h>
1.7       mycroft    56: #include <signal.h>
                     57: #include <stdio.h>
                     58: #include <stdlib.h>
                     59: #include <string.h>
1.26      kleink     60: #include <time.h>
1.1       cgd        61: #include <tzfile.h>
1.7       mycroft    62: #include <unistd.h>
1.47      christos   63: #include <errno.h>
1.7       mycroft    64:
1.1       cgd        65: #include "pathnames.h"
                     66:
                     67: #ifdef DEBUG
                     68: #undef _PATH_NOLOGIN
                     69: #define        _PATH_NOLOGIN   "./nologin"
                     70: #undef _PATH_FASTBOOT
                     71: #define        _PATH_FASTBOOT  "./fastboot"
                     72: #endif
                     73:
                     74: #define        H               *60*60
                     75: #define        M               *60
                     76: #define        S               *1
                     77: #define        NOLOG_TIME      5*60
1.47      christos   78: static const struct interval {
                     79:        time_t timeleft, timetowait;
1.1       cgd        80: } tlist[] = {
1.13      mikel      81:        { 10 H,  5 H }, {  5 H,  3 H }, {  2 H,  1 H }, { 1 H, 30 M },
                     82:        { 30 M, 10 M }, { 20 M, 10 M }, { 10 M,  5 M }, { 5 M,  3 M },
                     83:        {  2 M,  1 M }, {  1 M, 30 S }, { 30 S, 30 S },
                     84:        {  0, 0 }
1.7       mycroft    85: };
1.1       cgd        86: #undef H
                     87: #undef M
                     88: #undef S
                     89:
                     90: static time_t offset, shuttime;
1.47      christos   91: static int dofast, dohalt, doreboot, killflg, nofork, nosync, dodump;
                     92: static size_t mbuflen;
1.27      thorpej    93: static int dopowerdown;
1.53      dyoung     94: static int dodebug, dosilent, doverbose;
1.29      mycroft    95: static const char *whom;
                     96: static char mbuf[BUFSIZ];
1.47      christos   97: static char *bootstr;
1.1       cgd        98:
1.49      perry      99: static void badtime(void) __dead;
                    100: static void die_you_gravy_sucking_pig_dog(void) __dead;
1.47      christos  101: static void doitfast(void);
1.55    ! joerg     102: static void dorcshutdown(void);
1.49      perry     103: static void finish(int) __dead;
1.47      christos  104: static void getoffset(char *);
1.55    ! joerg     105: static void loop(void) __dead;
1.47      christos  106: static void nolog(void);
1.55    ! joerg     107: static void timeout(int) __dead;
1.47      christos  108: static void timewarn(time_t);
1.49      perry     109: static void usage(void) __dead;
1.5       cgd       110:
1.7       mycroft   111: int
1.43      xtraeme   112: main(int argc, char *argv[])
1.1       cgd       113: {
1.14      lukem     114:        char *p, *endp;
1.7       mycroft   115:        struct passwd *pw;
1.47      christos  116:        size_t arglen, len;
                    117:        int ch;
1.1       cgd       118:
1.47      christos  119:        (void)setprogname(argv[0]);
1.1       cgd       120: #ifndef DEBUG
1.19      mycroft   121:        if (geteuid())
1.50      dholland  122:                errx(1, "%s: Not super-user", strerror(EPERM));
1.1       cgd       123: #endif
1.53      dyoung    124:        while ((ch = getopt(argc, argv, "b:Ddfhknprvxz")) != -1)
1.1       cgd       125:                switch (ch) {
1.39      atatat    126:                case 'b':
                    127:                        bootstr = optarg;
                    128:                        break;
1.19      mycroft   129:                case 'd':
                    130:                        dodump = 1;
1.1       cgd       131:                        break;
1.25      fair      132:                case 'D':
                    133:                        nofork = 1;
                    134:                        break;
1.1       cgd       135:                case 'f':
                    136:                        dofast = 1;
                    137:                        break;
1.27      thorpej   138:                case 'p':
                    139:                        dopowerdown = 1;
                    140:                        /* FALLTHROUGH */
1.1       cgd       141:                case 'h':
                    142:                        dohalt = 1;
                    143:                        break;
                    144:                case 'k':
                    145:                        killflg = 1;
                    146:                        break;
                    147:                case 'n':
1.11      mikel     148:                        nosync = 1;
1.1       cgd       149:                        break;
                    150:                case 'r':
                    151:                        doreboot = 1;
                    152:                        break;
1.53      dyoung    153:                case 'v':
                    154:                        doverbose = 1;
                    155:                        break;
                    156:                case 'x':
                    157:                        dodebug = 1;
                    158:                        break;
                    159:                case 'z':
                    160:                        dosilent = 1;
                    161:                        break;
1.1       cgd       162:                case '?':
                    163:                default:
                    164:                        usage();
                    165:                }
                    166:        argc -= optind;
                    167:        argv += optind;
                    168:
                    169:        if (argc < 1)
                    170:                usage();
                    171:
1.20      mycroft   172:        if (dodump && !dohalt && !doreboot)
                    173:                doreboot = 1;
                    174:
1.1       cgd       175:        if (dofast && nosync) {
1.50      dholland  176:                warnx("Incompatible options -f and -n");
1.1       cgd       177:                usage();
                    178:        }
1.20      mycroft   179:        if (dohalt && doreboot) {
1.27      thorpej   180:                const char *which_flag = dopowerdown ? "p" : "h";
                    181:
1.50      dholland  182:                warnx("Incompatible options -%s and -r", which_flag);
1.12      jtk       183:                usage();
                    184:        }
1.19      mycroft   185:
1.1       cgd       186:        getoffset(*argv++);
                    187:
1.30      ross      188:        if (argv[0]) {
1.21      mycroft   189:                if (strcmp(argv[0], "-") || argv[1]) {
1.19      mycroft   190:                        for (p = mbuf, len = sizeof(mbuf); *argv; ++argv) {
                    191:                                arglen = strlen(*argv);
                    192:                                if ((len -= arglen) <= 2)
                    193:                                        break;
                    194:                                if (p != mbuf)
                    195:                                        *p++ = ' ';
1.47      christos  196:                                (void)memmove(p, *argv, arglen);
1.19      mycroft   197:                                p += arglen;
                    198:                        }
                    199:                        *p = '\n';
                    200:                        *++p = '\0';
                    201:                } else {
                    202:                        p = mbuf;
                    203:                        endp = mbuf + sizeof(mbuf) - 2;
                    204:                        for (;;) {
                    205:                                if (!fgets(p, endp - p + 1, stdin))
                    206:                                        break;
                    207:                                for (; *p &&  p < endp; ++p);
                    208:                                if (p == endp) {
                    209:                                        *p = '\n';
                    210:                                        *++p = '\0';
                    211:                                        break;
                    212:                                }
1.1       cgd       213:                        }
                    214:                }
1.30      ross      215:        }
1.1       cgd       216:        mbuflen = strlen(mbuf);
                    217:
                    218:        if (offset)
                    219:                (void)printf("Shutdown at %.24s.\n", ctime(&shuttime));
                    220:        else
                    221:                (void)printf("Shutdown NOW!\n");
                    222:
                    223:        if (!(whom = getlogin()))
                    224:                whom = (pw = getpwuid(getuid())) ? pw->pw_name : "???";
                    225:
                    226: #ifdef DEBUG
                    227:        (void)putc('\n', stdout);
                    228: #else
                    229:        (void)setpriority(PRIO_PROCESS, 0, PRIO_MIN);
1.25      fair      230:        if (nofork == 0) {
1.1       cgd       231:                int forkpid;
                    232:
                    233:                forkpid = fork();
                    234:                if (forkpid == -1) {
                    235:                        perror("shutdown: fork");
                    236:                        exit(1);
                    237:                }
                    238:                if (forkpid) {
                    239:                        (void)printf("shutdown: [pid %d]\n", forkpid);
                    240:                        exit(0);
                    241:                }
1.46      jnemeth   242:                (void)setsid();
1.1       cgd       243:        }
                    244: #endif
                    245:        openlog("shutdown", LOG_CONS, LOG_AUTH);
                    246:        loop();
1.7       mycroft   247:        /* NOTREACHED */
1.13      mikel     248: #ifdef __GNUC__
                    249:        return 1;
                    250: #endif
1.1       cgd       251: }
                    252:
1.55    ! joerg     253: static void
1.43      xtraeme   254: loop(void)
1.1       cgd       255: {
1.47      christos  256:        const struct interval *tp;
1.1       cgd       257:        u_int sltime;
                    258:        int logged;
                    259:
                    260:        if (offset <= NOLOG_TIME) {
                    261:                logged = 1;
                    262:                nolog();
                    263:        }
                    264:        else
                    265:                logged = 0;
                    266:        tp = tlist;
                    267:        if (tp->timeleft < offset)
                    268:                (void)sleep((u_int)(offset - tp->timeleft));
                    269:        else {
                    270:                while (offset < tp->timeleft)
                    271:                        ++tp;
                    272:                /*
1.7       mycroft   273:                 * Warn now, if going to sleep more than a fifth of
1.1       cgd       274:                 * the next wait time.
                    275:                 */
1.13      mikel     276:                if ((sltime = offset - tp->timeleft) != 0) {
1.1       cgd       277:                        if (sltime > tp->timetowait / 5)
1.7       mycroft   278:                                timewarn(offset);
1.1       cgd       279:                        (void)sleep(sltime);
                    280:                }
                    281:        }
                    282:        for (;; ++tp) {
1.7       mycroft   283:                timewarn(tp->timeleft);
1.1       cgd       284:                if (!logged && tp->timeleft <= NOLOG_TIME) {
                    285:                        logged = 1;
                    286:                        nolog();
                    287:                }
                    288:                (void)sleep((u_int)tp->timetowait);
                    289:                if (!tp->timeleft)
                    290:                        break;
                    291:        }
                    292:        die_you_gravy_sucking_pig_dog();
                    293: }
                    294:
                    295: static jmp_buf alarmbuf;
                    296:
1.55    ! joerg     297: static void
1.47      christos  298: timewarn(time_t timeleft)
1.1       cgd       299: {
                    300:        static int first;
                    301:        static char hostname[MAXHOSTNAMELEN + 1];
1.7       mycroft   302:        FILE *pf;
1.1       cgd       303:        char wcmd[MAXPATHLEN + 4];
                    304:
1.28      mrg       305:        if (!first++) {
1.1       cgd       306:                (void)gethostname(hostname, sizeof(hostname));
1.28      mrg       307:                hostname[sizeof(hostname) - 1] = '\0';
                    308:        }
1.1       cgd       309:
                    310:        /* undoc -n option to wall suppresses normal wall banner */
1.28      mrg       311:        (void)snprintf(wcmd, sizeof wcmd, "%s -n", _PATH_WALL);
1.47      christos  312:        if ((pf = popen(wcmd, "w")) == NULL) {
                    313:                syslog(LOG_ERR, "%s: Can't find `%s' (%m)", getprogname(),
                    314:                    _PATH_WALL);
1.1       cgd       315:                return;
                    316:        }
                    317:
                    318:        (void)fprintf(pf,
                    319:            "\007*** %sSystem shutdown message from %s@%s ***\007\n",
1.5       cgd       320:            timeleft ? "": "FINAL ", whom, hostname);
1.1       cgd       321:
1.5       cgd       322:        if (timeleft > 10*60)
1.1       cgd       323:                (void)fprintf(pf, "System going down at %5.5s\n\n",
                    324:                    ctime(&shuttime) + 11);
1.5       cgd       325:        else if (timeleft > 59)
1.47      christos  326:                (void)fprintf(pf, "System going down in %ld minute%s\n\n",
                    327:                    (long)timeleft / 60, (timeleft > 60) ? "s" : "");
1.5       cgd       328:        else if (timeleft)
1.1       cgd       329:                (void)fprintf(pf, "System going down in 30 seconds\n\n");
                    330:        else
                    331:                (void)fprintf(pf, "System going down IMMEDIATELY\n\n");
                    332:
                    333:        if (mbuflen)
                    334:                (void)fwrite(mbuf, sizeof(*mbuf), mbuflen, pf);
                    335:
                    336:        /*
                    337:         * play some games, just in case wall doesn't come back
1.41      dsainty   338:         * probably unnecessary, given that wall is careful.
1.1       cgd       339:         */
                    340:        if (!setjmp(alarmbuf)) {
                    341:                (void)signal(SIGALRM, timeout);
                    342:                (void)alarm((u_int)30);
                    343:                (void)pclose(pf);
                    344:                (void)alarm((u_int)0);
                    345:                (void)signal(SIGALRM, SIG_DFL);
                    346:        }
                    347: }
                    348:
1.47      christos  349: static void
                    350: /*ARGSUSED*/
1.43      xtraeme   351: timeout(int signo)
1.1       cgd       352: {
                    353:        longjmp(alarmbuf, 1);
                    354: }
                    355:
1.47      christos  356: static void
1.44      xtraeme   357: die_you_gravy_sucking_pig_dog(void)
1.1       cgd       358: {
1.50      dholland  359:        const char *what;
1.1       cgd       360:
1.50      dholland  361:        if (doreboot) {
                    362:                what = "reboot";
                    363:        } else if (dohalt && dopowerdown) {
                    364:                what = "poweroff";
                    365:        } else if (dohalt) {
                    366:                what = "halt";
                    367:        } else {
                    368:                what = "shutdown";
                    369:        }
                    370:
                    371:        syslog(LOG_NOTICE, "%s by %s: %s", what, whom, mbuf);
1.1       cgd       372:        (void)sleep(2);
                    373:
                    374:        (void)printf("\r\nSystem shutdown time has arrived\007\007\r\n");
                    375:        if (killflg) {
                    376:                (void)printf("\rbut you'll have to do it yourself\r\n");
1.7       mycroft   377:                finish(0);
1.1       cgd       378:        }
                    379:        if (dofast)
                    380:                doitfast();
1.33      bad       381:        dorcshutdown();
1.20      mycroft   382:        if (doreboot || dohalt) {
1.53      dyoung    383:                const char *args[20];
1.45      christos  384:                const char **arg, *path;
1.48      jnemeth   385: #ifndef DEBUG
1.47      christos  386:                int serrno;
1.48      jnemeth   387: #endif
1.20      mycroft   388:
                    389:                arg = &args[0];
                    390:                if (doreboot) {
                    391:                        path = _PATH_REBOOT;
                    392:                        *arg++ = "reboot";
                    393:                } else {
                    394:                        path = _PATH_HALT;
                    395:                        *arg++ = "halt";
                    396:                }
1.53      dyoung    397:                if (doverbose)
                    398:                        *arg++ = "-v";
                    399:                if (dodebug)
                    400:                        *arg++ = "-x";
                    401:                if (dosilent)
                    402:                        *arg++ = "-z";
1.20      mycroft   403:                if (dodump)
                    404:                        *arg++ = "-d";
                    405:                if (nosync)
                    406:                        *arg++ = "-n";
1.27      thorpej   407:                if (dopowerdown)
                    408:                        *arg++ = "-p";
1.20      mycroft   409:                *arg++ = "-l";
1.39      atatat    410:                if (bootstr)
                    411:                        *arg++ = bootstr;
1.20      mycroft   412:                *arg++ = 0;
                    413: #ifndef DEBUG
1.52      riz       414:                (void)unlink(_PATH_NOLOGIN);
1.47      christos  415:                (void)execve(path, __UNCONST(args), NULL);
                    416:                serrno = errno;
1.50      dholland  417:                syslog(LOG_ERR, "Can't exec `%s' (%m)", path);
1.47      christos  418:                errno = serrno;
                    419:                warn("Can't exec `%s'", path);
1.20      mycroft   420: #else
                    421:                printf("%s", path);
                    422:                for (arg = &args[0]; *arg; arg++)
                    423:                        printf(" %s", *arg);
                    424:                printf("\n");
                    425: #endif
                    426:        } else {
                    427: #ifndef DEBUG
                    428:                (void)kill(1, SIGTERM);         /* to single user */
1.1       cgd       429: #else
1.20      mycroft   430:                printf("kill 1\n");
                    431: #endif
1.1       cgd       432:        }
1.7       mycroft   433:        finish(0);
1.1       cgd       434: }
                    435:
1.23      mycroft   436: #define        ATOI2(s)        ((s) += 2, ((s)[-2] - '0') * 10 + ((s)[-1] - '0'))
1.1       cgd       437:
1.55    ! joerg     438: static void
1.43      xtraeme   439: getoffset(char *timearg)
1.1       cgd       440: {
1.14      lukem     441:        struct tm *lt;
                    442:        char *p;
1.7       mycroft   443:        time_t now;
1.18      mycroft   444:        int yearset;
1.1       cgd       445:
1.32      enami     446:        (void)time(&now);
1.1       cgd       447:        if (!strcasecmp(timearg, "now")) {              /* now */
                    448:                offset = 0;
1.32      enami     449:                shuttime = now;
1.1       cgd       450:                return;
                    451:        }
                    452:
                    453:        if (*timearg == '+') {                          /* +minutes */
1.42      dsl       454:                if (!isdigit((unsigned char)*++timearg))
1.1       cgd       455:                        badtime();
                    456:                offset = atoi(timearg) * 60;
                    457:                shuttime = now + offset;
                    458:                return;
                    459:        }
                    460:
                    461:        /* handle hh:mm by getting rid of the colon */
                    462:        for (p = timearg; *p; ++p)
1.42      dsl       463:                if (!isascii(*p) || !isdigit((unsigned char)*p)) {
1.1       cgd       464:                        if (*p == ':' && strlen(p) == 3) {
                    465:                                p[0] = p[1];
                    466:                                p[1] = p[2];
                    467:                                p[2] = '\0';
                    468:                        }
                    469:                        else
                    470:                                badtime();
1.30      ross      471:                }
1.1       cgd       472:
1.47      christos  473:        (void)unsetenv("TZ");                           /* OUR timezone */
1.1       cgd       474:        lt = localtime(&now);                           /* current time val */
                    475:
1.18      mycroft   476:        lt->tm_sec = 0;
                    477:
                    478:        yearset = 0;
                    479:        switch (strlen(timearg)) {
                    480:        case 12:
1.23      mycroft   481:                lt->tm_year = ATOI2(timearg) * 100 - TM_YEAR_BASE;
1.18      mycroft   482:                yearset = 1;
                    483:                /* FALLTHROUGH */
1.1       cgd       484:        case 10:
1.18      mycroft   485:                if (yearset) {
1.23      mycroft   486:                        lt->tm_year += ATOI2(timearg);
1.18      mycroft   487:                } else {
                    488:                        yearset = ATOI2(timearg);
                    489:                        if (yearset < 69)
1.23      mycroft   490:                                lt->tm_year = yearset + 2000 - TM_YEAR_BASE;
1.18      mycroft   491:                        else
1.23      mycroft   492:                                lt->tm_year = yearset + 1900 - TM_YEAR_BASE;
1.18      mycroft   493:                }
1.1       cgd       494:                /* FALLTHROUGH */
                    495:        case 8:
                    496:                lt->tm_mon = ATOI2(timearg);
1.18      mycroft   497:                --lt->tm_mon;
1.1       cgd       498:                /* FALLTHROUGH */
                    499:        case 6:
                    500:                lt->tm_mday = ATOI2(timearg);
                    501:                /* FALLTHROUGH */
                    502:        case 4:
                    503:                lt->tm_hour = ATOI2(timearg);
1.18      mycroft   504:                /* FALLTHROUGH */
                    505:        case 2:
1.1       cgd       506:                lt->tm_min = ATOI2(timearg);
                    507:                break;
                    508:        default:
                    509:                badtime();
1.18      mycroft   510:        }
                    511:
                    512:        if ((shuttime = mktime(lt)) == -1)
                    513:                badtime();
1.19      mycroft   514:        if ((offset = shuttime - now) < 0)
                    515:                errx(1, "time is already past");
1.33      bad       516: }
                    517:
1.55    ! joerg     518: static void
1.43      xtraeme   519: dorcshutdown(void)
1.33      bad       520: {
                    521:        (void)printf("\r\nAbout to run shutdown hooks...\r\n");
1.47      christos  522: #ifndef DEBUG
                    523:        (void)setuid(0);
1.38      cgd       524:        (void)system(". " _PATH_RCSHUTDOWN);
1.47      christos  525: #endif
1.37      jdolecek  526:        (void)sleep(5);         /* Give operator a chance to abort this. */
1.36      jdolecek  527:        (void)printf("\r\nDone running shutdown hooks.\r\n");
1.1       cgd       528: }
                    529:
                    530: #define        FSMSG   "fastboot file for fsck\n"
1.55    ! joerg     531: static void
1.43      xtraeme   532: doitfast(void)
1.1       cgd       533: {
                    534:        int fastfd;
                    535:
                    536:        if ((fastfd = open(_PATH_FASTBOOT, O_WRONLY|O_CREAT|O_TRUNC,
                    537:            0664)) >= 0) {
                    538:                (void)write(fastfd, FSMSG, sizeof(FSMSG) - 1);
                    539:                (void)close(fastfd);
                    540:        }
                    541: }
                    542:
                    543: #define        NOMSG   "\n\nNO LOGINS: System going down at "
1.55    ! joerg     544: static void
1.43      xtraeme   545: nolog(void)
1.1       cgd       546: {
                    547:        int logfd;
1.7       mycroft   548:        char *ct;
1.1       cgd       549:
                    550:        (void)unlink(_PATH_NOLOGIN);    /* in case linked to another file */
                    551:        (void)signal(SIGINT, finish);
                    552:        (void)signal(SIGHUP, finish);
                    553:        (void)signal(SIGQUIT, finish);
                    554:        (void)signal(SIGTERM, finish);
                    555:        if ((logfd = open(_PATH_NOLOGIN, O_WRONLY|O_CREAT|O_TRUNC,
                    556:            0664)) >= 0) {
                    557:                (void)write(logfd, NOMSG, sizeof(NOMSG) - 1);
                    558:                ct = ctime(&shuttime);
                    559:                (void)write(logfd, ct + 11, 5);
                    560:                (void)write(logfd, "\n\n", 2);
                    561:                (void)write(logfd, mbuf, strlen(mbuf));
                    562:                (void)close(logfd);
                    563:        }
                    564: }
                    565:
1.47      christos  566: static void
                    567: /*ARGSUSED*/
1.43      xtraeme   568: finish(int signo)
1.1       cgd       569: {
1.28      mrg       570:
1.6       mycroft   571:        if (!killflg)
                    572:                (void)unlink(_PATH_NOLOGIN);
1.1       cgd       573:        exit(0);
                    574: }
                    575:
1.47      christos  576: static void
1.43      xtraeme   577: badtime(void)
1.1       cgd       578: {
1.28      mrg       579:
1.19      mycroft   580:        warnx("illegal time format");
                    581:        usage();
1.1       cgd       582: }
                    583:
1.47      christos  584: static void
1.43      xtraeme   585: usage(void)
1.1       cgd       586: {
1.28      mrg       587:
1.19      mycroft   588:        (void)fprintf(stderr,
1.54      wiz       589:            "Usage: %s [-Ddfhknprvxz] [-b bootstr] time [message ... | -]\n",
1.47      christos  590:            getprogname());
1.1       cgd       591:        exit(1);
                    592: }

CVSweb <webmaster@jp.NetBSD.org>