]> asedeno.scripts.mit.edu Git - 1ts-debian.git/commitdiff
This commit was generated by cvs2svn to compensate for changes in r127,
authorhartmans <hartmans@cbed1d16-5ef5-0310-b6a1-d4a37b08ba1f>
Thu, 11 Jul 2002 23:32:11 +0000 (23:32 +0000)
committerhartmans <hartmans@cbed1d16-5ef5-0310-b6a1-d4a37b08ba1f>
Thu, 11 Jul 2002 23:32:11 +0000 (23:32 +0000)
which included commits to RCS files with non-trunk default branches.

git-svn-id: svn://svn.1ts.org/debian/trunk/zephyr@128 cbed1d16-5ef5-0310-b6a1-d4a37b08ba1f

55 files changed:
acconfig.h
clients/xzwrite/destlist.c
clients/xzwrite/interface.c
clients/xzwrite/zephyr.c
clients/zaway/zaway.c
clients/zctl/zctl.1
clients/zctl/zctl.c
clients/zctl/zctl_cmds.ct
clients/zleave/zleave.c
clients/zlocate/zlocate.c
clients/znol/znol.c
clients/zpopnotify/zpopnotify.c
clients/zstat/zstat.c
clients/zwrite/zwrite.c
h/config.h.in
lib/ZAsyncLocate.c
lib/ZCkAuth.c
lib/ZFmtAuth.c
lib/ZFmtRaw.c
lib/ZFmtRawLst.c
lib/ZFmtSmRLst.c
lib/ZFmtSmRaw.c
lib/ZGetSender.c
lib/ZInit.c
lib/ZLocations.c
lib/ZMkAuth.c
lib/ZNewLocU.c
lib/ZOpenPort.c
lib/ZParseNot.c
lib/ZReadAscii.c
lib/ZRecvNot.c
lib/ZRetSubs.c
lib/ZSetDest.c
lib/ZSubs.c
lib/zephyr_err.et
mkinstalldirs
server/bdump.c
server/class.c
server/dispatch.c
server/kstuff.c
server/subscr.c
server/uloc.c
server/version.c
zhm/queue.c
zhm/zhm.h
zhm/zhm_client.c
zhm/zhm_server.c
zwgc/X_gram.c
zwgc/file.h
zwgc/main.c
zwgc/notice.c
zwgc/subscriptions.c
zwgc/xmark.c
zwgc/xshow.c
zwgc/zephyr.c

index 96eb3d12a23a01381ad252847270c16d9aee30ac..102efca9086cbc3343311089ccfc3299b645bcf7 100644 (file)
@@ -25,3 +25,8 @@
 /* Define if `regcomp' exists and works. */
 #undef HAVE_REGCOMP
 
+/* Define if `struct sockaddr' has an `sa_len' field.  */
+#undef HAVE_SA_LEN
+
+/* Define if `resolv' libary exists and has either res_send or __res_send.  */
+#undef HAVE_LIB_RESOLV
index 862192299204c5331ad13d17ca84f783611ac5bb..1cc91e11e5220d1669a7b62842628c4eed45a588 100644 (file)
@@ -23,7 +23,7 @@ static DynObject      dests;
 extern Defaults                defs;
 
 static void get_dest_from_file(), _get_default_dest();
-static int sort_dest_func(const void *, const void *);
+static int sort_dest_func();
 
 /* A function for debugging */
 void dest_print()
@@ -366,13 +366,12 @@ void dest_add_reply(notice)
      list = dest_text();
      num = dest_num();
 
-         
-     /* A hack so local-realm is less annoying */
+     /* A hack so local-rhs is less annoying */
      {
          char *r;
 
          r = strchr(notice->z_sender, '@');
-         if (r && ! strcmp(r+1, ZGetRealm()))
+         if (r && ! strcmp(r+1, ZGetRhs(NULL)))
               *r = '\0';
      }
      
index 716e0e318420f1a8af55354890d46d7d48195c22..e218621a37017209ec7fb29f0c3d29db5609886b 100644 (file)
@@ -137,14 +137,13 @@ void build_interface(argc, argv)
 #ifdef HAVE_PUTENV
                                  strlen("XFILESEARCHPATH=") +
 #endif
-                                 strlen(DATADIR) + 12);
+                                 strlen(DATADIR) + 5);
          if (path2 != NULL) {
 #ifdef HAVE_PUTENV
-              sprintf(path2, "XFILESEARCHPATH=%s:%s/zephyr/%%N", path1,
-                      DATADIR);
+              sprintf(path2, "XFILESEARCHPATH=%s:%s/%%N", path1, DATADIR);
               putenv(path2);
 #else
-              sprintf(path2, "%s:%s/zephyr/%%N", path1, DATADIR);
+              sprintf(path2, "%s:%s/%N", path1, DATADIR);
               setenv("XFILESEARCHPATH", path2, 1);
               free(path2);
 #endif
@@ -226,7 +225,7 @@ static void Quit(w, e, p, n)
    Cardinal *n;
 {
      XtDestroyApplicationContext(app_con);
-     ZCancelSubscriptions(0);
+     ZCancelSubscriptions(NULL, 0);
      exit(0);
 }
 
index 6e25dd5c56af9991f506645183cfaefdabca64fc..1354fd115493c77787d993b15d507e0c6e27440c 100644 (file)
@@ -74,22 +74,23 @@ int zeph_locateable(user)
      int   n;
 
      if (strchr(user, '@') == NULL)
-         sprintf(buf, "%s@%s", user, ZGetRealm());
-     ZLocateUser(buf, &n, ZAUTH);
+         sprintf(buf, "%s@%s", user, ZGetRhs(NULL));
+     ZLocateUser(NULL, buf, &n, ZAUTH);
      return (!! n);
 }
 
-/* XXX This will break on interrealm zephyr */
+/* XXX This will break on intergalactic zephyr, since all these subs
+ * are done in the default galaxy. */
 void zeph_subto_logins(users, num)
    char **users;
    int num;
 {
      ZSubscription_t   *sublist;
-     char              *name, *realm;
+     char              *name, *rhs;
      int               rlen, c = 0;
 
-     realm = ZGetRealm();
-     rlen = strlen(realm);
+     rhs = ZGetRhs(NULL);
+     rlen = strlen(rhs);
      sublist = (ZSubscription_t *) Malloc(num*sizeof(ZSubscription_t),
                                          "while subscribing to logins", NULL);
 
@@ -102,12 +103,12 @@ void zeph_subto_logins(users, num)
          if (strchr(users[c], '@'))
               sprintf(name, "%s", users[c]);
          else
-              sprintf(name, "%s@%s", users[c], realm);
+              sprintf(name, "%s@%s", users[c], rhs);
          sublist[c].zsub_classinst = name;
          c += 1;
      }
 
-     ZSubscribeToSansDefaults(sublist, c, (unsigned short) 0);
+     ZSubscribeToSansDefaults(NULL, sublist, c, (unsigned short) 0);
      for(; c; --c)
          free(sublist[c-1].zsub_classinst);
      free(sublist);
@@ -121,7 +122,7 @@ void zeph_subto_replies()
      sub.zsub_classinst = "*";
      sub.zsub_recipient = ZGetSender();
 
-     ZSubscribeToSansDefaults(&sub, 1, (unsigned short) 0);
+     ZSubscribeToSansDefaults(NULL, &sub, 1, (unsigned short) 0);
 }
 
 int zeph_send_message(dest, msg)
index f3235e8fc481af1f5d62a23bfab912c596f7ebb1..418b6d13e7d1da8aa2b97a215b11332ab86a295e 100644 (file)
@@ -49,13 +49,15 @@ int main(argc,argv)
        struct passwd *pw;
        register char *ptr;
        char awayfile[BUFSIZ],*msg[2],*envptr;
-       int optchar, watch_location;
+       int optchar, watch_location, cmdline_file = 0;
        char *cmdline_msg;
        int nlocs;
        char *find_message();
 #ifdef _POSIX_VERSION
        struct sigaction sa;
 #endif
+       int i, cnt;
+       char *galaxy;
        
        if ((retval = ZInitialize()) != ZERR_NONE) {
                com_err(argv[0],retval,"while initializing");
@@ -97,9 +99,22 @@ int main(argc,argv)
                }
        }
 
-       if (argc > optind)
-               (void) strcpy(awayfile,argv[optind]);
-       else {
+       /* process or reject extra (filename) arguments */
+       if (argc > optind) {
+               if (cmdline_msg) {
+                       fprintf(stderr, "%s: Too many arguments - can't mix -m and filename\n", argv[0]);
+                       return 1;
+               } else if (argc > optind + 1) {
+                       fprintf(stderr, "%s: Too many arguments - only one filename\n", argv[0]);
+                       return 1;
+               } else {
+                       (void) strcpy(awayfile,argv[optind]);
+                       cmdline_file = 1;
+               }
+       }
+
+       /* after all that, construct the filename only if we'll need it */
+       if (!cmdline_msg && !cmdline_file) {
                envptr = getenv("HOME");
                if (envptr)
                        (void) sprintf(awayfile,"%s/.away",envptr);
@@ -112,11 +127,15 @@ int main(argc,argv)
                } 
        }
 
-       fp = fopen(awayfile,"r");
-       if (!fp && argc > optind) {
-               fprintf(stderr,"File %s not found!\n",awayfile);
-               exit(1);
-       } 
+       if (cmdline_msg) {
+               fp = NULL;
+       } else {
+               fp = fopen(awayfile,"r");
+               if (!fp && argc > optind) {
+                       fprintf(stderr,"File %s not found!\n",awayfile);
+                       exit(1);
+               }
+       }
 #ifdef _POSIX_VERSION
        (void) sigemptyset(&sa.sa_mask);
        sa.sa_flags = 0;
@@ -129,9 +148,27 @@ int main(argc,argv)
        (void) signal(SIGTERM, cleanup);
        (void) signal(SIGHUP, cleanup);
 #endif
