xref: /original-bsd/usr.bin/leave/leave.c (revision e188a54c)
1 /*
2  * Copyright (c) 1980, 1988 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 char copyright[] =
20 "@(#) Copyright (c) 1980, 1988 Regents of the University of California.\n\
21  All rights reserved.\n";
22 #endif /* not lint */
23 
24 #ifndef lint
25 static char sccsid[] = "@(#)leave.c	5.4 (Berkeley) 07/07/88";
26 #endif /* not lint */
27 
28 #include <sys/param.h>
29 #include <sys/time.h>
30 #include <stdio.h>
31 #include <ctype.h>
32 
33 /*
34  * leave [[+]hhmm]
35  *
36  * Reminds you when you have to leave.
37  * Leave prompts for input and goes away if you hit return.
38  * It nags you like a mother hen.
39  */
40 main(argc, argv)
41 	int argc;
42 	char **argv;
43 {
44 	register u_int secs;
45 	register int hours, minutes;
46 	register char c, *cp;
47 	struct tm *t, *localtime();
48 	time_t now, time();
49 	int plusnow;
50 	char buf[50];
51 
52 	if (argc < 2) {
53 #define	MSG1	"When do you have to leave? "
54 		(void)write(1, MSG1, sizeof(MSG1) - 1);
55 		cp = fgets(buf, sizeof(buf), stdin);
56 		if (*cp == '\n')
57 			exit(0);
58 	} else
59 		cp = argv[1];
60 
61 	if (*cp == '+') {
62 		plusnow = 1;
63 		++cp;
64 	} else {
65 		plusnow = 0;
66 		(void)time(&now);
67 		t = localtime(&now);
68 	}
69 
70 	for (hours = 0; (c = *cp) && c != '\n'; ++cp) {
71 		if (!isdigit(c))
72 			usage();
73 		hours = hours * 10 + (c - '0');
74 	}
75 	minutes = hours % 100;
76 	hours /= 100;
77 
78 	if (minutes < 0 || minutes > 59)
79 		usage();
80 	if (plusnow)
81 		secs = hours * 60 * 60 + minutes * 60;
82 	else {
83 		if (hours > 23 || t->tm_hour > hours ||
84 		    t->tm_hour == hours && minutes <= t->tm_min)
85 			usage();
86 		secs = (hours - t->tm_hour) * 60 * 60;
87 		secs += (minutes - t->tm_min) * 60;
88 	}
89 	doalarm(secs);
90 	exit(0);
91 }
92 
93 static
94 doalarm(secs)
95 	u_int secs;
96 {
97 	register int bother;
98 	time_t daytime, time();
99 	int pid;
100 	char *ctime();
101 
102 	if (pid = fork()) {
103 		(void)time(&daytime);
104 		daytime += secs;
105 		printf("Alarm set for %.16s. (pid %d)\n",
106 		    ctime(&daytime), pid);
107 		exit(0);
108 	}
109 	sleep((u_int)2);		/* let parent print set message */
110 
111 	/*
112 	 * if write fails, we've lost the terminal through someone else
113 	 * causing a vhangup by logging in.
114 	 */
115 #define	FIVEMIN	(5 * 60)
116 #define	MSG2	"\07\07You have to leave in 5 minutes.\n"
117 	if (secs >= FIVEMIN) {
118 		sleep(secs - FIVEMIN);
119 		if (write(1, MSG2, sizeof(MSG2) - 1) != sizeof(MSG2) - 1)
120 			exit(0);
121 		secs = FIVEMIN;
122 	}
123 
124 #define	ONEMIN	(60)
125 #define	MSG3	"\07\07Just one more minute!\n"
126 	if (secs >= ONEMIN) {
127 		sleep(secs - ONEMIN);
128 		if (write(1, MSG3, sizeof(MSG3) - 1) != sizeof(MSG3) - 1)
129 			exit(0);
130 	}
131 
132 #define	MSG4	"\07\07Time to leave!\n"
133 	for (bother = 10; bother--;) {
134 		sleep((u_int)ONEMIN);
135 		if (write(1, MSG4, sizeof(MSG4) - 1) != sizeof(MSG4) - 1)
136 			exit(0);
137 	}
138 
139 #define	MSG5	"\07\07That was the last time I'll tell you.  Bye.\n"
140 	(void)write(1, MSG5, sizeof(MSG5) - 1);
141 	exit(0);
142 }
143 
144 static
145 usage()
146 {
147 	fprintf(stderr, "usage: leave [[+]hhmm]\n");
148 	exit(1);
149 }
150