From: hartmans Date: Thu, 11 Jul 2002 23:32:11 +0000 (+0000) Subject: This commit was generated by cvs2svn to compensate for changes in r127, X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=commitdiff_plain;h=913576fd8e129c0da1f57cb0f86691727a70b1d1;p=1ts-debian.git This commit was generated by cvs2svn to compensate for changes in r127, which included commits to RCS files with non-trunk default branches. git-svn-id: svn://svn.1ts.org/debian/trunk/zephyr@128 cbed1d16-5ef5-0310-b6a1-d4a37b08ba1f --- 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 f3235e8..418b6d1 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 #include #include +#include #ifndef lint -static const char *rcsid_zctl_c = "$Id: zctl.c,v 1.31 1999/08/13 00:19:38 danw Exp $"; +static const char *rcsid_zctl_c = "$Id: zctl.c,v 1.28.4.1 1997/01/06 01:40:24 marc Exp $"; #endif -#define SUBSATONCE 7 -#define SUB 0 -#define UNSUB 1 -#define LIST 2 +#include "zutils.h" #define USERS_SUBS "/.zephyr.subs" #define OLD_SUBS "/.subscriptions" -#define TOKEN_HOSTNAME "%host%" -#define TOKEN_CANONNAME "%canon%" -#define TOKEN_ME "%me%" -#define TOKEN_WILD "*" - -#define ALL 0 -#define UNSUBONLY 1 -#define SUBONLY 2 - #define ERR (-1) #define NOT_REMOVED 0 #define REMOVED 1 int purge_subs(); +void add_file(char *fn, char *galaxy, short wgport, ZSubscription_t *subs, + int mode); +void del_file(char *fn, char *galaxy, short wgport, ZSubscription_t *subs, + int mode); + int sci_idx; char subsname[BUFSIZ]; -char ourhost[MAXHOSTNAMELEN],ourhostcanon[MAXHOSTNAMELEN]; extern ss_request_table zctl_cmds; -void add_file(), del_file(), fix_macros(), fix_macros2(); - main(argc,argv) int argc; char *argv[]; { struct passwd *pwd; - struct hostent *hent; char ssline[BUFSIZ],oldsubsname[BUFSIZ],*envptr,*tty = NULL; int retval,code,i; #ifdef HAVE_SYS_UTSNAME @@ -101,24 +92,6 @@ main(argc,argv) } } -#ifdef HAVE_SYS_UTSNAME - uname(&name); - strcpy(ourhost, name.nodename); -#else - if (gethostname(ourhost,MAXHOSTNAMELEN) == -1) { - com_err(argv[0],errno,"while getting host name"); - exit (1); - } -#endif - - if (!(hent = gethostbyname(ourhost))) { - fprintf(stderr,"%s: Can't resolve hostname %s; %s may be " - "wrong in subscriptions",argv[0],ourhost, - TOKEN_CANONNAME); - strncpy(ourhostcanon,ourhost,sizeof(ourhostcanon)-1); - } else - strncpy(ourhostcanon,hent->h_name,sizeof(ourhostcanon)-1); - sci_idx = ss_create_invocation("zctl","",0,&zctl_cmds,&code); if (code) { ss_perror(sci_idx,code,"while creating invocation"); @@ -137,11 +110,11 @@ main(argc,argv) exit((code != 0)); } - printf("ZCTL $Revision: 1.31 $ (Protocol %s%d.%d) - Type '?' for a list of commands.\n\n", + printf("ZCTL $Revision: 1.28.4.1 $ (Protocol %s%d.%d) - Type '?' for a list of commands.\n\n", ZVERSIONHDR, - ZVERSIONMAJOR,ZVERSIONMINOR); + ZVERSIONMAJOR,ZVERSIONMINOR_GALAXY); - ss_listen(sci_idx); + code = ss_listen(sci_idx); exit(0); } @@ -166,113 +139,136 @@ flush_locations(argc,argv) int argc; char *argv[]; { - int retval; + int retval; + char *galaxy; + int cnt, i; - if (argc > 1) { - fprintf(stderr,"Usage: %s\n",argv[0]); - return; + if (argc > 2) { + fprintf(stderr,"Usage: %s [galaxy]\n",argv[0]); + return; + } + + galaxy = (argc > 1)?argv[1]:NULL; + + if (galaxy && strcmp(galaxy, "*") == 0) { + if (retval = ZGetGalaxyCount(&cnt)) { + ss_perror(sci_idx, retval, "while getting galaxy count"); + return; } - if ((retval = ZFlushMyLocations()) != ZERR_NONE) - ss_perror(sci_idx,retval,"while flushing locations"); + for (i=0; i 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 *)¬ice, 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(¬ice,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 *)¬ice, 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 *)¬ice, 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(¬ice,ZNOAUTH)) != ZERR_NONE) + for (i=0; i [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 [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 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 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; izsub_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 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;itm_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(¬ice); 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(¬ice); diff --git a/clients/zwrite/zwrite.c b/clients/zwrite/zwrite.c index 678aae5..f44c246 100644 --- a/clients/zwrite/zwrite.c +++ b/clients/zwrite/zwrite.c @@ -29,7 +29,7 @@ static const char rcsid_zwrite_c[] = "$Id: zwrite.c,v 1.49 1999/08/13 00:19:42 d #define MAXRECIPS 100 int nrecips, msgarg, verbose, quiet, nodot, cc; -char *whoami, *inst, *class, *opcode, *realm, *recips[MAXRECIPS]; +char *whoami, *inst, *class, *opcode, *rhs, *galaxy, *recips[MAXRECIPS]; Z_AuthProc auth; void un_tabify(); @@ -174,7 +174,13 @@ main(argc, argv) if (arg == argc-1) usage(whoami); arg++; - realm = argv[arg]; + rhs = argv[arg]; + break; + case 'G': + if (arg == argc-1) + usage(whoami); + arg++; + galaxy = argv[arg]; break; case 'C': cc = 1; @@ -224,6 +230,7 @@ main(argc, argv) notice.z_sender = 0; notice.z_message_len = 0; notice.z_recipient = ""; + notice.z_dest_galaxy = galaxy; if (format) notice.z_default_format = format; else if (filsys == 1) @@ -343,15 +350,15 @@ send_off(notice, real) int real; { int i, success, retval; - char bfr[BUFSIZ], realm_recip[BUFSIZ], dest[3 * BUFSIZ], *cp; + char bfr[BUFSIZ], rhs_recip[BUFSIZ], dest[3 * BUFSIZ], *cp; ZNotice_t retnotice; success = 0; for (i=0;iz_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 header file. */ +#undef HAVE_X11_XAW_LABEL_H + +/* Define if you have the header file. */ +#undef HAVE_DLFCN_H + /* Define if you have the header file. */ #undef HAVE_FCNTL_H +/* Define if you have the header file. */ +#undef HAVE_IFADDRS_H + /* Define if you have the header file. */ #undef HAVE_MALLOC_H diff --git a/lib/ZAsyncLocate.c b/lib/ZAsyncLocate.c index 86e3ca0..b3976d7 100644 --- a/lib/ZAsyncLocate.c +++ b/lib/ZAsyncLocate.c @@ -16,7 +16,8 @@ static const char rcsid_ZAsyncLocate_c[] = "$Id: ZAsyncLocate.c,v 1.6 1999/01/22 23:19:02 ghudson Exp $"; #endif -Code_t ZRequestLocations(user, zald, kind, auth) +Code_t ZRequestLocations(galaxy, user, zald, kind, auth) + char *galaxy; char *user; register ZAsyncLocateData_t *zald; ZNotice_Kind_t kind; /* UNSAFE, UNACKED, or ACKED */ @@ -39,6 +40,7 @@ Code_t ZRequestLocations(user, zald, kind, auth) notice.z_recipient = ""; notice.z_default_format = ""; notice.z_message_len = 0; + notice.z_dest_galaxy = galaxy; if ((retval = ZSendNotice(¬ice, auth)) != ZERR_NONE) return(retval); diff --git a/lib/ZCkAuth.c b/lib/ZCkAuth.c index 90633ea..c903d8e 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 2372bb6..a67d6fc 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 19ab30b..342d06a 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 c1440c4..bf11b2f 100644 --- a/lib/ZFmtRawLst.c +++ b/lib/ZFmtRawLst.c @@ -3,7 +3,7 @@ * * Created by: Robert French * - * $Id: ZFmtRawLst.c,v 1.12 1999/01/22 23:19:09 ghudson Exp $ +n * $Id: ZFmtRawLst.c,v 1.12 1999/01/22 23:19:09 ghudson Exp $ * * Copyright (c) 1987 by the Massachusetts Institute of Technology. * For copying and distribution information, see the file @@ -28,8 +28,8 @@ Code_t ZFormatRawNoticeList(notice, list, nitems, buffer, ret_len) char *ptr; Code_t retval; - if ((retval = Z_FormatRawHeader(notice, header, sizeof(header), - &hdrlen, NULL, NULL)) != ZERR_NONE) + if ((retval = Z_FormatRawHeader(notice, header, sizeof(header), &hdrlen, + NULL, NULL, NULL, NULL)) != ZERR_NONE) return (retval); size = 0; diff --git a/lib/ZFmtSmRLst.c b/lib/ZFmtSmRLst.c index 391dfe1..4de08db 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 473c0b5..9d6d062 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 ef5e936..168cfa2 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 5479de9..4470402 100644 --- a/lib/ZInit.c +++ b/lib/ZInit.c @@ -18,6 +18,18 @@ static char rcsid_ZInitialize_c[] = #include #include +#include +#include +#include +#ifdef HAVE_SYS_SOCKIO_H +#include +#endif +#ifdef HAVE_IFADDRS_H +#include +#endif +#ifdef HAVE_NET_IF_H +#include +#endif #ifdef HAVE_KRB4 #include #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; + mph_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(¬ice); - } + 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; + mph_addrtype == AF_INET) - memcpy(&__My_addr, hostent->h_addr, sizeof(__My_addr)); - } + ZFreeNotice(¬ice); + + __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 4056e30..cf0db72 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 e14cfc2..3e09763 100644 --- a/lib/ZMkAuth.c +++ b/lib/ZMkAuth.c @@ -16,47 +16,76 @@ static const char rcsid_ZMakeAuthentication_c[] = "$Id: ZMkAuth.c,v 1.19 1999/01/22 23:19:16 ghudson Exp $"; #endif -#ifdef HAVE_KRB4 -#include -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 2d2e62b..404e22d 100644 --- a/lib/ZNewLocU.c +++ b/lib/ZNewLocU.c @@ -17,7 +17,8 @@ static const char rcsid_ZNewLocateUser_c[] = "$Id: ZNewLocU.c,v 1.10 1999/01/22 23:19:17 ghudson Exp $"; #endif -Code_t ZLocateUser(user, nlocs, auth) +Code_t ZLocateUser(galaxy, user, nlocs, auth) + char *galaxy; char *user; int *nlocs; Z_AuthProc auth; @@ -29,7 +30,8 @@ Code_t ZLocateUser(user, nlocs, auth) (void) ZFlushLocations(); /* ZFlushLocations never fails (the library is allowed to know this). */ - if ((retval = ZRequestLocations(user, &zald, UNACKED, auth)) != ZERR_NONE) + if ((retval = ZRequestLocations(galaxy, user, &zald, UNACKED, + auth)) != ZERR_NONE) return(retval); retval = Z_WaitForNotice (¬ice, ZCompareALDPred, &zald, SRV_TIMEOUT); diff --git a/lib/ZOpenPort.c b/lib/ZOpenPort.c index e5e6634..b1ceb5c 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 a0a8080..9067307 100644 --- a/lib/ZParseNot.c +++ b/lib/ZParseNot.c @@ -17,56 +17,8 @@ static char rcsid_ZParseNotice_c[] = #include -/* 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 8462bbc..4d2e6df 100644 --- a/lib/ZReadAscii.c +++ b/lib/ZReadAscii.c @@ -17,21 +17,6 @@ static char rcsid_ZReadAscii_c[] = "$Id: ZReadAscii.c,v 1.18 1999/01/22 23:19:21 #include #include -#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 231594f..c53791d 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 0df54e5..1da1a57 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(¬ice, 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(¬ice, nsubs, ZNOAUTH)); diff --git a/lib/ZSetDest.c b/lib/ZSetDest.c index 12de89e..6afd1a8 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 a150cd2..b11498e 100644 --- a/lib/ZSubs.c +++ b/lib/ZSubs.c @@ -17,41 +17,48 @@ static const char rcsid_ZSubscriptions_c[] = "$Id: ZSubs.c,v 1.21 1999/01/22 23:19:30 ghudson Exp $"; #endif -static Code_t Z_Subscriptions __P((register ZSubscription_t *sublist, +static Code_t Z_Subscriptions __P((char *galaxy, + register ZSubscription_t *sublist, int nitems, unsigned int port, char *opcode, int authit)); static Code_t subscr_sendoff __P((ZNotice_t *notice, char **lyst, int num, int authit)); -Code_t ZSubscribeTo(sublist, nitems, port) +Code_t ZSubscribeTo(galaxy, sublist, nitems, port) + char *galaxy; ZSubscription_t *sublist; int nitems; unsigned int port; { - return (Z_Subscriptions(sublist, nitems, port, CLIENT_SUBSCRIBE, 1)); + return (Z_Subscriptions(galaxy, sublist, nitems, port, + CLIENT_SUBSCRIBE, 1)); } -Code_t ZSubscribeToSansDefaults(sublist, nitems, port) +Code_t ZSubscribeToSansDefaults(galaxy, sublist, nitems, port) + char *galaxy; ZSubscription_t *sublist; int nitems; unsigned int port; { - return (Z_Subscriptions(sublist, nitems, port, CLIENT_SUBSCRIBE_NODEFS, - 1)); + return (Z_Subscriptions(galaxy, sublist, nitems, port, + CLIENT_SUBSCRIBE_NODEFS, 1)); } -Code_t ZUnsubscribeTo(sublist, nitems, port) +Code_t ZUnsubscribeTo(galaxy, sublist, nitems, port) + char *galaxy; ZSubscription_t *sublist; int nitems; unsigned int port; { - return (Z_Subscriptions(sublist, nitems, port, CLIENT_UNSUBSCRIBE, 1)); + return (Z_Subscriptions(galaxy, sublist, nitems, port, + CLIENT_UNSUBSCRIBE, 1)); } -Code_t ZCancelSubscriptions(port) +Code_t ZCancelSubscriptions(galaxy, port) + char *galaxy; unsigned int port; { - return (Z_Subscriptions((ZSubscription_t *)0, 0, port, + return (Z_Subscriptions(galaxy, (ZSubscription_t *)0, 0, port, CLIENT_CANCELSUB, 0)); } @@ -62,7 +69,8 @@ Code_t ZCancelSubscriptions(port) */ static Code_t -Z_Subscriptions(sublist, nitems, port, opcode, authit) +Z_Subscriptions(galaxy, sublist, nitems, port, opcode, authit) + char *galaxy; register ZSubscription_t *sublist; int nitems; unsigned int port; @@ -97,6 +105,7 @@ Z_Subscriptions(sublist, nitems, port, opcode, authit) notice.z_recipient = ""; notice.z_default_format = ""; notice.z_message_len = 0; + notice.z_dest_galaxy = galaxy; /* format the header to figure out how long it is */ retval = Z_FormatHeader(¬ice, header, sizeof(header), &hdrlen, ZAUTH); diff --git a/lib/zephyr_err.et b/lib/zephyr_err.et index 2e40a57..8acedb7 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/mkinstalldirs b/mkinstalldirs index 06cd397..1ac72bf 100755 --- a/mkinstalldirs +++ b/mkinstalldirs @@ -4,7 +4,7 @@ # Created: 1993-05-16 # Public domain -# $Id: mkinstalldirs,v 1.1 1999/11/01 19:33:54 danw Exp $ +# $Id: mkinstalldirs,v 1.1 2001/03/26 01:51:07 raeburn Exp $ errstatus=0 diff --git a/server/bdump.c b/server/bdump.c index da5015a..3077236 100644 --- a/server/bdump.c +++ b/server/bdump.c @@ -3,7 +3,7 @@ * * Created by: John T. Kohl * - * $Source: /afs/dev.mit.edu/source/repository/athena/lib/zephyr/server/bdump.c,v $ + * $Source: /var/raeburn/z/repos/athena/lib/zephyr/server/bdump.c,v $ * $Id: bdump.c,v 1.54 2001/02/27 04:43:01 zacheiss Exp $ * $Author: zacheiss $ * @@ -289,7 +289,7 @@ bdump_send() } if (strcmp(kdata.pname, SERVER_SERVICE) || strcmp(kdata.pinst, SERVER_INSTANCE) || - strcmp(kdata.prealm, ZGetRealm())) { + strcmp(kdata.prealm, my_krealm)) { syslog(LOG_ERR, "bdump_send: peer not zephyr: %s.%s@%s", kdata.pname, kdata.pinst, kdata.prealm); cleanup(server); @@ -478,7 +478,7 @@ bdump_get_v12 (notice, auth, who, server) if (strcmp(kdata.pname, SERVER_SERVICE) || strcmp(kdata.pinst, SERVER_INSTANCE) || - strcmp(kdata.prealm, ZGetRealm())) { + strcmp(kdata.prealm, my_krealm)) { syslog(LOG_ERR, "bdump_get: peer not zephyr in lrealm: %s.%s@%s", kdata.pname, kdata.pinst,kdata.prealm); cleanup(server); @@ -691,9 +691,6 @@ get_tgt() static char buf[INST_SZ + 1] = SERVER_INSTANCE; int retval = 0; CREDENTIALS cred; -#ifndef NOENCRYPTION - Sched *s; -#endif /* have they expired ? */ if (ticket_time < NOW - tkt_lifetime(TKTLIFETIME) + (15L * 60L)) { @@ -704,8 +701,8 @@ get_tgt() #endif dest_tkt(); - retval = krb_get_svc_in_tkt(SERVER_SERVICE, buf, ZGetRealm(), - "krbtgt", ZGetRealm(), + retval = krb_get_svc_in_tkt(SERVER_SERVICE, buf, my_krealm, + "krbtgt", my_krealm, TKTLIFETIME, srvtab_file); if (retval != KSUCCESS) { syslog(LOG_ERR,"get_tgt: krb_get_svc_in_tkt: %s", @@ -718,20 +715,27 @@ get_tgt() #ifndef NOENCRYPTION retval = read_service_key(SERVER_SERVICE, SERVER_INSTANCE, - ZGetRealm(), 0 /*kvno*/, + my_krealm, 0 /*kvno*/, srvtab_file, serv_key); if (retval != KSUCCESS) { syslog(LOG_ERR, "get_tgt: read_service_key: %s", krb_get_err_text(retval)); return 1; } - s = (Sched *) check_key_sched_cache(serv_key); - if (s) { - serv_ksched = *s; - } else { - des_key_sched(serv_key, serv_ksched.s); - add_to_key_sched_cache(serv_key, &serv_ksched); +#ifdef BAD_KRB4_HACK + { + Sched *s; + s = (Sched *) check_key_sched_cache(serv_key); + if (s) { + serv_ksched = *s; + } else { + des_key_sched(serv_key, serv_ksched.s); + add_to_key_sched_cache(serv_key, &serv_ksched); + } } +#else + des_key_sched(serv_key, serv_ksched.s); +#endif #endif /* !NOENCRYPTION */ } return(0); diff --git a/server/class.c b/server/class.c index c842864..da3bfbd 100644 --- a/server/class.c +++ b/server/class.c @@ -3,7 +3,7 @@ * * Created by: John T. Kohl * - * $Source: /afs/dev.mit.edu/source/repository/athena/lib/zephyr/server/class.c,v $ + * $Source: /var/raeburn/z/repos/athena/lib/zephyr/server/class.c,v $ * $Author: zacheiss $ * * Copyright (c) 1987 by the Massachusetts Institute of Technology. diff --git a/server/dispatch.c b/server/dispatch.c index 276f7ea..e2c6c84 100644 --- a/server/dispatch.c +++ b/server/dispatch.c @@ -3,7 +3,7 @@ * * Created by: John T. Kohl * - * $Source: /afs/dev.mit.edu/source/repository/athena/lib/zephyr/server/dispatch.c,v $ + * $Source: /var/raeburn/z/repos/athena/lib/zephyr/server/dispatch.c,v $ * $Author: ghudson $ * * Copyright (c) 1987, 1991 by the Massachusetts Institute of Technology. @@ -18,7 +18,7 @@ #ifndef lint #ifndef SABER static const char rcsid_dispatch_c[] = -"$Id: dispatch.c,v 1.63 2001/04/10 23:28:19 ghudson Exp $"; +"$Id: dispatch.c,v 1.62 2001/03/05 22:22:03 ghudson Exp $"; #endif #endif @@ -52,11 +52,12 @@ ZCONST char *ZNoticeKinds[9] = {"UNSAFE", "UNACKED", "ACKED", "HMACK", * void nack_release(client) * Client *client; * - * void sendit(notice, auth, who, external) + * void sendit(notice, auth, who, external, local_dest) * ZNotice_t *notice; * int auth; * struct sockaddr_in *who; * int external; + * int local_dest; * * void xmit(notice, dest, auth, client) * ZNotice_t *notice; @@ -251,13 +252,24 @@ dispatch(notice, auth, who, from_server) String *notice_class; struct sockaddr_in who2; int authflag; - Realm *realm; - char *cp; #ifdef DEBUG char dbg_buf[BUFSIZ]; #endif - authflag = (auth == ZAUTH_YES); + /* Set "authflag" to 1 or 0 for handler functions. Treat + * ZAUTH_CKSUM_FAILED as authentic except for sendit(), which is + * handled below. */ + switch (auth) { + case ZAUTH_YES: + case ZAUTH_CKSUM_FAILED: + authflag = 1; + break; + case ZAUTH_FAILED: + case ZAUTH_NO: + default: + authflag = 0; + break; + } if ((int) notice->z_kind < (int) UNSAFE || (int) notice->z_kind > (int) CLIENTACK) { @@ -311,21 +323,122 @@ dispatch(notice, auth, who, from_server) admin_notices.val++; status = server_adispatch(notice, authflag, who, me_server); } else { - if (!realm_bound_for_realm(ZGetRealm(), notice->z_recipient)) { - cp = strchr(notice->z_recipient, '@'); - if (!cp || - !(realm = realm_get_realm_by_name(cp + 1))) { - /* Foreign user, local realm */ - sendit(notice, authflag, who, 0); - } else + char *finalat, *inlhsat; + Realm *realm; + + if (auth == ZAUTH_CKSUM_FAILED) + authflag = 0; + + /* + +shadow@ANDREW.CMU.EDU: + +according to my whiteboard [external==0 indicates]: + +a message from a remote server to a local user + +a message from a remote server for remote broadcast (which i +don't think happens) + +a message from a remote server for remote user (also doesn't happen) + +and a message from a remote server for a local foreign user (a message +from ANDREW.CMU.EDU to ATHENA.MIT.EDU for jesse@FSCK.COM) + +it also claims a local client to local user message "could be external +== 0 but is not" + + */ + /* The idea is that an individual recipient is either a + kerberos-form name or a galaxy-augmented kerberos-form + name. + + possible cases: + + 1. The recipient is name-with-ats@rhs. The message has a + remote individual destination name-with-ats in the rhs + galaxy. [galaxy-augmented kerberos-form name] + + 2. The recipient is lhs@rhs. [kerberos-form name] + + 2a. lhs@rhs has a subscription in the local galaxy. The + message has a local individual destination + lhs@rhs. [kerberos-form name for local galaxy] + + 2b. rhs is a trusted galaxy whose kerberos realm, if any, + is also (case insensitively) rhs. The message has a remote + individual destination lhs@rhs in the rhs galaxy. A + trusted galaxy is one for which is is believed that a user + who may subscribe locally as lhs@rhs (case 2a) is the same + user as lhs@rhs in the rhs galaxy. Such determination is + currently made by static configuration of trusted galaxies. + [kerberos-form name for remote galaxy] + + 3. The recipient is @rhs, and rhs is a trusted remote + galaxy. The message has a remote broadcast destination in + the rhs galaxy. [broadcast recipient in remote galaxy] + + 4. The recipient has no @s. The message has a local + individual destination. [unqualified kerberos-form name] + + 5. The recipient is empty. The message has a local + broadcast destination. [broadcast recipient in local + galaxy] + + 6. The recipient has some other form. The message is + invalid. + + */ + + finalat = strrchr(notice->z_recipient, '@'); + + if (finalat && finalat > notice->z_recipient) { + /* XXX eeew. */ + *finalat = '\0'; + inlhsat = strrchr(notice->z_recipient, '@'); + *finalat = '@'; + + if (inlhsat == finalat-1) { + /* @foo@bar is not legal */ + nack(notice, who); + } else if (inlhsat) { + /* foo@bar@galaxy */ + Realm *realm = realm_get_realm_by_name(finalat+1); + if (!realm) { + /* case 1, unknown galaxy */ + nack(notice, who); + } else if (strcmp(realm->name, my_galaxy) == 0) { + /* case 1, explict local galaxy */ + *finalat = '\0'; + sendit(notice, authflag, who, 0, 1); + } else { + /* case 1 */ + *finalat = '\0'; + realm_handoff(notice, authflag, who, realm, 1); + } + } else { + /* foo@bar */ + /* 2a is handled by sendit directly; 2b is handled at + the end of sendit if there were no subscriptions */ + sendit(notice, authflag, who, 1, 1); + } + } else if (finalat) { + /* case 3: @foo */ + Realm *realm = realm_get_realm_by_name(finalat+1); + if (!realm) { + nack(notice, who); + } else if (strcmp(realm->name, my_galaxy) == 0) { + sendit(notice, authflag, who, 1, 1); + } else { realm_handoff(notice, authflag, who, realm, 1); + } + } else if (notice->z_recipient[0] != '\0') { + /* case 4: foo */ + sendit(notice, authflag, who, 0, 1); } else { - if (notice->z_recipient[0] == '@') - notice->z_recipient = ""; - sendit(notice, authflag, who, 1); + /* case 5: null recipient */ + sendit(notice, authflag, who, 1, 1); } - free_string(notice_class); - return; } if (status == ZSRV_REQUEUE) @@ -337,12 +450,15 @@ dispatch(notice, auth, who, from_server) * Send a notice off to those clients who have subscribed to it. */ +/* this never gets called with external==1; local_dest==0 */ + void -sendit(notice, auth, who, external) +sendit(notice, auth, who, external, local_dest) ZNotice_t *notice; int auth; struct sockaddr_in *who; int external; + int local_dest; { static int send_counter = 0; char recipbuf[ANAME_SZ + INST_SZ + REALM_SZ + 3], *recipp; @@ -352,7 +468,8 @@ sendit(notice, auth, who, external) String *class; class = make_string(notice->z_class, 1); - if (realm_bound_for_realm(ZGetRealm(), notice->z_recipient)) { + /* if (realm_bound_for_my_galaxy(notice->z_recipient)) { */ + if (local_dest) { Realm *rlm; acl = class_get_acl(class); @@ -435,10 +552,10 @@ sendit(notice, auth, who, external) /* Send to clients subscribed to the triplet itself. */ dest.classname = class; dest.inst = make_string(notice->z_class_inst, 1); - if (realm_bound_for_realm(ZGetRealm(), notice->z_recipient) && - *notice->z_recipient == '@') + /* if (realm_bound_for_my_galaxy(notice->z_recipient) && */ + if (local_dest && *notice->z_recipient == '@') { dest.recip = make_string("", 0); - else { + } else { strncpy(recipbuf, notice->z_recipient, sizeof(recipbuf)); recipp = strrchr(recipbuf, '@'); if (recipp) @@ -458,17 +575,29 @@ sendit(notice, auth, who, external) free_string(class); free_string(dest.recip); - if (any) + if (any) { ack(notice, who); - else + } else if (external) { + /* check to see if the recipient is really a name in another + known galaxy */ + Realm *realm; + char *galaxy = strchr(notice->z_recipient, '@'); + + if (galaxy && galaxy > notice->z_recipient && + (realm = realm_get_realm_by_name(galaxy))) + realm_handoff(notice, auth, who, realm, 1); + else + nack(notice, who); + } else { nack(notice, who); + } } /* * Send to each client in the list. Avoid duplicates by setting * last_send on each client to send_counter, a nonce which is updated - * by sendit() above. - */ + * by sendit() above. If the destination is a remote galaxy, send + * there only if external==1 */ static int send_to_dest(notice, auth, dest, send_counter, external) @@ -602,6 +731,7 @@ xmit(notice, dest, auth, client) Unacked *nacked; int packlen, sendfail = 0; Code_t retval; + struct in_addr my_addr; #if 0 zdbug((LOG_DEBUG,"xmit")); @@ -678,7 +808,7 @@ xmit(notice, dest, auth, client) buffer_len = sizeof(ZPacket_t); retval = Z_FormatRawHeader(&partnotice, buffer, buffer_len, - &hdrlen, NULL, NULL); + &hdrlen, NULL, NULL, NULL, NULL); if (retval != ZERR_NONE) { syslog(LOG_ERR, "xmit unauth refrag fmt: failed"); free(buffer); @@ -694,7 +824,9 @@ xmit(notice, dest, auth, client) return; } - fragsize = Z_MAXPKTLEN-hdrlen-Z_FRAGFUDGE; + fragsize = Z_MAXPKTLEN-hdrlen-Z_FRAGFUDGE; + + Z_SourceAddr(&client->addr.sin_addr, &my_addr); while (offset < notice->z_message_len || !notice->z_message_len) { (void) sprintf(multi, "%d/%d", offset+origoffset, origlen); @@ -705,15 +837,15 @@ xmit(notice, dest, auth, client) partnotice.z_uid.tv.tv_sec); partnotice.z_uid.tv.tv_usec = htonl((u_long) partnotice.z_uid.tv.tv_usec); - (void) memcpy((char *)&partnotice.z_uid.zuid_addr, &__My_addr, - sizeof(__My_addr)); + (void) memcpy((char *)&partnotice.z_uid.zuid_addr, &my_addr, + sizeof(my_addr)); } partnotice.z_message = notice->z_message+offset; message_len = min(notice->z_message_len-offset, fragsize); partnotice.z_message_len = message_len; retval = Z_FormatRawHeader(&partnotice, buffer, buffer_len, - &hdrlen, &ptr, NULL); + &hdrlen, NULL, NULL, &ptr, NULL); if (retval != ZERR_NONE) { syslog(LOG_WARNING, "xmit unauth refrag raw: %s", error_message(retval)); @@ -991,11 +1123,6 @@ nack_cancel(notice, who) #endif } -/* for compatibility when sending subscription information to old clients */ -#ifdef OLD_COMPAT -#define OLD_ZEPHYR_VERSION "ZEPH0.0" -#endif /* OLD_COMPAT */ - /* Dispatch an HM_CTL notice. */ Code_t @@ -1122,14 +1249,7 @@ control_dispatch(notice, auth, who, server) someone who has no subscriptions does NOT get a SERVNAK but rather an empty list. Note we must therefore check authentication inside subscr_sendlist */ -#ifdef OLD_COMPAT - /* only acknowledge if *not* old version; the old version - acknowledges the packet with the reply */ - if (strcmp(notice->z_version, OLD_ZEPHYR_VERSION) != 0) - ack(notice, who); -#else /* !OLD_COMPAT */ ack(notice, who); -#endif /* OLD_COMPAT */ subscr_sendlist(notice, auth, who); return ZERR_NONE; } else if (!auth) { @@ -1337,17 +1457,13 @@ static char * hm_recipient() { static char *recipient; - char *realm; if (recipient) return recipient; - realm = ZGetRealm(); - if (!realm) - realm = "???"; - recipient = (char *) malloc(strlen(realm) + 4); + recipient = (char *) malloc(strlen(my_galaxy) + 4); strcpy (recipient, "hm@"); - strcat (recipient, realm); + strcat (recipient, my_galaxy); return recipient; } diff --git a/server/kstuff.c b/server/kstuff.c index 5fd31c9..4a67faa 100644 --- a/server/kstuff.c +++ b/server/kstuff.c @@ -8,20 +8,21 @@ * "mit-copyright.h". */ /* - * $Source: /afs/dev.mit.edu/source/repository/athena/lib/zephyr/server/kstuff.c,v $ - * $Header: /afs/dev.mit.edu/source/repository/athena/lib/zephyr/server/kstuff.c,v 1.26 2001/04/10 23:28:20 ghudson Exp $ + * $Id: kstuff.c,v 1.25 2001/03/05 23:19:02 ghudson Exp $ */ #include "zserver.h" #ifndef lint #ifndef SABER -static const char rcsid_kstuff_c[] = "$Id: kstuff.c,v 1.26 2001/04/10 23:28:20 ghudson Exp $"; +static const char rcsid_kstuff_c[] = "$Id: kstuff.c,v 1.25 2001/03/05 23:19:02 ghudson Exp $"; #endif #endif #ifdef HAVE_KRB4 +C_Block __Zephyr_session; + /* Keep a hash table mapping tickets to session keys, so we can do a fast * check of the cryptographic checksum without doing and DES decryptions. * Also remember the expiry time of the ticket, so that we can sweep the @@ -43,9 +44,11 @@ struct hash_entry { Hash_entry *hashtab[HASHTAB_SIZE]; +#ifdef BAD_KRB4_HACK static int hash_ticket __P((unsigned char *, int)); static void add_session_key __P((KTEXT, C_Block, char *, time_t)); static int find_session_key __P((KTEXT, C_Block, char *)); +#endif static ZChecksum_t compute_checksum __P((ZNotice_t *, C_Block)); static ZChecksum_t compute_rlm_checksum __P((ZNotice_t *, C_Block)); @@ -125,7 +128,7 @@ SendKerberosData(fd, ticket, service, host) int written; int size_to_write; - rem = krb_mk_req(ticket, service, host, ZGetRealm(), (u_long) 0); + rem = krb_mk_req(ticket, service, host, my_galaxy, (u_long) 0); if (rem != KSUCCESS) return rem + krb_err_base; @@ -152,7 +155,10 @@ ZCheckRealmAuthentication(notice, from, realm) int result; char rlmprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4]; char srcprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4]; - KTEXT_ST authent, ticket; + KTEXT_ST authent; +#ifdef BAD_KRB4_HACK + KTEXT_ST ticket; +#endif AUTH_DAT dat; ZChecksum_t checksum; CREDENTIALS cred; @@ -174,13 +180,14 @@ ZCheckRealmAuthentication(notice, from, realm) } authent.length = notice->z_authent_len; + (void) sprintf(rlmprincipal, "%s.%s@%s", SERVER_SERVICE, + SERVER_INSTANCE, realm); + +#ifdef BAD_KRB4_HACK /* Copy the ticket out of the authentication data. */ if (krb_find_ticket(&authent, &ticket) != RD_AP_OK) return ZAUTH_FAILED; - (void) sprintf(rlmprincipal, "%s.%s@%s", SERVER_SERVICE, - SERVER_INSTANCE, realm); - /* Try to do a fast check against the cryptographic checksum. */ if (find_session_key(&ticket, session_key, srcprincipal) >= 0) { if (strcmp(srcprincipal, rlmprincipal) != 0) @@ -189,12 +196,13 @@ ZCheckRealmAuthentication(notice, from, realm) return ZAUTH_FAILED; checksum = compute_rlm_checksum(notice, session_key); - /* If checksum matches, packet is authentic. If not, we might - * have an outdated session key, so keep going the slow way. - */ + /* If checksum matches, packet is authentic. Otherwise, check + * the authenticator as if we didn't have the session key cached + * and return ZAUTH_CKSUM_FAILED. This is a rare case (since the + * ticket isn't cached after a checksum failure), so don't worry + * about the extra des_quad_cksum() call. */ if (checksum == notice->z_checksum) { - (void) memcpy((char *)__Zephyr_session, (char *)session_key, - sizeof(C_Block)); /* For control_dispatch() */ + memcpy(__Zephyr_session, session_key, sizeof(C_Block)); return ZAUTH_YES; } @@ -207,6 +215,7 @@ ZCheckRealmAuthentication(notice, from, realm) return ZAUTH_YES; } } +#endif /* We don't have the session key cached; do it the long way. */ result = krb_rd_req(&authent, SERVER_SERVICE, SERVER_INSTANCE, @@ -231,13 +240,15 @@ ZCheckRealmAuthentication(notice, from, realm) checksum = compute_checksum(notice, dat.session); if (checksum != notice->z_checksum) #endif - return ZAUTH_FAILED; + return ZAUTH_CKSUM_FAILED; } +#ifdef BAD_KRB4_HACK /* Record the session key, expiry time, and source principal in the * hash table, so we can do a fast check next time. */ add_session_key(&ticket, dat.session, srcprincipal, (time_t)(dat.time_sec + dat.life * 5 * 60)); +#endif return ZAUTH_YES; @@ -254,7 +265,10 @@ ZCheckAuthentication(notice, from) #ifdef HAVE_KRB4 int result; char srcprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4]; - KTEXT_ST authent, ticket; + KTEXT_ST authent; +#ifdef BAD_KRB4_HACK + KTEXT_ST ticket; +#endif AUTH_DAT dat; ZChecksum_t checksum; C_Block session_key; @@ -275,6 +289,7 @@ ZCheckAuthentication(notice, from) } authent.length = notice->z_authent_len; +#ifdef BAD_KRB4_HACK /* Copy the ticket out of the authentication data. */ if (krb_find_ticket(&authent, &ticket) != RD_AP_OK) return ZAUTH_FAILED; @@ -287,14 +302,17 @@ ZCheckAuthentication(notice, from) return ZAUTH_FAILED; checksum = compute_checksum(notice, session_key); - /* If checksum matches, packet is authentic. If not, we might - * have an outdated session key, so keep going the slow way. - */ + /* If the checksum matches, the packet is authentic. Otherwise, + * check authenticator as if we didn't have the session key cached + * and return ZAUTH_CKSUM_FAILED. This is a rare case (since the + * ticket isn't cached after a checksum failure), so don't worry + * about the extra des_quad_cksum() call. */ if (checksum == notice->z_checksum) { memcpy(__Zephyr_session, session_key, sizeof(C_Block)); return ZAUTH_YES; } } +#endif /* We don't have the session key cached; do it the long way. */ result = krb_rd_req(&authent, SERVER_SERVICE, SERVER_INSTANCE, @@ -316,12 +334,14 @@ ZCheckAuthentication(notice, from) checksum = compute_checksum(notice, dat.session); #endif if (checksum != notice->z_checksum) - return ZAUTH_FAILED; + return ZAUTH_CKSUM_FAILED; +#ifdef BAD_KRB4_HACK /* Record the session key, expiry time, and source principal in the * hash table, so we can do a fast check next time. */ add_session_key(&ticket, dat.session, srcprincipal, (time_t)(dat.time_sec + dat.life * 5 * 60)); +#endif return ZAUTH_YES; @@ -332,6 +352,8 @@ ZCheckAuthentication(notice, from) #ifdef HAVE_KRB4 +#ifdef BAD_KRB4_HACK + static int hash_ticket(p, len) unsigned char *p; int len; @@ -400,6 +422,8 @@ static int find_session_key(ticket, key, srcprincipal) return -1; } +#endif + static ZChecksum_t compute_checksum(notice, session_key) ZNotice_t *notice; C_Block session_key; diff --git a/server/subscr.c b/server/subscr.c index 00e6ab0..a8ccdd1 100644 --- a/server/subscr.c +++ b/server/subscr.c @@ -3,7 +3,7 @@ * * Created by: John T. Kohl * - * $Source: /afs/dev.mit.edu/source/repository/athena/lib/zephyr/server/subscr.c,v $ + * $Source: /var/raeburn/z/repos/athena/lib/zephyr/server/subscr.c,v $ * $Author: zacheiss $ * * Copyright (c) 1987,1988 by the Massachusetts Institute of Technology. @@ -16,7 +16,7 @@ #ifndef lint #ifndef SABER -static const char rcsid_subscr_c[] = "$Id: subscr.c,v 1.58 2001/03/01 00:47:05 zacheiss Exp $"; +static const char rcsid_subscr_c[] = "$Id: subscr.c,v 1.59 2001/07/03 03:28:31 zacheiss Exp $"; #endif #endif @@ -70,29 +70,14 @@ Sched serv_ksched; /* for compatibility when sending subscription information to old clients */ -#ifdef OLD_COMPAT -#define OLD_ZEPHYR_VERSION "ZEPH0.0" -#define OLD_CLIENT_INCOMPSUBS "INCOMP" -static void old_compat_subscr_sendlist __P((ZNotice_t *notice, int auth, - struct sockaddr_in *who)); -extern int old_compat_count_subscr; /* counter of old use */ -#endif /* OLD_COMPAT */ -#ifdef NEW_COMPAT -#define NEW_OLD_ZEPHYR_VERSION "ZEPH0.1" -static void new_old_compat_subscr_sendlist __P((ZNotice_t *notice, int auth, - struct sockaddr_in *who)); -extern int new_compat_count_subscr; /* counter of old use */ -#endif /* NEW_COMPAT */ - extern char *re_comp(), *re_conv(); static Code_t add_subscriptions __P((Client *who, Destlist *subs_queue, ZNotice_t *notice, Server *server)); static Destlist *extract_subscriptions __P((ZNotice_t *notice)); static void free_subscriptions __P((Destlist *subs)); static void free_subscription __P((Destlist *sub)); -static char **subscr_marshal_subs __P((ZNotice_t *notice, int auth, - struct sockaddr_in *who, - int *found)); +static char **subscr_marshal_subs __P((Destlist *subs, + int *found)); static Destlist *subscr_copy_def_subs __P((char *person)); static Code_t subscr_realm_sendit __P((Client *who, Destlist *subs, ZNotice_t *notice, Realm *realm)); @@ -157,7 +142,7 @@ add_subscriptions(who, subs, notice, server) /* check the recipient for a realm which isn't ours */ realm = NULL; if (subs->dest.recip->string[0] == '@' && - strcmp((subs->dest.recip->string + 1), ZGetRealm()) != 0) + strcmp((subs->dest.recip->string + 1), my_galaxy) != 0) realm = realm_get_realm_by_name(subs->dest.recip->string + 1); if (!bdumping) { if (subs->dest.recip != empty && subs->dest.recip != sender @@ -186,14 +171,19 @@ add_subscriptions(who, subs, notice, server) } } } - if (realm && !bdumping && server && server == me_server) { - retval = subscr_realm_sendit(who, subs, notice, realm); - if (retval != ZERR_NONE) { - free_subscriptions(subs); - free_string(sender); - return(retval); + if (realm && !bdumping) { + if (server && server == me_server) { + retval = subscr_realm_sendit(who, subs, notice, realm); + if (retval != ZERR_NONE) { + free_subscriptions(subs); + free_string(sender); + return(retval); + } else { + /* free this one, will get from ADD */ + free_subscription(subs); + } } else { - free_subscription(subs); /* free this one, will get from ADD */ + /* Indicates we leaked traffic back to our realm */ } } else { retval = triplet_register(who, &subs->dest, NULL); @@ -485,28 +475,15 @@ subscr_sendlist(notice, auth, who) int auth; struct sockaddr_in *who; { - char **answer; + unsigned short temp; + int defsubs = 0; + Destlist *subs = NULL; + Client *client; + char **answer = NULL; int found; struct sockaddr_in send_to_who; Code_t retval; -#ifdef OLD_COMPAT - if (strcmp(notice->z_version, OLD_ZEPHYR_VERSION) == 0) { - /* we are talking to an old client; use the old-style - acknowledgement-message */ - old_compat_subscr_sendlist(notice, auth, who); - return; - } -#endif /* OLD_COMPAT */ -#ifdef NEW_COMPAT - if (strcmp(notice->z_version, NEW_OLD_ZEPHYR_VERSION) == 0) { - /* we are talking to a new old client; use the new-old-style - acknowledgement-message */ - new_old_compat_subscr_sendlist(notice, auth, who); - return; - } -#endif /* NEW_COMPAT */ - answer = subscr_marshal_subs(notice, auth, who, &found); send_to_who = *who; send_to_who.sin_port = notice->z_port; /* Return port */ @@ -514,55 +491,13 @@ subscr_sendlist(notice, auth, who) if (retval != ZERR_NONE) { syslog(LOG_WARNING, "subscr_sendlist set addr: %s", error_message(retval)); - if (answer) - free(answer); return; } - /* XXX for now, don't do authentication */ - auth = 0; - - notice->z_kind = ACKED; - - /* use xmit_frag() to send each piece of the notice */ - - retval = ZSrvSendRawList(notice, answer, found * NUM_FIELDS, xmit_frag); - if (retval != ZERR_NONE) - syslog(LOG_WARNING, "subscr_sendlist xmit: %s", error_message(retval)); - if (answer) - free(answer); -} - -static char ** -subscr_marshal_subs(notice, auth, who, found) - ZNotice_t *notice; - int auth; - struct sockaddr_in *who; - int *found; -{ - char **answer = NULL; - unsigned short temp; - Code_t retval; - Client *client; - Destlist *subs = NULL, *sub; - int i; - int defsubs = 0; - -#if 0 - zdbug((LOG_DEBUG, "subscr_marshal")); -#endif - *found = 0; - - /* Note that the following code is an incredible crock! */ - - /* We cannot send multiple packets as acknowledgements to the client, - since the hostmanager will ignore the later packets. So we need - to send directly to the client. */ - - /* Make our own copy so we can send directly back to the client */ - /* RSF 11/07/87 */ - if (strcmp(notice->z_opcode, CLIENT_GIMMESUBS) == 0) { + if (!auth) + goto got_answer; + /* If the client has requested his current subscriptions, the message field of the notice contains the port number of the client for which the sender desires the subscription @@ -572,11 +507,25 @@ subscr_marshal_subs(notice, auth, who, found) if (retval != ZERR_NONE) { syslog(LOG_WARNING, "subscr_marshal read port num: %s", error_message(retval)); - return(NULL); + goto got_answer; } client = client_find(&who->sin_addr, htons(temp)); + if (!client) + goto got_answer; + + /* check authenticity here. The user must be authentic to get + a list of subscriptions. */ + + if (strcmp(client->principal->string, notice->z_sender) != 0) { + zdbug ((LOG_DEBUG, + "subscr_marshal: %s requests subs for %s at %s/%d", + notice->z_sender, client->principal->string, + inet_ntoa(who->sin_addr), ntohs(who->sin_port))); + goto got_answer; + } + if (client) subs = client->subs; } else if (strcmp(notice->z_opcode, CLIENT_GIMMEDEFS) == 0) { @@ -591,237 +540,74 @@ subscr_marshal_subs(notice, auth, who, found) } else { syslog(LOG_ERR, "subscr_marshal bogus opcode %s", notice->z_opcode); - return(NULL); + goto got_answer; } - if (subs) { + answer = subscr_marshal_subs(subs, &found); - /* check authenticity here. The user must be authentic to get - a list of subscriptions. If he is not subscribed to - anything, this if-clause fails, and he gets a response - indicating no subscriptions. - if retrieving default subscriptions, don't care about - authentication. */ - - if (!auth && !defsubs) - return(NULL); - if (!defsubs) { - if (client && (strcmp(client->principal->string, - notice->z_sender) != 0)) { - zdbug ((LOG_DEBUG, - "subscr_marshal: %s requests subs for %s at %s/%d", - notice->z_sender, client->principal->string, - inet_ntoa(who->sin_addr), ntohs(who->sin_port))); - return 0; - } - } - - for (sub = subs; sub; sub = sub->next) - (*found)++; + got_answer: + notice->z_kind = ACKED; - /* found is now the number of subscriptions */ + /* use xmit_frag() to send each piece of the notice */ - /* coalesce the subscription information into a list of char *'s */ - answer = (char **) malloc((*found) * NUM_FIELDS * sizeof(char *)); - if (answer == NULL) { - syslog(LOG_ERR, "subscr no mem(answer)"); - *found = 0; - } else { - i = 0; - for (sub = subs; sub; sub = sub->next) { - answer[i * NUM_FIELDS] = sub->dest.classname->string; - answer[i * NUM_FIELDS + 1] = sub->dest.inst->string; - answer[i * NUM_FIELDS + 2] = sub->dest.recip->string; - i++; - } - } - } + retval = ZSrvSendRawList(notice, answer, found * NUM_FIELDS, xmit_frag); + if (retval != ZERR_NONE) + syslog(LOG_WARNING, "subscr_sendlist xmit: %s", error_message(retval)); if (defsubs) free_subscriptions(subs); - return answer; + if (answer) + free(answer); } -#ifdef NEW_COMPAT -static void -new_old_compat_subscr_sendlist(notice, auth, who) - ZNotice_t *notice; - int auth; - struct sockaddr_in *who; +static char ** +subscr_marshal_subs(subs, found) + Destlist *subs; + int *found; { + char **answer = NULL; Code_t retval; - ZNotice_t reply; - ZPacket_t reppacket; - int packlen, found, count, initfound, zerofound; - char buf[64]; - const char **answer; - struct sockaddr_in send_to_who; + Destlist *sub; int i; - new_compat_count_subscr++; - - syslog(LOG_INFO, "new old subscr, %s", inet_ntoa(who->sin_addr)); - reply = *notice; - reply.z_kind = SERVACK; - reply.z_authent_len = 0; /* save some space */ - reply.z_auth = 0; - - send_to_who = *who; - send_to_who.sin_port = notice->z_port; /* Return port */ - - retval = ZSetDestAddr(&send_to_who); - if (retval != ZERR_NONE) { - syslog(LOG_WARNING, "new_old_subscr_sendlist set addr: %s", - error_message(retval)); - return; - } - - /* retrieve the subscriptions */ - answer = subscr_marshal_subs(notice, auth, who, &found); - - /* note that when there are no subscriptions, found == 0, so - we needn't worry about answer being NULL since - ZFormatSmallRawNoticeList won't reference the pointer */ - - /* send 5 at a time until we are finished */ - count = found?((found-1) / 5 + 1):1; /* total # to be sent */ - i = 0; /* pkt # counter */ -#if 0 - zdbug((LOG_DEBUG,"Found %d subscriptions for %d packets", found, count)); -#endif - initfound = found; - zerofound = (found == 0); - while (found > 0 || zerofound) { - packlen = sizeof(reppacket); - sprintf(buf, "%d/%d", ++i, count); - reply.z_opcode = buf; - retval = ZFormatSmallRawNoticeList(&reply, - answer + (initfound - found) - * NUM_FIELDS, - ((found > 5) ? 5 : found) - * NUM_FIELDS, - reppacket, &packlen); - if (retval != ZERR_NONE) { - syslog(LOG_ERR, "subscr_sendlist format: %s", - error_message(retval)); - if (answer) - free(answer); - return; - } - retval = ZSendPacket(reppacket, packlen, 0); - if (retval != ZERR_NONE) { - syslog(LOG_WARNING, "subscr_sendlist xmit: %s", - error_message(retval)); - if (answer) - free(answer); - return; - } - found -= 5; - zerofound = 0; - } #if 0 - zdbug((LOG_DEBUG,"subscr_sendlist acked")); + zdbug((LOG_DEBUG, "subscr_marshal")); #endif - if (answer) - free(answer); -} -#endif /* NEW_COMPAT */ - -#ifdef OLD_COMPAT -static void -old_compat_subscr_sendlist(notice, auth, who) - ZNotice_t *notice; - int auth; - struct sockaddr_in *who; -{ - Client *client = client_find(&who->sin_addr, notice->z_port); - Destlist *subs; - Code_t retval; - ZNotice_t reply; - ZPacket_t reppacket; - int packlen, i, found = 0; - char **answer = NULL; + *found = 0; - old_compat_count_subscr++; + /* Note that the following code is an incredible crock! */ + + /* We cannot send multiple packets as acknowledgements to the client, + since the hostmanager will ignore the later packets. So we need + to send directly to the client. */ - syslog(LOG_INFO, "old old subscr, %s", inet_ntoa(who->sin_addr)); - if (client && client->subs) { + /* Make our own copy so we can send directly back to the client */ + /* RSF 11/07/87 */ - /* check authenticity here. The user must be authentic to get - a list of subscriptions. If he is not subscribed to - anything, the above test fails, and he gets a response - indicating no subscriptions */ + if (!subs) + return(NULL); - if (!auth) { - clt_ack(notice, who, AUTH_FAILED); - return; - } + for (sub = subs; sub; sub = sub->next) + (*found)++; - for (subs = client->subs; subs; subs = subs->next) - found++; - /* found is now the number of subscriptions */ + /* found is now the number of subscriptions */ - /* coalesce the subscription information into a list of char *'s */ - answer = (char **) malloc(found * NUM_FIELDS * sizeof(char *)); - if (!answer) { - syslog(LOG_ERR, "old_subscr_sendlist no mem(answer)"); - found = 0; - } else { - i = 0; - for (subs = client->subs; subs; subs = subs->next) { - answer[i*NUM_FIELDS] = subs->dest.classname->string; - answer[i*NUM_FIELDS + 1] = subs->dest.inst->string; - answer[i*NUM_FIELDS + 2] = subs->dest.recip->string; - i++; - } + /* coalesce the subscription information into a list of char *'s */ + answer = (char **) malloc((*found) * NUM_FIELDS * sizeof(char *)); + if (answer == NULL) { + syslog(LOG_ERR, "subscr no mem(answer)"); + *found = 0; + } else { + i = 0; + for (sub = subs; sub; sub = sub->next) { + answer[i * NUM_FIELDS] = sub->dest.classname->string; + answer[i * NUM_FIELDS + 1] = sub->dest.inst->string; + answer[i * NUM_FIELDS + 2] = sub->dest.recip->string; + i++; } } - /* note that when there are no subscriptions, found == 0, so - we needn't worry about answer being NULL */ - - reply = *notice; - reply.z_kind = SERVACK; - reply.z_authent_len = 0; /* save some space */ - reply.z_auth = 0; - - /* if it's too long, chop off one at a time till it fits */ - while ((retval = ZFormatSmallRawNoticeList(&reply, answer, - found * NUM_FIELDS, - reppacket, - &packlen)) != ZERR_PKTLEN) { - found--; - reply.z_opcode = OLD_CLIENT_INCOMPSUBS; - } - if (retval != ZERR_NONE) { - syslog(LOG_ERR, "old_subscr_sendlist format: %s", - error_message(retval)); - if (answer) - free(answer); - return; - } - retval = ZSetDestAddr(who); - if (retval != ZERR_NONE) { - syslog(LOG_WARNING, "subscr_sendlist set addr: %s", - error_message(retval)); - if (answer) - free(answer); - return; - } - retval = ZSendPacket(reppacket, packlen, 0); - if (retval != ZERR_NONE) { - syslog(LOG_WARNING, "subscr_sendlist xmit: %s", - error_message(retval)); - if (answer) - free(answer); - return; - } -#if 0 - zdbug((LOG_DEBUG,"subscr_sendlist acked")); -#endif - if (answer) - free(answer); + return answer; } -#endif /* OLD_COMPAT */ /* * Send the client's subscriptions to another server @@ -992,7 +778,7 @@ extract_subscriptions(notice) sub->dest.classname = make_string(class_name, 1); sub->dest.inst = make_string(classinst, 1); /* Nuke @REALM if REALM is us. */ - if (recip[0] == '@' && !strcmp(recip + 1, ZGetRealm())) + if (recip[0] == '@' && !strcmp(recip + 1, my_galaxy)) sub->dest.recip = make_string("", 0); else sub->dest.recip = make_string(recip, 0); @@ -1238,6 +1024,7 @@ subscr_unsub_sendit(who, subs, realm) list[1] = subs->dest.inst->string; list[2] = ""; + (void) memset((char *)&unotice, 0, sizeof(unotice)); unotice.z_class = ZEPHYR_CTL_CLASS; unotice.z_class_inst = ZEPHYR_CTL_REALM; unotice.z_opcode = REALM_UNSUBSCRIBE; @@ -1381,6 +1168,7 @@ subscr_realm_subs(realm) text[4] = subs->dest.recip->string; /* format snotice */ + (void) memset((char *)&snotice, 0, sizeof(snotice)); snotice.z_class_inst = ZEPHYR_CTL_REALM; snotice.z_opcode = REALM_REQ_SUBSCRIBE; snotice.z_port = 0; @@ -1429,7 +1217,7 @@ subscr_check_foreign_subs(notice, who, server, realm, newsubs) Realm *realm; Destlist *newsubs; { - Destlist *subs, *subs2, *next; + Destlist *subs, *subs2; Acl *acl; char **text; int found = 0; @@ -1438,6 +1226,7 @@ subscr_check_foreign_subs(notice, who, server, realm, newsubs) int packlen; Code_t retval; String *sender; + Realm *rlm; for (subs = newsubs; subs; subs = subs->next) found++; @@ -1464,18 +1253,27 @@ subscr_check_foreign_subs(notice, who, server, realm, newsubs) I_ADVANCE(3); found = 0; - for (subs = newsubs; subs; subs = next) { - next=subs->next; + + rlm = realm_which_realm(who); + + for (subs = newsubs; subs; subs = subs->next) { + if (subs->dest.recip->string[0] != '\0') { + syslog(LOG_WARNING, "subscr bad recip %s by %s (%s)", + subs->dest.recip->string, + sender->string, rlm->name); + continue; + } acl = class_get_acl(subs->dest.classname); if (acl) { - Realm *rlm; - rlm = realm_which_realm(who); if (rlm && server == me_server) { if (!realm_sender_in_realm(rlm->name, sender->string)) { syslog(LOG_WARNING, "subscr auth not verifiable %s (%s) class %s", sender->string, rlm->name, subs->dest.classname->string); - continue; + free_subscriptions(newsubs); + free_string(sender); + free(text); + return ZSRV_CLASSRESTRICTED; } } if (!access_check(sender->string, acl, SUBSCRIBE)) { diff --git a/server/uloc.c b/server/uloc.c index 4b587cf..6adffe6 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 8129347..36e43ac 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: 3.24 $"; -#else -const char version[] = "Zephyr server $Revision: 3.24 $"; + "(DEBUG) " #endif + "$Revision: 3.24 $" + ": " ZSERVER_VERSION_STRING "/" MACHINE_TYPE +}; #if !defined (lint) && !defined (SABER) static const char rcsid_version_c[] = @@ -33,51 +36,5 @@ static const char copyright[] = char * get_version() { - static char vers_buf[256]; - - if (vers_buf[0] == '\0') { -#ifdef DEBUG - sprintf(vers_buf,"Zephyr Server (DEBUG) $Revision: 3.24 $: %s", - ZSERVER_VERSION_STRING); -#else - sprintf(vers_buf,"Zephyr Server $Revision: 3.24 $: %s", - ZSERVER_VERSION_STRING); -#endif /* DEBUG */ - - (void) strcat(vers_buf, "/"); -#ifdef vax - (void) strcat(vers_buf, "VAX"); -#endif /* vax */ -#ifdef ibm032 - (void) strcat(vers_buf, "IBM RT"); -#endif /* ibm032 */ -#ifdef _IBMR2 - (void) strcat(vers_buf, "IBM RS/6000"); -#endif /* _IBMR2 */ -#ifdef sun - (void) strcat(vers_buf, "SUN"); -#ifdef sparc - (void) strcat (vers_buf, "-4"); -#endif /* sparc */ -#ifdef sun386 - (void) strcat (vers_buf, "-386I"); -#endif /* sun386 */ -#endif /* sun */ - -#ifdef mips -#ifdef ultrix /* DECstation */ - (void) strcat (vers_buf, "DEC-"); -#endif /* ultrix */ - (void) strcat(vers_buf, "MIPS"); -#endif /* mips */ -#ifdef NeXT - (void) strcat(vers_buf, "NeXT"); -#endif /* NeXT */ - } - return(vers_buf); + return version; } - - - - - diff --git a/zhm/queue.c b/zhm/queue.c index 7f7b271..5ac13d8 100644 --- a/zhm/queue.c +++ b/zhm/queue.c @@ -18,78 +18,83 @@ static char rcsid_queue_c[] = "$Id: queue.c,v 1.22 1999/10/20 16:44:11 ghudson E #endif /* SABER */ #endif /* lint */ -typedef struct _Queue { - Timer *timer; - int retries; - ZNotice_t notice; - caddr_t packet; - struct sockaddr_in reply; - struct _Queue *next, **prev_p; -} Queue; - -static Queue *hm_queue; -static int retransmits_enabled = 0; - -static Queue *find_notice_in_queue __P((ZNotice_t *notice)); -static Code_t dump_queue __P((void)); -static void queue_timeout __P((void *arg)); +static const int rexmit_times[] = { 2, 2, 4, 4, 8, -1 }; -int rexmit_times[] = { 2, 2, 4, 4, 8, -1 }; +static Queue *find_notice_in_galaxy __P((galaxy_info *gi, ZNotice_t *notice)); +static void queue_timeout __P((void *arg)); #ifdef DEBUG -Code_t dump_queue(); +Code_t dump_galaxy_queue(galaxy_info *); #endif -void init_queue() +void init_galaxy_queue(galaxy_info *gi) { Queue *q; - while (hm_queue) { - q = hm_queue; + while (gi->queue) { + q = gi->queue; if (q->timer) timer_reset(q->timer); free(q->packet); - hm_queue = q->next; + gi->queue = q->next; free(q); } DPR("Queue initialized and flushed.\n"); } -Code_t add_notice_to_queue(notice, packet, repl, len) +Code_t add_notice_to_galaxy(gi, notice, repl, len) + galaxy_info *gi; ZNotice_t *notice; - char * packet; struct sockaddr_in *repl; int len; { Queue *entry; + int length; + int retval; DPR("Adding notice to queue...\n"); - if (!find_notice_in_queue(notice)) { + if (!find_notice_in_galaxy(gi, notice)) { entry = (Queue *) malloc(sizeof(Queue)); if (entry == NULL) return(ZERR_NONOTICE); + entry->gi = gi; entry->retries = 0; - entry->packet = (char *) malloc(Z_MAXPKTLEN); - if (entry->packet == NULL) { + if (!(entry->packet = (char *) malloc((unsigned)sizeof(ZPacket_t)))) { free(entry); - return(ZERR_NONOTICE); + return(ENOMEM); } - memcpy(entry->packet, packet, Z_MAXPKTLEN); - if (ZParseNotice(entry->packet, len, &entry->notice) != ZERR_NONE) { - syslog(LOG_ERR, "ZParseNotice failed, but succeeded before"); + + if ((retval = ZFormatSmallRawNotice(notice, entry->packet, &length)) + != ZERR_NONE) { free(entry->packet); - } else { - entry->reply = *repl; - LIST_INSERT(&hm_queue, entry); + free(entry); + return(retval); + } + + /* I dislike this, but I need a notice which represents the + packet. since the notice structure refers to the internals + of its packet, I can't use the notice which was passed in, + so I need to make a new one. */ + + if ((retval = ZParseNotice(entry->packet, length, &entry->notice)) + != ZERR_NONE) { + free(entry->packet); + free(entry); + return(retval); } - entry->timer = (retransmits_enabled) ? - timer_set_rel(rexmit_times[0], queue_timeout, entry) : NULL; + + entry->reply = *repl; + LIST_INSERT(&gi->queue, entry); + + entry->timer = (gi->state == ATTACHED) ? + timer_set_rel(rexmit_times[0], queue_timeout, entry) : NULL; } return(ZERR_NONE); } -Code_t remove_notice_from_queue(notice, kind, repl) +Code_t remove_notice_from_galaxy(gi, notice, kind, repl) + galaxy_info *gi; ZNotice_t *notice; ZNotice_Kind_t *kind; struct sockaddr_in *repl; @@ -97,7 +102,7 @@ Code_t remove_notice_from_queue(notice, kind, repl) Queue *entry; DPR("Removing notice from queue...\n"); - entry = find_notice_in_queue(notice); + entry = find_notice_in_galaxy(gi, notice); if (entry == NULL) return(ZERR_NONOTICE); @@ -115,19 +120,14 @@ Code_t remove_notice_from_queue(notice, kind, repl) } /* We have a server; transmit all of our packets. */ -void retransmit_queue(sin) - struct sockaddr_in *sin; +void retransmit_galaxy(gi) + galaxy_info *gi; { Queue *entry; Code_t ret; DPR("Retransmitting queue to new server...\n"); - ret = ZSetDestAddr(sin); - if (ret != ZERR_NONE) { - Zperr (ret); - com_err("queue", ret, "setting destination"); - } - for (entry = hm_queue; entry; entry = entry->next) { + for (entry = gi->queue; entry; entry = entry->next) { DPR("notice:\n"); DPR2("\tz_kind: %d\n", entry->notice.z_kind); DPR2("\tz_port: %u\n", ntohs(entry->notice.z_port)); @@ -136,7 +136,7 @@ void retransmit_queue(sin) DPR2("\tz_opcode: %s\n", entry->notice.z_opcode); DPR2("\tz_sender: %s\n", entry->notice.z_sender); DPR2("\tz_recip: %s\n", entry->notice.z_recipient); - ret = send_outgoing(&entry->notice); + ret = send_outgoing(&gi->sin, &entry->notice); if (ret != ZERR_NONE) { Zperr(ret); com_err("queue", ret, "sending raw notice"); @@ -144,36 +144,36 @@ void retransmit_queue(sin) entry->timer = timer_set_rel(rexmit_times[0], queue_timeout, entry); entry->retries = 0; } - retransmits_enabled = 1; } /* We lost our server; nuke all of our timers. */ -void disable_queue_retransmits() +void disable_galaxy_retransmits(gi) + galaxy_info *gi; { Queue *entry; - for (entry = hm_queue; entry; entry = entry->next) { + for (entry = gi->queue; entry; entry = entry->next) { if (entry->timer) timer_reset(entry->timer); entry->timer = NULL; } - retransmits_enabled = 0; } #ifdef DEBUG -static Code_t dump_queue() +static Code_t dump_galaxy_queue(gi) + galaxy_info *gi; { Queue *entry; caddr_t mp; int ml; DPR("Dumping queue...\n"); - if (!hm_queue) { + if (!gi->queue) { printf("Queue is empty.\n"); return; } - for (entry = hm_queue; entry; entry = entry->next) { + for (entry = gi->queue; entry; entry = entry->next) { printf("notice:\n"); printf("\tz_kind: %d\n", entry->notice.z_kind); printf("\tz_port: %u\n", ntohs(entry->notice.z_port)); @@ -193,22 +193,24 @@ static Code_t dump_queue() } #endif /* DEBUG */ -int queue_len() +int galaxy_queue_len(gi) + galaxy_info *gi; { int length = 0; Queue *entry; - for (entry = hm_queue; entry; entry = entry->next) + for (entry = gi->queue; entry; entry = entry->next) length++; return length; } -static Queue *find_notice_in_queue(notice) +static Queue *find_notice_in_galaxy(gi, notice) + galaxy_info *gi; ZNotice_t *notice; { Queue *entry; - for (entry = hm_queue; entry; entry = entry->next) { + for (entry = gi->queue; entry; entry = entry->next) { if (ZCompareUID(&entry->notice.z_uid, ¬ice->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 6fc72a3..da76e09 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 d887980..db65066 100644 --- a/zhm/zhm_client.c +++ b/zhm/zhm_client.c @@ -18,79 +18,95 @@ static char rcsid_hm_client_c[] = "$Id: zhm_client.c,v 1.12 2000/04/05 14:57:37 #endif /* SABER */ #endif /* lint */ -extern int no_server, nclt, deactivated, noflushflag; -extern struct sockaddr_in cli_sin, serv_sin, from; +extern int noflushflag; +extern struct sockaddr_in cli_sin; -void transmission_tower(notice, packet, pak_len) +void transmission_tower(notice, from, packet, pak_len) ZNotice_t *notice; + struct sockaddr_in *from; char *packet; int pak_len; { + int i; + galaxy_info *gi; ZNotice_t gack; Code_t ret; struct sockaddr_in gsin; - nclt++; + if (notice->z_dest_galaxy) { + for (i=0; iz_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 cd460c8..bbcbd99 100644 --- a/zhm/zhm_server.c +++ b/zhm/zhm_server.c @@ -18,30 +18,15 @@ static char rcsid_hm_server_c[] = "$Id: zhm_server.c,v 1.18 2000/05/08 16:00:08 #endif /* SABER */ #endif /* lint */ +static void send_back __P((galaxy_info *, ZNotice_t *)); static void boot_timeout __P((void *)); -static int get_serv_timeout __P((void)); -static Timer *boot_timer = NULL; -static int serv_rexmit_times[] = { 5, 10, 20, 40 }; -static int serv_timeouts = 0; - -int serv_loop = 0; +extern int hmdebug; extern u_short cli_port; -extern struct sockaddr_in serv_sin, from; -extern int timeout_type, hmdebug, nservchang, booting, nserv, no_server; -extern int deactivated, rebootflag; -extern int numserv; -extern char **serv_list; -extern char cur_serv[], prim_serv[]; -extern void die_gracefully(); - -void hm_control(), send_back(), new_server(); - -/* Argument is whether we are actually booting, or just attaching - * after a server switch */ -void -send_boot_notice(op) -char *op; + +static void send_hmctl_notice(gi, op) + galaxy_info *gi; + char *op; { ZNotice_t notice; Code_t ret; @@ -55,271 +40,244 @@ char *op; notice.z_sender = "HM"; notice.z_recipient = ""; notice.z_default_format = ""; + notice.z_dest_galaxy = ""; notice.z_num_other_fields = 0; notice.z_message_len = 0; - /* Notify server that this host is here */ - if ((ret = ZSetDestAddr(&serv_sin)) != ZERR_NONE) { + if ((ret = ZSetDestAddr(&gi->sin)) != ZERR_NONE) { Zperr(ret); com_err("hm", ret, "setting destination"); } if ((ret = ZSendNotice(¬ice, 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(¬ice, 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; isin_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; igalaxy_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 0e3c6ac..4c7c319 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 ; inumblocks ; 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 4c0d1ee..b66a4b5 100644 --- a/zwgc/file.h +++ b/zwgc/file.h @@ -19,6 +19,7 @@ #include +extern char *get_home_directory(); extern FILE *locate_file(); #endif diff --git a/zwgc/main.c b/zwgc/main.c index e3c5ed8..ab9d5df 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 a702c05..7ece689 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 8adf5f0..d671498 100644 --- a/zwgc/subscriptions.c +++ b/zwgc/subscriptions.c @@ -32,6 +32,7 @@ static char rcsid_subscriptions_c[] = "$Id: subscriptions.c,v 1.13 1999/06/01 19 #include "error.h" #include "file.h" #include "main.h" +#include "zutils.h" /****************************************************************************/ /* */ @@ -128,6 +129,8 @@ void unpunt(class, instance, recipient) int_dictionary_Delete(puntable_addresses_dict, binding); } +#if 0 + /****************************************************************************/ /* */ /* Code to implement batching [un]subscription requests: */ @@ -161,7 +164,7 @@ static void free_subscription_list(list, number_of_elements) static void flush_subscriptions() { - TRAP(ZSubscribeTo(subscription_list,subscription_list_size, 0), + TRAP(ZSubscribeTo(NULL, subscription_list,subscription_list_size, 0), "while subscribing"); free_subscription_list(subscription_list, subscription_list_size); @@ -171,7 +174,8 @@ static void flush_subscriptions() static void flush_unsubscriptions() { if (unsubscription_list_size) - TRAP(ZUnsubscribeTo(unsubscription_list, unsubscription_list_size, 0), + TRAP(ZUnsubscribeTo(NULL, unsubscription_list, + unsubscription_list_size, 0), "while unsubscribing"); free_subscription_list(unsubscription_list, unsubscription_list_size); @@ -232,7 +236,7 @@ static void inithosts() strncpy(ourhostcanon, ourhost, sizeof(ourhostcanon)-1); return; } - strncpy(ourhostcanon, hent->h_name, sizeof(ourhostcanon)-1); + (void) strncpy(ourhostcanon,hent->h_name, sizeof(ourhostcanon)-1); return; } @@ -317,19 +321,28 @@ static void load_subscriptions_from_file(file) fclose(file); } +#endif /* 0 */ + #define DEFSUBS "/dev/null" static void load_subscriptions() { - FILE *subscriptions_file; - - /* no system default sub file on client--they live on the server */ - /* BUT...we need to use something to call load_subscriptions_from_file, - so we use /dev/null */ - subscriptions_file = locate_file(subscriptions_filename_override, - USRSUBS, DEFSUBS); - if (subscriptions_file) - load_subscriptions_from_file(subscriptions_file); + char subsname[MAXPATHLEN]; + int i, cnt; + char *home, *galaxy; + + if (subscriptions_filename_override) { + strcpy(subsname, subscriptions_filename_override); + } else if (home = get_home_directory()) { + strcpy(subsname, home?home:""); + strcat(subsname, "/"); + strcat(subsname, USRSUBS); + } else { + strcpy(subsname, ""); + } + + FATAL_TRAP(load_all_sub_files(SUB, *subsname?subsname:NULL), + "while loading subscription files"); } /****************************************************************************/ @@ -340,45 +353,94 @@ static void load_subscriptions() int zwgc_active = 0; -static ZSubscription_t *saved_subscriptions = NULL; -static int number_of_saved_subscriptions; +static ZSubscription_t **saved_subscriptions = NULL; +static int *number_of_saved_subscriptions; void zwgc_shutdown() { + int cnt, i; + char *galaxy; + if (!zwgc_active) return; - TRAP(ZRetrieveSubscriptions(0, &number_of_saved_subscriptions), - "while retrieving zephyr subscription list"); + TRAP(ZGetGalaxyCount(&cnt), "while getting galaxy count"); if (error_code) - return; - saved_subscriptions = (ZSubscription_t *) - malloc(number_of_saved_subscriptions*sizeof(ZSubscription_t)); - if (number_of_saved_subscriptions) - TRAP(ZGetSubscriptions(saved_subscriptions, - &number_of_saved_subscriptions), - "while getting subscriptions"); - if (error_code) { - free(saved_subscriptions); - saved_subscriptions = NULL; + return; + + if ((saved_subscriptions = + (ZSubscription_t **) malloc(sizeof(ZSubscription_t *)*cnt)) == NULL) { + fprintf(stderr, "out of memory allocating list of subscription lists"); + return; + } + if ((number_of_saved_subscriptions = + (int *) malloc(sizeof(int)*cnt)) == NULL) { + fprintf(stderr, + "out of memory allocating number of subscription lists"); + return; + } + + for (i=0; iy1;(inumblocks) && (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)); - xofsstrlen; - 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)); + xofsstrlen; + 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 05bfab8..81c0d24 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; iascent; 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; linefid; 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 f988a32..0e69933 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