1 /* This file is part of the Project Athena Zephyr Notification System.
2 * It contains code for the "zleave" command.
4 * Created by: David Jedlinsky
6 * $Id: zleave.c 2493 2009-07-13 05:17:23Z kcr@ATHENA.MIT.EDU $
8 * Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
9 * For copying and distribution information, see the file
14 #include <zephyr/mit-copyright.h>
15 #include <zephyr/zephyr.h>
18 static const char rcsid_zlocate_c[] = "$Id: zleave.c 2493 2009-07-13 05:17:23Z kcr@ATHENA.MIT.EDU $";
22 * Copyright (c) 1980 Regents of the University of California.
23 * All rights reserved.
25 * Redistribution and use in source and binary forms are permitted
26 * provided that this notice is preserved and that due credit is given
27 * to the University of California at Berkeley. The name of the University
28 * may not be used to endorse or promote products derived from this
29 * software without specific written prior permission. This software
30 * is provided ``as is'' without express or implied warranty.
35 "@(#) Copyright (c) 1980 Regents of the University of California.\n\
36 All rights reserved.\n";
39 #define MESSAGE_CLASS "MESSAGE"
40 #define INSTANCE "LEAVE"
42 * zleave [[+]hhmm [ -m "Reminder Message" ]]
46 * Reminds you when you have to leave.
47 * Leave prompts for input and goes away if you hit return.
48 * Messages are sent through Zephyr. Subscriptions are handled automagically.
49 * It nags you like a mother hen.
54 char *reminder_message = NULL;
56 int use_zephyr=1, oldpid;
60 void bother(long, char *);
62 int gethm(char *, int *, int*);
77 if (ZInitialize() != ZERR_NONE) {
78 fprintf(stderr,"No Zephyr! Will write directly to terminal.\n");
81 (void) sprintf(tempfile, "/tmp/zleave.%d", (int) getuid());
84 if ((port = ZGetWGPort()) == -1) {
86 "Can't find WindowGram subscription port.\n");
87 fprintf(stderr,"Will write directly to terminal.\n");
90 sub.zsub_class = MESSAGE_CLASS;
91 sub.zsub_classinst = INSTANCE;
92 sub.zsub_recipient = ZGetSender();
93 if (ZSubscribeToSansDefaults(&sub,1,(u_short)port)
96 "Subscription error! Writing to your terminal...\n");
102 if ((cp = getlogin()) == NULL) {
103 fputs("leave: You are not logged in.\n", stderr);
106 (void) strcpy(origlogin, cp);
110 while ((c<argc) && (! reminder_message))
111 if (!strcmp(argv[c++],"-m")) {
113 reminder_message = argv[c];
118 if (!reminder_message)
119 reminder_message = "";
122 printf("When do you have to leave? ");
123 (void) fflush(stdout);
124 buff[read(0, buff, sizeof buff)] = 0;
132 if (!gethm(cp, &hours, &minutes))
134 if (minutes < 0 || minutes > 59)
136 diff = 60*hours+minutes;
140 if (!strcmp(cp, "cancel") || !strcmp(cp, "can")) {
141 if (!(fp = fopen(tempfile,"r"))) {
142 printf("No zleave is currently running.\n");
145 if (fscanf(fp, "%d", &oldpid) != 1) {
146 printf("The zleave pid file is corrupted.\n");
152 printf("No zleave is currently running.\n");
153 (void) unlink(tempfile);
156 if (!gethm(cp, &hours, &minutes))
163 if (hours < 0 || hours > 12 || minutes < 0 || minutes > 59)
167 nv = localtime(&now);
168 when = 60*hours+minutes;
169 if (nv->tm_hour > 12)
170 nv->tm_hour -= 12; /* do am/pm bit */
171 now = 60 * nv->tm_hour + nv->tm_min;
176 fprintf(stderr, "That time has already passed!\n");
187 fprintf(stderr, "usage: zleave [[+]hhmm [-m \"Reminder Message\"]]\n\
188 \tor: zleave can[cel]\n");
201 while ((c = *cp++) != '\0') {
204 tod = tod * 10 + (c - '0');
215 char *msg1, *msg2, *msg3, *msg4;
217 long slp1, slp2, slp3, slp4;
218 long seconds, gseconds;
220 #ifdef _POSIX_VERSION
224 seconds = 60 * nmins;
229 msg1 = "You have to leave in 5 minutes";
230 if (seconds <= 60*5) {
233 slp1 = seconds - 60*5;
237 msg2 = "Just one more minute!";
245 msg3 = "Time to leave!";
248 msg4 = "You're going to be late!";
251 (void) time(&daytime);
253 whenleave = ctime(&daytime);
255 fp = fopen(tempfile,"r");
257 if (fscanf(fp, "%d", &oldpid) == 1)
259 printf("Old zleave process killed.\n");
262 printf("Alarm set for %s", whenleave);
264 /* Subscribe to MESSAGE.LEAVE here */
277 if (!(fp = fopen(tempfile, "w")))
278 fprintf(stderr, "Cannot open pid file.\n");
280 fprintf(fp, "%d\n", getpid());
281 if (fclose(fp) == EOF)
282 (void) perror("fclose on pid file");
285 #ifdef _POSIX_VERSION
286 sigemptyset(&sa.sa_mask);
288 sa.sa_handler = SIG_IGN;
289 sigaction(SIGINT, &sa, (struct sigaction *)0);
290 sigaction(SIGQUIT, &sa, (struct sigaction *)0);
291 sigaction(SIGTERM, &sa, (struct sigaction *)0);
292 sigaction(SIGTTOU, &sa, (struct sigaction *)0);
294 (void) signal(SIGINT, SIG_IGN);
295 (void) signal(SIGQUIT, SIG_IGN);
296 (void) signal(SIGTERM, SIG_IGN);
297 (void) signal(SIGTTOU, SIG_IGN);
305 for (i = 0; i < 10; i++)
308 bother(0L, "That was the last time I'll tell you. Bye.");
309 (void) unlink(tempfile);
325 real_message = (char *) malloc(strlen(msg) +
326 strlen(reminder_message) + 3);
327 if (real_message == NULL) {
328 fprintf (stderr, "zleave: out of memory\n");
331 sprintf(real_message,"%c%s\n%s",'\0',msg,reminder_message);
333 (void) memset((char *)¬ice, 0, sizeof(notice));
334 notice.z_kind = ACKED;
336 notice.z_charset = ZCHARSET_UNKNOWN;
337 notice.z_class = MESSAGE_CLASS;
338 notice.z_class_inst = INSTANCE;
339 notice.z_recipient = ZGetSender();
340 notice.z_opcode = "";
341 notice.z_sender = (char *) 0;
342 notice.z_default_format = "\n$2";
343 notice.z_message = real_message;
344 /* +3: initial null, newline, final null */
345 notice.z_message_len = strlen(msg)+strlen(reminder_message)+3;
347 if (ZSendNotice(¬ice, ZAUTH) != ZERR_NONE) {
348 printf("\7\7\7%s\n%s", msg, reminder_message);
351 if ((retval = ZIfNotice(&retnotice, (struct sockaddr_in *) 0,
353 (char *)¬ice.z_uid)) != ZERR_NONE) {
355 "zleave: %s while waiting for acknowledgement\n",
356 error_message(retval));
359 if (retnotice.z_kind == SERVNAK) {
361 "zleave: authorization failure while sending\n");
364 if (retnotice.z_kind != SERVACK || !retnotice.z_message_len) {
365 fprintf(stderr, "zleave: Detected server failure while receiving acknowledgement\n");
368 if (strcmp(retnotice.z_message, ZSRVACK_SENT)) {
374 ZFreeNotice(&retnotice);
378 printf("\a\a\a%s\n%s", msg, reminder_message);
380 printf("\7\7\7%s\n%s", msg, reminder_message);
385 * delay is like sleep but does it in 100 sec pieces and
386 * knows what zero means.
405 if (strcmp(origlogin, l) != 0)
411 #ifndef HAVE_GETLOGIN
415 static struct utmp ubuf;
418 ufd = open("/etc/utmp",0);
419 seek(ufd, ttyn(0)*sizeof(ubuf), 0);
420 read(ufd, &ubuf, sizeof(ubuf));
421 ubuf.ut_name[sizeof(ubuf.ut_name)] = 0;
422 return(&ubuf.ut_name);