-       if ((retval = ZSubscribeToSansDefaults(&sub,1,port)) != ZERR_NONE) {
-               com_err(argv[0],retval,"while subscribing");
-               exit(1);
+       
+       if (retval = ZGetGalaxyCount(&cnt)) {
+               com_err(argv[0], retval, "while getting galaxy count");
+           return;
+       }
+
+       for (i=0; i<cnt; i++) {
+               if (retval = ZGetGalaxyName(i, &galaxy)) {
+                       com_err(argv[0], retval, "while getting galaxy name");
+                       return;
+               }
+
+               if (((retval = ZSubscribeTo(galaxy, &sub,1,port))
+                    != ZERR_NONE)
+#ifdef HAVE_KRB4
+                   && (retval != KRBET_AD_NOTGT)
+#endif
+                   ) {
+                       com_err(argv[0],retval,"while subscribing");
+                       exit(1);
+               }
        }
 
        for (;;) {
@@ -149,7 +186,17 @@ int main(argc,argv)
                }
 
                if (watch_location) {
-                       if ((retval = ZLocateUser(ZGetSender(), &nlocs, ZNOAUTH))
+                       char *defgalaxy;
+
+                       if ((retval = ZGetGalaxyName(0, &defgalaxy))
+                           != ZERR_NONE) {
+                               com_err(argv[0],retval,
+                                       "while getting default galaxy");
+                               continue;
+                       }
+
+                       if ((retval = ZLocateUser(defgalaxy, ZGetSender(),
+                                                 &nlocs, ZNOAUTH))
                            != ZERR_NONE) {
                                com_err(argv[0],retval,"while locating self");
                                continue;
@@ -164,7 +211,7 @@ int main(argc,argv)
                }
 
                if (cmdline_msg) {
-                       ptr = malloc(strlen(cmdline_msg));
+                       ptr = malloc(strlen(cmdline_msg) + 1);
                        if (!ptr) {
                                com_err(argv[0],ENOMEM,"while getting cmdline message");
                                exit(1);
@@ -178,7 +225,7 @@ int main(argc,argv)
                        }
                }
                else {
-                       ptr = malloc(sizeof(DEFAULT_MSG)+1);
+                       ptr = malloc(sizeof(DEFAULT_MSG));
                        if (!ptr) {
                                com_err(argv[0],ENOMEM,"while getting default message");
                                exit(1);
@@ -254,6 +301,19 @@ char *find_message(notice,fp)
 
 RETSIGTYPE cleanup()
 {
-    ZCancelSubscriptions(port);
-    exit(1);
+       int i, cnt;
+       char *galaxy;
+
+       if (ZGetGalaxyCount(&cnt))
+               exit(1);
+
+       for (i=0; i<cnt; i++) {
+               if (ZGetGalaxyName(i, &galaxy))
+                       continue;
+
+               if (ZCancelSubscriptions(galaxy, port))
+                       continue;
+       }
+       
+       exit(1);
 }
index a200ffd7e9d8647ba5c761c5139aaaea115a2978..af8aaa8fbeea4f9a59b648a3864c8e65070924d4 100644 (file)
@@ -87,7 +87,7 @@ List contents of current subscriptions file or
 Any macros in the file (see below) are displayed verbatim and not expanded.
 .TP
 .B list_requests
-List all available commands.  May be abbreviated by '?'.
+List all available commands.  May be abbreviated by '?' or 'help'.
 .TP
 .B load \fR[ \fIfile\fR ]
 Subscribe to all subscription triplets and unsubscribe to all
index fc5943e5a322d9612484c23b03175ce0abdee65b..4cf17b6c4370d164e75ee0bd4d82487d7433c742 100644 (file)
@@ -3,7 +3,8 @@
  *
  *     Created by:     Robert French
  *
- *     $Id: zctl.c,v 1.31 1999/08/13 00:19:38 danw Exp $
+ *     $Source: /afs/athena/astaff/project/zephyr/attic2/repository/zephyr/clients/zctl/zctl.c,v $
+ *     $Author: marc $
  *
  *     Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
  *     For copying and distribution information, see the file
 #include <com_err.h>
 #include <pwd.h>
 #include <netdb.h>
+#include <errno.h>
 #ifndef lint
-static const char *rcsid_zctl_c = "$Id: zctl.c,v 1.31 1999/08/13 00:19:38 danw Exp $";
+static const char *rcsid_zctl_c = "$Id: zctl.c,v 1.28.4.1 1997/01/06 01:40:24 marc Exp $";
 #endif
 
-#define SUBSATONCE 7
-#define SUB 0
-#define UNSUB 1
-#define LIST 2
+#include "zutils.h"
 
 #define USERS_SUBS "/.zephyr.subs"
 #define OLD_SUBS "/.subscriptions"
 
-#define        TOKEN_HOSTNAME  "%host%"
-#define        TOKEN_CANONNAME "%canon%"
-#define        TOKEN_ME        "%me%"
-#define        TOKEN_WILD      "*"
-
-#define        ALL             0
-#define        UNSUBONLY       1
-#define        SUBONLY         2
-
 #define        ERR             (-1)
 #define        NOT_REMOVED     0
 #define        REMOVED         1
 int purge_subs();
+void add_file(char *fn, char *galaxy, short wgport, ZSubscription_t *subs,
+             int mode);
+void del_file(char *fn, char *galaxy, short wgport, ZSubscription_t *subs,
+             int mode);
+
 
 int sci_idx;
 char subsname[BUFSIZ];
-char ourhost[MAXHOSTNAMELEN],ourhostcanon[MAXHOSTNAMELEN];
 
 extern ss_request_table zctl_cmds;
 
-void add_file(), del_file(), fix_macros(), fix_macros2();
-
 main(argc,argv)
        int argc;
        char *argv[];
 {
        struct passwd *pwd;
-       struct hostent *hent;
        char ssline[BUFSIZ],oldsubsname[BUFSIZ],*envptr,*tty = NULL;
        int retval,code,i;
 #ifdef HAVE_SYS_UTSNAME
@@ -101,24 +92,6 @@ main(argc,argv)
                }
        }
 
-#ifdef HAVE_SYS_UTSNAME
-       uname(&name);
-       strcpy(ourhost, name.nodename);
-#else
-       if (gethostname(ourhost,MAXHOSTNAMELEN) == -1) {
-               com_err(argv[0],errno,"while getting host name");
-               exit (1);
-       }
-#endif
-
-       if (!(hent = gethostbyname(ourhost))) {
-               fprintf(stderr,"%s: Can't resolve hostname %s; %s may be "
-                       "wrong in subscriptions",argv[0],ourhost,
-                       TOKEN_CANONNAME);
-               strncpy(ourhostcanon,ourhost,sizeof(ourhostcanon)-1);
-       } else
-               strncpy(ourhostcanon,hent->h_name,sizeof(ourhostcanon)-1);
-
        sci_idx = ss_create_invocation("zctl","",0,&zctl_cmds,&code);
        if (code) {
                ss_perror(sci_idx,code,"while creating invocation");
@@ -137,11 +110,11 @@ main(argc,argv)
                exit((code != 0));
        } 
 
-       printf("ZCTL $Revision: 1.31 $ (Protocol %s%d.%d) - Type '?' for a list of commands.\n\n",
+       printf("ZCTL $Revision: 1.28.4.1 $ (Protocol %s%d.%d) - Type '?' for a list of commands.\n\n",
               ZVERSIONHDR,
-              ZVERSIONMAJOR,ZVERSIONMINOR);
+              ZVERSIONMAJOR,ZVERSIONMINOR_GALAXY);
        
-       ss_listen(sci_idx);
+       code = ss_listen(sci_idx);
        exit(0);
 }
 
@@ -166,113 +139,136 @@ flush_locations(argc,argv)
        int argc;
        char *argv[];
 {
-       int retval;
+    int retval;
+    char *galaxy;
+    int cnt, i;
        
-       if (argc > 1) {
-               fprintf(stderr,"Usage: %s\n",argv[0]);
-               return;
+    if (argc > 2) {
+       fprintf(stderr,"Usage: %s [galaxy]\n",argv[0]);
+       return;
+    }
+
+    galaxy = (argc > 1)?argv[1]:NULL;
+
+    if (galaxy && strcmp(galaxy, "*") == 0) {
+       if (retval = ZGetGalaxyCount(&cnt)) {
+           ss_perror(sci_idx, retval, "while getting galaxy count");
+           return;
        }
 
-       if ((retval = ZFlushMyLocations()) != ZERR_NONE)
-               ss_perror(sci_idx,retval,"while flushing locations");
+       for (i=0; i<cnt; i++) {
+           if (retval = ZGetGalaxyName(i, &galaxy)) {
+               ss_perror(sci_idx, retval, "while getting galaxy name");
+               return;
+           }
+
+           if ((retval = ZFlushMyLocations(galaxy)) != ZERR_NONE) {
+               ss_perror(sci_idx, retval, "while flushing locations");
+               return;
+           }
+       }
+    } else {
+       if ((retval = ZFlushMyLocations(galaxy)) != ZERR_NONE) {
+           ss_perror(sci_idx, retval, "while flushing locations");
+           return;
+       }
+    }
 }
 
 void
 wgc_control(argc,argv)
        int argc;
-       register char **argv;
+       char *argv[];
 {
-       int retval;
-       short newport;
-       struct sockaddr_in newsin;
-       ZNotice_t notice;
-
-       newsin = ZGetDestAddr();
+       Code_t retval;
 
        if (argc > 1) {
                fprintf(stderr,"Usage: %s\n",argv[0]);
                return;
        }
-       
-       if ((newport = ZGetWGPort()) == -1) {
-               ss_perror(sci_idx,errno,"while getting WindowGram port");
-               return;
-       }
 
-       newsin.sin_port = (u_short) newport;
-       if ((retval = ZSetDestAddr(&newsin)) != ZERR_NONE) {
-               ss_perror(sci_idx,retval,"while setting destination address");
-               return;
-       }
-
-       (void) memset((char *)&notice, 0, sizeof(notice));
-       notice.z_kind = UNSAFE;
-       notice.z_port = 0;
-       notice.z_class = WG_CTL_CLASS;
-       notice.z_class_inst = WG_CTL_USER;
-
-       if (!strcmp(argv[0],"wg_read"))
-               notice.z_opcode = USER_REREAD;
-       if (!strcmp(argv[0],"wg_shutdown"))
-               notice.z_opcode = USER_SHUTDOWN;
-       if (!strcmp(argv[0],"wg_startup"))
-               notice.z_opcode = USER_STARTUP;
-       if (!strcmp(argv[0],"wg_exit"))
-               notice.z_opcode = USER_EXIT;
-       if (!notice.z_opcode) {
+       if (!strcmp(argv[0],"wg_read")) {
+               retval = send_wgc_control(USER_REREAD, NULL, 0);
+       } else if (!strcmp(argv[0],"wg_shutdown")) {
+               retval = send_wgc_control(USER_SHUTDOWN, NULL, 0);
+       } else if (!strcmp(argv[0],"wg_startup")) {
+               retval = send_wgc_control(USER_STARTUP, NULL, 0);
+       } else if (!strcmp(argv[0],"wg_exit")) {
+               retval = send_wgc_control(USER_EXIT, NULL, 0);
+       } else {
                fprintf(stderr,
                        "unknown WindowGram client control command %s\n",
                        argv[0]);
                return;
        }
-       notice.z_sender = 0;
-       notice.z_recipient = "";
-       notice.z_default_format = "";
-       notice.z_message_len = 0;
-
-       if ((retval = ZSendNotice(&notice,ZNOAUTH)) != ZERR_NONE)
-               ss_perror(sci_idx,retval,"while sending notice");
 
-       if ((retval = ZInitialize()) != ZERR_NONE)
-               ss_perror(sci_idx,retval,
-                         "while reinitializing");
-} 
+       if (retval)
+               ss_perror(sci_idx, retval,
+                         "while sending WindowGram control message");
+}
 
 void
 hm_control(argc,argv)
        int argc;
        char *argv[];
 {
-       int retval;
-       ZNotice_t notice;
+    int retval;
+    ZNotice_t notice;
+    char *galaxy;
+    int cnt, i;
 
-       if (argc > 1) {
-               fprintf(stderr,"Usage: %s\n",argv[0]);
-               return;
-       }
+    if (argc > 2) {
+       fprintf(stderr,"Usage: %s [galaxy]\n",argv[0]);
+       return;
+    }
        
-       (void) memset((char *)&notice, 0, sizeof(notice));
-       notice.z_kind = HMCTL;
-       notice.z_port = 0;
-       notice.z_class = HM_CTL_CLASS;
-       notice.z_class_inst = HM_CTL_CLIENT;
-
-       if (!strcmp(argv[0],"hm_flush"))
-               notice.z_opcode = CLIENT_FLUSH;
-       if (!strcmp(argv[0],"new_server"))
-               notice.z_opcode = CLIENT_NEW_SERVER;
-       if (!notice.z_opcode) {
-               fprintf(stderr, "unknown HostManager control command %s\n",
-                       argv[0]);
-               return;
+    galaxy = (argc > 1)?argv[1]:NULL;
+
+    (void) memset((char *)&notice, 0, sizeof(notice));
+    notice.z_kind = HMCTL;
+    notice.z_port = 0;
+    notice.z_class = HM_CTL_CLASS;
+    notice.z_class_inst = HM_CTL_CLIENT;
+
+    if (!strcmp(argv[0],"hm_flush"))
+       notice.z_opcode = CLIENT_FLUSH;
+    if (!strcmp(argv[0],"new_server"))
+       notice.z_opcode = CLIENT_NEW_SERVER;
+    if (!notice.z_opcode) {
+       fprintf(stderr, "unknown HostManager control command %s\n",
+               argv[0]);
+       return;
+    }
+    notice.z_sender = 0;
+    notice.z_recipient = "";
+    notice.z_default_format = "";
+    notice.z_message_len = 0;
+
+    if (galaxy && strcmp(galaxy, "*") == 0) {
+       if (retval = ZGetGalaxyCount(&cnt)) {
+           ss_perror(sci_idx, retval, "while getting galaxy count");
+           return;
        }
-       notice.z_sender = 0;
-       notice.z_recipient = "";
-       notice.z_default_format = "";
-       notice.z_message_len = 0;
 
-       if ((retval = ZSendNotice(&notice,ZNOAUTH)) != ZERR_NONE)
+       for (i=0; i<cnt; i++) {
+           if (retval = ZGetGalaxyName(i, &galaxy)) {
+               ss_perror(sci_idx, retval, "while getting galaxy name");
+               return;
+           }
+
+           notice.z_dest_galaxy = galaxy;
+
+           if ((retval = ZSendNotice(&notice,ZNOAUTH)) != ZERR_NONE) {
                ss_perror(sci_idx,retval,"while sending notice");
+               return;
+           }
+       }
+    } else {
+       if ((retval = ZSendNotice(&notice,ZNOAUTH)) != ZERR_NONE) {
+           ss_perror(sci_idx,retval,"while sending notice");
+           return;
+       }
+    }
 } 
 
 void
@@ -302,79 +298,55 @@ set_var(argc,argv)
        int argc;
        register char **argv;
 {
-       int retval,setting_exp,i;
-       char *exp_level,*newargv[1];
-       char varcat[BUFSIZ];
+    int retval,setting_exp,i;
+    char *galaxy;
+    char varcat[BUFSIZ];
        
-       if (argc < 2) {
-               fprintf(stderr,"Usage: %s <varname> [value]\n",
-                       argv[0]);
-               return;
-       }
-
-       setting_exp = 0;
-
-       if (!strcasecmp(argv[1],"exposure")) {
-               setting_exp = 1;
-               if (argc != 3) {
-                       fprintf(stderr,"An exposure setting must be specified.\n");
-                       return;
-               }
-               exp_level = (char *)0;
-               if (!strcasecmp(argv[2],EXPOSE_NONE))
-                       exp_level = EXPOSE_NONE;
-               if (!strcasecmp(argv[2],EXPOSE_OPSTAFF))
-                       exp_level = EXPOSE_OPSTAFF;
-               if (!strcasecmp(argv[2],EXPOSE_REALMVIS))
-                       exp_level = EXPOSE_REALMVIS;
-               if (!strcasecmp(argv[2],EXPOSE_REALMANN))
-                       exp_level = EXPOSE_REALMANN;
-               if (!strcasecmp(argv[2],EXPOSE_NETVIS))
-                       exp_level = EXPOSE_NETVIS;
-               if (!strcasecmp(argv[2],EXPOSE_NETANN))
-                       exp_level = EXPOSE_NETANN;
-               if (!exp_level) {
-                       fprintf(stderr,"The exposure setting must be one of:\n");
-                       fprintf(stderr,"%s, %s, %s, %s, %s, %s.\n",
-                               EXPOSE_NONE,
-                               EXPOSE_OPSTAFF,
-                               EXPOSE_REALMVIS,
-                               EXPOSE_REALMANN,
-                               EXPOSE_NETVIS,
-                               EXPOSE_NETANN);
-                       return;
-               }
-       } 
-       if (argc == 2)
-               retval = ZSetVariable(argv[1],"");
-       else {
-               (void) strcpy(varcat,argv[2]);
-               for (i=3;i<argc;i++) {
-                       (void) strcat(varcat," ");
-                       (void) strcat(varcat,argv[i]);
-               } 
-               retval = ZSetVariable(argv[1],varcat);
+    if (argc < 2) {
+       fprintf(stderr,"Usage: %s <varname> [value]\n",
+               argv[0]);
+       return;
+    }
+
+    setting_exp = 0;
+
+    if (strncasecmp(argv[1],"exposure",8) == 0) {
+       setting_exp = 1;
+       if (argc != 3) {
+           fprintf(stderr, "An exposure setting must be specified.\n");
+           return;
+       }
+       if (strlen(argv[1]) == 8) {
+           galaxy = NULL; /* the default */
+       } else if ((strlen(argv[1]) == 9) ||
+                  (ZGetRhs(argv[1]+9) == NULL)) {
+           fprintf(stderr, "The exposure variable's galaxy name was empty or invalid.\nUse a variable of the form exposure-GALAXYNAME.\n");
+           return;
+       } else {
+           galaxy = argv[1]+9;
+       }
+    } 
+
+    if (argc == 2)
+       retval = ZSetVariable(argv[1],"");
+    else {
+       (void) strcpy(varcat,argv[2]);
+       for (i=3;i<argc;i++) {
+           (void) strcat(varcat," ");
+           (void) strcat(varcat,argv[i]);
        } 
+       retval = ZSetVariable(argv[1],varcat);
+    } 
 
-       if (retval != ZERR_NONE) {
-               ss_perror(sci_idx,retval,"while setting variable value");
-               return;
-       }
+    if (retval != ZERR_NONE) {
+       ss_perror(sci_idx,retval,"while setting variable value");
+       return;
+    }
 
-       /* Side-effects?  Naw, us? */
+    /* Side-effects?  Naw, us? */
        
-       if (setting_exp) {
-               if ((retval = ZSetLocation(exp_level)) != ZERR_NONE)
-                       ss_perror(sci_idx,retval,"while changing exposure status");
-               if (!strcmp(exp_level,EXPOSE_NONE)) {
-                       newargv[0] = "wg_shutdown";
-                       wgc_control(1,newargv);
-               } else {
-                       newargv[0] = "wg_startup";
-                       wgc_control(1,newargv);
-               }
-               return;
-       } 
+    if (setting_exp)
+       set_exposure(galaxy?galaxy:"*", argv[2]);
 }
 
 void
@@ -382,20 +354,32 @@ do_hide(argc,argv)
        int argc;
        char *argv[];
 {
-       char *exp_level = NULL;
-       Code_t retval;
+    char *exp_level;
+    char *galaxy;
+    int cnt, i;
+    Code_t code;
 
-       if (argc != 1) {
-               fprintf(stderr, "Usage: %s\n",argv[0]);
-               return;
-       }
-       if (!strcmp(argv[0],"unhide"))
-               exp_level = EXPOSE_REALMVIS;
-       else
-               exp_level = EXPOSE_OPSTAFF;
-       if ((retval = ZSetLocation(exp_level)) != ZERR_NONE)
-               ss_perror(sci_idx,retval,"while changing exposure status");
+    if (argc > 2) {
+       fprintf(stderr, "Usage: %s [galaxy]\n",argv[0]);
        return;
+    }
+
+    if (strcmp(argv[0], "unhide") == 0) {
+       exp_level = ZGetVariable("exposure");
+       if (exp_level)
+           exp_level = ZParseExposureLevel(exp_level);
+       if (!exp_level)
+           exp_level = EXPOSE_REALMVIS;
+    } else {
+       exp_level = EXPOSE_OPSTAFF;
+    }
+
+    galaxy = (argc > 1)?argv[1]:NULL;
+
+    if (code = set_exposure(galaxy, exp_level)) {
+       ss_perror(sci_idx, code, "while setting exposures");
+       return;
+    }
 }
 
 void
@@ -416,26 +400,54 @@ unset_var(argc,argv)
                        ss_perror(sci_idx,retval,
                                  "while unsetting variable value");
 }
-
+       
 void
 cancel_subs(argc,argv)
        int argc;
        char *argv[];
 {
-       int retval;
-       short wgport;
+    int retval;
+    short wgport;
+    int i, cnt;
+    char *galaxy;
 
-       if (argc != 1) {
-               fprintf(stderr,"Usage: %s\n",argv[0]);
-               return;
-       } 
+    if (argc > 2) {
+       fprintf(stderr,"Usage: %s [galaxy]\n",argv[0]);
+       return;
+    }
 
-       if ((wgport = ZGetWGPort()) == -1) {
-               ss_perror(sci_idx,errno,"while finding WindowGram port");
+    if ((wgport = ZGetWGPort()) == -1) {
+       ss_perror(sci_idx,errno,"while finding WindowGram port");
+       return;
+    } 
+
+    galaxy = (argc > 1)?argv[1]:NULL;
+
+    if (galaxy && strcmp(galaxy, "*") == 0) {
+       if (retval = ZGetGalaxyCount(&cnt)) {
+           ss_perror(sci_idx, retval, "while getting galaxy count");
+           return;
+       }
+
+       for (i=0; i<cnt; i++) {
+           if (retval = ZGetGalaxyName(i, &galaxy)) {
+               ss_perror(sci_idx, retval, "while getting galaxy name");
                return;
-       } 
-       if ((retval = ZCancelSubscriptions((u_short)wgport)) != ZERR_NONE)
+           }
+
+           if ((retval = ZCancelSubscriptions(galaxy, (u_short)wgport))
+               != ZERR_NONE) {
                ss_perror(sci_idx,retval,"while cancelling subscriptions");
+               return;
+           }
+       }
+    } else {
+       if ((retval = ZCancelSubscriptions(galaxy, (u_short)wgport))
+           != ZERR_NONE) {
+           ss_perror(sci_idx,retval,"while cancelling subscriptions");
+           return;
+       }
+    }
 }
 
 void
@@ -446,15 +458,35 @@ subscribe(argc,argv)
        int retval;
        short wgport;
        ZSubscription_t sub,sub2;
+       char *galaxy;
+       int mode;
        
-       if (argc > 4 || argc < 3) {
-               fprintf(stderr,"Usage: %s class instance [*]\n",argv[0]);
+       if (argc > 5 || argc < 3) {
+               fprintf(stderr,"Usage: %s class instance [* [galaxy]]\n",
+                       argv[0]);
                return;
        }
        
+       if (strncmp(argv[0], "sub", 3) == 0) {
+               mode = SUB;
+       } else if (strncmp(argv[0], "unsub", 5) == 0) {
+               mode = UNSUB;
+       } else if ((strncmp(argv[0], "punt", 4) == 0) ||
+                  (strncmp(argv[0], "sup", 3) == 0)) {
+               mode = PUNT;
+       } else if ((strncmp(argv[0], "unpunt", 6) == 0) ||
+                  (strncmp(argv[0], "unsup", 5) == 0)) {
+               mode = UNPUNT;
+       } else {
+               ss_perror(sci_idx, 0, "internal error in subscribe");
+               exit(1);
+       }
+
        sub.zsub_class = argv[1];
        sub.zsub_classinst = argv[2];
-       sub.zsub_recipient = (argc == 3)?ZGetSender():argv[3];
+       sub.zsub_recipient = (argc > 3)?argv[3]:
+               (((mode == PUNT) || (mode == UNPUNT))?"":ZGetSender());
+       galaxy = (argc > 4)?argv[4]:NULL;
 
        fix_macros(&sub,&sub2,1);
        
@@ -463,11 +495,26 @@ subscribe(argc,argv)
                return;
        } 
 
-       retval = (*argv[0] == 's') ? ZSubscribeTo(&sub2,1,(u_short)wgport) :
-               ZUnsubscribeTo(&sub2,1,(u_short)wgport);
-       
-       if (retval != ZERR_NONE)
-               ss_perror(sci_idx,retval,"while subscribing");
+       switch (mode) {
+       case SUB:
+               if (retval = ZSubscribeTo(galaxy, &sub2, 1, (u_short) wgport))
+                       ss_perror(sci_idx, retval, "while subscribing");
+               break;
+       case UNSUB:
+               if (retval = ZUnsubscribeTo(galaxy, &sub2, 1, (u_short) wgport))
+                       ss_perror(sci_idx, retval, "while subscribing");
+               break;
+       case PUNT:
+               if (retval = xpunt(sub2.zsub_class, sub2.zsub_classinst,
+                                 sub2.zsub_recipient, PUNT))
+                       ss_perror(sci_idx, retval, "while suppressing");
+               break;
+       case UNPUNT:
+               if (retval = xpunt(sub2.zsub_class, sub2.zsub_classinst,
+                                   sub2.zsub_recipient, UNPUNT))
+                       ss_perror(sci_idx, retval, "while unsuppressing");
+               break;
+       }
 } 
 
 void
@@ -477,69 +524,145 @@ sub_file(argc,argv)
 {
        ZSubscription_t sub;
        short wgport;
+       char fn[MAXPATHLEN];
+       char *arggalaxy, *galaxy;
+       int cnt, i;
+       Code_t retval;
+       int del, mode;
 
-       if (argc > 4 || argc < 3) {
-               fprintf(stderr,"Usage: %s class instance [*]\n",argv[0]);
+       if (argc > 5 || argc < 3) {
+               fprintf(stderr,"Usage: %s class instance [* [galaxy]]\n",
+                       argv[0]);
                return;
        }
 
+       if (!strcmp(argv[0],"add")) {
+               del = 0;
+               mode = SUB;
+       } else if (!strcmp(argv[0],"add_unsubscription") ||
+                  !strcmp(argv[0],"add_un")) {
+               del = 0;
+               mode = UNSUB;
+       } else if (!strcmp(argv[0],"add_suppression") ||
+                  !strcmp(argv[0],"add_punt")) {
+               del = 0;
+               mode = PUNT;
+       } else if (!strcmp(argv[0],"delete") ||
+                  !strcmp(argv[0],"del") ||
+                  !strcmp(argv[0],"dl")) {
+               del = 1;
+               mode = SUB;
+       } else if (!strcmp(argv[0],"delete_unsubscription") ||
+                  !strcmp(argv[0],"del_un")) {
+               del = 1;
+               mode = UNSUB;
+       } else if (!strcmp(argv[0],"delete_suppression") ||
+                  !strcmp(argv[0],"del_punt")) {
+               del = 1;
+               mode = PUNT;
+       } else {
+               ss_perror(sci_idx,0,"unknown command name");
+       }
+
        if (argv[1][0] == '!') {
-               ss_perror(sci_idx,0,
-                         (!strcmp(argv[0],"add_unsubscription") ||
-                          !strcmp(argv[0],"add_un") ||
-                          !strcmp(argv[0],"delete_unsubscription") ||
-                          !strcmp(argv[0],"del_un")) ?
+               ss_perror(sci_idx,0, (mode == UNSUB)?
                          "Do not use `!' as the first character of a class.\n\tIt is automatically added before modifying the subscription file." :
                          "Do not use `!' as the first character of a class.\n\tIt is reserved for internal use with un-subscriptions.");
                return;
+       } else if (argv[1][0] == '-') {
+               ss_perror(sci_idx,0, (mode == PUNT)?
+                         "Do not use `-' as the first character of a class.\n\tIt is automatically added before modifying the subscription file." :
+                         "Do not use `-' as the first character of a class.\n\tIt is reserved for internal use with suppressions.");
+               return;
        }
+
        sub.zsub_class = argv[1];
        sub.zsub_classinst = argv[2];
-       sub.zsub_recipient = (argc == 3)?TOKEN_ME:argv[3];
+       sub.zsub_recipient = (argc > 3)?argv[3]:
+               (((mode == PUNT) || (mode == UNPUNT))?"":TOKEN_ME);
+       arggalaxy = (argc > 4)?argv[4]:NULL;
+
+       if (arggalaxy) {
+           if (retval = ZGetGalaxyCount(&cnt)) {
+               ss_perror(sci_idx, retval, "while getting galaxy count");
+               return;
+           }
+
+           for (i=0; i<cnt; i++) {
+               if (retval = ZGetGalaxyName(i, &galaxy)) {
+                   ss_perror(sci_idx, retval, "while getting galaxy name");
+                   return;
+               }
+
+               if (strcasecmp(galaxy, arggalaxy) == 0)
+                   break;
+           }
 
-       if (make_exist(subsname))
+           if (i == cnt) {
+               ss_perror(sci_idx, 0,
+                         "unknown galaxy specified while modifying subscripion file");
                return;
+           }
+       } else {
+           galaxy = ZGetDefaultGalaxy();
+       }
+
        if ((wgport = ZGetWGPort()) == -1) {
                ss_perror(sci_idx,errno,"while finding WindowGram port");
                return;
        } 
 
-       if (!strcmp(argv[0],"add"))
-               add_file(wgport,&sub,0);
-       else if (!strcmp(argv[0],"add_unsubscription") ||
-                !strcmp(argv[0],"add_un"))
-               add_file(wgport,&sub,1);
-       else if (!strcmp(argv[0],"delete") ||
-                !strcmp(argv[0],"del") ||
-                !strcmp(argv[0],"dl"))
-               del_file(wgport,&sub,0);
-       else if (!strcmp(argv[0],"delete_unsubscription") ||
-                !strcmp(argv[0],"del_un")) {
-               del_file(wgport,&sub,1);
-       } else
+       strcpy(fn, subsname);
+       strcat(fn, "-");
+       strcat(fn, galaxy);
+
+       if (!strcmp(argv[0],"add")) {
+               add_file(fn, galaxy, wgport, &sub, SUB);
+       } else if (!strcmp(argv[0],"add_unsubscription") ||
+                  !strcmp(argv[0],"add_un")) {
+               add_file(fn, galaxy, wgport, &sub, UNSUB);
+       } else if (!strcmp(argv[0],"add_suppression") ||
+                  !strcmp(argv[0],"add_punt")) {
+               add_file(fn, galaxy, wgport, &sub, PUNT);
+       } else if (!strcmp(argv[0],"delete") ||
+                  !strcmp(argv[0],"del") ||
+                  !strcmp(argv[0],"dl")) {
+               del_file(fn, galaxy, wgport, &sub, SUB);
+       } else if (!strcmp(argv[0],"delete_unsubscription") ||
+                  !strcmp(argv[0],"del_un")) {
+               del_file(fn, galaxy, wgport, &sub, UNSUB);
+       } else if (!strcmp(argv[0],"delete_suppression") ||
+                  !strcmp(argv[0],"del_punt")) {
+               del_file(fn, galaxy, wgport, &sub, PUNT);
+       } else {
                ss_perror(sci_idx,0,"unknown command name");
+       }
        return;
 }
 
 void
-add_file(wgport,subs,unsub)
-short wgport;
-ZSubscription_t *subs;
-int unsub;
+add_file(fn,galaxy,wgport,subs,mode)
+     char *fn;
+     char *galaxy;
+     short wgport;
+     ZSubscription_t *subs;
+     int mode;
 {
        FILE *fp;
        char errbuf[BUFSIZ];
        ZSubscription_t sub2;
        Code_t retval;
 
-       (void) purge_subs(subs,ALL);    /* remove copies in the subs file */
-       if (!(fp = fopen(subsname,"a"))) {
-               (void) sprintf(errbuf,"while opening %s for append",subsname);
+       (void) purge_subs(fn,subs,ALL); /* remove copies in the subs file */
+       if (!(fp = fopen(fn,"a"))) {
+               (void) sprintf(errbuf,"while opening %s for append", fn);
                ss_perror(sci_idx,errno,errbuf);
                return;
        } 
        fprintf(fp,"%s%s,%s,%s\n",
-               unsub ? "!" : "",
+               ((mode == UNSUB) ? "!" : 
+                ((mode == PUNT) ? "*" :
+                 "")),
                subs->zsub_class, subs->zsub_classinst, subs->zsub_recipient);
        if (fclose(fp) == EOF) {
                (void) sprintf(errbuf, "while closing %s", subsname);
@@ -547,53 +670,70 @@ int unsub;
                return;
        }
        fix_macros(subs,&sub2,1);
-       if (retval = (unsub ? ZUnsubscribeTo(&sub2,1,(u_short)wgport) :
-                      ZSubscribeTo(&sub2,1,(u_short)wgport)))
-               ss_perror(sci_idx,retval,
-                         unsub ? "while unsubscribing" :
-                         "while subscribing");
+       if (mode == UNSUB) {
+               if (retval = ZUnsubscribeTo(galaxy, &sub2,1,(u_short)wgport))
+                       ss_perror(sci_idx, retval, "while subscribing");
+       } else if (mode == PUNT) {
+               if (retval = xpunt(sub2.zsub_class, sub2.zsub_classinst,
+                                 sub2.zsub_recipient, PUNT))
+                       ss_perror(sci_idx, retval, "while unsubscribing");
+       } else {
+               if (retval = ZSubscribeTo(galaxy, &sub2,1,(u_short)wgport))
+                       ss_perror(sci_idx, retval, "while suppressing");
+       }
+
        return;
 }
 
 void
-del_file(wgport,subs,unsub)
-short wgport;
-register ZSubscription_t *subs;
-int unsub;
+del_file(fn,galaxy,wgport,subs,mode)
+     char *fn;
+     char *galaxy;
+     short wgport;
+     ZSubscription_t *subs;
+     int mode;
 {
        ZSubscription_t sub2;
        int retval;
        
-       retval = purge_subs(subs, unsub ? UNSUBONLY : SUBONLY);
+       retval = purge_subs(fn, subs, mode);
        if (retval == ERR)
                return;
        if (retval == NOT_REMOVED)
                fprintf(stderr,
                        "Couldn't find %sclass %s instance %s recipient %s in\n\tfile %s\n",
-                       unsub ? "un-subscription " : "",
+                       ((mode == UNSUB) ? "un-subscription " : 
+                        ((mode == PUNT) ? "suppression " :
+                         "")),
                        subs->zsub_class, subs->zsub_classinst,
                        subs->zsub_recipient, subsname);
        fix_macros(subs,&sub2,1);
-       if ((retval = ZUnsubscribeTo(&sub2,1,(u_short)wgport)) !=
-           ZERR_NONE)
+       if (mode == PUNT) {
+               if (retval = xpunt(sub2.zsub_class, sub2.zsub_classinst,
+                                   sub2.zsub_recipient, UNPUNT))
+                       ss_perror(sci_idx,retval,"while unsuppressing");
+       } else if ((retval = ZUnsubscribeTo(galaxy, &sub2,1,(u_short)wgport)) !=
+                  ZERR_NONE) {
                ss_perror(sci_idx,retval,"while unsubscribing");
-       return;
+       }
 }
 
 int
-purge_subs(subs,which)
-register ZSubscription_t *subs;
-int which;
+purge_subs(fn, subs, mode)
+     char *fn;
+     register ZSubscription_t *subs;
+     int mode;
 {
        FILE *fp,*fpout;
        char errbuf[BUFSIZ],subline[BUFSIZ];
        char backup[BUFSIZ],ourline[BUFSIZ];
        int delflag = NOT_REMOVED;
-       int keep;
+       int purge;
 
-       switch (which) {
-       case SUBONLY:
-       case UNSUBONLY:
+       switch (mode) {
+       case SUB:
+       case UNSUB:
+       case PUNT:
        case ALL:
                break;
        default:
@@ -606,12 +746,16 @@ int which;
                       subs->zsub_classinst,
                       subs->zsub_recipient);
 
-       if (!(fp = fopen(subsname,"r"))) {
-               (void) sprintf(errbuf,"while opening %s for read",subsname);
+       if (!(fp = fopen(fn,"r"))) {
+               if (errno == ENOENT)
+                       /* if the filw doesn't exist, then the sub
+                          is clearly purged */
+                       return(delflag);
+               (void) sprintf(errbuf,"while opening %s for read", fn);
                ss_perror(sci_idx,errno,errbuf);
                return(ERR);
        } 
-       (void) strcpy(backup, subsname);
+       (void) strcpy(backup, fn);
        (void) strcat(backup, ".temp");
        (void) unlink(backup);
        if (!(fpout = fopen(backup,"w"))) {
@@ -625,28 +769,34 @@ int which;
                        break;
                if (*subline)
                        subline[strlen(subline)-1] = '\0'; /* nuke newline */
-               switch (which) {
-               case SUBONLY:
-                       keep = strcmp(subline,ourline);
+               switch (mode) {
+               case SUB:
+                       purge = (strcmp(subline,ourline) == 0);
                        break;
-               case UNSUBONLY:
-                       keep = (*subline != '!' || strcmp(subline+1,ourline));
+               case UNSUB:
+                       purge = (*subline == '!' &&
+                                (strcmp(subline+1,ourline) == 0));
+                       break;
+               case PUNT:
+                       purge = (*subline == '-' &&
+                                (strcmp(subline+1,ourline) == 0));
                        break;
                case ALL:
-                       keep = (strcmp(subline,ourline) &&
-                               (*subline != '!' || strcmp(subline+1,
-                                                          ourline)));
+                       purge = ((strcmp(subline,ourline) == 0) ||
+                                (((*subline == '!') || (*subline == '-')) &&
+                                 (strcmp(subline+1, ourline) == 0)));
                        break;
                }
-               if (keep) {
+               if (purge) {
+                       delflag = REMOVED;
+               } else {
                        fputs(subline, fpout);
                        if (ferror(fpout) || (fputc('\n', fpout) == EOF)) {
                                (void) sprintf(errbuf, "while writing to %s",
                                               backup);
                                ss_perror(sci_idx, errno, errbuf);
                        }
-               } else
-                       delflag = REMOVED;
+               }
        }
        (void) fclose(fp);              /* open read-only, ignore errs */
        if (fclose(fpout) == EOF) {
@@ -654,9 +804,9 @@ int which;
                ss_perror(sci_idx, errno, errbuf);
                return(ERR);
        }
-       if (rename(backup,subsname) == -1) {
+       if (rename(backup, fn) == -1) {
                (void) sprintf(errbuf,"while renaming %s to %s\n",
-                              backup,subsname);
+                              backup, fn);
                ss_perror(sci_idx,errno,errbuf);
                return(ERR);
        }
@@ -668,177 +818,78 @@ load_subs(argc,argv)
        int argc;
        char *argv[];
 {
-       ZSubscription_t subs[SUBSATONCE],subs2[SUBSATONCE],unsubs[SUBSATONCE];
-       FILE *fp;
-       int ind,unind,lineno,i,retval,type;
-       short wgport;
-       char *comma,*comma2,*file,subline[BUFSIZ];
+       int type, cnt, i;
+       char *file;
+       char *arggalaxy, *galaxy;
+       Code_t code;
 
-       if (argc > 2) {
-               fprintf(stderr,"Usage: %s [file]\n",argv[0]);
+       if (argc > 3) {
+               fprintf(stderr,"Usage: %s [file [galaxy]]\n",argv[0]);
                return;
        }
 
        if (*argv[0] == 'u')
                type = UNSUB;
+       else if (!strcmp(argv[0],"list") || !strcmp(argv[0],"ls"))
+               type = LIST;
        else
-               if (!strcmp(argv[0],"list") || !strcmp(argv[0],"ls"))
-                       type = LIST;
-               else
-                       type = SUB;
+               type = SUB;
 
-       if (type != LIST) 
-               if ((wgport = ZGetWGPort()) == -1) {
-                       ss_perror(sci_idx,errno,
-                                 "while finding WindowGram port");
-                       return;
-               } 
-
-       file = (argc == 1) ? subsname : argv[1];
-       
-       fp = fopen(file,"r");
+       file = (argc > 1)?argv[1]:subsname;
+       arggalaxy = (argc > 2)?argv[2]:NULL;
 
-       if (fp == NULL) {
-               ss_perror(sci_idx,errno,
-                         "while loading subscription file");
+       if (arggalaxy) {
+           if (code = ZGetGalaxyCount(&cnt)) {
+               ss_perror(sci_idx, code, "while getting galaxy count");
                return;
-       }
-       
-       ind = unind = 0;
-       lineno = 1;
-       
-       for (;;lineno++) {
-               if (!fgets(subline,sizeof subline,fp))
-                       break;
-               if (*subline == '#' || !*subline)
-                       continue;
-               subline[strlen(subline)-1] = '\0'; /* nuke newline */
-               comma = strchr(subline,',');
-               if (comma)
-                       comma2 = strchr(comma+1,',');
-               else
-                       comma2 = 0;
-               if (!comma || !comma2) {
-                       fprintf(stderr,
-                               "Malformed subscription at line %d of %s:\n%s\n",
-                               lineno,file,subline);
-                       continue;
-               }
-               *comma = '\0';
-               *comma2 = '\0';
-               if (type == LIST) {
-                       if (*subline == '!') 
-                               printf("(Un-subscription) Class %s instance %s recipient %s\n",
-                                      subline+1, comma+1, comma2+1);
-                       else
-                               printf("Class %s instance %s recipient %s\n",
-                                      subline, comma+1, comma2+1);
-                       continue;
-               }
-               if (*subline == '!') {  /* an un-subscription */
-                       /* if we are explicitly un-subscribing to
-                          the contents of a subscription file, ignore
-                          any un-subscriptions in that file */
-                       if (type == UNSUB)
-                               continue;
-                       unsubs[unind].zsub_class =
-                           (char *)malloc((unsigned)(strlen(subline)));
-                       /* XXX check malloc return */
-                       /* skip the leading '!' */
-                       (void) strcpy(unsubs[unind].zsub_class,subline+1);
-                       unsubs[unind].zsub_classinst =
-                           (char *)malloc((unsigned)(strlen(comma+1)+1));
-                       /* XXX check malloc return */
-                       (void) strcpy(unsubs[unind].zsub_classinst,comma+1);
-                       unsubs[unind].zsub_recipient =
-                           (char *)malloc((unsigned)(strlen(comma2+1)+1));
-                       /* XXX check malloc return */
-                       (void) strcpy(unsubs[unind].zsub_recipient,comma2+1);
-                       unind++;
-               } else {
-                       subs[ind].zsub_class =
-                           (char *)malloc((unsigned)(strlen(subline)+1));
-                       /* XXX check malloc return */
-                       (void) strcpy(subs[ind].zsub_class,subline);
-                       subs[ind].zsub_classinst =
-                           (char *)malloc((unsigned)(strlen(comma+1)+1));
-                       /* XXX check malloc return */
-                       (void) strcpy(subs[ind].zsub_classinst,comma+1);
-                       subs[ind].zsub_recipient =
-                           (char *)malloc((unsigned)(strlen(comma2+1)+1));
-                       /* XXX check malloc return */
-                       (void) strcpy(subs[ind].zsub_recipient,comma2+1);
-                       ind++;
-               }
-               if (ind == SUBSATONCE) {
-                       fix_macros(subs,subs2,ind);
-                       if ((retval = (type == SUB)?
-                            ZSubscribeTo(subs2,ind,(u_short)wgport):
-                            ZUnsubscribeTo(subs2,ind,(u_short)wgport)) !=
-                           ZERR_NONE) {
-                               ss_perror(sci_idx,retval,(type == SUB)?
-                                         "while subscribing":
-                                         "while unsubscribing");
-                               goto cleanup;
-                       }
-                       for (i=0;i<ind;i++) {
-                               free(subs[i].zsub_class);
-                               free(subs[i].zsub_classinst);
-                               free(subs[i].zsub_recipient);
-                       } 
-                       ind = 0;
-               }
-               if (unind == SUBSATONCE) {
-                       fix_macros(unsubs,subs2,unind);
-                       if ((retval = ZUnsubscribeTo(subs2,unind,(u_short)wgport)) != ZERR_NONE) {
-                               ss_perror(sci_idx,retval,
-                                         "while unsubscribing to un-subscriptions");
-                               goto cleanup;
-                       }
-                       for (i=0;i<unind;i++) {
-                               free(unsubs[i].zsub_class);
-                               free(unsubs[i].zsub_classinst);
-                               free(unsubs[i].zsub_recipient);
-                       } 
-                       unind = 0;
-               }
-       }
-       
-       if (type != LIST) {
-               /* even if we have no subscriptions, be sure to send
-                  an empty packet to trigger the default subscriptions */
-               fix_macros(subs,subs2,ind);
-               if ((retval = (type == SUB)?ZSubscribeTo(subs2,ind,(u_short)wgport):
-                    ZUnsubscribeTo(subs2,ind,(u_short)wgport)) != ZERR_NONE) {
-                       ss_perror(sci_idx,retval,(type == SUB)?
-                                 "while subscribing":
-                                 "while unsubscribing");
-                       goto cleanup;
-               }
-               if (unind) {
-                       fix_macros(unsubs,subs2,unind);
-                       if ((retval =
-                            ZUnsubscribeTo(subs2,unind,(u_short)wgport)) != ZERR_NONE) {
-                               ss_perror(sci_idx,retval,
-                                         "while unsubscribing to un-subscriptions");
-                               goto cleanup;
-                       }
+           }
+
+           for (i=0; i<cnt; i++) {
+               if (code = ZGetGalaxyName(i, &galaxy)) {
+                   ss_perror(sci_idx, code, "while getting galaxy name");
+                   return;
                }
+
+               if (strcasecmp(galaxy, arggalaxy) == 0)
+                   break;
+           }
+
+           if (i == cnt) {
+               ss_perror(sci_idx, 0,
+                         "unknown galaxy specified while loading subscription file");
+               return;
+           }
+       } else {
+           galaxy = NULL;
        }
-cleanup:
-       for (i=0;i<ind;i++) {
-         free(subs[i].zsub_class);
-         free(subs[i].zsub_classinst);
-         free(subs[i].zsub_recipient);
-       } 
-       for (i=0;i<unind;i++) {
-         free(unsubs[i].zsub_class);
-         free(unsubs[i].zsub_classinst);
-         free(unsubs[i].zsub_recipient);
-       } 
 
-       (void) fclose(fp);      /* ignore errs--file is read-only */
+       if (code = load_sub_file(type, file, galaxy))
+           ss_perror(sci_idx, code,
+                     "while loading subscription file");
+
+}
+
+void
+loadall(argc,argv)
+       int argc;
+       char *argv[];
+{      
+    int retval;
+    char *galaxy;
+    int type, cnt, i;
+    char fn[MAXPATHLEN];
+       
+    if (argc > 1) {
+       fprintf(stderr,"Usage: %s\n",argv[0]);
        return;
+    }
+
+    if (!strcmp(argv[0],"list") || !strcmp(argv[0],"ls"))
+       type = LIST;
+    else
+       type = SUB;
+
+    load_all_sub_files(type, subsname);
 }
 
 void
@@ -851,7 +902,7 @@ current(argc,argv)
        ZSubscription_t subs;
        int i,nsubs,retval,save,one,defs;
        short wgport;
-       char *file,backup[BUFSIZ];
+       char *galaxy, *file, backup[BUFSIZ];
        
        save = 0;
        defs = 0;
@@ -861,9 +912,22 @@ current(argc,argv)
        else if (!strcmp(argv[0], "defaults") || !strcmp(argv[0], "defs"))
                defs = 1;
 
-       if (argc != 1 && !(save && argc == 2)) {
-               fprintf(stderr,"Usage: %s%s\n",argv[0],save?" [filename]":"");
-               return;
+       if (save) {
+               if (argc > 3) {
+                       fprintf(stderr,"Usage: %s [filename [galaxy]]\n",
+                               argv[0]);
+                       return;
+               } else {
+                       file = (argc > 1)?argv[1]:subsname;
+                       galaxy = (argc > 2)?argv[2]:NULL;
+               }
+       } else {
+               if (argc > 2) {
+                       fprintf(stderr,"Usage: %s [galaxy]\n",argv[0]);
+                       return;
+               } else {
+                       galaxy = (argc > 1)?argv[1]:NULL;
+               }
        }
 
        if (!defs)
@@ -874,9 +938,9 @@ current(argc,argv)
                } 
 
        if (defs)
-               retval = ZRetrieveDefaultSubscriptions(&nsubs);
+               retval = ZRetrieveDefaultSubscriptions(galaxy, &nsubs);
        else
-               retval = ZRetrieveSubscriptions((u_short)wgport,&nsubs);
+               retval = ZRetrieveSubscriptions(galaxy,(u_short)wgport,&nsubs);
 
        if (retval == ZERR_TOOMANYSUBS) {
                fprintf(stderr,"Too many subscriptions -- some have not been returned.\n");
@@ -892,7 +956,6 @@ current(argc,argv)
                }
 
        if (save) {
-               file = (argc == 1)?subsname:argv[1];
                (void) strcpy(backup,file);
                (void) strcat(backup,".temp");
                if (!(fp = fopen(backup,"w"))) {
@@ -937,59 +1000,3 @@ current(argc,argv)
                }
        }
 }
-
-int
-make_exist(filename)
-       char *filename;
-{
-       char errbuf[BUFSIZ];
-       FILE *fpout;
-       
-       if (!access(filename,F_OK))
-               return (0);
-
-       if (!(fpout = fopen(filename,"w"))) {
-               (void) sprintf(errbuf,"while opening %s for write",filename);
-               ss_perror(sci_idx,errno,errbuf);
-               return (1);
-       }
-
-       if (fclose(fpout) == EOF) {
-               (void) sprintf(errbuf, "while closing %s", filename);
-               ss_perror(sci_idx, errno, errbuf);
-               return(1);
-       }
-       return (0);
-}
-
-void
-fix_macros(subs,subs2,num)
-       ZSubscription_t *subs,*subs2;
-       int num;
-{
-       int i;
-
-       for (i=0;i<num;i++) {
-               subs2[i] = subs[i];
-               fix_macros2(subs[i].zsub_class,&subs2[i].zsub_class);
-               fix_macros2(subs[i].zsub_classinst,&subs2[i].zsub_classinst);
-               fix_macros2(subs[i].zsub_recipient,&subs2[i].zsub_recipient);
-       }
-}
-
-void
-fix_macros2(src,dest)
-       register char *src;
-       char **dest;
-{
-       if (!strcmp(src,TOKEN_HOSTNAME)) {
-               *dest = ourhost;
-               return;
-       }
-       if (!strcmp(src,TOKEN_CANONNAME)) {
-               *dest = ourhostcanon;
-               return;
-       }
-       if (!strcmp(src,TOKEN_ME))
-               *dest = ZGetSender();
-}
index 52f18e02810af479d276373ff37f3b57a9119ae2..9548f9a6275327c60b9d2d76a7c1de075c3318c6 100644 (file)
@@ -1,4 +1,6 @@
-#      $Id: zctl_cmds.ct,v 1.7 1999/01/22 23:18:30 ghudson Exp $
+#      $Source: /afs/athena/astaff/project/zephyr/attic2/repository/zephyr/clients/zctl/zctl_cmds.ct,v $
+#      $Author: marc $
+#      $Header: /afs/athena/astaff/project/zephyr/attic2/repository/zephyr/clients/zctl/zctl_cmds.ct,v 1.6.4.1 1997/01/06 01:40:27 marc Exp $
 #
        command_table   zctl_cmds;
 
@@ -8,6 +10,12 @@
        request         cancel_subs, "Cancel all subscriptions.",
                        cancel;
 
+       request         loadall, "Subscribe to all subscriptions files.",
+                       loadall, ldall;
+
+       request         loadall, "List all subscriptions files.",
+                       listall, lsall;
+
        request         load_subs, "Subscribe to a subscriptions file.",
                        load, ld;
 
        request         subscribe, "Unsubscribe to a class/class instance.",
                        unsubscribe, unsub;
 
+       request         subscribe, "Suppress a class/class instance.",
+                       suppress, punt;
+
+       request         subscribe, "Unsuppress to a class/class instance.",
+                       unsuppress, unpunt;
+
        request         sub_file, "Subscribe and add to subscriptions file.",
                        add;
 
        request         sub_file, "Unsubscribe and add to subscriptions file\n                         as un-subscription.",
                        add_unsubscription, add_un;
 
-       request         sub_file, "Unsubscribe and delete subscription from\n                         subscriptions file.",
+       request         sub_file, "Suppress and add to subscriptions file\n\t\t\t as suppression.",
+                       add_suppression, add_punt;
+
+       request         sub_file, "Unsubscribe and delete subscription from\n\t\t\t subscriptions file.",
                        delete, del, dl;
        request         sub_file, "Delete un-subscription from subscriptions file.",
                        delete_unsubscription, del_un;
 
+       request         sub_file, "Unsuppress and delete suppression from\n\t\t\t subscriptions file.",
+                       delete_suppression, del_punt;
+
        request         current, "Retrieve current subscriptions.",
                        retrieve, ret;
 
                        unhide;
 
        request         ss_list_requests, "List available commands.",
-                       list_requests, lr, "?";
+                       list_requests, help, lr, "?";
 
        request         ss_quit, "Quit.",
                        quit, exit, q;
index dbb10877f8d27a2e58419983cdf8d67a9c28cdd0..f1d318a736caa7d22b95f04c13516cd4b187f02f 100644 (file)
@@ -88,7 +88,7 @@ char **argv;
                        sub.zsub_class = MESSAGE_CLASS;
                        sub.zsub_classinst = INSTANCE;
                        sub.zsub_recipient = ZGetSender();
-                       if (ZSubscribeToSansDefaults(&sub,1,(u_short)port)
+                       if (ZSubscribeToSansDefaults(NULL, &sub,1,(u_short)port)
                            != ZERR_NONE) {
                                fprintf(stderr,
                                        "Subscription error!  Writing to your terminal...\n");
index 863c82068791907ddf3f6fe1d4f610b0ad257f4c..2fd438d72c7b1c9e78ff6d9fdae3623c1d9e6c4c 100644 (file)
@@ -72,6 +72,7 @@ main(argc,argv)
     char user[BUFSIZ],*whichuser;
     ZAsyncLocateData_t ald;
     int retval,i,numlocs,numfound,loc,auth,rlen;
+    char *galaxy;
     ZNotice_t notice;
 #ifdef _POSIX_VERSION
     struct sigaction sa;
@@ -100,6 +101,12 @@ main(argc,argv)
            case '1':
                oneline = 1;
                break;
+           case 'G':
+               if (i+1 == argc)
+                   usage();
+               galaxy = argv[i+1];
+               i++;
+               break;
            default:
                usage();
                break;
@@ -119,27 +126,37 @@ main(argc,argv)
 
     numleft = numusers;
     numfound = 0;
-    rlen = strlen(ZGetRealm());
 
     i = 0;
     for (loc = 0; loc < argc; loc++) {
-       if (argv[loc][0] == '-') continue;
+       char *rhs;
+
+       if (argv[loc][0] == '-') {
+          if (argv[loc][1] == 'G')
+             loc++;
+          continue;
+       }
+
+       rhs = ZGetRhs(galaxy);
+       rlen = strlen(rhs);
 
        (void) strncpy(user,argv[loc],sizeof(user) - rlen - 2);
        user[sizeof(user) - rlen - 2] = '\0';
        if (!strchr(user,'@')) {
            (void) strcat(user,"@");
-           (void) strcat(user,ZGetRealm());
+           (void) strcat(user,rhs);
        } 
        if (parallel) {
-           if ((retval = ZRequestLocations(user, &ald, i ? UNSAFE : UNACKED,
+           if ((retval = ZRequestLocations(galaxy, user, &ald,
+                                           i ? UNSAFE : UNACKED,
                                            auth?ZAUTH:ZNOAUTH)) != ZERR_NONE) {
                com_err(whoami,retval,"requesting location of %s",user);
                exit(1);
            }
            i = 1;
        } else {
-           if ((retval = ZLocateUser(user,&numlocs,auth?ZAUTH:ZNOAUTH)) != ZERR_NONE) {
+           if ((retval = ZLocateUser(galaxy, user,&numlocs,
+                                     auth?ZAUTH:ZNOAUTH)) != ZERR_NONE) {
                com_err(whoami,retval,"while locating user %s",user);
                exit(1);
            }
index 67f7a5e83842b28d2e3934ce8dff0dc8618fc7fe..744867d45041bc0fc0f66c7ce2078c99f826a25c 100644 (file)
@@ -32,7 +32,7 @@ main(argc,argv)
        ZLocations_t locations;
        FILE *fp;
        struct passwd *pwd;
-       char anyonename[BUFSIZ],name[BUFSIZ],cleanname[BUFSIZ],*envptr;
+       char anyonename[BUFSIZ],name[BUFSIZ],cleanname[BUFSIZ],galaxyname[BUFSIZ],*envptr;
        char *comment_ptr;
        int onoff = ON,quiet = 0,justlist = 0,useronly = 0, filenamed = 0;
        int retval,arg,ind,one,numlocs,i;
@@ -79,6 +79,14 @@ main(argc,argv)
                                (void) strcpy(cleanname,argv[++arg]);
                                useronly = 1;
                                break;
+                       case 'G':
+                               if (arg == argc-1) {
+                                       fprintf(stderr,"No galaxy name specified\n");
+                                       goto usage;
+                               }
+                               (void) strcpy(galaxyname,argv[++arg]);
+                               useronly = 1;
+                               break;
                        default:
                                goto usage;
                        }
@@ -154,7 +162,7 @@ main(argc,argv)
                if (!strchr(name,'@')) {
                        cp = name + strlen(name);
                        *cp++ = '@';
-                       (void) strcpy(cp,ZGetRealm());
+                       (void) strcpy(cp, ZGetRhs(galaxyname));
                }
                if ((subs[ind].zsub_classinst = malloc((unsigned)(strlen(name)+1))) == NULL) {
                        fprintf (stderr, "znol: out of memory");
@@ -164,7 +172,7 @@ main(argc,argv)
                subs[ind++].zsub_recipient = "";
 
                if (!quiet && onoff == ON) {
-                       if ((retval = ZLocateUser(name,&numlocs,ZAUTH))
+                       if ((retval = ZLocateUser(galaxyname,name,&numlocs,ZAUTH))
                            != ZERR_NONE) {
                                com_err(argv[0],retval,"locating user");
                                exit(1);
@@ -194,9 +202,9 @@ main(argc,argv)
                if (ind == SUBSATONCE) {
                        if (!justlist)
                                if ((retval = (onoff==ON)?
-                                    ZSubscribeToSansDefaults(subs,ind,
+                                    ZSubscribeToSansDefaults(galaxyname,subs,ind,
                                                              (u_short)wgport):
-                                    ZUnsubscribeTo(subs,ind,(u_short)wgport)) !=
+                                    ZUnsubscribeTo(galaxyname,subs,ind,(u_short)wgport)) !=
                                    ZERR_NONE) {
                                        com_err(argv[0],retval,(onoff==ON)?
                                                "subscribing":
@@ -211,8 +219,8 @@ main(argc,argv)
 
        if (ind && !justlist)
                if ((retval = (onoff==ON)?
-                    ZSubscribeToSansDefaults(subs,ind,(u_short)wgport):
-                    ZUnsubscribeTo(subs,ind,(u_short)wgport)) !=
+                    ZSubscribeToSansDefaults(galaxyname,subs,ind,(u_short)wgport):
+                    ZUnsubscribeTo(galaxyname,subs,ind,(u_short)wgport)) !=
                    ZERR_NONE) {
                        com_err(argv[0],retval,(onoff==ON)?
                                "subscribing":
index e9334cd37d339f0d937bc916f3706d20e54e9a22..2d7140b6e9adcca796c985f16a638f3337fa7c8e 100644 (file)
@@ -71,7 +71,7 @@ main(argc,argv)
        lines[1] = "You have new mail.";
        
        (void) strcpy(mysender,"pop@");
-       (void) strcat(mysender,ZGetRealm());
+       (void) strcat(mysender,ZGetRhs(NULL));
 
        for (i = 1; i < argc; i++) {
            (void) memset((char *)&notice, 0, sizeof(notice));
index d475096c12fad4ac4e78a52d6765c5f354669e27..efb0018e34e3e2739077f4f0e601fbaf214fe392 100644 (file)
@@ -22,7 +22,7 @@ static const char rcsid_zstat_c[] = "$Id: zstat.c,v 1.21 1999/08/13 00:18:50 dan
 #endif
 
 const char *hm_head[] = {
-    "Current server =",
+    "Current server:",
     "Items in queue:",
     "Client packets received:",
     "Server packets received:",
@@ -124,22 +124,18 @@ do_stat(host)
                return;
        }
 
-       if (hm_stat(host,srv_host))
-               return;
-
-       if (!hmonly)
-               (void) srv_stat(srv_host);
+       hm_stat(host, !hmonly);
 }
 
-int
-hm_stat(host,server)
-       char *host,*server;
+hm_stat(host, do_server)
+       char *host;
+       int do_server;
 {
        struct in_addr inaddr;
        Code_t code;
 
-       char *line[20],*mp;
-       int i,nf;
+       char **line,*mp;
+       int sock,i,nf,ret;
        struct hostent *hp;
        time_t runtime;
        struct tm *tim;
@@ -161,36 +157,55 @@ hm_stat(host,server)
        }
        
        if ((code = ZhmStat(&inaddr, &notice)) != ZERR_NONE) {
-           com_err("zstat", code, "getting hostmanager status");
+           com_err("zstat", ret, "getting hostmanager status");
            exit(-1);
        }
        
+       for (nf=0, mp = notice.z_message;
+            mp<notice.z_message+notice.z_message_len;
+            nf++, mp += strlen(mp)+1)
+               ;
+
+       line = (char **) malloc(sizeof(char *)*nf);
+
        mp = notice.z_message;
-       for (nf=0;mp<notice.z_message+notice.z_message_len;nf++) {
+       for (nf=0, mp = notice.z_message;
+            mp<notice.z_message+notice.z_message_len;
+            nf++, mp += strlen(mp)+1) 
                line[nf] = mp;
-               mp += strlen(mp)+1;
-       }
 
-       (void) strcpy(server,line[0]);
 
-       printf("HostManager protocol version = %s\n",notice.z_version);
+       printf("HostManager protocol version = %s\n\n",notice.z_version);
 
-       for (i=0; (i < nf) && (i < HM_SIZE); i++) {
-               if (!strncmp("Time",hm_head[i],4)) {
+       for (i=0; i<nf; i++) {
+               if (((i%(HM_SIZE+2)) == 0) && (i+HM_SIZE<nf)) {
+                       printf("Zephyr galaxy = %s\n", line[i+HM_SIZE]);
+                       printf("%s %s\n",hm_head[i%(HM_SIZE+2)],line[i]);
+               } else if ((i%(HM_SIZE+2)) == 7) {
                        runtime = atol(line[i]);
                        tim = gmtime(&runtime);
-                       printf("%s %d days, %02d:%02d:%02d\n", hm_head[i],
+                       printf("%s %d days, %02d:%02d:%02d\n", hm_head[i%(HM_SIZE+1)],
                                tim->tm_yday,
                                tim->tm_hour,
                                tim->tm_min,
                                tim->tm_sec);
+               } else if ((i%(HM_SIZE+2)) == HM_SIZE) {
+                       /* do nothing */
+               } else if (((i%(HM_SIZE+2)) == (HM_SIZE+1)) ||
+                          (i == nf-1)) {
+                       printf("\n");
+                       if (do_server) {
+                               srv_stat(line[i-(i%(HM_SIZE+2))]);
+                               printf("\n");
+                       }
+               } else {
+                       printf("%s %s\n",hm_head[i%(HM_SIZE+2)],line[i]);
                }
-               else
-                       printf("%s %s\n",hm_head[i],line[i]);
        }
-
-       printf("\n");
        
+       free(line);
+
+       (void) close(sock);
        ZFreeNotice(&notice);
        return(0);
 }
@@ -300,7 +315,6 @@ srv_stat(host)
                        printf("%s\n",line[i]);
                } else printf("%s\n",line[i]);
        }
-       printf("\n");
        
        (void) close(sock);
        ZFreeNotice(&notice);
index 678aae52f96b3c72a26b3d6a8ff897d510643f25..f44c246bb65839fcd807fa234b893f379fc98c5f 100644 (file)
@@ -29,7 +29,7 @@ static const char rcsid_zwrite_c[] = "$Id: zwrite.c,v 1.49 1999/08/13 00:19:42 d
 #define MAXRECIPS 100
 
 int nrecips, msgarg, verbose, quiet, nodot, cc;
-char *whoami, *inst, *class, *opcode, *realm, *recips[MAXRECIPS];
+char *whoami, *inst, *class, *opcode, *rhs, *galaxy, *recips[MAXRECIPS];
 Z_AuthProc auth;
 void un_tabify();
 
@@ -174,7 +174,13 @@ main(argc, argv)
            if (arg == argc-1)
                usage(whoami);
            arg++;
-           realm = argv[arg];
+           rhs = argv[arg];
+           break;
+       case 'G':
+           if (arg == argc-1)
+               usage(whoami);
+           arg++;
+           galaxy = argv[arg];
            break;
        case 'C':
            cc = 1;
@@ -224,6 +230,7 @@ main(argc, argv)
     notice.z_sender = 0;
     notice.z_message_len = 0;
     notice.z_recipient = "";
+    notice.z_dest_galaxy = galaxy;
     if (format)
            notice.z_default_format = format;
     else if (filsys == 1)
@@ -343,15 +350,15 @@ send_off(notice, real)
     int real;
 {
     int i, success, retval;
-    char bfr[BUFSIZ], realm_recip[BUFSIZ], dest[3 * BUFSIZ], *cp;
+    char bfr[BUFSIZ], rhs_recip[BUFSIZ], dest[3 * BUFSIZ], *cp;
     ZNotice_t retnotice;
 
     success = 0;
        
     for (i=0;i<nrecips || !nrecips;i++) {
-       if (realm) {
-           sprintf(realm_recip, "%s@%s", (nrecips) ? recips[i] : "", realm);
-           notice->z_recipient = realm_recip;
+       if (rhs) {
+           sprintf(rhs_recip, "%s@%s", (nrecips) ? recips[i] : "", rhs);
+           notice->z_recipient = rhs_recip;
        } else {
            notice->z_recipient = (nrecips) ? recips[i] : "";
        }
@@ -452,8 +459,9 @@ usage(s)
 {
     fprintf(stderr,
            "Usage: %s [-a] [-o] [-d] [-v] [-q] [-n] [-t] [-u] [-l]\n\
-\t[-c class] [-i inst] [-O opcode] [-f fsname] [-s signature] [-C]\n\
-\t[user ...] [-F format] [-r realm] [-m message]\n", s);
+\t[-c class] [-i inst] [-O opcode] [-f fsname] [-s signature] \n\
+\t[-G galaxy] [-C]\n\
+\t[user ...] [-F format] [-r rhs] [-m message]\n", s);
     fprintf(stderr,"\t-f and -c are mutually exclusive\n\
 \t-f and -i are mutually exclusive\n\
 \trecipients must be specified unless -c or -f specifies a class\n\
index 1a3dd61b5c8518999b5bb9e925bd7cab4422e981..8c62ca8a2f4a966b958fb094815620885544fdb5 100644 (file)
@@ -1,4 +1,4 @@
-/* h/config.h.in.  Generated automatically from configure.in by autoheader.  */
+/* h/config.h.in.  Generated automatically from configure.in by autoheader 2.13.  */
 
 /* Define if the `getpgrp' function takes no argument.  */
 #undef GETPGRP_VOID
 /* Define to the type of the host system. */
 #define MACHINE_TYPE "unknown"
 
+/* Define if `struct sockaddr' has an `sa_len' field.  */
+#undef HAVE_SA_LEN
+
+/* Define if `resolv' libary exists and has either res_send or __res_send.  */
+#undef HAVE_LIB_RESOLV
+
 /* The number of bytes in a int.  */
 #undef SIZEOF_INT
 
 /* Define if you have the waitpid function.  */
 #undef HAVE_WAITPID
 
+/* Define if you have the <X11/Xaw/Label.h> header file.  */
+#undef HAVE_X11_XAW_LABEL_H
+
+/* Define if you have the <dlfcn.h> header file.  */
+#undef HAVE_DLFCN_H
+
 /* Define if you have the <fcntl.h> header file.  */
 #undef HAVE_FCNTL_H
 
+/* Define if you have the <ifaddrs.h> header file.  */
+#undef HAVE_IFADDRS_H
+
 /* Define if you have the <malloc.h> header file.  */
 #undef HAVE_MALLOC_H
 
index 86e3ca069edfb60cf63e795c15681d8d52bd6fac..b3976d74ecb52bb65dca772d507a8b5ce2341190 100644 (file)
@@ -16,7 +16,8 @@
 static const char rcsid_ZAsyncLocate_c[] = "$Id: ZAsyncLocate.c,v 1.6 1999/01/22 23:19:02 ghudson Exp $";
 #endif
 
-Code_t ZRequestLocations(user, zald, kind, auth)
+Code_t ZRequestLocations(galaxy, user, zald, kind, auth)
+     char *galaxy;
      char *user;
      register ZAsyncLocateData_t *zald;
      ZNotice_Kind_t kind;      /* UNSAFE, UNACKED, or ACKED */
@@ -39,6 +40,7 @@ Code_t ZRequestLocations(user, zald, kind, auth)
     notice.z_recipient = "";
     notice.z_default_format = "";
     notice.z_message_len = 0;
+    notice.z_dest_galaxy = galaxy;
 
     if ((retval = ZSendNotice(&notice, auth)) != ZERR_NONE)
        return(retval);
index 90633ea00c5495be88d2a46ceddbb1b265f21ae0..c903d8e2777ddd196b9f59cf489bb917acf69a36 100644 (file)
@@ -33,6 +33,7 @@ Code_t ZCheckAuthentication(notice, from)
     int result;
     ZChecksum_t our_checksum;
     CREDENTIALS cred;
+    char *realm;
 
     /* If the value is already known, return it. */
     if (notice->z_checked_auth != ZAUTH_UNSET)
@@ -41,8 +42,12 @@ Code_t ZCheckAuthentication(notice, from)
     if (!notice->z_auth)
        return (ZAUTH_NO);
        
+    /* yes, this really is a realm, not a rhs */
+    if ((realm = ZGetRhs(notice->z_dest_galaxy)) == NULL)
+       return (ZAUTH_NO);
+
     if ((result = krb_get_cred(SERVER_SERVICE, SERVER_INSTANCE, 
-                              __Zephyr_realm, &cred)) != 0)
+                              realm, &cred)) != 0)
        return (ZAUTH_NO);
 
 #ifdef NOENCRYPTION
index 2372bb6e62dec65c3095757fc99a9dfb794a2ee5..a67d6fc936bdd94e26ad1f37c5962bab2cc833d6 100644 (file)
@@ -33,8 +33,8 @@ Code_t ZFormatAuthenticNotice(notice, buffer, buffer_len, len, session)
     newnotice.z_authent_len = 0;
     newnotice.z_ascii_authent = "";
 
-    if ((retval = Z_FormatRawHeader(&newnotice, buffer, buffer_len,
-                                   &hdrlen, &ptr, NULL)) != ZERR_NONE)
+    if ((retval = Z_FormatRawHeader(&newnotice, buffer, buffer_len, &hdrlen,
+                                   NULL, NULL, &ptr, NULL)) != ZERR_NONE)
        return (retval);
 
 #ifdef NOENCRYPTION
@@ -43,8 +43,8 @@ Code_t ZFormatAuthenticNotice(notice, buffer, buffer_len, len, session)
     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)
+    if ((retval = Z_FormatRawHeader(&newnotice, buffer, buffer_len, &hdrlen,
+                                   NULL, NULL, NULL, NULL)) != ZERR_NONE)
        return (retval);
 
     ptr = buffer+hdrlen;
index 19ab30b882c7757459677c4289ee8836f441577f..342d06aae5b79489cf69414f1383678586c18684 100644 (file)
@@ -25,8 +25,8 @@ Code_t ZFormatRawNotice(notice, buffer, ret_len)
     int hdrlen;
     Code_t retval;
 
-    if ((retval = Z_FormatRawHeader(notice, header, sizeof(header),
-                                   &hdrlen, NULL, NULL)) != ZERR_NONE)
+    if ((retval = Z_FormatRawHeader(notice, header, sizeof(header), &hdrlen,
+                                   NULL, NULL, NULL, NULL)) != ZERR_NONE)
        return (retval);
 
     *ret_len = hdrlen+notice->z_message_len;
index c1440c428c7c76c29330021f8ad921e8981020d8..bf11b2fa1a995ac361e7634615830e7b84f80080 100644 (file)
@@ -3,7 +3,7 @@
  *
  *     Created by:     Robert French
  *
- *     $Id: ZFmtRawLst.c,v 1.12 1999/01/22 23:19:09 ghudson Exp $
+n *    $Id: ZFmtRawLst.c,v 1.12 1999/01/22 23:19:09 ghudson Exp $
  *
  *     Copyright (c) 1987 by the Massachusetts Institute of Technology.
  *     For copying and distribution information, see the file
@@ -28,8 +28,8 @@ Code_t ZFormatRawNoticeList(notice, list, nitems, buffer, ret_len)
     char *ptr;
     Code_t retval;
 
-    if ((retval = Z_FormatRawHeader(notice, header, sizeof(header),
-                                   &hdrlen, NULL, NULL)) != ZERR_NONE)
+    if ((retval = Z_FormatRawHeader(notice, header, sizeof(header), &hdrlen,
+                                   NULL, NULL, NULL, NULL)) != ZERR_NONE)
        return (retval);
 
     size = 0;
index 391dfe122d43904f6d1ca1436cd861b732a19d34..4de08db3ad92cf2c1e8851bed1b0d8feb34eeeda 100644 (file)
@@ -27,8 +27,8 @@ Code_t ZFormatSmallRawNoticeList(notice, list, nitems, buffer, ret_len)
     int hdrlen, i, size;
     char *ptr;
 
-    if ((retval = Z_FormatRawHeader(notice, buffer, Z_MAXHEADERLEN,
-                                   &hdrlen, NULL, NULL)) != ZERR_NONE)
+    if ((retval = Z_FormatRawHeader(notice, buffer, Z_MAXHEADERLEN, &hdrlen,
+                                   NULL, NULL, NULL, NULL)) != ZERR_NONE)
        return (retval);
 
     size = 0;
index 473c0b505b4d5db0d2bdf84d589af4817965b326..9d6d062fc309e286e4afced70845d78aa09952f8 100644 (file)
@@ -24,8 +24,8 @@ Code_t ZFormatSmallRawNotice(notice, buffer, ret_len)
     Code_t retval;
     int hdrlen;
     
-    if ((retval = Z_FormatRawHeader(notice, buffer, Z_MAXHEADERLEN,
-                                   &hdrlen, NULL, NULL)) != ZERR_NONE)
+    if ((retval = Z_FormatRawHeader(notice, buffer, Z_MAXHEADERLEN, &hdrlen,
+                                   NULL, NULL, NULL, NULL)) != ZERR_NONE)
        return (retval);
 
     *ret_len = hdrlen+notice->z_message_len;
index ef5e936f660bb5e8054e33cc1d748b01fab117a8..168cfa274dc1582d9c0e14d1aa4fc7d748aa354b 100644 (file)
@@ -1,5 +1,5 @@
 /* This file is part of the Project Athena Zephyr Notification System.
- * It contains source for the ZGetSender.c function.
+ * It contains source for the ZGetSender function.
  *
  *     Created by:     Robert French
  *
@@ -47,6 +47,6 @@ char *ZGetSender()
     pw = getpwuid((int) getuid());
     if (!pw)
        return ("unknown");
-    (void) sprintf(sender, "%s@%s", pw->pw_name, __Zephyr_realm);
+    (void) sprintf(sender, "%s@%s", pw->pw_name, ZGetRhs(NULL));
     return (sender);
 }
index 5479de974b87b70d582fb36599fb6051d564632a..4470402419b0318641c4b64b796f077f2469063c 100644 (file)
@@ -18,6 +18,18 @@ static char rcsid_ZInitialize_c[] =
 #include <internal.h>
 
 #include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/ioctl.h>
+#include <config.h>
+#ifdef HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
+#endif
+#ifdef HAVE_IFADDRS_H
+#include <ifaddrs.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
 #ifdef HAVE_KRB4
 #include <krb_err.h>
 #endif
@@ -30,17 +42,15 @@ Code_t ZInitialize()
 {
     struct servent *hmserv;
     struct hostent *hostent;
-    char addr[4], hostname[MAXHOSTNAMELEN];
-    struct in_addr servaddr;
+    char hostname[MAXHOSTNAMELEN], *def;
     struct sockaddr_in sin;
     int s, sinsize = sizeof(sin);
     Code_t code;
     ZNotice_t notice;
+    char *mp;
+    int i;
 #ifdef HAVE_KRB4
-    char *krealm = NULL;
-    int krbval;
-    char d1[ANAME_SZ], d2[INST_SZ];
-
+    char *krealm;
     initialize_krb_error_table();
 #endif
 
@@ -49,20 +59,14 @@ Code_t ZInitialize()
     (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;
+#ifdef HAVE_SA_LEN
+    __HM_addr.sin_len = sizeof (struct sockaddr_in);
+#endif
+    __HM_addr.sin_addr.s_addr = htonl (0x7f000001L);
 
     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;
-
     /* Initialize the input queue */
     __Q_Tail = NULL;
     __Q_Head = NULL;
@@ -71,7 +75,6 @@ Code_t ZInitialize()
        code will fall back to something which might not be "right",
        but this is is ok, since none of the servers call krb_rd_req. */
 
-    servaddr.s_addr = INADDR_NONE;
     if (! __Zephyr_server) {
        if ((code = ZOpenPort(NULL)) != ZERR_NONE)
          return(code);
@@ -85,62 +88,94 @@ Code_t ZInitialize()
          If this code ever support a multiplexing zhm, this will have to
          be made smarter, and probably per-message */
 
+       for (i=0, mp = notice.z_message;
+           mp<notice.z_message+notice.z_message_len;
+           i++, mp += strlen(mp)+1)
+          ;
+
+       /* if this is an old zhm, i will be 10, and __ngalaxies will be 0 */
+
+       __ngalaxies = i/12;     /* XXX should be a defined constant */
+
+       if (__ngalaxies == 0) {
+          char galaxy_config[1024];
+
+          __ngalaxies = 1;
+          __galaxy_list = (Z_GalaxyList *) malloc(sizeof(Z_GalaxyList)*1);
+
+          /* we're talking to an old zhm.  Use the one server name we get
+             to figure out the krealm.  ZReceiveNotice() knows this case,
+             and will always assume the current/only galaxy. */
+
+          strcpy(galaxy_config, "local-galaxy hostlist ");
+          strcat(galaxy_config, notice.z_message);
+
+          if ((code =
+               Z_ParseGalaxyConfig(galaxy_config,
+                                   &__galaxy_list[0].galaxy_config))
+              != ZERR_NONE) {
+              __ngalaxies = 0;
+              free(__galaxy_list);
+              return(code);
+          }
+
 #ifdef HAVE_KRB4
-       krealm = krb_realmofhost(notice.z_message);
-#endif
-       hostent = gethostbyname(notice.z_message);
-       if (hostent && hostent->h_addrtype == AF_INET)
-          memcpy(&servaddr, hostent->h_addr, sizeof(servaddr));
+          krealm = krb_realmofhost(__galaxy_list[0].galaxy_config.server_list[0].name);
+          if (!krealm)
+              krealm = "";
 
-       ZFreeNotice(&notice);
-    }
+          strcpy(__galaxy_list[0].krealm, krealm);
+                 
+          __galaxy_list[0].last_authent_time = 0;
+#endif
+       } else {
+          __galaxy_list = (Z_GalaxyList *) malloc(sizeof(Z_GalaxyList)*__ngalaxies);
+          for (i=0, mp = notice.z_message;
+               mp<notice.z_message+notice.z_message_len;
+               i++, mp += strlen(mp)+1) {
+              if (i%12 == 11) {
+                  if ((code =
+                       Z_ParseGalaxyConfig(mp,
+                                           &__galaxy_list[i/12].galaxy_config))
+                      != ZERR_NONE) {
+                      __ngalaxies = i/12;
+                      for (i=0; i<__ngalaxies; i++)
+                          Z_FreeGalaxyConfig(&__galaxy_list[i].galaxy_config);
+                      free(__galaxy_list);
+                      return(code);
+                  }
 
 #ifdef HAVE_KRB4
-    if (krealm) {
-       strcpy(__Zephyr_realm, krealm);
-    } else if ((krb_get_tf_fullname(TKT_FILE, d1, d2, __Zephyr_realm)
-               != KSUCCESS) &&
-              ((krbval = krb_get_lrealm(__Zephyr_realm, 1)) != KSUCCESS)) {
-       return (krbval);
-    }
-#else
-    strcpy(__Zephyr_realm, "local-realm");
+                  krealm = krb_realmofhost(__galaxy_list[i/12].galaxy_config.server_list[0].name);
+                  if (!krealm)
+                      krealm = "";
+
+                  strcpy(__galaxy_list[i/12].krealm, krealm);
+
+                  __galaxy_list[i/12].last_authent_time = 0;
 #endif
+              }
+          }
+       }
 
-    __My_addr.s_addr = INADDR_NONE;
-    if (servaddr.s_addr != INADDR_NONE) {
-       /* Try to get the local interface address by connecting a UDP
-        * socket to the server address and getting the local address.
-        * Some broken operating systems (e.g. Solaris 2.0-2.5) yield
-        * INADDR_ANY (zero), so we have to check for that. */
-       s = socket(AF_INET, SOCK_DGRAM, 0);
-       if (s != -1) {
-           memset(&sin, 0, sizeof(sin));
-           sin.sin_family = AF_INET;
-           memcpy(&sin.sin_addr, &servaddr, sizeof(servaddr));
-           sin.sin_port = HM_SRV_SVC_FALLBACK;
-           if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) == 0
-               && getsockname(s, (struct sockaddr *) &sin, &sinsize) == 0
-               && sin.sin_addr.s_addr != 0)
-               memcpy(&__My_addr, &sin.sin_addr, sizeof(__My_addr));
-           close(s);
-       }
-    }
-    if (__My_addr.s_addr == INADDR_NONE) {
-       /* We couldn't figure out the local interface address by the
-        * above method.  Try by resolving the local hostname.  (This
-        * is a pretty broken thing to do, and unfortunately what we
-        * always do on server machines.) */
-       if (gethostname(hostname, sizeof(hostname)) == 0) {
-           hostent = gethostbyname(hostname);
-           if (hostent && hostent->h_addrtype == AF_INET)
-               memcpy(&__My_addr, hostent->h_addr, sizeof(__My_addr));
-       }
+       ZFreeNotice(&notice);
+
+       __default_galaxy = 0;
+
+       if (def = ZGetVariable("defaultgalaxy")) {
+          for (i=0; i<__ngalaxies; i++) {
+              if (strcasecmp(__galaxy_list[i].galaxy_config.galaxy,
+                             def) == 0) {
+                  __default_galaxy = i;
+                  break;
+              }
+          }
+       }
+    } else {
+       __galaxy_list = 0;
+       __ngalaxies = 0;
+       __default_galaxy = 0;
     }
-    /* If the above methods failed, zero out __My_addr so things will
-     * sort of kind of work. */
-    if (__My_addr.s_addr == INADDR_NONE)
-       __My_addr.s_addr = 0;
 
     /* Get the sender so we can cache it */
     (void) ZGetSender();
index 4056e30fed1941ad91825360719589d460de44d7..cf0db72cb76792ed81398db56488d922912fe95c 100644 (file)
@@ -56,22 +56,25 @@ Code_t ZInitLocationInfo(hostname, tty)
     return (ZERR_NONE);
 }
 
-Code_t ZSetLocation(exposure)
+Code_t ZSetLocation(galaxy, exposure)
+    char *galaxy;
     char *exposure;
 {
-    return (Z_SendLocation(LOGIN_CLASS, exposure, ZAUTH, 
+    return (Z_SendLocation(galaxy, LOGIN_CLASS, exposure, ZAUTH, 
                           "$sender logged in to $1 on $3 at $2"));
 }
 
-Code_t ZUnsetLocation()
+Code_t ZUnsetLocation(galaxy)
+    char *galaxy;
 {
-    return (Z_SendLocation(LOGIN_CLASS, LOGIN_USER_LOGOUT, ZNOAUTH, 
+    return (Z_SendLocation(galaxy, LOGIN_CLASS, LOGIN_USER_LOGOUT, ZNOAUTH, 
                           "$sender logged out of $1 on $3 at $2"));
 }
 
-Code_t ZFlushMyLocations()
+Code_t ZFlushMyLocations(galaxy)
+    char *galaxy;
 {
-    return (Z_SendLocation(LOGIN_CLASS, LOGIN_USER_FLUSH, ZAUTH, ""));
+    return (Z_SendLocation(galaxy, LOGIN_CLASS, LOGIN_USER_FLUSH, ZAUTH, ""));
 }
 
 char *ZParseExposureLevel(text)
@@ -93,7 +96,8 @@ char *ZParseExposureLevel(text)
        return(NULL);
 }
 
-Code_t Z_SendLocation(class, opcode, auth, format)
+Code_t Z_SendLocation(galaxy, class, opcode, auth, format)
+    char *galaxy;
     char *class;
     char *opcode;
     Z_AuthProc auth;
@@ -119,6 +123,7 @@ Code_t Z_SendLocation(class, opcode, auth, format)
     notice.z_recipient = "";
     notice.z_num_other_fields = 0;
     notice.z_default_format = format;
+    notice.z_dest_galaxy = galaxy;
 
     bptr[0] = host;
     ourtime = time((time_t *)0);
index e14cfc22f4dffa9554fff85dcdd01b2bab50b276..3e09763994c4ab8a5057d781471f820f50eea56b 100644 (file)
 static const char rcsid_ZMakeAuthentication_c[] = "$Id: ZMkAuth.c,v 1.19 1999/01/22 23:19:16 ghudson Exp $";
 #endif
 
-#ifdef HAVE_KRB4
-#include <krb_err.h>
-static long last_authent_time = 0L;
-static KTEXT_ST last_authent;
-#endif
-
 Code_t ZResetAuthentication () {
 #ifdef HAVE_KRB4
-    last_authent_time = 0L;
+    int i;
+
+    for (i=0; i<__ngalaxies; i++)
+       __galaxy_list[i].last_authent_time = 0;
+
 #endif
     return ZERR_NONE;
 }
 
-Code_t ZMakeAuthentication(notice, buffer, buffer_len, len)
+Code_t ZMakeAuthentication(notice, buffer, buffer_len, phdr_len)
     register ZNotice_t *notice;
     char *buffer;
     int buffer_len;
-    int *len;
+    int *phdr_len;
 {
 #ifdef HAVE_KRB4
+    int i;
+    int cksum_len;
     int result;
     time_t now;
     KTEXT_ST authent;
-    char *cstart, *cend;
+    char *krealm, *cksum_start, *cstart, *cend;
     ZChecksum_t checksum;
     CREDENTIALS cred;
     extern unsigned long des_quad_cksum();
 
+    if (notice->z_dest_galaxy && *notice->z_dest_galaxy) {
+       for (i=0; i<__ngalaxies; i++) {
+           if (strcasecmp(notice->z_dest_galaxy,
+                          __galaxy_list[i].galaxy_config.galaxy) == 0)
+               break;
+       }
+
+       if (i == __ngalaxies)
+           return(ZERR_GALAXYUNKNOWN);
+    } else {
+       i = __default_galaxy;
+    }
+
+    krealm = __galaxy_list[i].krealm;
+
+    if (krealm[0] == '\0')
+#endif
+       {
+           notice->z_checksum = 0;
+           notice->z_auth = 1;
+           notice->z_authent_len = 0;
+           notice->z_ascii_authent = "";
+           return (Z_FormatRawHeader(notice, buffer, buffer_len, phdr_len,
+                                     NULL, NULL, NULL, NULL));
+       }
+
+#ifdef HAVE_KRB4
     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 ((__galaxy_list[i].last_authent_time == 0) ||
+       (now - __galaxy_list[i].last_authent_time > 120)) {
+       result = krb_mk_req(&authent, SERVER_SERVICE, SERVER_INSTANCE,
+                           krealm, 0);
        if (result != MK_AP_OK) {
-           last_authent_time = 0;
+           __galaxy_list[i].last_authent_time = 0;
            return (result+krb_err_base);
         }
-       last_authent_time = now;
-       last_authent = authent;
+       __galaxy_list[i].last_authent_time = now;
+       __galaxy_list[i].last_authent = authent;
     }
     else {
-       authent = last_authent;
+       authent = __galaxy_list[i].last_authent;
     }
     notice->z_auth = 1;
     notice->z_authent_len = authent.length;
@@ -71,31 +100,27 @@ Code_t ZMakeAuthentication(notice, buffer, buffer_len, len)
        free(notice->z_ascii_authent);
        return (result);
     }
-    result = Z_FormatRawHeader(notice, buffer, buffer_len, len, &cstart,
-                              &cend);
+    result = Z_FormatRawHeader(notice, buffer, buffer_len, phdr_len,
+                              &cksum_start, &cksum_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)
+                              krealm, &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,
+    checksum = des_quad_cksum(cksum_start, NULL, cstart - cksum_start, 0,
+                             cred.session);
+    checksum ^= des_quad_cksum(cend, NULL, (cksum_start + cksum_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);
+    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
 }
index 2d2e62b853aa5363eb19250cc8c14a7736724c3f..404e22d5893bd4e22903cf2aab50b7acad0b2395 100644 (file)
@@ -17,7 +17,8 @@ static const char rcsid_ZNewLocateUser_c[] =
     "$Id: ZNewLocU.c,v 1.10 1999/01/22 23:19:17 ghudson Exp $";
 #endif
 
-Code_t ZLocateUser(user, nlocs, auth)
+Code_t ZLocateUser(galaxy, user, nlocs, auth)
+    char *galaxy;
     char *user;
     int *nlocs;
     Z_AuthProc auth;
@@ -29,7 +30,8 @@ Code_t ZLocateUser(user, nlocs, auth)
     (void) ZFlushLocations();  /* ZFlushLocations never fails (the library
                                   is allowed to know this). */
 
-    if ((retval = ZRequestLocations(user, &zald, UNACKED, auth)) != ZERR_NONE)
+    if ((retval = ZRequestLocations(galaxy, user, &zald, UNACKED,
+                                   auth)) != ZERR_NONE)
        return(retval);
 
     retval = Z_WaitForNotice (&notice, ZCompareALDPred, &zald, SRV_TIMEOUT);
index e5e66340f718266ab95fa1dd73df7396055f2d8f..b1ceb5c917ee306f81f521e5cbbe7f7f7dde21e6 100644 (file)
@@ -68,3 +68,11 @@ Code_t ZOpenPort(port)
 
     return (ZERR_NONE);
 }
+
+int ZGetPort()
+{
+    if (__Zephyr_open)
+       return(__Zephyr_port);
+    else
+       return(-1);
+}
index a0a808024c22168d6a0ce17d3bb218f007befc00..9067307f2d9a5aa60fa87901aad70d559de93bef 100644 (file)
@@ -17,56 +17,8 @@ static char rcsid_ZParseNotice_c[] =
 
 #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;
@@ -74,7 +26,7 @@ Code_t ZParseNotice(buffer, len, notice)
 {
     char *ptr, *end;
     unsigned long temp;
-    int maj, numfields, i;
+    int maj, min, numfields, i;
 
 #ifdef __LINE__
     int lineno;
@@ -110,8 +62,17 @@ Code_t ZParseNotice(buffer, len, notice)
     maj = atoi(ptr);
     if (maj != ZVERSIONMAJOR)
        return (ZERR_VERS);
+    while (*ptr != '.') ptr++;
+    min = atoi(ptr+1);
     next_field (ptr);
 
+    if (min == ZVERSIONMINOR_GALAXY) {
+       notice->z_dest_galaxy = ptr;
+       next_field (ptr);
+       /* skip the dummy version field */
+       next_field (ptr);
+    }
+
     if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
        BAD_PACKET;
     numfields = temp;
index 8462bbc0121c8177f2909aed0b7fcb60b8c8be84..4d2e6dfc65418d149ff408c33fc7e8547221b195 100644 (file)
@@ -17,21 +17,6 @@ static char rcsid_ZReadAscii_c[] = "$Id: ZReadAscii.c,v 1.18 1999/01/22 23:19:21
 #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)
index 231594fcf8d5ff5b154c23e73d3180c9e5d88c0c..c53791d14ee4a7f4c62fc846928bd2d8a80fbd6b 100644 (file)
@@ -22,8 +22,9 @@ Code_t ZReceiveNotice(notice, from)
 {
     char *buffer;
     struct _Z_InputQ *nextq;
-    int len, auth;
+    int len, auth, i, j;
     Code_t retval;
+    struct sockaddr_in sin;
 
     if ((retval = Z_WaitForComplete()) != ZERR_NONE)
        return (retval);
@@ -35,9 +36,11 @@ Code_t ZReceiveNotice(notice, from)
     if (!(buffer = (char *) malloc((unsigned) len)))
        return (ENOMEM);
 
-    if (from)
-       *from = nextq->from;
-    
+    if (!from)
+       from = &sin;
+
+    *from = nextq->from;
+
     (void) memcpy(buffer, nextq->packet, len);
 
     auth = nextq->auth;
@@ -46,5 +49,23 @@ Code_t ZReceiveNotice(notice, from)
     if ((retval = ZParseNotice(buffer, len, notice)) != ZERR_NONE)
        return (retval);
     notice->z_checked_auth = auth;
+
+    notice->z_dest_galaxy = "unknown-galaxy";
+
+    if (__ngalaxies == 1) {
+       /* assume everything is in the same galaxy */
+
+       notice->z_dest_galaxy = __galaxy_list[0].galaxy_config.galaxy;
+    } else {
+       for (i=0; i<__ngalaxies; i++)
+           for (j=0; j<__galaxy_list[i].galaxy_config.nservers; j++)
+               if (from->sin_addr.s_addr ==
+                   __galaxy_list[i].galaxy_config.server_list[j].addr.s_addr) {
+                   notice->z_dest_galaxy =
+                       __galaxy_list[i].galaxy_config.galaxy;
+                   break;
+               }
+    }
+
     return ZERR_NONE;
 }
index 0df54e557a00b6462dd90dca99f386232271ce81..1da1a579ce49ddca70386928caf30749250bca5c 100644 (file)
@@ -22,9 +22,11 @@ static Code_t Z_RetSubs ();
 
 /* Need STDC definition when possible for unsigned short argument. */
 #ifdef __STDC__
-Code_t ZRetrieveSubscriptions(unsigned short port, int *nsubs)
+Code_t ZRetrieveSubscriptions(char *galaxy,
+                             unsigned short port, int *nsubs)
 #else
-Code_t ZRetrieveSubscriptions(port,nsubs)
+Code_t ZRetrieveSubscriptions(galaxy,port,nsubs)
+        ZCONST char *galaxy;
        unsigned short port;
        int *nsubs;
 #endif
@@ -44,11 +46,13 @@ Code_t ZRetrieveSubscriptions(port,nsubs)
        notice.z_message = asciiport;
        notice.z_message_len = strlen(asciiport)+1;
        notice.z_opcode = CLIENT_GIMMESUBS;
+       notice.z_dest_galaxy = galaxy;
 
        return(Z_RetSubs(&notice, nsubs, ZAUTH));
 }
 
-Code_t ZRetrieveDefaultSubscriptions(nsubs)
+Code_t ZRetrieveDefaultSubscriptions(galaxy, nsubs)
+       char *galaxy;
        int *nsubs;
 {
        ZNotice_t notice;
@@ -57,6 +61,7 @@ Code_t ZRetrieveDefaultSubscriptions(nsubs)
        notice.z_message = (char *) 0;
        notice.z_message_len = 0;
        notice.z_opcode = CLIENT_GIMMEDEFS;
+       notice.z_dest_galaxy = galaxy;
 
        return(Z_RetSubs(&notice, nsubs, ZNOAUTH));
 
index 12de89e21b1a2e1825e3768533d9060baae3102b..6afd1a81a39399fb6f7f59f996cedf8a4bcc346d 100644 (file)
@@ -21,7 +21,5 @@ Code_t ZSetDestAddr(addr)
 {
        __HM_addr = *addr;
 
-       __HM_set = 1;
-       
        return (ZERR_NONE);
 }
index a150cd2e735db33faa944ca93adc42cb3c92c133..b11498ec4e9e617c61ae869de0265c3aea394a22 100644 (file)
 static const char rcsid_ZSubscriptions_c[] = "$Id: ZSubs.c,v 1.21 1999/01/22 23:19:30 ghudson Exp $";
 #endif
 
-static Code_t Z_Subscriptions __P((register ZSubscription_t *sublist,
+static Code_t Z_Subscriptions __P((char *galaxy,
+                                  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)
+Code_t ZSubscribeTo(galaxy, sublist, nitems, port)
+    char *galaxy;
     ZSubscription_t *sublist;
     int nitems;
     unsigned int port;
 {
-    return (Z_Subscriptions(sublist, nitems, port, CLIENT_SUBSCRIBE, 1));
+    return (Z_Subscriptions(galaxy, sublist, nitems, port,
+                           CLIENT_SUBSCRIBE, 1));
 }
 
-Code_t ZSubscribeToSansDefaults(sublist, nitems, port)
+Code_t ZSubscribeToSansDefaults(galaxy, sublist, nitems, port)
+    char *galaxy;
     ZSubscription_t *sublist;
     int nitems;
     unsigned int port;
 {
-    return (Z_Subscriptions(sublist, nitems, port, CLIENT_SUBSCRIBE_NODEFS,
-                           1));
+    return (Z_Subscriptions(galaxy, sublist, nitems, port,
+                           CLIENT_SUBSCRIBE_NODEFS, 1));
 }
 
-Code_t ZUnsubscribeTo(sublist, nitems, port)
+Code_t ZUnsubscribeTo(galaxy, sublist, nitems, port)
+    char *galaxy;
     ZSubscription_t *sublist;
     int nitems;
     unsigned int port;
 {
-    return (Z_Subscriptions(sublist, nitems, port, CLIENT_UNSUBSCRIBE, 1));
+    return (Z_Subscriptions(galaxy, sublist, nitems, port,
+                           CLIENT_UNSUBSCRIBE, 1));
 }
 
-Code_t ZCancelSubscriptions(port)
+Code_t ZCancelSubscriptions(galaxy, port)
+    char *galaxy;
     unsigned int port;
 {
-    return (Z_Subscriptions((ZSubscription_t *)0, 0, port,
+    return (Z_Subscriptions(galaxy, (ZSubscription_t *)0, 0, port,
                            CLIENT_CANCELSUB, 0));
 }
 
@@ -62,7 +69,8 @@ Code_t ZCancelSubscriptions(port)
  */
 
 static Code_t
-Z_Subscriptions(sublist, nitems, port, opcode, authit)
+Z_Subscriptions(galaxy, sublist, nitems, port, opcode, authit)
+    char *galaxy;
     register ZSubscription_t *sublist;
     int nitems;
     unsigned int port;
@@ -97,6 +105,7 @@ Z_Subscriptions(sublist, nitems, port, opcode, authit)
     notice.z_recipient = "";
     notice.z_default_format = "";
     notice.z_message_len = 0;
+    notice.z_dest_galaxy = galaxy;
 
     /* format the header to figure out how long it is */
     retval = Z_FormatHeader(&notice, header, sizeof(header), &hdrlen, ZAUTH);
index 2e40a570d35aa8d7bf465694e2a78708ec69c3c7..8acedb791ec2d24102643f18ea42830db19dd64e 100644 (file)
@@ -53,5 +53,13 @@ ec  ZERR_TOOMANYSUBS,
        "Too many subscriptions to transmit"
 ec  ZERR_EOF,
        "End of file detected during read"
+ec  ZERR_BADCONF,
+       "Error parsing configuration file"
+ec  ZERR_BADCONFHOST,
+       "Unknown host parsing configuration file"
+ec  ZERR_BADCONFGALAXY,
+       "Galaxy had no servers while parsing configuration file"
+ec  ZERR_GALAXYUNKNOWN,
+       "Unknown zephyr galaxy"
 
        end
index 06cd397f948b2b91a49a58b2aeccf758ab748dbe..1ac72bf3edc9e166bc5acc4957e3d0b4c31d36e2 100755 (executable)
@@ -4,7 +4,7 @@
 # Created: 1993-05-16
 # Public domain
 
-# $Id: mkinstalldirs,v 1.1 1999/11/01 19:33:54 danw Exp $
+# $Id: mkinstalldirs,v 1.1 2001/03/26 01:51:07 raeburn Exp $
 
 errstatus=0
 
index da5015a6c93ed701689fcaa7a132839402ca566f..3077236fb4ab6eafa2b000555b1cf908097900ea 100644 (file)
@@ -3,7 +3,7 @@
  *
  *     Created by:     John T. Kohl
  *
- *     $Source: /afs/dev.mit.edu/source/repository/athena/lib/zephyr/server/bdump.c,v $
+ *     $Source: /var/raeburn/z/repos/athena/lib/zephyr/server/bdump.c,v $
  *     $Id: bdump.c,v 1.54 2001/02/27 04:43:01 zacheiss Exp $
  *     $Author: zacheiss $
  *
@@ -289,7 +289,7 @@ bdump_send()
     }
     if (strcmp(kdata.pname, SERVER_SERVICE) ||
        strcmp(kdata.pinst, SERVER_INSTANCE) ||
-       strcmp(kdata.prealm, ZGetRealm())) {
+       strcmp(kdata.prealm, my_krealm)) {
        syslog(LOG_ERR, "bdump_send: peer not zephyr: %s.%s@%s",
               kdata.pname, kdata.pinst, kdata.prealm);
        cleanup(server);
@@ -478,7 +478,7 @@ bdump_get_v12 (notice, auth, who, server)
 
     if (strcmp(kdata.pname, SERVER_SERVICE) ||
        strcmp(kdata.pinst, SERVER_INSTANCE) ||
-       strcmp(kdata.prealm, ZGetRealm())) {
+       strcmp(kdata.prealm, my_krealm)) {
        syslog(LOG_ERR, "bdump_get: peer not zephyr in lrealm: %s.%s@%s",
               kdata.pname, kdata.pinst,kdata.prealm);
        cleanup(server);
@@ -691,9 +691,6 @@ get_tgt()
     static char buf[INST_SZ + 1] = SERVER_INSTANCE;
     int retval = 0;
     CREDENTIALS cred;
-#ifndef NOENCRYPTION
-    Sched *s;
-#endif
        
     /* have they expired ? */
     if (ticket_time < NOW - tkt_lifetime(TKTLIFETIME) + (15L * 60L)) {
@@ -704,8 +701,8 @@ get_tgt()
 #endif
        dest_tkt();
 
-       retval = krb_get_svc_in_tkt(SERVER_SERVICE, buf, ZGetRealm(),
-                                   "krbtgt", ZGetRealm(),
+       retval = krb_get_svc_in_tkt(SERVER_SERVICE, buf, my_krealm,
+                                   "krbtgt", my_krealm,
                                    TKTLIFETIME, srvtab_file);
        if (retval != KSUCCESS) {
            syslog(LOG_ERR,"get_tgt: krb_get_svc_in_tkt: %s",
@@ -718,20 +715,27 @@ get_tgt()
 
 #ifndef NOENCRYPTION
        retval = read_service_key(SERVER_SERVICE, SERVER_INSTANCE,
-                                 ZGetRealm(), 0 /*kvno*/,
+                                 my_krealm, 0 /*kvno*/,
                                  srvtab_file, serv_key);
        if (retval != KSUCCESS) {
            syslog(LOG_ERR, "get_tgt: read_service_key: %s",
                   krb_get_err_text(retval));
            return 1;
        }
-       s = (Sched *) check_key_sched_cache(serv_key);
-       if (s) {
-           serv_ksched = *s;
-       } else {
-           des_key_sched(serv_key, serv_ksched.s);
-           add_to_key_sched_cache(serv_key, &serv_ksched);
+#ifdef BAD_KRB4_HACK
+       {
+               Sched *s;
+               s = (Sched *) check_key_sched_cache(serv_key);
+               if (s) {
+                       serv_ksched = *s;
+               } else {
+                       des_key_sched(serv_key, serv_ksched.s);
+                       add_to_key_sched_cache(serv_key, &serv_ksched);
+               }
        }
+#else
+       des_key_sched(serv_key, serv_ksched.s);
+#endif
 #endif /* !NOENCRYPTION */
     }
     return(0);
index c84286499feaae58b49cfeafa893a3f454276bbf..da3bfbd3abd38e60ff2de6f0cf35618c76cf8252 100644 (file)
@@ -3,7 +3,7 @@
  *
  *     Created by:     John T. Kohl
  *
- *     $Source: /afs/dev.mit.edu/source/repository/athena/lib/zephyr/server/class.c,v $
+ *     $Source: /var/raeburn/z/repos/athena/lib/zephyr/server/class.c,v $
  *     $Author: zacheiss $
  *
  *     Copyright (c) 1987 by the Massachusetts Institute of Technology.
index 276f7ea2d739b5b94a83e3c73034f035e75513c3..e2c6c841042e2e65abf8104dc3e974eca36dbc63 100644 (file)
@@ -3,7 +3,7 @@
  *
  *     Created by:     John T. Kohl
  *
- *     $Source: /afs/dev.mit.edu/source/repository/athena/lib/zephyr/server/dispatch.c,v $
+ *     $Source: /var/raeburn/z/repos/athena/lib/zephyr/server/dispatch.c,v $
  *     $Author: ghudson $
  *
  *     Copyright (c) 1987, 1991 by the Massachusetts Institute of Technology.
@@ -18,7 +18,7 @@
 #ifndef lint
 #ifndef SABER
 static const char rcsid_dispatch_c[] =
-"$Id: dispatch.c,v 1.63 2001/04/10 23:28:19 ghudson Exp $";
+"$Id: dispatch.c,v 1.62 2001/03/05 22:22:03 ghudson Exp $";
 #endif
 #endif
 
@@ -52,11 +52,12 @@ ZCONST char *ZNoticeKinds[9] = {"UNSAFE", "UNACKED", "ACKED", "HMACK",
  * void nack_release(client)
  *     Client *client;
  *
- * void sendit(notice, auth, who, external)
+ * void sendit(notice, auth, who, external, local_dest)
  *     ZNotice_t *notice;
  *     int auth;
  *     struct sockaddr_in *who;
  *      int external;
+ *     int local_dest;
  *
  * void xmit(notice, dest, auth, client)
  *     ZNotice_t *notice;
@@ -251,13 +252,24 @@ dispatch(notice, auth, who, from_server)
     String *notice_class;
     struct sockaddr_in who2;
     int authflag;
-    Realm *realm;
-    char *cp;
 #ifdef DEBUG
     char dbg_buf[BUFSIZ];
 #endif
 
-    authflag = (auth == ZAUTH_YES);
+    /* Set "authflag" to 1 or 0 for handler functions.  Treat
+     * ZAUTH_CKSUM_FAILED as authentic except for sendit(), which is
+     * handled below. */
+    switch (auth) {
+      case ZAUTH_YES:
+      case ZAUTH_CKSUM_FAILED:
+       authflag = 1;
+       break;
+      case ZAUTH_FAILED:
+      case ZAUTH_NO:
+      default:
+       authflag = 0;
+       break;
+    }
 
     if ((int) notice->z_kind < (int) UNSAFE ||
        (int) notice->z_kind > (int) CLIENTACK) {
@@ -311,21 +323,122 @@ dispatch(notice, auth, who, from_server)
        admin_notices.val++;
        status = server_adispatch(notice, authflag, who, me_server);
     } else {
-       if (!realm_bound_for_realm(ZGetRealm(), notice->z_recipient)) {
-           cp = strchr(notice->z_recipient, '@');
-           if (!cp ||
-               !(realm = realm_get_realm_by_name(cp + 1))) {
-               /* Foreign user, local realm */
-               sendit(notice, authflag, who, 0);
-           } else
+       char *finalat, *inlhsat;
+       Realm *realm;
+
+       if (auth == ZAUTH_CKSUM_FAILED)
+           authflag = 0;
+
+       /*
+
+shadow@ANDREW.CMU.EDU:
+
+according to my whiteboard [external==0 indicates]:
+
+a message from a remote server to a local user
+
+a message from a remote server for remote broadcast (which i
+don't think happens)
+
+a message from a remote server for remote user (also doesn't happen)
+
+and a message from a remote server for a local foreign user (a message
+from ANDREW.CMU.EDU to ATHENA.MIT.EDU for jesse@FSCK.COM)
+
+it also claims a local client to local user message "could be external
+== 0 but is not"
+
+       */
+       /* The idea is that an individual recipient is either a
+          kerberos-form name or a galaxy-augmented kerberos-form
+          name.
+
+          possible cases:
+
+          1. The recipient is name-with-ats@rhs.  The message has a
+          remote individual destination name-with-ats in the rhs
+          galaxy. [galaxy-augmented kerberos-form name]
+
+          2. The recipient is lhs@rhs. [kerberos-form name]
+
+          2a. lhs@rhs has a subscription in the local galaxy.  The
+          message has a local individual destination
+          lhs@rhs. [kerberos-form name for local galaxy]
+
+          2b. rhs is a trusted galaxy whose kerberos realm, if any,
+          is also (case insensitively) rhs.  The message has a remote
+          individual destination lhs@rhs in the rhs galaxy.  A
+          trusted galaxy is one for which is is believed that a user
+          who may subscribe locally as lhs@rhs (case 2a) is the same
+          user as lhs@rhs in the rhs galaxy.  Such determination is
+          currently made by static configuration of trusted galaxies.
+          [kerberos-form name for remote galaxy]
+
+          3. The recipient is @rhs, and rhs is a trusted remote
+          galaxy.  The message has a remote broadcast destination in
+          the rhs galaxy. [broadcast recipient in remote galaxy]
+
+          4. The recipient has no @s.  The message has a local
+          individual destination. [unqualified kerberos-form name]
+
+          5. The recipient is empty.  The message has a local
+          broadcast destination. [broadcast recipient in local
+          galaxy]
+
+          6. The recipient has some other form.  The message is
+          invalid.
+
+       */
+
+       finalat = strrchr(notice->z_recipient, '@');
+
+       if (finalat && finalat > notice->z_recipient) {
+           /* XXX eeew. */
+           *finalat = '\0';
+           inlhsat = strrchr(notice->z_recipient, '@');
+           *finalat = '@';
+
+           if (inlhsat == finalat-1) {
+               /* @foo@bar is not legal */
+               nack(notice, who);
+           } else if (inlhsat) {
+               /* foo@bar@galaxy */
+               Realm *realm = realm_get_realm_by_name(finalat+1);
+               if (!realm) {
+                   /* case 1, unknown galaxy */
+                   nack(notice, who);
+               } else if (strcmp(realm->name, my_galaxy) == 0) {
+                   /* case 1, explict local galaxy */
+                   *finalat = '\0';
+                   sendit(notice, authflag, who, 0, 1);
+               } else {
+                   /* case 1 */
+                   *finalat = '\0';
+                   realm_handoff(notice, authflag, who, realm, 1);
+               }
+           } else {
+               /* foo@bar */
+               /* 2a is handled by sendit directly; 2b is handled at
+                  the end of sendit if there were no subscriptions */
+               sendit(notice, authflag, who, 1, 1);
+           }
+       } else if (finalat) {
+           /* case 3: @foo */
+           Realm *realm = realm_get_realm_by_name(finalat+1);
+           if (!realm) {
+               nack(notice, who);
+           } else if (strcmp(realm->name, my_galaxy) == 0) {
+               sendit(notice, authflag, who, 1, 1);
+           } else {
                realm_handoff(notice, authflag, who, realm, 1);
+           }
+       } else if (notice->z_recipient[0] != '\0') {
+           /* case 4: foo */
+           sendit(notice, authflag, who, 0, 1);
        } else {
-           if (notice->z_recipient[0] == '@')
-               notice->z_recipient = "";
-           sendit(notice, authflag, who, 1);
+           /* case 5: null recipient */
+           sendit(notice, authflag, who, 1, 1);
        }
-       free_string(notice_class);
-       return;
     }
 
     if (status == ZSRV_REQUEUE)
@@ -337,12 +450,15 @@ dispatch(notice, auth, who, from_server)
  * Send a notice off to those clients who have subscribed to it.
  */
 
+/* this never gets called with external==1; local_dest==0 */
+
 void
-sendit(notice, auth, who, external)
+sendit(notice, auth, who, external, local_dest)
     ZNotice_t *notice;
     int auth;
     struct sockaddr_in *who;
     int external;
+    int local_dest;
 {
     static int send_counter = 0;
     char recipbuf[ANAME_SZ + INST_SZ + REALM_SZ + 3], *recipp;
@@ -352,7 +468,8 @@ sendit(notice, auth, who, external)
     String *class;
 
     class = make_string(notice->z_class, 1);
-    if (realm_bound_for_realm(ZGetRealm(), notice->z_recipient)) {
+    /* if (realm_bound_for_my_galaxy(notice->z_recipient)) { */
+    if (local_dest) {
       Realm *rlm;
 
       acl = class_get_acl(class);
@@ -435,10 +552,10 @@ sendit(notice, auth, who, external)
     /* Send to clients subscribed to the triplet itself. */
     dest.classname = class;
     dest.inst = make_string(notice->z_class_inst, 1);
-    if (realm_bound_for_realm(ZGetRealm(), notice->z_recipient) && 
-       *notice->z_recipient == '@') 
+    /* if (realm_bound_for_my_galaxy(notice->z_recipient) && */
+    if (local_dest && *notice->z_recipient == '@') {
       dest.recip = make_string("", 0);
-    else {
+    else {
       strncpy(recipbuf, notice->z_recipient, sizeof(recipbuf));
       recipp = strrchr(recipbuf, '@');
       if (recipp)
@@ -458,17 +575,29 @@ sendit(notice, auth, who, external)
 
     free_string(class);
     free_string(dest.recip);
-    if (any)
+    if (any) {
        ack(notice, who);
-    else
+    } else if (external) {
+       /* check to see if the recipient is really a name in another
+          known galaxy */
+       Realm *realm;
+       char *galaxy = strchr(notice->z_recipient, '@');
+
+       if (galaxy && galaxy > notice->z_recipient &&
+           (realm = realm_get_realm_by_name(galaxy)))
+           realm_handoff(notice, auth, who, realm, 1);
+       else
+           nack(notice, who);
+    } else {
        nack(notice, who);
+    }
 }
 
 /*
  * Send to each client in the list.  Avoid duplicates by setting
  * last_send on each client to send_counter, a nonce which is updated
- * by sendit() above.
- */
+ * by sendit() above.  If the destination is a remote galaxy, send
+ * there only if external==1 */
 
 static int
 send_to_dest(notice, auth, dest, send_counter, external)
@@ -602,6 +731,7 @@ xmit(notice, dest, auth, client)
     Unacked *nacked;
     int packlen, sendfail = 0;
     Code_t retval;
+    struct in_addr my_addr;
 
 #if 0
     zdbug((LOG_DEBUG,"xmit"));
@@ -678,7 +808,7 @@ xmit(notice, dest, auth, client)
           buffer_len = sizeof(ZPacket_t);
 
           retval = Z_FormatRawHeader(&partnotice, buffer, buffer_len, 
-                                     &hdrlen, NULL, NULL);
+                                     &hdrlen, NULL, NULL, NULL, NULL);
           if (retval != ZERR_NONE) {
             syslog(LOG_ERR, "xmit unauth refrag fmt: failed");
             free(buffer);
@@ -694,7 +824,9 @@ xmit(notice, dest, auth, client)
                 return;
               }
 
-              fragsize = Z_MAXPKTLEN-hdrlen-Z_FRAGFUDGE;
+         fragsize = Z_MAXPKTLEN-hdrlen-Z_FRAGFUDGE;
+
+         Z_SourceAddr(&client->addr.sin_addr, &my_addr);
 
           while (offset < notice->z_message_len || !notice->z_message_len) {
             (void) sprintf(multi, "%d/%d", offset+origoffset, origlen);
@@ -705,15 +837,15 @@ xmit(notice, dest, auth, client)
                                                  partnotice.z_uid.tv.tv_sec);
               partnotice.z_uid.tv.tv_usec = htonl((u_long)
                                                   partnotice.z_uid.tv.tv_usec);
-              (void) memcpy((char *)&partnotice.z_uid.zuid_addr, &__My_addr,
-                            sizeof(__My_addr));
+              (void) memcpy((char *)&partnotice.z_uid.zuid_addr, &my_addr,
+                            sizeof(my_addr));
             }
             partnotice.z_message = notice->z_message+offset;
             message_len = min(notice->z_message_len-offset, fragsize);
             partnotice.z_message_len = message_len;
 
             retval = Z_FormatRawHeader(&partnotice, buffer, buffer_len, 
-                                       &hdrlen, &ptr, NULL);
+                                       &hdrlen, NULL, NULL, &ptr, NULL);
             if (retval != ZERR_NONE) {
               syslog(LOG_WARNING, "xmit unauth refrag raw: %s",
                      error_message(retval));
@@ -991,11 +1123,6 @@ nack_cancel(notice, who)
 #endif
 }
 
-/* for compatibility when sending subscription information to old clients */
-#ifdef OLD_COMPAT
-#define        OLD_ZEPHYR_VERSION      "ZEPH0.0"
-#endif /* OLD_COMPAT */
-
 /* Dispatch an HM_CTL notice. */
 
 Code_t
@@ -1122,14 +1249,7 @@ control_dispatch(notice, auth, who, server)
           someone who has no subscriptions does NOT get a SERVNAK
           but rather an empty list.  Note we must therefore
           check authentication inside subscr_sendlist */
-#ifdef OLD_COMPAT
-       /* only acknowledge if *not* old version; the old version
-          acknowledges the packet with the reply */
-       if (strcmp(notice->z_version, OLD_ZEPHYR_VERSION) != 0)
-           ack(notice, who);
-#else /* !OLD_COMPAT */
        ack(notice, who);
-#endif /* OLD_COMPAT */
        subscr_sendlist(notice, auth, who);
        return ZERR_NONE;
     } else if (!auth) {
@@ -1337,17 +1457,13 @@ static char *
 hm_recipient()
 {
     static char *recipient;
-    char *realm;
 
     if (recipient)
        return recipient;
 
-    realm = ZGetRealm();
-    if (!realm)
-       realm = "???";
-    recipient = (char *) malloc(strlen(realm) + 4);
+    recipient = (char *) malloc(strlen(my_galaxy) + 4);
     strcpy (recipient, "hm@");
-    strcat (recipient, realm);
+    strcat (recipient, my_galaxy);
     return recipient;
 }
 
index 5fd31c9f2a0e57b54938a9c012c3028314e457d3..4a67faa58e6d2dc3fc60211c0328624c12af847a 100644 (file)
@@ -8,20 +8,21 @@
  *     "mit-copyright.h". 
  */
 /*
- *     $Source: /afs/dev.mit.edu/source/repository/athena/lib/zephyr/server/kstuff.c,v $
- *     $Header: /afs/dev.mit.edu/source/repository/athena/lib/zephyr/server/kstuff.c,v 1.26 2001/04/10 23:28:20 ghudson Exp $
+ *     $Id: kstuff.c,v 1.25 2001/03/05 23:19:02 ghudson Exp $
  */
 
 #include "zserver.h"
 
 #ifndef lint
 #ifndef SABER
-static const char rcsid_kstuff_c[] = "$Id: kstuff.c,v 1.26 2001/04/10 23:28:20 ghudson Exp $";
+static const char rcsid_kstuff_c[] = "$Id: kstuff.c,v 1.25 2001/03/05 23:19:02 ghudson Exp $";
 #endif
 #endif
 
 #ifdef HAVE_KRB4
 
+C_Block __Zephyr_session;
+
 /* Keep a hash table mapping tickets to session keys, so we can do a fast
  * check of the cryptographic checksum without doing and DES decryptions.
  * Also remember the expiry time of the ticket, so that we can sweep the
@@ -43,9 +44,11 @@ struct hash_entry {
 
 Hash_entry *hashtab[HASHTAB_SIZE];
 
+#ifdef BAD_KRB4_HACK
 static int hash_ticket __P((unsigned char *, int));
 static void add_session_key __P((KTEXT, C_Block, char *, time_t));
 static int find_session_key __P((KTEXT, C_Block, char *));
+#endif
 static ZChecksum_t compute_checksum __P((ZNotice_t *, C_Block));
 static ZChecksum_t compute_rlm_checksum __P((ZNotice_t *, C_Block));
 
@@ -125,7 +128,7 @@ SendKerberosData(fd, ticket, service, host)
     int written;
     int size_to_write;
 
-    rem = krb_mk_req(ticket, service, host, ZGetRealm(), (u_long) 0);
+    rem = krb_mk_req(ticket, service, host, my_galaxy, (u_long) 0);
     if (rem != KSUCCESS)
        return rem + krb_err_base;
 
@@ -152,7 +155,10 @@ ZCheckRealmAuthentication(notice, from, realm)
     int result;
     char rlmprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4];
     char srcprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4];
-    KTEXT_ST authent, ticket;
+    KTEXT_ST authent;
+#ifdef BAD_KRB4_HACK
+    KTEXT_ST ticket;
+#endif
     AUTH_DAT dat;
     ZChecksum_t checksum;
     CREDENTIALS cred;
@@ -174,13 +180,14 @@ ZCheckRealmAuthentication(notice, from, realm)
     }
     authent.length = notice->z_authent_len;
 
+    (void) sprintf(rlmprincipal, "%s.%s@%s", SERVER_SERVICE,
+                   SERVER_INSTANCE, realm);
+
+#ifdef BAD_KRB4_HACK
     /* Copy the ticket out of the authentication data. */
     if (krb_find_ticket(&authent, &ticket) != RD_AP_OK)
         return ZAUTH_FAILED;
 
-    (void) sprintf(rlmprincipal, "%s.%s@%s", SERVER_SERVICE,
-                   SERVER_INSTANCE, realm);
-
     /* Try to do a fast check against the cryptographic checksum. */
     if (find_session_key(&ticket, session_key, srcprincipal) >= 0) {
         if (strcmp(srcprincipal, rlmprincipal) != 0)
@@ -189,12 +196,13 @@ ZCheckRealmAuthentication(notice, from, realm)
             return ZAUTH_FAILED;
         checksum = compute_rlm_checksum(notice, session_key);
 
-        /* If checksum matches, packet is authentic.  If not, we might
-         * have an outdated session key, so keep going the slow way.
-         */
+        /* If checksum matches, packet is authentic.  Otherwise, check
+         * the authenticator as if we didn't have the session key cached
+         * and return ZAUTH_CKSUM_FAILED.  This is a rare case (since the
+         * ticket isn't cached after a checksum failure), so don't worry
+         * about the extra des_quad_cksum() call. */
         if (checksum == notice->z_checksum) {
-          (void) memcpy((char *)__Zephyr_session, (char *)session_key, 
-                        sizeof(C_Block)); /* For control_dispatch() */
+          memcpy(__Zephyr_session, session_key, sizeof(C_Block)); 
           return ZAUTH_YES;
         }
 
@@ -207,6 +215,7 @@ ZCheckRealmAuthentication(notice, from, realm)
            return ZAUTH_YES;
         }
     }
+#endif
 
     /* We don't have the session key cached; do it the long way. */
     result = krb_rd_req(&authent, SERVER_SERVICE, SERVER_INSTANCE,
@@ -231,13 +240,15 @@ ZCheckRealmAuthentication(notice, from, realm)
       checksum = compute_checksum(notice, dat.session);
       if (checksum != notice->z_checksum)
 #endif
-        return ZAUTH_FAILED;
+         return ZAUTH_CKSUM_FAILED;
     }
 
+#ifdef BAD_KRB4_HACK
     /* Record the session key, expiry time, and source principal in the
      * hash table, so we can do a fast check next time. */
     add_session_key(&ticket, dat.session, srcprincipal,
                     (time_t)(dat.time_sec + dat.life * 5 * 60));
+#endif
 
     return ZAUTH_YES;
 
@@ -254,7 +265,10 @@ ZCheckAuthentication(notice, from)
 #ifdef HAVE_KRB4
     int result;
     char srcprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4];
-    KTEXT_ST authent, ticket;
+    KTEXT_ST authent;
+#ifdef BAD_KRB4_HACK
+    KTEXT_ST ticket;
+#endif
     AUTH_DAT dat;
     ZChecksum_t checksum;
     C_Block session_key;
@@ -275,6 +289,7 @@ ZCheckAuthentication(notice, from)
     }
     authent.length = notice->z_authent_len;
 
+#ifdef BAD_KRB4_HACK
     /* Copy the ticket out of the authentication data. */
     if (krb_find_ticket(&authent, &ticket) != RD_AP_OK)
        return ZAUTH_FAILED;
@@ -287,14 +302,17 @@ ZCheckAuthentication(notice, from)
            return ZAUTH_FAILED;
        checksum = compute_checksum(notice, session_key);
 
-        /* If checksum matches, packet is authentic.  If not, we might
-        * have an outdated session key, so keep going the slow way.
-        */
+       /* If the checksum matches, the packet is authentic.  Otherwise,
+        * check authenticator as if we didn't have the session key cached
+        * and return ZAUTH_CKSUM_FAILED.  This is a rare case (since the
+        * ticket isn't cached after a checksum failure), so don't worry
+        * about the extra des_quad_cksum() call. */
        if (checksum == notice->z_checksum) {
            memcpy(__Zephyr_session, session_key, sizeof(C_Block));
            return ZAUTH_YES;
        }
     }
+#endif
 
     /* We don't have the session key cached; do it the long way. */
     result = krb_rd_req(&authent, SERVER_SERVICE, SERVER_INSTANCE,
@@ -316,12 +334,14 @@ ZCheckAuthentication(notice, from)
     checksum = compute_checksum(notice, dat.session);
 #endif
     if (checksum != notice->z_checksum)
-       return ZAUTH_FAILED;
+       return ZAUTH_CKSUM_FAILED;
 
+#ifdef BAD_KRB4_HACK
     /* Record the session key, expiry time, and source principal in the
      * hash table, so we can do a fast check next time. */
     add_session_key(&ticket, dat.session, srcprincipal,
                    (time_t)(dat.time_sec + dat.life * 5 * 60));
+#endif
 
     return ZAUTH_YES;
 
@@ -332,6 +352,8 @@ ZCheckAuthentication(notice, from)
 
 #ifdef HAVE_KRB4
 
+#ifdef BAD_KRB4_HACK
+
 static int hash_ticket(p, len)
     unsigned char *p;
     int len;
@@ -400,6 +422,8 @@ static int find_session_key(ticket, key, srcprincipal)
     return -1;
 }
 
+#endif
+
 static ZChecksum_t compute_checksum(notice, session_key)
     ZNotice_t *notice;
     C_Block session_key;
index 00e6ab00bcbfbaf4a2ac7cf0f901f64841b3d67f..a8ccdd1b0e8371f03da25c63fe4e1a72027b4e01 100644 (file)
@@ -3,7 +3,7 @@
  *
  *     Created by:     John T. Kohl
  *
- *     $Source: /afs/dev.mit.edu/source/repository/athena/lib/zephyr/server/subscr.c,v $
+ *     $Source: /var/raeburn/z/repos/athena/lib/zephyr/server/subscr.c,v $
  *     $Author: zacheiss $
  *
  *     Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
@@ -16,7 +16,7 @@
 
 #ifndef lint
 #ifndef SABER
-static const char rcsid_subscr_c[] = "$Id: subscr.c,v 1.58 2001/03/01 00:47:05 zacheiss Exp $";
+static const char rcsid_subscr_c[] = "$Id: subscr.c,v 1.59 2001/07/03 03:28:31 zacheiss Exp $";
 #endif
 #endif
 
@@ -70,29 +70,14 @@ Sched       serv_ksched;
 
 /* for compatibility when sending subscription information to old clients */
 
-#ifdef OLD_COMPAT
-#define        OLD_ZEPHYR_VERSION      "ZEPH0.0"
-#define        OLD_CLIENT_INCOMPSUBS   "INCOMP"
-static void old_compat_subscr_sendlist __P((ZNotice_t *notice, int auth,
-                                         struct sockaddr_in *who));
-extern int old_compat_count_subscr;    /* counter of old use */
-#endif /* OLD_COMPAT */
-#ifdef NEW_COMPAT
-#define NEW_OLD_ZEPHYR_VERSION "ZEPH0.1"
-static void new_old_compat_subscr_sendlist __P((ZNotice_t *notice, int auth,
-                                             struct sockaddr_in *who)); 
-extern int new_compat_count_subscr;    /* counter of old use */
-#endif /* NEW_COMPAT */
-
 extern char *re_comp(), *re_conv();
 static Code_t add_subscriptions __P((Client *who, Destlist *subs_queue,
                                   ZNotice_t *notice, Server *server));
 static Destlist *extract_subscriptions __P((ZNotice_t *notice));
 static void free_subscriptions __P((Destlist *subs));
 static void free_subscription __P((Destlist *sub));
-static char **subscr_marshal_subs __P((ZNotice_t *notice, int auth,
-                                    struct sockaddr_in *who,
-                                    int *found));
+static char **subscr_marshal_subs __P((Destlist *subs, 
+                                      int *found));
 static Destlist *subscr_copy_def_subs __P((char *person));
 static Code_t subscr_realm_sendit __P((Client *who, Destlist *subs,
                                       ZNotice_t *notice, Realm *realm));
@@ -157,7 +142,7 @@ add_subscriptions(who, subs, notice, server)
        /* check the recipient for a realm which isn't ours */
        realm = NULL;
        if (subs->dest.recip->string[0] == '@' &&
-           strcmp((subs->dest.recip->string + 1), ZGetRealm()) != 0)
+           strcmp((subs->dest.recip->string + 1), my_galaxy) != 0)
            realm = realm_get_realm_by_name(subs->dest.recip->string + 1);
        if (!bdumping) {
            if (subs->dest.recip != empty && subs->dest.recip != sender
@@ -186,14 +171,19 @@ add_subscriptions(who, subs, notice, server)
                }
            }
        }
-       if (realm && !bdumping && server && server == me_server) {
-           retval = subscr_realm_sendit(who, subs, notice, realm);
-           if (retval != ZERR_NONE) {
-               free_subscriptions(subs);
-               free_string(sender);
-               return(retval);
+       if (realm && !bdumping) {
+           if (server && server == me_server) {
+               retval = subscr_realm_sendit(who, subs, notice, realm);
+               if (retval != ZERR_NONE) {
+                   free_subscriptions(subs);
+                   free_string(sender);
+                   return(retval);
+               } else {
+                   /* free this one, will get from ADD */
+                   free_subscription(subs);
+               }
            } else {
-             free_subscription(subs); /* free this one, will get from ADD */
+                   /* Indicates we leaked traffic back to our realm */
            }
        } else {
          retval = triplet_register(who, &subs->dest, NULL);
@@ -485,28 +475,15 @@ subscr_sendlist(notice, auth, who)
     int auth;
     struct sockaddr_in *who;
 {
-    char **answer;
+    unsigned short temp;
+    int defsubs = 0;
+    Destlist *subs = NULL;
+    Client *client;
+    char **answer = NULL;
     int found;
     struct sockaddr_in send_to_who;
     Code_t retval;
 
-#ifdef OLD_COMPAT
-    if (strcmp(notice->z_version, OLD_ZEPHYR_VERSION) == 0) {
-       /* we are talking to an old client; use the old-style
-          acknowledgement-message */
-       old_compat_subscr_sendlist(notice, auth, who);
-       return;
-    }
-#endif /* OLD_COMPAT */
-#ifdef NEW_COMPAT
-    if (strcmp(notice->z_version, NEW_OLD_ZEPHYR_VERSION) == 0) {
-       /* we are talking to a new old client; use the new-old-style
-          acknowledgement-message */
-       new_old_compat_subscr_sendlist(notice, auth, who);
-       return;
-    }
-#endif /* NEW_COMPAT */
-    answer = subscr_marshal_subs(notice, auth, who, &found);
     send_to_who = *who;
     send_to_who.sin_port = notice->z_port;  /* Return port */
 
@@ -514,55 +491,13 @@ subscr_sendlist(notice, auth, who)
     if (retval != ZERR_NONE) {
        syslog(LOG_WARNING, "subscr_sendlist set addr: %s",
               error_message(retval));
-       if (answer)
-           free(answer);
        return;
     }
 
-    /* XXX for now, don't do authentication */
-    auth = 0;
-
-    notice->z_kind = ACKED;
-
-    /* use xmit_frag() to send each piece of the notice */
-
-    retval = ZSrvSendRawList(notice, answer, found * NUM_FIELDS, xmit_frag);
-    if (retval != ZERR_NONE)
-       syslog(LOG_WARNING, "subscr_sendlist xmit: %s", error_message(retval));
-    if (answer)
-       free(answer);
-}
-
-static char **
-subscr_marshal_subs(notice, auth, who, found)
-    ZNotice_t *notice;
-    int auth;
-    struct sockaddr_in *who;
-    int *found;
-{
-    char **answer = NULL;
-    unsigned short temp;
-    Code_t retval;
-    Client *client;
-    Destlist *subs = NULL, *sub;
-    int i;
-    int defsubs = 0;
-
-#if 0
-    zdbug((LOG_DEBUG, "subscr_marshal"));
-#endif
-    *found = 0;
-
-    /* Note that the following code is an incredible crock! */
-       
-    /* We cannot send multiple packets as acknowledgements to the client,
-       since the hostmanager will ignore the later packets.  So we need
-       to send directly to the client. */
-
-    /* Make our own copy so we can send directly back to the client */
-    /* RSF 11/07/87 */
-
     if (strcmp(notice->z_opcode, CLIENT_GIMMESUBS) == 0) {
+       if (!auth)
+           goto got_answer;
+
        /* If the client has requested his current subscriptions,
           the message field of the notice contains the port number
           of the client for which the sender desires the subscription
@@ -572,11 +507,25 @@ subscr_marshal_subs(notice, auth, who, found)
        if (retval != ZERR_NONE) {
            syslog(LOG_WARNING, "subscr_marshal read port num: %s",
                   error_message(retval));
-           return(NULL);
+           goto got_answer;
        }
 
        client = client_find(&who->sin_addr, htons(temp));
 
+       if (!client)
+           goto got_answer;
+
+       /* check authenticity here.  The user must be authentic to get
+          a list of subscriptions. */
+
+       if (strcmp(client->principal->string, notice->z_sender) != 0) {
+           zdbug ((LOG_DEBUG,
+                   "subscr_marshal: %s requests subs for %s at %s/%d",
+                   notice->z_sender, client->principal->string,
+                   inet_ntoa(who->sin_addr), ntohs(who->sin_port)));
+           goto got_answer;
+       }
+
        if (client)
            subs = client->subs;
     } else if (strcmp(notice->z_opcode, CLIENT_GIMMEDEFS) == 0) {
@@ -591,237 +540,74 @@ subscr_marshal_subs(notice, auth, who, found)
     } else {
        syslog(LOG_ERR, "subscr_marshal bogus opcode %s",
               notice->z_opcode);
-       return(NULL);
+       goto got_answer;
     }
 
-    if (subs) {
+    answer = subscr_marshal_subs(subs, &found);
 
-       /* check authenticity here.  The user must be authentic to get
-          a list of subscriptions. If he is not subscribed to
-          anything, this if-clause fails, and he gets a response
-          indicating no subscriptions.
-          if retrieving default subscriptions, don't care about
-          authentication. */
-
-       if (!auth && !defsubs)
-           return(NULL);
-       if (!defsubs) {
-           if (client && (strcmp(client->principal->string,
-                                 notice->z_sender) != 0)) {
-               zdbug ((LOG_DEBUG,
-                       "subscr_marshal: %s requests subs for %s at %s/%d",
-                       notice->z_sender, client->principal->string,
-                       inet_ntoa(who->sin_addr), ntohs(who->sin_port)));
-               return 0;
-           }
-       }
-
-       for (sub = subs; sub; sub = sub->next)
-           (*found)++;
+ got_answer:
+    notice->z_kind = ACKED;
 
-       /* found is now the number of subscriptions */
+    /* use xmit_frag() to send each piece of the notice */
 
-       /* coalesce the subscription information into a list of char *'s */
-       answer = (char **) malloc((*found) * NUM_FIELDS * sizeof(char *));
-       if (answer == NULL) {
-           syslog(LOG_ERR, "subscr no mem(answer)");
-           *found = 0;
-       } else {
-           i = 0;
-           for (sub = subs; sub; sub = sub->next) {
-               answer[i * NUM_FIELDS] = sub->dest.classname->string;
-               answer[i * NUM_FIELDS + 1] = sub->dest.inst->string;
-               answer[i * NUM_FIELDS + 2] = sub->dest.recip->string;
-               i++;
-           }
-       }
-    }
+    retval = ZSrvSendRawList(notice, answer, found * NUM_FIELDS, xmit_frag);
+    if (retval != ZERR_NONE)
+       syslog(LOG_WARNING, "subscr_sendlist xmit: %s", error_message(retval));
     if (defsubs)
        free_subscriptions(subs);
-    return answer;
+    if (answer)
+       free(answer);
 }
 
-#ifdef NEW_COMPAT
-static void
-new_old_compat_subscr_sendlist(notice, auth, who)
-    ZNotice_t *notice;
-    int auth;
-    struct sockaddr_in *who;
+static char **
+subscr_marshal_subs(subs, found)
+    Destlist *subs;
+    int *found;
 {
+    char **answer = NULL;
     Code_t retval;
-    ZNotice_t reply;
-    ZPacket_t reppacket;
-    int packlen, found, count, initfound, zerofound;
-    char buf[64];
-    const char **answer;
-    struct sockaddr_in send_to_who;
+    Destlist *sub;
     int i;
 
-    new_compat_count_subscr++;
-
-    syslog(LOG_INFO, "new old subscr, %s", inet_ntoa(who->sin_addr));
-    reply = *notice;
-    reply.z_kind = SERVACK;
-    reply.z_authent_len = 0; /* save some space */
-    reply.z_auth = 0;
-
-    send_to_who = *who;
-    send_to_who.sin_port = notice->z_port;  /* Return port */
-
-    retval = ZSetDestAddr(&send_to_who);
-    if (retval != ZERR_NONE) {
-       syslog(LOG_WARNING, "new_old_subscr_sendlist set addr: %s",
-              error_message(retval));
-       return;
-    }
-
-    /* retrieve  the subscriptions */
-    answer = subscr_marshal_subs(notice, auth, who, &found);
-
-    /* note that when there are no subscriptions, found == 0, so
-       we needn't worry about answer being NULL since
-       ZFormatSmallRawNoticeList won't reference the pointer */
-
-    /* send 5 at a time until we are finished */
-    count = found?((found-1) / 5 + 1):1;       /* total # to be sent */
-    i = 0;                                     /* pkt # counter */
-#if 0
-    zdbug((LOG_DEBUG,"Found %d subscriptions for %d packets", found, count));
-#endif
-    initfound = found;
-    zerofound = (found == 0);
-    while (found > 0 || zerofound) {
-       packlen = sizeof(reppacket);
-       sprintf(buf, "%d/%d", ++i, count);
-       reply.z_opcode = buf;
-       retval = ZFormatSmallRawNoticeList(&reply,
-                                          answer + (initfound - found)
-                                           * NUM_FIELDS,
-                                          ((found > 5) ? 5 : found)
-                                           * NUM_FIELDS,
-                                          reppacket, &packlen);
-       if (retval != ZERR_NONE) {
-           syslog(LOG_ERR, "subscr_sendlist format: %s",
-                  error_message(retval));
-           if (answer)
-               free(answer);
-           return;
-       }
-       retval = ZSendPacket(reppacket, packlen, 0);
-       if (retval != ZERR_NONE) {
-           syslog(LOG_WARNING, "subscr_sendlist xmit: %s",
-                  error_message(retval));
-           if (answer)
-               free(answer);
-           return;
-       }
-       found -= 5;
-       zerofound = 0;
-    }
 #if 0
-    zdbug((LOG_DEBUG,"subscr_sendlist acked"));
+    zdbug((LOG_DEBUG, "subscr_marshal"));
 #endif
-    if (answer)
-       free(answer);
-}
-#endif /* NEW_COMPAT */
-
-#ifdef OLD_COMPAT
-static void
-old_compat_subscr_sendlist(notice, auth, who)
-    ZNotice_t *notice;
-    int auth;
-    struct sockaddr_in *who;
-{
-    Client *client = client_find(&who->sin_addr, notice->z_port);
-    Destlist *subs;
-    Code_t retval;
-    ZNotice_t reply;
-    ZPacket_t reppacket;
-    int packlen, i, found = 0;
-    char **answer = NULL;
+    *found = 0;
 
-    old_compat_count_subscr++;
+    /* Note that the following code is an incredible crock! */
+       
+    /* We cannot send multiple packets as acknowledgements to the client,
+       since the hostmanager will ignore the later packets.  So we need
+       to send directly to the client. */
 
-    syslog(LOG_INFO, "old old subscr, %s", inet_ntoa(who->sin_addr));
-    if (client && client->subs) {
+    /* Make our own copy so we can send directly back to the client */
+    /* RSF 11/07/87 */
 
-       /* check authenticity here.  The user must be authentic to get
-          a list of subscriptions. If he is not subscribed to
-          anything, the above test fails, and he gets a response
-          indicating no subscriptions */
+    if (!subs)
+       return(NULL);
 
-       if (!auth) {
-           clt_ack(notice, who, AUTH_FAILED);
-           return;
-       }
+    for (sub = subs; sub; sub = sub->next)
+       (*found)++;
 
-       for (subs = client->subs; subs; subs = subs->next)
-           found++;
-       /* found is now the number of subscriptions */
+    /* found is now the number of subscriptions */
 
-       /* coalesce the subscription information into a list of char *'s */
-       answer = (char **) malloc(found * NUM_FIELDS * sizeof(char *));
-       if (!answer) {
-           syslog(LOG_ERR, "old_subscr_sendlist no mem(answer)");
-           found = 0;
-       } else {
-           i = 0;
-           for (subs = client->subs; subs; subs = subs->next) {
-               answer[i*NUM_FIELDS] = subs->dest.classname->string;
-               answer[i*NUM_FIELDS + 1] = subs->dest.inst->string;
-               answer[i*NUM_FIELDS + 2] = subs->dest.recip->string;
-               i++;
-           }
+    /* coalesce the subscription information into a list of char *'s */
+    answer = (char **) malloc((*found) * NUM_FIELDS * sizeof(char *));
+    if (answer == NULL) {
+       syslog(LOG_ERR, "subscr no mem(answer)");
+       *found = 0;
+    } else {
+       i = 0;
+       for (sub = subs; sub; sub = sub->next) {
+           answer[i * NUM_FIELDS] = sub->dest.classname->string;
+           answer[i * NUM_FIELDS + 1] = sub->dest.inst->string;
+           answer[i * NUM_FIELDS + 2] = sub->dest.recip->string;
+           i++;
        }
     }
 
-    /* note that when there are no subscriptions, found == 0, so
-       we needn't worry about answer being NULL */
-
-    reply = *notice;
-    reply.z_kind = SERVACK;
-    reply.z_authent_len = 0; /* save some space */
-    reply.z_auth = 0;
-
-    /* if it's too long, chop off one at a time till it fits */
-    while ((retval = ZFormatSmallRawNoticeList(&reply, answer,
-                                              found * NUM_FIELDS,
-                                              reppacket,
-                                              &packlen)) != ZERR_PKTLEN) {
-       found--;
-       reply.z_opcode = OLD_CLIENT_INCOMPSUBS;
-    }
-    if (retval != ZERR_NONE) {
-       syslog(LOG_ERR, "old_subscr_sendlist format: %s",
-              error_message(retval));
-       if (answer)
-           free(answer);
-       return;
-    }
-    retval = ZSetDestAddr(who);
-    if (retval != ZERR_NONE) {
-       syslog(LOG_WARNING, "subscr_sendlist set addr: %s",
-              error_message(retval));
-       if (answer)
-           free(answer);
-       return;
-    }
-    retval = ZSendPacket(reppacket, packlen, 0);
-    if (retval != ZERR_NONE) {
-       syslog(LOG_WARNING, "subscr_sendlist xmit: %s",
-              error_message(retval));
-       if (answer)
-           free(answer);
-       return;
-    }
-#if 0
-    zdbug((LOG_DEBUG,"subscr_sendlist acked"));
-#endif
-    if (answer)
-       free(answer);
+    return answer;
 }
-#endif /* OLD_COMPAT */
 
 /*
  * Send the client's subscriptions to another server
@@ -992,7 +778,7 @@ extract_subscriptions(notice)
        sub->dest.classname = make_string(class_name, 1);
        sub->dest.inst = make_string(classinst, 1);
        /* Nuke @REALM if REALM is us. */
-       if (recip[0] == '@' && !strcmp(recip + 1, ZGetRealm()))
+       if (recip[0] == '@' && !strcmp(recip + 1, my_galaxy))
            sub->dest.recip = make_string("", 0);
        else
            sub->dest.recip = make_string(recip, 0);
@@ -1238,6 +1024,7 @@ subscr_unsub_sendit(who, subs, realm)
   list[1] = subs->dest.inst->string;
   list[2] = "";
 
+  (void) memset((char *)&unotice, 0, sizeof(unotice));
   unotice.z_class = ZEPHYR_CTL_CLASS;
   unotice.z_class_inst = ZEPHYR_CTL_REALM;
   unotice.z_opcode = REALM_UNSUBSCRIBE;
@@ -1381,6 +1168,7 @@ subscr_realm_subs(realm)
     text[4] = subs->dest.recip->string;
 
     /* format snotice */
+    (void) memset((char *)&snotice, 0, sizeof(snotice));
     snotice.z_class_inst = ZEPHYR_CTL_REALM;
     snotice.z_opcode = REALM_REQ_SUBSCRIBE;
     snotice.z_port = 0;
@@ -1429,7 +1217,7 @@ subscr_check_foreign_subs(notice, who, server, realm, newsubs)
     Realm *realm;
     Destlist *newsubs;
 {
-    Destlist *subs, *subs2, *next;
+    Destlist *subs, *subs2;
     Acl *acl;
     char **text;
     int found = 0;
@@ -1438,6 +1226,7 @@ subscr_check_foreign_subs(notice, who, server, realm, newsubs)
     int packlen;
     Code_t retval;
     String *sender;
+    Realm *rlm;
 
     for (subs = newsubs; subs; subs = subs->next)
        found++;
@@ -1464,18 +1253,27 @@ subscr_check_foreign_subs(notice, who, server, realm, newsubs)
     I_ADVANCE(3);
 
     found = 0;
-    for (subs = newsubs; subs; subs = next) {
-       next=subs->next;
+
+    rlm = realm_which_realm(who); 
+
+    for (subs = newsubs; subs; subs = subs->next) {
+       if (subs->dest.recip->string[0] != '\0') {
+           syslog(LOG_WARNING, "subscr bad recip %s by %s (%s)", 
+                   subs->dest.recip->string, 
+                   sender->string, rlm->name); 
+           continue;
+       }
        acl = class_get_acl(subs->dest.classname);
        if (acl) {
-           Realm *rlm;
-           rlm = realm_which_realm(who); 
            if (rlm && server == me_server) { 
                if (!realm_sender_in_realm(rlm->name, sender->string)) { 
                    syslog(LOG_WARNING, "subscr auth not verifiable %s (%s) class %s",
                           sender->string, rlm->name, 
                           subs->dest.classname->string);
-                   continue; 
+                   free_subscriptions(newsubs);
+                   free_string(sender);
+                   free(text);
+                   return ZSRV_CLASSRESTRICTED;
                } 
            } 
            if (!access_check(sender->string, acl, SUBSCRIBE)) {
index 4b587cfbae9a855b97ca123325f5a8caafb85ef4..6adffe65604e4975a2eed82d673a02ea3b41b030 100644 (file)
@@ -150,7 +150,7 @@ ulogin_dispatch(notice, auth, who, server)
          case REALM_ANN:
          case NET_VIS:
            if (server == me_server)
-               sendit(notice, 1, who, 0);
+               sendit(notice, 1, who, 0, 1);
            break;
          case NET_ANN:
            /* currently no distinction between these.
@@ -160,7 +160,7 @@ ulogin_dispatch(notice, auth, who, server)
               authentic.  ulogin_remove_user checks the
               ip addrs */
            if (server == me_server)
-               sendit(notice, 1, who, 1);
+               sendit(notice, 1, who, 1, 1);
            break;
          default:
            syslog(LOG_ERR,"bogus location exposure %d/%s",
@@ -267,7 +267,7 @@ login_sendit(notice, auth, who, external)
     log_notice = *notice;
 
     log_notice.z_opcode = LOGIN_USER_LOGIN;
-    sendit(&log_notice, auth, who, external);
+    sendit(&log_notice, auth, who, external, 1);
 }
 
 
@@ -287,11 +287,7 @@ ulocate_dispatch(notice, auth, who, server)
     if (!strcmp(notice->z_opcode, LOCATE_LOCATE)) {
        /* we are talking to a current-rev client; send an ack */
        ack(notice, who);
-       cp = strchr(notice->z_class_inst, '@');
-       if (cp && (realm = realm_get_realm_by_name(cp + 1)))
-           ulogin_locate_forward(notice, who, realm);
-       else
-           ulogin_locate(notice, who, auth);
+       ulogin_locate(notice, who, auth);
        return ZERR_NONE;
     } else {
        syslog(LOG_ERR, "unknown uloc opcode %s", notice->z_opcode);
@@ -827,9 +823,30 @@ ulogin_locate(notice, who, auth)
     int found;
     Code_t retval;
     struct sockaddr_in send_to_who;
+    char *cp;
+    Realm *realm;
 
     answer = ulogin_marshal_locs(notice, &found, auth);
 
+    /* XXX do more parsing, like in dispatch() */
+
+    if (found == 0) {
+       cp = strrchr(notice->z_class_inst, '@');
+       if (cp && (realm = realm_get_realm_by_name(cp + 1))) {
+           char *inlhsat;
+
+           /* XXX eeew. */
+           *cp = '\0';
+           inlhsat = strrchr(notice->z_class_inst, '@');
+
+           if (!inlhsat)
+               *cp = '@';
+
+           ulogin_locate_forward(notice, who, realm);
+           return;
+       }
+    }
+
     send_to_who = *who;
     send_to_who.sin_port = notice->z_port;
 
@@ -869,7 +886,7 @@ ulogin_marshal_locs(notice, found, auth)
     char **answer;
     int i = 0;
     String *inst;
-    int local = (auth && realm_sender_in_realm(ZGetRealm(), notice->z_sender));
+    int local = (auth && realm_sender_in_realm(my_galaxy, notice->z_sender));
 
     *found = 0;                        /* # of matches */
 
@@ -922,7 +939,6 @@ ulogin_marshal_locs(notice, found, auth)
     /* OK, now we have a list of user@host's to return to the client
        in matches */
        
-       
 #ifdef DEBUG
     if (zdebug) {
        for (i = 0; i < *found ; i++)
index 8129347cf94661daf991091345c962482578afdc..36e43ac675a2ae294e1ee26de8a8edcea4259d75 100644 (file)
 
 const char zephyr_version[] = "Zephyr system version 2.0";
 
+static char version[] = {
+    "Zephyr Server "
 #ifdef DEBUG
-const char version[] = "Zephyr server (DEBUG) $Revision: 3.24 $";
-#else
-const char version[] = "Zephyr server $Revision: 3.24 $";
+    "(DEBUG) "
 #endif
+    "$Revision: 3.24 $"
+    ": " ZSERVER_VERSION_STRING "/" MACHINE_TYPE
+};
 
 #if !defined (lint) && !defined (SABER)
 static const char rcsid_version_c[] =
@@ -33,51 +36,5 @@ static const char copyright[] =
 char *
 get_version()
 {
-  static char vers_buf[256];
-
-  if (vers_buf[0] == '\0') {
-#ifdef DEBUG
-    sprintf(vers_buf,"Zephyr Server (DEBUG) $Revision: 3.24 $: %s",
-           ZSERVER_VERSION_STRING);
-#else
-    sprintf(vers_buf,"Zephyr Server $Revision: 3.24 $: %s",
-           ZSERVER_VERSION_STRING);
-#endif /* DEBUG */
-
-    (void) strcat(vers_buf, "/");
-#ifdef vax
-    (void) strcat(vers_buf, "VAX");
-#endif /* vax */
-#ifdef ibm032
-    (void) strcat(vers_buf, "IBM RT");
-#endif /* ibm032 */
-#ifdef _IBMR2
-    (void) strcat(vers_buf, "IBM RS/6000");
-#endif /* _IBMR2 */
-#ifdef sun
-    (void) strcat(vers_buf, "SUN");
-#ifdef sparc
-    (void) strcat (vers_buf, "-4");
-#endif /* sparc */
-#ifdef sun386
-    (void) strcat (vers_buf, "-386I");
-#endif /* sun386 */
-#endif /* sun */
-
-#ifdef mips
-#ifdef ultrix                  /* DECstation */
-    (void) strcat (vers_buf, "DEC-");
-#endif /* ultrix */
-    (void) strcat(vers_buf, "MIPS");
-#endif /* mips */
-#ifdef NeXT
-    (void) strcat(vers_buf, "NeXT");
-#endif /* NeXT */
-  }
-  return(vers_buf);
+    return version;
 }
-
-
-
-
-
index 7f7b2716d743bac478c7f1cc739c1f57db772bbe..5ac13d81226f5b36611795a133c808e2145c2740 100644 (file)
@@ -18,78 +18,83 @@ static char rcsid_queue_c[] = "$Id: queue.c,v 1.22 1999/10/20 16:44:11 ghudson E
 #endif /* SABER */
 #endif /* lint */
 
-typedef struct _Queue {
-    Timer *timer;
-    int retries;
-    ZNotice_t notice;
-    caddr_t packet;
-    struct sockaddr_in reply;
-    struct _Queue *next, **prev_p;
-} Queue;
-
-static Queue *hm_queue;
-static int retransmits_enabled = 0;
-
-static Queue *find_notice_in_queue __P((ZNotice_t *notice));
-static Code_t dump_queue __P((void));
-static void queue_timeout __P((void *arg));
+static const int rexmit_times[] = { 2, 2, 4, 4, 8, -1 };
 
-int rexmit_times[] = { 2, 2, 4, 4, 8, -1 };
+static Queue *find_notice_in_galaxy __P((galaxy_info *gi, ZNotice_t *notice));
+static void queue_timeout __P((void *arg));
 
 #ifdef DEBUG
-Code_t dump_queue();
+Code_t dump_galaxy_queue(galaxy_info *);
 #endif
 
-void init_queue()
+void init_galaxy_queue(galaxy_info *gi)
 {
     Queue *q;
 
-    while (hm_queue) {
-       q = hm_queue;
+    while (gi->queue) {
+       q = gi->queue;
        if (q->timer)
            timer_reset(q->timer);
        free(q->packet);
-       hm_queue = q->next;
+       gi->queue = q->next;
        free(q);
     }
 
     DPR("Queue initialized and flushed.\n");
 }
 
-Code_t add_notice_to_queue(notice, packet, repl, len)
+Code_t add_notice_to_galaxy(gi, notice, repl, len)
+    galaxy_info *gi;
     ZNotice_t *notice;
-    char * packet;
     struct sockaddr_in *repl;
     int len;
 {
     Queue *entry;
+    int length;
+    int retval;
 
     DPR("Adding notice to queue...\n");
-    if (!find_notice_in_queue(notice)) {
+    if (!find_notice_in_galaxy(gi, notice)) {
        entry = (Queue *) malloc(sizeof(Queue));
        if (entry == NULL)
            return(ZERR_NONOTICE);
+       entry->gi = gi;
        entry->retries = 0;
-       entry->packet = (char *) malloc(Z_MAXPKTLEN);
-       if (entry->packet == NULL) {
+       if (!(entry->packet = (char *) malloc((unsigned)sizeof(ZPacket_t)))) {
            free(entry);
-           return(ZERR_NONOTICE);
+           return(ENOMEM);
        }
-       memcpy(entry->packet, packet, Z_MAXPKTLEN);
-       if (ZParseNotice(entry->packet, len, &entry->notice) != ZERR_NONE) {
-           syslog(LOG_ERR, "ZParseNotice failed, but succeeded before");
+
+       if ((retval = ZFormatSmallRawNotice(notice, entry->packet, &length))
+           != ZERR_NONE) {
            free(entry->packet);
-       } else {
-           entry->reply = *repl;
-           LIST_INSERT(&hm_queue, entry);
+           free(entry);
+           return(retval);
+       }
+
+       /* I dislike this, but I need a notice which represents the
+          packet.  since the notice structure refers to the internals
+          of its packet, I can't use the notice which was passed in,
+          so I need to make a new one. */
+
+       if ((retval = ZParseNotice(entry->packet, length, &entry->notice))
+           != ZERR_NONE) {
+          free(entry->packet);
+          free(entry);
+          return(retval);
        }
-       entry->timer = (retransmits_enabled) ?
-           timer_set_rel(rexmit_times[0], queue_timeout, entry) : NULL;
+
+       entry->reply = *repl;
+       LIST_INSERT(&gi->queue, entry);
+
+       entry->timer = (gi->state == ATTACHED) ?
+          timer_set_rel(rexmit_times[0], queue_timeout, entry) : NULL;
     }
     return(ZERR_NONE);
 }
 
-Code_t remove_notice_from_queue(notice, kind, repl)
+Code_t remove_notice_from_galaxy(gi, notice, kind, repl)
+    galaxy_info *gi;
     ZNotice_t *notice;
     ZNotice_Kind_t *kind;
     struct sockaddr_in *repl;
@@ -97,7 +102,7 @@ Code_t remove_notice_from_queue(notice, kind, repl)
     Queue *entry;
 
     DPR("Removing notice from queue...\n");
-    entry = find_notice_in_queue(notice);
+    entry = find_notice_in_galaxy(gi, notice);
     if (entry == NULL)
        return(ZERR_NONOTICE);
 
@@ -115,19 +120,14 @@ Code_t remove_notice_from_queue(notice, kind, repl)
 }
 
 /* We have a server; transmit all of our packets. */
-void retransmit_queue(sin)
-    struct sockaddr_in *sin;
+void retransmit_galaxy(gi)
+    galaxy_info *gi;
 {
     Queue *entry;
     Code_t ret;
 
     DPR("Retransmitting queue to new server...\n");
-    ret = ZSetDestAddr(sin);
-    if (ret != ZERR_NONE) {
-       Zperr (ret);
-       com_err("queue", ret, "setting destination");
-    }
-    for (entry = hm_queue; entry; entry = entry->next) {
+    for (entry = gi->queue; entry; entry = entry->next) {
        DPR("notice:\n");
        DPR2("\tz_kind: %d\n", entry->notice.z_kind);
        DPR2("\tz_port: %u\n", ntohs(entry->notice.z_port));
@@ -136,7 +136,7 @@ void retransmit_queue(sin)
        DPR2("\tz_opcode: %s\n", entry->notice.z_opcode);
        DPR2("\tz_sender: %s\n", entry->notice.z_sender);
        DPR2("\tz_recip: %s\n", entry->notice.z_recipient);
-       ret = send_outgoing(&entry->notice);
+       ret = send_outgoing(&gi->sin, &entry->notice);
        if (ret != ZERR_NONE) {
            Zperr(ret);
            com_err("queue", ret, "sending raw notice");
@@ -144,36 +144,36 @@ void retransmit_queue(sin)
        entry->timer = timer_set_rel(rexmit_times[0], queue_timeout, entry);
        entry->retries = 0;
     }
-    retransmits_enabled = 1;
 }
 
 /* We lost our server; nuke all of our timers. */
-void disable_queue_retransmits()
+void disable_galaxy_retransmits(gi)
+    galaxy_info *gi;
 {
     Queue *entry;
 
-    for (entry = hm_queue; entry; entry = entry->next) {
+    for (entry = gi->queue; entry; entry = entry->next) {
        if (entry->timer)
            timer_reset(entry->timer);
        entry->timer = NULL;
     }
-    retransmits_enabled = 0;
 }
 
 #ifdef DEBUG
-static Code_t dump_queue()
+static Code_t dump_galaxy_queue(gi)
+    galaxy_info *gi;
 {
     Queue *entry;
     caddr_t mp;
     int ml;
 
     DPR("Dumping queue...\n");
-    if (!hm_queue) {
+    if (!gi->queue) {
        printf("Queue is empty.\n");
        return;
     }
 
-    for (entry = hm_queue; entry; entry = entry->next) {
+    for (entry = gi->queue; entry; entry = entry->next) {
        printf("notice:\n");
        printf("\tz_kind: %d\n", entry->notice.z_kind);
        printf("\tz_port: %u\n", ntohs(entry->notice.z_port));
@@ -193,22 +193,24 @@ static Code_t dump_queue()
 }
 #endif /* DEBUG */
 
-int queue_len()
+int galaxy_queue_len(gi)
+    galaxy_info *gi;
 {
     int length = 0;
     Queue *entry;
 
-    for (entry = hm_queue; entry; entry = entry->next)
+    for (entry = gi->queue; entry; entry = entry->next)
        length++;
     return length;
 }
 
-static Queue *find_notice_in_queue(notice)
+static Queue *find_notice_in_galaxy(gi, notice)
+    galaxy_info *gi;
     ZNotice_t *notice;
 {
     Queue *entry;
 
-    for (entry = hm_queue; entry; entry = entry->next) {
+    for (entry = gi->queue; entry; entry = entry->next) {
        if (ZCompareUID(&entry->notice.z_uid, &notice->z_uid))
            return entry;
     }
@@ -222,14 +224,14 @@ static void queue_timeout(arg)
     Code_t ret;
 
     entry->timer = NULL;
-    ret = ZSetDestAddr(&serv_sin);
+
     if (ret != ZERR_NONE) {
        Zperr(ret);
        com_err("queue", ret, "setting destination");
     }
     entry->retries++;
     if (rexmit_times[entry->retries] == -1) {
-       new_server(NULL);
+       galaxy_new_server(entry->gi, NULL);
        return;
     }
     DPR("Resending notice:\n");
@@ -240,7 +242,7 @@ static void queue_timeout(arg)
     DPR2("\tz_opcode: %s\n", entry->notice.z_opcode);
     DPR2("\tz_sender: %s\n", entry->notice.z_sender);
     DPR2("\tz_recip: %s\n", entry->notice.z_recipient);
-    ret = send_outgoing(&entry->notice);
+    ret = send_outgoing(&entry->gi->sin, &entry->notice);
     if (ret != ZERR_NONE) {
        Zperr(ret);
        com_err("queue", ret, "sending raw notice");
index 6fc72a36826c945453440480951541547e11f73d..da76e095f1f5a062fa57bc7e3b4c60aed06c3b63 100644 (file)
--- a/zhm/zhm.h
+++ b/zhm/zhm.h
 #define Zperr(e)
 #endif
 
-#define ever (;;)
-
-#define BOOTING 1
-#define NOTICES 2
+#define BOOT_TIMEOUT 10
+#define DEAD_TIMEOUT 5*60
+
+typedef struct _Queue {
+    struct _galaxy_info *gi;
+    Timer *timer;
+    int retries;
+    ZNotice_t notice;
+    caddr_t packet;
+    struct sockaddr_in reply;
+    struct _Queue *next, **prev_p;
+} Queue;
+
+typedef enum _galaxy_state {
+   NEED_SERVER, /* never had a server, HM_BOOT when we find one.  This can
+                  also be set if a flush was requested when the state
+                  was != ATTACHED. */
+   DEAD_SERVER, /* server timed out, no others around.  This is
+                  actually handled in the same way as BOOTING or
+                  ATTACHING (although some of the timeouts are
+                  different), but it's handy to know which of the two
+                  states the zhm is in */
+   BOOTING, /* waiting for HM_BOOT SERVACK */
+   ATTACHING, /* waiting for HM_BOOT SERVACK */
+   ATTACHED /* active and connected */
+} galaxy_state;
+
+typedef struct _galaxy_info {
+   Z_GalaxyConfig galaxy_config;
+
+#define NO_SERVER -1
+#define EXCEPTION_SERVER -2
+   int current_server;
+   struct sockaddr_in sin;
+   galaxy_state state;
+
+   int nchange;
+   int nsrvpkts;
+   int ncltpkts;
+
+   Queue *queue;
+   Timer *boot_timer;
+} galaxy_info;
 
 /* main.c */
-void die_gracefully __P((void));
 
 /* zhm_client.c */
-void transmission_tower __P((ZNotice_t *, char *, int));
-Code_t send_outgoing __P((ZNotice_t *));
+void transmission_tower __P((ZNotice_t *, struct sockaddr_in *, char *, int));
+Code_t send_outgoing __P((struct sockaddr_in *, ZNotice_t *));
 
 /* queue.c */
-void init_queue __P((void));
-Code_t add_notice_to_queue __P((ZNotice_t *, char *, struct sockaddr_in *,
-                               int));
-Code_t remove_notice_from_queue __P((ZNotice_t *, ZNotice_Kind_t *,
-                                    struct sockaddr_in *));
-void retransmit_queue __P((struct sockaddr_in *));
-void disable_queue_retransmits __P((void));
-int queue_len __P((void));
-
-struct sockaddr_in serv_sin;
-extern int rexmit_times[];
+void init_galaxy_queue __P((galaxy_info *));
+Code_t add_notice_to_galaxy __P((galaxy_info *, ZNotice_t *,
+                               struct sockaddr_in *, int));
+Code_t remove_notice_from_galaxy __P((galaxy_info *, ZNotice_t *,
+                                    ZNotice_Kind_t *, struct sockaddr_in *));
+void retransmit_galaxy __P((galaxy_info *));
+void disable_galaxy_retransmits __P((galaxy_info *));
+int galaxy_queue_len __P((galaxy_info *));
+
+/* zhm.c */
+extern galaxy_info *galaxy_list;
+extern int ngalaxies;
+extern int noflushflag;
+
+/* zhm_server.c */
+void server_manager __P((ZNotice_t *, struct sockaddr_in *));
+void hm_control __P((galaxy_info *, ZNotice_t *));
+void galaxy_new_server __P((galaxy_info *, struct in_addr *addr));
+void galaxy_flush __P((galaxy_info *));
+void galaxy_reset __P((galaxy_info *));
+
 
 #ifdef vax
 #define use_etext
index d8879808a7833aeb7da888d7d5fd13781520f628..db6506657223e134575ef120a05f68c69f47be40 100644 (file)
@@ -18,79 +18,95 @@ static char rcsid_hm_client_c[] = "$Id: zhm_client.c,v 1.12 2000/04/05 14:57:37
 #endif /* SABER */
 #endif /* lint */
 
-extern int no_server, nclt, deactivated, noflushflag;
-extern struct sockaddr_in cli_sin, serv_sin, from;
+extern int noflushflag;
+extern struct sockaddr_in cli_sin;
 
-void transmission_tower(notice, packet, pak_len)
+void transmission_tower(notice, from, packet, pak_len)
      ZNotice_t *notice;
+     struct sockaddr_in *from;
      char *packet;
      int pak_len;
 {
+    int i;
+    galaxy_info *gi;
     ZNotice_t gack;
     Code_t ret;
     struct sockaddr_in gsin;
 
-    nclt++;
+    if (notice->z_dest_galaxy) {
+       for (i=0; i<ngalaxies; i++)
+           if (strcasecmp(galaxy_list[i].galaxy_config.galaxy,
+                          notice->z_dest_galaxy) == 0) {
+               gi = &galaxy_list[i];
+               break;
+           }
+       if (i == ngalaxies) {
+           /* XXX I should generate some sort of error here.  Fortunately,
+              only new clients can elicit this error, so I can use a new
+              error value (message body string, probably) here.  For now,
+              just return and let the sender time out. */
+           return;
+       }
+    } else {
+       gi = &galaxy_list[0];
+    }
+
     if (notice->z_kind == HMCTL) {
        if (!strcmp(notice->z_opcode, CLIENT_FLUSH)) {
            if (noflushflag)
                syslog(LOG_INFO, "Client requested hm flush (disabled).");
-           else {
-               send_flush_notice(HM_FLUSH);
-               deactivated = 1;
-           }
+           else
+               galaxy_flush(gi);
        } else if (!strcmp(notice->z_opcode, CLIENT_NEW_SERVER)) {
-           new_server((char *)NULL);
+           galaxy_new_server(gi, NULL);
        } else {
            syslog (LOG_INFO, "Bad control notice from client.");
        }
        return;
-    } else {
-       if (notice->z_kind != UNSAFE) {
-           gack = *notice;
-           gack.z_kind = HMACK;
-           gack.z_message_len = 0;
-           gack.z_multinotice = "";
-           gsin = cli_sin;
-           gsin.sin_port = from.sin_port;
-           if (gack.z_port == 0)
-               gack.z_port = from.sin_port;
-           DPR2 ("Client Port = %u\n", ntohs(gack.z_port));
-           notice->z_port = gack.z_port;
-           if ((ret = ZSetDestAddr(&gsin)) != ZERR_NONE) {
-               Zperr(ret);
-               com_err("hm", ret, "setting destination");
-           }
-           /* Bounce ACK to library */
-           if ((ret = send_outgoing(&gack)) != ZERR_NONE) {
-               Zperr(ret);
-               com_err("hm", ret, "sending raw notice");
-           }
-       }
-    }
-    if (!no_server) {
-       DPR2 ("Server Port = %u\n", ntohs(serv_sin.sin_port));
-       if ((ret = ZSetDestAddr(&serv_sin)) != ZERR_NONE) {
+    } 
+
+    if (notice->z_kind != UNSAFE) {
+       gack = *notice;
+       gack.z_kind = HMACK;
+       gack.z_message_len = 0;
+       gack.z_multinotice = "";
+       gsin = cli_sin;
+       gsin.sin_port = from->sin_port;
+       if (gack.z_port == 0)
+           gack.z_port = from->sin_port;
+       notice->z_port = gack.z_port;
+       /* Bounce ACK to library */
+       if ((ret = send_outgoing(&gsin, &gack)) != ZERR_NONE) {
            Zperr(ret);
-           com_err("hm", ret, "setting destination");
+           com_err("hm", ret, "sending raw notice");
        }
-       if ((ret = send_outgoing(notice)) != ZERR_NONE) {
+    }
+
+    /* remove the dest galaxy, since the servers aren't prepared for it */
+    notice->z_dest_galaxy = NULL;
+
+    if (gi->current_server != NO_SERVER) {
+       if ((ret = send_outgoing(&gi->sin, notice)) != ZERR_NONE) {
            Zperr(ret);
            com_err("hm", ret, "while sending raw notice");
        }
     }
-    if (add_notice_to_queue(notice, packet, &gsin, pak_len) != ZERR_NONE)
-        syslog(LOG_INFO, "Hey! Insufficient memory to add notice to queue!");
+
+    add_notice_to_galaxy(gi, notice, &gsin, pak_len);
 }
 
 Code_t
-send_outgoing(notice)
-ZNotice_t *notice;
+send_outgoing(sin, notice)
+     struct sockaddr_in *sin;
+     ZNotice_t *notice;
 {
     Code_t retval;
     char *packet;
     int length;
 
+    if ((retval = ZSetDestAddr(sin)) != ZERR_NONE)
+       return(retval);
+
     if (!(packet = (char *) malloc((unsigned)sizeof(ZPacket_t))))
        return(ENOMEM);
 
@@ -99,8 +115,11 @@ ZNotice_t *notice;
        free(packet);
        return(retval);
     }
+
     retval = ZSendPacket(packet, length, 0);
+
     free(packet);
+
     return(retval);
 }
 
index cd460c89ce85d9b361a21217f9e9927c8183d17f..bbcbd99e45925052f3891476ab36add6d6a5617d 100644 (file)
@@ -18,30 +18,15 @@ static char rcsid_hm_server_c[] = "$Id: zhm_server.c,v 1.18 2000/05/08 16:00:08
 #endif /* SABER */
 #endif /* lint */
 
+static void send_back __P((galaxy_info *, ZNotice_t *));
 static void boot_timeout __P((void *));
-static int get_serv_timeout __P((void));
 
-static Timer *boot_timer = NULL;
-static int serv_rexmit_times[] = { 5, 10, 20, 40 };
-static int serv_timeouts = 0;
-
-int serv_loop = 0;
+extern int hmdebug;
 extern u_short cli_port;
-extern struct sockaddr_in serv_sin, from;
-extern int timeout_type, hmdebug, nservchang, booting, nserv, no_server;
-extern int deactivated, rebootflag;
-extern int numserv;
-extern char **serv_list;
-extern char cur_serv[], prim_serv[];
-extern void die_gracefully();
-
-void hm_control(), send_back(), new_server();
-
-/* Argument is whether we are actually booting, or just attaching
- * after a server switch */
-void
-send_boot_notice(op)
-char *op;
+
+static void send_hmctl_notice(gi, op)
+     galaxy_info *gi;
+     char *op;
 {
      ZNotice_t notice;
      Code_t ret;
@@ -55,271 +40,244 @@ char *op;
      notice.z_sender = "HM";
      notice.z_recipient = "";
      notice.z_default_format = "";
+     notice.z_dest_galaxy = "";
      notice.z_num_other_fields = 0;
      notice.z_message_len = 0;
   
-     /* Notify server that this host is here */
-     if ((ret = ZSetDestAddr(&serv_sin)) != ZERR_NONE) {
+     if ((ret = ZSetDestAddr(&gi->sin)) != ZERR_NONE) {
          Zperr(ret);
          com_err("hm", ret, "setting destination");
      }
      if ((ret = ZSendNotice(&notice, ZNOAUTH)) != ZERR_NONE) {
          Zperr(ret);
-         com_err("hm", ret, "sending startup notice");
+         com_err("hm", ret, "sending hmctl notice %s", op);
      }
-     boot_timer = timer_set_rel(get_serv_timeout(), boot_timeout, NULL);
 }
 
-/* Argument is whether we are detaching or really going down */
-void
-send_flush_notice(op)
-char *op;
+static int choose_next_server(gi)
+     galaxy_info *gi;
 {
-     ZNotice_t notice;
-     Code_t ret;
-     
-     /* Set up server notice */
-     notice.z_kind = HMCTL;
-     notice.z_port = cli_port;
-     notice.z_class = ZEPHYR_CTL_CLASS;
-     notice.z_class_inst = ZEPHYR_CTL_HM;
-     notice.z_opcode = op;
-     notice.z_sender = "HM";
-     notice.z_recipient = "";
-     notice.z_default_format = "";
-     notice.z_num_other_fields = 0;
-     notice.z_message_len = 0;
+    int new_server;
 
-     /* Tell server to lose us */
-     if ((ret = ZSetDestAddr(&serv_sin)) != ZERR_NONE) {
-         Zperr(ret);
-         com_err("hm", ret, "setting destination");
-     }
-     if ((ret = ZSendNotice(&notice, ZNOAUTH)) != ZERR_NONE) {
-         Zperr(ret);
-         com_err("hm", ret, "sending flush notice");
+     if (gi->current_server < 0) {
+        new_server = random() % gi->galaxy_config.nservers;
+     } else if (gi->galaxy_config.nservers == 1) {
+        new_server = NO_SERVER;
+     } else if ((new_server = (random() % (gi->galaxy_config.nservers - 1))) ==
+               gi->current_server) {
+        new_server = gi->galaxy_config.nservers - 1;
      }
-}
 
-void
-find_next_server(sugg_serv)
-char *sugg_serv;
-{
-     struct hostent *hp;
-     int done = 0;
-     char **parse = serv_list;
-     char *new_serv;
-  
-     if (sugg_serv) {
-         do {
-              if (!strcmp(*parse, sugg_serv))
-                   done = 1;
-         } while ((done == 0) && (*++parse != NULL));
-     }
-     if (done) {
-         if ((hp = gethostbyname(sugg_serv)) != NULL) {
-              DPR2 ("Server = %s\n", sugg_serv);       
-              (void)strncpy(cur_serv, sugg_serv, MAXHOSTNAMELEN);
-              cur_serv[MAXHOSTNAMELEN - 1] = '\0';
-              if (hmdebug)
-                   syslog(LOG_DEBUG, "Suggested server: %s\n", sugg_serv);
-         } else {
-              done = 0; 
-         }
-     }
-     while (!done) {
-        if ((++serv_loop > 3) && (strcmp(cur_serv, prim_serv))) {
-            serv_loop = 0;
-            if ((hp = gethostbyname(prim_serv)) != NULL) {
-                DPR2 ("Server = %s\n", prim_serv);
-                (void)strncpy(cur_serv, prim_serv, MAXHOSTNAMELEN);
-                cur_serv[MAXHOSTNAMELEN - 1] = '\0';
-                done = 1;
-                break;
-            }
-        }
-
-        switch (numserv) {
-        case 1:
-            if ((hp = gethostbyname(*serv_list)) != NULL) {
-                DPR2 ("Server = %s\n", *serv_list);
-                (void)strncpy(cur_serv, *serv_list, MAXHOSTNAMELEN);
-                cur_serv[MAXHOSTNAMELEN - 1] = '\0';
-                done = 1;
-                break;
-            }
-            /* fall through */
-        case 0:
-            if (rebootflag)
-                die_gracefully();
-            else
-                sleep(1);
-            break;
-        default:
-            do {
-                new_serv = serv_list[random() % numserv];
-            } while (!strcmp(new_serv, cur_serv));
-
-            if ((hp = gethostbyname(new_serv)) != NULL) {
-                DPR2 ("Server = %s\n", new_serv);
-                (void)strncpy(cur_serv, new_serv, MAXHOSTNAMELEN);
-                cur_serv[MAXHOSTNAMELEN - 1] = '\0';
-                done = 1;
-            } else
-                sleep(1);
-
-            break;
-        }
-     }
-     (void) memcpy((char *)&serv_sin.sin_addr, hp->h_addr, 4);
-     nservchang++;
+     return(new_server);
 }
 
-void
-server_manager(notice)
-ZNotice_t *notice;
+void server_manager(notice, from)
+     ZNotice_t *notice;
+     struct sockaddr_in *from;
 {
-    if (memcmp((char *)&serv_sin.sin_addr, (char *)&from.sin_addr, 4) ||
-       (serv_sin.sin_port != from.sin_port)) {
-       syslog (LOG_INFO, "Bad notice from port %u.", notice->z_port);
-    } else {
-       /* This is our server, handle the notice */
-       booting = 0;
-       serv_timeouts = 0;
-       if (boot_timer) {
-           timer_reset(boot_timer);
-           boot_timer = NULL;
-       }
-       DPR ("A notice came in from the server.\n");
-       nserv++;
-       switch(notice->z_kind) {
-       case HMCTL:
-           hm_control(notice);
-           break;
-       case SERVNAK:
-       case SERVACK:
-           send_back(notice);
-           break;
-       default:
-           syslog (LOG_INFO, "Bad notice kind!?");
+    int i;
+    galaxy_info *gi;
+
+    for (i=0; i<ngalaxies; i++)
+       if ((memcmp((char *)&galaxy_list[i].sin.sin_addr,
+                   (char *)&from->sin_addr, 4) == 0) &&
+           (galaxy_list[i].sin.sin_port == from->sin_port)) {
+           gi = &galaxy_list[i];
            break;
        }
+
+    if (!gi) {
+       syslog(LOG_INFO, "Bad server notice from %s:%u.",
+              inet_ntoa(from->sin_addr), from->sin_port);
+       return;
+    }
+
+    DPR ("A notice came in from the server.\n");
+
+    if (gi->boot_timer) {
+       timer_reset(gi->boot_timer);
+       gi->boot_timer = NULL;
+    }
+
+    gi->nsrvpkts++;
+
+    switch (gi->state) {
+    case NEED_SERVER:
+       /* there's a server which thinks it cares about us.  it's
+          wrong.  reboot the hm. */
+       send_hmctl_notice(gi, HM_BOOT);
+
+       gi->state = BOOTING;
+       gi->boot_timer = timer_set_rel(BOOT_TIMEOUT, boot_timeout, gi);
+
+       return;
+    case DEAD_SERVER:
+       /* the server is back from the dead.  reanimate the queue and
+          pretend it never went away */
+       /* fall through */
+    case BOOTING:
+       /* got the ack. */
+       retransmit_galaxy(gi);
+       gi->state = ATTACHED;
+       break;
+    }
+
+    switch(notice->z_kind) {
+    case HMCTL:
+       hm_control(gi, notice);
+       break;
+    case SERVNAK:
+    case SERVACK:
+       send_back(gi, notice);
+       break;
+    default:
+       syslog (LOG_INFO, "Bad notice kind %d", notice->z_kind);
+       break;
     }
 }
 
-void
-hm_control(notice)
-ZNotice_t *notice;
+void hm_control(gi, notice)
+     galaxy_info *gi;
+     ZNotice_t *notice;
 {
     Code_t ret;
     struct hostent *hp;
-    char suggested_server[MAXHOSTNAMELEN];
-    unsigned long addr;
+    char suggested_server[64];
+    struct in_addr addr;
      
     DPR("Control message!\n");
     if (!strcmp(notice->z_opcode, SERVER_SHUTDOWN)) {
        if (notice->z_message_len) {
-           addr = inet_addr(notice->z_message);
-           hp = gethostbyaddr((char *) &addr, sizeof(addr), AF_INET);
-           if (hp != NULL) {
-               strncpy(suggested_server, hp->h_name, sizeof(suggested_server));
-               suggested_server[sizeof(suggested_server) - 1] = '\0';
-               new_server(suggested_server);
-           } else {
-               new_server(NULL);
-           }
+           addr.s_addr = inet_addr(notice->z_message);
+           galaxy_new_server(gi, &addr);
        } else {
-           new_server((char *)NULL);
+           galaxy_new_server(gi, NULL);
        }
     } else if (!strcmp(notice->z_opcode, SERVER_PING)) {
        notice->z_kind = HMACK;
-       if ((ret = ZSetDestAddr(&serv_sin)) != ZERR_NONE) {
-           Zperr(ret);
-           com_err("hm", ret, "setting destination");
-       }
-       if ((ret = send_outgoing(notice)) != ZERR_NONE) {
+       if ((ret = send_outgoing(&gi->sin, notice)) != ZERR_NONE) {
            Zperr(ret);
            com_err("hm", ret, "sending ACK");
        }
-       if (no_server) {
-           no_server = 0;
-           retransmit_queue(&serv_sin);
-       }
     } else {
        syslog (LOG_INFO, "Bad control message.");
     }
 }
 
-void
-send_back(notice)
-ZNotice_t *notice;
+static void send_back(gi, notice)
+     galaxy_info *gi;
+     ZNotice_t *notice;
 {
     ZNotice_Kind_t kind;
     struct sockaddr_in repl;
     Code_t ret;
   
-    if (!strcmp(notice->z_opcode, HM_BOOT) ||
-       !strcmp(notice->z_opcode, HM_ATTACH)) {
-       /* ignore message, just an ack from boot, but exit if we
-        * are rebooting.
-        */
-       if (rebootflag)
-           die_gracefully();
-    } else {
-       if (remove_notice_from_queue(notice, &kind, &repl) != ZERR_NONE) {
-           syslog (LOG_INFO, "Hey! This packet isn't in my queue!");
-       } else {
-           /* check if client wants an ACK, and send it */
-           if (kind == ACKED) {
-               DPR2 ("Client ACK port: %u\n", ntohs(repl.sin_port));
-               if ((ret = ZSetDestAddr(&repl)) != ZERR_NONE) {
-                   Zperr(ret);
-                   com_err("hm", ret, "setting destination");
-               }
-               if ((ret = send_outgoing(notice)) != ZERR_NONE) {
-                   Zperr(ret);
-                   com_err("hm", ret, "sending ACK");
-               }
-           }
-       }
+    if ((strcmp(notice->z_opcode, HM_BOOT) == 0) ||
+       (strcmp(notice->z_opcode, HM_ATTACH) == 0))
+       return;
+
+    if (remove_notice_from_galaxy(gi, notice, &kind, &repl) != ZERR_NONE) {
+       syslog (LOG_INFO, "Hey! This packet isn't in my queue!");
+       return;
     }
-    if (no_server) {
-       no_server = 0;
-       retransmit_queue(&serv_sin);
+
+    /* check if client wants an ACK, and send it */
+    if (kind == ACKED) {
+       DPR2 ("Client ACK port: %u\n", ntohs(repl.sin_port));
+       if ((ret = send_outgoing(&repl, notice)) != ZERR_NONE) {
+           Zperr(ret);
+           com_err("hm", ret, "sending ACK");
+       }
     }
 }
 
-void
-new_server(sugg_serv)
-char *sugg_serv;
+void galaxy_new_server(gi, addr)
+     galaxy_info *gi;
+     struct in_addr *addr;
 {
-    no_server = 1;
-    syslog (LOG_INFO, "Server went down, finding new server.");
-    send_flush_notice(HM_DETACH);
-    find_next_server(sugg_serv);
-    if (booting) {
-       send_boot_notice(HM_BOOT);
-       deactivated = 0;
+    int i;
+    int new_server;
+
+    if (gi->state == ATTACHED) {
+       disable_galaxy_retransmits(gi);
+       gi->nchange++;
+       syslog(LOG_INFO, "Server went down, finding new server.");
+    }
+
+    if (gi->current_server != NO_SERVER)
+       send_hmctl_notice(gi, HM_DETACH);
+
+    if (gi->boot_timer) {
+       timer_reset(gi->boot_timer);
+       gi->boot_timer = 0;
+    }
+
+    if (addr) {
+       gi->current_server = EXCEPTION_SERVER;
+       gi->sin.sin_addr = *addr;
+
+       for (i=0; i<gi->galaxy_config.nservers; i++)
+           if (gi->galaxy_config.server_list[i].addr.s_addr ==
+               gi->sin.sin_addr.s_addr) {
+               gi->current_server = i;
+               break;
+           }
+
+       gi->state = ATTACHING;
+    } else if ((new_server = choose_next_server(gi)) == NO_SERVER) {
+       /* the only server went away.  Set a boot timer, try again
+          later */
+
+       gi->current_server = NO_SERVER;
+
+       gi->state = (gi->state == BOOTING)?NEED_SERVER:DEAD_SERVER;
+       gi->boot_timer = timer_set_rel(DEAD_TIMEOUT, boot_timeout, gi);
+
+       return;
     } else {
-       send_boot_notice(HM_ATTACH);
+       gi->current_server = new_server;
+       gi->sin.sin_addr =
+           gi->galaxy_config.server_list[gi->current_server].addr;
+
+       gi->state = (gi->state == NEED_SERVER)?BOOTING:ATTACHING;
     }
-    disable_queue_retransmits();
+
+    send_hmctl_notice(gi, (gi->state == BOOTING)?HM_BOOT:HM_ATTACH);
+    gi->boot_timer = timer_set_rel(BOOT_TIMEOUT, boot_timeout, gi);
 }
 
-static void boot_timeout(arg)
-void *arg;
+void galaxy_flush(gi)
+     galaxy_info *gi;
 {
-    serv_timeouts++;
-    new_server(NULL);
+    init_galaxy_queue(gi);
+
+    /* to flush, actually do a boot, because this causes an ACK to
+       come back when it completes */
+
+    if (gi->state == ATTACHED) {
+       send_hmctl_notice(gi, HM_BOOT);
+
+       gi->state = BOOTING;
+       gi->boot_timer = timer_set_rel(BOOT_TIMEOUT, boot_timeout, gi);
+    } else {
+       gi->state = NEED_SERVER;
+    }
 }
 
-static int get_serv_timeout(void)
+void galaxy_reset(gi)
+     galaxy_info *gi;
 {
-    int ind, ntimeouts;
+    gi->current_server = NO_SERVER;
+    gi->nchange = 0;
+    gi->nsrvpkts = 0;
+    gi->ncltpkts = 0;
+
+    galaxy_flush(gi);
+}
 
-    ind = (numserv == 0) ? serv_timeouts : serv_timeouts / numserv;
-    ntimeouts = sizeof(serv_rexmit_times) / sizeof(*serv_rexmit_times);
-    if (ind >= ntimeouts)
-       ind = ntimeouts - 1;
-    return serv_rexmit_times[ind];
+static void boot_timeout(arg)
+void *arg;
+{
+    galaxy_new_server((galaxy_info *) arg, NULL);
 }
+
index 0e3c6ac0220e8776f28cc76aca59c03e28a3b620..4c7c319579d10995857c4e872b2c4a178d8159f0 100644 (file)
@@ -434,8 +434,9 @@ void x_gram_draw(dpy, w, gram, region)
    XChangeGC(dpy,gc,GCFunction,&gcvals);
 
    for (i=0,xb=gram->blocks ; i<gram->numblocks ; i++,xb++) {
-      if (XRectInRegion(region,xb->x1,xb->y1,xb->x2-xb->x1,
-                       xb->y2-xb->y1) != RectangleOut) {
+      if ((xb->strlen > 0) &&
+         (XRectInRegion(region,xb->x1,xb->y1,xb->x2-xb->x1,
+                        xb->y2-xb->y1) != RectangleOut)) {
         SetFG(gram->bgcolor^xb->fgcolor);
         text.chars=gram->text+xb->strindex;
         text.nchars=xb->strlen;
index 4c0d1ee9af4d7463a71171db84bfa305b5231300..b66a4b55ab0da0ac150c9ea38326c5a61df1c515 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <stdio.h>
 
+extern char *get_home_directory();
 extern FILE *locate_file();
 
 #endif
index e3c5ed81410d6b4da7c1efc389549cfb7afa14c7..ab9d5df427136ed821b1d0e7bd486ceb428766da 100644 (file)
@@ -126,6 +126,7 @@ static void fake_startup_packet()
     notice.z_port = 0;
     notice.z_kind = ACKED;
     notice.z_auth = ZAUTH_YES;
+    notice.z_dest_galaxy = ZGetDefaultGalaxy();
     sprintf(msgbuf,"Zwgc mark II version %s now running...",
            zwgc_version_string);
     notice.z_message = msgbuf;
index a702c05120192d5b6746db22ff1bbec310124095..7ece689e5e66b9441056e9b09e0e72a1a1c67a82 100644 (file)
@@ -253,7 +253,7 @@ char *decode_notice(notice, hostname)
      ZNotice_t *notice;
      char *hostname;
 {
-    char *temp;
+    char *notice_rhs, *galaxy_rhs;
     string time, notyear, year, date_string, time_string;
 
     /*
@@ -269,18 +269,22 @@ char *decode_notice(notice, hostname)
     var_set_variable("recipient",
                     (notice->z_recipient[0] ? notice->z_recipient : "*"));
     var_set_variable("fullsender", notice->z_sender);
+    var_set_variable("destgalaxy", notice->z_dest_galaxy);
     var_set_variable_to_number("port", (int)notice->z_port);
     var_set_variable_then_free_value("kind", z_kind_to_ascii(notice->z_kind));
     var_set_variable_then_free_value("auth", z_auth_to_ascii(notice->z_auth));
 
     /*
-     * Set $sender to the name of the notice sender except first strip off the
-     * realm name if it is the local realm:
-     */
-    if ( (temp=strchr(notice->z_sender,'@')) && string_Eq(temp+1, ZGetRealm()) )
+     * Set $sender to the name of the notice sender except first strip
+     * off the rhs if it is the rhs of the zephyr server which
+     * delivered the message.  */
+    if ((notice_rhs = strchr(notice->z_sender,'@')) &&
+       (galaxy_rhs = ZGetRhs(notice->z_dest_galaxy)) &&
+       string_Eq(notice_rhs+1, galaxy_rhs))
       var_set_variable_then_free_value("sender",
                                string_CreateFromData(notice->z_sender,
-                                                     temp-notice->z_sender));
+                                                     (notice_rhs-
+                                                      notice->z_sender)));
     else
       var_set_variable("sender", notice->z_sender);
     
index 8adf5f0c85045dca3de065ac339087e777496b48..d67149808746701017b191405ea1e698c9b7f911 100644 (file)
@@ -32,6 +32,7 @@ static char rcsid_subscriptions_c[] = "$Id: subscriptions.c,v 1.13 1999/06/01 19
 #include "error.h"
 #include "file.h"
 #include "main.h"
+#include "zutils.h"
 
 /****************************************************************************/
 /*                                                                          */
@@ -128,6 +129,8 @@ void unpunt(class, instance, recipient)
       int_dictionary_Delete(puntable_addresses_dict, binding);
 }
 
+#if 0
+
 /****************************************************************************/
 /*                                                                          */
 /*           Code to implement batching [un]subscription requests:          */
@@ -161,7 +164,7 @@ static void free_subscription_list(list, number_of_elements)
 
 static void flush_subscriptions()
 {
-      TRAP(ZSubscribeTo(subscription_list,subscription_list_size, 0),
+      TRAP(ZSubscribeTo(NULL, subscription_list,subscription_list_size, 0),
           "while subscribing");
 
     free_subscription_list(subscription_list, subscription_list_size);
@@ -171,7 +174,8 @@ static void flush_subscriptions()
 static void flush_unsubscriptions()
 {
     if (unsubscription_list_size)
-      TRAP(ZUnsubscribeTo(unsubscription_list, unsubscription_list_size, 0),
+      TRAP(ZUnsubscribeTo(NULL, unsubscription_list,
+                         unsubscription_list_size, 0),
           "while unsubscribing");
 
     free_subscription_list(unsubscription_list, unsubscription_list_size);
@@ -232,7 +236,7 @@ static void inithosts()
        strncpy(ourhostcanon, ourhost, sizeof(ourhostcanon)-1);
        return;
     }
-    strncpy(ourhostcanon, hent->h_name, sizeof(ourhostcanon)-1);
+    (void) strncpy(ourhostcanon,hent->h_name, sizeof(ourhostcanon)-1);
     return;
 }
 
@@ -317,19 +321,28 @@ static void load_subscriptions_from_file(file)
     fclose(file);
 }
 
+#endif /* 0 */
+
 #define DEFSUBS "/dev/null"
 
 static void load_subscriptions()
 {
-    FILE *subscriptions_file;
-
-    /* no system default sub file on client--they live on the server */
-    /* BUT...we need to use something to call load_subscriptions_from_file,
-       so we use /dev/null */
-    subscriptions_file = locate_file(subscriptions_filename_override,
-                                    USRSUBS, DEFSUBS);
-    if (subscriptions_file)
-      load_subscriptions_from_file(subscriptions_file);
+    char subsname[MAXPATHLEN];
+    int i, cnt;
+    char *home, *galaxy;
+
+    if (subscriptions_filename_override) {
+       strcpy(subsname, subscriptions_filename_override);
+    } else if (home = get_home_directory()) {
+       strcpy(subsname, home?home:"");
+       strcat(subsname, "/");
+       strcat(subsname, USRSUBS);
+    } else {
+       strcpy(subsname, "");
+    }
+
+    FATAL_TRAP(load_all_sub_files(SUB, *subsname?subsname:NULL),
+              "while loading subscription files");
 }
 
 /****************************************************************************/
@@ -340,45 +353,94 @@ static void load_subscriptions()
 
 int zwgc_active = 0;
 
-static ZSubscription_t *saved_subscriptions = NULL;
-static int number_of_saved_subscriptions;
+static ZSubscription_t **saved_subscriptions = NULL;
+static int *number_of_saved_subscriptions;
 
 void zwgc_shutdown()
 {
+    int cnt, i;
+    char *galaxy;
+
     if (!zwgc_active)
       return;
 
-    TRAP(ZRetrieveSubscriptions(0, &number_of_saved_subscriptions),
-        "while retrieving zephyr subscription list");
+    TRAP(ZGetGalaxyCount(&cnt), "while getting galaxy count");
     if (error_code)
-      return;
-    saved_subscriptions = (ZSubscription_t *)
-      malloc(number_of_saved_subscriptions*sizeof(ZSubscription_t));
-    if (number_of_saved_subscriptions)
-      TRAP(ZGetSubscriptions(saved_subscriptions,
-                            &number_of_saved_subscriptions),
-          "while getting subscriptions");
-    if (error_code) {
-       free(saved_subscriptions);
-       saved_subscriptions = NULL;
+       return;
+
+    if ((saved_subscriptions =
+        (ZSubscription_t **) malloc(sizeof(ZSubscription_t *)*cnt)) == NULL) {
+       fprintf(stderr, "out of memory allocating list of subscription lists");
+       return;
+    }
+    if ((number_of_saved_subscriptions =
+        (int *) malloc(sizeof(int)*cnt)) == NULL) {
+       fprintf(stderr,
+               "out of memory allocating number of subscription lists");
+       return;
+    }
+
+    for (i=0; i<cnt; i++) {
+       TRAP(ZGetGalaxyName(i, &galaxy), "while getting galaxy name")
+           if (error_code)
+               continue;
+
+       TRAP(ZRetrieveSubscriptions(galaxy, 0,
+                                   &number_of_saved_subscriptions[i]),
+            "while retrieving zephyr subscription list");
+       if (error_code)
+           return;
+
+       saved_subscriptions[i] = (ZSubscription_t *)
+           malloc(number_of_saved_subscriptions[i]*sizeof(ZSubscription_t));
+
+       if (number_of_saved_subscriptions[i])
+           TRAP(ZGetSubscriptions(saved_subscriptions[i],
+                                  &number_of_saved_subscriptions[i]),
+                "while getting subscriptions");
+       if (error_code) {
+           free(saved_subscriptions[i]);
+           saved_subscriptions[i] = NULL;
+       }
+       TRAP(ZCancelSubscriptions(galaxy, 0), "while canceling subscriptions");
     }
-    TRAP(ZCancelSubscriptions(0), "while canceling subscriptions") ;
 
     zwgc_active = 0;
 }
 
 void zwgc_startup()
 {
+    int cnt, i;
+    char *galaxy;
+
     if (zwgc_active)
       return;
 
     if (saved_subscriptions) {
-       TRAP(ZSubscribeTo(saved_subscriptions,number_of_saved_subscriptions,0),
-            "while resubscribing to zephyr messages");
-       free(saved_subscriptions);
+       TRAP(ZGetGalaxyCount(&cnt), "while getting galaxy count");
+       if (error_code)
+           return;
+
+       for (i=0; i<cnt; i++) {
+           TRAP(ZGetGalaxyName(i, &galaxy), "while getting galaxy name");
+           if (error_code)
+               continue;
+
+           if (saved_subscriptions[i]) {
+               TRAP(ZSubscribeToSansDefaults(galaxy, saved_subscriptions[i],
+                                             number_of_saved_subscriptions[i],
+                                             0),
+                    "while resubscribing to zephyr messages");
+               free(saved_subscriptions[i]);
+               saved_subscriptions[i] = NULL;
+           }
+       }
+
        saved_subscriptions = NULL;
-    } else
-      load_subscriptions();
+    } else {
+       load_subscriptions();
+    }
+
 
     zwgc_active = 1;
 }
index 577b035612e57278165c1ebfec99ee19f46a0b83..3d114c4396ab45eccc22165c9d0de911723e987c 100644 (file)
@@ -48,7 +48,7 @@ void xmarkSetBound(gram,x,y,which)
      int x,y;
      int which;
 {
-   int i,xofs,yofs;
+   int i,j,xofs,yofs;
    XFontStruct *font;
    xblock *xb;
    unsigned char *s;
@@ -104,26 +104,34 @@ void xmarkSetBound(gram,x,y,which)
    }
 
    for (yofs=xb->y1;(i<gram->numblocks) && (xb->y1 == yofs);i++,xb++) {
-
       if (x <= xb->x2) {
         markblock[which]=i;
 
         xofs=xb->x1;
+        
         if ((x < xofs) || (y < xb->y1)) {
            markchar[which]=0;
+           markpixel[which]=0;
+           RETURN;
+        }
+
+        if (xb->strlen == -1) {
+           markchar[which]=0;
+           markpixel[which]=0;
            RETURN;
         }
+
         font=get_fontst_from_fid(xb->fid);
-        for (i=0,s=(unsigned char *)((gram->text)+(xb->strindex));
-             xofs<x && i<xb->strlen;
-             i++,s++) {
-            /* if font->per_char is NULL, then we should use min_bounds */
-            short usewidth = font->per_char ? font->per_char[*s - font->min_char_or_byte2].width : font->min_bounds.width;
-          if (x <= (xofs+=usewidth)) {
-             markchar[which]=i;
-             markpixel[which]=xofs - xb->x1 - usewidth;
-             RETURN;
-          }
+        for (j=0,s=(unsigned char *)((gram->text)+(xb->strindex));
+             xofs<x && j<xb->strlen;
+             j++,s++) {
+           /* if font->per_char is NULL, then we should use min_bounds */
+           short usewidth = font->per_char ? font->per_char[*s - font->min_char_or_byte2].width : font->min_bounds.width;
+           if (x <= (xofs+=usewidth)) {
+              markchar[which]=j;
+              markpixel[which]=xofs - xb->x1 - usewidth;
+              RETURN;
+           }
         }
       }
    }
@@ -364,21 +372,24 @@ char *xmarkGetText()
        }
 
        for (i=startblock; i<=endblock; i++) {
-         if (last_y != -1 && last_y != markgram->blocks[i].y)
-           text_so_far = string_Concat2(text_so_far, "\n");
          index = markgram->blocks[i].strindex;
          len = markgram->blocks[i].strlen;
-         if (startblock == endblock)
-           temp = string_CreateFromData(text+index+startchar,
-                                        endchar-startchar);
-         else if (i==startblock)
-           temp = string_CreateFromData(text+index+startchar,len-startchar);
-         else if (i==endblock)
-           temp = string_CreateFromData(text+index,endchar);
-         else
-           temp = string_CreateFromData(text+index,len);
-         text_so_far = string_Concat2(text_so_far, temp);
-         free(temp);
+         if ((len == -1) && (i != endblock)) {
+            text_so_far = string_Concat2(text_so_far, "\n");
+         } else {
+            if (startblock == endblock)
+               temp = string_CreateFromData(text+index+startchar,
+                                            endchar-startchar);
+            else if (i==startblock)
+               temp = string_CreateFromData(text+index+startchar,
+                                            len-startchar);
+            else if (i==endblock)
+               temp = string_CreateFromData(text+index, endchar);
+            else
+               temp = string_CreateFromData(text+index, len);
+            text_so_far = string_Concat2(text_so_far, temp);
+            free(temp);
+         }
          last_y = markgram->blocks[i].y;
        }
     }
index 05bfab8bb1a0019030103c9b9568cd1200b7e0ce..81c0d24d19e8e9c6ff55e0de66bcd48f8af4eac6 100644 (file)
@@ -134,7 +134,7 @@ void fixup_and_draw(dpy, style, auxblocks, blocks, num, lines, numlines,
     x_gram *gram;
     int strindex = 0;
 
-    int line, block=0;
+    int line, block;
     int maxwidth=0, chars=0, maxascent, maxdescent;
     int ssize,  lsize,csize, rsize, width;
     int i, ascent, descent;
@@ -156,7 +156,8 @@ void fixup_and_draw(dpy, style, auxblocks, blocks, num, lines, numlines,
        
        /* add up sizes for each block, get max ascent and descent */
        
-       for (i=0; i<lines[line].numblock; i++,block++) {
+       for (i=0, block=lines[line].startblock; i<lines[line].numblock;
+            i++,block++) {
            chars += auxblocks[block].len;
            ssize = XTextWidth(auxblocks[block].font, auxblocks[block].str,
                               auxblocks[block].len);
@@ -164,19 +165,19 @@ void fixup_and_draw(dpy, style, auxblocks, blocks, num, lines, numlines,
            ascent = auxblocks[block].font->ascent;
            descent = auxblocks[block].font->descent;
            if (ascent>maxascent)
-             maxascent = ascent;
+               maxascent = ascent;
            if (descent>maxdescent)
-             maxdescent = descent;
+               maxdescent = descent;
            switch (auxblocks[block].align) {
-             case LEFTALIGN:
+           case LEFTALIGN:
                lsize += ssize;
                break;
-               
-             case CENTERALIGN:
+
+           case CENTERALIGN:
                csize += ssize;
                break;
-               
-             case RIGHTALIGN:
+
+           case RIGHTALIGN:
                rsize += ssize;
                break;
            }
@@ -246,7 +247,6 @@ void fixup_and_draw(dpy, style, auxblocks, blocks, num, lines, numlines,
     /* set x1,y1,x2,y2 of each block also. */
 
     gram->text = (char *)malloc(chars);
-    block = 0;
 
     for (line=0; line<numlines; line++) {
        lofs = internal_border_width;
@@ -257,7 +257,8 @@ void fixup_and_draw(dpy, style, auxblocks, blocks, num, lines, numlines,
        yend = yofs+lines[line].descent+1;   /* +1 because lines look scrunched
                                                without it. */
 
-       for (i=0; i<lines[line].numblock; i++,block++) {
+       for (i=0, block=lines[line].startblock; i<lines[line].numblock;
+            i++,block++) {
            blocks[block].fid = auxblocks[block].font->fid;
            switch (auxblocks[block].align) {
              case LEFTALIGN:
@@ -291,8 +292,20 @@ void fixup_and_draw(dpy, style, auxblocks, blocks, num, lines, numlines,
            strindex += blocks[block].strlen;
        }
 
-       yofs = yend;
+       blocks[block].fid = block?blocks[block-1].fid:auxblocks[0].font->fid;
+       blocks[block].x = maxwidth + internal_border_width;
+       blocks[block].x1 = (lines[line].rsize?rofs:
+                          (lines[line].csize?cofs:
+                           lofs));
+       blocks[block].x2 = maxwidth + internal_border_width*2;
+       blocks[block].y = yofs;
+       blocks[block].y1 = ystart;
+       blocks[block].y2 = yend;
+       blocks[block].strindex = 0;
+       blocks[block].strlen = -1; /* magic value indicates newline */
+       block++;
 
+       yofs = yend;
     }
 
     if ((geometry = var_get_variable("X_geometry")),(geometry[0]=='\0')) 
@@ -374,8 +387,8 @@ void xshow(dpy, desc, numstr, numnl)
 
     lines = (xlinedesc *)malloc(sizeof(xlinedesc)*(numnl+1));
 
-    blocks = (xblock *)malloc(sizeof(xblock)*numstr);
-    auxblocks = (xauxblock *)malloc(sizeof(xauxblock)*numstr);
+    blocks = (xblock *)malloc(sizeof(xblock)*(numstr+numnl+1));
+    auxblocks = (xauxblock *)malloc(sizeof(xauxblock)*(numstr+numnl+1));
 
     curmode.bold = 0;
     curmode.italic = 0;
@@ -504,12 +517,24 @@ void xshow(dpy, desc, numstr, numnl)
            break;
 
          case DT_NL:
-           lines[line].startblock = linestart;
-           lines[line].numblock = nextblock-linestart;
            font = MODE_TO_FONT(dpy,style,&curmode);
+
+           auxblocks[nextblock].len = -1;
+           auxblocks[nextblock].font = font;
+           if (curmode.expcolor)
+              blocks[nextblock].fgcolor = curmode.color;
+           else
+              blocks[nextblock].fgcolor =
+                x_string_to_color(mode_to_colorname(dpy,style,&curmode),
+                                  default_fgcolor);
+           nextblock++;
+
+           lines[line].startblock = linestart;
+           lines[line].numblock = (nextblock-linestart)-1;
            lines[line].ascent = font->ascent;
            lines[line].descent = font->descent;
            line++;
+
            linestart = nextblock;
            break;
        }
@@ -518,9 +543,19 @@ void xshow(dpy, desc, numstr, numnl)
     /* case DT_EOF:    will drop through to here. */
 
     if (linestart != nextblock) {
-       lines[line].startblock = linestart;
-       lines[line].numblock = nextblock-linestart;
        font = MODE_TO_FONT(dpy,style,&curmode);
+       auxblocks[nextblock].len = -1;
+       auxblocks[nextblock].font = font;
+       if (curmode.expcolor)
+         blocks[nextblock].fgcolor = curmode.color;
+       else
+         blocks[nextblock].fgcolor =
+            x_string_to_color(mode_to_colorname(dpy,style,&curmode),
+                              default_fgcolor);
+       nextblock++;
+
+       lines[line].startblock = linestart;
+       lines[line].numblock = (nextblock-linestart)-1;
        lines[line].ascent = 0;
        lines[line].descent = 0;
        line++;
index f988a329641ed77c029a04ac7ae48a63445f53b8..0e69933ef9be73bfa9344bd32a54049bc07ae320 100644 (file)
@@ -132,14 +132,6 @@ void zephyr_init(notice_handler)
        fprintf(stderr, "zwgc: and try again.\n");
        exit(1);
     }
-    port_file = fopen(temp, "w");
-    if (port_file) {
-       fprintf(port_file, "%d\n", port);
-       fclose(port_file);
-    } else {
-       fprintf(stderr, "zwgc: error while opening %s for writing: ", temp);
-       perror("");
-    }
 
     /* Set hostname and tty for locations.  If we support X, use the
      * display string for the default tty name. */
@@ -159,28 +151,22 @@ void zephyr_init(notice_handler)
      * not one of the allowed ones, print an error and treat it as
      * EXPOSE_NONE.
      */
-    if (temp = ZGetVariable("exposure")) {
-       if (!(exposure = ZParseExposureLevel(temp))) {
-           ERROR2("invalid exposure level %s, using exposure level none instead.\n", temp);
-           exposure = EXPOSE_NONE;
-       }
-    } else
-      exposure = EXPOSE_OPSTAFF;
-    error_code = ZSetLocation(exposure); /* <<<>>> */
-    if (error_code != ZERR_LOGINFAIL)
+
+    error_code = set_exposure("*", exposure = ZGetVariable("exposure"));
+    if (error_code)
       TRAP( error_code, "while setting location" );
 
     /*
-     * If the exposure level isn't EXPOSE_NONE, turn on recieving notices.
+     * If the exposure level isn't EXPOSE_NONE, turn on receiving notices.
      * (this involves reading in the subscription file, etc.)
      */
     if (string_Neq(exposure, EXPOSE_NONE))
       zwgc_startup();
 
     /*
-     * Set $realm to our realm and $user to our zephyr username:
+     * Set $galaxy to our galaxy and $user to our zephyr username:
      */
-    var_set_variable("realm", ZGetRealm());
+    var_set_variable("galaxy", ZGetDefaultGalaxy());
     var_set_variable("user", ZGetSender());
 
     /*
@@ -189,6 +175,16 @@ void zephyr_init(notice_handler)
     mux_add_input_source(ZGetFD(), (void (*)())handle_zephyr_input,
                         notice_handler);
     zephyr_inited = 1;
+
+    port_file = fopen(temp, "w");
+    if (port_file) {
+       fprintf(port_file, "%d\n", port);
+       fclose(port_file);
+    } else {
+       fprintf(stderr, "zwgc: error while opening %s for writing: ", temp);
+       perror("");
+    }
+
     return;
 }
 
@@ -199,6 +195,8 @@ void zephyr_init(notice_handler)
 void finalize_zephyr() /* <<<>>> */
 {
     string temp;
+    int i, cnt;
+    char *galaxy;
 
     if (zephyr_inited) {
        /*
@@ -216,17 +214,28 @@ void finalize_zephyr() /* <<<>>> */
         * Cancel our subscriptions, unset our location, and close our zephyr
         * connection:
         */
+
+       TRAP(ZGetGalaxyCount(&cnt), "while getting galaxy count");
+       if (error_code)
+           return;
+
+       for (i=0; i<cnt; i++) {
+           TRAP(ZGetGalaxyName(i, &galaxy), "while getting galaxy name");
+           if (error_code)
+               continue;
 #ifdef DEBUG
-       if (zwgc_debug) {
-           TRAP( ZUnsetLocation(), "while unsetting location" );
-           TRAP( ZCancelSubscriptions(0), "while canceling subscriptions" );
-       } else {
+           if (zwgc_debug) {
+               TRAP( ZCancelSubscriptions(galaxy, 0),
+                     "while canceling subscriptions" );
+               TRAP( ZUnsetLocation(galaxy), "while unsetting location" );
+           } else {
 #endif /* DEBUG */
-           (void) ZUnsetLocation();
-           (void) ZCancelSubscriptions(0);
+               (void) ZCancelSubscriptions(galaxy, 0);
+               (void) ZUnsetLocation(galaxy);
 #ifdef DEBUG
-       }
+           }
 #endif /* DEBUG */
+       }
        ZClosePort();
     }
     return;