source: trunk/minix/commands/simple/leave.c@ 20

Last change on this file since 20 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 4.5 KB
Line 
1/* Usage: leave [ [+] hh[:]mm ]
2 *
3 * Author: Terrence W. Holm
4 *
5 * Revision:
6 * Fred van Kempen, MINIX User Group Holland
7 * -adapted to MSS
8 * -adapted to new utmp database
9 * -adapted to POSIX (MINIX 1.5)
10 * Michael Temari, <temari@ix.netcom.com>
11 * -use localtime/mktime to fix bug with DST
12 */
13
14#include <sys/types.h>
15#include <signal.h>
16#include <time.h>
17#include <utmp.h>
18#include <stdlib.h>
19#include <string.h>
20#include <unistd.h>
21#include <stdio.h>
22
23
24#define Min(a,b) ((a<b) ? a : b)
25
26#define STRING 80 /* lots of room for an argument */
27#define MIN 60L /* seconds per minute */
28#define HOUR (60L*60L) /* seconds per hour */
29
30/* Set the following to your personal preferences for the
31 * time and contents of warnings.
32 */
33#define INTERVALS 13 /* size of intervals[] */
34#define WARNINGS 4 /* size of warnings[] */
35
36
37static char *Version = "@(#) LEAVE 1.4 (01/09/90)";
38static int intervals[INTERVALS] = {
39 -5 * MIN,
40 -1 * MIN,
41 0,
42 MIN,
43 2 * MIN,
44 3 * MIN,
45 4 * MIN,
46 5 * MIN,
47 6 * MIN,
48 7 * MIN,
49 8 * MIN,
50 9 * MIN,
51 10 * MIN
52};
53static char *warnings[WARNINGS] = {
54 "You have to leave within 5 minutes",
55 "Just one more minute!",
56 "Time to leave!",
57 "You're going to be late!" /* for all subsequent warnings */
58};
59
60
61_PROTOTYPE(int main, (int argc, char **argv));
62_PROTOTYPE(void Usage, (void));
63_PROTOTYPE(void Get_Hour_Min, (char *when, int *hour, int *min));
64_PROTOTYPE(int Still_Logged_On, (char *user, char *tty));
65
66void Usage()
67{
68 fprintf(stderr, "Usage: leave [[+]hh[:]mm]\n");
69 exit(1);
70}
71
72
73void Get_Hour_Min(when, hour, min)
74char *when;
75int *hour;
76int *min;
77{
78 int hour_min;
79 int just_min = 0;
80
81 switch (sscanf(when, "%d:%d", &hour_min, &just_min)) {
82 case 1:
83 *hour = hour_min / 100;
84 *min = hour_min % 100;
85 break;
86 case 2:
87 *hour = hour_min;
88 *min = just_min;
89 break;
90 default:
91 Usage();
92 }
93
94 if (hour_min < 0 || just_min < 0 || *min > 59) Usage();
95}
96
97
98int Still_Logged_On(user, tty)
99char *user;
100char *tty;
101{
102 FILE *f;
103 struct utmp login;
104
105 if ((f = fopen(UTMP, "r")) == NULL)
106 /* no login/logout records kept */
107 return(1);
108
109 while (fread(&login, sizeof(struct utmp), (size_t)1, f) == 1) {
110 if (!strncmp(login.ut_line, tty, (size_t)8))
111 if (!strncmp(login.ut_name, user, (size_t)8)) {
112 fclose(f);
113 return(1);
114 } else {
115 fclose(f);
116 return(0);
117 }
118 }
119 fclose(f);
120 return(0);
121}
122
123
124int main(argc, argv)
125int argc;
126char *argv[];
127{
128 char when[STRING];
129 time_t now = time((time_t *)0);
130 time_t leave, delta;
131 struct tm *tm;
132 int hour, min;
133 int pid, i;
134 char *user = cuserid( (char *)NULL);
135 char *tty = ttyname(0) + 5;
136
137 /* get the argument string "when" either from stdin, or argv */
138 if (argc <= 1) {
139 printf("When do you have to leave? ");
140 fflush(stdout);
141 if (fgets(when, STRING, stdin) == NULL || when[0] == '\n') exit(0);
142 } else {
143 strcpy(when, argv[1]);
144 if (argc > 2) strcat(when, argv[2]);
145 }
146
147 /* determine the leave time from the current time and "when" */
148 tm = localtime(&now);
149 if (when[0] == '+') {
150 Get_Hour_Min(&when[1], &hour, &min);
151 tm->tm_hour += hour;
152 tm->tm_min += min;
153 leave = mktime(tm);
154 } else {
155 /* user entered an absolute time */
156 Get_Hour_Min(&when[0], &hour, &min);
157 tm->tm_hour = hour;
158 tm->tm_min = min;
159 leave = mktime(tm);
160 if (leave < now) {
161 printf("That time has already passed!\n");
162 exit(1);
163 }
164 }
165
166 printf("Alarm set for %s", ctime(&leave));
167
168 if ((pid = fork()) == -1) {
169 fprintf(stderr, "leave: can not fork\n");
170 exit(1);
171 }
172 if (pid != 0) exit(0);
173
174 /* only the child continues on */
175 if (user == NULL || tty == NULL) {
176 fprintf(stderr, "leave: Can not determine user and terminal name\n");
177 exit(1);
178 }
179 signal(SIGINT, SIG_IGN);
180 signal(SIGQUIT, SIG_IGN);
181 signal(SIGTERM, SIG_IGN);
182
183 for (;;) {
184 if (!Still_Logged_On(user, tty)) exit(0);
185
186 /* how much longer until the leave time? */
187 /* XXX - use difftime all over. */
188 delta = leave - time((time_t *)0);
189
190 /* which interval are we currently in? */
191 for (i = 0; i < INTERVALS; ++i)
192 if (delta + intervals[i] > 0) break;
193
194 /* if we are within intervals[0] then print a warning If
195 * there are more intervals than messages, then use/
196 * warnings[WARNINGS-1] for all subsequent messages. */
197 if (i > 0)
198 printf("\007\r%s\r\n",
199 warnings[i > WARNINGS ? WARNINGS - 1 : i - 1]);
200
201 if (i == INTERVALS) {
202 printf("That was the last time I'll tell you. Bye.\r\n");
203 exit(0);
204 }
205 /* Sleep until the next interval. For long periods, wake up
206 * every hour to check if the user is still on (also required
207 * because 16 bit ints don't allow long waits). */
208 sleep((unsigned) Min(delta + intervals[i], HOUR));
209 }
210}
Note: See TracBrowser for help on using the repository browser.