changeset 1700:1e0fa7e130d0

[gaim-migrate @ 1710] Zephyr. committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Thu, 12 Apr 2001 09:21:16 +0000
parents 644056e095f1
children e2922e6435bc
files ChangeLog STATUS TODO acconfig.h configure.in plugins/Makefile.am plugins/zephyr/.cvsignore plugins/zephyr/Makefile.am plugins/zephyr/ZAsyncLocate.c plugins/zephyr/ZCkAuth.c plugins/zephyr/ZCkIfNot.c plugins/zephyr/ZClosePort.c plugins/zephyr/ZCmpUID.c plugins/zephyr/ZCmpUIDP.c plugins/zephyr/ZFlsLocs.c plugins/zephyr/ZFlsSubs.c plugins/zephyr/ZFmtAuth.c plugins/zephyr/ZFmtList.c plugins/zephyr/ZFmtNotice.c plugins/zephyr/ZFmtRaw.c plugins/zephyr/ZFmtRawLst.c plugins/zephyr/ZFmtSmRLst.c plugins/zephyr/ZFmtSmRaw.c plugins/zephyr/ZFreeNot.c plugins/zephyr/ZGetLocs.c plugins/zephyr/ZGetSender.c plugins/zephyr/ZGetSubs.c plugins/zephyr/ZGetWGPort.c plugins/zephyr/ZIfNotice.c plugins/zephyr/ZInit.c plugins/zephyr/ZLocations.c plugins/zephyr/ZMakeAscii.c plugins/zephyr/ZMkAuth.c plugins/zephyr/ZNewLocU.c plugins/zephyr/ZOpenPort.c plugins/zephyr/ZParseNot.c plugins/zephyr/ZPeekIfNot.c plugins/zephyr/ZPeekNot.c plugins/zephyr/ZPeekPkt.c plugins/zephyr/ZPending.c plugins/zephyr/ZReadAscii.c plugins/zephyr/ZRecvNot.c plugins/zephyr/ZRecvPkt.c plugins/zephyr/ZRetSubs.c plugins/zephyr/ZSendList.c plugins/zephyr/ZSendNot.c plugins/zephyr/ZSendPkt.c plugins/zephyr/ZSendRLst.c plugins/zephyr/ZSendRaw.c plugins/zephyr/ZSetDest.c plugins/zephyr/ZSetFD.c plugins/zephyr/ZSetSrv.c plugins/zephyr/ZSubs.c plugins/zephyr/ZVariables.c plugins/zephyr/ZWait4Not.c plugins/zephyr/Zinternal.c plugins/zephyr/com_err.h plugins/zephyr/error_message.c plugins/zephyr/error_table.h plugins/zephyr/et_name.c plugins/zephyr/init_et.c plugins/zephyr/internal.h plugins/zephyr/mit-copyright.h plugins/zephyr/mit-sipb-copyright.h plugins/zephyr/sysdep.h plugins/zephyr/zephyr.c plugins/zephyr/zephyr.h plugins/zephyr/zephyr_err.c plugins/zephyr/zephyr_err.h
diffstat 69 files changed, 5924 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Apr 12 01:03:56 2001 +0000
+++ b/ChangeLog	Thu Apr 12 09:21:16 2001 +0000
@@ -10,6 +10,8 @@
 	* Sound on buddy pounce (Thanks Andrew Echols)
 	* Can view all group chats in one tabbed window (same keybindings
 	  as for tabbed normal conversations)
