summaryrefslogtreecommitdiff
path: root/server/subscr.c.old
diff options
context:
space:
mode:
Diffstat (limited to 'server/subscr.c.old')
-rw-r--r--server/subscr.c.old1384
1 files changed, 0 insertions, 1384 deletions
diff --git a/server/subscr.c.old b/server/subscr.c.old
deleted file mode 100644
index cb2b110..0000000
--- a/server/subscr.c.old
+++ /dev/null
@@ -1,1384 +0,0 @@
-/* This file is part of the Project Athena Zephyr Notification System.
- * It contains functions for managing subscription lists.
- *
- * Created by: John T. Kohl
- *
- * $Source$
- * $Author$
- *
- * Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
- * For copying and distribution information, see the file
- * "mit-copyright.h".
- */
-
-#include <zephyr/mit-copyright.h>
-
-#ifndef lint
-#ifndef SABER
-static char rcsid_subscr_c[] = "$Id$";
-#endif
-#endif
-
-/*
- * The subscription manager.
- *
- * External functions:
- *
- * Code_t subscr_subscribe(who, notice)
- * ZClient_t *who;
- * ZNotice_t *notice;
- *
- * Code_t subscr_cancel(sin, notice)
- * struct sockaddr_in *sin;
- * ZNotice_t *notice;
- *
- * Code_t subscr_cancel_client(client)
- * ZClient_t *client;
- *
- * Code_t subscr_cancel_host(addr)
- * struct in_addr *addr;
- *
- * ZClientList_t *subscr_match_list(notice)
- * ZNotice_t *notice;
- *
- * void subscr_free_list(list)
- * ZClientList_t *list;
- *
- * void subscr_sendlist(notice, auth, who)
- * ZNotice_t *notice;
- * int auth;
- * struct sockaddr_in *who;
- *
- * Code_t subscr_send_subs(client, vers)
- * ZClient_t *client;
- * char *vers;
- *
- * Code_t subscr_def_subs(who)
- * ZClient_t *who;
- *
- * void subscr_reset();
- *
- */
-
-#include "zserver.h"
-#include <ctype.h>
-#include <strings.h>
-#include <sys/stat.h>
-
-#ifdef __STDC__
-# define P(s) s
-#else
-# define P(s) ()
-#endif
-
-#ifdef KERBEROS
-#ifndef NOENCRYPTION
-C_Block serv_key;
-Sched serv_ksched;
-#endif
-#endif
-
-/* for compatibility when sending subscription information to old clients */
-
-static void check_sub_order P((ZSubscr_t *subs, int wc));
-#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 ZSubscr_t *extract_subscriptions P((register ZNotice_t *notice));
-static int clt_unique P((ZClient_t *clt, ZClientList_t *clist));
-static void free_subscriptions P((register ZSubscr_t *subs));
-static char **subscr_marshal_subs P((ZNotice_t *notice, int auth,
- struct sockaddr_in *who,
- register int *found));
-static Code_t subscr_subscribe_real P((ZClient_t *who, ZSubscr_t *newsubs,
- ZNotice_t *notice));
-static ZSubscr_t *subscr_copy_def_subs P((char *));
-static int cl_match P((ZSubscr_t*, ZClient_t *));
-
-static int defaults_read = 0; /* set to 1 if the default subs
- are in memory */
-static ZNotice_t default_notice; /* contains default subscriptions */
-
-#undef P
-
-ZSTRING *wildcard_class;
-ZSTRING *wildcard_instance;
-ZSTRING *empty;
-ZSubscr_t matchall_sub;
-
-/* WARNING: make sure this is the same as the number of strings you */
-/* plan to hand back to the user in response to a subscription check, */
-/* else you will lose. See subscr_sendlist() */
-#define NUM_FIELDS 3
-
-/*
- * subscribe the client to types described in notice.
- */
-
-Code_t
-subscr_subscribe(who, notice)
- ZClient_t *who;
- ZNotice_t *notice;
-{
- ZSubscr_t *subs;
-
- if (!who->zct_subs) {
- /* allocate a subscription head */
- if (!(subs = (ZSubscr_t *) xmalloc(sizeof(ZSubscr_t))))
- return(ENOMEM);
- subs->q_forw = subs->q_back = subs;
- subs->zst_dest.classname = subs->zst_dest.inst =
- subs->zst_dest.recip = NULL;
- subs->zst_dest.hash_value = 0;
- who->zct_subs = subs;
- }
-
- if (!(subs = extract_subscriptions(notice)))
- return(ZERR_NONE); /* no subscr -> no error */
-
- return(subscr_subscribe_real(who, subs, notice));
-}
-
-static Code_t
-subscr_subscribe_real(who, newsubs, notice)
- ZClient_t *who;
- register ZSubscr_t *newsubs;
- ZNotice_t *notice;
-{
- Code_t retval;
- ZAcl_t *acl;
- ZSTRING *sender;
- ZSubscr_t *subs2, *subs3, *subs;
- int relation;
-
- sender = make_zstring(notice->z_sender,0);
-
- START_CRITICAL_CODE;
-
- for (subs = newsubs->q_forw;
- subs != newsubs;
- subs = subs->q_forw) {
- /* for each new subscription */
-
-#if 0
- zdbug ((LOG_DEBUG, "subscr: %s/%s/%s",
- subs->zst_dest.classname->string,
- subs->zst_dest.inst->string,
- subs->zst_dest.recip->string));
-#endif
-
- if (!bdumping
- && (subs->zst_dest.recip != empty)
- && (subs->zst_dest.recip != sender)) {
- syslog(LOG_WARNING, "subscr unauth %s recipient %s",
- sender->string,
- subs->zst_dest.recip->string);
- continue;
- }
- if (!bdumping) {
- acl = class_get_acl(subs->zst_dest.classname);
- if (acl) {
- if (!(access_check(sender->string, acl, SUBSCRIBE))) {
- syslog(LOG_WARNING,
- "subscr unauth %s class %s",
- sender->string,
- subs->zst_dest.classname->string);
- continue; /* the for loop */
- }
- if (wildcard_instance == subs->zst_dest.inst) {
- if (!access_check(sender->string, acl, INSTWILD)) {
- syslog(LOG_WARNING,
- "subscr unauth %s class %s wild inst",
- notice->z_sender,
- subs->zst_dest.classname->string);
- continue;
- }
- }
- }
- }
- /* subscriptions are stored in ascending order by */
- /* subscription hash value */
- /* Scan through list to check for duplicates, and to find */
- /* where to insert these subs */
-
- for (subs2 = who->zct_subs->q_forw;
- subs2 != who->zct_subs;
- subs2 = subs2->q_forw) {
- /* for each existing subscription */
- relation = compare_subs(subs2,subs,0);
- if (relation == 0)
- goto duplicate;
- if (relation > 0) /* we have passed last possible one */
- break;
- if (relation < 0) /* nope... */
- continue;
- }
-
- /* subs2 now points to the first class which is greater
- than the new class. We need to back up so that the
- insertion below goes BEFORE this one (i.e. after the
- previous one) */
- subs2 = subs2->q_back;
-
- /* ok, we are a new subscription. register and chain on. */
-
- if (!(subs3 = (ZSubscr_t *) xmalloc(sizeof(ZSubscr_t)))) {
- free_subscriptions(newsubs);
- END_CRITICAL_CODE;
- return(ENOMEM);
- }
-
- subs3->q_forw = subs3->q_back = subs3;
- subs3->zst_dest.classname =
- dup_zstring(subs->zst_dest.classname);
- subs3->zst_dest.inst = dup_zstring(subs->zst_dest.inst);
- subs3->zst_dest.recip = dup_zstring(subs->zst_dest.recip);
- set_ZDestination_hash(&subs3->zst_dest);
-
- if ((retval = class_register(who, subs)) != ZERR_NONE) {
- xfree(subs3);
- free_subscriptions(newsubs);
- END_CRITICAL_CODE;
- return(retval);
- }
-
- /* subs2 was adjusted above */
- xinsque(subs3, subs2);
- duplicate:
- ;
- }
-
- END_CRITICAL_CODE;
-
- free_subscriptions(newsubs);
- return(ZERR_NONE);
-}
-
-/*
- * add default subscriptions to the client's subscription chain.
- */
-
-Code_t
-subscr_def_subs(who)
- ZClient_t *who;
-{
- ZSubscr_t *subs;
-
- if (!who->zct_subs) {
- /* allocate a subscription head */
- if (!(subs = (ZSubscr_t *) xmalloc(sizeof(ZSubscr_t)))) {
- syslog(LOG_ERR, "no mem subscr_def_subs");
- return(ENOMEM);
- }
- subs->q_forw = subs->q_back = subs;
- subs->zst_dest.classname = subs->zst_dest.inst =
- subs->zst_dest.recip = (ZSTRING *) NULL;
- subs->zst_dest.hash_value = 0;
- who->zct_subs = subs;
- }
-
- subs = subscr_copy_def_subs(who->zct_principal->string);
- return(subscr_subscribe_real(who, subs, &default_notice));
-}
-
-void
-subscr_reset()
-{
-#if 0
- zdbug((LOG_DEBUG, "subscr_reset()"));
-#endif
- xfree(default_notice.z_message);
- default_notice.z_message = NULL;
- defaults_read = 0;
-}
-
-static ZSubscr_t *
-subscr_copy_def_subs(person)
- char *person;
-{
- int retval;
- int fd;
- struct stat statbuf;
- char *def_sub_area;
- register char *cp;
- ZSubscr_t *subs;
- register ZSubscr_t *subs2;
-
- if (!defaults_read) {
-#if 0
- zdbug((LOG_DEBUG, "reading default subscription file"));
-#endif
- fd = open(DEFAULT_SUBS_FILE, O_RDONLY, 0666);
- if (fd < 0) {
- syslog(LOG_ERR, "can't open %s:%m", DEFAULT_SUBS_FILE);
- return((ZSubscr_t *)0);
- }
- retval = fstat(fd, &statbuf);
- if (retval < 0) {
- syslog(LOG_ERR, "fstat failure on %s:%m",
- DEFAULT_SUBS_FILE);
- (void) close(fd);
- return((ZSubscr_t *)0);
- }
- if (!(def_sub_area = (char *) xmalloc(statbuf.st_size + 1))) {
- syslog(LOG_ERR, "no mem copy_def_subs");
- (void) close(fd);
- return((ZSubscr_t *)0);
- }
- retval = read(fd, def_sub_area, (int) statbuf.st_size);
- /*
- "Upon successful completion, read and readv return the number
- of bytes actually read and placed in the buffer. The system
- guarantees to read the number of bytes requested if the
- descriptor references a normal file that has that many bytes
- left before the end-of-file, but in no other case."
- -- read(2)
- Therefore, the following test is valid.
- */
- if (retval != statbuf.st_size) {
- syslog(LOG_ERR, "short read in copy_def_subs");
- (void) close(fd);
- return((ZSubscr_t *)0);
- }
-
- (void) close(fd);
- def_sub_area[statbuf.st_size] = '\0'; /* null-terminate it */
-
- /*
- def_subs_area now points to a buffer full of subscription
- info.
- each line of the stuff is of the form:
- class,inst,recipient
-
- Commas and newlines may not appear as part of the class,
- instance, or recipient. XXX!
- */
-
- /* split up the subscription info */
- for (cp = def_sub_area;
- cp < def_sub_area + statbuf.st_size;
- cp++)
- if ((*cp == '\n') || (*cp == ','))
- *cp = '\0';
- default_notice.z_message = def_sub_area;
- default_notice.z_message_len = (int) statbuf.st_size + 1;
- default_notice.z_auth = 1;
- defaults_read = 1;
- }
- /* needed later for access_check() */
- default_notice.z_sender = person;
- subs = extract_subscriptions(&default_notice);
- /* replace any non-* recipients with "person" */
-
- for (subs2 = subs->q_forw; subs2 != subs; subs2 = subs2->q_forw) {
- /* if not a wildcard, replace it with person */
- if (strcmp(subs2->zst_dest.recip->string, "*")) {
- free_zstring(subs2->zst_dest.recip);
- subs2->zst_dest.recip = make_zstring(person,0);
- } else { /* replace with null recipient */
- free_zstring(subs2->zst_dest.recip);
- subs2->zst_dest.recip = dup_zstring(empty);
- }
- set_ZDestination_hash(&(subs2->zst_dest));
- }
- return(subs);
-}
-
-/*
- * Cancel one subscription.
- */
-
-Code_t
-subscr_cancel(sin, notice)
- struct sockaddr_in *sin;
- ZNotice_t *notice;
-{
- ZClient_t *who;
- register ZSubscr_t *subs, *subs2, *subs3, *subs4;
- Code_t retval;
- int found = 0;
- int relation;
-
-#if 0
- zdbug((LOG_DEBUG,"subscr_cancel"));
-#endif
- if (!(who = client_which_client(sin, notice)))
- return(ZSRV_NOCLT);
-
- if (!who->zct_subs)
- return(ZSRV_NOSUB);
-
- if (!(subs = extract_subscriptions(notice)))
- return(ZERR_NONE); /* no subscr -> no error */
-
- START_CRITICAL_CODE;
-
- for (subs4 = subs->q_forw; subs4 != subs; subs4 = subs4->q_forw) {
- for (subs2 = who->zct_subs->q_forw;
- subs2 != who->zct_subs;) {
- /* for each existing subscription */
- /* is this what we are canceling? */
- relation = compare_subs(subs2, subs4,0);
- if (relation < 0) {
- subs2 = subs2->q_forw;
- continue;
- }
- if (relation > 0)
- /* We have passed last possible one */
- break;
-
- /* go back, since remque will change things */
- subs3 = subs2->q_back;
- xremque(subs2);
- (void) class_deregister(who, subs2);
- free_zstring(subs2->zst_dest.classname);
- free_zstring(subs2->zst_dest.inst);
- free_zstring(subs2->zst_dest.recip);
- xfree(subs2);
- found = 1;
- /* now that the remque adjusted the linked
- list, we go forward again */
- subs2 = subs3->q_forw;
- break;
- }
- }
-
- /* make sure we are still registered for all the classes */
- if (found) {
- for (subs2 = who->zct_subs->q_forw;
- subs2 != who->zct_subs;
- subs2 = subs2->q_forw)
- if ((retval = class_register(who, subs2)) != ZERR_NONE) {
- free_subscriptions(subs);
- END_CRITICAL_CODE;
- return(retval);
- }
- }
-
- END_CRITICAL_CODE;
-
- free_subscriptions(subs);
- if (found) {
-#if 0
- zdbug((LOG_DEBUG, "found & removed"));
-#endif
- return(ZERR_NONE);
- } else {
-#if 0
- zdbug((LOG_DEBUG, "not found"));
-#endif
- return(ZSRV_NOSUB);
- }
-}
-
-/*
- * Cancel all the subscriptions for this client.
- */
-
-void
-subscr_cancel_client(client)
- ZClient_t *client;
-{
- register ZSubscr_t *subs;
-
-#if 0
- zdbug((LOG_DEBUG,"subscr_cancel_client %s",
- inet_ntoa (client->zct_addr.sin_addr)));
-#endif
- if (!client->zct_subs)
- return;
-
- START_CRITICAL_CODE;
-
- for (subs = client->zct_subs->q_forw;
- subs != client->zct_subs;
- subs = client->zct_subs->q_forw) {
-#if 0
- zdbug((LOG_DEBUG,"sub_can %s",
- subs->zst_dest.classname->string));
-#endif
- if (class_deregister(client, subs) != ZERR_NONE) {
-#if 0
- zdbug((LOG_DEBUG,"sub_can_clt: not registered!"));
-#endif
- }
- xremque(subs);
- free_zstring(subs->zst_dest.classname);
- free_zstring(subs->zst_dest.inst);
- free_zstring(subs->zst_dest.recip);
- xfree(subs);
- }
-
- /* also flush the head of the queue */
- /* subs is now client->zct_subs */
- free_zstring(subs->zst_dest.classname);
- free_zstring(subs->zst_dest.inst);
- free_zstring(subs->zst_dest.recip);
- xfree(subs);
- client->zct_subs = NULLZST;
-
- END_CRITICAL_CODE;
-
- return;
-}
-
-#ifdef notdef
-/* not used for the moment */
-/*
- * Cancel all the subscriptions for clients at this addr.
- */
-
-Code_t
-subscr_cancel_host(addr)
-struct in_addr *addr;
-{
- register ZHostList_t *hosts;
- register ZClientList_t *clist = NULLZCLT, *clt;
-
- /* find the host */
- if (!(hosts = hostm_find_host(addr)))
- return(ZSRV_HNOTFOUND);
- clist = hosts->zh_clients;
-
- START_CRITICAL_CODE;
-
- /* flush each one */
- for (clt = clist->q_forw; clt != clist; clt = clt->q_forw)
- (void) subscr_cancel_client(clt->zclt_client);
-
- END_CRITICAL_CODE;
-
- return(ZERR_NONE);
-}
-#endif
-
-/*
- * Here is the bulk of the work in the subscription manager.
- * We grovel over the list of clients possibly interested in this
- * notice, and copy into a list on a match. Make sure we only add any given
- * client once.
- */
-
-ZClientList_t *
-subscr_match_list(notice)
- ZNotice_t *notice;
-{
- register ZClientList_t *hits, *clients, *majik, *clients2, *hit2;
- char *saveclass, *saveclinst;
- ZSTRING *newclass;
- ZSTRING *newclinst;
- ZSubscr_t check_sub;
-
- if (!(hits = (ZClientList_t *) xmalloc(sizeof(ZClientList_t))))
- return(NULLZCLT);
- hits->q_forw = hits->q_back = hits;
-
- saveclass = notice->z_class;
- newclass = make_zstring(notice->z_class, 1);
-
- saveclinst = notice->z_class_inst;
- newclinst = make_zstring(notice->z_class_inst, 1);
-
- check_sub.zst_dest.classname = newclass;
- check_sub.zst_dest.inst = newclinst;
- check_sub.zst_dest.recip = make_zstring(notice->z_recipient, 0);
- set_ZDestination_hash(&check_sub.zst_dest);
- check_sub.q_forw = check_sub.q_back = &check_sub;
-
- clients = class_lookup (&check_sub);
- majik = class_lookup (&matchall_sub);
- if (!clients && !majik)
- return NULLZCLT;
-
- notice->z_class = (char *) newclass->string;
- notice->z_class_inst = (char *) newclinst->string;
- if (clients) {
- for (clients2 = clients->q_forw;
- clients2 != clients;
- clients2 = clients2->q_forw)
- if (cl_match(&check_sub, clients2->zclt_client)) {
- if (!clt_unique(clients2->zclt_client, hits))
- continue;
- /* we hit */
- if (!(hit2 = (ZClientList_t *) xmalloc(sizeof(ZClientList_t)))) {
- syslog(LOG_WARNING,
- "subscr_match: punting/no mem");
- notice->z_class = saveclass;
- notice->z_class_inst = saveclinst;
- free_zstring(newclass);
- free_zstring(newclinst);
- free_zstring(check_sub.zst_dest.recip);
- return(hits);
- }
- hit2->zclt_client = clients2->zclt_client;
- hit2->q_forw = hit2->q_back = hit2;
- xinsque(hit2, hits);
- }
- class_free(clients);
- }
- if (majik) {
- for (clients2 = majik->q_forw;
- clients2 != majik;
- clients2 = clients2->q_forw) {
- if (!clt_unique(clients2->zclt_client, hits))
- continue;
- /* we hit */
- if (!(hit2 = (ZClientList_t *) xmalloc(sizeof(ZClientList_t)))) {
- syslog(LOG_WARNING,
- "subscr_match(majik): punting/no mem");
- notice->z_class = saveclass;
- notice->z_class_inst = saveclinst;
- free_zstring(newclass);
- free_zstring(newclinst);
- free_zstring(check_sub.zst_dest.recip);
- return(hits);
- }
- hit2->zclt_client = clients2->zclt_client;
- hit2->q_forw = hit2->q_back = hit2;
-
- xinsque(hit2, hits);
- }
- class_free(majik);
- }
- notice->z_class = saveclass;
- notice->z_class_inst = saveclinst;
- free_zstring(newclass);
- free_zstring(newclinst);
- free_zstring(check_sub.zst_dest.recip);
- if (hits->q_forw == hits) {
- xfree(hits);
- return(NULLZCLT);
- }
- return(hits);
-}
-
-/*
- * Free memory used by a list we allocated.
- */
-
-void
-subscr_free_list(list)
- ZClientList_t *list;
-{
- register ZClientList_t *lyst;
-
- for (lyst = list->q_forw; lyst != list; lyst = list->q_forw) {
- xremque(lyst);
- xfree(lyst);
- }
- xfree(list);
- return;
-}
-
-/*
- * Send the requester a list of his current subscriptions
- */
-
-void
-subscr_sendlist(notice, auth, who)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
-{
- char **answer;
- int found;
- struct sockaddr_in send_to_who;
- Code_t retval;
-
-#ifdef OLD_COMPAT
- if (!strcmp(notice->z_version, OLD_ZEPHYR_VERSION)) {
- /* 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)) {
- /* 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 */
-
- if ((retval = ZSetDestAddr(&send_to_who)) != ZERR_NONE) {
- syslog(LOG_WARNING, "subscr_sendlist set addr: %s",
- error_message(retval));
- if (answer)
- xfree(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 */
-
- if ((retval = ZSrvSendRawList(notice, (char **) answer,
- found*NUM_FIELDS, xmit_frag))
- != ZERR_NONE) {
- syslog(LOG_WARNING, "subscr_sendlist xmit: %s",
- error_message(retval));
- }
- if (answer)
- xfree(answer);
- return;
-}
-
-static char **
-subscr_marshal_subs(notice, auth, who, found)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
- register int *found;
-{
- ZNotice_t reply;
- char **answer = (char **) 0;
- int temp;
- Code_t retval;
- ZClient_t *client;
- register ZSubscr_t *subs, *subs2 = NULLZST;
- register 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)) {
- /* 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
- list. The port field is the port of the sender. */
-
- if ((retval = ZReadAscii(notice->z_message,
- notice->z_message_len,
- (unsigned char *)&temp,
- sizeof(u_short))) != ZERR_NONE) {
- syslog(LOG_WARNING, "subscr_marshal read port num: %s",
- error_message(retval));
- return((char **)0);
- }
-
- /* Blech blech blech */
- reply = *notice;
- reply.z_port = *((u_short *)&temp);
-
- client = client_which_client(who, &reply);
-
- if (client)
- subs2 = client->zct_subs;
- } else if (!strcmp(notice->z_opcode, CLIENT_GIMMEDEFS)) {
-#if 0
- zdbug((LOG_DEBUG, "gimmedefs"));
-#endif
- /* subscr_copy_def_subs allocates new pointer rings, so
- it must be freed when finished.
- the string areas pointed to are static, however.*/
- subs2 = subscr_copy_def_subs(notice->z_sender);
- defsubs = 1;
- } else {
- syslog(LOG_ERR, "subscr_marshal bogus opcode %s",
- notice->z_opcode);
- return((char **) 0);
- }
-
- if (subs2) {
-
- /* 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((char **) 0);
- }
- if (!defsubs) {
- if (client && (strcmp(client->zct_principal->string,
- notice->z_sender) != 0)) {
- zdbug ((LOG_DEBUG,
- "subscr_marshal: %s requests subs for %s at %s/%d",
- notice->z_sender,
- client->zct_principal->string,
- inet_ntoa (who->sin_addr),
- ntohs (who->sin_port)));
- return 0;
- }
- }
-
- for (subs = subs2->q_forw;
- subs != subs2;
- subs = subs->q_forw, (*found)++);
-
- /* found is now the number of subscriptions */
-
- /* coalesce the subscription information into a list of
- char *'s */
- if ((answer = (char **) xmalloc((*found) * NUM_FIELDS * sizeof(char *))) == (char **) 0) {
- syslog(LOG_ERR, "subscr no mem(answer)");
- *found = 0;
- } else
- for (i = 0, subs = subs2->q_forw;
- i < *found ;
- i++, subs = subs->q_forw) {
- answer[i*NUM_FIELDS] = subs->zst_dest.classname->string;
- answer[i*NUM_FIELDS + 1] = subs->zst_dest.inst->string;
- answer[i*NUM_FIELDS + 2] = subs->zst_dest.recip->string;
- }
- }
- if (defsubs)
- free_subscriptions(subs2);
- return(answer);
-}
-
-#ifdef NEW_COMPAT
-static void
-new_old_compat_subscr_sendlist(notice, auth, who)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
-{
- Code_t retval;
- ZNotice_t reply;
- ZPacket_t reppacket;
- int packlen, found, count, initfound, zerofound;
- char buf[64];
- Zconst char **answer;
- struct sockaddr_in send_to_who;
- register 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 */
-
- if ((retval = ZSetDestAddr(&send_to_who)) != 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);
- (void) 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)
- xfree(answer);
- return;
- }
- if ((retval = ZSendPacket(reppacket, packlen, 0)) != ZERR_NONE) {
- syslog(LOG_WARNING, "subscr_sendlist xmit: %s",
- error_message(retval));
- if (answer)
- xfree(answer);
- return;
- }
- found -= 5;
- zerofound = 0;
- }
-#if 0
- zdbug((LOG_DEBUG,"subscr_sendlist acked"));
-#endif
- if (answer)
- xfree(answer);
- return;
-}
-#endif /* NEW_COMPAT */
-
-#ifdef OLD_COMPAT
-static void
-old_compat_subscr_sendlist(notice, auth, who)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
-{
- ZClient_t *client = client_which_client(who, notice);
- register ZSubscr_t *subs;
- Code_t retval;
- ZNotice_t reply;
- ZPacket_t reppacket;
- int packlen, i, found = 0;
- char **answer = (char **) NULL;
-
- old_compat_count_subscr++;
-
- syslog(LOG_INFO, "old old subscr, %s", inet_ntoa(who->sin_addr));
- if (client && client->zct_subs) {
-
- /* 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 (!auth) {
- clt_ack(notice, who, AUTH_FAILED);
- return;
- }
-
- for (subs = client->zct_subs->q_forw;
- subs != client->zct_subs;
- subs = subs->q_forw, found++);
-
- /* found is now the number of subscriptions */
-
- /* coalesce the subscription information into a list of
- char *'s */
- if ((answer = (char **) xmalloc(found * NUM_FIELDS * sizeof(char *))) == (char **) 0) {
- syslog(LOG_ERR, "old_subscr_sendlist no mem(answer)");
- found = 0;
- } else
- for (i = 0, subs = client->zct_subs->q_forw;
- i < found ;
- i++, subs = subs->q_forw) {
- answer[i*NUM_FIELDS] = subs->zst_class;
- answer[i*NUM_FIELDS + 1] = subs->zst_classinst;
- answer[i*NUM_FIELDS + 2] = subs->zst_recipient;
- }
- }
- /* 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)
- xfree(answer);
- return;
- }
- if ((retval = ZSetDestAddr(who)) != ZERR_NONE) {
- syslog(LOG_WARNING, "subscr_sendlist set addr: %s",
- error_message(retval));
- if (answer)
- xfree(answer);
- return;
- }
- if ((retval = ZSendPacket(reppacket, packlen, 0)) != ZERR_NONE) {
- syslog(LOG_WARNING, "subscr_sendlist xmit: %s",
- error_message(retval));
- if (answer)
- xfree(answer);
- return;
- }
-#if 0
- zdbug((LOG_DEBUG,"subscr_sendlist acked"));
-#endif
- if (answer)
- xfree(answer);
- return;
-}
-#endif /* OLD_COMPAT */
-
-/*
- * Send the client's subscriptions to another server
- */
-
-/* version is currently unused; if necessary later versions may key off it
- to determine what to send to the peer (protocol changes) */
-
-/*ARGSUSED*/
-Code_t
-subscr_send_subs(client, vers)
- ZClient_t *client;
- char *vers;
-{
- register int i = 0;
- register ZSubscr_t *sub;
-#ifdef KERBEROS
- char buf[512];
- C_Block cblock;
-#endif /* KERBEROS */
- char buf2[512];
- char *lyst[7 * NUM_FIELDS];
- int num = 0;
- Code_t retval;
-
-#if 0
- zdbug((LOG_DEBUG, "send_subs"));
-#endif
- (void) sprintf(buf2, "%d",ntohs(client->zct_sin.sin_port));
-
- lyst[num++] = buf2;
-
-#ifdef KERBEROS
-#ifdef NOENCRYPTION
- (void) memcpy((caddr_t)cblock, (caddr_t)client->zct_cblock, sizeof(C_Block));
-#else
- des_ecb_encrypt(client->zct_cblock, cblock, serv_ksched.s, DES_ENCRYPT);
-#endif
-
- if ((retval = ZMakeAscii(buf, sizeof(buf), cblock,
- sizeof(C_Block))) != ZERR_NONE) {
-#if 0
- zdbug((LOG_DEBUG,"zmakeascii failed: %s",
- error_message(retval)));
-#endif
- } else {
- lyst[num++] = buf;
-#if 0
- zdbug((LOG_DEBUG,"cblock %s",buf));
-#endif
- }
-#endif /* KERBEROS */
- if ((retval = bdump_send_list_tcp(SERVACK, client->zct_sin.sin_port,
- ZEPHYR_ADMIN_CLASS,
- num > 1 ? "CBLOCK" : "",
- ADMIN_NEWCLT,
- (char*)client->zct_principal->string,
- "", lyst, num)) != ZERR_NONE ) {
- syslog(LOG_ERR, "subscr_send_subs newclt: %s",
- error_message(retval));
- return(retval);
- }
-
- if (!client->zct_subs)
- return(ZERR_NONE);
- for (sub = client->zct_subs->q_forw;
- sub != client->zct_subs;
- sub = sub->q_forw) {
- /* for each subscription */
- lyst[i * NUM_FIELDS] = sub->zst_dest.classname->string;
- lyst[i * NUM_FIELDS + 1] = sub->zst_dest.inst->string;
- lyst[i * NUM_FIELDS + 2] = sub->zst_dest.recip->string;
- i++;
- if (i >= 7) {
- /* we only put 7 in each packet, so we don't
- run out of room */
- if ((retval = bdump_send_list_tcp(ACKED,
- client->zct_sin.sin_port,
- ZEPHYR_CTL_CLASS, "",
- CLIENT_SUBSCRIBE, "",
- "", lyst,
- i * NUM_FIELDS))
- != ZERR_NONE) {
- syslog(LOG_ERR, "subscr_send_subs subs: %s",
- error_message(retval));
- return(retval);
- }
- i = 0;
- }
- }
- if (i) {
- if ((retval = bdump_send_list_tcp(ACKED,
- client->zct_sin.sin_port,
- ZEPHYR_CTL_CLASS, "",
- CLIENT_SUBSCRIBE, "", "",
- lyst, i * NUM_FIELDS))
- != ZERR_NONE) {
- syslog(LOG_ERR, "subscr_send_subs subs: %s",
- error_message(retval));
- return(retval);
- }
- }
- return(ZERR_NONE);
-}
-
-/*
- * is this client unique to this list? 0 = no, 1 = yes
- */
-
-static int
-clt_unique(clt, clist)
- ZClient_t *clt;
- ZClientList_t *clist;
-{
- register ZClientList_t *client;
-
- for (client = clist->q_forw;
- client != clist;
- client = client->q_forw)
- if (client->zclt_client == clt)
- return(0);
- return(1);
-}
-
-/*
- * is this client listening to this notice? 1=yes, 0=no
- */
-
-static int
-cl_match(notice_subs, client)
- register ZSubscr_t *notice_subs;
- register ZClient_t *client;
-{
- register ZSubscr_t *subs;
- int relation;
-
- if (client->zct_subs == NULLZST) {
- syslog(LOG_WARNING, "cl_match w/ no subs");
- return(0);
- }
-
- for (subs = client->zct_subs->q_forw;
- subs != client->zct_subs;
- subs = subs->q_forw) {
- relation = compare_subs(notice_subs, subs, 1);
-
-/*
- if (relation < 0)
- return(0);
-*/
- if (relation == 0)
- return(1);
- }
- /* fall through */
- return(0);
-}
-
-/*
- * free the memory allocated for the list of subscriptions.
- */
-
-static void
-free_subscriptions(subs)
- register ZSubscr_t *subs;
-{
- register ZSubscr_t *sub;
-
- for (sub = subs->q_forw; sub != subs; sub = subs->q_forw) {
- xremque(sub);
- free_zstring(sub->zst_dest.classname);
- free_zstring(sub->zst_dest.inst);
- free_zstring(sub->zst_dest.recip);
- xfree(sub);
- }
- free_zstring(subs->zst_dest.classname);
- free_zstring(subs->zst_dest.inst);
- free_zstring(subs->zst_dest.recip);
- xfree(subs);
-
- return;
-}
-
-#define ADVANCE(xx) { cp += (strlen(cp) + 1); \
- if (cp >= notice->z_message + notice->z_message_len) { \
- syslog(LOG_WARNING, "malformed subscription %d", xx); \
- return(subs); \
- }}
-
-/*
- * Parse the message body, returning a linked list of subscriptions, or
- * NULLZST if there are no subscriptions there.
- */
-
-static ZSubscr_t *
-extract_subscriptions(notice)
- register ZNotice_t *notice;
-{
- register ZSubscr_t *subs = NULLZST, *subs2;
- register char *recip, *class_name, *classinst;
- register char *cp = notice->z_message;
-
- /* parse the data area for the subscriptions */
- while (cp < notice->z_message + notice->z_message_len) {
- class_name = cp;
- if (*cp == '\0')
- /* we've exhausted the subscriptions */
- return(subs);
- ADVANCE(1);
- classinst = cp;
- ADVANCE(2);
- recip = cp;
-#if 0
- zdbug((LOG_DEBUG, "ext_sub: CLS %s INST %s RCPT %s",
- class_name, classinst, cp));
-#endif
- cp += (strlen(cp) + 1);
- if (cp > notice->z_message + notice->z_message_len) {
- syslog(LOG_WARNING, "malformed sub 3");
- return(subs);
- }
- if (!subs) {
- if (!(subs = (ZSubscr_t *)
- xmalloc(sizeof(ZSubscr_t)))) {
- syslog(LOG_WARNING, "ex_subs: no mem");
- return(NULLZST);
- }
- subs->q_forw = subs->q_back = subs;
- subs->zst_dest.classname = subs->zst_dest.inst =
- subs->zst_dest.recip = NULL;
- subs->zst_dest.hash_value = 0;
- }
- if (!(subs2 = (ZSubscr_t *) xmalloc(sizeof(ZSubscr_t)))) {
- syslog(LOG_WARNING, "ex_subs: no mem 2");
- return(subs);
- }
- subs2->q_forw = subs2->q_back = subs2;
- subs2->zst_dest.classname = make_zstring(class_name,1);
- subs2->zst_dest.inst = make_zstring(classinst,1);
- subs2->zst_dest.recip = make_zstring(recip,0);
- set_ZDestination_hash(&subs2->zst_dest);
-
- xinsque(subs2, subs);
- }
- return(subs);
-}
-
-/*
- * print subscriptions in subs onto fp.
- * assumed to be called with SIGFPE blocked
- * (true if called from signal handler)
- */
-
-void
-subscr_dump_subs(fp, subs)
- FILE *fp;
- ZSubscr_t *subs;
-{
- register ZSubscr_t *ptr;
-
- if (!subs) /* no subscriptions to dump */
- return;
-
- for (ptr = subs->q_forw; ptr != subs; ptr = ptr->q_forw) {
- fputs("\t\t'", fp);
- fputs(ptr->zst_dest.classname->string, fp);
- fputs("' '", fp);
- fputs(ptr->zst_dest.inst->string, fp);
- fputs("' '", fp);
- fputs(ptr->zst_dest.recip->string, fp);
- fputs("'\n", fp);
- }
- return;
-}
-
-int
-compare_subs(s1,s2,do_wildcard)
- ZSubscr_t *s1, *s2;
- int do_wildcard;
-{
-
-#if 0
- zdbug((LOG_DEBUG,"compare_subs: %s/%s/%s to %s/%s/%s",
- s1->zst_dest.classname->string, s1->zst_dest.inst->string, s1->zst_dest.recip->string,
- s2->zst_dest.classname->string, s2->zst_dest.inst->string, s2->zst_dest.recip->string));
-#endif
- /* wildcard must be in s2 in order for it to match */
-
- if (do_wildcard && (s1->zst_dest.classname == s2->zst_dest.classname) &&
- (s2->zst_dest.inst == wildcard_instance) &&
- (s1->zst_dest.recip == s2->zst_dest.recip))
- return(0);
-
- if (s1->zst_dest.hash_value > s2->zst_dest.hash_value)
- return 1;
- if (s1->zst_dest.hash_value < s2->zst_dest.hash_value)
- return -1;
-
- if (s1->zst_dest.classname != s2->zst_dest.classname)
- return(strcasecmp(s1->zst_dest.classname->string,
- s2->zst_dest.classname->string));
-
- if (s1->zst_dest.inst != s2->zst_dest.inst)
- return(strcasecmp(s1->zst_dest.inst->string,
- s2->zst_dest.inst->string));
-
- if (s1->zst_dest.recip != s2->zst_dest.recip)
- return(strcasecmp(s1->zst_dest.recip->string,
- s2->zst_dest.recip->string));
-
- return(0);
-}
-
-static void
-check_sub_order(subs,wc)
- ZSubscr_t *subs;
- int wc;
-{
- ZSubscr_t *subs2;
- int relation;
-
- for (subs2 = subs->q_forw;
- subs2->q_forw != subs;
- subs2 = subs2->q_forw) {
-
- /* for each existing subscription */
- relation = compare_subs(subs2,subs2->q_forw,wc);
- if (relation > 0) {
- syslog(LOG_DEBUG, "s_check failed: %s/%s/%s <=> %s/%s/%s = %d",
- subs2->zst_dest.classname->string,
- subs2->zst_dest.inst->string,
- subs2->zst_dest.recip->string,
- subs2->q_forw->zst_dest.classname->string,
- subs2->q_forw->zst_dest.inst->string,
- subs2->q_forw->zst_dest.recip->string,
- relation);
- }
-
- }
-}