6 #include <zephyr/zephyr.h>
8 static int zeph_send_notice();
10 extern DynObject zsigs;
13 void zeph_dispatch(client_data, source, input_id)
14 XtPointer client_data;
19 struct sockaddr_in from;
22 while (ZPending() > 0) {
23 ret = ZReceiveNotice(¬ice, &from);
24 if (ret != ZERR_NONE) {
25 Warning(error_message(ret), " while receiving Zephyr notice.",
30 if (defs.track_logins &&
31 (! strcmp(notice.z_opcode, "USER_LOGIN") ||
32 ! strcmp(notice.z_opcode, "USER_LOGOUT")))
35 else if (defs.auto_reply &&
36 ! strcasecmp(notice.z_class, DEFAULT_CLASS) &&
37 ! strcasecmp(notice.z_recipient, ZGetSender()))
38 dest_add_reply(¬ice);
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,
61 retval = ZInitialize();
62 if (retval != ZERR_NONE)
63 Error("Cannot initialize the Zephyr library.", NULL);
65 retval = ZOpenPort(NULL);
66 if (retval != ZERR_NONE)
67 Error("Cannot open Zephyr port.", NULL);
70 int zeph_locateable(user)
76 if (strchr(user, '@') == NULL)
77 sprintf(buf, "%s@%s", user, ZGetRealm());
78 ZLocateUser(buf, &n, ZAUTH);
82 /* XXX This will break on interrealm zephyr */
83 void zeph_subto_logins(users, num)
87 ZSubscription_t *sublist;
93 sublist = (ZSubscription_t *) Malloc(num*sizeof(ZSubscription_t),
94 "while subscribing to logins", NULL);
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],
102 if (strchr(users[c], '@'))
103 sprintf(name, "%s", users[c]);
105 sprintf(name, "%s@%s", users[c], realm);
106 sublist[c].zsub_classinst = name;
110 ZSubscribeToSansDefaults(sublist, c, (unsigned short) 0);
112 free(sublist[c-1].zsub_classinst);
116 void zeph_subto_replies()
120 sub.zsub_class = "message";
121 sub.zsub_classinst = "*";
122 sub.zsub_recipient = ZGetSender();
124 ZSubscribeToSansDefaults(&sub, 1, (unsigned short) 0);
127 int zeph_send_message(dest, msg)
132 int msglen, siglen, ret;
135 if (!zsigs) sig = defs.signature;
138 tmp = (char **) DynGet (zsigs, rand() % DynSize(zsigs));
141 msglen = strlen(msg);
142 siglen = strlen(sig);
143 sig_msg = (char *) Malloc(msglen + siglen + 2, "while sending message",
145 sprintf(sig_msg, "%s%c%s", sig, '\0', msg);
147 memset((char *) ¬ice, 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;
153 notice.z_opcode = defs.opcode;
155 notice.z_message = sig_msg;
156 notice.z_message_len = msglen + siglen + 1;
158 /* This really gross looking mess is brought to you by zwrite.c */
161 notice.z_default_format = "Class $class, Instance $instance:\nTo: @bold($recipient)\n@bold($1) <$sender>\n\n$2";
163 notice.z_default_format = "Class $class, Instance $instance:\nTo: @bold($recipient)\n$message";
167 notice.z_default_format = "@bold(UNAUTHENTIC) Class $class, Instance $instance:\n@bold($1) <$sender>\n\n$2";
169 notice.z_default_format = "@bold(UNAUTHENTIC) Class $class, Instance $instance:\n$message";
172 ret = zeph_send_notice(¬ice, (defs.auth) ? ZAUTH : ZNOAUTH);
177 if (strcmp(defs.logfile, "*"))
178 log_message (dest, msg);
188 (void) memset((char *) ¬ice, 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";
195 /* Should a PING ever be authenticated? */
196 return (zeph_send_notice(¬ice, ZNOAUTH));
204 (void) memset((char *) ¬ice, 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;
213 /* Should a PING ever be authenticated? */
214 return (zeph_send_notice(¬ice, ZNOAUTH));
217 char *zeph_get_signature()
221 sig = ZGetVariable("xzwrite-signature");
222 if (! sig) sig = ZGetVariable("zwrite-signature");
226 static int zeph_send_notice(notice, auth)
233 /* Send message with appropriate authentication */
234 retval = ZSendNotice(notice, auth);
235 if (retval != ZERR_NONE) {
237 Warning(error_message(retval), " while sending message.", NULL);
238 return SENDFAIL_SEND;
241 /* Wait for server acknowledgement */
242 retval = ZIfNotice(&retnotice, (struct sockaddr_in *) 0,
243 ZCompareUIDPred, (char *) ¬ice->z_uid);
245 if (retval != ZERR_NONE) {
247 Warning(error_message(retval),
248 " while waiting for acknowledgement.", NULL);
252 /* Make sure someone receives it */
253 if (strcmp(retnotice.z_message, ZSRVACK_NOTSENT)==0)
254 return SENDFAIL_RECV;
259 void log_message(dest, msg)
267 fp = fopen(defs.logfile, "a");
269 fp = fopen(defs.logfile, "w");
271 fprintf(stderr, "xzwrite: could not open log file \"%s\".\n",
277 fprintf(fp, "To: %s, %s, %s\n", dest->zclass, dest->zinst, dest->zrecip);
278 fprintf(fp, "Date: %s\n", ctime (&now));
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");