]> asedeno.scripts.mit.edu Git - 1ts-debian.git/blob - clients/zaway/zaway.c
undo merge disaster
[1ts-debian.git] / 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$
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$";
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 > optind) {
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                         if (retval != ETIMEDOUT)
140                                 com_err(argv[0],retval,"while receiving notice");
141                         continue;
142                 }
143
144                 if (strcmp(notice.z_sender,ZGetSender()) == 0 ||
145                     strcmp(notice.z_opcode,"PING") == 0 ||
146                     strcmp(notice.z_opcode,"AUTO") == 0 ||
147                     strcmp(notice.z_message,"Automated reply:") == 0) {
148                      ZFreeNotice(&notice);
149                      continue;
150                 }
151
152                 if (watch_location) {
153                         if ((retval = ZLocateUser(ZGetSender(), &nlocs, ZNOAUTH))
154                             != ZERR_NONE) {
155                                 com_err(argv[0],retval,"while locating self");
156                                 continue;
157                         }
158
159                         if (nlocs != 0) {
160                                 /* User is logged in.  Don't send an autoreply. */
161                                 continue;
162                         }
163
164                         ZFlushLocations();
165                 }
166
167                 if (cmdline_msg) {
168                         ptr = malloc(strlen(cmdline_msg)+1);
169                         if (!ptr) {
170                                 com_err(argv[0],ENOMEM,"while getting cmdline message");
171                                 exit(1);
172                         }
173                         (void) strcpy(ptr,cmdline_msg);
174                 }
175                 else if (fp) {
176                         if (!(ptr = find_message(&notice,fp))) {
177                                 ZFreeNotice(&notice);
178                                 continue;
179                         }
180                 }
181                 else {
182                         ptr = malloc(sizeof(DEFAULT_MSG)+1);
183                         if (!ptr) {
184                                 com_err(argv[0],ENOMEM,"while getting default message");
185                                 exit(1);
186                         }
187                         (void) strcpy(ptr,DEFAULT_MSG);
188                 }
189                 notice.z_recipient = notice.z_sender;
190                 notice.z_sender = 0;
191                 notice.z_default_format = "";
192                 notice.z_opcode = RESPONSE_OPCODE;
193
194                 msg[0] = "Automated reply:";
195                 msg[1] = ptr;
196                 
197                 notice.z_message_len = strlen(notice.z_message)+1;
198                 if ((retval = ZSendList(&notice,msg,2,ZNOAUTH)) != ZERR_NONE) {
199                         com_err(argv[0],retval,"while sending notice");
200                 }
201                 free(ptr);
202                 ZFreeNotice(&notice);
203         }
204 }
205
206 char *find_message(notice,fp)
207         ZNotice_t *notice;
208         register FILE *fp;
209 {
210         register char *ptr,*ptr2;
211         char bfr[BUFSIZ],sender[BUFSIZ];
212         int gotone,lastwasnt;
213         
214         rewind(fp);
215
216         (void) strcpy(sender,notice->z_sender);
217         ptr2 = strchr(sender,'@');
218         if (ptr2)
219                 *ptr2 = '\0';
220         
221         ptr = 0;
222         gotone = 0;
223         lastwasnt = 0;
224         
225         while (fgets(bfr,sizeof bfr,fp) != (char *)0) {
226                 if (*bfr == '>') {
227                         if (lastwasnt)
228                                 gotone = 0;
229                         bfr[strlen(bfr)-1] = '\0';
230                         ptr2 = strchr(bfr,'@');
231                         if (ptr2)
232                                 *ptr2 = '\0';
233                         if (!strcmp(bfr+1,sender) ||
234                             !strcmp(bfr+1,"*") ||
235                             (!strcmp(bfr+1,"%") && !ptr))
236                                 gotone = 1;
237                         lastwasnt = 0;
238                 } 
239                 else {
240                         if (gotone) {
241                                 if (!ptr) {
242                                         ptr = malloc((unsigned)(strlen(bfr)+1));
243                                         *ptr = '\0';
244                                 } 
245                                 else
246                                         ptr = realloc(ptr,(unsigned)(strlen(bfr)+strlen(ptr)+1));
247                                 (void) strcat(ptr,bfr);
248                         }
249                         lastwasnt = 1;
250                 }
251         }
252
253         return (ptr);
254 }
255
256 RETSIGTYPE cleanup()
257 {
258     ZCancelSubscriptions(port);
259     exit(1);
260 }