summaryrefslogtreecommitdiff
path: root/clients
diff options
context:
space:
mode:
authorGravatar Craig Fields <cfields@mit.edu>1994-08-18 15:07:26 +0000
committerGravatar Craig Fields <cfields@mit.edu>1994-08-18 15:07:26 +0000
commit05feef22880a2a6490d5568ca6db033892ce5eee (patch)
tree49a304f82276fe3395115115b8bb8fab4a36cbe3 /clients
parent38acb61e5ddf3be6187dfaabf6197fbba56e8054 (diff)
Initial revision
Diffstat (limited to 'clients')
-rw-r--r--clients/syslogd/syslog.c.old206
-rw-r--r--clients/xzwrite/destlist.c.old417
-rw-r--r--clients/xzwrite/zephyr.c.old269
3 files changed, 892 insertions, 0 deletions
diff --git a/clients/syslogd/syslog.c.old b/clients/syslogd/syslog.c.old
new file mode 100644
index 0000000..e1af361
--- /dev/null
+++ b/clients/syslogd/syslog.c.old
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 1983, 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is given
+ * to the University of California at Berkeley. The name of the University
+ * may not be used to endorse or promote products derived from this
+ * software without specific prior written permission. This software
+ * is provided ``as is'' without express or implied warranty.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)syslog.c 5.14 (Berkeley) 5/20/88";
+#endif /* LIBC_SCCS and not lint */
+
+
+/*
+ * SYSLOG -- print message on log file
+ *
+ * This routine looks a lot like printf, except that it
+ * outputs to the log file instead of the standard output.
+ * Also:
+ * adds a timestamp,
+ * prints the module name in front of the message,
+ * has some other formatting types (or will sometime),
+ * adds a newline on the end of the message.
+ *
+ * The output of this routine is intended to be read by /etc/syslogd.
+ *
+ * Author: Eric Allman
+ * Modified to use UNIX domain IPC by Ralph Campbell
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/signal.h>
+#include <syslog.h>
+#include <netdb.h>
+#include <strings.h>
+
+#define MAXLINE 1024 /* max message size */
+#define NULL 0 /* manifest */
+
+#define PRIFAC(p) (((p) & LOG_FACMASK) >> 3)
+ /* XXX should be in <syslog.h> */
+#define IMPORTANT LOG_ERR
+
+static char logname[] = "/dev/log";
+static char ctty[] = "/dev/console";
+
+static int LogFile = -1; /* fd for log */
+static int LogStat = 0; /* status bits, set by openlog() */
+static char *LogTag = "syslog"; /* string to tag the entry with */
+static int LogMask = 0xff; /* mask of priorities to be logged */
+static int LogFacility = LOG_USER; /* default facility code */
+
+static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */
+
+extern int errno, sys_nerr;
+extern char *sys_errlist[];
+
+syslog(pri, fmt, p0, p1, p2, p3, p4)
+ int pri;
+ char *fmt;
+{
+ char buf[MAXLINE + 1], outline[MAXLINE + 1];
+ register char *b, *f, *o;
+ register int c;
+ long now;
+ int pid, olderrno = errno;
+
+ /* see if we should just throw out this message */
+ if ((unsigned) PRIFAC(pri) >= LOG_NFACILITIES ||
+ (LOG_MASK(pri & LOG_PRIMASK) & LogMask) == 0 ||
+ (pri &~ (LOG_PRIMASK|LOG_FACMASK)) != 0)
+ return;
+ if (LogFile < 0)
+ openlog(LogTag, LogStat | LOG_NDELAY, 0);
+
+ /* set default facility if none specified */
+ if ((pri & LOG_FACMASK) == 0)
+ pri |= LogFacility;
+
+ /* build the message */
+ o = outline;
+ (void)sprintf(o, "<%d>", pri);
+ o += strlen(o);
+ time(&now);
+ (void)sprintf(o, "%.15s ", ctime(&now) + 4);
+ o += strlen(o);
+ if (LogTag) {
+ strcpy(o, LogTag);
+ o += strlen(o);
+ }
+ if (LogStat & LOG_PID) {
+ (void)sprintf(o, "[%d]", getpid());
+ o += strlen(o);
+ }
+ if (LogTag) {
+ strcpy(o, ": ");
+ o += 2;
+ }
+
+ b = buf;
+ f = fmt;
+ while ((c = *f++) != '\0' && c != '\n' && b < &buf[MAXLINE]) {
+ if (c != '%') {
+ *b++ = c;
+ continue;
+ }
+ if ((c = *f++) != 'm') {
+ *b++ = '%';
+ *b++ = c;
+ continue;
+ }
+ if ((unsigned)olderrno > sys_nerr)
+ (void)sprintf(b, "error %d", olderrno);
+ else
+ strcpy(b, sys_errlist[olderrno]);
+ b += strlen(b);
+ }
+ *b++ = '\n';
+ *b = '\0';
+ (void)sprintf(o, buf, p0, p1, p2, p3, p4);
+ c = strlen(outline);
+ if (c > MAXLINE)
+ c = MAXLINE;
+
+ /* output the message to the local logger */
+ if (sendto(LogFile, outline, c, 0, &SyslogAddr, sizeof SyslogAddr) >= 0)
+ return;
+ if (!(LogStat & LOG_CONS))
+ return;
+
+ /* output the message to the console */
+ pid = vfork();
+ if (pid == -1)
+ return;
+ if (pid == 0) {
+ int fd;
+
+ signal(SIGALRM, SIG_DFL);
+ sigsetmask(sigblock(0L) & ~sigmask(SIGALRM));
+ alarm(5);
+ fd = open(ctty, O_WRONLY);
+ alarm(0);
+ strcat(o, "\r");
+ o = index(outline, '>') + 1;
+ write(fd, o, c + 1 - (o - outline));
+ close(fd);
+ _exit(0);
+ }
+ if (!(LogStat & LOG_NOWAIT))
+ while ((c = wait((int *)0)) > 0 && c != pid)
+ ;
+}
+
+/*
+ * OPENLOG -- open system log
+ */
+
+openlog(ident, logstat, logfac)
+ char *ident;
+ int logstat, logfac;
+{
+ if (ident != NULL)
+ LogTag = ident;
+ LogStat = logstat;
+ if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
+ LogFacility = logfac;
+ if (LogFile >= 0)
+ return;
+ SyslogAddr.sa_family = AF_UNIX;
+ strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data);
+ if (LogStat & LOG_NDELAY) {
+ LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
+ fcntl(LogFile, F_SETFD, 1);
+ }
+}
+
+/*
+ * CLOSELOG -- close the system log
+ */
+
+closelog()
+{
+
+ (void) close(LogFile);
+ LogFile = -1;
+}
+
+/*
+ * SETLOGMASK -- set the log mask level
+ */
+setlogmask(pmask)
+ int pmask;
+{
+ int omask;
+
+ omask = LogMask;
+ if (pmask != 0)
+ LogMask = pmask;
+ return (omask);
+}
diff --git a/clients/xzwrite/destlist.c.old b/clients/xzwrite/destlist.c.old
new file mode 100644
index 0000000..a81d2c9
--- /dev/null
+++ b/clients/xzwrite/destlist.c.old
@@ -0,0 +1,417 @@
+#include <stdio.h>
+#include <dyn.h>
+#include <strings.h>
+
+#include "xzwrite.h"
+
+/*
+ * The following code extracts keypressed from an X event:
+ *
+ * keyevent = event->xkey;
+ * XLookupString(&keyevent, buffer, 1, NULL, NULL);
+ */
+
+/*
+ * This entire file could easily be changes so that multiple destination
+ * lists could be used. But I don't know that that's necessary for this
+ * program.
+ */
+
+/* Globals */
+DestRec current_dest;
+
+static DynObject dests;
+extern Defaults defs;
+
+static void get_dest_from_file(), _get_default_dest();
+static int sort_dest_func();
+
+/* A function for debugging */
+void dest_print()
+{
+ char **d;
+ int i;
+
+ d = (char **) DynGet(dests, 0);
+ for (i=0; i<DynSize(dests); i++)
+ printf("%d %s\n", i, d[i]);
+}
+
+char **dest_text()
+{
+ return ((char **) DynGet(dests, 0));
+}
+
+int dest_num()
+{
+ return (DynSize(dests));
+}
+
+void dest_set_current_dest(dest)
+ Dest dest;
+{
+ (void) memcpy((char *) &current_dest, (char *) dest, sizeof(DestRec));
+}
+
+void dest_init()
+{
+ dests = DynCreate(sizeof(char *), 0);
+ if (! dests)
+ Error("Out of memory reading destinations", NULL);
+
+ strcpy(current_dest.zclass, DEFAULT_CLASS);
+ strcpy(current_dest.zinst, DEFAULT_INST);
+ strcpy(current_dest.zrecip, get_username());
+}
+
+char **load_default_dest()
+{
+ char *get_home_dir();
+
+ if (! *get_home_dir())
+ Error("Cannot find your home directory.", NULL);
+
+ if (defs.read_xzwrite)
+ _get_default_dest(XZWRITE_DEST_FILE);
+ if (defs.read_zephyr)
+ _get_default_dest(ZEPHYR_FILE);
+ if (defs.read_anyone)
+ _get_default_dest(ANYONE_FILE);
+
+ if (DynSize(dests) == 0) {
+ char *def;
+
+ Warning("XZwrite: No destinations specified, using default.",
+ NULL);
+
+ def = (char *) Malloc(strlen("...") + 1, "adding default dests",
+ NULL);
+ strcpy(def, "...");
+ if (DynAdd(dests, (char *) &def) == DYN_NOMEM)
+ Error("Out of memory adding default destinations.", NULL);
+ }
+
+ sort_destinations();
+ return ((char **) DynGet(dests, 0));
+}
+
+static void _get_default_dest(s)
+ char *s;
+{
+ char *filename;
+
+ filename = (char *) Malloc(strlen(get_home_dir()) + strlen(s) + 1,
+ "While reading file ", s, NULL);
+ sprintf(filename, "%s%s", get_home_dir(), s);
+ get_dest_from_file(dests, filename);
+ free(filename);
+}
+
+static void get_dest_from_file(dests, f)
+ DynObject dests;
+ char *f;
+{
+ FILE *file;
+ char *line, buf[BUFSIZ];
+ DestRec dest;
+
+ if ((file = fopen(f, "r")) == NULL) {
+ Warning("Cannot find destinations file ", f, NULL);
+ return;
+ }
+
+ while (bfgets(buf, 80, file)) {
+ if (buf[0] == '#' || buf[0] == '\0') {
+ if (defs.debug)
+ printf("xzwrite: skipping comment or blank line\n");
+ continue;
+ }
+
+ if (! parse_into_dest(&dest, buf)) {
+ Warning("Ignoring incorrect destination: ", buf, NULL);
+ continue;
+ }
+
+ line = (char *) Malloc(strlen(buf) + 1, "parsing file ", f, NULL);
+ strcpy(line, buf);
+ if (DynAdd(dests, (char *) &line) == DYN_NOMEM)
+ Error("Out of memory parsing file ", f, NULL);
+ }
+
+ fclose(file);
+}
+
+char **dest_add(dest)
+ Dest dest;
+{
+ char *buf;
+
+ /* Two extra bytes if instance or recipient are "" */
+ buf = (char *) Malloc(strlen(dest->zclass) + strlen(dest->zinst) +
+ strlen(dest->zrecip) + 5,
+ "while adding destination ", NULL);
+ sprintf(buf, "%s,%s,%s", dest->zclass,
+ *dest->zinst ? dest->zinst : "*",
+ *dest->zrecip ? dest->zrecip : "*");
+
+ if (DynAdd(dests, &buf) == DYN_NOMEM) {
+ Warning("Out of memory adding destination ", buf, ". Skipping.",
+ NULL);
+ free(buf);
+ }
+
+ sort_destinations();
+ return ((char **) DynGet(dests, 0));
+}
+
+/* XXX The return/output semantics of this function are not good */
+char **dest_add_string(s)
+ char *s;
+{
+ DestRec dest;
+
+ if (! parse_into_dest(&dest, s))
+ return NULL;
+
+ if (DynAdd(dests, &s) == DYN_NOMEM)
+ Warning("Out of memory adding destination ", s, ". Skipping.",
+ NULL);
+
+ sort_destinations();
+ return ((char **) DynGet(dests, 0));
+}
+
+char **dest_delete_string(s)
+ char *s;
+{
+ int i;
+ char **d;
+
+ d = (char **) DynGet(dests, 0);
+ for (i=0; i<DynSize(dests); i++) {
+ if (! strcmp(s, d[i])) {
+ DynDelete(dests, i);
+ break;
+ }
+ }
+
+ return ((char **) DynGet(dests, 0));
+}
+
+char **delete_dest_index(i)
+ int i;
+{
+ int ret;
+
+ ret = DynDelete(dests, i);
+ if (ret != DYN_OK)
+ return NULL;
+
+ return ((char **) DynGet(dests, 0));
+}
+
+
+static int sort_dest_func(c1, c2)
+ char **c1, **c2;
+{
+ char *s1, *s2, *i1, *i2;
+
+ /* A string with a , in it is always less than one without */
+ s1 = *c1; s2 = *c2;
+ i1 = strchr(s1, ',');
+ i2 = strchr(s2, ',');
+ if (i1 == NULL && i2 != NULL)
+ return 1;
+ else if (i1 != NULL && i2 == NULL)
+ return -1;
+ else
+ return strcmp(s1, s2);
+}
+
+static int
+binary_find_dest(key)
+char *key;
+{
+ register int low = 0, high = DynHigh(dests), mid;
+ register int val;
+ register char **d;
+
+ d = (char **) DynGet(dests, 0);
+
+ /* do binary search */
+ while (low <= high) {
+ mid = (low + high) / 2;
+ val = sort_dest_func(&key, &d[mid]);
+ if (val < 0) {
+ high = mid - 1;
+ } else if (val > 0) {
+ low = mid + 1;
+ } else {
+ return (mid);
+ }
+ }
+
+ return -1;
+}
+
+char **sort_destinations()
+{
+ register char **d;
+ register int idx, idx2;
+ int dsiz = DynSize(dests);
+
+ d = (char **) DynGet(dests, 0);
+ qsort(d, dsiz, sizeof(char *), sort_dest_func);
+
+ for (idx = 0; idx < DynSize(dests);) {
+ if (d[idx][0] == '!') {
+ /* unsubscription */
+ char *next = d[idx];
+ next++;
+ while ((idx2 = binary_find_dest(next)) >= 0) {
+ /* found one to nuke */
+ DynDelete(dests, idx2);
+ if (idx2 <= idx) {
+ /* indexes shifted, so restart this pass. */
+ idx--;
+ if (idx <= 0)
+ idx = 0;
+ continue;
+ }
+ }
+ /* ok, no more to nuke from this one, so delete it and
+ move on. */
+ DynDelete(dests, idx);
+ continue;
+ }
+ /* nope, continue on to next unsub */
+ idx++;
+ }
+ return d;
+}
+
+/* Fills in dest from s */
+#define distance(a,b) ((int) b - (int) a)
+int parse_into_dest(dest, s)
+ Dest dest;
+ char *s;
+{
+ char *a, *b;
+ int x, y;
+
+ /* Check for just recipient */
+ if ((a=strchr(s, ','))==0) {
+ if (strlen(s) > ZLEN)
+ return 0;
+ strcpy(dest->zclass, DEFAULT_CLASS);
+ strcpy(dest->zinst, DEFAULT_INST);
+ strcpy(dest->zrecip, s);
+ }
+
+ /* Check for just class,instance or instace,recipient */
+ else if ((b=strchr((++a), ','))==0) {
+ if (defs.class_inst) {
+ x = distance(s, a-1);
+ if (x >= ZLEN)
+ return 0;
+
+ strncpy(dest->zclass, s, x);
+ dest->zclass[x] = '\0';
+ strcpy(dest->zinst, a);
+ strcpy(dest->zrecip, "*"); }
+ else {
+ x = distance(s, a-1);
+ if (x >= ZLEN)
+ return 0;
+
+ strcpy(dest->zclass, DEFAULT_CLASS);
+ strncpy(dest->zinst, s, x);
+ dest->zinst[x] = '\0';
+ strcpy(dest->zrecip, a); }
+ }
+
+ /* Otherwise, deal with class,instance,recipent */
+ else {
+ ++b;
+ x = distance(s, a-1);
+ y = distance(a, b-1);
+ if (x >= ZLEN || y >= ZLEN)
+ return 0;
+
+ strncpy(dest->zclass, s, x);
+ dest->zclass[x] = '\0';
+ strncpy(dest->zinst, a, y);
+ dest->zinst[y] = '\0';
+ strcpy(dest->zrecip, b);
+ }
+ if (!strcmp(dest->zrecip,"*")) *(dest->zrecip) = '\0';
+ if (!strcmp(dest->zinst,"*")) *(dest->zinst) = '\0';
+
+ return 1;
+}
+#undef distance
+
+/*
+ * notice is from <MESSAGE,inst,sender>. If inst is "PERSONAL", add
+ * destination string "<sender>" if
+ * 1) MESSAGE,PERSONAL,<sender> is not in list, and
+ * 2) <sender> is not in list.
+ * If inst is not "PERSONAL", add destination string
+ * "<MESSAGE,<inst>,<sender>>" if it is not in the list.
+ */
+void dest_add_reply(notice)
+ ZNotice_t *notice;
+{
+ Dest dest;
+ char **list, *newdest, buf[ZLEN*3+2];
+ int i, num;
+
+ list = dest_text();
+ num = dest_num();
+
+
+ /* A hack so local-realm is less annoying */
+ {
+ char *r;
+
+ r = strchr(notice->z_sender, '@');
+ if (r && ! strcmp(r+1, ZGetRealm()))
+ *r = '\0';
+ }
+
+ if (! strcasecmp(notice->z_class_inst, DEFAULT_INST)) {
+ sprintf(buf, "message,personal,%s", notice->z_sender);
+ for (i=0; i < num; i++) {
+ if (! strcasecmp(list[i], buf) ||
+ ! strcasecmp(list[i], notice->z_sender))
+ return;
+ }
+
+ newdest = (char *) Malloc(strlen(notice->z_sender) + 1,
+ "while adding reply destination", NULL);
+ sprintf(newdest, "%s", notice->z_sender);
+ }
+ else {
+ sprintf(buf, "message,%s,%s", notice->z_class_inst,
+ notice->z_sender);
+ for (i=0; i < num; i++) {
+ if (! strcasecmp(list[i], buf))
+ return;
+ }
+
+ newdest = (char *) Malloc(strlen(notice->z_class) +
+ strlen(notice->z_class_inst) +
+ strlen(notice->z_sender) + 3,
+ "while adding reply destintion",
+ NULL);
+ sprintf(newdest, "%s,%s,%s", notice->z_class,
+ notice->z_class_inst, notice->z_sender);
+ }
+
+ dest_add_string(newdest);
+ display_dest();
+
+ if (defs.track_logins)
+ zeph_subto_logins(&notice->z_sender, 1);
+}
+
diff --git a/clients/xzwrite/zephyr.c.old b/clients/xzwrite/zephyr.c.old
new file mode 100644
index 0000000..40d9958
--- /dev/null
+++ b/clients/xzwrite/zephyr.c.old
@@ -0,0 +1,269 @@
+#include <zephyr/zephyr.h>
+
+#include "xzwrite.h"
+#include <strings.h>
+
+static int zeph_send_notice();
+extern Defaults defs;
+
+/* ARGSUSED */
+void zeph_dispatch(client_data, source, input_id)
+ XtPointer client_data;
+ int *source;
+ XtInputId *input_id;
+{
+ ZNotice_t notice;
+ struct sockaddr_in from;
+ int ret;
+
+ while (ZPending() > 0) {
+ ret = ZReceiveNotice(&notice, &from);
+ if (ret != ZERR_NONE) {
+ Warning(error_message(ret), " while receiving Zephyr notice.",
+ NULL);
+ continue;
+ }
+
+ if (defs.track_logins &&
+ (! strcmp(notice.z_opcode, "USER_LOGIN") ||
+ ! strcmp(notice.z_opcode, "USER_LOGOUT")))
+ logins_deal(&notice);
+
+ else if (defs.auto_reply &&
+ ! strcasecmp(notice.z_class, DEFAULT_CLASS) &&
+ ! strcasecmp(notice.z_recipient, ZGetSender()))
+ dest_add_reply(&notice);
+
+ /* Handle the zlocating bug the Zephyr library explicitly. */
+ /* Only display bogon zlocate packets in debug mode */
+ else if (strcmp(notice.z_class, LOCATE_CLASS) || defs.debug) {
+ Warning("XZwrite: Unexpected notice received. ",
+ "You can probably ignore this.\n",
+ "To: <", notice.z_class, ", ",
+ notice.z_class_inst, ", ", (*notice.z_recipient) ?
+ notice.z_recipient : "*", ">\n",
+ "From: ", notice.z_sender, "\nOpcode: ",
+ notice.z_opcode, "\nMessage: ", notice.z_message,
+ "\n", NULL);
+ }
+
+ ZFreeNotice(&notice);
+ }
+}
+
+void zeph_init()
+{
+ int retval;
+
+ retval = ZInitialize();
+ if (retval != ZERR_NONE)
+ Error("Cannot initialize the Zephyr library.", NULL);
+
+ retval = ZOpenPort((int *) 0);
+ if (retval != ZERR_NONE)
+ Error("Cannot open Zephyr port.", NULL);
+}
+
+int zeph_locateable(user)
+ char *user;
+{
+ char buf[BUFSIZ];
+ int n;
+
+ if (strchr(user, '@') == NULL)
+ sprintf(buf, "%s@%s", user, ZGetRealm());
+ ZLocateUser(buf, &n, ZAUTH);
+ return (!! n);
+}
+
+/* XXX This will break on interrealm zephyr */
+void zeph_subto_logins(users, num)
+ char **users;
+ int num;
+{
+ ZSubscription_t *sublist;
+ char *name, *realm;
+ int rlen, c = 0;
+
+ realm = ZGetRealm();
+ rlen = strlen(realm);
+ sublist = (ZSubscription_t *) Malloc(num*sizeof(ZSubscription_t),
+ "while subscribing to logins", NULL);
+
+ while (c < num) {
+ sublist[c].zsub_class = "login";
+ sublist[c].zsub_recipient = "";
+ name = (char *) Malloc(strlen(users[c])+rlen+2,
+ "while subscribing to login, ", users[c],
+ NULL);
+ if (strchr(users[c], '@'))
+ sprintf(name, "%s", users[c]);
+ else
+ sprintf(name, "%s@%s", users[c], realm);
+ sublist[c].zsub_classinst = name;
+ c += 1;
+ }
+
+ ZSubscribeToSansDefaults(sublist, c, (unsigned short) 0);
+ for(; c; --c)
+ free(sublist[c-1].zsub_classinst);
+ free(sublist);
+}
+
+void zeph_subto_replies()
+{
+ ZSubscription_t sub;
+
+ sub.zsub_class = "message";
+ sub.zsub_classinst = "*";
+ sub.zsub_recipient = ZGetSender();
+
+ ZSubscribeToSansDefaults(&sub, 1, (unsigned short) 0);
+}
+
+int zeph_send_message(dest, msg)
+ Dest dest;
+ char *msg;
+{
+ ZNotice_t notice;
+ int msglen, siglen, ret;
+ char *sig_msg;
+
+ msglen = strlen(msg);
+ siglen = strlen(defs.signature);
+ sig_msg = (char *) Malloc(msglen + siglen + 2, "while sending message",
+ NULL);
+ sprintf(sig_msg, "%s%c%s", defs.signature, '\0', msg);
+
+ (void) memset((char *) &notice, 0, sizeof(ZNotice_t));
+ notice.z_kind = ACKED;
+ notice.z_class = dest->zclass;
+ notice.z_class_inst = dest->zinst;
+ notice.z_recipient = dest->zrecip;
+ notice.z_sender = 0;
+ notice.z_opcode = defs.opcode;
+ notice.z_port = 0;
+ notice.z_message = sig_msg;
+ notice.z_message_len = msglen + siglen + 1;
+
+ /* This really gross looking mess is brought to you by zwrite.c */
+ if (defs.auth) {
+ if (*defs.signature)
+ notice.z_default_format = "Class $class, Instance $instance:\nTo: @bold($recipient)\n@bold($1) <$sender>\n\n$2";
+ else
+ notice.z_default_format = "Class $class, Instance $instance:\nTo: @bold($recipient)\n$message";
+ }
+ else {
+ if (*defs.signature)
+ notice.z_default_format = "@bold(UNAUTHENTIC) Class $class, Instance $instance:\n@bold($1) <$sender>\n\n$2";
+ else
+ notice.z_default_format = "@bold(UNAUTHENTIC) Class $class, Instance $instance:\n$message";
+ }
+
+ ret = zeph_send_notice(&notice, (defs.auth) ? ZAUTH : ZNOAUTH);
+ free(sig_msg);
+ return ret;
+}
+
+int zeph_ping(dest)
+ Dest dest;
+{
+ ZNotice_t notice;
+
+ (void) memset((char *) &notice, 0, sizeof(ZNotice_t));
+ notice.z_kind = ACKED;
+ notice.z_class = dest->zclass;
+ notice.z_class_inst = dest->zinst;
+ notice.z_recipient = dest->zrecip;
+ notice.z_opcode = "PING";
+
+ /* Should a PING ever be authenticated? */
+ return (zeph_send_notice(&notice, ZNOAUTH));
+}
+
+int zeph_pong(dest)
+ Dest dest;
+{
+ ZNotice_t notice;
+
+ (void) memset((char *) &notice, 0, sizeof(ZNotice_t));
+ notice.z_kind = ACKED;
+ notice.z_class = dest->zclass;
+ notice.z_class_inst = dest->zinst;
+ notice.z_recipient = dest->zrecip;
+ notice.z_opcode = "PING";
+ notice.z_message = "PONG";
+ notice.z_message_len = 4;
+
+ /* Should a PING ever be authenticated? */
+ return (zeph_send_notice(&notice, ZNOAUTH));
+}
+
+char *zeph_get_signature()
+{
+ char *sig;
+
+ sig = ZGetVariable("xzwrite-signature");
+ if (! sig) sig = ZGetVariable("zwrite-signature");
+ return sig;
+}
+
+static int zeph_send_notice(notice, auth)
+ ZNotice_t *notice;
+ int (*auth)();
+{
+ int retval;
+ ZNotice_t retnotice;
+
+ /* Send message with appropriate authentication */
+ retval = ZSendNotice(notice, auth);
+ if (retval != ZERR_NONE) {
+ if (defs.debug)
+ Warning(error_message(retval), " while sending message.", NULL);
+ return SENDFAIL_SEND;
+ }
+
+ /* Wait for server acknowledgement */
+ retval = ZIfNotice(&retnotice, (struct sockaddr_in *) 0,
+ ZCompareUIDPred, (char *) &notice->z_uid);
+
+ if (retval != ZERR_NONE) {
+ if (defs.debug)
+ Warning(error_message(retval),
+ " while waiting for acknowledgement.", NULL);
+ return SENDFAIL_ACK;
+ }
+
+ /* Make sure someone receives it */
+ if (strcmp(retnotice.z_message, ZSRVACK_NOTSENT)==0)
+ return SENDFAIL_RECV;
+
+ return SEND_OK;
+}
+
+#ifdef DEBUG
+/* debugging function */
+void zeph_display_subscriptions()
+{
+ ZSubscription_t sub;
+ int n, retval, i = 1;
+
+ retval = ZRetrieveSubscriptions((unsigned short) 0, &n);
+ if (retval != ZERR_NONE) {
+ Warning(error_message(retval), " while retrieving subscriptions.",
+ NULL);
+ return;
+ }
+
+ printf("Retrieving %d subscriptions.\n", n);
+
+ while (ZGetSubscriptions(&sub, &i) == ZERR_NONE) {
+ if (i != 1)
+ Warning("Subscriptions skipped while printing.", NULL);
+
+ printf("<%s,%s,%s>\n", sub.class, (*sub.zsub_classinst) ?
+ sub.zsub_classinst : "**", (*sub.zsub_recipient) ?
+ sub.zsub_recipient : "**");
+ }
+}
+#endif