+	* More Protocol plugins:
+		Zephyr (plugins/zephyr)
 
 version 0.11.0-pre9 (03/26/2001):
 	* Can register Jabber accounts (load the Jabber plugin and click
--- a/STATUS	Thu Apr 12 01:03:56 2001 +0000
+++ b/STATUS	Thu Apr 12 09:21:16 2001 +0000
@@ -1,4 +1,4 @@
-STATUS of GAIM CVS tree. Last modified $Date: 2001-03-27 16:01:29 -0500 (Tue, 27 Mar 2001) $ by
+STATUS of GAIM CVS tree. Last modified $Date: 2001-04-12 05:21:16 -0400 (Thu, 12 Apr 2001) $ by
 $Author: warmenhoven $.
 
 This file is meant to provide gaim users who use the CVS version to see whether
@@ -145,3 +145,13 @@
 You can search for files and browse a list of other user's files.  You can
 currently download files as long as the person you're retrieving files from
 is not firewalled.
+
+
+Zephyr (Eric)
+======
+Let me start off by saying how much I really despise Zephyr. They do a lot of
+things that make me realize why this never caught on. For those of you who are
+unfortunate enough to feel compelling need to use this, gaim now has a Zephyr
+plugin. It can currently sign on/off, handles presence/buddy lists (it even
+imports your .anyone file!), and can send/receive personal messages. A lot of
+stuff is missing, this is just a real rough first stab at it.
--- a/TODO	Thu Apr 12 01:03:56 2001 +0000
+++ b/TODO	Thu Apr 12 09:21:16 2001 +0000
@@ -52,9 +52,11 @@
 	File Transfer
 	New User Registration
 
+Zephyr:
+	God help us.
+
 Future Plugins? :
 	ICQ through Oscar plugin (requires hacking libfaim :-/)
-	Zephyr (do people even want this? should I bother?)
 	Hotline (Or is this a waste of time?.  Ill decide soon enough, heh)
 
 
--- a/acconfig.h	Thu Apr 12 01:03:56 2001 +0000
+++ b/acconfig.h	Thu Apr 12 09:21:16 2001 +0000
@@ -16,6 +16,8 @@
 #undef _REENTRANT
 #undef NEED_GNOMESUPPORT_H
 #undef NEED_SOCKLEN_T
+#undef ZEPHYR_INT32
+#undef ZEPHYR_USES_KERBEROS
 
 
 
--- a/configure.in	Thu Apr 12 01:03:56 2001 +0000
+++ b/configure.in	Thu Apr 12 09:21:16 2001 +0000
@@ -53,6 +53,7 @@
 AC_ARG_ENABLE(perl,    [  --disable-perl          compile without perl scripting],,enable_perl=yes)
 AC_ARG_ENABLE(debug,   [  --enable-debug          compile with debugging support],,enable_debug=no)
 AC_ARG_ENABLE(screensaver,   [  --disable-screensaver   compile without X screensaver extension],,enable_xss=yes)
+AC_ARG_WITH(krb4,      [  --with-krb4=PREFIX      Compile Zephyr plugin with Kerberos 4 support],kerberos="$withval",kerberos="no")
 AC_ARG_ENABLE(,,,)
 
 if test "$enable_debug" = yes ; then
@@ -204,6 +205,38 @@
 	AC_CHECK_FUNCS(snprintf connect)
 	AC_CHECK_LIB(nsl, gethostent)
 
+	dnl checks for zephyr
+	AC_DEFINE(ZEPHYR_INT32, long)
+	if test "x$kerberos" != "xno" ; then
+		if test "x$kerberos" != "xyes" ; then
+			CFLAGS="$CFLAGS -I${kerberos}/include"
+			if test -d "$kerberos/include/kerberosIV" ; then
+				CFLAGS="$CFLAGS -I${kerberos}/include/kerberosIV"
+			fi
+			LDFLAGS="$LDFLAGS -L${kerberos}/lib"
+		elif test -d /usr/local/include/kerberosIV ; then
+			CFLAGS="$CFLAGS -I/usr/local/include/kerberosIV"
+		elif test -d /usr/include/kerberosIV ; then
+			CFLAGS="$CFLAGS -I/usr/include/kerberosIV"
+		fi
+		AC_DEFINE(ZEPHYR_USES_KERBEROS)
+		AC_CHECK_LIB(krb4, krb_rd_req,
+				[KRB4_LIBS="-lkrb4 -ldes425 -lkrb5 -lcrypto"],
+				[AC_CHECK_LIB(krb, krb_rd_req,
+					[KRB4_LIBS="-lkrb -ldes"],
+					[AC_ERROR(Kerberos 4 libraries not found)],
+					-ldes)],
+				-ldes425 -lkrb5 -lcrypto)
+		LIBS="$LIBS $KRB4_LIBS"
+		AC_CHECK_FUNCS(krb_set_key krb_rd_req krb_get_lrealm)
+	fi
+	AC_CHECK_FUNCS(gethostid krb_get_err_text krb_log lrand48)
+	AC_CHECK_FUNCS(memcpy memmove random strchr strerror vprintf)
+	AC_CHECK_HEADERS(malloc.h paths.h sgtty.h stdarg.h sys/cdefs.h)
+	AC_CHECK_HEADERS(sys/file.h sys/filio.h sys/ioctl.h sys/msgbuf.h)
+	AC_CHECK_HEADERS(sys/select.h sys/uio.h sys/utsname.h sys/wait.h)
+	AC_CHECK_HEADERS(termios.h)
+
 	AM_CONDITIONAL(PRPLS, test "x$enable_plugins" = "xyes")
 else
 	enable_prpls=no
@@ -218,6 +251,7 @@
 	   plugins/icq/Makefile
 	   plugins/msn/Makefile
 	   plugins/jabber/Makefile
+	   plugins/zephyr/Makefile
            pixmaps/Makefile
            libfaim/Makefile
 	   po/Makefile.in
--- a/plugins/Makefile.am	Thu Apr 12 01:03:56 2001 +0000
+++ b/plugins/Makefile.am	Thu Apr 12 09:21:16 2001 +0000
@@ -17,7 +17,7 @@
 
 if PRPLS
 
-SUBDIRS = yay icq msn jabber
+SUBDIRS = yay icq msn jabber zephyr
 
 prpls = irc.so napster.so
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/.cvsignore	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,120 @@
+Makefile.in
+Makefile
+.deps
+ZCkAuth.lo
+ZAsyncLocate.lo
+ZCkIfNot.lo
+ZClosePort.lo
+ZCmpUID.lo
+ZCmpUIDP.lo
+ZFlsLocs.lo
+ZFlsSubs.lo
+ZFmtAuth.lo
+ZFmtList.lo
+ZFmtNotice.lo
+ZFmtRaw.lo
+ZFmtRawLst.lo
+ZFmtSmRLst.lo
+ZFmtSmRaw.lo
+ZFreeNot.lo
+ZGetLocs.lo
+ZGetSender.lo
+ZGetSubs.lo
+ZGetWGPort.lo
+ZIfNotice.lo
+ZInit.lo
+ZLocations.lo
+ZMakeAscii.lo
+ZMkAuth.lo
+ZNewLocU.lo
+ZOpenPort.lo
+ZParseNot.lo
+ZPeekIfNot.lo
+ZPeekNot.lo
+ZPeekPkt.lo
+ZPending.lo
+ZReadAscii.lo
+ZRecvNot.lo
+ZRecvPkt.lo
+ZRetSubs.lo
+ZSendList.lo
+ZSendNot.lo
+ZSendPkt.lo
+ZSendRLst.lo
+ZSendRaw.lo
+ZSetDest.lo
+ZSetFD.lo
+ZSetSrv.lo
+ZSubs.lo
+ZVariables.lo
+ZWait4Not.lo
+Zinternal.lo
+error_message.lo
+et_name.lo
+init_et.lo
+zephyr_err.lo
+zephyr.lo
+.libs
+libzephyr.la
+Makefile.am
+ZAsyncLocate.c
+ZCkAuth.c
+ZCkIfNot.c
+ZClosePort.c
+ZCmpUID.c
+ZCmpUIDP.c
+ZFlsLocs.c
+ZFlsSubs.c
+ZFmtAuth.c
+ZFmtList.c
+ZFmtNotice.c
+ZFmtRaw.c
+ZFmtRawLst.c
+ZFmtSmRLst.c
+ZFmtSmRaw.c
+ZFreeNot.c
+ZGetLocs.c
+ZGetSender.c
+ZGetSubs.c
+ZGetWGPort.c
+ZIfNotice.c
+ZInit.c
+ZLocations.c
+ZMakeAscii.c
+ZMkAuth.c
+ZNewLocU.c
+ZOpenPort.c
+ZParseNot.c
+ZPeekIfNot.c
+ZPeekNot.c
+ZPeekPkt.c
+ZPending.c
+ZReadAscii.c
+ZRecvNot.c
+ZRecvPkt.c
+ZRetSubs.c
+ZSendList.c
+ZSendNot.c
+ZSendPkt.c
+ZSendRLst.c
+ZSendRaw.c
+ZSetDest.c
+ZSetFD.c
+ZSetSrv.c
+ZSubs.c
+ZVariables.c
+ZWait4Not.c
+Zinternal.c
+com_err.h
+error_message.c
+error_table.h
+et_name.c
+init_et.c
+internal.h
+mit-copyright.h
+mit-sipb-copyright.h
+sysdep.h
+zephyr.c
+zephyr.h
+zephyr_err.c
+zephyr_err.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/Makefile.am	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,69 @@
+CFLAGS += -I\$(top_srcdir)/src -I\$(top_srcdir)/plugins -DCONFDIR=\"$(confdir)\"
+LIBS += $(GTK_LIBS)
+
+pkgdir = $(libdir)/gaim
+pkg_LTLIBRARIES = libzephyr.la
+
+libzephyr_la_SOURCES = \
+			ZAsyncLocate.c \
+			ZCkAuth.c \
+			ZCkIfNot.c \
+			ZClosePort.c \
+			ZCmpUID.c \
+			ZCmpUIDP.c \
+			ZFlsLocs.c \
+			ZFlsSubs.c \
+			ZFmtAuth.c \
+			ZFmtList.c \
+			ZFmtNotice.c \
+			ZFmtRaw.c \
+			ZFmtRawLst.c \
+			ZFmtSmRLst.c \
+			ZFmtSmRaw.c \
+			ZFreeNot.c \
+			ZGetLocs.c \
+			ZGetSender.c \
+			ZGetSubs.c \
+			ZGetWGPort.c \
+			ZIfNotice.c \
+			ZInit.c \
+			ZLocations.c \
+			ZMakeAscii.c \
+			ZMkAuth.c \
+			ZNewLocU.c \
+			ZOpenPort.c \
+			ZParseNot.c \
+			ZPeekIfNot.c \
+			ZPeekNot.c \
+			ZPeekPkt.c \
+			ZPending.c \
+			ZReadAscii.c \
+			ZRecvNot.c \
+			ZRecvPkt.c \
+			ZRetSubs.c \
+			ZSendList.c \
+			ZSendNot.c \
+			ZSendPkt.c \
+			ZSendRLst.c \
+			ZSendRaw.c \
+			ZSetDest.c \
+			ZSetFD.c \
+			ZSetSrv.c \
+			ZSubs.c \
+			ZVariables.c \
+			ZWait4Not.c \
+			Zinternal.c \
+			com_err.h \
+			error_message.c \
+			error_table.h \
+			et_name.c \
+			init_et.c \
+			internal.h \
+			mit-copyright.h \
+			mit-sipb-copyright.h \
+			sysdep.h \
+			zephyr.h \
+			zephyr_err.c \
+			zephyr_err.h \
+			\
+			zephyr.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZAsyncLocate.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,170 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for asynchronous location functions.
+ *
+ *	Created by:	Marc Horowitz
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1990,1991 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#include <internal.h>
+
+#ifndef lint
+static const char rcsid_ZAsyncLocate_c[] = "$Id: ZAsyncLocate.c 1710 2001-04-12 09:21:16Z warmenhoven $";
+#endif
+
+Code_t ZRequestLocations(user, zald, kind, auth)
+     char *user;
+     register ZAsyncLocateData_t *zald;
+     ZNotice_Kind_t kind;	/* UNSAFE, UNACKED, or ACKED */
+     Z_AuthProc auth;
+{
+    int retval;
+    ZNotice_t notice;
+
+    if (ZGetFD() < 0)
+	if ((retval = ZOpenPort((u_short *)0)) != ZERR_NONE)
+	    return (retval);
+
+    (void) memset((char *)&notice, 0, sizeof(notice));
+    notice.z_kind = kind;
+    notice.z_port = __Zephyr_port;
+    notice.z_class = LOCATE_CLASS;
+    notice.z_class_inst = user;
+    notice.z_opcode = LOCATE_LOCATE;
+    notice.z_sender = 0;
+    notice.z_recipient = "";
+    notice.z_default_format = "";
+    notice.z_message_len = 0;
+
+    if ((retval = ZSendNotice(&notice, auth)) != ZERR_NONE)
+	return(retval);
+
+    if ((zald->user = (char *) malloc(strlen(user)+1)) == NULL) {
+	return(ENOMEM);
+    }
+    if ((zald->version = (char *) malloc(strlen(notice.z_version)+1)) == NULL) {
+	free(zald->user);
+	return(ENOMEM);
+    }
+    zald->uid = notice.z_multiuid;
+    strcpy(zald->user,user);
+    strcpy(zald->version,notice.z_version);
+
+    return(ZERR_NONE);
+}
+
+Code_t ZParseLocations(notice,zald,nlocs,user)
+     register ZNotice_t *notice;
+     register ZAsyncLocateData_t *zald;
+     int *nlocs;
+     char **user;
+{
+    char *ptr, *end;
+    int i;
+
+    ZFlushLocations();    /* This never fails (this function is part of the
+			     library, so it is allowed to know this). */
+
+    /* non-matching protocol version numbers means the
+       server is probably an older version--must punt */
+
+    if (zald && strcmp(notice->z_version, zald->version))
+      return(ZERR_VERS);
+
+    if (notice->z_kind == SERVNAK)
+      return (ZERR_SERVNAK);
+
+    /* flag ACKs as special */
+    if (notice->z_kind == SERVACK &&
+	!strcmp(notice->z_opcode, LOCATE_LOCATE)) {
+	*nlocs = -1;
+	return(ZERR_NONE);
+    }
+
+    if (notice->z_kind != ACKED)
+	return (ZERR_INTERNAL);
+
+    end = notice->z_message+notice->z_message_len;
+
+    __locate_num = 0;
+	
+    for (ptr=notice->z_message;ptr<end;ptr++)
+      if (!*ptr)
+	__locate_num++;
+
+    __locate_num /= 3;
+
+    if (__locate_num)
+      {
+      __locate_list = (ZLocations_t *)malloc((unsigned)__locate_num*
+					     sizeof(ZLocations_t));
+      if (!__locate_list)
+	return (ENOMEM);
+    } else {
+      __locate_list = 0;
+    }
+
+    for (ptr=notice->z_message, i=0; i<__locate_num; i++) {
+       unsigned int len;
+
+       len = strlen (ptr) + 1;
+       __locate_list[i].host = (char *) malloc(len);
+       if (!__locate_list[i].host)
+	  return (ENOMEM);
+       (void) strcpy(__locate_list[i].host, ptr);
+       ptr += len;
+
+       len = strlen (ptr) + 1;
+       __locate_list[i].time = (char *) malloc(len);
+       if (!__locate_list[i].time)
+	  return (ENOMEM);
+       (void) strcpy(__locate_list[i].time, ptr);
+       ptr += len;
+
+       len = strlen (ptr) + 1;
+       __locate_list[i].tty = (char *) malloc(len);
+       if (!__locate_list[i].tty)
+	  return (ENOMEM);
+       (void) strcpy(__locate_list[i].tty, ptr);
+       ptr += len;
+    }
+
+    __locate_next = 0;
+    *nlocs = __locate_num;
+    if (user) {
+	if (zald) {
+	    if ((*user = (char *) malloc(strlen(zald->user)+1)) == NULL)
+		return(ENOMEM);
+	    strcpy(*user,zald->user);
+	} else {
+	    if ((*user = (char *) malloc(strlen(notice->z_class_inst)+1)) == NULL)
+		return(ENOMEM);
+	    strcpy(*user,notice->z_class_inst);
+	}
+    }
+    return (ZERR_NONE);
+}
+
+int ZCompareALDPred(notice, zald)
+     ZNotice_t *notice;
+     void *zald;
+{
+    return(ZCompareUID(&(notice->z_multiuid),
+		       &(((ZAsyncLocateData_t *) zald)->uid)));
+}
+
+void ZFreeALD(zald)
+     register ZAsyncLocateData_t *zald;
+{
+   if (!zald) return;
+
+   if (zald->user) free(zald->user);
+   if (zald->version) free(zald->version);
+   (void) memset(zald, 0, sizeof(*zald));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZCkAuth.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,64 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZCheckAuthentication function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987,1991 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZCheckAuthentication_c[] =
+    "$Zephyr: /mit/zephyr/src/lib/RCS/ZCheckAuthentication.c,v 1.14 89/03/24 14:17:38 jtkohl Exp Locker: raeburn $";
+#endif
+
+#include <internal.h>
+
+/* Check authentication of the notice.
+   If it looks authentic but fails the Kerberos check, return -1.
+   If it looks authentic and passes the Kerberos check, return 1.
+   If it doesn't look authentic, return 0
+
+   When not using Kerberos, return true if the notice claims to be authentic.
+   Only used by clients; the server uses its own routine.
+ */
+Code_t ZCheckAuthentication(notice, from)
+    ZNotice_t *notice;
+    struct sockaddr_in *from;
+{	
+#ifdef ZEPHYR_USES_KERBEROS
+    int result;
+    ZChecksum_t our_checksum;
+    CREDENTIALS cred;
+
+    /* If the value is already known, return it. */
+    if (notice->z_checked_auth != ZAUTH_UNSET)
+	return (notice->z_checked_auth);
+
+    if (!notice->z_auth)
+	return (ZAUTH_NO);
+	
+    if ((result = krb_get_cred(SERVER_SERVICE, SERVER_INSTANCE, 
+			       __Zephyr_realm, &cred)) != 0)
+	return (ZAUTH_NO);
+
+#ifdef NOENCRYPTION
+    our_checksum = 0;
+#else
+    our_checksum = des_quad_cksum(notice->z_packet, NULL, 
+				  notice->z_default_format+
+				  strlen(notice->z_default_format)+1-
+				  notice->z_packet, 0, cred.session);
+#endif
+    /* if mismatched checksum, then the packet was corrupted */
+    return ((our_checksum == notice->z_checksum) ? ZAUTH_YES : ZAUTH_FAILED);
+
+#else
+    return (notice->z_auth ? ZAUTH_YES : ZAUTH_NO);
+#endif
+} 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZCkIfNot.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,59 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZCheckIfNotice function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#include <internal.h>
+
+#ifndef lint
+static const char rcsid_ZCheckIfNotice_c[] = "$Id: ZCkIfNot.c 1710 2001-04-12 09:21:16Z warmenhoven $";
+#endif
+
+Code_t ZCheckIfNotice(notice, from, predicate, args)
+    ZNotice_t *notice;
+    struct sockaddr_in *from;
+    register int (*predicate) __P((ZNotice_t *, void *));
+    void *args;
+{
+    ZNotice_t tmpnotice;
+    Code_t retval;
+    register char *buffer;
+    register struct _Z_InputQ *qptr;
+
+    if ((retval = Z_ReadEnqueue()) != ZERR_NONE)
+	return (retval);
+	
+    qptr = Z_GetFirstComplete();
+    
+    while (qptr) {
+	if ((retval = ZParseNotice(qptr->packet, qptr->packet_len, 
+				   &tmpnotice)) != ZERR_NONE)
+	    return (retval);
+	if ((*predicate)(&tmpnotice, args)) {
+	    if (!(buffer = (char *) malloc((unsigned) qptr->packet_len)))
+		return (ENOMEM);
+	    (void) memcpy(buffer, qptr->packet, qptr->packet_len);
+	    if (from)
+		*from = qptr->from;
+	    if ((retval = ZParseNotice(buffer, qptr->packet_len, 
+				       notice)) != ZERR_NONE) {
+		free(buffer);
+		return (retval);
+	    }
+	    Z_RemQueue(qptr);
+	    return (ZERR_NONE);
+	} 
+	qptr = Z_GetNextComplete(qptr);
+    }
+
+    return (ZERR_NONOTICE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZClosePort.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,30 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZClosePort function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#include <internal.h>
+
+#ifndef lint
+static const char rcsid_ZClosePort_c[] = "$Id: ZClosePort.c 1710 2001-04-12 09:21:16Z warmenhoven $";
+#endif
+
+Code_t ZClosePort()
+{
+    if (__Zephyr_fd >= 0 && __Zephyr_open)
+	(void) close(__Zephyr_fd);
+
+    __Zephyr_fd = -1;
+    __Zephyr_open = 0;
+	
+    return (ZERR_NONE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZCmpUID.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,25 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZCompareUID function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZCompareUID_c[] = "$Id: ZCmpUID.c 1710 2001-04-12 09:21:16Z warmenhoven $";
+#endif
+
+#include <internal.h>
+
+int ZCompareUID(uid1, uid2)
+    ZUnique_Id_t *uid1, *uid2;
+{
+    return (!memcmp((char *)uid1, (char *)uid2, sizeof (*uid1)));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZCmpUIDP.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,33 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZCompareUIDPred function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZCompareUIDPred_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+
+int ZCompareUIDPred(notice, uid)
+    ZNotice_t *notice;
+    void *uid;
+{
+    return (ZCompareUID(&notice->z_uid, (ZUnique_Id_t *) uid));
+}
+
+int ZCompareMultiUIDPred(notice, uid)
+    ZNotice_t *notice;
+    void *uid;
+{
+    return (ZCompareUID(&notice->z_multiuid, (ZUnique_Id_t *) uid));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZFlsLocs.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,40 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZFlushLocations function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZFlushLocations_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+
+Code_t ZFlushLocations()
+{
+	int i;
+	
+	if (!__locate_list)
+		return (ZERR_NONE);
+
+	for (i=0;i<__locate_num;i++) {
+		free(__locate_list[i].host);
+		free(__locate_list[i].time);
+		free(__locate_list[i].tty);
+	}
+	
+	free((char *)__locate_list);
+
+	__locate_list = 0;
+	__locate_num = 0;
+
+	return (ZERR_NONE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZFlsSubs.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,41 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZFlushSubscriptions function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#include <internal.h>
+
+#ifndef lint
+static const char rcsid_ZFlushSubscriptions_c[] = "$Id: ZFlsSubs.c 1710 2001-04-12 09:21:16Z warmenhoven $";
+#endif
+
+Code_t ZFlushSubscriptions()
+{
+	register int i;
+	
+	if (!__subscriptions_list)
+		return (ZERR_NONE);
+
+	for (i=0;i<__subscriptions_num;i++) {
+		free(__subscriptions_list[i].zsub_class);
+		free(__subscriptions_list[i].zsub_classinst);
+		free(__subscriptions_list[i].zsub_recipient);
+	}
+	
+	free((char *)__subscriptions_list);
+
+	__subscriptions_list = 0;
+	__subscriptions_num = 0;
+
+	return (ZERR_NONE);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZFmtAuth.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,66 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZFormatAuthenticNotice function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZFormatAuthenticNotice_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+
+#ifdef ZEPHYR_USES_KERBEROS
+Code_t ZFormatAuthenticNotice(notice, buffer, buffer_len, len, session)
+    ZNotice_t *notice;
+    register char *buffer;
+    register int buffer_len;
+    int *len;
+    C_Block session;
+{
+    ZNotice_t newnotice;
+    char *ptr;
+    int retval, hdrlen;
+
+    newnotice = *notice;
+    newnotice.z_auth = 1;
+    newnotice.z_authent_len = 0;
+    newnotice.z_ascii_authent = "";
+
+    if ((retval = Z_FormatRawHeader(&newnotice, buffer, buffer_len,
+				    &hdrlen, &ptr, NULL)) != ZERR_NONE)
+	return (retval);
+
+#ifdef NOENCRYPTION
+    newnotice.z_checksum = 0;
+#else
+    newnotice.z_checksum =
+	(ZChecksum_t)des_quad_cksum(buffer, NULL, ptr - buffer, 0, session);
+#endif
+    if ((retval = Z_FormatRawHeader(&newnotice, buffer, buffer_len,
+				    &hdrlen, NULL, NULL)) != ZERR_NONE)
+	return (retval);
+
+    ptr = buffer+hdrlen;
+
+    if (newnotice.z_message_len+hdrlen > buffer_len)
+	return (ZERR_PKTLEN);
+
+    (void) memcpy(ptr, newnotice.z_message, newnotice.z_message_len);
+
+    *len = hdrlen+newnotice.z_message_len;
+
+    if (*len > Z_MAXPKTLEN)
+	return (ZERR_PKTLEN);
+
+    return (ZERR_NONE);
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZFmtList.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,62 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZFormatNoticeList function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987,1991 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#include <internal.h>
+
+#ifndef lint
+static const char rcsid_ZFormatNoticeList_c[] =
+    "$Id: ZFmtList.c 1710 2001-04-12 09:21:16Z warmenhoven $";
+#endif
+
+Code_t ZFormatNoticeList(notice, list, nitems, buffer, ret_len, 
+			 cert_routine)
+    ZNotice_t *notice;
+    register char **list;
+    int nitems;
+    char **buffer;
+    int *ret_len;
+    Z_AuthProc cert_routine;
+{
+    char header[Z_MAXHEADERLEN];
+    register int i;
+    int hdrlen, size;
+    char *ptr;
+    Code_t retval;
+
+    if ((retval = Z_FormatHeader(notice, header, sizeof(header), &hdrlen,
+				 cert_routine)) != ZERR_NONE)
+	return (retval);
+
+    size = 0;
+    for (i=0;i<nitems;i++)
+	size += strlen(list[i])+1;
+
+    *ret_len = hdrlen+size;
+
+    /* *ret_len can never be zero here, no need to worry about malloc(0). */
+    if (!(*buffer = (char *) malloc((unsigned)*ret_len)))
+	return (ENOMEM);
+
+    (void) memcpy(*buffer, header, hdrlen);
+
+    ptr = *buffer+hdrlen;
+
+    for (;nitems;nitems--, list++) {
+	i = strlen(*list)+1;
+	(void) memcpy(ptr, *list, i);
+	ptr += i;
+    }
+
+    return (ZERR_NONE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZFmtNotice.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,45 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZFormatNotice function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZFormatNotice_c[] = "$Id: ZFmtNotice.c 1710 2001-04-12 09:21:16Z warmenhoven $";
+#endif
+
+#include <internal.h>
+
+Code_t ZFormatNotice(notice, buffer, ret_len, cert_routine)
+    register ZNotice_t *notice;
+    char **buffer;
+    int *ret_len;
+    Z_AuthProc cert_routine;
+{
+    char header[Z_MAXHEADERLEN];
+    int hdrlen;
+    Code_t retval;
+
+    if ((retval = Z_FormatHeader(notice, header, sizeof(header), &hdrlen, 
+				 cert_routine)) != ZERR_NONE)
+	return (retval);
+
+    *ret_len = hdrlen+notice->z_message_len;
+
+    /* Length can never be zero, don't have to worry about malloc(0). */
+    if (!(*buffer = (char *) malloc((unsigned)*ret_len)))
+	return (ENOMEM);
+
+    (void) memcpy(*buffer, header, hdrlen);
+    (void) memcpy(*buffer+hdrlen, notice->z_message, notice->z_message_len);
+
+    return (ZERR_NONE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZFmtRaw.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,44 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZFormatRawNotice function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZFormatRawNotice_c[] = "$Id: ZFmtRaw.c 1710 2001-04-12 09:21:16Z warmenhoven $";
+#endif
+
+#include <internal.h>
+
+Code_t ZFormatRawNotice(notice, buffer, ret_len)
+    register ZNotice_t *notice;
+    char **buffer;
+    int *ret_len;
+{
+    char header[Z_MAXHEADERLEN];
+    int hdrlen;
+    Code_t retval;
+
+    if ((retval = Z_FormatRawHeader(notice, header, sizeof(header),
+				    &hdrlen, NULL, NULL)) != ZERR_NONE)
+	return (retval);
+
+    *ret_len = hdrlen+notice->z_message_len;
+
+    /* *ret_len is never 0, don't have to worry about malloc(0) */
+    if (!(*buffer = (char *) malloc((unsigned) *ret_len)))
+	return (ENOMEM);
+
+    (void) memcpy(*buffer, header, hdrlen);
+    (void) memcpy(*buffer+hdrlen, notice->z_message, notice->z_message_len);
+
+    return (ZERR_NONE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZFmtRawLst.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,57 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZFormatRawNoticeList function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZFormatRawNoticeList_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+
+Code_t ZFormatRawNoticeList(notice, list, nitems, buffer, ret_len)
+    ZNotice_t *notice;
+    char *list[];
+    int nitems;
+    char **buffer;
+    int *ret_len;
+{
+    char header[Z_MAXHEADERLEN];
+    int hdrlen, i, size;
+    char *ptr;
+    Code_t retval;
+
+    if ((retval = Z_FormatRawHeader(notice, header, sizeof(header),
+				    &hdrlen, NULL, NULL)) != ZERR_NONE)
+	return (retval);
+
+    size = 0;
+    for (i=0;i<nitems;i++)
+	size += strlen(list[i])+1;
+
+    *ret_len = hdrlen+size;
+    
+    if (!(*buffer = (char *) malloc((unsigned) *ret_len)))
+	return (ENOMEM);
+
+    (void) memcpy(*buffer, header, hdrlen);
+    
+    ptr = *buffer+hdrlen;
+
+    for (;nitems;nitems--, list++) {
+	i = strlen(*list)+1;
+	(void) memcpy(ptr, *list, i);
+	ptr += i;
+    }
+
+    return (ZERR_NONE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZFmtSmRLst.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,54 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZFormatSmallRawNoticeList function.
+ *
+ *	Created by:	John T. Kohl
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1988 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZFormatRawNoticeList_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+
+Code_t ZFormatSmallRawNoticeList(notice, list, nitems, buffer, ret_len)
+    ZNotice_t *notice;
+    char *list[];
+    int nitems;
+    ZPacket_t buffer;
+    int *ret_len;
+{
+    Code_t retval;
+    int hdrlen, i, size;
+    char *ptr;
+
+    if ((retval = Z_FormatRawHeader(notice, buffer, Z_MAXHEADERLEN,
+				    &hdrlen, NULL, NULL)) != ZERR_NONE)
+	return (retval);
+
+    size = 0;
+    for (i=0;i<nitems;i++)
+	size += strlen(list[i])+1;
+
+    *ret_len = hdrlen+size;
+
+    if (*ret_len > Z_MAXPKTLEN)
+	return (ZERR_PKTLEN);
+
+    ptr = buffer+hdrlen;
+
+    for (;nitems;nitems--, list++) {
+	i = strlen(*list)+1;
+	(void) memcpy(ptr, *list, i);
+	ptr += i;
+    }
+
+    return (ZERR_NONE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZFmtSmRaw.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,41 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZFormatSmallRawNotice function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZFormatRawNotice_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+
+Code_t ZFormatSmallRawNotice(notice, buffer, ret_len)
+    ZNotice_t *notice;
+    ZPacket_t buffer;
+    int *ret_len;
+{
+    Code_t retval;
+    int hdrlen;
+    
+    if ((retval = Z_FormatRawHeader(notice, buffer, Z_MAXHEADERLEN,
+				    &hdrlen, NULL, NULL)) != ZERR_NONE)
+	return (retval);
+
+    *ret_len = hdrlen+notice->z_message_len;
+
+    if (*ret_len > Z_MAXPKTLEN)
+	return (ZERR_PKTLEN);
+
+    (void) memcpy(buffer+hdrlen, notice->z_message, notice->z_message_len);
+
+    return (ZERR_NONE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZFreeNot.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,26 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZFreeNotice function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZFreeNotice_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+
+Code_t ZFreeNotice(notice)
+    ZNotice_t *notice;
+{
+    free(notice->z_packet);
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZGetLocs.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,44 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZGetLocations function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZGetLocations_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+
+#define min(a,b) ((a)<(b)?(a):(b))
+	
+Code_t ZGetLocations(location, numlocs)
+    ZLocations_t *location;
+    int *numlocs;
+{
+    int i;
+	
+    if (!__locate_list)
+	return (ZERR_NOLOCATIONS);
+
+    if (__locate_next == __locate_num)
+	return (ZERR_NOMORELOCS);
+	
+    for (i=0;i<min(*numlocs, __locate_num-__locate_next);i++)
+	location[i] = __locate_list[i+__locate_next];
+
+    if (__locate_num-__locate_next < *numlocs)
+	*numlocs = __locate_num-__locate_next;
+
+    __locate_next += *numlocs;
+	
+    return (ZERR_NONE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZGetSender.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,54 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZGetSender.c function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987, 1991 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#include <internal.h>
+
+#ifndef lint
+static const char rcsid_ZGetSender_c[] =
+    "$Id: ZGetSender.c 1710 2001-04-12 09:21:16Z warmenhoven $";
+#endif
+
+#include <pwd.h>
+
+char *ZGetSender()
+{
+    struct passwd *pw;
+#ifdef ZEPHYR_USES_KERBEROS
+    char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
+    static char sender[ANAME_SZ+INST_SZ+REALM_SZ+3] = "";
+#else
+    static char sender[128] = "";
+#endif
+
+    /* Return it if already cached */
+    if (*sender)
+	return (sender);
+
+#ifdef ZEPHYR_USES_KERBEROS
+    if (krb_get_tf_fullname((char *)TKT_FILE, pname, pinst, prealm) == KSUCCESS)
+    {
+	(void) sprintf(sender, "%s%s%s@%s", pname, (pinst[0]?".":""),
+		       pinst, prealm);
+	return (sender);
+    }
+#endif
+
+    /* XXX a uid_t is a u_short (now),  but getpwuid
+     * wants an int. AARGH! */
+    pw = getpwuid((int) getuid());
+    if (!pw)
+	return ("unknown");
+    (void) sprintf(sender, "%s@%s", pw->pw_name, __Zephyr_realm);
+    return (sender);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZGetSubs.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,44 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZGetSubscriptions function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZGetSubscriptions_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+
+#define min(a,b) ((a)<(b)?(a):(b))
+	
+Code_t ZGetSubscriptions(subscription, numsubs)
+    ZSubscription_t *subscription;
+    int *numsubs;
+{
+    int i;
+	
+    if (!__subscriptions_list)
+	return (ZERR_NOSUBSCRIPTIONS);
+
+    if (__subscriptions_next == __subscriptions_num)
+	return (ZERR_NOMORESUBSCRIPTIONS);
+	
+    for (i=0;i<min(*numsubs, __subscriptions_num-__subscriptions_next);i++)
+	subscription[i] = __subscriptions_list[i+__subscriptions_next];
+
+    if (__subscriptions_num-__subscriptions_next < *numsubs)
+	*numsubs = __subscriptions_num-__subscriptions_next;
+
+    __subscriptions_next += *numsubs;
+	
+    return (ZERR_NONE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZGetWGPort.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,42 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZGetWGPort function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZGetWGPort_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+
+int ZGetWGPort()
+{
+    char *envptr, name[128];
+    FILE *fp;
+    int wgport;
+	
+    envptr = getenv("WGFILE");
+    if (!envptr) {
+	(void) sprintf(name, "/tmp/wg.%d", getuid());
+	envptr = name;
+    } 
+    if (!(fp = fopen(envptr, "r")))
+	return (-1);
+
+    /* if fscanf fails, return -1 via wgport */
+    if (fscanf(fp, "%d", &wgport) != 1)
+	    wgport = -1;
+
+    (void) fclose(fp);
+
+    return (wgport);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZIfNotice.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,64 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZIfNotice function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#include <internal.h>
+
+#ifndef lint
+static const char rcsid_ZIfNotice_c[] = "$Id: ZIfNotice.c 1710 2001-04-12 09:21:16Z warmenhoven $";
+#endif
+
+Code_t ZIfNotice(notice, from, predicate, args)
+    ZNotice_t *notice;
+    struct sockaddr_in *from;
+    int (*predicate) __P((ZNotice_t *, void *));
+    void *args;
+{
+    ZNotice_t tmpnotice;
+    Code_t retval;
+    char *buffer;
+    struct _Z_InputQ *qptr;
+
+    if ((retval = Z_WaitForComplete()) != ZERR_NONE)
+	return (retval);
+	
+    qptr = Z_GetFirstComplete();
+    
+    for (;;) {
+	while (qptr) {
+	    if ((retval = ZParseNotice(qptr->packet, qptr->packet_len, 
+				       &tmpnotice)) != ZERR_NONE)
+		return (retval);
+	    if ((*predicate)(&tmpnotice, args)) {
+		if (!(buffer = (char *) malloc((unsigned) qptr->packet_len)))
+		    return (ENOMEM);
+		(void) memcpy(buffer, qptr->packet, qptr->packet_len);
+		if (from)
+		    *from = qptr->from;
+		if ((retval = ZParseNotice(buffer, qptr->packet_len, 
+					   notice)) != ZERR_NONE) {
+		    free(buffer);
+		    return (retval);
+		}
+		Z_RemQueue(qptr);
+		return (ZERR_NONE);
+	    }
+	    qptr = Z_GetNextComplete(qptr);
+	}
+	if ((retval = Z_ReadWait()) != ZERR_NONE)
+	    return (retval);
+	qptr = Z_GetFirstComplete();	/* need to look over all of
+					   the queued messages, in case
+					   a fragment has been reassembled */
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZInit.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,69 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZInitialize function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987, 1991 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZInitialize_c[] =
+    "$Zephyr: /afs/athena.mit.edu/astaff/project/zephyr/src/lib/RCS/ZInitialize.c,v 1.17 89/05/30 18:11:25 jtkohl Exp $";
+#endif
+
+#include <internal.h>
+
+#include <sys/socket.h>
+#ifdef ZEPHYR_USES_KERBEROS
+#include <krb_err.h>
+#endif
+
+Code_t ZInitialize()
+{
+    struct servent *hmserv;
+    char addr[4];
+#ifdef ZEPHYR_USES_KERBEROS
+    int krbval;
+
+    initialize_krb_error_table();
+#endif
+
+    initialize_zeph_error_table();
+    
+    (void) memset((char *)&__HM_addr, 0, sizeof(__HM_addr));
+
+    __HM_addr.sin_family = AF_INET;
+
+    /* Set up local loopback address for HostManager */
+    addr[0] = 127;
+    addr[1] = 0;
+    addr[2] = 0;
+    addr[3] = 1;
+
+    hmserv = (struct servent *)getservbyname(HM_SVCNAME, "udp");
+    __HM_addr.sin_port = (hmserv) ? hmserv->s_port : HM_SVC_FALLBACK;
+
+    (void) memcpy((char *)&__HM_addr.sin_addr, addr, 4);
+
+    __HM_set = 0;
+
+#ifdef ZEPHYR_USES_KERBEROS
+    if ((krbval = krb_get_lrealm(__Zephyr_realm, 1)) != KSUCCESS)
+	return (krbval);
+#endif
+
+    /* Get the sender so we can cache it */
+    (void) ZGetSender();
+
+    /* Initialize the input queue */
+    __Q_Tail = NULL;
+    __Q_Head = NULL;
+    
+    return (ZERR_NONE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZLocations.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,168 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZSetLocation, ZUnsetLocation, and
+ * ZFlushMyLocations functions.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZLocations_c[] =
+    "$Zephyr: /afs/athena.mit.edu/astaff/project/zephyr/src/lib/RCS/ZLocations.c,v 1.30 90/12/20 03:04:39 raeburn Exp $";
+#endif
+
+#include <internal.h>
+
+#include <pwd.h>
+
+extern char *getenv();
+extern int errno;
+
+Code_t ZSetLocation(exposure)
+    char *exposure;
+{
+    return (Z_SendLocation(LOGIN_CLASS, exposure, ZAUTH, 
+			   "$sender logged in to $1 on $3 at $2"));
+}
+
+Code_t ZUnsetLocation()
+{
+    return (Z_SendLocation(LOGIN_CLASS, LOGIN_USER_LOGOUT, ZNOAUTH, 
+			   "$sender logged out of $1 on $3 at $2"));
+}
+
+Code_t ZFlushMyLocations()
+{
+    return (Z_SendLocation(LOGIN_CLASS, LOGIN_USER_FLUSH, ZAUTH, ""));
+}
+
+static char host[MAXHOSTNAMELEN], mytty[MAXPATHLEN];
+static int reenter = 0;
+
+Code_t Z_SendLocation(class, opcode, auth, format)
+    char *class;
+    char *opcode;
+    Z_AuthProc auth;
+    char *format;
+{
+    int retval;
+    time_t ourtime;
+    ZNotice_t notice, retnotice;
+    char *bptr[3];
+#ifndef X_DISPLAY_MISSING
+    char *display;
+#endif
+    char *ttyp;
+    struct hostent *hent;
+    short wg_port = ZGetWGPort();
+
+    (void) memset((char *)&notice, 0, sizeof(notice));
+    notice.z_kind = ACKED;
+    notice.z_port = (u_short) ((wg_port == -1) ? 0 : wg_port);
+    notice.z_class = class;
+    notice.z_class_inst = ZGetSender();
+    notice.z_opcode = opcode;
+    notice.z_sender = 0;
+    notice.z_recipient = "";
+    notice.z_num_other_fields = 0;
+    notice.z_default_format = format;
+
+    /*
+      keep track of what we said before so that we can be consistent
+      when changing location information.
+      This is done mainly for the sake of the WindowGram client.
+     */
+
+    if (!reenter) {
+	    if (gethostname(host, MAXHOSTNAMELEN) < 0)
+		    return (errno);
+
+	    hent = gethostbyname(host);
+	    if (hent) {
+	      (void) strncpy(host, hent->h_name, sizeof(host));
+	      host[sizeof(host) - 1] = '\0';
+	    }
+	    bptr[0] = host;
+#ifndef X_DISPLAY_MISSING
+	    if ((display = getenv("DISPLAY")) && *display) {
+		    (void) strcpy(mytty, display);
+		    bptr[2] = mytty;
+	    } else {
+#endif
+		    ttyp = ttyname(0);
+		    if (ttyp) {
+			bptr[2] = strrchr(ttyp, '/');
+			if (bptr[2])
+			    bptr[2]++;
+			else
+			    bptr[2] = ttyp;
+		    }
+		    else
+			bptr[2] = "unknown";
+		    (void) strcpy(mytty, bptr[2]);
+#ifndef X_DISPLAY_MISSING
+	    }
+#endif
+	    reenter = 1;
+    } else {
+	    bptr[0] = host;
+	    bptr[2] = mytty;
+    }
+
+    ourtime = time((time_t *)0);
+    bptr[1] = ctime(&ourtime);
+    bptr[1][strlen(bptr[1])-1] = '\0';
+
+	
+    if ((retval = ZSendList(&notice, bptr, 3, auth)) != ZERR_NONE)
+	return (retval);
+
+    retval = Z_WaitForNotice (&retnotice, ZCompareUIDPred, &notice.z_uid,
+			      SRV_TIMEOUT);
+    if (retval != ZERR_NONE)
+      return retval;
+
+    if (retnotice.z_kind == SERVNAK) {
+	if (!retnotice.z_message_len) {
+	    ZFreeNotice(&retnotice);
+	    return (ZERR_SERVNAK);
+	}
+	if (!strcmp(retnotice.z_message, ZSRVACK_NOTSENT)) {
+	    ZFreeNotice(&retnotice);
+	    return (ZERR_AUTHFAIL);
+	}
+	if (!strcmp(retnotice.z_message, ZSRVACK_FAIL)) {
+	    ZFreeNotice(&retnotice);
+	    return (ZERR_LOGINFAIL);
+	}
+	ZFreeNotice(&retnotice);
+	return (ZERR_SERVNAK);
+    } 
+	
+    if (retnotice.z_kind != SERVACK) {
+	ZFreeNotice(&retnotice);
+	return (ZERR_INTERNAL);
+    }
+
+    if (!retnotice.z_message_len) {
+	ZFreeNotice(&retnotice);
+	return (ZERR_INTERNAL);
+    }
+
+    if (strcmp(retnotice.z_message, ZSRVACK_SENT) &&
+	strcmp(retnotice.z_message, ZSRVACK_NOTSENT)) {
+	ZFreeNotice(&retnotice);
+	return (ZERR_INTERNAL);
+    }
+
+    ZFreeNotice(&retnotice);
+	
+    return (ZERR_NONE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZMakeAscii.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,94 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZMakeAscii function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#include <internal.h>
+#include <assert.h>
+
+#ifndef lint
+static const char rcsid_ZMakeAscii_c[] = "$Id: ZMakeAscii.c 1710 2001-04-12 09:21:16Z warmenhoven $";
+#endif
+
+static char *itox_chars = "0123456789ABCDEF";
+
+Code_t ZMakeAscii(ptr, len, field, num)
+    register char *ptr;
+    int len;
+    unsigned char *field;
+    int num;
+{
+    int i;
+
+    for (i=0;i<num;i++) {
+	/* we need to add "0x" if we are between 4 byte pieces */
+	if ((i & 3) == 0) {
+	    if (len < (i?4:3))
+		return ZERR_FIELDLEN;
+	    /* except at the beginning, put a space in before the "0x" */
+	    if (i) {
+		*ptr++ = ' ';
+		len--;
+	    }
+	    *ptr++ = '0';
+	    *ptr++ = 'x';
+	    len -= 2;
+	} 
+	if (len < 3)
+	    return ZERR_FIELDLEN;
+	*ptr++ = itox_chars[(int) (field[i] >> 4)];
+	*ptr++ = itox_chars[(int) (field[i] & 0xf)];
+	len -= 2;
+    }
+
+    *ptr = '\0';
+    return ZERR_NONE;
+}
+
+Code_t ZMakeAscii32(ptr, len, value)
+    register char *ptr;
+    int len;
+    unsigned long value;
+{
+    if (len < 11)
+	return ZERR_FIELDLEN;
+    *ptr++ = '0';
+    *ptr++ = 'x';
+    *ptr++ = itox_chars[(value >> 28) & 0xf];
+    *ptr++ = itox_chars[(value >> 24) & 0xf];
+    *ptr++ = itox_chars[(value >> 20) & 0xf];
+    *ptr++ = itox_chars[(value >> 16) & 0xf];
+    *ptr++ = itox_chars[(value >> 12) & 0xf];
+    *ptr++ = itox_chars[(value >>  8) & 0xf];
+    *ptr++ = itox_chars[(value >>  4) & 0xf];
+    *ptr++ = itox_chars[(value >>  0) & 0xf];
+    *ptr = 0;
+    return ZERR_NONE;
+}
+
+Code_t ZMakeAscii16(ptr, len, value)
+    register char *ptr;
+    int len;
+    unsigned int value;
+{
+    if (len < 7)
+	return ZERR_FIELDLEN;
+    *ptr++ = '0';
+    *ptr++ = 'x';
+    *ptr++ = itox_chars[(value >> 12) & 0xf];
+    *ptr++ = itox_chars[(value >>  8) & 0xf];
+    *ptr++ = itox_chars[(value >>  4) & 0xf];
+    *ptr++ = itox_chars[(value >>  0) & 0xf];
+    *ptr = 0;
+    return ZERR_NONE;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZMkAuth.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,103 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZMakeAuthentication function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Id: ZMkAuth.c 1710 2001-04-12 09:21:16Z warmenhoven $ */
+
+#include <internal.h>
+
+#ifndef lint
+static const char rcsid_ZMakeAuthentication_c[] = "$Id: ZMkAuth.c 1710 2001-04-12 09:21:16Z warmenhoven $";
+#endif
+
+#ifdef ZEPHYR_USES_KERBEROS
+#include <krb_err.h>
+static long last_authent_time = 0L;
+static KTEXT_ST last_authent;
+#endif
+
+Code_t ZResetAuthentication () {
+#ifdef ZEPHYR_USES_KERBEROS
+    last_authent_time = 0L;
+#endif
+    return ZERR_NONE;
+}
+
+Code_t ZMakeAuthentication(notice, buffer, buffer_len, len)
+    register ZNotice_t *notice;
+    char *buffer;
+    int buffer_len;
+    int *len;
+{
+#ifdef ZEPHYR_USES_KERBEROS
+    int result;
+    time_t now;
+    KTEXT_ST authent;
+    char *cstart, *cend;
+    ZChecksum_t checksum;
+    CREDENTIALS cred;
+    extern unsigned long des_quad_cksum();
+
+    now = time(0);
+    if (last_authent_time == 0 || (now - last_authent_time > 120)) {
+	result = krb_mk_req(&authent, SERVER_SERVICE, 
+			    SERVER_INSTANCE, __Zephyr_realm, 0);
+	if (result != MK_AP_OK) {
+	    last_authent_time = 0;
+	    return (result+krb_err_base);
+        }
+	last_authent_time = now;
+	last_authent = authent;
+    }
+    else {
+	authent = last_authent;
+    }
+    notice->z_auth = 1;
+    notice->z_authent_len = authent.length;
+    notice->z_ascii_authent = (char *)malloc((unsigned)authent.length*3);
+    /* zero length authent is an error, so malloc(0) is not a problem */
+    if (!notice->z_ascii_authent)
+	return (ENOMEM);
+    if ((result = ZMakeAscii(notice->z_ascii_authent, 
+			     authent.length*3, 
+			     authent.dat, 
+			     authent.length)) != ZERR_NONE) {
+	free(notice->z_ascii_authent);
+	return (result);
+    }
+    result = Z_FormatRawHeader(notice, buffer, buffer_len, len, &cstart,
+			       &cend);
+    free(notice->z_ascii_authent);
+    notice->z_authent_len = 0;
+    if (result)
+	return(result);
+
+    /* Compute a checksum over the header and message. */
+    if ((result = krb_get_cred(SERVER_SERVICE, SERVER_INSTANCE, 
+			      __Zephyr_realm, &cred)) != 0)
+	return result;
+    checksum = des_quad_cksum(buffer, NULL, cstart - buffer, 0, cred.session);
+    checksum ^= des_quad_cksum(cend, NULL, buffer + *len - cend, 0,
+			       cred.session);
+    checksum ^= des_quad_cksum(notice->z_message, NULL, notice->z_message_len,
+			       0, cred.session);
+    notice->z_checksum = checksum;
+    ZMakeAscii32(cstart, buffer + buffer_len - cstart, checksum);
+
+    return (ZERR_NONE);
+#else
+    notice->z_checksum = 0;
+    notice->z_auth = 1;
+    notice->z_authent_len = 0;
+    notice->z_ascii_authent = "";
+    return (Z_FormatRawHeader(notice, buffer, buffer_len, len, NULL, NULL));
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZNewLocU.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,51 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZNewLocateUser function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#include <internal.h>
+
+#ifndef lint
+static const char rcsid_ZNewLocateUser_c[] =
+    "$Id: ZNewLocU.c 1710 2001-04-12 09:21:16Z warmenhoven $";
+#endif
+
+Code_t ZLocateUser(user, nlocs, auth)
+    char *user;
+    int *nlocs;
+    Z_AuthProc auth;
+{
+    Code_t retval;
+    ZNotice_t notice;
+    ZAsyncLocateData_t zald;
+
+    (void) ZFlushLocations();	/* ZFlushLocations never fails (the library
+				   is allowed to know this). */
+
+    if ((retval = ZRequestLocations(user, &zald, UNACKED, auth)) != ZERR_NONE)
+	return(retval);
+
+    retval = Z_WaitForNotice (&notice, ZCompareALDPred, &zald, SRV_TIMEOUT);
+    if (retval == ZERR_NONOTICE)
+	return ETIMEDOUT;
+    if (retval != ZERR_NONE)
+	return retval;
+
+    if ((retval = ZParseLocations(&notice, &zald, nlocs, NULL)) != ZERR_NONE) {
+	ZFreeNotice(&notice);
+	return(retval);
+    }
+
+    ZFreeNotice(&notice);
+    ZFreeALD(&zald);
+    return(ZERR_NONE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZOpenPort.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,73 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZOpenPort function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZOpenPort_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+#include <sys/socket.h>
+
+Code_t ZOpenPort(port)
+    u_short *port;
+{
+    struct sockaddr_in bindin;
+    int len;
+    
+    (void) ZClosePort();
+
+    if ((__Zephyr_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+	__Zephyr_fd = -1;
+	return (errno);
+    }
+
+#ifdef SO_BSDCOMPAT
+    {
+      int on = 1;
+
+      setsockopt(__Zephyr_fd, SOL_SOCKET, SO_BSDCOMPAT, (char *)&on, 
+		 sizeof(on));
+    }
+#endif
+
+    bindin.sin_family = AF_INET;
+
+    if (port && *port)
+	bindin.sin_port = *port;
+    else
+	bindin.sin_port = 0;
+
+    bindin.sin_addr.s_addr = INADDR_ANY;
+
+    if (bind(__Zephyr_fd, (struct sockaddr *)&bindin, sizeof(bindin)) < 0) {
+	if (errno == EADDRINUSE && port && *port)
+	    return (ZERR_PORTINUSE);
+	else
+	    return (errno);
+    }
+
+    if (!bindin.sin_port) {
+	len = sizeof(bindin);
+	if (getsockname(__Zephyr_fd, (struct sockaddr *)&bindin, &len))
+	    return (errno);
+    }
+    
+    __Zephyr_port = bindin.sin_port;
+    __Zephyr_open = 1;
+
+    if (port)
+	*port = bindin.sin_port;
+
+    return (ZERR_NONE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZParseNot.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,293 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZParseNotice function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987,1991 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZParseNotice_c[] =
+    "$Zephyr: /mit/zephyr/src/lib/RCS/ZParseNotice.c,v 1.22 91/03/29 03:34:46 raeburn Exp $";
+#endif
+
+#include <internal.h>
+
+/* Assume that strlen is efficient on this machine... */
+#define next_field(ptr)	ptr += strlen (ptr) + 1
+
+#if defined (__GNUC__) && defined (__vax__)
+#undef next_field
+static __inline__ char * Istrend (char *str) {
+    /*
+     * This should be faster on VAX models outside the 2 series.  Don't
+     * use it if you are using MicroVAX 2 servers.  If you are using a
+     * VS2 server, use something like
+     *	#define next_field(ptr)		while(*ptr++)
+     * instead of this code.
+     *
+     * This requires use of GCC to get the optimized code, but
+     * everybody uses GCC, don't they? :-)
+     */
+    register char *str2 asm ("r1");
+    /* Assumes that no field is longer than 64K.... */
+    asm ("locc $0,$65535,(%1)" : "=r" (str2) : "r" (str) : "r0");
+    return str2;
+}
+#define next_field(ptr) ptr = Istrend (ptr) + 1
+#endif
+
+#ifdef mips
+#undef next_field
+/*
+ * The compiler doesn't optimize this macro as well as it does the
+ * following function.
+ */
+#define next_fieldXXX(ptr) do{register unsigned c1,c2;c1= *ptr;	\
+		   while((ptr++,c2= *ptr,c1)&&(ptr++,c1= *ptr,c2));}while(0)
+static char *next_field_1 (s) char *s; {
+    /*
+     * Calling overhead is still present, but this routine is faster
+     * than strlen, and doesn't bother with some of the other math
+     * that we'd just have to undo later anyways.
+     */
+    register unsigned c1 = *s, c2;
+    while (1) {
+	s++; c2 = *s; if (c1 == 0) break;
+	s++; c1 = *s; if (c2 == 0) break;
+	s++; c2 = *s; if (c1 == 0) break;
+	s++; c1 = *s; if (c2 == 0) break;
+    }
+    return s;
+}
+#define next_field(ptr)	ptr=next_field_1(ptr)
+#endif
+
+Code_t ZParseNotice(buffer, len, notice)
+    char *buffer;
+    int len;
+    ZNotice_t *notice;
+{
+    char *ptr, *end;
+    unsigned long temp;
+    int maj, numfields, i;
+
+#ifdef __LINE__
+    int lineno;
+    /* Note: This definition of BAD eliminates lint and compiler
+     * complains about the "while (0)", but require that the macro not
+     * be used as the "then" part of an "if" statement that also has
+     * an "else" clause.
+     */
+#define BAD_PACKET	{lineno=__LINE__;goto badpkt;}
+    /* This one gets lint/compiler complaints.  */
+/*#define BAD	do{lineno=__LINE__;goto badpkt;}while(0)*/
+#else
+#define BAD_PACKET	goto badpkt
+#endif
+
+    (void) memset((char *)notice, 0, sizeof(ZNotice_t));
+	
+    ptr = buffer;
+    end = buffer+len;
+
+    notice->z_packet = buffer;
+    
+    notice->z_version = ptr;
+    if (strncmp(ptr, ZVERSIONHDR, sizeof(ZVERSIONHDR) - 1))
+	return (ZERR_VERS);
+    ptr += sizeof(ZVERSIONHDR) - 1;
+    if (!*ptr) {
+#ifdef Z_DEBUG
+	Z_debug ("ZParseNotice: null version string");
+#endif
+	return ZERR_BADPKT;
+    }
+    maj = atoi(ptr);
+    if (maj != ZVERSIONMAJOR)
+	return (ZERR_VERS);
+    next_field (ptr);
+
+    if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
+	BAD_PACKET;
+    numfields = temp;
+    next_field (ptr);
+
+    /*XXX 3 */
+    numfields -= 2; /* numfields, version, and checksum */
+    if (numfields < 0) {
+#ifdef __LINE__
+	lineno = __LINE__;
+      badpkt:
+#ifdef Z_DEBUG
+	Z_debug ("ZParseNotice: bad packet from %s/%d (line %d)",
+		 inet_ntoa (notice->z_uid.zuid_addr.s_addr),
+		 notice->z_port, lineno);
+#endif
+#else
+    badpkt:
+#ifdef Z_DEBUG
+	Z_debug ("ZParseNotice: bad packet from %s/%d",
+		 inet_ntoa (notice->z_uid.zuid_addr.s_addr),
+		 notice->z_port);
+#endif
+#endif
+	return ZERR_BADPKT;
+    }
+
+    if (numfields) {
+	if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
+	    BAD_PACKET;
+	notice->z_kind = temp;
+	numfields--;
+	next_field (ptr);
+    }
+    else
+	BAD_PACKET;
+	
+    if (numfields) {
+	if (ZReadAscii(ptr, end-ptr, (unsigned char *)&notice->z_uid,
+		       sizeof(ZUnique_Id_t)) == ZERR_BADFIELD)
+	    BAD_PACKET;
+	notice->z_time.tv_sec = ntohl((u_long) notice->z_uid.tv.tv_sec);
+	notice->z_time.tv_usec = ntohl((u_long) notice->z_uid.tv.tv_usec);
+	numfields--;
+	next_field (ptr);
+    }
+    else
+	BAD_PACKET;
+	
+    if (numfields) {
+	if (ZReadAscii16(ptr, end-ptr, &notice->z_port) == ZERR_BADFIELD)
+	    BAD_PACKET;
+	notice->z_port = htons(notice->z_port);
+	numfields--;
+	next_field (ptr);
+    }
+    else
+	BAD_PACKET;
+
+    if (numfields) {
+	if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
+	    BAD_PACKET;
+	notice->z_auth = temp;
+	numfields--;
+	next_field (ptr);
+    }
+    else
+	BAD_PACKET;
+    notice->z_checked_auth = ZAUTH_UNSET;
+	
+    if (numfields) {
+	if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
+	    BAD_PACKET;
+	notice->z_authent_len = temp;
+	numfields--;
+	next_field (ptr);
+    }
+    else
+	BAD_PACKET;
+
+    if (numfields) {
+	notice->z_ascii_authent = ptr;
+	numfields--;
+	next_field (ptr);
+    }
+    else
+	BAD_PACKET;
+
+    if (numfields) {
+	notice->z_class = ptr;
+	numfields--;
+	next_field (ptr);
+    }
+    else
+	notice->z_class = "";
+	
+    if (numfields) {
+	notice->z_class_inst = ptr;
+	numfields--;
+	next_field (ptr);
+    }
+    else
+	notice->z_class_inst = "";
+
+    if (numfields) {
+	notice->z_opcode = ptr;
+	numfields--;
+	next_field (ptr);
+    }
+    else
+	notice->z_opcode = "";
+
+    if (numfields) {
+	notice->z_sender = ptr;
+	numfields--;
+	next_field (ptr);
+    }
+    else
+	notice->z_sender = "";
+
+    if (numfields) {
+	notice->z_recipient = ptr;
+	numfields--;
+	next_field (ptr);
+    }
+    else
+	notice->z_recipient = "";
+
+    if (numfields) {
+	notice->z_default_format = ptr;
+	numfields--;
+	next_field (ptr);
+    }
+    else
+	notice->z_default_format = "";
+	
+/*XXX*/
+    if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
+	BAD_PACKET;
+    notice->z_checksum = temp;
+    numfields--;
+    next_field (ptr);
+
+    if (numfields) {
+	notice->z_multinotice = ptr;
+	numfields--;
+	next_field (ptr);
+    }
+    else
+	notice->z_multinotice = "";
+
+    if (numfields) {
+	if (ZReadAscii(ptr, end-ptr, (unsigned char *)&notice->z_multiuid,
+		       sizeof(ZUnique_Id_t)) == ZERR_BADFIELD)
+	    BAD_PACKET;
+	notice->z_time.tv_sec = ntohl((u_long) notice->z_multiuid.tv.tv_sec);
+	notice->z_time.tv_usec = ntohl((u_long) notice->z_multiuid.tv.tv_usec);
+	numfields--;
+	next_field (ptr);
+    }
+    else
+	notice->z_multiuid = notice->z_uid;
+
+    for (i=0;i<Z_MAXOTHERFIELDS && numfields;i++,numfields--) {
+	notice->z_other_fields[i] = ptr;
+	next_field (ptr);
+    }
+    notice->z_num_other_fields = i;
+    
+    for (i=0;i<numfields;i++)
+	next_field (ptr);
+	
+    notice->z_message = (caddr_t) ptr;
+    notice->z_message_len = len-(ptr-buffer);
+
+    return (ZERR_NONE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZPeekIfNot.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,59 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZPeekIfNotice function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZPeekIfNotice_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+
+Code_t ZPeekIfNotice(notice, from, predicate, args)
+    ZNotice_t *notice;
+    struct sockaddr_in *from;
+    int (*predicate)();
+    char *args;
+{
+    ZNotice_t tmpnotice;
+    Code_t retval;
+    char *buffer;
+    struct _Z_InputQ *qptr;
+
+    if ((retval = Z_WaitForComplete()) != ZERR_NONE)
+	return (retval);
+    
+    for (;;) {
+	qptr = Z_GetFirstComplete();
+	while (qptr) {
+	    if ((retval = ZParseNotice(qptr->packet, qptr->packet_len, 
+				       &tmpnotice)) != ZERR_NONE)
+		return (retval);
+	    if ((*predicate)(&tmpnotice, args)) {
+		if (!(buffer = (char *) malloc((unsigned) qptr->packet_len)))
+		    return (ENOMEM);
+		(void) memcpy(buffer, qptr->packet, qptr->packet_len);
+		if (from)
+		    *from = qptr->from;
+		if ((retval = ZParseNotice(buffer, qptr->packet_len, 
+					   notice)) != ZERR_NONE) {
+		    free(buffer);
+		    return (retval);
+		}
+		return (ZERR_NONE);
+	    }
+	    qptr = Z_GetNextComplete(qptr);
+	}
+	if ((retval = Z_ReadWait()) != ZERR_NONE)
+	    return (retval);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZPeekNot.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,33 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for ZPeekNotice function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZPeekNotice_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+
+Code_t ZPeekNotice(notice, from)
+    ZNotice_t *notice;
+    struct sockaddr_in *from;
+{
+    char *buffer;
+    int len;
+    Code_t retval;
+	
+    if ((retval = ZPeekPacket(&buffer, &len, from)) != ZERR_NONE)
+	return (retval);
+
+    return (ZParseNotice(buffer, len, notice));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZPeekPkt.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,45 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for ZPeekPacket function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZPeekPacket_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+
+Code_t ZPeekPacket(buffer, ret_len, from)
+    char **buffer;
+    int *ret_len;
+    struct sockaddr_in *from;
+{
+    Code_t retval;
+    struct _Z_InputQ *nextq;
+    
+    if ((retval = Z_WaitForComplete()) != ZERR_NONE)
+	return (retval);
+
+    nextq =Z_GetFirstComplete();
+
+    *ret_len = nextq->packet_len;
+    
+    if (!(*buffer = (char *) malloc((unsigned) *ret_len)))
+	return (ENOMEM);
+
+    (void) memcpy(*buffer, nextq->packet, *ret_len);
+
+    if (from)
+	*from = nextq->from;
+	
+    return (ZERR_NONE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZPending.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,36 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZPending function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZPending_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+
+int ZPending()
+{
+	int retval;
+	
+	if (ZGetFD() < 0) {
+		errno = ZERR_NOPORT;
+		return (-1);
+	}
+	
+	if ((retval = Z_ReadEnqueue()) != ZERR_NONE) {
+		errno = retval;
+		return (-1);
+	} 
+	
+	return(ZQLength());
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZReadAscii.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,108 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZReadAscii function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987, 1990 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZReadAscii_c[] = "$Header$";
+#endif /* lint */
+
+#include <internal.h>
+#include <assert.h>
+
+#if 0
+static __inline__
+int
+Z_cnvt_xtoi (char c)
+{
+    c -= '0';
+    if (c < 10)
+	return c;
+    c -= 'A'-'9'-1;
+    if (c < 16)
+	return c;
+    return -1;
+}
+#endif
+
+#define Z_cnvt_xtoi(c)  ((temp=(c)-'0'),(temp<10)?temp:((temp-='A'-'9'-1),(temp<16)?temp:-1))
+
+Code_t ZReadAscii(ptr, len, field, num)
+    char *ptr;
+    int len;
+    unsigned char *field;
+    int num;
+{
+    int i;
+    unsigned int hexbyte;
+    register int c1, c2;
+    register unsigned int temp;
+
+    for (i=0;i<num;i++) {
+	if (*ptr == ' ') {
+	    ptr++;
+	    if (--len < 0)
+		return ZERR_BADFIELD;
+	} 
+	if (ptr[0] == '0' && ptr[1] == 'x') {
+	    ptr += 2;
+	    len -= 2;
+	    if (len < 0)
+		return ZERR_BADFIELD;
+	} 
+	c1 = Z_cnvt_xtoi(ptr[0]);
+	if (c1 < 0)
+		return ZERR_BADFIELD;
+	c2 = Z_cnvt_xtoi(ptr[1]);
+	if (c2 < 0)
+		return ZERR_BADFIELD;
+	hexbyte = (c1 << 4) | c2;
+	field[i] = hexbyte;
+	ptr += 2;
+	len -= 2;
+	if (len < 0)
+	    return ZERR_BADFIELD;
+    }
+
+    return *ptr ? ZERR_BADFIELD : ZERR_NONE;
+}
+
+Code_t ZReadAscii32(ptr, len, value_ptr)
+    char *ptr;
+    int len;
+    unsigned long *value_ptr;
+{
+    unsigned char buf[4];
+    Code_t retval;
+
+    retval = ZReadAscii(ptr, len, buf, 4);
+    if (retval != ZERR_NONE)
+	return retval;
+    *value_ptr = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+    return ZERR_NONE;
+}
+
+Code_t ZReadAscii16(ptr, len, value_ptr)
+    char *ptr;
+    int len;
+    unsigned short *value_ptr;
+{
+    unsigned char buf[2];
+    Code_t retval;
+
+    retval = ZReadAscii(ptr, len, buf, 2);
+    if (retval != ZERR_NONE)
+	return retval;
+    *value_ptr = (buf[0] << 8) | buf[1];
+    return ZERR_NONE;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZRecvNot.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,52 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for ZReceiveNotice function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZReceiveNotice_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+
+Code_t ZReceiveNotice(notice, from)
+    ZNotice_t *notice;
+    struct sockaddr_in *from;
+{
+    char *buffer;
+    struct _Z_InputQ *nextq;
+    int len, auth;
+    Code_t retval;
+
+    if ((retval = Z_WaitForComplete()) != ZERR_NONE)
+	return (retval);
+
+    nextq = Z_GetFirstComplete();
+
+    len = nextq->packet_len;
+    
+    if (!(buffer = (char *) malloc((unsigned) len)))
+	return (ENOMEM);
+
+    if (from)
+	*from = nextq->from;
+    
+    (void) memcpy(buffer, nextq->packet, len);
+
+    auth = nextq->auth;
+    Z_RemQueue(nextq);
+    
+    if ((retval = ZParseNotice(buffer, len, notice)) != ZERR_NONE)
+	return (retval);
+    notice->z_checked_auth = auth;
+    return ZERR_NONE;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZRecvPkt.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,46 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for ZReceivePacket function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZReceivePacket_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+
+Code_t ZReceivePacket(buffer, ret_len, from)
+    ZPacket_t buffer;
+    int *ret_len;
+    struct sockaddr_in *from;
+{
+    Code_t retval;
+    struct _Z_InputQ *nextq;
+    
+    if ((retval = Z_WaitForComplete()) != ZERR_NONE)
+	return (retval);
+
+    nextq = Z_GetFirstComplete();
+
+    *ret_len = nextq->packet_len;
+    if (*ret_len > Z_MAXPKTLEN)
+	return (ZERR_PKTLEN);
+    
+    (void) memcpy(buffer, nextq->packet, *ret_len);
+
+    if (from)
+	*from = nextq->from;
+	
+    Z_RemQueue(nextq);
+
+    return (ZERR_NONE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZRetSubs.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,186 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZRetrieveSubscriptions and
+ * ZRetrieveDefaultSubscriptions functions.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#include <internal.h>
+
+#ifndef lint
+static const char rcsid_ZRetrieveSubscriptions_c[] =
+    "$Id: ZRetSubs.c 1710 2001-04-12 09:21:16Z warmenhoven $";
+#endif
+
+static Code_t Z_RetSubs ();
+
+/* Need STDC definition when possible for unsigned short argument. */
+#ifdef __STDC__
+Code_t ZRetrieveSubscriptions(unsigned short port, int *nsubs)
+#else
+Code_t ZRetrieveSubscriptions(port,nsubs)
+	unsigned short port;
+	int *nsubs;
+#endif
+{
+	int retval;
+	ZNotice_t notice;
+	char asciiport[50];
+	
+	if (!port)			/* use default port */
+	    port = __Zephyr_port;
+
+	retval = ZMakeAscii16(asciiport, sizeof(asciiport), ntohs(port));
+	if (retval != ZERR_NONE)
+		return (retval);
+
+	(void) memset((char *)&notice, 0, sizeof(notice));
+	notice.z_message = asciiport;
+	notice.z_message_len = strlen(asciiport)+1;
+	notice.z_opcode = CLIENT_GIMMESUBS;
+
+	return(Z_RetSubs(&notice, nsubs, ZAUTH));
+}
+
+Code_t ZRetrieveDefaultSubscriptions(nsubs)
+	int *nsubs;
+{
+	ZNotice_t notice;
+
+	(void) memset((char *)&notice, 0, sizeof(notice));
+	notice.z_message = (char *) 0;
+	notice.z_message_len = 0;
+	notice.z_opcode = CLIENT_GIMMEDEFS;
+
+	return(Z_RetSubs(&notice, nsubs, ZNOAUTH));
+
+}
+
+static Code_t Z_RetSubs(notice, nsubs, auth_routine)
+	register ZNotice_t *notice;
+	int *nsubs;
+	Z_AuthProc auth_routine;
+{
+	register int i;
+	int retval,nrecv,gimmeack;
+	ZNotice_t retnotice;
+	char *ptr,*end,*ptr2;
+
+	retval = ZFlushSubscriptions();
+
+	if (retval != ZERR_NONE && retval != ZERR_NOSUBSCRIPTIONS)
+		return (retval);
+
+	if (ZGetFD() < 0)
+		if ((retval = ZOpenPort((u_short *)0)) != ZERR_NONE)
+			return (retval);
+
+	notice->z_kind = ACKED;
+	notice->z_port = __Zephyr_port;
+	notice->z_class = ZEPHYR_CTL_CLASS;
+	notice->z_class_inst = ZEPHYR_CTL_CLIENT;
+	notice->z_sender = 0;
+	notice->z_recipient = "";
+	notice->z_default_format = "";
+
+	if ((retval = ZSendNotice(notice,auth_routine)) != ZERR_NONE)
+		return (retval);
+
+	nrecv = 0;
+	gimmeack = 0;
+	__subscriptions_list = (ZSubscription_t *) 0;
+
+	while (!nrecv || !gimmeack) {
+		retval = Z_WaitForNotice (&retnotice, ZCompareMultiUIDPred,
+					  &notice->z_multiuid, SRV_TIMEOUT);
+		if (retval == ZERR_NONOTICE)
+		  return ETIMEDOUT;
+		else if (retval != ZERR_NONE)
+		  return retval;
+
+		if (retnotice.z_kind == SERVNAK) {
+			ZFreeNotice(&retnotice);
+			return (ZERR_SERVNAK);
+		}	
+		/* non-matching protocol version numbers means the
+		   server is probably an older version--must punt */
+		if (strcmp(notice->z_version,retnotice.z_version)) {
+			ZFreeNotice(&retnotice);
+			return(ZERR_VERS);
+		}
+		if (retnotice.z_kind == SERVACK &&
+		    !strcmp(retnotice.z_opcode,notice->z_opcode)) {
+			ZFreeNotice(&retnotice);
+			gimmeack = 1;
+			continue;
+		} 
+
+		if (retnotice.z_kind != ACKED) {
+			ZFreeNotice(&retnotice);
+			return (ZERR_INTERNAL);
+		}
+
+		nrecv++;
+
+		end = retnotice.z_message+retnotice.z_message_len;
+
+		__subscriptions_num = 0;
+		for (ptr=retnotice.z_message;ptr<end;ptr++)
+			if (!*ptr)
+				__subscriptions_num++;
+
+		__subscriptions_num = __subscriptions_num / 3;
+
+		__subscriptions_list = (ZSubscription_t *)
+			malloc((unsigned)(__subscriptions_num*
+					  sizeof(ZSubscription_t)));
+		if (__subscriptions_num && !__subscriptions_list) {
+			ZFreeNotice(&retnotice);
+			return (ENOMEM);
+		}
+
+		for (ptr=retnotice.z_message,i = 0; i< __subscriptions_num; i++) {
+			__subscriptions_list[i].zsub_class = (char *)
+				malloc((unsigned)strlen(ptr)+1);
+			if (!__subscriptions_list[i].zsub_class) {
+				ZFreeNotice(&retnotice);
+				return (ENOMEM);
+			}
+			(void) strcpy(__subscriptions_list[i].zsub_class,ptr);
+			ptr += strlen(ptr)+1;
+			__subscriptions_list[i].zsub_classinst = (char *)
+				malloc((unsigned)strlen(ptr)+1);
+			if (!__subscriptions_list[i].zsub_classinst) {
+				ZFreeNotice(&retnotice);
+				return (ENOMEM);
+			}
+			(void) strcpy(__subscriptions_list[i].zsub_classinst,ptr);
+			ptr += strlen(ptr)+1;
+			ptr2 = ptr;
+			if (!*ptr2)
+				ptr2 = "*";
+			__subscriptions_list[i].zsub_recipient = (char *)
+				malloc((unsigned)strlen(ptr2)+1);
+			if (!__subscriptions_list[i].zsub_recipient) {
+				ZFreeNotice(&retnotice);
+				return (ENOMEM);
+			}
+			(void) strcpy(__subscriptions_list[i].zsub_recipient,ptr2);
+			ptr += strlen(ptr)+1;
+		}
+		ZFreeNotice(&retnotice);
+	}
+
+	__subscriptions_next = 0;
+	*nsubs = __subscriptions_num;
+
+	return (ZERR_NONE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZSendList.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,55 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZSendList function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZSendList_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+
+Code_t ZSendList(notice, list, nitems, cert_routine)
+    ZNotice_t *notice;
+    char *list[];
+    int nitems;
+    Z_AuthProc cert_routine;
+{
+    return(ZSrvSendList(notice, list, nitems, cert_routine, Z_XmitFragment));
+}
+
+Code_t ZSrvSendList(notice, list, nitems, cert_routine, send_routine)
+    ZNotice_t *notice;
+    char *list[];
+    int nitems;
+    Z_AuthProc cert_routine;
+    Code_t (*send_routine)();
+{
+    Code_t retval;
+    ZNotice_t newnotice;
+    char *buffer;
+    int len;
+
+    if ((retval = ZFormatNoticeList(notice, list, nitems, &buffer, 
+				    &len, cert_routine)) != ZERR_NONE)
+	return (retval);
+
+    if ((retval = ZParseNotice(buffer, len, &newnotice)) != ZERR_NONE)
+	return (retval);
+    
+    retval = Z_SendFragmentedNotice(&newnotice, len, cert_routine,
+				    send_routine);
+
+    free(buffer);
+
+    return (retval);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZSendNot.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,51 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZSendNotice function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZSendNotice_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+
+Code_t ZSendNotice(notice, cert_routine)
+    ZNotice_t *notice;
+    Z_AuthProc cert_routine;
+{
+    return(ZSrvSendNotice(notice, cert_routine, Z_XmitFragment));
+}
+
+Code_t ZSrvSendNotice(notice, cert_routine, send_routine)
+    ZNotice_t *notice;
+    Z_AuthProc cert_routine;
+    Code_t (*send_routine)();
+{    
+    Code_t retval;
+    ZNotice_t newnotice;
+    char *buffer;
+    int len;
+
+    if ((retval = ZFormatNotice(notice, &buffer, &len, 
+				cert_routine)) != ZERR_NONE)
+	return (retval);
+
+    if ((retval = ZParseNotice(buffer, len, &newnotice)) != ZERR_NONE)
+	return (retval);
+    
+    retval = Z_SendFragmentedNotice(&newnotice, len, cert_routine,
+				    send_routine);
+
+    free(buffer);
+
+    return (retval);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZSendPkt.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,73 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZSendPacket function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987,1991 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZSendPacket_c[] =
+    "$Zephyr: /mit/zephyr/src/lib/RCS/ZSendPacket.c,v 1.29 91/03/21 11:57:08 raeburn Exp $";
+#endif
+
+#include <internal.h>
+#include <sys/socket.h>
+
+static int wait_for_ack();
+
+Code_t ZSendPacket(packet, len, waitforack)
+    char *packet;
+    int len;
+    int waitforack;
+{
+    Code_t retval;
+    struct sockaddr_in dest;
+    ZNotice_t notice, acknotice;
+	
+    if (!packet || len < 0)
+	return (ZERR_ILLVAL);
+
+    if (len > Z_MAXPKTLEN)
+	return (ZERR_PKTLEN);
+    
+    if (ZGetFD() < 0)
+	if ((retval = ZOpenPort((u_short *)0)) != ZERR_NONE)
+	    return (retval);
+
+    dest = ZGetDestAddr();
+	
+    if (sendto(ZGetFD(), packet, len, 0, (struct sockaddr *)&dest,
+	       sizeof(dest)) < 0)
+	return (errno);
+
+    if (!waitforack)
+	return (ZERR_NONE);
+
+    if ((retval = ZParseNotice(packet, len, &notice)) != ZERR_NONE)
+	return (retval);
+    
+    retval = Z_WaitForNotice (&acknotice, wait_for_ack, &notice.z_uid,
+			      HM_TIMEOUT);
+    if (retval == ETIMEDOUT)
+      return ZERR_HMDEAD;
+    if (retval == ZERR_NONE)
+      ZFreeNotice (&acknotice);
+    return retval;
+}
+
+static int wait_for_ack(notice, uid)
+    ZNotice_t *notice;
+    ZUnique_Id_t *uid;
+{
+  return (ZCompareUID(&notice->z_uid, uid) &&
+	  (notice->z_kind == HMACK     ||
+	   notice->z_kind == SERVACK   ||
+	   notice->z_kind == CLIENTACK ));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZSendRLst.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,52 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZSendRawNotice function.
+ *
+ *	Created by:	John T. Kohl
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1988 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZSendRawList_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+
+Code_t ZSendRawList(notice, list, nitems)
+    ZNotice_t *notice;
+    char *list[];
+    int nitems;
+{
+    return(ZSrvSendRawList(notice, list, nitems, Z_XmitFragment));
+}
+
+Code_t ZSrvSendRawList(notice, list, nitems, send_routine)
+    ZNotice_t *notice;
+    char *list[];
+    int nitems;
+    Code_t (*send_routine)();
+{
+    Code_t retval;
+    ZNotice_t newnotice;
+    char *buffer;
+    int len;
+
+    if ((retval = ZFormatRawNoticeList(notice, list, nitems, &buffer, 
+				       &len)) != ZERR_NONE)
+	return (retval);
+
+    if ((retval = ZParseNotice(buffer, len, &newnotice)) != ZERR_NONE)
+	return (retval);
+    
+    retval = Z_SendFragmentedNotice(&newnotice, len, NULL, send_routine);
+
+    free(buffer);
+
+    return (retval);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZSendRaw.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,41 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZSendRawNotice function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZSendRawNotice_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+
+Code_t ZSendRawNotice(notice)
+    ZNotice_t *notice;
+{
+    Code_t retval;
+    ZNotice_t newnotice;
+    char *buffer;
+    int len;
+
+    if ((retval = ZFormatRawNotice(notice, &buffer, &len)) !=
+	ZERR_NONE)
+	return (retval);
+
+    if ((retval = ZParseNotice(buffer, len, &newnotice)) != ZERR_NONE)
+	return (retval);
+    
+    retval = Z_SendFragmentedNotice(&newnotice, len, NULL, Z_XmitFragment);
+
+    free(buffer);
+
+    return (retval);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZSetDest.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,29 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZSetDestAddr function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZSetDestAddr_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+
+Code_t ZSetDestAddr(addr)
+	struct	sockaddr_in *addr;
+{
+	__HM_addr = *addr;
+
+	__HM_set = 1;
+	
+	return (ZERR_NONE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZSetFD.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,30 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZSetFD function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZSetFD_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+
+Code_t ZSetFD(fd)
+	int	fd;
+{
+	(void) ZClosePort();
+
+	__Zephyr_fd = fd;
+	__Zephyr_open = 0;
+	
+	return (ZERR_NONE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZSetSrv.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,27 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZSetServerState function.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZSetServerState_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+
+Code_t ZSetServerState(state)
+	int	state;
+{
+	__Zephyr_server = state;
+	
+	return (ZERR_NONE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZSubs.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,199 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZSubscribeTo, ZUnsubscribeTo, and
+ * ZCancelSubscriptions functions.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#include <internal.h>
+
+#ifndef lint
+static const char rcsid_ZSubscriptions_c[] = "$Id: ZSubs.c 1710 2001-04-12 09:21:16Z warmenhoven $";
+#endif
+
+static Code_t Z_Subscriptions __P((register ZSubscription_t *sublist,
+				   int nitems, unsigned int port,
+				   char *opcode, int authit));
+static Code_t subscr_sendoff __P((ZNotice_t *notice, char **lyst, int num,
+				  int authit));
+
+Code_t ZSubscribeTo(sublist, nitems, port)
+    ZSubscription_t *sublist;
+    int nitems;
+    unsigned int port;
+{
+    return (Z_Subscriptions(sublist, nitems, port, CLIENT_SUBSCRIBE, 1));
+}
+
+Code_t ZSubscribeToSansDefaults(sublist, nitems, port)
+    ZSubscription_t *sublist;
+    int nitems;
+    unsigned int port;
+{
+    return (Z_Subscriptions(sublist, nitems, port, CLIENT_SUBSCRIBE_NODEFS,
+			    1));
+}
+
+Code_t ZUnsubscribeTo(sublist, nitems, port)
+    ZSubscription_t *sublist;
+    int nitems;
+    unsigned int port;
+{
+    return (Z_Subscriptions(sublist, nitems, port, CLIENT_UNSUBSCRIBE, 1));
+}
+
+Code_t ZCancelSubscriptions(port)
+    unsigned int port;
+{
+    return (Z_Subscriptions((ZSubscription_t *)0, 0, port,
+			    CLIENT_CANCELSUB, 0));
+}
+
+/*
+ * This routine must do its own fragmentation.  Subscriptions must
+ * not be broken across packet boundaries, or else the server will
+ * mis-interpret them.
+ */
+
+static Code_t
+Z_Subscriptions(sublist, nitems, port, opcode, authit)
+    register ZSubscription_t *sublist;
+    int nitems;
+    unsigned int port;
+    char *opcode;
+    int authit;
+{
+    register int i, j;
+    int retval;
+    ZNotice_t notice;
+    char header[Z_MAXHEADERLEN];
+    char **list;
+    int hdrlen;
+    int size_avail = Z_MAXPKTLEN-Z_FRAGFUDGE; /* space avail for data,
+						 adjusted below */
+    int size, start, numok;
+
+    /* nitems = 0 means cancel all subscriptions; still need to allocate a */
+    /* array for one item so we can cancel, however. */
+  
+    list = (char **)malloc((unsigned)((nitems==0)?1:nitems)*3*sizeof(char *));
+    if (!list)
+        return (ENOMEM);
+
+    (void) memset((char *)&notice, 0, sizeof(notice));
+    notice.z_kind = ACKED;
+    notice.z_port = port;
+    notice.z_class = ZEPHYR_CTL_CLASS;
+    notice.z_class_inst = ZEPHYR_CTL_CLIENT;
+    notice.z_opcode = opcode;
+    notice.z_sender = 0;
+    notice.z_recipient = "";
+    notice.z_default_format = "";
+    notice.z_message_len = 0;
+
+    /* format the header to figure out how long it is */
+    retval = Z_FormatHeader(&notice, header, sizeof(header), &hdrlen, ZAUTH);
+    if (retval != ZERR_NONE && !authit)
+	retval = Z_FormatHeader(&notice, header, sizeof(header),
+				&hdrlen, ZAUTH);
+    if (retval != ZERR_NONE) {
+	free((char *)list);
+	return(retval);
+    }
+
+    /* compute amount of room left */
+    size_avail -= hdrlen;
+    size = size_avail;
+
+    /* assemble subs into an array of pointers */
+    for (i=0;i<nitems;i++) {
+	list[i*3] = sublist[i].zsub_class;
+	list[i*3+1] = sublist[i].zsub_classinst;
+	if (sublist[i].zsub_recipient && *sublist[i].zsub_recipient &&
+	    *sublist[i].zsub_recipient != '*')
+	    list[i*3+2] = ZGetSender();
+	else
+	    list[i*3+2] = "";
+    }
+
+    start = -1;
+    i = 0;
+    numok = 0;
+    if (!nitems) {
+	/* there aren't really any, but we need to xmit anyway */
+	retval = subscr_sendoff(&notice, list, 0, authit);
+	free((char *)list);
+	return(retval);
+    }
+    while(i < nitems) {
+	if (start == -1) {
+	    size = size_avail;
+	    start = i;
+	    numok = 0;
+	}
+	if ((j = strlen(list[i*3])
+	     + strlen(list[i*3+1])
+	     + strlen(list[i*3+2]) + 3) <= size) {
+	    /* it will fit in this packet */
+	    size -= j;
+	    numok++;
+	    i++;
+	    continue;
+	}
+	if (!numok) {			/* a single subscription won't
+					   fit into one packet */
+	    free((char *)list);
+	    return(ZERR_FIELDLEN);
+	}
+	retval = subscr_sendoff(&notice, &list[start*3], numok, authit);
+	if (retval) {
+	    free((char *)list);
+	    return(retval);
+	}
+	start = -1;
+    }
+    if (numok)
+	retval = subscr_sendoff(&notice, &list[start*3], numok, authit);
+    free((char *)list);
+    return(retval);
+}
+
+static Code_t
+subscr_sendoff(notice, lyst, num, authit)
+ZNotice_t *notice;
+char **lyst;
+int num;
+int authit;
+{
+    register Code_t retval;
+    ZNotice_t retnotice;
+
+    retval = ZSendList(notice, lyst, num*3, ZAUTH);
+    if (retval != ZERR_NONE && !authit)
+	retval = ZSendList(notice, lyst, num*3, ZNOAUTH);
+	
+    if (retval != ZERR_NONE)
+	return (retval);
+    if ((retval = ZIfNotice(&retnotice, (struct sockaddr_in *)0, 
+				ZCompareUIDPred, (char *)&notice->z_uid)) !=
+	ZERR_NONE)
+	return (retval);
+    if (retnotice.z_kind == SERVNAK) {
+	ZFreeNotice(&retnotice);
+	return (ZERR_SERVNAK);
+    }
+    if (retnotice.z_kind != SERVACK) {
+	ZFreeNotice(&retnotice);
+	return (ZERR_INTERNAL);
+    }
+    ZFreeNotice(&retnotice);
+    return (ZERR_NONE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZVariables.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,191 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZGetVariable, ZSetVariable, and ZUnsetVariable
+ * functions.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#ifndef lint
+static char rcsid_ZVariables_c[] = "$Header$";
+#endif
+
+#include <internal.h>
+
+#include <ctype.h>
+#include <pwd.h>
+
+static int get_localvarfile __P((char *bfr));
+static char *get_varval __P((char *fn, char *val));
+static int varline __P((char *bfr, char *var));
+
+char *ZGetVariable(var)
+    char *var;
+{
+    char varfile[128], *ret;
+    char *get_varval();
+
+    if (get_localvarfile(varfile))
+	return ((char *)0);
+
+    if ((ret = get_varval(varfile, var)) != ZERR_NONE)
+	return (ret);
+
+    sprintf(varfile, "%s/zephyr.vars", CONFDIR);
+    return (get_varval(varfile, var));
+}
+
+Code_t ZSetVariable(var, value)
+    char *var;
+    char *value;
+{
+    int written;
+    FILE *fpin, *fpout;
+    char varfile[128], varfilebackup[128], varbfr[512];
+
+    written = 0;
+	
+    if (get_localvarfile(varfile))
+	return (ZERR_INTERNAL);
+
+    (void) strcpy(varfilebackup, varfile);
+    (void) strcat(varfilebackup, ".backup");
+	
+    if (!(fpout = fopen(varfilebackup, "w")))
+	return (errno);
+    if ((fpin = fopen(varfile, "r")) != NULL) {
+	while (fgets(varbfr, sizeof varbfr, fpin) != (char *) 0) {
+	    if (varbfr[strlen(varbfr)-1] < ' ')
+		varbfr[strlen(varbfr)-1] = '\0';
+	    if (varline(varbfr, var)) {
+		fprintf(fpout, "%s = %s\n", var, value);
+		written = 1;
+	    }
+	    else
+		fprintf(fpout, "%s\n", varbfr);
+	}
+	(void) fclose(fpin);		/* don't care about errs on input */
+    } 
+    if (!written)
+	fprintf(fpout, "%s = %s\n", var, value);
+    if (fclose(fpout) == EOF)
+	    return(EIO);		/* can't rely on errno */
+    if (rename(varfilebackup, varfile))
+	return (errno);
+    return (ZERR_NONE);
+}	
+
+Code_t ZUnsetVariable(var)
+    char *var;
+{
+    FILE *fpin, *fpout;
+    char varfile[128], varfilebackup[128], varbfr[512];
+
+    if (get_localvarfile(varfile))
+	return (ZERR_INTERNAL);
+
+    (void) strcpy(varfilebackup, varfile);
+    (void) strcat(varfilebackup, ".backup");
+	
+    if (!(fpout = fopen(varfilebackup, "w")))
+	return (errno);
+    if ((fpin = fopen(varfile, "r")) != NULL) {
+	while (fgets(varbfr, sizeof varbfr, fpin) != (char *) 0) {
+	    if (varbfr[strlen(varbfr)-1] < ' ')
+		varbfr[strlen(varbfr)-1] = '\0';
+	    if (!varline(varbfr, var))
+		fprintf(fpout, "%s\n", varbfr);
+	}
+	(void) fclose(fpin);		/* don't care about read close errs */
+    } 
+    if (fclose(fpout) == EOF)
+	    return(EIO);		/* errno isn't reliable */
+    if (rename(varfilebackup, varfile))
+	return (errno);
+    return (ZERR_NONE);
+}	
+
+static int get_localvarfile(bfr)
+    char *bfr;
+{
+    char *envptr;
+    struct passwd *pwd;
+
+    envptr = getenv("HOME");
+    if (envptr)
+	(void) strcpy(bfr, envptr);
+    else {
+	if (!(pwd = getpwuid((int) getuid()))) {
+	    fprintf(stderr, "Zephyr internal failure: Can't find your entry in /etc/passwd\n");
+	    return (1);
+	}
+	(void) strcpy(bfr, pwd->pw_dir);
+    }
+
+    (void) strcat(bfr, "/");
+    (void) strcat(bfr, ".zephyr.vars");
+    return (0);
+} 
+	
+static char *get_varval(fn, var)
+    char *fn;
+    char *var;
+{
+    FILE *fp;
+    static char varbfr[512];
+    int i;
+	
+    fp = fopen(fn, "r");
+    if (!fp)
+	return ((char *)0);
+
+    while (fgets(varbfr, sizeof varbfr, fp) != (char *) 0) {
+	if (varbfr[strlen(varbfr)-1] < ' ')
+	    varbfr[strlen(varbfr)-1] = '\0';
+	if (!(i = varline(varbfr, var)))
+	    continue;
+	(void) fclose(fp);		/* open read-only, don't care */
+	return (varbfr+i);
+    }
+    (void) fclose(fp);			/* open read-only, don't care */
+    return ((char *)0);
+}
+
+/* If the variable in the line bfr[] is the same as var, return index to
+   the variable value, else return 0. */
+static int varline(bfr, var)
+    char *bfr;
+    char *var;
+{
+    register char *cp;
+	
+
+    if (!bfr[0] || bfr[0] == '#')	/* comment or null line */
+	return (0);
+	
+    cp = bfr;
+    while (*cp && !isspace(*cp) && (*cp != '='))
+	cp++;
+
+#define max(a,b) ((a > b) ? (a) : (b))
+
+    if (strncasecmp(bfr, var, max(strlen(var),cp - bfr)))
+	return(0);			/* var is not the var in
+					   bfr ==> no match */
+
+    cp = strchr(bfr, '=');
+    if (!cp)
+	return(0);
+    cp++;
+    while (*cp && isspace(*cp))		/* space up to variable value */
+	cp++;
+
+    return (cp - bfr);			/* return index */
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/ZWait4Not.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,71 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains the ZCheckIfNotice/select loop used for waiting for
+ * a notice, with a timeout.
+ *
+ *	Created by:	<Joe Random Hacker>
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1991 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+
+#include "mit-copyright.h"
+
+#ifndef lint
+static char rcsid_ZWaitForNotice_c[] = "$Zephyr$";
+#endif
+
+#include <internal.h>
+#include <sys/socket.h>
+
+Code_t Z_WaitForNotice (notice, pred, arg, timeout)
+     ZNotice_t *notice;
+     int (*pred) __P((ZNotice_t *, void *));
+     void *arg;
+     int timeout;
+{
+  Code_t retval;
+  struct timeval tv, t0;
+  fd_set fdmask;
+  int i, fd;
+
+  retval = ZCheckIfNotice (notice, (struct sockaddr_in *) 0, pred,
+			   (char *) arg);
+  if (retval == ZERR_NONE)
+    return ZERR_NONE;
+  if (retval != ZERR_NONOTICE)
+    return retval;
+
+  fd = ZGetFD ();
+  FD_ZERO (&fdmask);
+  tv.tv_sec = timeout;
+  tv.tv_usec = 0;
+  gettimeofday (&t0, (struct timezone *) 0);
+  t0.tv_sec += timeout;
+  while (1) {
+    FD_SET (fd, &fdmask);
+    i = select (fd + 1, &fdmask, (fd_set *) 0, (fd_set *) 0, &tv);
+    if (i == 0)
+      return ETIMEDOUT;
+    if (i < 0 && errno != EINTR)
+      return errno;
+    if (i > 0) {
+      retval = ZCheckIfNotice (notice, (struct sockaddr_in *) 0, pred,
+			       (char *) arg);
+      if (retval != ZERR_NONOTICE) /* includes ZERR_NONE */
+	return retval;
+    }
+    gettimeofday (&tv, (struct timezone *) 0);
+    tv.tv_usec = t0.tv_usec - tv.tv_usec;
+    if (tv.tv_usec < 0) {
+      tv.tv_usec += 1000000;
+      tv.tv_sec = t0.tv_sec - tv.tv_sec - 1;
+    }
+    else
+      tv.tv_sec = t0.tv_sec - tv.tv_sec;
+  }
+  /*NOTREACHED*/
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/Zinternal.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,1012 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the internal Zephyr routines.
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *
+ *	Copyright (c) 1987,1988,1991 by the Massachusetts Institute of
+ *	Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+/* $Header$ */
+
+#include <internal.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <utmp.h>
+
+#ifndef lint
+static const char rcsid_Zinternal_c[] =
+  "$Id: Zinternal.c 1710 2001-04-12 09:21:16Z warmenhoven $";
+static const char copyright[] =
+  "Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology.";
+#endif
+
+extern char *inet_ntoa ();
+
+int __Zephyr_fd = -1;
+int __Zephyr_open;
+int __Zephyr_port = -1;
+int __My_length;
+char *__My_addr;
+int __Q_CompleteLength;
+int __Q_Size;
+struct _Z_InputQ *__Q_Head, *__Q_Tail;
+struct sockaddr_in __HM_addr;
+struct sockaddr_in __HM_addr_real;
+int __HM_set;
+int __Zephyr_server;
+ZLocations_t *__locate_list;
+int __locate_num;
+int __locate_next;
+ZSubscription_t *__subscriptions_list;
+int __subscriptions_num;
+int __subscriptions_next;
+
+#ifdef ZEPHYR_USES_KERBEROS
+C_Block __Zephyr_session;
+char __Zephyr_realm[REALM_SZ];
+#endif
+
+#ifdef Z_DEBUG
+void (*__Z_debug_print) __P((const char *fmt, va_list args, void *closure));
+void *__Z_debug_print_closure;
+#endif
+
+#define min(a,b) ((a)<(b)?(a):(b))
+
+static int Z_AddField __P((char **ptr, char *field, char *end));
+static int find_or_insert_uid __P((ZUnique_Id_t *uid, ZNotice_Kind_t kind));
+
+/* Find or insert uid in the old uids buffer.  The buffer is a sorted
+ * circular queue.  We make the assumption that most packets arrive in
+ * order, so we can usually search for a uid or insert it into the buffer
+ * by looking back just a few entries from the end.  Since this code is
+ * only executed by the client, the implementation isn't microoptimized. */
+static int find_or_insert_uid(uid, kind)
+    ZUnique_Id_t *uid;
+    ZNotice_Kind_t kind;
+{
+    static struct _filter {
+	ZUnique_Id_t	uid;
+	ZNotice_Kind_t	kind;
+	time_t		t;
+    } *buffer;
+    static long size;
+    static long start;
+    static long num;
+
+    time_t now;
+    struct _filter *new;
+    long i, j, new_size;
+    int result;
+
+    /* Initialize the uid buffer if it hasn't been done already. */
+    if (!buffer) {
+	size = Z_INITFILTERSIZE;
+	buffer = (struct _filter *) malloc(size * sizeof(*buffer));
+	if (!buffer)
+	    return 0;
+    }
+
+    /* Age the uid buffer, discarding any uids older than the clock skew. */
+    time(&now);
+    while (num && (now - buffer[start % size].t) > CLOCK_SKEW)
+	start++, num--;
+    start %= size;
+
+    /* Make room for a new uid, since we'll probably have to insert one. */
+    if (num == size) {
+	new_size = size * 2 + 2;
+	new = (struct _filter *) malloc(new_size * sizeof(*new));
+	if (!new)
+	    return 0;
+	for (i = 0; i < num; i++)
+	    new[i] = buffer[(start + i) % size];
+	free(buffer);
+	buffer = new;
+	size = new_size;
+	start = 0;
+    }
+
+    /* Search for this uid in the buffer, starting from the end. */
+    for (i = start + num - 1; i >= start; i--) {
+	result = memcmp(uid, &buffer[i % size].uid, sizeof(*uid));
+	if (result == 0 && buffer[i % size].kind == kind)
+	    return 1;
+	if (result > 0)
+	    break;
+    }
+
+    /* We didn't find it; insert the uid into the buffer after i. */
+    i++;
+    for (j = start + num; j > i; j--)
+	buffer[j % size] = buffer[(j - 1) % size];
+    buffer[i % size].uid = *uid;
+    buffer[i % size].kind = kind;
+    buffer[i % size].t = now;
+    num++;
+
+    return 0;
+}
+
+/* Get the address of the local host and cache it */
+
+Code_t Z_GetMyAddr()
+{
+    register struct hostent *myhost;
+    char hostname[MAXHOSTNAMELEN];
+	
+    if (__My_length > 0)
+	return (ZERR_NONE);
+
+    if (gethostname(hostname, MAXHOSTNAMELEN) < 0)
+	return (errno);
+
+    if (!(myhost = gethostbyname(hostname)))
+	return (errno);
+
+    /* If h_length is 0, that is a serious problem and it doesn't
+       make it worse for malloc(0) to return NULL, so don't worry
+       about that case. */
+    if (!(__My_addr = (char *)malloc((unsigned)myhost->h_length)))
+	return (ENOMEM);
+
+    __My_length = myhost->h_length;
+
+    (void) memcpy(__My_addr, myhost->h_addr, myhost->h_length);
+
+    return (ZERR_NONE);
+} 
+
+
+/* Return 1 if there is a packet waiting, 0 otherwise */
+
+int Z_PacketWaiting()
+{
+    struct timeval tv;
+    fd_set read;
+
+    tv.tv_sec = tv.tv_usec = 0;
+    FD_ZERO(&read);
+    FD_SET(ZGetFD(), &read);
+    return (select(ZGetFD() + 1, &read, NULL, NULL, &tv));
+} 
+
+
+/* Wait for a complete notice to become available */
+
+Code_t Z_WaitForComplete()
+{
+    Code_t retval;
+
+    if (__Q_CompleteLength)
+	return (Z_ReadEnqueue());
+
+    while (!__Q_CompleteLength)
+	if ((retval = Z_ReadWait()) != ZERR_NONE)
+	    return (retval);
+
+    return (ZERR_NONE);
+}
+
+
+/* Read any available packets and enqueue them */
+
+Code_t Z_ReadEnqueue()
+{
+    Code_t retval;
+
+    if (ZGetFD() < 0)
+	return (ZERR_NOPORT);
+    
+    while (Z_PacketWaiting())
+	if ((retval = Z_ReadWait()) != ZERR_NONE)
+	    return (retval);
+
+    return (ZERR_NONE);
+}
+
+
+/*
+ * Search the queue for a notice with the proper multiuid - remove any
+ * notices that haven't been touched in a while
+ */
+
+struct _Z_InputQ *Z_SearchQueue(uid, kind)
+    ZUnique_Id_t *uid;
+    ZNotice_Kind_t kind;
+{
+    register struct _Z_InputQ *qptr;
+    struct _Z_InputQ *next;
+    struct timeval tv;
+
+    (void) gettimeofday(&tv, (struct timezone *)0);
+
+    qptr = __Q_Head;
+
+    while (qptr) {
+	if (ZCompareUID(uid, &qptr->uid) && qptr->kind == kind)
+	    return (qptr);
+	next = qptr->next;
+	if (qptr->timep && (qptr->timep+Z_NOTICETIMELIMIT < tv.tv_sec))
+	    Z_RemQueue(qptr);
+	qptr = next;
+    }
+    return (NULL);
+}
+
+/*
+ * Now we delve into really convoluted queue handling and
+ * fragmentation reassembly algorithms and other stuff you probably
+ * don't want to look at...
+ *
+ * This routine does NOT guarantee a complete packet will be ready when it
+ * returns.
+ */
+
+Code_t Z_ReadWait()
+{
+    register struct _Z_InputQ *qptr;
+    ZNotice_t notice;
+    ZPacket_t packet;
+    struct sockaddr_in olddest, from;
+    int from_len, packet_len, part, partof;
+    char *slash;
+    Code_t retval;
+    register int i;
+
+    if (ZGetFD() < 0)
+	return (ZERR_NOPORT);
+	
+    from_len = sizeof(struct sockaddr_in);
+
+    packet_len = recvfrom(ZGetFD(), packet, sizeof(packet), 0, 
+			  (struct sockaddr *)&from, &from_len);
+
+    if (packet_len < 0)
+	return (errno);
+
+    if (!packet_len)
+	return (ZERR_EOF);
+
+    /* XXX Check for null data (debugging) */
+    for (i = packet_len - 1; i >= 0; i--)
+      if (packet[i])
+	goto not_all_null;
+#ifdef Z_DEBUG
+    Z_debug ("got null packet from %s", inet_ntoa (from.sin_addr));
+#endif
+    return ZERR_NONE;
+  not_all_null:
+
+    /* Parse the notice */
+    if ((retval = ZParseNotice(packet, packet_len, &notice)) != ZERR_NONE)
+	return (retval);
+
+    /*
+     * If we're not a server and the notice is of an appropriate kind,
+     * send back a CLIENTACK to whoever sent it to say we got it.
+     */
+    if (!__Zephyr_server) {
+	if (notice.z_kind != HMACK && notice.z_kind != SERVACK &&
+	    notice.z_kind != SERVNAK && notice.z_kind != CLIENTACK) {
+	    ZNotice_t tmpnotice;
+	    ZPacket_t pkt;
+	    int len;
+
+	    tmpnotice = notice;
+	    tmpnotice.z_kind = CLIENTACK;
+	    tmpnotice.z_message_len = 0;
+	    olddest = __HM_addr;
+	    __HM_addr = from;
+	    if ((retval = ZFormatSmallRawNotice(&tmpnotice, pkt, &len))
+		!= ZERR_NONE)
+		return(retval);
+	    if ((retval = ZSendPacket(pkt, len, 0)) != ZERR_NONE)
+		return (retval);
+	    __HM_addr = olddest;
+	}
+	if (find_or_insert_uid(&notice.z_uid, notice.z_kind))
+	    return(ZERR_NONE);
+
+	/* Check authentication on the notice. */
+	notice.z_checked_auth = ZCheckAuthentication(&notice, &from);
+    }
+
+
+    /*
+     * Parse apart the z_multinotice field - if the field is blank for
+     * some reason, assume this packet stands by itself.
+     */
+    slash = strchr(notice.z_multinotice, '/');
+    if (slash) {
+	part = atoi(notice.z_multinotice);
+	partof = atoi(slash+1);
+	if (part > partof || partof == 0) {
+	    part = 0;
+	    partof = notice.z_message_len;
+	}
+    }
+    else {
+	part = 0;
+	partof = notice.z_message_len;
+    }
+
+    /* Too big a packet...just ignore it! */
+    if (partof > Z_MAXNOTICESIZE)
+	return (ZERR_NONE);
+
+    /*
+     * If we aren't a server and we can find a notice in the queue
+     * with the same multiuid field, insert the current fragment as
+     * appropriate.
+     */
+    switch (notice.z_kind) {
+    case SERVACK:
+    case SERVNAK:
+	/* The SERVACK and SERVNAK replies shouldn't be reassembled
+	   (they have no parts).  Instead, we should hold on to the reply
+	   ONLY if it's the first part of a fragmented message, i.e.
+	   multi_uid == uid.  This allows programs to wait for the uid
+	   of the first packet, and get a response when that notice
+	   arrives.  Acknowledgements of the other fragments are discarded
+	   (XXX we assume here that they all carry the same information
+	   regarding failure/success)
+	 */
+	if (!__Zephyr_server &&
+	    !ZCompareUID(&notice.z_multiuid, &notice.z_uid))
+	    /* they're not the same... throw away this packet. */
+	    return(ZERR_NONE);
+	/* fall thru & process it */
+    default:
+	/* for HMACK types, we assume no packet loss (local loopback
+	   connections).  The other types can be fragmented and MUST
+	   run through this code. */
+	if (!__Zephyr_server && (qptr = Z_SearchQueue(&notice.z_multiuid,
+						      notice.z_kind))) {
+	    /*
+	     * If this is the first fragment, and we haven't already
+	     * gotten a first fragment, grab the header from it.
+	     */
+	    if (part == 0 && !qptr->header) {
+		qptr->header_len = packet_len-notice.z_message_len;
+		qptr->header = (char *) malloc((unsigned) qptr->header_len);
+		if (!qptr->header)
+		    return (ENOMEM);
+		(void) memcpy(qptr->header, packet, qptr->header_len);
+	    }
+	    return (Z_AddNoticeToEntry(qptr, &notice, part));
+	}
+    }
+
+    /*
+     * We'll have to create a new entry...make sure the queue isn't
+     * going to get too big.
+     */
+    if (__Q_Size+(__Zephyr_server ? notice.z_message_len : partof) > Z_MAXQUEUESIZE)
+	return (ZERR_NONE);
+
+    /*
+     * This is a notice we haven't heard of, so create a new queue
+     * entry for it and zero it out.
+     */
+    qptr = (struct _Z_InputQ *)malloc(sizeof(struct _Z_InputQ));
+    if (!qptr)
+	return (ENOMEM);
+    (void) memset((char *)qptr, 0, sizeof(struct _Z_InputQ));
+
+    /* Insert the entry at the end of the queue */
+    qptr->next = NULL;
+    qptr->prev = __Q_Tail;
+    if (__Q_Tail)
+	__Q_Tail->next = qptr;
+    __Q_Tail = qptr;
+
+    if (!__Q_Head)
+	__Q_Head = qptr;
+
+    
+    /* Copy the from field, multiuid, kind, and checked authentication. */
+    qptr->from = from;
+    qptr->uid = notice.z_multiuid;
+    qptr->kind = notice.z_kind;
+    qptr->auth = notice.z_checked_auth;
+    
+    /*
+     * If this is the first part of the notice, we take the header
+     * from it.  We only take it if this is the first fragment so that
+     * the Unique ID's will be predictable.
+     *
+     * If a Zephyr Server, we always take the header.
+     */
+    if (__Zephyr_server || part == 0) {
+	qptr->header_len = packet_len-notice.z_message_len;
+	qptr->header = (char *) malloc((unsigned) qptr->header_len);
+	if (!qptr->header)
+	    return ENOMEM;
+	(void) memcpy(qptr->header, packet, qptr->header_len);
+    }
+
+    /*
+     * If this is not a fragmented notice, then don't bother with a
+     * hole list.
+     * If we are a Zephyr server, all notices are treated as complete.
+     */
+    if (__Zephyr_server || (part == 0 && notice.z_message_len == partof)) {
+	__Q_CompleteLength++;
+	qptr->holelist = (struct _Z_Hole *) 0;
+	qptr->complete = 1;
+	/* allocate a msg buf for this piece */
+	if (notice.z_message_len == 0)
+	    qptr->msg = 0;
+	else if (!(qptr->msg = (char *) malloc((unsigned) notice.z_message_len)))
+	    return(ENOMEM);
+	else
+	    (void) memcpy(qptr->msg, notice.z_message, notice.z_message_len);
+	qptr->msg_len = notice.z_message_len;
+	__Q_Size += notice.z_message_len;
+	qptr->packet_len = qptr->header_len+qptr->msg_len;
+	if (!(qptr->packet = (char *) malloc((unsigned) qptr->packet_len)))
+	    return (ENOMEM);
+	(void) memcpy(qptr->packet, qptr->header, qptr->header_len);
+	if(qptr->msg)
+	    (void) memcpy(qptr->packet+qptr->header_len, qptr->msg,
+			   qptr->msg_len);
+	return (ZERR_NONE);
+    }
+
+    /*
+     * We know how long the message is going to be (this is better
+     * than IP fragmentation...), so go ahead and allocate it all.
+     */
+    if (!(qptr->msg = (char *) malloc((unsigned) partof)) && partof)
+	return (ENOMEM);
+    qptr->msg_len = partof;
+    __Q_Size += partof;
+
+    /*
+     * Well, it's a fragmented notice...allocate a hole list and
+     * initialize it to the full packet size.  Then insert the
+     * current fragment.
+     */
+    if (!(qptr->holelist = (struct _Z_Hole *)
+	  malloc(sizeof(struct _Z_Hole))))
+	return (ENOMEM);
+    qptr->holelist->next = (struct _Z_Hole *) 0;
+    qptr->holelist->first = 0;
+    qptr->holelist->last = partof-1;
+    return (Z_AddNoticeToEntry(qptr, &notice, part));
+}
+
+
+/* Fragment management routines - compliments, more or less, of RFC815 */
+
+Code_t Z_AddNoticeToEntry(qptr, notice, part)
+    struct _Z_InputQ *qptr;
+    ZNotice_t *notice;
+    int part;
+{
+    int last, oldfirst, oldlast;
+    struct _Z_Hole *hole, *lasthole;
+    struct timeval tv;
+
+    /* Incorporate this notice's checked authentication. */
+    if (notice->z_checked_auth == ZAUTH_FAILED)
+	qptr->auth = ZAUTH_FAILED;
+    else if (notice->z_checked_auth == ZAUTH_NO && qptr->auth != ZAUTH_FAILED)
+	qptr->auth = ZAUTH_NO;
+
+    (void) gettimeofday(&tv, (struct timezone *)0);
+    qptr->timep = tv.tv_sec;
+    
+    last = part+notice->z_message_len-1;
+
+    hole = qptr->holelist;
+    lasthole = (struct _Z_Hole *) 0;
+
+    /* copy in the message body */
+    (void) memcpy(qptr->msg+part, notice->z_message, notice->z_message_len);
+
+    /* Search for a hole that overlaps with the current fragment */
+    while (hole) {
+	if (part <= hole->last && last >= hole->first)
+	    break;
+	lasthole = hole;
+	hole = hole->next;
+    }
+
+    /* If we found one, delete it and reconstruct a new hole */
+    if (hole) {
+	oldfirst = hole->first;
+	oldlast = hole->last;
+	if (lasthole)
+	    lasthole->next = hole->next;
+	else
+	    qptr->holelist = hole->next;
+	free((char *)hole);
+	/*
+	 * Now create a new hole that is the original hole without the
+	 * current fragment.
+	 */
+	if (part > oldfirst) {
+	    /* Search for the end of the hole list */
+	    hole = qptr->holelist;
+	    lasthole = (struct _Z_Hole *) 0;
+	    while (hole) {
+		lasthole = hole;
+		hole = hole->next;
+	    }
+	    if (lasthole) {
+		if (!(lasthole->next = (struct _Z_Hole *)
+		      malloc(sizeof(struct _Z_InputQ))))
+		    return (ENOMEM);
+		hole = lasthole->next;
+	    }
+	    else {
+		if (!(qptr->holelist = (struct _Z_Hole *)
+		      malloc(sizeof(struct _Z_InputQ))))
+		    return (ENOMEM);
+		hole = qptr->holelist;
+	    }
+	    hole->next = NULL;
+	    hole->first = oldfirst;
+	    hole->last = part-1;
+	}
+	if (last < oldlast) {
+	    /* Search for the end of the hole list */
+	    hole = qptr->holelist;
+	    lasthole = (struct _Z_Hole *) 0;
+	    while (hole) {
+		lasthole = hole;
+		hole = hole->next;
+	    }
+	    if (lasthole) {
+		if (!(lasthole->next = (struct _Z_Hole *)
+		      malloc(sizeof(struct _Z_InputQ))))
+		    return (ENOMEM);
+		hole = lasthole->next;
+	    }
+	    else {
+		if (!(qptr->holelist = (struct _Z_Hole *)
+		      malloc(sizeof(struct _Z_InputQ))))
+		    return (ENOMEM);
+		hole = qptr->holelist;
+	    }
+	    hole->next = (struct _Z_Hole *) 0;
+	    hole->first = last+1;
+	    hole->last = oldlast;
+	}
+    }
+
+    if (!qptr->holelist) {
+	if (!qptr->complete)
+	    __Q_CompleteLength++;
+	qptr->complete = 1;
+	qptr->timep = 0;		/* don't time out anymore */
+	qptr->packet_len = qptr->header_len+qptr->msg_len;
+	if (!(qptr->packet = (char *) malloc((unsigned) qptr->packet_len)))
+	    return (ENOMEM);
+	(void) memcpy(qptr->packet, qptr->header, qptr->header_len);
+	(void) memcpy(qptr->packet+qptr->header_len, qptr->msg,
+		       qptr->msg_len);
+    }
+    
+    return (ZERR_NONE);
+}
+
+Code_t Z_FormatHeader(notice, buffer, buffer_len, len, cert_routine)
+    ZNotice_t *notice;
+    char *buffer;
+    int buffer_len;
+    int *len;
+    Z_AuthProc cert_routine;
+{
+    Code_t retval;
+    static char version[BUFSIZ]; /* default init should be all \0 */
+    struct sockaddr_in name;
+    int namelen = sizeof(name);
+
+    if (!notice->z_sender)
+	notice->z_sender = ZGetSender();
+
+    if (notice->z_port == 0) {
+	if (ZGetFD() < 0) {
+	    retval = ZOpenPort((u_short *)0);
+	    if (retval != ZERR_NONE)
+		return (retval);
+	}
+	retval = getsockname(ZGetFD(), (struct sockaddr *) &name, &namelen);
+	if (retval != 0)
+	    return (retval);
+	notice->z_port = name.sin_port;
+    }
+
+    notice->z_multinotice = "";
+    
+    (void) gettimeofday(&notice->z_uid.tv, (struct timezone *)0);
+    notice->z_uid.tv.tv_sec = htonl((u_long) notice->z_uid.tv.tv_sec);
+    notice->z_uid.tv.tv_usec = htonl((u_long) notice->z_uid.tv.tv_usec);
+    
+    if ((retval = Z_GetMyAddr()) != ZERR_NONE)
+	return (retval);
+
+    (void) memcpy((char *)&notice->z_uid.zuid_addr, __My_addr, __My_length);
+
+    notice->z_multiuid = notice->z_uid;
+
+    if (!version[0])
+	    (void) sprintf(version, "%s%d.%d", ZVERSIONHDR, ZVERSIONMAJOR,
+			   ZVERSIONMINOR);
+    notice->z_version = version;
+
+    return Z_FormatAuthHeader(notice, buffer, buffer_len, len, cert_routine);
+}
+
+Code_t Z_FormatAuthHeader(notice, buffer, buffer_len, len, cert_routine)
+    ZNotice_t *notice;
+    char *buffer;
+    int buffer_len;
+    int *len;
+    Z_AuthProc cert_routine;
+{
+    if (!cert_routine) {
+	notice->z_auth = 0;
+	notice->z_authent_len = 0;
+	notice->z_ascii_authent = "";
+	notice->z_checksum = 0;
+	return (Z_FormatRawHeader(notice, buffer, buffer_len,
+				  len, NULL, NULL));
+    }
+    
+    return ((*cert_routine)(notice, buffer, buffer_len, len));
+} 
+	
+Code_t Z_FormatRawHeader(notice, buffer, buffer_len, len, cstart, cend)
+    ZNotice_t *notice;
+    char *buffer;
+    int buffer_len;
+    int *len;
+    char **cstart, **cend;
+{
+    char newrecip[BUFSIZ];
+    char *ptr, *end;
+    int i;
+
+    if (!notice->z_class)
+	    notice->z_class = "";
+
+    if (!notice->z_class_inst)
+	    notice->z_class_inst = "";
+
+    if (!notice->z_opcode)
+	    notice->z_opcode = "";
+
+    if (!notice->z_recipient)
+	    notice->z_recipient = "";
+
+    if (!notice->z_default_format)
+	    notice->z_default_format = "";
+
+    ptr = buffer;
+    end = buffer+buffer_len;
+
+    if (buffer_len < strlen(notice->z_version)+1)
+	return (ZERR_HEADERLEN);
+
+    (void) strcpy(ptr, notice->z_version);
+    ptr += strlen(ptr)+1;
+
+    if (ZMakeAscii32(ptr, end-ptr, Z_NUMFIELDS + notice->z_num_other_fields)
+	== ZERR_FIELDLEN)
+	return (ZERR_HEADERLEN);
+    ptr += strlen(ptr)+1;
+
+    if (ZMakeAscii32(ptr, end-ptr, notice->z_kind) == ZERR_FIELDLEN)
+	return (ZERR_HEADERLEN);
+    ptr += strlen(ptr)+1;
+
+    if (ZMakeAscii(ptr, end-ptr, (unsigned char *)&notice->z_uid, 
+		   sizeof(ZUnique_Id_t)) == ZERR_FIELDLEN)
+	return (ZERR_HEADERLEN);
+    ptr += strlen(ptr)+1;
+
+    if (ZMakeAscii16(ptr, end-ptr, ntohs(notice->z_port)) == ZERR_FIELDLEN)
+	return (ZERR_HEADERLEN);
+    ptr += strlen(ptr)+1;
+
+    if (ZMakeAscii32(ptr, end-ptr, notice->z_auth) == ZERR_FIELDLEN)
+	return (ZERR_HEADERLEN);
+    ptr += strlen(ptr)+1;
+
+    if (ZMakeAscii32(ptr, end-ptr, notice->z_authent_len) == ZERR_FIELDLEN)
+	return (ZERR_HEADERLEN);
+    ptr += strlen(ptr)+1;
+
+    if (Z_AddField(&ptr, notice->z_ascii_authent, end))
+	return (ZERR_HEADERLEN);
+    if (Z_AddField(&ptr, notice->z_class, end))
+	return (ZERR_HEADERLEN);
+    if (Z_AddField(&ptr, notice->z_class_inst, end))
+	return (ZERR_HEADERLEN);
+    if (Z_AddField(&ptr, notice->z_opcode, end))
+	return (ZERR_HEADERLEN);
+    if (Z_AddField(&ptr, notice->z_sender, end))
+	return (ZERR_HEADERLEN);
+    if (strchr(notice->z_recipient, '@') || !*notice->z_recipient) {
+	if (Z_AddField(&ptr, notice->z_recipient, end))
+	    return (ZERR_HEADERLEN);
+    }
+    else {
+	if (strlen(notice->z_recipient) + strlen(__Zephyr_realm) + 2 >
+		sizeof(newrecip))
+	    return (ZERR_HEADERLEN);            
+	(void) sprintf(newrecip, "%s@%s", notice->z_recipient, __Zephyr_realm);
+	if (Z_AddField(&ptr, newrecip, end))
+	    return (ZERR_HEADERLEN);
+    }		
+    if (Z_AddField(&ptr, notice->z_default_format, end))
+	return (ZERR_HEADERLEN);
+
+    /* copy back the end pointer location for crypto checksum */
+    if (cstart)
+	*cstart = ptr;
+    if (ZMakeAscii32(ptr, end-ptr, notice->z_checksum) == ZERR_FIELDLEN)
+	return (ZERR_HEADERLEN);
+    ptr += strlen(ptr)+1;
+    if (cend)
+	*cend = ptr;
+
+    if (Z_AddField(&ptr, notice->z_multinotice, end))
+	return (ZERR_HEADERLEN);
+
+    if (ZMakeAscii(ptr, end-ptr, (unsigned char *)&notice->z_multiuid, 
+		   sizeof(ZUnique_Id_t)) == ZERR_FIELDLEN)
+	return (ZERR_HEADERLEN);
+    ptr += strlen(ptr)+1;
+	
+    for (i=0;i<notice->z_num_other_fields;i++)
+	if (Z_AddField(&ptr, notice->z_other_fields[i], end))
+	    return (ZERR_HEADERLEN);
+    
+    *len = ptr-buffer;
+	
+    return (ZERR_NONE);
+}
+
+static int
+Z_AddField(ptr, field, end)
+    char **ptr, *field, *end;
+{
+    register int len;
+
+    len = field ? strlen (field) + 1 : 1;
+
+    if (*ptr+len > end)
+	return 1;
+    if (field)
+	(void) strcpy(*ptr, field);
+    else
+	**ptr = '\0';
+    *ptr += len;
+
+    return 0;
+}
+
+struct _Z_InputQ *Z_GetFirstComplete()
+{
+    struct _Z_InputQ *qptr;
+
+    qptr = __Q_Head;
+
+    while (qptr) {
+	if (qptr->complete)
+	    return (qptr);
+	qptr = qptr->next;
+    }
+
+    return ((struct _Z_InputQ *)0);
+}
+
+struct _Z_InputQ *Z_GetNextComplete(qptr)
+    struct _Z_InputQ *qptr;
+{
+    qptr = qptr->next;
+    while (qptr) {
+	if (qptr->complete)
+	    return (qptr);
+	qptr = qptr->next;
+    }
+
+    return ((struct _Z_InputQ *)0);
+}
+
+void Z_RemQueue(qptr)
+    struct _Z_InputQ *qptr;
+{
+    struct _Z_Hole *hole, *nexthole;
+    
+    if (qptr->complete)
+	__Q_CompleteLength--;
+
+    __Q_Size -= qptr->msg_len;
+    
+    if (qptr->header)
+	free(qptr->header);
+    if (qptr->msg)
+	free(qptr->msg);
+    if (qptr->packet)
+	free(qptr->packet);
+    
+    hole = qptr->holelist;
+    while (hole) {
+	nexthole = hole->next;
+	free((char *)hole);
+	hole = nexthole;
+    }
+    
+    if (qptr == __Q_Head && __Q_Head == __Q_Tail) {
+	free ((char *)qptr);
+	__Q_Head = (struct _Z_InputQ *)0;
+	__Q_Tail = (struct _Z_InputQ *)0;
+	return;
+    }
+    
+    if (qptr == __Q_Head) {
+	__Q_Head = qptr->next;
+	__Q_Head->prev = (struct _Z_InputQ *)0;
+	free ((char *)qptr);
+	return;
+    } 
+    if (qptr == __Q_Tail) {
+	__Q_Tail = qptr->prev;
+	__Q_Tail->next = (struct _Z_InputQ *)0;
+	free ((char *)qptr);
+	return;
+    }
+    qptr->prev->next = qptr->next;
+    qptr->next->prev = qptr->prev;
+    free ((char *)qptr);
+    return;
+}
+
+Code_t Z_SendFragmentedNotice(notice, len, cert_func, send_func)
+    ZNotice_t *notice;
+    int len;
+    Z_AuthProc cert_func;
+    Z_SendProc send_func;
+{
+    ZNotice_t partnotice;
+    ZPacket_t buffer;
+    char multi[64];
+    int offset, hdrsize, fragsize, ret_len, message_len, waitforack;
+    Code_t retval;
+    
+    hdrsize = len-notice->z_message_len;
+    fragsize = Z_MAXPKTLEN-hdrsize-Z_FRAGFUDGE;
+    
+    offset = 0;
+
+    waitforack = ((notice->z_kind == UNACKED || notice->z_kind == ACKED)
+		  && !__Zephyr_server);
+    
+    partnotice = *notice;
+
+    while (offset < notice->z_message_len || !notice->z_message_len) {
+	(void) sprintf(multi, "%d/%d", offset, notice->z_message_len);
+	partnotice.z_multinotice = multi;
+	if (offset > 0) {
+	    (void) gettimeofday(&partnotice.z_uid.tv,
+				(struct timezone *)0);
+	    partnotice.z_uid.tv.tv_sec =
+		htonl((u_long) partnotice.z_uid.tv.tv_sec);
+	    partnotice.z_uid.tv.tv_usec =
+		htonl((u_long) partnotice.z_uid.tv.tv_usec);
+	    if ((retval = Z_GetMyAddr()) != ZERR_NONE)
+		return (retval);
+	    (void) memcpy((char *)&partnotice.z_uid.zuid_addr, __My_addr, 
+			   __My_length);
+	}
+	message_len = min(notice->z_message_len-offset, fragsize);
+	partnotice.z_message = notice->z_message+offset;
+	partnotice.z_message_len = message_len;
+	if ((retval = Z_FormatAuthHeader(&partnotice, buffer, Z_MAXHEADERLEN,
+					 &ret_len, cert_func)) != ZERR_NONE) {
+	    return (retval);
+	}
+	memcpy(buffer + ret_len, partnotice.z_message, message_len);
+	if ((retval = (*send_func)(&partnotice, buffer, ret_len+message_len,
+				   waitforack)) != ZERR_NONE) {
+	    return (retval);
+	}
+	offset += fragsize;
+	if (!notice->z_message_len)
+	    break;
+    }
+
+    return (ZERR_NONE);
+}
+
+/*ARGSUSED*/
+Code_t Z_XmitFragment(notice, buf, len, wait)
+ZNotice_t *notice;
+char *buf;
+int len;
+int wait;
+{
+	return(ZSendPacket(buf, len, wait));
+}
+
+#ifdef Z_DEBUG
+/* For debugging printing */
+const char *const ZNoticeKinds[] = {
+    "UNSAFE", "UNACKED", "ACKED", "HMACK", "HMCTL", "SERVACK", "SERVNAK",
+    "CLIENTACK", "STAT"
+};
+#endif
+
+#ifdef Z_DEBUG
+
+#undef Z_debug
+#ifdef HAVE_STDARG_H
+void Z_debug (const char *format, ...)
+{
+    va_list pvar;
+    if (!__Z_debug_print)
+      return;
+    va_start (pvar, format);
+    (*__Z_debug_print) (format, pvar, __Z_debug_print_closure);
+    va_end (pvar);
+}
+#else /* stdarg */
+void Z_debug (va_alist) va_dcl
+{
+    va_list pvar;
+    char *format;
+    if (!__Z_debug_print)
+      return;
+    va_start (pvar);
+    format = va_arg (pvar, char *);
+    (*__Z_debug_print) (format, pvar, __Z_debug_print_closure);
+    va_end (pvar);
+}
+#endif
+
+void Z_debug_stderr (format, args, closure)
+     const char *format;
+     va_list args;
+     void *closure;
+{
+#ifdef HAVE_VPRINTF
+    vfprintf (stderr, format, args);
+#else
+    _doprnt (format, args, stderr);
+#endif
+    putc ('\n', stderr);
+}
+
+#undef ZGetFD
+int ZGetFD () { return __Zephyr_fd; }
+
+#undef ZQLength
+int ZQLength () { return __Q_CompleteLength; }
+
+#undef ZGetDestAddr
+struct sockaddr_in ZGetDestAddr () { return __HM_addr; }
+
+#undef ZGetRealm
+Zconst char * ZGetRealm () { return __Zephyr_realm; }
+
+#undef ZSetDebug
+void ZSetDebug(proc, arg)
+    void (*proc) __P((const char *, va_list, void *));
+    char *arg;
+{
+    __Z_debug_print = proc;
+    __Z_debug_print_closure = arg;
+}
+#endif /* Z_DEBUG */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/com_err.h	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,38 @@
+/*
+ * Header file for common error description library.
+ *
+ * Copyright 1988, Student Information Processing Board of the
+ * Massachusetts Institute of Technology.
+ *
+ * For copyright and distribution info, see the documentation supplied
+ * with this package.
+ */
+
+#ifndef __COM_ERR_H
+#define __COM_ERR_H
+
+#define COM_ERR_BUF_LEN 25
+
+/* Use __STDC__ to guess whether we can use stdarg, prototypes, and const.
+ * This is a public header file, so autoconf can't help us here. */
+#ifdef __STDC__
+# include <stdarg.h>
+# define ETP(x) x
+# define ETCONST const
+#else
+# define ETP(x) ()
+# define ETCONST
+#endif
+
+typedef void (*error_handler_t) ETP((ETCONST char *, long, ETCONST char *,
+				     va_list));
+extern error_handler_t com_err_hook;
+void com_err ETP((ETCONST char *, long, ETCONST char *, ...));
+ETCONST char *error_message ETP((long));
+ETCONST char *error_message_r ETP((long, char *));
+error_handler_t set_com_err_hook ETP((error_handler_t));
+error_handler_t reset_com_err_hook ETP((void));
+
+#undef ETP
+
+#endif /* ! defined(__COM_ERR_H) */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/error_message.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,76 @@
+/*
+ * $Header$
+ * $Source$
+ * $Locker$
+ *
+ * Copyright 1987 by the Student Information Processing Board
+ * of the Massachusetts Institute of Technology
+ *
+ * For copyright info, see "mit-sipb-copyright.h".
+ */
+
+#include <sysdep.h>
+#include "error_table.h"
+#include "mit-sipb-copyright.h"
+#include "com_err.h"
+
+static const char rcsid[] =
+    "$Header$";
+static const char copyright[] =
+    "Copyright 1986, 1987, 1988 by the Student Information Processing Board\nand the department of Information Systems\nof the Massachusetts Institute of Technology";
+
+char *error_table_name_r __P((int, char *));
+
+struct et_list * _et_list = (struct et_list *) NULL;
+
+const char * error_message (code)
+long	code;
+{
+    static char buf[COM_ERR_BUF_LEN];
+
+    return(error_message_r(code, buf));
+}
+
+const char * error_message_r (code, buf)
+long	code;
+char	*buf;
+{
+    int offset;
+    struct et_list *et;
+    int table_num;
+    int started = 0;
+    char *cp, namebuf[6];
+
+    offset = code & ((1<<ERRCODE_RANGE)-1);
+    table_num = code - offset;
+    if (!table_num)
+	return strerror(offset);
+    for (et = _et_list; et; et = et->next) {
+	if (et->table->base == table_num) {
+	    /* This is the right table */
+	    if (et->table->n_msgs <= offset)
+		break;
+	    return(et->table->msgs[offset]);
+	}
+    }
+
+    strcpy (buf, "Unknown code ");
+    if (table_num) {
+	strcat (buf, error_table_name_r (table_num, namebuf));
+	strcat (buf, " ");
+    }
+    for (cp = buf; *cp; cp++)
+	;
+    if (offset >= 100) {
+	*cp++ = '0' + offset / 100;
+	offset %= 100;
+	started++;
+    }
+    if (started || offset >= 10) {
+	*cp++ = '0' + offset / 10;
+	offset %= 10;
+    }
+    *cp++ = '0' + offset;
+    *cp = '\0';
+    return(buf);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/error_table.h	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,25 @@
+/*
+ * Copyright 1988 by the Student Information Processing Board of the
+ * Massachusetts Institute of Technology.
+ *
+ * For copyright info, see mit-sipb-copyright.h.
+ */
+
+#ifndef _ET_H
+struct error_table {
+    char const * const * msgs;
+    long base;
+    int n_msgs;
+};
+struct et_list {
+    struct et_list *next;
+    const struct error_table *table;
+};
+extern struct et_list * _et_list;
+
+#define	ERRCODE_RANGE	8	/* # of bits to shift table number */
+#define	BITS_PER_CHAR	6	/* # bits to shift per character in name */
+
+extern const char *error_table_name();
+#define _ET_H
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/et_name.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,51 @@
+/*
+ * Copyright 1987 by MIT Student Information Processing Board
+ *
+ * For copyright info, see mit-sipb-copyright.h.
+ */
+
+#include <sysdep.h>
+#include "error_table.h"
+#include "mit-sipb-copyright.h"
+
+#ifndef	lint
+static const char copyright[] =
+    "Copyright 1987,1988 by Student Information Processing Board, Massachusetts Institute of Technology";
+static const char rcsid_et_name_c[] =
+    "$Header$";
+#endif
+
+static const char char_set[] =
+	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
+
+const char * error_table_name_r(num, buf)
+    int num;
+    char *buf;
+{
+    int ch;
+    int i;
+    char *p;
+
+    /* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */
+    p = buf;
+    num >>= ERRCODE_RANGE;
+    /* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */
+    num &= 077777777;
+    /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */
+    for (i = 4; i >= 0; i--) {
+	ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1);
+	if (ch != 0)
+	    *p++ = char_set[ch-1];
+    }
+    *p = '\0';
+    return(buf);
+}
+
+const char * error_table_name(num)
+    int num;
+{
+    static char buf[6];
+
+    return(error_table_name_r(num, buf));
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/init_et.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,49 @@
+/*
+ * $Header$
+ * $Source$
+ * $Locker$
+ *
+ * Copyright 1986, 1987, 1988 by MIT Information Systems and
+ *	the MIT Student Information Processing Board.
+ *
+ * For copyright info, see mit-sipb-copyright.h.
+ */
+
+#include <sysdep.h>
+#include "error_table.h"
+#include "mit-sipb-copyright.h"
+
+#ifndef	lint
+static const char rcsid_init_et_c[] =
+    "$Header$";
+#endif
+
+struct foobar {
+    struct et_list etl;
+    struct error_table et;
+};
+
+extern struct et_list * _et_list;
+
+int init_error_table(msgs, base, count)
+    const char * const * msgs;
+    int base;
+    int count;
+{
+    struct foobar * new_et;
+
+    if (!base || !count || !msgs)
+	return 0;
+
+    new_et = (struct foobar *) malloc(sizeof(struct foobar));
+    if (!new_et)
+	return errno;	/* oops */
+    new_et->etl.table = &new_et->et;
+    new_et->et.msgs = msgs;
+    new_et->et.base = base;
+    new_et->et.n_msgs= count;
+
+    new_et->etl.next = _et_list;
+    _et_list = &new_et->etl;
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/internal.h	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,96 @@
+
+#ifndef __INTERNAL_H__
+#define __INTERNAL_H__
+
+#include <sysdep.h>
+#include <zephyr/zephyr.h>
+#include <netdb.h>
+
+#ifdef ZEPHYR_USES_HESIOD
+#include <hesiod.h>
+#endif
+
+#ifndef ZEPHYR_USES_KERBEROS
+#define REALM_SZ	MAXHOSTNAMELEN
+#define INST_SZ		0		/* no instances w/o Kerberos */
+#define ANAME_SZ	9		/* size of a username + null */
+#define CLOCK_SKEW	300		/* max time to cache packet ids */
+#endif
+
+#define SERVER_SVC_FALLBACK	htons((unsigned short) 2103)
+#define HM_SVC_FALLBACK		htons((unsigned short) 2104)
+#define HM_SRV_SVC_FALLBACK	htons((unsigned short) 2105)
+
+#define ZAUTH_CKSUM_FAILED	(-2) /* Used only by server. */
+#define ZAUTH_UNSET		(-3) /* Internal to client library. */
+#define Z_MAXFRAGS		500	/* Max number of packet fragments */
+#define Z_MAXNOTICESIZE		400000	/* Max size of incoming notice */
+#define Z_MAXQUEUESIZE		1500000	/* Max size of input queue notices */
+#define Z_FRAGFUDGE		13	/* Room to for multinotice field */
+#define Z_NOTICETIMELIMIT	30	/* Time to wait for fragments */
+#define Z_INITFILTERSIZE	30	/* Starting size of uid filter */
+
+struct _Z_Hole {
+    struct _Z_Hole	*next;
+    int			first;
+    int			last;
+};
+
+struct _Z_InputQ {
+    struct _Z_InputQ	*next;
+    struct _Z_InputQ	*prev;
+    ZNotice_Kind_t	kind;
+    unsigned ZEPHYR_INT32 timep;
+    int			packet_len;
+    char		*packet;
+    int			complete;
+    struct sockaddr_in	from;
+    struct _Z_Hole	*holelist;
+    ZUnique_Id_t	uid;
+    int			auth;
+    int			header_len;
+    char		*header;
+    int			msg_len;
+    char		*msg;
+};
+
+extern struct _Z_InputQ *__Q_Head, *__Q_Tail;
+
+extern int __Zephyr_open;	/* 0 if FD opened, 1 otherwise */
+extern int __HM_set;		/* 0 if dest addr set, 1 otherwise */
+extern int __Zephyr_server;	/* 0 if normal client, 1 if server or zhm */
+
+extern ZLocations_t *__locate_list;
+extern int __locate_num;
+extern int __locate_next;
+
+extern ZSubscription_t *__subscriptions_list;
+extern int __subscriptions_num;
+extern int __subscriptions_next;
+
+extern int __Zephyr_port;		/* Port number */
+
+typedef Code_t (*Z_SendProc) __P((ZNotice_t *, char *, int, int));
+
+struct _Z_InputQ *Z_GetFirstComplete __P((void));
+struct _Z_InputQ *Z_GetNextComplete __P((struct _Z_InputQ *));
+Code_t Z_XmitFragment __P((ZNotice_t*, char *,int,int));
+void Z_RemQueue __P((struct _Z_InputQ *));
+Code_t Z_AddNoticeToEntry __P((struct _Z_InputQ*, ZNotice_t*, int));
+Code_t Z_FormatAuthHeader __P((ZNotice_t *, char *, int, int *, Z_AuthProc));
+Code_t Z_FormatHeader __P((ZNotice_t *, char *, int, int *, Z_AuthProc));
+Code_t Z_FormatRawHeader __P((ZNotice_t *, char*, int,
+			      int*, char **, char **));
+Code_t Z_ReadEnqueue __P((void));
+Code_t Z_ReadWait __P((void));
+Code_t Z_SendLocation __P((char*, char*, Z_AuthProc, char*));
+Code_t Z_SendFragmentedNotice __P((ZNotice_t *notice, int len,
+				   Z_AuthProc cert_func,
+				   Z_SendProc send_func));
+Code_t Z_WaitForComplete __P((void));
+Code_t Z_WaitForNotice __P((ZNotice_t *notice,
+			    int (*pred) __P((ZNotice_t *, void *)), void *arg,
+			    int timeout));
+
+#endif /* __INTERNAL_H__ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/mit-copyright.h	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,24 @@
+/*
+
+Copyright 1987,1988 by the Massachusetts Institute of Technology
+
+All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of the Massachusetts
+Institute of Technology (M.I.T.) not be used in advertising or publicity
+pertaining to distribution of the software without specific, written
+prior permission.
+
+M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/mit-sipb-copyright.h	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,19 @@
+/*
+
+Copyright 1987, 1989 by the Student Information Processing Board
+	of the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this software
+and its documentation for any purpose and without fee is
+hereby granted, provided that the above copyright notice
+appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation,
+and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+M.I.T. and the M.I.T. S.I.P.B. make no representations about
+the suitability of this software for any purpose.  It is
+provided "as is" without express or implied warranty.
+
+*/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/sysdep.h	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,197 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains system-dependent header code.
+ *
+ *	Created by:	Greg Hudson
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *	$Zephyr: /mit/zephyr/src/include/zephyr/RCS/zephyr_conf.h,v 1.8 90/12/21 17:40:40 raeburn Exp $
+ *
+ *	Copyright (c) 1988,1991 by the Massachusetts Institute of Technology.
+ *	For copying and distribution information, see the file
+ *	"mit-copyright.h". 
+ */
+
+#ifndef __SYSDEP_H__
+#define __SYSDEP_H__
+
+#include <config.h>
+#include <stdio.h>
+#include <errno.h>
+#include <ctype.h>
+#include <time.h>
+#include <signal.h>
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/time.h>
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+#else
+# ifdef HAVE_MALLOC_H
+#  include <malloc.h>
+# else
+char *malloc(), *realloc();
+# endif
+char *getenv(), *strerror(), *ctime(), *strcpy();
+time_t time();
+ZEPHYR_INT32 random();
+#endif
+
+#ifndef HAVE_RANDOM
+#ifdef HAVE_LRAND48
+#define random lrand48
+#define srandom srand48
+#else
+#define random rand
+#define srandom srand
+#endif
+#endif
+
+#ifndef HAVE_STRERROR
+extern char *sys_errlist[];
+# define strerror(x) (sys_errlist[(x)])
+#endif
+
+/* Strings. */
+#ifdef STDC_HEADERS
+# include <string.h>
+#else
+# ifndef HAVE_STRCHR
+#  define strchr index
+#  define strrchr rindex
+# endif
+char *strchr(), *strrchr();
+# ifndef HAVE_MEMCPY
+#  define memcpy(d, s, n) bcopy ((s), (d), (n))
+#  define memcmp bcmp
+# endif
+# ifndef HAVE_MEMMOVE
+#  define memmove(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+/* Exit status handling and wait(). */
+#ifdef HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#endif
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+
+/* Because we have public header files (and our prototypes need to agree with
+ * those header files, use __STDC__ to guess whether the compiler can handle
+ * stdarg, const, and prototypes. */
+#ifdef __STDC__
+# include <stdarg.h>
+# define VA_START(ap, last) va_start(ap, last)
+# ifndef __P
+#  define __P(x) x
+# endif
+#else
+# include <varargs.h>
+# define VA_START(ap, last) va_start(ap)
+# define const
+# ifndef __P
+#  define __P(x) ()
+# endif
+#endif
+
+/* openlog(). */
+#ifdef LOG_AUTH
+/* A decent syslog */
+#define OPENLOG(str, opts, facility)	openlog(str, opts, facility)
+#else
+/* Probably a 4.2-type syslog */
+#define OPENLOG(str, opts, facility)	openlog(str, opts)
+#endif
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#ifdef HAVE_PATHS_H
+# include <paths.h>
+# define TEMP_DIRECTORY _PATH_VARTMP
+#else
+# define TEMP_DIRECTORY FOUND_TMP
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#else
+# ifdef HAVE_SYS_FILE_H
+#  include <sys/file.h>
+# endif
+uid_t getuid();
+char *ttyname();
+#ifdef HAVE_GETHOSTID
+ZEPHYR_INT32 gethostid();
+#endif
+#endif
+
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+#endif
+
+#ifdef HAVE_TERMIOS_H
+# include <termios.h>
+#else
+# ifdef HAVE_SYS_FILIO_H
+#  include <sys/filio.h>
+# else
+#  ifdef HAVE_SGTTY_H
+#   include <sgtty.h>
+#  endif
+#  ifdef HAVE_SYS_IOCTL_H
+#   include <sys/ioctl.h>
+#  endif
+# endif
+#endif
+
+/* Kerberos compatibility. */
+#ifdef ZEPHYR_USES_KERBEROS
+# include <krb.h>
+# include <krb_err.h>
+# include <des.h>
+# ifndef HAVE_KRB_GET_ERR_TEXT
+#  define krb_get_err_text(n)	krb_err_txt[n]
+# endif
+# ifndef HAVE_KRB_LOG
+#  define krb_log		log
+# endif
+#endif
+
+#ifdef HAVE_SYS_UIO_H
+# include <sys/uio.h>
+#endif
+
+#ifdef HAVE_SYS_UTSNAME_H
+# include <sys/utsname.h>
+#endif
+
+#ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+#endif
+
+#ifdef HAVE_SYS_MSGBUF_H
+#include <sys/msgbuf.h>
+#endif
+
+#ifndef MSG_BSIZE
+#define MSG_BSIZE BUFSIZ
+#endif
+
+#endif /* __SYSDEP_H__ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/zephyr.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,320 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/*
+ * gaim
+ *
+ * Copyright (C) 1998-2001, Mark Spencer <markster@marko.net>
+ * Some code borrowed from GtkZephyr, by
+ * 	Jag/Sean Dilda <agrajag@linuxpower.org>/<smdilda@unity.ncsu.edu>
+ * 	http://gtkzephyr.linuxpower.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gtk/gtk.h>
+#include <string.h>
+#include "gaim.h"
+#include "prpl.h"
+#include "zephyr/zephyr.h"
+
+char *name()
+{
+	return "Zephyr";
+}
+
+char *description()
+{
+	return "Allows gaim to use the Zephyr protocol";
+}
+
+static char *zephyr_name()
+{
+	return "Zephyr";
+}
+
+#define z_call(func)		if (func != ZERR_NONE)\
+					return;
+#define z_call_r(func)		if (func != ZERR_NONE)\
+					return TRUE;
+#define z_call_s(func, err)	if (func != ZERR_NONE) {\
+					hide_login_progress(zgc, err);\
+					signoff(zgc);\
+					return;\
+				}
+
+/* this is so bad, and if Zephyr weren't so fucked up to begin with I
+ * wouldn't do this. but it is so i will. */
+static guint32 nottimer = 0;
+static guint32 loctimer = 0;
+struct gaim_connection *zgc = NULL;
+
+/* just for debugging
+static void handle_unknown(ZNotice_t notice)
+{
+	g_print("z_packet: %s\n", notice.z_packet);
+	g_print("z_version: %s\n", notice.z_version);
+	g_print("z_kind: %d\n", notice.z_kind);
+	g_print("z_class: %s\n", notice.z_class);
+	g_print("z_class_inst: %s\n", notice.z_class_inst);
+	g_print("z_opcode: %s\n", notice.z_opcode);
+	g_print("z_sender: %s\n", notice.z_sender);
+	g_print("z_recipient: %s\n", notice.z_recipient);
+	g_print("z_message: %s\n", notice.z_message);
+	g_print("z_message_len: %d\n", notice.z_message_len);
+	g_print("\n");
+}
+*/
+
+static void handle_message(ZNotice_t notice, struct sockaddr_in from)
+{
+	if (!g_strcasecmp(notice.z_class, LOGIN_CLASS)) {
+		/* well, we'll be updating in 2 seconds anyway, might as well ignore this. */
+	} else if (!g_strcasecmp(notice.z_class, LOCATE_CLASS)) {
+		if (!g_strcasecmp(notice.z_opcode, LOCATE_LOCATE)) {
+			int nlocs;
+			char *user;
+			struct buddy *b;
+
+			if (ZParseLocations(&notice, NULL, &nlocs, &user) != ZERR_NONE)
+				return;
+			if ((b = find_buddy(zgc, user)) == NULL) {
+				char *e = strchr(user, '@');
+				if (e) *e = '\0';
+				b = find_buddy(zgc, user);
+			}
+			if (!b) {
+				free(user);
+				return;
+			}
+			serv_got_update(zgc, b->name, nlocs, 0, 0, 0, 0, 0);
+
+			free(user);
+		}
+	} else if (!g_strcasecmp(notice.z_class, "MESSAGE")) {
+		char buf[BUF_LONG];
+		char *ptr = notice.z_message + strlen(notice.z_message) + 1;
+		int len = notice.z_message_len - (ptr - notice.z_message);
+		if (len > 0) {
+			g_snprintf(buf, len + 1, "%s", ptr);
+			g_strchomp(buf);
+			serv_got_im(zgc, notice.z_sender, buf, 0);
+		}
+	} else {
+		/* yes. */
+	}
+}
+
+static gint check_notify(gpointer data)
+{
+	while (ZPending()) {
+		ZNotice_t notice;
+		struct sockaddr_in from;
+		z_call_r(ZReceiveNotice(&notice, &from));
+
+		switch (notice.z_kind) {
+		case UNSAFE:
+		case UNACKED:
+		case ACKED:
+			handle_message(notice, from);
+			break;
+		default:
+			/* we'll just ignore things for now */
+			debug_printf("ZEPHYR: Unhandled Notice\n");
+			break;
+		}
+
+		ZFreeNotice(&notice);
+	}
+
+	return TRUE;
+}
+
+static gint check_loc(gpointer data)
+{
+	GSList *gr, *m;
+	ZAsyncLocateData_t ald;
+
+	ald.user = NULL;
+	memset(&(ald.uid), 0, sizeof(ZUnique_Id_t));
+	ald.version = NULL;
+
+	gr = zgc->groups;
+	while (gr) {
+		struct group *g = gr->data;
+		m = g->members;
+		while (m) {
+			struct buddy *b = m->data;
+			char *chk;
+			if (!strchr(b->name, '@'))
+				chk = g_strdup_printf("%s@%s", b->name, ZGetRealm());
+			else
+				chk = g_strdup(b->name);
+			/* doesn't matter if this fails or not; we'll just move on to the next one */
+			ZRequestLocations(chk, &ald, UNACKED, ZAUTH);
+			g_free(chk);
+			m = m->next;
+		}
+		gr = gr->next;
+	}
+
+	return TRUE;
+}
+
+static char *get_exposure_level()
+{
+	char *exposure = ZGetVariable("exposure");
+
+	if (!exposure)
+		return EXPOSE_REALMVIS;
+	if (!g_strcasecmp(exposure, EXPOSE_NONE))
+		return EXPOSE_NONE;
+	if (!g_strcasecmp(exposure, EXPOSE_OPSTAFF))
+		return EXPOSE_OPSTAFF;
+	if (!g_strcasecmp(exposure, EXPOSE_REALMANN))
+		return EXPOSE_REALMANN;
+	if (!g_strcasecmp(exposure, EXPOSE_NETVIS))
+		return EXPOSE_NETVIS;
+	if (!g_strcasecmp(exposure, EXPOSE_NETANN))
+		return EXPOSE_NETANN;
+	return EXPOSE_REALMVIS;
+}
+
+static void strip_comments(char *str)
+{
+	char *tmp = strchr(str, '#');
+	if (tmp)
+		*tmp = '\0';
+	g_strchug(str);
+	g_strchomp(str);
+}
+
+static void process_anyone()
+{
+	FILE *fd;
+	gchar buff[BUFSIZ], *filename;
+
+	filename = g_strconcat(g_get_home_dir(), "/.anyone", NULL);
+	if ((fd = fopen(filename, "r")) != NULL) {
+		while (fgets(buff, BUFSIZ, fd)) {
+			strip_comments(buff);
+			if (buff[0])
+				add_buddy(zgc, "Anyone", buff, buff);
+		}
+		fclose(fd);
+	}
+	g_free(filename);
+}
+
+static void zephyr_login(struct aim_user *user)
+{
+	ZSubscription_t sub;
+
+	if (zgc) {
+		do_error_dialog("Already logged in with Zephyr", "Zephyr");
+		return;
+	}
+
+	zgc = new_gaim_conn(user);
+
+	z_call_s(ZInitialize(), "Couldn't initialize zephyr");
+	z_call_s(ZOpenPort(NULL), "Couldn't open port");
+	z_call_s(ZSetLocation(get_exposure_level()), "Couldn't set location");
+
+	sub.zsub_class = "MESSAGE";
+	sub.zsub_classinst = "PERSONAL";
+	sub.zsub_recipient = ZGetSender();
+
+	/* we don't care if this fails. i'm lying right now. */
+	ZSubscribeTo(&sub, 1, 0);
+
+	account_online(zgc);
+	serv_finish_login(zgc);
+
+	if (bud_list_cache_exists(zgc))
+		do_import(NULL, zgc);
+	process_anyone();
+	/* should also process .zephyr.subs */
+
+	nottimer = gtk_timeout_add(100, check_notify, NULL);
+	loctimer = gtk_timeout_add(2000, check_loc, NULL);
+}
+
+static void zephyr_close(struct gaim_connection *gc)
+{
+	/* should probably write .anyone, but eh. we all use gaim exclusively, right? :-P */
+	if (nottimer)
+		gtk_timeout_remove(nottimer);
+	nottimer = 0;
+	if (loctimer)
+		gtk_timeout_remove(loctimer);
+	loctimer = 0;
+	zgc = NULL;
+	z_call(ZCancelSubscriptions(0));
+	z_call(ZUnsetLocation());
+	z_call(ZClosePort());
+}
+
+static void zephyr_add_buddy(struct gaim_connection *gc, char *buddy) { }
+static void zephyr_remove_buddy(struct gaim_connection *gc, char *buddy) { }
+
+static void zephyr_send_im(struct gaim_connection *gc, char *who, char *im, int away) {
+	ZNotice_t notice;
+
+	bzero((char *)&notice, sizeof(notice));
+	notice.z_kind = ACKED;
+	notice.z_port = 0;
+	notice.z_opcode = "";
+	notice.z_class = "MESSAGE";
+	notice.z_class_inst = "PERSONAL";
+	notice.z_sender = 0;
+	notice.z_recipient = who;
+	notice.z_default_format =
+		"Class $class, Instance $instance:\nTo: @bold($recipient) at $time $date\n$message";
+	notice.z_message_len = strlen(im) + 1;
+	notice.z_message = im;
+	ZSendNotice(&notice, ZAUTH);
+}
+
+static struct prpl *my_protocol = NULL;
+
+void zephyr_init(struct prpl *ret)
+{
+	ret->protocol = PROTO_ZEPHYR;
+	ret->name = zephyr_name;
+	ret->login = zephyr_login;
+	ret->close = zephyr_close;
+	ret->add_buddy = zephyr_add_buddy;
+	ret->remove_buddy = zephyr_remove_buddy;
+	ret->send_im = zephyr_send_im;
+
+	my_protocol = ret;
+}
+
+char *gaim_plugin_init(GModule *handle)
+{
+	load_protocol(zephyr_init, sizeof(struct prpl));
+	return NULL;
+}
+
+void gaim_plugin_remove()
+{
+	struct prpl *p = find_prpl(PROTO_ZEPHYR);
+	if (p == my_protocol)
+		unload_protocol(p);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/zephyr.h	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,342 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains global definitions
+ *
+ *	Created by:	Robert French
+ *
+ *	$Source$
+ *	$Author: warmenhoven $
+ *	$Id: zephyr.h 1710 2001-04-12 09:21:16Z warmenhoven $
+ *
+ *	Copyright (c) 1987,1988,1991 by the Massachusetts Institute of
+ *	Technology. For copying and distribution information, see the
+ *	file "mit-copyright.h".
+ */
+
+#ifndef __ZEPHYR_H__
+#define __ZEPHYR_H__
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <zephyr/zephyr_err.h>
+#ifdef ZEPHYR_USES_KERBEROS
+#include <krb.h>
+#endif
+
+#ifndef IPPROTO_MAX	/* Make sure not already included */
+#include <netinet/in.h>
+#endif
+
+/* Use __STDC__ to guess whether we can use stdarg, prototypes, and const.
+ * This is a public header file, so autoconf can't help us here. */
+#ifdef __STDC__
+# include <stdarg.h>
+# define ZP(x) x
+# define ZCONST const
+#else
+# define ZP(x) ()
+# define ZCONST
+#endif
+
+/* Service names */
+#define	HM_SVCNAME		"zephyr-hm"
+#define HM_SRV_SVCNAME		"zephyr-hm-srv"
+#define	SERVER_SVCNAME		"zephyr-clt"
+#define SERVER_SERVICE		"zephyr"
+#define SERVER_INSTANCE		"zephyr"
+
+#define ZVERSIONHDR	"ZEPH"
+#define ZVERSIONMAJOR	0
+#define ZVERSIONMINOR	2
+
+#define Z_MAXPKTLEN		1024
+#define Z_MAXHEADERLEN		800
+#define Z_MAXOTHERFIELDS	10	/* Max unknown fields in ZNotice_t */
+#define Z_NUMFIELDS		17
+
+/* Authentication levels returned by ZCheckAuthentication */
+#define ZAUTH_FAILED    	(-1)
+#define ZAUTH_YES       	1
+#define ZAUTH_NO        	0
+
+typedef char ZPacket_t[Z_MAXPKTLEN];
+
+/* Packet type */
+typedef enum {
+    UNSAFE, UNACKED, ACKED, HMACK, HMCTL, SERVACK, SERVNAK, CLIENTACK, STAT
+} ZNotice_Kind_t;
+extern ZCONST char *ZNoticeKinds[9];
+
+/* Unique ID format */
+typedef struct _ZUnique_Id_t {
+    struct	in_addr zuid_addr;
+    struct	timeval	tv;
+} ZUnique_Id_t;
+
+/* Checksum */
+typedef unsigned long ZChecksum_t;
+
+/* Notice definition */
+typedef struct _ZNotice_t {
+    char		*z_packet;
+    char		*z_version;
+    ZNotice_Kind_t	z_kind;
+    ZUnique_Id_t	z_uid;
+#define z_sender_addr	z_uid.zuid_addr
+    struct		timeval z_time;
+    unsigned short	z_port;
+    int			z_auth;
+    int			z_checked_auth;
+    int			z_authent_len;
+    char		*z_ascii_authent;
+    char		*z_class;
+    char		*z_class_inst;
+    char		*z_opcode;
+    char		*z_sender;
+    char		*z_recipient;
+    char		*z_default_format;
+    char		*z_multinotice;
+    ZUnique_Id_t	z_multiuid;
+    ZChecksum_t		z_checksum;
+    int			z_num_other_fields;
+    char		*z_other_fields[Z_MAXOTHERFIELDS];
+    caddr_t		z_message;
+    int			z_message_len;
+} ZNotice_t;
+
+/* Subscription structure */
+typedef struct _ZSubscriptions_t {
+    char	*zsub_recipient;
+    char	*zsub_class;
+    char	*zsub_classinst;
+} ZSubscription_t;
+
+/* Function return code */
+typedef int Code_t;
+
+/* Locations structure */
+typedef struct _ZLocations_t {
+    char	*host;
+    char	*time;
+    char	*tty;
+} ZLocations_t;
+
+typedef struct _ZAsyncLocateData_t {
+    char		*user;
+    ZUnique_Id_t	uid;
+    char		*version;
+} ZAsyncLocateData_t;
+
+/* for ZSetDebug */
+#ifdef Z_DEBUG
+void (*__Z_debug_print) ZP((ZCONST char *fmt, va_list args, void *closure));
+void *__Z_debug_print_closure;
+#endif
+
+int ZCompareUIDPred ZP((ZNotice_t *, void *));
+int ZCompareMultiUIDPred ZP((ZNotice_t *, void *));
+
+/* Defines for ZFormatNotice, et al. */
+typedef Code_t (*Z_AuthProc) ZP((ZNotice_t*, char *, int, int *));
+Code_t ZMakeAuthentication ZP((ZNotice_t*, char *,int, int*));
+
+char *ZGetSender ZP((void));
+char *ZGetVariable ZP((char *));
+Code_t ZSetVariable ZP((char *var, char *value));
+Code_t ZUnsetVariable ZP((char *var));
+int ZGetWGPort ZP((void));
+Code_t ZSetDestAddr ZP((struct sockaddr_in *));
+Code_t ZFormatNoticeList ZP((ZNotice_t*, char**, int,
+			     char **, int*, Z_AuthProc));
+Code_t ZParseNotice ZP((char*, int, ZNotice_t *));
+Code_t ZReadAscii ZP((char*, int, unsigned char*, int));
+Code_t ZReadAscii32 ZP((char *, int, unsigned long *));
+Code_t ZReadAscii16 ZP((char *, int, unsigned short *));
+Code_t ZSendPacket ZP((char*, int, int));
+Code_t ZSendList ZP((ZNotice_t*, char *[], int, Z_AuthProc));
+Code_t ZSrvSendList ZP((ZNotice_t*, char*[], int, Z_AuthProc, Code_t (*)()));
+Code_t ZSendNotice ZP((ZNotice_t *, Z_AuthProc));
+Code_t ZSrvSendNotice ZP((ZNotice_t*, Z_AuthProc, Code_t (*)()));
+Code_t ZFormatNotice ZP((ZNotice_t*, char**, int*, Z_AuthProc));
+Code_t ZFormatSmallNotice ZP((ZNotice_t*, ZPacket_t, int*, Z_AuthProc));
+Code_t ZFormatRawNoticeList ZP((ZNotice_t *notice, char *list[], int nitems,
+				char **buffer, int *ret_len));
+Code_t ZLocateUser ZP((char *, int *, Z_AuthProc));
+Code_t ZRequestLocations ZP((char *, ZAsyncLocateData_t *,
+			     ZNotice_Kind_t, Z_AuthProc));
+Code_t ZInitialize ZP((void));
+Code_t ZSetServerState ZP((int));
+Code_t ZSetFD ZP((int));
+Code_t ZFormatSmallRawNotice ZP((ZNotice_t*, ZPacket_t, int*));
+int ZCompareUID ZP((ZUnique_Id_t*, ZUnique_Id_t*));
+Code_t ZSrvSendRawList ZP((ZNotice_t*, char*[], int,
+			   Code_t (*)(ZNotice_t *, char *, int, int)));
+Code_t ZMakeAscii ZP((char*, int, unsigned char*, int));
+Code_t ZMakeAscii32 ZP((char *, int, unsigned long));
+Code_t ZMakeAscii16 ZP((char *, int, unsigned int));
+Code_t ZReceivePacket ZP((ZPacket_t, int*, struct sockaddr_in*));
+Code_t ZCheckAuthentication ZP((ZNotice_t*, struct sockaddr_in*));
+Code_t ZFlushMyLocations ZP((void));
+#ifdef ZEPHYR_USES_KERBEROS
+Code_t ZFormatAuthenticNotice ZP((ZNotice_t*, char*, int, int*, C_Block));
+#endif
+Code_t ZFormatRawNotice ZP((ZNotice_t *, char**, int *));
+Code_t ZRetrieveSubscriptions ZP((unsigned short, int*));
+Code_t ZOpenPort ZP((unsigned short *port));
+Code_t ZClosePort ZP((void));
+Code_t ZFlushLocations ZP((void));
+Code_t ZFlushSubscriptions ZP((void));
+Code_t ZFreeNotice ZP((ZNotice_t *notice));
+Code_t ZParseLocations ZP((register ZNotice_t *notice,
+			   register ZAsyncLocateData_t *zald, int *nlocs,
+			   char **user));
+int ZCompareALDPred ZP((ZNotice_t *notice, void *zald));
+void ZFreeALD ZP((register ZAsyncLocateData_t *zald));
+Code_t ZCheckIfNotice ZP((ZNotice_t *notice, struct sockaddr_in *from,
+			  register int (*predicate) ZP((ZNotice_t *,void *)),
+			  void *args));
+Code_t ZPeekPacket ZP((char **buffer, int *ret_len,
+		       struct sockaddr_in *from));
+Code_t ZPeekNotice ZP((ZNotice_t *notice, struct sockaddr_in *from));
+Code_t ZIfNotice ZP((ZNotice_t *notice, struct sockaddr_in *from,
+		     int (*predicate) ZP((ZNotice_t *, void *)), void *args));
+Code_t ZSubscribeTo ZP((ZSubscription_t *sublist, int nitems,
+			unsigned int port));
+Code_t ZSubscribeToSansDefaults ZP((ZSubscription_t *sublist, int nitems,
+				    unsigned int port));
+Code_t ZUnsubscribeTo ZP((ZSubscription_t *sublist, int nitems,
+			  unsigned int port));
+Code_t ZCancelSubscriptions ZP((unsigned int port));
+int ZPending ZP((void));
+Code_t ZReceiveNotice ZP((ZNotice_t *notice, struct sockaddr_in *from));
+#ifdef Z_DEBUG
+void Z_debug ZP((ZCONST char *, ...));
+#endif
+
+#undef ZP
+
+/* Compatibility */
+#define	ZNewLocateUser ZLocateUser
+
+/* Macros to retrieve Zephyr library values. */
+extern int __Zephyr_fd;
+extern int __Q_CompleteLength;
+extern struct sockaddr_in __HM_addr;
+extern char __Zephyr_realm[];
+#define ZGetFD()	__Zephyr_fd
+#define ZQLength()	__Q_CompleteLength
+#define ZGetDestAddr()	__HM_addr
+#define ZGetRealm()	__Zephyr_realm
+
+#ifdef ZEPHYR_USES_KERBEROS
+/* Session key for last parsed packet - server only */
+extern C_Block __Zephyr_session;
+#define ZGetSession() (__Zephyr_session)
+#else
+#define __Zephyr_realm ("local-realm")
+#endif
+
+
+#ifdef Z_DEBUG
+void ZSetDebug ZP((void (*)(ZCONST char *, va_list, void *), void *));
+#define ZSetDebug(proc,closure)    (__Z_debug_print=(proc), \
+				    __Z_debug_print_closure=(closure), \
+				    (void) 0)
+#else
+#define	ZSetDebug(proc,closure)
+#endif
+
+/* Maximum queue length */
+#define Z_MAXQLEN 		30
+
+/* Successful function return */
+#define ZERR_NONE		0
+
+/* Hostmanager wait time (in secs) */
+#define HM_TIMEOUT		10
+
+/* Server wait time (in secs) */
+#define	SRV_TIMEOUT		30
+
+#define ZAUTH (ZMakeAuthentication)
+#define ZNOAUTH ((Z_AuthProc)0)
+
+/* Packet strings */
+#define ZSRVACK_SENT		"SENT"	/* SERVACK codes */
+#define ZSRVACK_NOTSENT		"LOST"
+#define ZSRVACK_FAIL		"FAIL"
+
+/* Server internal class */
+#define ZEPHYR_ADMIN_CLASS	"ZEPHYR_ADMIN"	/* Class */
+
+/* Control codes sent to a server */
+#define ZEPHYR_CTL_CLASS	"ZEPHYR_CTL"	/* Class */
+
+#define ZEPHYR_CTL_CLIENT	"CLIENT"	/* Inst: From client */
+#define CLIENT_SUBSCRIBE	"SUBSCRIBE"	/* Opcode: Subscribe */
+#define CLIENT_SUBSCRIBE_NODEFS	"SUBSCRIBE_NODEFS"	/* Opcode: Subscribe */
+#define CLIENT_UNSUBSCRIBE	"UNSUBSCRIBE"	/* Opcode: Unsubsubscribe */
+#define CLIENT_CANCELSUB	"CLEARSUB"	/* Opcode: Clear all subs */
+#define CLIENT_GIMMESUBS	"GIMME"		/* Opcode: Give me subs */
+#define	CLIENT_GIMMEDEFS	"GIMMEDEFS"	/* Opcode: Give me default
+						 * subscriptions */
+
+#define ZEPHYR_CTL_HM		"HM"		/* Inst: From HM */
+#define HM_BOOT			"BOOT"		/* Opcode: Boot msg */
+#define HM_FLUSH		"FLUSH"		/* Opcode: Flush me */
+#define HM_DETACH		"DETACH"	/* Opcode: Detach me */
+#define HM_ATTACH		"ATTACH"	/* Opcode: Attach me */
+
+/* Control codes send to a HostManager */
+#define	HM_CTL_CLASS		"HM_CTL"	/* Class */
+
+#define HM_CTL_SERVER		"SERVER"	/* Inst: From server */
+#define SERVER_SHUTDOWN		"SHUTDOWN"	/* Opcode: Server shutdown */
+#define SERVER_PING		"PING"		/* Opcode: PING */
+
+#define HM_CTL_CLIENT           "CLIENT"        /* Inst: From client */
+#define CLIENT_FLUSH            "FLUSH"         /* Opcode: Send flush to srv */
+#define CLIENT_NEW_SERVER       "NEWSERV"       /* Opcode: Find new server */
+
+/* HM Statistics */
+#define HM_STAT_CLASS		"HM_STAT"	/* Class */
+
+#define HM_STAT_CLIENT		"HMST_CLIENT"	/* Inst: From client */
+#define HM_GIMMESTATS		"GIMMESTATS"	/* Opcode: get stats */
+
+/* Login class messages */
+#define LOGIN_CLASS		"LOGIN"		/* Class */
+
+/* Class Instance is principal of user who is logging in or logging out */
+
+#define EXPOSE_NONE		"NONE"		/* Opcode: Not visible */
+#define EXPOSE_OPSTAFF		"OPSTAFF"	/* Opcode: Opstaff visible */
+#define EXPOSE_REALMVIS		"REALM-VISIBLE"	/* Opcode: Realm visible */
+#define EXPOSE_REALMANN		"REALM-ANNOUNCED"/* Opcode: Realm announced */
+#define EXPOSE_NETVIS		"NET-VISIBLE"	/* Opcode: Net visible */
+#define EXPOSE_NETANN		"NET-ANNOUNCED"	/* Opcode: Net announced */
+#define	LOGIN_USER_LOGIN	"USER_LOGIN"	/* Opcode: user login
+						   (from server) */
+#define LOGIN_USER_LOGOUT	"USER_LOGOUT"	/* Opcode: User logout */
+#define	LOGIN_USER_FLUSH	"USER_FLUSH"	/* Opcode: flush all locs */
+
+/* Locate class messages */
+#define LOCATE_CLASS		"USER_LOCATE"	/* Class */
+
+#define LOCATE_HIDE		"USER_HIDE"	/* Opcode: Hide me */
+#define LOCATE_UNHIDE		"USER_UNHIDE"	/* Opcode: Unhide me */
+
+/* Class Instance is principal of user to locate */
+#define LOCATE_LOCATE		"LOCATE"	/* Opcode: Locate user */
+
+/* WG_CTL class messages */
+#define WG_CTL_CLASS		"WG_CTL"	/* Class */
+
+#define WG_CTL_USER		"USER"		/* Inst: User request */
+#define USER_REREAD		"REREAD"	/* Opcode: Reread desc file */
+#define USER_SHUTDOWN		"SHUTDOWN"	/* Opcode: Go catatonic */
+#define USER_STARTUP		"STARTUP"	/* Opcode: Come out of it */
+
+#endif /* __ZEPHYR_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/zephyr_err.c	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,60 @@
+/*
+ * zephyr_err.c:
+ * This file is automatically generated; please do not edit it.
+ */
+#ifdef __STDC__
+#define NOARGS void
+#else
+#define NOARGS
+#define const
+#endif
+
+static const char * const text[] = {
+	"Packet too long or buffer too small",
+	"Notice header too large",
+	"Illegal value in notice",
+	"Can't get host manager port",
+	"Can't assign port",
+	"Bad packet format",
+	"Incompatible version numbers",
+	"No port opened",
+	"No notices match criteria",
+	"Input queue too long",
+	"Hostmanager not responding",
+	"Internal error",
+	"No previous call to ZLocateUser",
+	"No more locations available",
+	"Field too long for buffer",
+	"Improperly formatted field",
+	"SERVNAK received",
+	"Server could not verify authentication",
+	"Not logged-in",
+	"No previous call to ZRetrieveSubscriptions",
+	"No more subscriptions available",
+	"Too many subscriptions to transmit",
+	"End of file detected during read",
+    0
+};
+
+struct error_table {
+    char const * const * msgs;
+    long base;
+    int n_msgs;
+};
+struct et_list {
+    struct et_list *next;
+    const struct error_table * table;
+};
+extern struct et_list *_et_list;
+
+static const struct error_table et = { text, -772103680L, 23 };
+
+static struct et_list link = { 0, 0 };
+
+void initialize_zeph_error_table (NOARGS) {
+    if (!link.table) {
+        link.next = _et_list;
+        link.table = &et;
+        _et_list = &link;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/zephyr/zephyr_err.h	Thu Apr 12 09:21:16 2001 +0000
@@ -0,0 +1,33 @@
+/*
+ * zephyr_err.h:
+ * This file is automatically generated; please do not edit it.
+ */
+#define ZERR_PKTLEN                              (-772103680L)
+#define ZERR_HEADERLEN                           (-772103679L)
+#define ZERR_ILLVAL                              (-772103678L)
+#define ZERR_HMPORT                              (-772103677L)
+#define ZERR_PORTINUSE                           (-772103676L)
+#define ZERR_BADPKT                              (-772103675L)
+#define ZERR_VERS                                (-772103674L)
+#define ZERR_NOPORT                              (-772103673L)
+#define ZERR_NONOTICE                            (-772103672L)
+#define ZERR_QLEN                                (-772103671L)
+#define ZERR_HMDEAD                              (-772103670L)
+#define ZERR_INTERNAL                            (-772103669L)
+#define ZERR_NOLOCATIONS                         (-772103668L)
+#define ZERR_NOMORELOCS                          (-772103667L)
+#define ZERR_FIELDLEN                            (-772103666L)
+#define ZERR_BADFIELD                            (-772103665L)
+#define ZERR_SERVNAK                             (-772103664L)
+#define ZERR_AUTHFAIL                            (-772103663L)
+#define ZERR_LOGINFAIL                           (-772103662L)
+#define ZERR_NOSUBSCRIPTIONS                     (-772103661L)
+#define ZERR_NOMORESUBSCRIPTIONS                 (-772103660L)
+#define ZERR_TOOMANYSUBS                         (-772103659L)
+#define ZERR_EOF                                 (-772103658L)
+extern void initialize_zeph_error_table ();
+#define ERROR_TABLE_BASE_zeph (-772103680L)
+
+/* for compatibility with older versions... */
+#define init_zeph_err_tbl initialize_zeph_error_table
+#define zeph_err_base ERROR_TABLE_BASE_zeph