]> asedeno.scripts.mit.edu Git - 1ts-debian.git/blob - zephyr/clients/zaway/zaway.c
new upstream tarball
[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 2337 2009-03-22 21:03:21Z kcr $
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 2337 2009-03-22 21:03:21Z kcr $";
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(int);
28 u_short port;
29
30 void
31 usage(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
42 main(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(ZNotice_t *, FILE *);
56         char *charset = NULL;
57         unsigned short zcharset;
58             
59 #ifdef _POSIX_VERSION
60         struct sigaction sa;
61 #endif
62         
63         if ((retval = ZInitialize()) != ZERR_NONE) {
64                 com_err(argv[0],retval,"while initializing");
65                 exit(1);
66         }
67
68         port = 0;
69         if ((retval = ZOpenPort(&port)) != ZERR_NONE) {
70                 com_err(argv[0],retval,"while opening port");
71                 exit(1);
72         }
73
74         sub.zsub_class = MESSAGE_CLASS;
75         sub.zsub_classinst = "*";
76         sub.zsub_recipient = ZGetSender();
77
78         cmdline_msg = 0;
79         watch_location = 0;
80         while ((optchar = getopt(argc, argv, "m:whx:")) != EOF) {
81                 switch (optchar) {
82                 case 'm':
83                         cmdline_msg = optarg;
84                         break;
85
86                 case 'w':
87                         watch_location = 1;
88                         break;
89
90                 case 'h':
91                         usage(argv[0]);
92                         return 0;
93
94                 case 'x':
95                         charset = optarg;
96                         break;
97
98                 case '?':
99                         fprintf(stderr,
100                                 "Unrecognized option '-%c'.\n"
101                                 "Try '%s -h' for more information.\n",
102                                 optopt, argv[0]);
103                         return 1;
104                 }
105         }
106
107         zcharset = ZGetCharset(charset);
108
109         if (argc > optind)
110                 (void) strcpy(awayfile,argv[optind]);
111         else {
112                 envptr = getenv("HOME");
113                 if (envptr)
114                         (void) sprintf(awayfile,"%s/.away",envptr);
115                 else {
116                         if (!(pw = getpwuid((int) getuid()))) {
117                                 fprintf(stderr,"Who are you?\n");
118                                 exit(1);
119                         }
120                         (void) sprintf(awayfile,"%s/.away",pw->pw_dir);
121                 } 
122         }
123
124         fp = fopen(awayfile,"r");
125         if (!fp && argc > optind) {
126                 fprintf(stderr,"File %s not found!\n",awayfile);
127                 exit(1);
128         } 
129 #ifdef _POSIX_VERSION
130         (void) sigemptyset(&sa.sa_mask);
131         sa.sa_flags = 0;
132         sa.sa_handler = cleanup;
133         (void) sigaction(SIGINT, &sa, (struct sigaction *)0);
134         (void) sigaction(SIGTERM, &sa, (struct sigaction *)0);
135         (void) sigaction(SIGHUP, &sa, (struct sigaction *)0);
136 #else
137         (void) signal(SIGINT, cleanup);
138         (void) signal(SIGTERM, cleanup);
139         (void) signal(SIGHUP, cleanup);
140 #endif
141         if ((retval = ZSubscribeToSansDefaults(&sub,1,port)) != ZERR_NONE) {
142                 com_err(argv[0],retval,"while subscribing");
143                 exit(1);
144         }
145
146         for (;;) {
147                 if ((retval = ZReceiveNotice(&notice, (struct sockaddr_in *)0)) != ZERR_NONE) {
148                         if (retval != ETIMEDOUT)
149                                 com_err(argv[0],retval,"while receiving notice");
150                         continue;
151                 }
152
153                 if (strcmp(notice.z_sender,ZGetSender()) == 0 ||
154                     strcmp(notice.z_opcode,"PING") == 0 ||
155                     strcmp(notice.z_opcode,"AUTO") == 0 ||
156                     strcmp(notice.z_message,"Automated reply:") == 0) {
157                      ZFreeNotice(&notice);
158                      continue;
159                 }
160
161                 if (watch_location) {
162                         if ((retval = ZLocateUser(ZGetSender(), &nlocs, ZNOAUTH))
163                             != ZERR_NONE) {
164                                 com_err(argv[0],retval,"while locating self");
165                                 continue;
166                         }
167
168                         if (nlocs != 0) {
169                                 /* User is logged in.  Don't send an autoreply. */
170                                 continue;
171                         }
172
173                         ZFlushLocations();
174                 }
175
176                 if (cmdline_msg) {
177                     ptr = strdup(cmdline_msg);
178                     if (!ptr) {
179                         com_err(argv[0],ENOMEM,"while getting cmdline message");
180                         exit(1);
181                     }
182                 }
183                 else if (fp) {
184                         if (!(ptr = find_message(&notice,fp))) {
185                                 ZFreeNotice(&notice);
186                                 continue;
187                         }
188                 }
189                 else {
190                         ptr = malloc(sizeof(DEFAULT_MSG)+1);
191                         if (!ptr) {
192                                 com_err(argv[0],ENOMEM,"while getting default message");
193                                 exit(1);
194                         }
195                         (void) strcpy(ptr,DEFAULT_MSG);
196                 }
197                 notice.z_recipient = notice.z_sender;
198                 notice.z_sender = 0;
199                 notice.z_default_format = "";
200                 notice.z_opcode = RESPONSE_OPCODE;
201                 notice.z_charset = zcharset;
202
203                 msg[0] = "Automated reply:";
204                 msg[1] = ptr;
205                 
206                 notice.z_message_len = strlen(notice.z_message)+1;
207                 if ((retval = ZSendList(&notice,msg,2,ZNOAUTH)) != ZERR_NONE) {
208                         com_err(argv[0],retval,"while sending notice");
209                 }
210                 free(ptr);
211                 ZFreeNotice(&notice);
212         }
213 }
214
215 char *
216 find_message(ZNotice_t *notice,
217              FILE *fp)
218 {
219         char *ptr,*ptr2;
220         char bfr[BUFSIZ],sender[BUFSIZ];
221         int gotone,lastwasnt;
222         
223         rewind(fp);
224
225         (void) strcpy(sender,notice->z_sender);
226         ptr2 = strchr(sender,'@');
227         if (ptr2)
228                 *ptr2 = '\0';
229         
230         ptr = 0;
231         gotone = 0;
232         lastwasnt = 0;
233         
234         while (fgets(bfr,sizeof bfr,fp) != (char *)0) {
235                 if (*bfr == '>') {
236                         if (lastwasnt)
237                                 gotone = 0;
238                         bfr[strlen(bfr)-1] = '\0';
239                         ptr2 = strchr(bfr,'@');
240                         if (ptr2)
241                                 *ptr2 = '\0';
242                         if (!strcmp(bfr+1,sender) ||
243                             !strcmp(bfr+1,"*") ||
244                             (!strcmp(bfr+1,"%") && !ptr))
245                                 gotone = 1;
246                         lastwasnt = 0;
247                 } 
248                 else {
249                         if (gotone) {
250                                 if (!ptr) {
251                                         ptr = malloc((unsigned)(strlen(bfr)+1));
252                                         *ptr = '\0';
253                                 } 
254                                 else
255                                         ptr = realloc(ptr,(unsigned)(strlen(bfr)+strlen(ptr)+1));
256                                 (void) strcat(ptr,bfr);
257                         }
258                         lastwasnt = 1;
259                 }
260         }
261
262         return (ptr);
263 }
264
265 RETSIGTYPE
266 cleanup(int ignored)
267 {
268     ZCancelSubscriptions(port);
269     exit(1);
270 }