1 /* This file is part of the Project Athena Zephyr Notification System.
2 * It contains code for the "zaway" command.
4 * Created by: Robert French
6 * $Id: zaway.c 2337 2009-03-22 21:03:21Z kcr $
8 * Copyright (c) 1987, 1993 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>
20 static const char rcsid_zaway_c[] = "$Id: zaway.c 2337 2009-03-22 21:03:21Z kcr $";
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 ""
27 RETSIGTYPE cleanup(int);
33 printf("Usage: %s [OPTIONS] [FILE]\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",
51 char awayfile[BUFSIZ],*msg[2],*envptr;
52 int optchar, watch_location;
55 char *find_message(ZNotice_t *, FILE *);
57 unsigned short zcharset;
63 if ((retval = ZInitialize()) != ZERR_NONE) {
64 com_err(argv[0],retval,"while initializing");
69 if ((retval = ZOpenPort(&port)) != ZERR_NONE) {
70 com_err(argv[0],retval,"while opening port");
74 sub.zsub_class = MESSAGE_CLASS;
75 sub.zsub_classinst = "*";
76 sub.zsub_recipient = ZGetSender();
80 while ((optchar = getopt(argc, argv, "m:whx:")) != EOF) {
100 "Unrecognized option '-%c'.\n"
101 "Try '%s -h' for more information.\n",
107 zcharset = ZGetCharset(charset);
110 (void) strcpy(awayfile,argv[optind]);
112 envptr = getenv("HOME");
114 (void) sprintf(awayfile,"%s/.away",envptr);
116 if (!(pw = getpwuid((int) getuid()))) {
117 fprintf(stderr,"Who are you?\n");
120 (void) sprintf(awayfile,"%s/.away",pw->pw_dir);
124 fp = fopen(awayfile,"r");
125 if (!fp && argc > optind) {
126 fprintf(stderr,"File %s not found!\n",awayfile);
129 #ifdef _POSIX_VERSION
130 (void) sigemptyset(&sa.sa_mask);
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);
137 (void) signal(SIGINT, cleanup);
138 (void) signal(SIGTERM, cleanup);
139 (void) signal(SIGHUP, cleanup);
141 if ((retval = ZSubscribeToSansDefaults(&sub,1,port)) != ZERR_NONE) {
142 com_err(argv[0],retval,"while subscribing");
147 if ((retval = ZReceiveNotice(¬ice, (struct sockaddr_in *)0)) != ZERR_NONE) {
148 if (retval != ETIMEDOUT)
149 com_err(argv[0],retval,"while receiving notice");
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(¬ice);
161 if (watch_location) {
162 if ((retval = ZLocateUser(ZGetSender(), &nlocs, ZNOAUTH))
164 com_err(argv[0],retval,"while locating self");
169 /* User is logged in. Don't send an autoreply. */
177 ptr = strdup(cmdline_msg);
179 com_err(argv[0],ENOMEM,"while getting cmdline message");
184 if (!(ptr = find_message(¬ice,fp))) {
185 ZFreeNotice(¬ice);
190 ptr = malloc(sizeof(DEFAULT_MSG)+1);
192 com_err(argv[0],ENOMEM,"while getting default message");
195 (void) strcpy(ptr,DEFAULT_MSG);
197 notice.z_recipient = notice.z_sender;
199 notice.z_default_format = "";
200 notice.z_opcode = RESPONSE_OPCODE;
201 notice.z_charset = zcharset;
203 msg[0] = "Automated reply:";
206 notice.z_message_len = strlen(notice.z_message)+1;
207 if ((retval = ZSendList(¬ice,msg,2,ZNOAUTH)) != ZERR_NONE) {
208 com_err(argv[0],retval,"while sending notice");
211 ZFreeNotice(¬ice);
216 find_message(ZNotice_t *notice,
220 char bfr[BUFSIZ],sender[BUFSIZ];
221 int gotone,lastwasnt;
225 (void) strcpy(sender,notice->z_sender);
226 ptr2 = strchr(sender,'@');
234 while (fgets(bfr,sizeof bfr,fp) != (char *)0) {
238 bfr[strlen(bfr)-1] = '\0';
239 ptr2 = strchr(bfr,'@');
242 if (!strcmp(bfr+1,sender) ||
243 !strcmp(bfr+1,"*") ||
244 (!strcmp(bfr+1,"%") && !ptr))
251 ptr = malloc((unsigned)(strlen(bfr)+1));
255 ptr = realloc(ptr,(unsigned)(strlen(bfr)+strlen(ptr)+1));
256 (void) strcat(ptr,bfr);
268 ZCancelSubscriptions(port);