/* * halt: halt or reboot the system * * Copyright (c) 1999 David Parsons. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgement: * * This product includes software developed by David Parsons * (orc@pell.chi.il.us) * * 4. My name may not be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY DAVID PARSONS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID * PARSONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * * usage: halt [-nwd] * reboot [-fnwd] * * -f: (f)orced reboot (don't ask init to do the deed) * -n: (n)o sync before halt or reboot * -w: (w)rite utmp record, but don't actually do anything. * -d: (d)on't write a utmp record. * */ static const char rcsid[] = "Mastodon $Id: halt.c,v 1.9 1999/06/09 10:04:38 orc Exp $"; #include #include #include #include #include #include #include #include #include #include #include "init.h" int polite; /* signal init, even if single user */ int forced = 0; /* do the halt/reboot ourself */ int dosync = 1; /* sync before our demise */ int wtmp = 1; /* write a wtmp record */ int faked = 0; /* pretend to do it */ int halt = 0; /* set nonzero if we're ``halt'' */ char *__progname; /* * spit out an usage message, then exit */ void usage(int iserror) { fprintf(stderr, "usage: %s [-fnwdp]\n", __progname); exit(iserror ? 1 : 0); } /* usage */ /* * halt, or reboot, we can't really tell */ float /* we won't stay afloat for very long */ main(int argc, char **argv) { int opt; char *runlevel = get_runlevel(); __progname = basename(argv[0]); if (strcasecmp(__progname, "halt") == 0) halt = 1; polite = runlevel && (*runlevel == MULTI); opterr = 1; while ((opt = getopt(argc, argv, "fnwdp?")) != EOF) switch (opt) { case 'f': forced = 1; break; case 'p': polite = 1; break; case 'n': dosync = 0; break; case 'w': wtmp = 1; faked = 1; break; case 'd': wtmp = 0; break; case '?': default: usage(opt == '?'); } if (wtmp) log_runlevel(HALT, 0); if (faked) exit(0); if (forced) polite = 0; if (dosync) { sync(); sleep(1); sync(); sleep(1); sync(); sleep(1); } /* If we're forcing it or we're not multiuser, Just Do It (tm), * otherwise ask init to do the deed for us */ if (polite) { if (kill(1, halt ? S_HALT : S_REBOOT) == 0) exit(0); perror("when signalling init"); exit(1); } if (halt) { #if DEBUG fprintf(stderr, "forced halt\n"); #else /* turn off special C-A-D handling */ reboot(0xfee1dead, 672274793, 0xCDEF0123); /* try to kill all 'dem nasty processes off */ kill(-1, SIGTSTP); kill(-1, SIGSTOP); kill(0, SIGSTOP); /* and at this point doing C-A-D will bring the * remaining house of cards down */ #endif } else { /* Goodbye, cruel world! */ #if DEBUG fprintf(stderr, "forced reboot\n"); #else reboot(0xfee1dead, 672274793, 0x01234567); #endif } exit(0); }