leave.c revision 32295
11590Srgrimes/* 21590Srgrimes * Copyright (c) 1980, 1988, 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 3. All advertising materials mentioning features or use of this software 141590Srgrimes * must display the following acknowledgement: 151590Srgrimes * This product includes software developed by the University of 161590Srgrimes * California, Berkeley and its contributors. 171590Srgrimes * 4. Neither the name of the University nor the names of its contributors 181590Srgrimes * may be used to endorse or promote products derived from this software 191590Srgrimes * without specific prior written permission. 201590Srgrimes * 211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311590Srgrimes * SUCH DAMAGE. 321590Srgrimes */ 331590Srgrimes 341590Srgrimes#ifndef lint 3527572Scharnierstatic const char copyright[] = 361590Srgrimes"@(#) Copyright (c) 1980, 1988, 1993\n\ 371590Srgrimes The Regents of the University of California. All rights reserved.\n"; 381590Srgrimes#endif /* not lint */ 391590Srgrimes 401590Srgrimes#ifndef lint 4127572Scharnier#if 0 421590Srgrimesstatic char sccsid[] = "@(#)leave.c 8.1 (Berkeley) 6/6/93"; 4327572Scharnier#endif 4427572Scharnierstatic const char rcsid[] = 4532295Shelbig "$Id: leave.c,v 1.2 1997/07/21 12:04:31 charnier Exp $"; 461590Srgrimes#endif /* not lint */ 471590Srgrimes 4832295Shelbig#include <err.h> 4927572Scharnier#include <ctype.h> 5032295Shelbig#include <locale.h> 511590Srgrimes#include <stdio.h> 5232295Shelbig#include <time.h> 5327572Scharnier#include <unistd.h> 541590Srgrimes 5527572Scharniervoid doalarm __P((u_int)); 5627572Scharnierstatic void usage __P((void)); 5727572Scharnier 581590Srgrimes/* 591590Srgrimes * leave [[+]hhmm] 601590Srgrimes * 611590Srgrimes * Reminds you when you have to leave. 621590Srgrimes * Leave prompts for input and goes away if you hit return. 631590Srgrimes * It nags you like a mother hen. 641590Srgrimes */ 6527572Scharnierint 661590Srgrimesmain(argc, argv) 671590Srgrimes int argc; 681590Srgrimes char **argv; 691590Srgrimes{ 701590Srgrimes register u_int secs; 711590Srgrimes register int hours, minutes; 721590Srgrimes register char c, *cp; 731590Srgrimes struct tm *t, *localtime(); 741590Srgrimes time_t now, time(); 7532295Shelbig int plusnow, t_12_hour; 761590Srgrimes char buf[50]; 771590Srgrimes 7832295Shelbig if (setlocale(LC_TIME, "") == NULL) 7932295Shelbig warn("setlocale"); 8032295Shelbig 811590Srgrimes if (argc < 2) { 821590Srgrimes#define MSG1 "When do you have to leave? " 831590Srgrimes (void)write(1, MSG1, sizeof(MSG1) - 1); 841590Srgrimes cp = fgets(buf, sizeof(buf), stdin); 8527572Scharnier if (cp == NULL || *cp == '\n') 861590Srgrimes exit(0); 871590Srgrimes } else 881590Srgrimes cp = argv[1]; 891590Srgrimes 901590Srgrimes if (*cp == '+') { 911590Srgrimes plusnow = 1; 921590Srgrimes ++cp; 9332295Shelbig } else 941590Srgrimes plusnow = 0; 951590Srgrimes 961590Srgrimes for (hours = 0; (c = *cp) && c != '\n'; ++cp) { 971590Srgrimes if (!isdigit(c)) 981590Srgrimes usage(); 991590Srgrimes hours = hours * 10 + (c - '0'); 1001590Srgrimes } 1011590Srgrimes minutes = hours % 100; 1021590Srgrimes hours /= 100; 1031590Srgrimes 1041590Srgrimes if (minutes < 0 || minutes > 59) 1051590Srgrimes usage(); 1061590Srgrimes if (plusnow) 1071590Srgrimes secs = hours * 60 * 60 + minutes * 60; 1081590Srgrimes else { 10932295Shelbig (void)time(&now); 11032295Shelbig t = localtime(&now); 11132295Shelbig 11232295Shelbig if (hours > 23) 1131590Srgrimes usage(); 11432295Shelbig 11532295Shelbig /* Convert tol to 12 hr time (0:00...11:59) */ 11632295Shelbig if (hours > 11) 11732295Shelbig hours -= 12; 11832295Shelbig 11932295Shelbig /* Convert tm to 12 hr time (0:00...11:59) */ 12032295Shelbig if (t->tm_hour > 11) 12132295Shelbig t_12_hour = t->tm_hour - 12; 12232295Shelbig else 12332295Shelbig t_12_hour = t->tm_hour; 12432295Shelbig 12532295Shelbig if (hours < t_12_hour || 12632295Shelbig (hours == t_12_hour && minutes <= t->tm_min)) 12732295Shelbig /* Leave time is in the past so we add 12 hrs */ 12832295Shelbig hours += 12; 12932295Shelbig 13032295Shelbig secs = (hours - t_12_hour) * 60 * 60; 1311590Srgrimes secs += (minutes - t->tm_min) * 60; 13232295Shelbig secs -= now % 60; /* truncate (now + secs) to min */ 1331590Srgrimes } 1341590Srgrimes doalarm(secs); 1351590Srgrimes exit(0); 1361590Srgrimes} 1371590Srgrimes 13827572Scharniervoid 1391590Srgrimesdoalarm(secs) 1401590Srgrimes u_int secs; 1411590Srgrimes{ 1421590Srgrimes register int bother; 1431590Srgrimes time_t daytime, time(); 14432295Shelbig char tb[80]; 1451590Srgrimes int pid; 1461590Srgrimes 14727572Scharnier if ((pid = fork())) { 1481590Srgrimes (void)time(&daytime); 1491590Srgrimes daytime += secs; 15032295Shelbig strftime(tb, sizeof(tb), "%+", localtime(&daytime)); 15132295Shelbig printf("Alarm set for %s. (pid %d)\n", tb, pid); 1521590Srgrimes exit(0); 1531590Srgrimes } 1541590Srgrimes sleep((u_int)2); /* let parent print set message */ 15532295Shelbig secs -= 2; 1561590Srgrimes 1571590Srgrimes /* 1581590Srgrimes * if write fails, we've lost the terminal through someone else 1591590Srgrimes * causing a vhangup by logging in. 1601590Srgrimes */ 1611590Srgrimes#define FIVEMIN (5 * 60) 1621590Srgrimes#define MSG2 "\07\07You have to leave in 5 minutes.\n" 1631590Srgrimes if (secs >= FIVEMIN) { 1641590Srgrimes sleep(secs - FIVEMIN); 1651590Srgrimes if (write(1, MSG2, sizeof(MSG2) - 1) != sizeof(MSG2) - 1) 1661590Srgrimes exit(0); 1671590Srgrimes secs = FIVEMIN; 1681590Srgrimes } 1691590Srgrimes 1701590Srgrimes#define ONEMIN (60) 1711590Srgrimes#define MSG3 "\07\07Just one more minute!\n" 1721590Srgrimes if (secs >= ONEMIN) { 1731590Srgrimes sleep(secs - ONEMIN); 1741590Srgrimes if (write(1, MSG3, sizeof(MSG3) - 1) != sizeof(MSG3) - 1) 1751590Srgrimes exit(0); 1761590Srgrimes } 1771590Srgrimes 1781590Srgrimes#define MSG4 "\07\07Time to leave!\n" 1791590Srgrimes for (bother = 10; bother--;) { 1801590Srgrimes sleep((u_int)ONEMIN); 1811590Srgrimes if (write(1, MSG4, sizeof(MSG4) - 1) != sizeof(MSG4) - 1) 1821590Srgrimes exit(0); 1831590Srgrimes } 1841590Srgrimes 1851590Srgrimes#define MSG5 "\07\07That was the last time I'll tell you. Bye.\n" 1861590Srgrimes (void)write(1, MSG5, sizeof(MSG5) - 1); 1871590Srgrimes exit(0); 1881590Srgrimes} 1891590Srgrimes 19027572Scharnierstatic void 1911590Srgrimesusage() 1921590Srgrimes{ 1931590Srgrimes fprintf(stderr, "usage: leave [[+]hhmm]\n"); 1941590Srgrimes exit(1); 1951590Srgrimes} 196