summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Sam Hartman <hartmans@mit.edu>2002-07-11 23:32:11 +0000
committerGravatar Sam Hartman <hartmans@mit.edu>2002-07-11 23:32:11 +0000
commit0f0b68e3637451e5920be85676a2b797eff65ba3 (patch)
tree8ff68a6be5b6118b47fa8d789db3aa25e31b6a98
parent55146dda74723763d48ae3e01aad21a0498bd3e9 (diff)
This commit was generated by cvs2svn to compensate for changes in r127,
which included commits to RCS files with non-trunk default branches.
-rw-r--r--acconfig.h5
-rw-r--r--clients/xzwrite/destlist.c7
-rw-r--r--clients/xzwrite/interface.c9
-rw-r--r--clients/xzwrite/zephyr.c19
-rw-r--r--clients/zaway/zaway.c94
-rw-r--r--clients/zctl/zctl.12
-rw-r--r--clients/zctl/zctl.c1005
-rw-r--r--clients/zctl/zctl_cmds.ct26
-rw-r--r--clients/zleave/zleave.c2
-rw-r--r--clients/zlocate/zlocate.c27
-rw-r--r--clients/znol/znol.c22
-rw-r--r--clients/zpopnotify/zpopnotify.c2
-rw-r--r--clients/zstat/zstat.c64
-rw-r--r--clients/zwrite/zwrite.c24
-rw-r--r--h/config.h.in17
-rw-r--r--lib/ZAsyncLocate.c4
-rw-r--r--lib/ZCkAuth.c7
-rw-r--r--lib/ZFmtAuth.c8
-rw-r--r--lib/ZFmtRaw.c4
-rw-r--r--lib/ZFmtRawLst.c6
-rw-r--r--lib/ZFmtSmRLst.c4
-rw-r--r--lib/ZFmtSmRaw.c4
-rw-r--r--lib/ZGetSender.c4
-rw-r--r--lib/ZInit.c167
-rw-r--r--lib/ZLocations.c19
-rw-r--r--lib/ZMkAuth.c83
-rw-r--r--lib/ZNewLocU.c6
-rw-r--r--lib/ZOpenPort.c8
-rw-r--r--lib/ZParseNot.c59
-rw-r--r--lib/ZReadAscii.c15
-rw-r--r--lib/ZRecvNot.c29
-rw-r--r--lib/ZRetSubs.c11
-rw-r--r--lib/ZSetDest.c2
-rw-r--r--lib/ZSubs.c31
-rw-r--r--lib/zephyr_err.et8
-rw-r--r--server/bdump.c32
-rw-r--r--server/dispatch.c212
-rw-r--r--server/kstuff.c60
-rw-r--r--server/subscr.c402
-rw-r--r--server/uloc.c36
-rw-r--r--server/version.c57
-rw-r--r--zhm/queue.c122
-rw-r--r--zhm/zhm.h84
-rw-r--r--zhm/zhm_client.c101
-rw-r--r--zhm/zhm_server.c412
-rw-r--r--zwgc/X_gram.c5
-rw-r--r--zwgc/file.h1
-rw-r--r--zwgc/main.c1
-rw-r--r--zwgc/notice.c16
-rw-r--r--zwgc/subscriptions.c126
-rw-r--r--zwgc/xmark.c61
-rw-r--r--zwgc/xshow.c71
-rw-r--r--zwgc/zephyr.c63
53 files changed, 1977 insertions, 1689 deletions
diff --git a/acconfig.h b/acconfig.h
index 96eb3d1..102efca 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -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
diff --git a/clients/xzwrite/destlist.c b/clients/xzwrite/destlist.c
index 8621922..1cc91e1 100644
--- a/clients/xzwrite/destlist.c
+++ b/clients/xzwrite/destlist.c
@@ -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';
}
diff --git a/clients/xzwrite/interface.c b/clients/xzwrite/interface.c
index 716e0e3..e218621 100644
--- a/clients/xzwrite/interface.c
+++ b/clients/xzwrite/interface.c
@@ -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);
}
diff --git a/clients/xzwrite/zephyr.c b/clients/xzwrite/zephyr.c
index 6e25dd5..1354fd1 100644
--- a/clients/xzwrite/zephyr.c
+++ b/clients/xzwrite/zephyr.c
@@ -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)
diff --git a/clients/zaway/zaway.c b/clients/zaway/zaway.c
index 332598f..7703092 100644
--- a/clients/zaway/zaway.c
+++ b/clients/zaway/zaway.c
@@ -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);
}
diff --git a/clients/zctl/zctl.1 b/clients/zctl/zctl.1
index 73d4fd5..614ca5a 100644
--- a/clients/zctl/zctl.1
+++ b/clients/zctl/zctl.1
@@ -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
diff --git a/clients/zctl/zctl.c b/clients/zctl/zctl.c
index b7154ec..e1e5174 100644
--- a/clients/zctl/zctl.c
+++ b/clients/zctl/zctl.c
@@ -3,7 +3,8 @@
*
* Created by: Robert French
*
- * $Id$
+ * $Source$
+ * $Author$
*
* Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
* For copying and distribution information, see the file
@@ -16,46 +17,36 @@
#include <com_err.h>
#include <pwd.h>
#include <netdb.h>
+#include <errno.h>
#ifndef lint
static const char *rcsid_zctl_c = "$Id$";
#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");
@@ -139,9 +112,9 @@ main(argc,argv)
printf("ZCTL $Revision$ (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();
-}
diff --git a/clients/zctl/zctl_cmds.ct b/clients/zctl/zctl_cmds.ct
index 374effc..aa9c5c4 100644
--- a/clients/zctl/zctl_cmds.ct
+++ b/clients/zctl/zctl_cmds.ct
@@ -1,4 +1,6 @@
-# $Id$
+# $Source$
+# $Author$
+# $Header$
#
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;
@@ -23,17 +31,29 @@
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;
@@ -80,7 +100,7 @@
unhide;
request ss_list_requests, "List available commands.",
- list_requests, lr, "?";
+ list_requests, help, lr, "?";
request ss_quit, "Quit.",
quit, exit, q;
diff --git a/clients/zleave/zleave.c b/clients/zleave/zleave.c
index 91e8c14..edea16a 100644
--- a/clients/zleave/zleave.c
+++ b/clients/zleave/zleave.c
@@ -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");
diff --git a/clients/zlocate/zlocate.c b/clients/zlocate/zlocate.c
index 4469565..8428274 100644
--- a/clients/zlocate/zlocate.c
+++ b/clients/zlocate/zlocate.c
@@ -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);
}
diff --git a/clients/znol/znol.c b/clients/znol/znol.c
index 53fd47c..2c843c0 100644
--- a/clients/znol/znol.c
+++ b/clients/znol/znol.c
@@ -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":
diff --git a/clients/zpopnotify/zpopnotify.c b/clients/zpopnotify/zpopnotify.c
index b2f79e3..b6488c6 100644
--- a/clients/zpopnotify/zpopnotify.c
+++ b/clients/zpopnotify/zpopnotify.c
@@ -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));
diff --git a/clients/zstat/zstat.c b/clients/zstat/zstat.c
index 0c034f9..1ed7054 100644
--- a/clients/zstat/zstat.c
+++ b/clients/zstat/zstat.c
@@ -22,7 +22,7 @@ static const char rcsid_zstat_c[] = "$Id$";
#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);
diff --git a/clients/zwrite/zwrite.c b/clients/zwrite/zwrite.c
index 5edc779..ebd4a41 100644
--- a/clients/zwrite/zwrite.c
+++ b/clients/zwrite/zwrite.c
@@ -29,7 +29,7 @@ static const char rcsid_zwrite_c[] = "$Id$";
#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\
diff --git a/h/config.h.in b/h/config.h.in
index 1a3dd61..8c62ca8 100644
--- a/h/config.h.in
+++ b/h/config.h.in
@@ -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
@@ -51,6 +51,12 @@
/* 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
@@ -102,9 +108,18 @@
/* 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
diff --git a/lib/ZAsyncLocate.c b/lib/ZAsyncLocate.c
index d248064..055cc52 100644
--- a/lib/ZAsyncLocate.c
+++ b/lib/ZAsyncLocate.c
@@ -16,7 +16,8 @@
static const char rcsid_ZAsyncLocate_c[] = "$Id$";
#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);
diff --git a/lib/ZCkAuth.c b/lib/ZCkAuth.c
index 17fdc2b..8db1f94 100644
--- a/lib/ZCkAuth.c
+++ b/lib/ZCkAuth.c
@@ -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
diff --git a/lib/ZFmtAuth.c b/lib/ZFmtAuth.c
index c2d8a00..29ed7f7 100644
--- a/lib/ZFmtAuth.c
+++ b/lib/ZFmtAuth.c
@@ -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;
diff --git a/lib/ZFmtRaw.c b/lib/ZFmtRaw.c
index 2940f98..6e2f2cc 100644
--- a/lib/ZFmtRaw.c
+++ b/lib/ZFmtRaw.c
@@ -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;
diff --git a/lib/ZFmtRawLst.c b/lib/ZFmtRawLst.c
index 7d83f71..1d7acd6 100644
--- a/lib/ZFmtRawLst.c
+++ b/lib/ZFmtRawLst.c
@@ -3,7 +3,7 @@
*
* Created by: Robert French
*
- * $Id$
+n * $Id$
*
* 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;
diff --git a/lib/ZFmtSmRLst.c b/lib/ZFmtSmRLst.c
index 6e41285..31574a2 100644
--- a/lib/ZFmtSmRLst.c
+++ b/lib/ZFmtSmRLst.c
@@ -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;
diff --git a/lib/ZFmtSmRaw.c b/lib/ZFmtSmRaw.c
index a9ce79d..cae6d4b 100644
--- a/lib/ZFmtSmRaw.c
+++ b/lib/ZFmtSmRaw.c
@@ -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;
diff --git a/lib/ZGetSender.c b/lib/ZGetSender.c
index df5f3e2..aac5d7c 100644
--- a/lib/ZGetSender.c
+++ b/lib/ZGetSender.c
@@ -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);
}
diff --git a/lib/ZInit.c b/lib/ZInit.c
index 401f6db..9eb0fa5 100644
--- a/lib/ZInit.c
+++ b/lib/ZInit.c
@@ -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();
diff --git a/lib/ZLocations.c b/lib/ZLocations.c
index e157342..a237604 100644
--- a/lib/ZLocations.c
+++ b/lib/ZLocations.c
@@ -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);
diff --git a/lib/ZMkAuth.c b/lib/ZMkAuth.c
index cbd3136..1a35058 100644
--- a/lib/ZMkAuth.c
+++ b/lib/ZMkAuth.c
@@ -16,47 +16,76 @@
static const char rcsid_ZMakeAuthentication_c[] = "$Id$";
#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
}
diff --git a/lib/ZNewLocU.c b/lib/ZNewLocU.c
index 9ad620d..94a1278 100644
--- a/lib/ZNewLocU.c
+++ b/lib/ZNewLocU.c
@@ -17,7 +17,8 @@ static const char rcsid_ZNewLocateUser_c[] =
"$Id$";
#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);
diff --git a/lib/ZOpenPort.c b/lib/ZOpenPort.c
index b8241db..ee043ae 100644
--- a/lib/ZOpenPort.c
+++ b/lib/ZOpenPort.c
@@ -68,3 +68,11 @@ Code_t ZOpenPort(port)
return (ZERR_NONE);
}
+
+int ZGetPort()
+{
+ if (__Zephyr_open)
+ return(__Zephyr_port);
+ else
+ return(-1);
+}
diff --git a/lib/ZParseNot.c b/lib/ZParseNot.c
index 6d393a0..44dbaf6 100644
--- a/lib/ZParseNot.c
+++ b/lib/ZParseNot.c
@@ -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;
diff --git a/lib/ZReadAscii.c b/lib/ZReadAscii.c
index f826bc7..baf7469 100644
--- a/lib/ZReadAscii.c
+++ b/lib/ZReadAscii.c
@@ -17,21 +17,6 @@ static char rcsid_ZReadAscii_c[] = "$Id$";
#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)
diff --git a/lib/ZRecvNot.c b/lib/ZRecvNot.c
index 27cba29..bfed17a 100644
--- a/lib/ZRecvNot.c
+++ b/lib/ZRecvNot.c
@@ -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;
}
diff --git a/lib/ZRetSubs.c b/lib/ZRetSubs.c
index bd2cf5d..e79941f 100644
--- a/lib/ZRetSubs.c
+++ b/lib/ZRetSubs.c
@@ -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));
diff --git a/lib/ZSetDest.c b/lib/ZSetDest.c
index 7190dcd..f6b8b4b 100644
--- a/lib/ZSetDest.c
+++ b/lib/ZSetDest.c
@@ -21,7 +21,5 @@ Code_t ZSetDestAddr(addr)
{
__HM_addr = *addr;
- __HM_set = 1;
-
return (ZERR_NONE);
}
diff --git a/lib/ZSubs.c b/lib/ZSubs.c
index 15a5a91..c8e5a03 100644
--- a/lib/ZSubs.c
+++ b/lib/ZSubs.c
@@ -17,41 +17,48 @@
static const char rcsid_ZSubscriptions_c[] = "$Id$";
#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);
diff --git a/lib/zephyr_err.et b/lib/zephyr_err.et
index 8fae4b3..3f24aec 100644
--- a/lib/zephyr_err.et
+++ b/lib/zephyr_err.et
@@ -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
diff --git a/server/bdump.c b/server/bdump.c
index 80f7e72..ed17199 100644
--- a/server/bdump.c
+++ b/server/bdump.c
@@ -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);
diff --git a/server/dispatch.c b/server/dispatch.c
index 493fcd4..0092bad 100644
--- a/server/dispatch.c
+++ b/server/dispatch.c
@@ -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;
}
diff --git a/server/kstuff.c b/server/kstuff.c
index ca9f055..89791cf 100644
--- a/server/kstuff.c
+++ b/server/kstuff.c
@@ -8,8 +8,7 @@
* "mit-copyright.h".
*/
/*
- * $Source$
- * $Header$
+ * $Id$
*/
#include "zserver.h"
@@ -22,6 +21,8 @@ static const char rcsid_kstuff_c[] = "$Id$";
#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;
diff --git a/server/subscr.c b/server/subscr.c
index eb3ba27..2ef5bd9 100644
--- a/server/subscr.c
+++ b/server/subscr.c
@@ -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)) {
diff --git a/server/uloc.c b/server/uloc.c
index 0d7ea8e..b0e3866 100644
--- a/server/uloc.c
+++ b/server/uloc.c
@@ -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++)
diff --git a/server/version.c b/server/version.c
index 230a66c..477ac4e 100644
--- a/server/version.c
+++ b/server/version.c
@@ -17,11 +17,14 @@
const char zephyr_version[] = "Zephyr system version 2.0";
+static char version[] = {
+ "Zephyr Server "
#ifdef DEBUG
-const char version[] = "Zephyr server (DEBUG) $Revision$";
-#else
-const char version[] = "Zephyr server $Revision$";
+ "(DEBUG) "
#endif
+ "$Revision$"
+ ": " 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$: %s",
- ZSERVER_VERSION_STRING);
-#else
- sprintf(vers_buf,"Zephyr Server $Revision$: %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;
}
-
-
-
-
-
diff --git a/zhm/queue.c b/zhm/queue.c
index 5a072aa..ecffdbf 100644
--- a/zhm/queue.c
+++ b/zhm/queue.c
@@ -18,78 +18,83 @@ static char rcsid_queue_c[] = "$Id$";
#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");
diff --git a/zhm/zhm.h b/zhm/zhm.h
index 3d6f153..1d4ef2b 100644
--- a/zhm/zhm.h
+++ b/zhm/zhm.h
@@ -42,30 +42,78 @@
#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
diff --git a/zhm/zhm_client.c b/zhm/zhm_client.c
index 6ee448b..87b7362 100644
--- a/zhm/zhm_client.c
+++ b/zhm/zhm_client.c
@@ -18,79 +18,95 @@ static char rcsid_hm_client_c[] = "$Id$";
#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);
}
diff --git a/zhm/zhm_server.c b/zhm/zhm_server.c
index 50fa04f..9d515d5 100644
--- a/zhm/zhm_server.c
+++ b/zhm/zhm_server.c
@@ -18,30 +18,15 @@ static char rcsid_hm_server_c[] = "$Id$";
#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);
}
+
diff --git a/zwgc/X_gram.c b/zwgc/X_gram.c
index 5743667..0597135 100644
--- a/zwgc/X_gram.c
+++ b/zwgc/X_gram.c
@@ -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;
diff --git a/zwgc/file.h b/zwgc/file.h
index b0aff1f..d222873 100644
--- a/zwgc/file.h
+++ b/zwgc/file.h
@@ -19,6 +19,7 @@
#include <stdio.h>
+extern char *get_home_directory();
extern FILE *locate_file();
#endif
diff --git a/zwgc/main.c b/zwgc/main.c
index 83413da..151647e 100644
--- a/zwgc/main.c
+++ b/zwgc/main.c
@@ -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;
diff --git a/zwgc/notice.c b/zwgc/notice.c
index e3d4cdb..5168562 100644
--- a/zwgc/notice.c
+++ b/zwgc/notice.c
@@ -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);
diff --git a/zwgc/subscriptions.c b/zwgc/subscriptions.c
index c319729..0bdac84 100644
--- a/zwgc/subscriptions.c
+++ b/zwgc/subscriptions.c
@@ -32,6 +32,7 @@ static char rcsid_subscriptions_c[] = "$Id$";
#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;
}
diff --git a/zwgc/xmark.c b/zwgc/xmark.c
index 1c796f3..ba3c26f 100644
--- a/zwgc/xmark.c
+++ b/zwgc/xmark.c
@@ -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;
}
}
diff --git a/zwgc/xshow.c b/zwgc/xshow.c
index d970ccc..4cc3f16 100644
--- a/zwgc/xshow.c
+++ b/zwgc/xshow.c
@@ -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++;
diff --git a/zwgc/zephyr.c b/zwgc/zephyr.c
index c3276e5..6eaee64 100644
--- a/zwgc/zephyr.c
+++ b/zwgc/zephyr.c
@@ -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;