setgid to group "write" so that terminals need not be world writable
[unix-history] / usr / src / usr.bin / leave / leave.c
CommitLineData
22e155fc
DF
1/*
2 * Copyright (c) 1980 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
7#ifndef lint
8char copyright[] =
9"@(#) Copyright (c) 1980 Regents of the University of California.\n\
10 All rights reserved.\n";
11#endif not lint
12
13#ifndef lint
14static char sccsid[] = "@(#)leave.c 5.1 (Berkeley) %G%";
15#endif not lint
16
fdd8e0d1 17#include <stdio.h>
18a5872f 18#include <signal.h>
fdd8e0d1 19/*
cc4f5b4e 20 * leave [[+]hhmm]
fdd8e0d1
BJ
21 *
22 * Reminds you when you have to leave.
23 * Leave prompts for input and goes away if you hit return.
24 * It nags you like a mother hen.
25 */
cc4f5b4e 26char origlogin[20];
fdd8e0d1
BJ
27char *getlogin();
28char *whenleave;
29char *ctime();
30char buff[100];
31
cc4f5b4e 32main(argc, argv)
fdd8e0d1
BJ
33char **argv;
34{
35 long when, tod, now, diff, hours, minutes;
cc4f5b4e 36 char *cp;
fdd8e0d1
BJ
37 int *nv;
38 int atoi();
39 int *localtime();
40
cc4f5b4e 41 strcpy(origlogin, getlogin());
fdd8e0d1
BJ
42 if (argc < 2) {
43 printf("When do you have to leave? ");
44 fflush(stdout);
cc4f5b4e
RC
45 buff[read(0, buff, sizeof buff)] = 0;
46 cp = buff;
47 } else
48 cp = argv[1];
49 if (*cp == '\n')
fdd8e0d1 50 exit(0);
cc4f5b4e
RC
51 if (*cp == '+') {
52 cp++;
53 if (*cp < '0' || *cp > '9')
54 usage();
55 tod = atoi(cp);
56 hours = tod / 100;
57 minutes = tod % 100;
58 if (minutes < 0 || minutes > 59)
59 usage();
60 diff = 60*hours+minutes;
fdd8e0d1 61 doalarm(diff);
cc4f5b4e 62 exit(0);
fdd8e0d1 63 }
cc4f5b4e
RC
64 if (*cp < '0' || *cp > '9')
65 usage();
66 tod = atoi(cp);
fdd8e0d1
BJ
67 hours = tod / 100;
68 if (hours > 12)
69 hours -= 12;
70 if (hours == 12)
71 hours = 0;
72 minutes = tod % 100;
73
cc4f5b4e
RC
74 if (hours < 0 || hours > 12 || minutes < 0 || minutes > 59)
75 usage();
fdd8e0d1 76
fdd8e0d1
BJ
77 time(&now);
78 nv = localtime(&now);
79 when = 60*hours+minutes;
cc4f5b4e
RC
80 if (nv[2] > 12)
81 nv[2] -= 12; /* do am/pm bit */
fdd8e0d1
BJ
82 now = 60*nv[2] + nv[1];
83 diff = when - now;
84 while (diff < 0)
85 diff += 12*60;
cc4f5b4e
RC
86 if (diff > 11*60) {
87 printf("That time has already passed!\n");
88 exit(1);
89 }
fdd8e0d1
BJ
90 doalarm(diff);
91 exit(0);
92}
93
cc4f5b4e
RC
94usage()
95{
96 printf("usage: leave [[+]hhmm]\n");
97 exit(1);
98}
fdd8e0d1
BJ
99
100doalarm(nmins)
101long nmins;
102{
103 char *msg1, *msg2, *msg3, *msg4;
104 register int i;
105 int slp1, slp2, slp3, slp4;
106 int seconds, gseconds;
107 long daytime;
108
109 seconds = 60 * nmins;
110 if (seconds <= 0)
111 seconds = 1;
112 gseconds = seconds;
113
114 msg1 = "You have to leave in 5 minutes";
115 if (seconds <= 60*5) {
116 slp1 = 0;
117 } else {
118 slp1 = seconds - 60*5;
119 seconds = 60*5;
120 }
121
122 msg2 = "Just one more minute!";
123 if (seconds <= 60) {
124 slp2 = 0;
125 } else {
126 slp2 = seconds - 60;
127 seconds = 60;
128 }
129
130 msg3 = "Time to leave!";
131 slp3 = seconds;
132
133 msg4 = "You're going to be late!";
134 slp4 = 60;
135
136 time(&daytime);
137 daytime += gseconds;
138 whenleave = ctime(&daytime);
cc4f5b4e 139 printf("Alarm set for %s", whenleave);
fdd8e0d1
BJ
140 if (fork())
141 exit(0);
18a5872f
EW
142 signal(SIGINT, SIG_IGN);
143 signal(SIGQUIT, SIG_IGN);
144 signal(SIGTERM, SIG_IGN);
145 signal(SIGTTOU, SIG_IGN);
fdd8e0d1
BJ
146
147 if (slp1)
cc4f5b4e 148 bother(slp1, msg1);
fdd8e0d1 149 if (slp2)
cc4f5b4e
RC
150 bother(slp2, msg2);
151 bother(slp3, msg3);
152 for (i = 0; i < 10; i++)
153 bother(slp4, msg4);
154 printf("That was the last time I'll tell you. Bye.\n");
155 exit(0);
fdd8e0d1
BJ
156}
157
cc4f5b4e 158bother(slp, msg)
fdd8e0d1
BJ
159int slp;
160char *msg;
161{
162
163 delay(slp);
cc4f5b4e 164 printf("\7\7\7%s\n", msg);
fdd8e0d1
BJ
165}
166
167/*
168 * delay is like sleep but does it in 100 sec pieces and
169 * knows what zero means.
170 */
cc4f5b4e
RC
171delay(secs)
172int secs;
173{
fdd8e0d1
BJ
174 int n;
175
cc4f5b4e 176 while (secs > 0) {
fdd8e0d1 177 n = 100;
cc4f5b4e
RC
178 if (secs < n)
179 n = secs;
180 secs -= n;
fdd8e0d1
BJ
181 if (n > 0)
182 sleep(n);
cc4f5b4e 183 if (strcmp(origlogin, getlogin()))
fdd8e0d1
BJ
184 exit(0);
185 }
186}
187
188#ifdef V6
189char *getlogin() {
190#include <utmp.h>
191
192 static struct utmp ubuf;
193 int ufd;
194
195 ufd = open("/etc/utmp",0);
196 seek(ufd, ttyn(0)*sizeof(ubuf), 0);
197 read(ufd, &ubuf, sizeof(ubuf));
198 ubuf.ut_name[sizeof(ubuf.ut_name)] = 0;
199 return(&ubuf.ut_name);
200}
201#endif