]> asedeno.scripts.mit.edu Git - 1ts-debian.git/blob - zephyr/clients/xzwrite/zephyr.c
finalize -3
[1ts-debian.git] / zephyr / clients / xzwrite / zephyr.c
1 #include "xzwrite.h"
2 #include <string.h>
3 #include <dyn.h>
4 #include <com_err.h>
5
6 #include <zephyr/zephyr.h>
7
8 static int zeph_send_notice();
9 extern Defaults defs;
10 extern DynObject zsigs;
11
12 /* ARGSUSED */
13 void zeph_dispatch(client_data, source, input_id)
14    XtPointer client_data;
15    int *source;
16    XtInputId *input_id;
17 {
18      ZNotice_t notice;
19      struct sockaddr_in from;
20      int ret;
21
22      while (ZPending() > 0) {
23           ret = ZReceiveNotice(&notice, &from);
24           if (ret != ZERR_NONE) {
25                Warning(error_message(ret), " while receiving Zephyr notice.",
26                        NULL);
27                continue;
28           }
29
30           if (defs.track_logins &&
31               (! strcmp(notice.z_opcode, "USER_LOGIN") ||
32                ! strcmp(notice.z_opcode, "USER_LOGOUT")))
33                logins_deal(&notice);
34
35           else if (defs.auto_reply &&
36                    ! strcasecmp(notice.z_class, DEFAULT_CLASS) &&
37                    ! strcasecmp(notice.z_recipient, ZGetSender()))
38                dest_add_reply(&notice);
39           
40           /* Handle the zlocating bug the Zephyr library explicitly. */
41           /* Only display bogon zlocate packets in debug mode */
42           else if (strcmp(notice.z_class, LOCATE_CLASS) || defs.debug) {
43                Warning("XZwrite: Unexpected notice received.  ",
44                        "You can probably ignore this.\n",
45                        "To: <", notice.z_class, ", ",
46                        notice.z_class_inst, ", ", (*notice.z_recipient) ?
47                        notice.z_recipient : "*", ">\n",
48                        "From: ", notice.z_sender, "\nOpcode: ",
49                        notice.z_opcode, "\nMessage: ", notice.z_message,
50                        "\n", NULL);
51           }
52           
53           ZFreeNotice(&notice);
54      }
55 }
56
57 void zeph_init()
58 {
59      int        retval;
60      
61      retval = ZInitialize();
62      if (retval != ZERR_NONE)
63           Error("Cannot initialize the Zephyr library.", NULL);
64
65      retval = ZOpenPort(NULL);
66      if (retval != ZERR_NONE)
67           Error("Cannot open Zephyr port.", NULL);
68 }
69
70 int zeph_locateable(user)
71    char *user;
72 {
73      char       buf[BUFSIZ];
74      int   n;
75
76      if (strchr(user, '@') == NULL)
77           sprintf(buf, "%s@%s", user, ZGetRealm());
78      ZLocateUser(buf, &n, ZAUTH);
79      return (!! n);
80 }
81
82 /* XXX This will break on interrealm zephyr */
83 void zeph_subto_logins(users, num)
84    char **users;
85    int num;
86 {
87      ZSubscription_t    *sublist;
88      char               *name, *realm;
89      int                rlen, c = 0;
90
91      realm = ZGetRealm();
92      rlen = strlen(realm);
93      sublist = (ZSubscription_t *) Malloc(num*sizeof(ZSubscription_t),
94                                           "while subscribing to logins", NULL);
95
96      while (c < num) {
97           sublist[c].zsub_class = "login";
98           sublist[c].zsub_recipient = "";
99           name = (char *) Malloc(strlen(users[c])+rlen+2,
100                                  "while subscribing to login, ", users[c],
101                                  NULL);
102           if (strchr(users[c], '@'))
103                sprintf(name, "%s", users[c]);
104           else
105                sprintf(name, "%s@%s", users[c], realm);
106           sublist[c].zsub_classinst = name;
107           c += 1;
108      }
109
110      ZSubscribeToSansDefaults(sublist, c, (unsigned short) 0);
111      for(; c; --c)
112           free(sublist[c-1].zsub_classinst);
113      free(sublist);
114 }
115
116 void zeph_subto_replies()
117 {
118      ZSubscription_t sub;
119
120      sub.zsub_class = "message";
121      sub.zsub_classinst = "*";
122      sub.zsub_recipient = ZGetSender();
123
124      ZSubscribeToSansDefaults(&sub, 1, (unsigned short) 0);
125 }
126
127 int zeph_send_message(dest, msg)
128    Dest dest;
129    char *msg;
130 {
131      ZNotice_t  notice;
132      int        msglen, siglen, ret;
133      char       *sig_msg, *sig;
134
135      if (!zsigs) sig = defs.signature;
136      else {
137        char **tmp;
138        tmp = (char **) DynGet (zsigs, rand() % DynSize(zsigs));
139        sig = *tmp; }
140
141      msglen = strlen(msg);
142      siglen = strlen(sig);
143      sig_msg = (char *) Malloc(msglen + siglen + 2, "while sending message",
144                                NULL);
145      sprintf(sig_msg, "%s%c%s", sig, '\0', msg);
146           
147      memset((char *) &notice, 0, sizeof(ZNotice_t));
148      notice.z_kind = ACKED;
149      notice.z_class = dest->zclass;
150      notice.z_class_inst = dest->zinst;
151      notice.z_recipient = dest->zrecip;
152      notice.z_sender = 0;
153      notice.z_opcode = defs.opcode;
154      notice.z_port = 0;
155      notice.z_message = sig_msg;
156      notice.z_message_len = msglen + siglen + 1;
157
158      /* This really gross looking mess is brought to you by zwrite.c */
159      if (defs.auth) {
160           if (*sig)
161                notice.z_default_format = "Class $class, Instance $instance:\nTo: @bold($recipient)\n@bold($1) <$sender>\n\n$2";
162           else
163                notice.z_default_format = "Class $class, Instance $instance:\nTo: @bold($recipient)\n$message";
164      }
165      else {
166           if (*sig)
167                notice.z_default_format = "@bold(UNAUTHENTIC) Class $class, Instance $instance:\n@bold($1) <$sender>\n\n$2";
168           else
169                notice.z_default_format = "@bold(UNAUTHENTIC) Class $class, Instance $instance:\n$message";
170      }
171      
172      ret = zeph_send_notice(&notice, (defs.auth) ? ZAUTH : ZNOAUTH);
173      free(sig_msg);
174
175      /* log to file */
176      if (defs.logfile)
177        if (strcmp(defs.logfile, "*"))
178          log_message (dest, msg);
179
180      return ret;
181 }
182
183 int zeph_ping(dest)
184    Dest dest;
185 {
186      ZNotice_t          notice;
187
188      (void) memset((char *) &notice, 0, sizeof(ZNotice_t));
189      notice.z_kind = ACKED;
190      notice.z_class = dest->zclass;
191      notice.z_class_inst = dest->zinst;
192      notice.z_recipient = dest->zrecip;
193      notice.z_opcode = "PING";
194
195      /* Should a PING ever be authenticated? */
196      return (zeph_send_notice(&notice, ZNOAUTH));
197 }
198
199 int zeph_pong(dest)
200    Dest dest;
201 {
202      ZNotice_t          notice;
203
204      (void) memset((char *) &notice, 0, sizeof(ZNotice_t));
205      notice.z_kind = ACKED;
206      notice.z_class = dest->zclass;
207      notice.z_class_inst = dest->zinst;
208      notice.z_recipient = dest->zrecip;
209      notice.z_opcode = "PING";
210      notice.z_message = "PONG";
211      notice.z_message_len = 4;
212
213      /* Should a PING ever be authenticated? */
214      return (zeph_send_notice(&notice, ZNOAUTH));
215 }
216
217 char *zeph_get_signature()
218 {
219      char *sig;
220           
221      sig = ZGetVariable("xzwrite-signature");
222      if (! sig) sig = ZGetVariable("zwrite-signature");
223      return sig;
224 }
225
226 static int zeph_send_notice(notice, auth)
227    ZNotice_t    *notice;
228    int          (*auth)();
229 {
230      int        retval;
231      ZNotice_t  retnotice;
232
233      /* Send message with appropriate authentication */
234      retval = ZSendNotice(notice, auth);
235      if (retval != ZERR_NONE) {
236           if (defs.debug)
237                Warning(error_message(retval), " while sending message.", NULL);
238           return SENDFAIL_SEND;
239      }
240
241      /* Wait for server acknowledgement */
242      retval = ZIfNotice(&retnotice, (struct sockaddr_in *) 0,
243                         ZCompareUIDPred, (char *) &notice->z_uid);
244
245      if (retval != ZERR_NONE) {
246           if (defs.debug)
247                Warning(error_message(retval),
248                        " while waiting for acknowledgement.", NULL);
249           return SENDFAIL_ACK;
250      }
251
252      /* Make sure someone receives it */
253      if (strcmp(retnotice.z_message, ZSRVACK_NOTSENT)==0)
254           return SENDFAIL_RECV;
255
256      return SEND_OK;
257 }
258
259 void log_message(dest, msg)
260    Dest dest;
261    char *msg;
262 {
263   FILE *fp;
264   int i;
265   time_t now;
266
267   fp = fopen(defs.logfile, "a");
268   if (!fp) {
269     fp = fopen(defs.logfile, "w");
270     if (!fp) {
271       fprintf(stderr, "xzwrite: could not open log file \"%s\".\n",
272               defs.logfile);
273       return; }
274   }
275
276   now = time (NULL);
277   fprintf(fp, "To: %s, %s, %s\n", dest->zclass, dest->zinst, dest->zrecip);
278   fprintf(fp, "Date: %s\n", ctime (&now));
279
280   i = strlen(msg)-1;
281   while (msg[i] == '\n' && i > 0) i--;
282   if (msg[i] != '\n') i++; msg[i] = 0;
283   fputs(msg, fp); fprintf(fp, "\n\n");
284   fclose(fp);
285 }