]> asedeno.scripts.mit.edu Git - 1ts-debian.git/blob - zephyr/clients/zaway/zaway.c
Initial revision
[1ts-debian.git] / zephyr / clients / zaway / zaway.c
1 /* This file is part of the Project Athena Zephyr Notification System.
2  * It contains code for the "zaway" command.
3  *
4  *      Created by:     Robert French
5  *
6  *      $Id: zaway.c,v 1.14 1999/07/21 12:34:22 ghudson Exp $
7  *
8  *      Copyright (c) 1987, 1993 by the Massachusetts Institute of Technology.
9  *      For copying and distribution information, see the file
10  *      "mit-copyright.h". 
11  */
12
13 #include <sysdep.h>
14 #include <zephyr/mit-copyright.h>
15 #include <zephyr/zephyr.h>
16 #include <pwd.h>
17 #include <com_err.h>
18
19 #ifndef lint
20 static const char rcsid_zaway_c[] = "$Id: zaway.c,v 1.14 1999/07/21 12:34:22 ghudson Exp $";
21 #endif
22
23 #define MESSAGE_CLASS "MESSAGE"
24 #define DEFAULT_MSG "I'm sorry, but I am currently away from the terminal and am\nnot able to receive your message.\n"
25 #define RESPONSE_OPCODE ""
26
27 RETSIGTYPE cleanup();
28 u_short port;
29
30 void usage(name)
31         char *name;
32 {
33         printf("Usage: %s [OPTIONS] [FILE]\n"
34                "\n"
35                "  -m STRING    use STRING as the body of the reply message\n"
36                "  -w           watch your location and only reply if you aren't locatable\n"
37                "  -h           display this help and exit\n",
38                name);
39 }
40
41 int main(argc,argv)
42         int argc;
43         char *argv[];
44 {
45         FILE *fp;
46         ZNotice_t notice;
47         ZSubscription_t sub;
48         register int retval;
49         struct passwd *pw;
50         register char *ptr;
51         char awayfile[BUFSIZ],*msg[2],*envptr;
52         int optchar, watch_location;
53         char *cmdline_msg;
54         int nlocs;
55         char *find_message();
56 #ifdef _POSIX_VERSION
57         struct sigaction sa;
58 #endif
59         
60         if ((retval = ZInitialize()) != ZERR_NONE) {
61                 com_err(argv[0],retval,"while initializing");
62                 exit(1);
63         }
64
65         port = 0;
66         if ((retval = ZOpenPort(&port)) != ZERR_NONE) {
67                 com_err(argv[0],retval,"while opening port");
68                 exit(1);
69         }
70
71         sub.zsub_class = MESSAGE_CLASS;
72         sub.zsub_classinst = "*";
73         sub.zsub_recipient = ZGetSender();
74
75         cmdline_msg = 0;
76         watch_location = 0;
77         while ((optchar = getopt(argc, argv, "m:wh")) != EOF) {
78                 switch (optchar) {
79                 case 'm':
80                         cmdline_msg = optarg;
81                         break;
82
83                 case 'w':
84                         watch_location = 1;
85                         break;
86
87                 case 'h':
88                         usage(argv[0]);
89                         return 0;
90
91                 case '?':
92                         fprintf(stderr,
93                                 "Unrecognized option '-%c'.\n"
94                                 "Try '%s -h' for more information.\n",
95                                 optopt, argv[0]);
96                         return 1;
97                 }
98         }
99
100         if (argc > optind)
101                 (void) strcpy(awayfile,argv[optind]);
102         else {
103                 envptr = getenv("HOME");
104                 if (envptr)
105                         (void) sprintf(awayfile,"%s/.away",envptr);
106                 else {
107                         if (!(pw = getpwuid((int) getuid()))) {
108                                 fprintf(stderr,"Who are you?\n");
109                                 exit(1);
110                         }
111                         (void) sprintf(awayfile,"%s/.away",pw->pw_dir);
112                 } 
113         }
114
115         fp = fopen(awayfile,"r");
116         if (!fp && argc > 1) {
117                 fprintf(stderr,"File %s not found!\n",awayfile);
118                 exit(1);
119         } 
120 #ifdef _POSIX_VERSION
121         (void) sigemptyset(&sa.sa_mask);
122         sa.sa_flags = 0;
123         sa.sa_handler = cleanup;
124         (void) sigaction(SIGINT, &sa, (struct sigaction *)0);
125         (void) sigaction(SIGTERM, &sa, (struct sigaction *)0);
126         (void) sigaction(SIGHUP, &sa, (struct sigaction *)0);
127 #else
128         (void) signal(SIGINT, cleanup);
129         (void) signal(SIGTERM, cleanup);
130         (void) signal(SIGHUP, cleanup);
131 #endif
132         if ((retval = ZSubscribeToSansDefaults(&sub,1,port)) != ZERR_NONE) {
133                 com_err(argv[0],retval,"while subscribing");
134                 exit(1);
135         }
136
137         for (;;) {
138                 if ((retval = ZReceiveNotice(&notice, (struct sockaddr_in *)0)) != ZERR_NONE) {
139                         com_err(argv[0],retval,"while receiving notice");
140                         continue;
141                 }
142
143                 if (strcmp(notice.z_sender,ZGetSender()) == 0 ||
144                     strcmp(notice.z_opcode,"PING") == 0 ||
145                     strcmp(notice.z_message,"Automated reply:") == 0) {
146                      ZFreeNotice(&notice);
147                      continue;
148                 }
149
150                 if (watch_location) {
151                         if ((retval = ZLocateUser(ZGetSender(), &nlocs, ZNOAUTH))
152                             != ZERR_NONE) {
153                                 com_err(argv[0],retval,"while locating self");
154                                 continue;
155                         }
156
157                         if (nlocs != 0) {
158                                 /* User is logged in.  Don't send an autoreply. */
159                                 continue;
160                         }
161
162                         ZFlushLocations();
163                 }
164
165                 if (cmdline_msg) {
166                         ptr = malloc(strlen(cmdline_msg));
167                         if (!ptr) {
168                                 com_err(argv[0],ENOMEM,"while getting cmdline message");
169                                 exit(1);
170                         }
171                         (void) strcpy(ptr,cmdline_msg);
172                 }
173                 else if (fp) {
174                         if (!(ptr = find_message(&notice,fp))) {
175                                 ZFreeNotice(&notice);
176                                 continue;
177                         }
178                 }
179                 else {
180                         ptr = malloc(sizeof(DEFAULT_MSG)+1);
181                         if (!ptr) {
182                                 com_err(argv[0],ENOMEM,"while getting default message");
183                                 exit(1);
184                         }
185                         (void) strcpy(ptr,DEFAULT_MSG);
186                 }
187                 notice.z_recipient = notice.z_sender;
188                 notice.z_sender = 0;
189                 notice.z_default_format = "";
190                 notice.z_opcode = RESPONSE_OPCODE;
191
192                 msg[0] = "Automated reply:";
193                 msg[1] = ptr;
194                 
195                 notice.z_message_len = strlen(notice.z_message)+1;
196                 if ((retval = ZSendList(&notice,msg,2,ZNOAUTH)) != ZERR_NONE) {
197                         com_err(argv[0],retval,"while sending notice");
198                 }
199                 free(ptr);
200                 ZFreeNotice(&notice);
201         }
202 }
203
204 char *find_message(notice,fp)
205         ZNotice_t *notice;
206         register FILE *fp;
207 {
208         register char *ptr,*ptr2;
209         char bfr[BUFSIZ],sender[BUFSIZ];
210         int gotone,lastwasnt;
211         
212         rewind(fp);
213
214         (void) strcpy(sender,notice->z_sender);
215         ptr2 = strchr(sender,'@');
216         if (ptr2)
217                 *ptr2 = '\0';
218         
219         ptr = 0;
220         gotone = 0;
221         lastwasnt = 0;
222         
223         while (fgets(bfr,sizeof bfr,fp) != (char *)0) {
224                 if (*bfr == '>') {
225                         if (lastwasnt)
226                                 gotone = 0;
227                         bfr[strlen(bfr)-1] = '\0';
228                         ptr2 = strchr(bfr,'@');
229                         if (ptr2)
230                                 *ptr2 = '\0';
231                         if (!strcmp(bfr+1,sender) ||
232                             !strcmp(bfr+1,"*") ||
233                             (!strcmp(bfr+1,"%") && !ptr))
234                                 gotone = 1;
235                         lastwasnt = 0;
236                 } 
237                 else {
238                         if (gotone) {
239                                 if (!ptr) {
240                                         ptr = malloc((unsigned)(strlen(bfr)+1));
241                                         *ptr = '\0';
242                                 } 
243                                 else
244                                         ptr = realloc(ptr,(unsigned)(strlen(bfr)+strlen(ptr)+1));
245                                 (void) strcat(ptr,bfr);
246                         }
247                         lastwasnt = 1;
248                 }
249         }
250
251         return (ptr);
252 }
253
254 RETSIGTYPE cleanup()
255 {
256     ZCancelSubscriptions(port);
257     exit(1);
258 }