1: static char *sccsid = "@(#)reboot.c 4.5 (Berkeley) 4/21/81"; 2: /* 3: * Reboot 4: * Required signal handling: 5: * /etc/init must go to idle mode when sent a SIGQUIT. 6: * A subsequent SIGHUP sends init back to normal mode. 7: * The kernel must exempt the current process from kill(-1,SIGKILL). 8: * The reboot system call must be implemented! 9: */ 10: #include <whoami.h> 11: #include <sys/param.h> 12: #include <stdio.h> 13: #include <sys/reboot.h> 14: #include <errno.h> 15: #include <signal.h> 16: #include <time.h> 17: 18: #define SHUTDOWNLOG "/usr/adm/shutdownlog" 19: #define DEVDIR "/dev/" 20: #define KMEM "/dev/kmem" 21: 22: int halt; 23: 24: main(argc, argv) 25: int argc; 26: char **argv; 27: { 28: register howto; 29: register char *argp; 30: register i; 31: int qflag = 0; 32: dev_t bootdev=NODEV, getdev(), rootdev(); 33: 34: argc--, argv++; 35: howto = 0; 36: while (argc > 0) { 37: if (!strcmp(*argv, "-q")) 38: qflag++; 39: else if (!strcmp(*argv, "-n")) 40: howto |= RB_NOSYNC; 41: else if (!strcmp(*argv, "-a")) 42: howto |= (RB_ASKNAME | RB_SINGLE); 43: else if (!strcmp(*argv,"-f")) 44: howto |= RB_NOFSCK; 45: else if (!strcmp(*argv,"-d")) 46: howto |= RB_DUMP; 47: else if (!strcmp(*argv,"-h")) { 48: howto |= RB_HALT; 49: halt++; 50: } else if ((bootdev=getdev(*argv)) == NODEV) { 51: fprintf(stderr, 52: "usage: reboot [ -n ][ -q ][ -f ][ -a ][ -d ][ -h ][ dev ]\n"); 53: exit(1); 54: } 55: argc--, argv++; 56: } 57: 58: if (bootdev==NODEV) 59: bootdev = rootdev(); 60: for (i = 1; i < NSIG; i++) 61: signal(i, SIG_IGN); 62: 63: if (kill(1, SIGQUIT) == -1) { 64: fprintf(stderr, "reboot: can't idle init\n"); 65: exit(1); 66: } 67: 68: if (!qflag) for (i = 1; ; i++) { 69: if (kill(-1, SIGKILL) == -1) { 70: extern int errno; 71: 72: if (errno == ESRCH) 73: break; 74: 75: perror("reboot: kill"); 76: kill(1, SIGHUP); 77: exit(1); 78: } 79: if (i > 5) { 80: fprintf(stderr, "CAUTION: some process(es) wouldn't die\n"); 81: break; 82: } 83: setalarm(2 * i); 84: pause(); 85: } 86: 87: if ((howto & RB_NOSYNC) == 0) 88: log_entry(); 89: if (!qflag) { 90: if (!(howto & RB_NOSYNC)) { 91: markdown(); 92: sync(); 93: sync(); 94: } 95: setalarm(5); 96: pause(); 97: } 98: reboot(bootdev, howto); 99: perror("reboot"); 100: /* 101: * Reboot failed. Tell init to go back to work. 102: */ 103: kill(1, SIGHUP); 104: exit(1); 105: } 106: 107: dingdong() 108: { 109: /* RRRIIINNNGGG RRRIIINNNGGG */ 110: } 111: 112: setalarm(n) 113: { 114: signal(SIGALRM, dingdong); 115: alarm(n); 116: } 117: 118: #include <utmp.h> 119: #define SCPYN(a, b) strncpy(a, b, sizeof(a)) 120: char wtmpf[] = "/usr/adm/wtmp"; 121: struct utmp wtmp; 122: 123: markdown() 124: { 125: register f = open(wtmpf, 1); 126: if (f >= 0) { 127: lseek(f, 0L, 2); 128: SCPYN(wtmp.ut_line, "~"); 129: SCPYN(wtmp.ut_name, "shutdown"); 130: time(&wtmp.ut_time); 131: write(f, (char *)&wtmp, sizeof(wtmp)); 132: close(f); 133: } 134: } 135: 136: char *days[] = { 137: "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" 138: }; 139: 140: char *months[] = { 141: "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", 142: "Oct", "Nov", "Dec" 143: }; 144: 145: log_entry() 146: { 147: FILE *fp; 148: struct tm *tm, *localtime(); 149: time_t now; 150: 151: time(&now); 152: tm = localtime(&now); 153: fp = fopen(SHUTDOWNLOG, "a"); 154: if (fp == NULL) 155: return; 156: fseek(fp, 0L, 2); 157: fprintf(fp, "%02d:%02d %s %s %2d, %4d. %s.\n", tm->tm_hour, 158: tm->tm_min, days[tm->tm_wday], months[tm->tm_mon], 159: tm->tm_mday, tm->tm_year + 1900, 160: halt? "Halted": "Shutdown for reboot"); 161: fclose(fp); 162: } 163: 164: #include <sys/stat.h> 165: char dev[2*DIRSIZ] = DEVDIR; 166: /* 167: * Figure out the dev for a given string, e.g. "hp0a". 168: * Returns NODEV if device doesn't exist, or isn't a block device. 169: */ 170: dev_t 171: getdev(s) 172: char *s; 173: { 174: struct stat statbuf; 175: char *index(); 176: 177: if (index(s,'/')==NULL) { 178: strcat(dev,s); 179: s = dev; 180: } 181: if (stat(s,&statbuf) == -1) 182: return(NODEV); 183: if ((statbuf.st_mode&S_IFMT) != S_IFBLK) 184: return(NODEV); 185: return(statbuf.st_rdev); 186: } 187: 188: /* 189: * get the dev for the root filesystem. 190: */ 191: dev_t 192: rootdev() { 193: struct stat statbuf; 194: 195: if (stat("/",&statbuf) == -1) { 196: fprintf(stderr,"Can't stat root\n"); 197: exit(1); 198: } 199: return(statbuf.st_dev); 200: }