- t = 0;
- while (strlen(s) > 2 && isdigit(*s))
- t = t * 10 + *s++ - '0';
- if (*s == ':')
- s++;
- if (t > 23)
- goto badform;
- tim = t*60;
- t = 0;
- while (isdigit(*s))
- t = t * 10 + *s++ - '0';
- if (t > 59)
- goto badform;
- tim += t;
- tim *= 60;
- t1 = time((long *) 0);
- lt = localtime(&t1);
- t = lt->tm_sec + lt->tm_min*60 + lt->tm_hour*3600;
- if (tim < t || tim >= (24*3600)) {
- /* before now or after midnight */
- printf("That must be tomorrow\nCan't you wait till then?\n");
- finish();
+ for (;; ++tp) {
+ warn();
+ if (!logged && tp->timeleft <= NOLOG_TIME) {
+ logged = 1;
+ nolog();
+ }
+ (void)sleep((u_int)tp->timetowait);
+ if (!tp->timeleft)
+ break;
+ }
+ die_you_gravy_sucking_pig_dog();
+}
+
+static jmp_buf alarmbuf;
+
+warn()
+{
+ static int first;
+ static char hostname[MAXHOSTNAMELEN + 1];
+ char wcmd[MAXPATHLEN + 4];
+ FILE *pf;
+ char *ctime();
+ void timeout();
+
+ if (!first++)
+ (void)gethostname(hostname, sizeof(hostname));
+
+ /* undoc -n option to wall suppresses normal wall banner */
+ (void)sprintf(wcmd, "%s -n", _PATH_WALL);
+ if (!(pf = popen(wcmd, "w"))) {
+ syslog(LOG_ERR, "shutdown: can't find %s: %m", _PATH_WALL);
+ return;
+ }
+
+ (void)fprintf(pf,
+ "\007*** %sSystem shutdown message from %s@%s ***\007\n",
+ tp->timeleft ? "": "FINAL ", whom, hostname);
+
+ if (tp->timeleft > 10*60)
+ (void)fprintf(pf, "System going down at %5.5s\n\n",
+ ctime(&shuttime) + 11);
+ else if (tp->timeleft > 59)
+ (void)fprintf(pf, "System going down in %d minute%s\n\n",
+ tp->timeleft / 60, (tp->timeleft > 60) ? "s" : "");
+ else if (tp->timeleft)
+ (void)fprintf(pf, "System going down in 30 seconds\n\n");
+ else
+ (void)fprintf(pf, "System going down IMMEDIATELY\n\n");
+
+ if (mbuflen)
+ (void)fwrite(mbuf, sizeof(*mbuf), mbuflen, pf);
+
+ /*
+ * play some games, just in case wall doesn't come back
+ * probably unecessary, given that wall is careful.
+ */
+ if (!setjmp(alarmbuf)) {
+ (void)signal(SIGALRM, timeout);
+ (void)alarm((u_int)30);
+ (void)pclose(pf);
+ (void)alarm((u_int)0);
+ (void)signal(SIGALRM, SIG_DFL);