summaryrefslogtreecommitdiff
path: root/server/subscr.c
diff options
context:
space:
mode:
authorGravatar Greg Hudson <ghudson@mit.edu>1997-09-14 17:50:06 +0000
committerGravatar Greg Hudson <ghudson@mit.edu>1997-09-14 17:50:06 +0000
commitac16f380e349fa39ec7e26bccb5456cb300006a5 (patch)
treec07ca88af97b4f6b77d28a2dc723d2e4621ed302 /server/subscr.c
parentd33e482744fad80d95cdd89ed380c5b8401e49bf (diff)
Pull in sources from zephyr locker. See /mit/zephyr/repository for
detailed change information.
Diffstat (limited to 'server/subscr.c')
-rw-r--r--server/subscr.c2025
1 files changed, 1231 insertions, 794 deletions
diff --git a/server/subscr.c b/server/subscr.c
index 742adda..c305c70 100644
--- a/server/subscr.c
+++ b/server/subscr.c
@@ -12,10 +12,11 @@
*/
#include <zephyr/mit-copyright.h>
+#include "zserver.h"
#ifndef lint
#ifndef SABER
-static char rcsid_subscr_c[] = "$Id$";
+static const char rcsid_subscr_c[] = "$Id$";
#endif
#endif
@@ -25,7 +26,7 @@ static char rcsid_subscr_c[] = "$Id$";
* External functions:
*
* Code_t subscr_subscribe(who, notice)
- * ZClient_t *who;
+ * Client *who;
* ZNotice_t *notice;
*
* Code_t subscr_cancel(sin, notice)
@@ -33,16 +34,16 @@ static char rcsid_subscr_c[] = "$Id$";
* ZNotice_t *notice;
*
* Code_t subscr_cancel_client(client)
- * ZClient_t *client;
+ * Client *client;
*
* Code_t subscr_cancel_host(addr)
* struct in_addr *addr;
*
- * ZClientList_t *subscr_match_list(notice)
+ * Client *subscr_match_list(notice)
* ZNotice_t *notice;
*
* void subscr_free_list(list)
- * ZClientList_t *list;
+ * Client *list;
*
* void subscr_sendlist(notice, auth, who)
* ZNotice_t *notice;
@@ -50,28 +51,17 @@ static char rcsid_subscr_c[] = "$Id$";
* struct sockaddr_in *who;
*
* Code_t subscr_send_subs(client, vers)
- * ZClient_t *client;
+ * Client *client;
* char *vers;
*
* Code_t subscr_def_subs(who)
- * ZClient_t *who;
+ * Client *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
+#ifdef ZEPHYR_USES_KERBEROS
#ifndef NOENCRYPTION
C_Block serv_key;
Sched serv_ksched;
@@ -83,36 +73,41 @@ Sched serv_ksched;
#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,
+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,
+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((ZClient_t *who, ZSubscr_t *subs_queue,
+static Code_t add_subscriptions __P((Client *who, Destlist *subs_queue,
ZNotice_t *notice));
-static ZSubscr_t *extract_subscriptions P((register ZNotice_t *notice));
-static void free_subscriptions P((register ZSubscr_t *subs));
-static char **subscr_marshal_subs P((ZNotice_t *notice, int auth,
+static Destlist *extract_subscriptions __P((ZNotice_t *notice));
+static void free_subscriptions __P((Destlist *subs));
+static char **subscr_marshal_subs __P((ZNotice_t *notice, int auth,
struct sockaddr_in *who,
- register int *found));
-static ZSubscr_t *subscr_copy_def_subs P((char *person));
-static int cl_match P((ZSubscr_t*, ZClient_t *));
+ int *found));
+static Destlist *subscr_copy_def_subs __P((char *person));
+static Code_t subscr_subscribe_realms __P((struct sockaddr_in *who,
+ Destlist *newsubs,
+ ZNotice_t *notice));
+static Code_t subscr_realm_sendit __P((Client *who, Destlist *subs,
+ ZNotice_t *notice, Realm *realm));
+static void subscr_unsub_realms __P((Destlist *newsubs));
+static void subscr_unsub_sendit __P((Destlist *subs, Realm *realm));
+static int cl_match __P((Destlist*, Client *));
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_instance;
-ZSTRING *empty;
+String *wildcard_instance;
+String *empty;
/* 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, */
@@ -125,105 +120,89 @@ ZSTRING *empty;
Code_t
subscr_subscribe(who, notice)
- ZClient_t *who;
- ZNotice_t *notice;
+ Client *who;
+ ZNotice_t *notice;
{
- ZSubscr_t *subs_queue, *sub;
- Code_t retval;
-
- if (!who->zct_subs) {
- /* allocate a subscription head */
- sub = (ZSubscr_t *) xmalloc(sizeof(ZSubscr_t));
- if (!sub)
- return(ENOMEM);
- sub->q_forw = sub->q_back = sub;
- sub->zst_dest.classname = sub->zst_dest.inst =
- sub->zst_dest.recip = NULL;
- who->zct_subs = sub;
- }
+ Destlist *subs;
- subs_queue = extract_subscriptions(notice);
- return(add_subscriptions(who, subs_queue, notice));
+ subs = extract_subscriptions(notice);
+ return add_subscriptions(who, subs, notice);
}
static Code_t
-add_subscriptions(who, subs_queue, notice)
- ZClient_t *who;
- ZSubscr_t *subs_queue;
- ZNotice_t *notice;
+add_subscriptions(who, subs, notice)
+ Client *who;
+ Destlist *subs;
+ ZNotice_t *notice;
{
- ZSubscr_t *sub, *next;
- Code_t retval;
- ZAcl_t *acl;
- ZSTRING *sender;
-
- if (!subs_queue)
- return(ZERR_NONE); /* no subscr -> no error */
+ Destlist *next;
+ Code_t retval;
+ Acl *acl;
+ String *sender;
+ Realm *realm = NULL;
- sender = make_zstring(notice->z_sender,0);
+ if (!subs)
+ return ZERR_NONE; /* no subscr -> no error */
- START_CRITICAL_CODE;
-
- /* Loop over the new subscriptions. */
- next = subs_queue->q_forw;
- while (next != subs_queue) {
- sub = next;
- next = sub->q_forw;
+ sender = make_string(notice->z_sender, 0);
+ /* Loop over the new subscriptions. */
+ for (; subs; subs = next) {
+ next = subs->next;
#if 0
- zdbug ((LOG_DEBUG, "subscr: %s/%s/%s",
- sub->zst_dest.classname->string,
- sub->zst_dest.inst->string,
- sub->zst_dest.recip->string));
+ zdbug ((LOG_DEBUG, "subscr: %s/%s/%s", subs->dest.classname->string,
+ subs->dest.inst->string, subs->dest.recip->string));
#endif
-
- if (!bdumping) {
- if ((sub->zst_dest.recip != empty)
- && (sub->zst_dest.recip != sender)) {
- syslog(LOG_WARNING, "subscr unauth %s recipient %s",
- sender->string,
- sub->zst_dest.recip->string);
+ if (!bdumping) {
+ if (subs->dest.recip != empty && subs->dest.recip != sender
+ && subs->dest.recip->string[0] != '@') {
+ syslog(LOG_WARNING, "subscr unauth %s recipient %s",
+ sender->string, subs->dest.recip->string);
+ continue;
+ }
+ acl = class_get_acl(subs->dest.classname);
+ if (acl) {
+ if (!access_check(sender->string, acl, SUBSCRIBE)) {
+ syslog(LOG_WARNING, "subscr unauth %s class %s",
+ sender->string, subs->dest.classname->string);
+ continue; /* the for loop */
+ }
+ if (wildcard_instance == subs->dest.inst) {
+ if (!access_check(sender->string, acl, INSTWILD)) {
+ syslog(LOG_WARNING,
+ "subscr unauth %s class %s wild inst",
+ sender->string, subs->dest.classname->string);
continue;
}
- acl = class_get_acl(sub->zst_dest.classname);
- if (acl) {
- if (!(access_check(sender->string, acl, SUBSCRIBE))) {
- syslog(LOG_WARNING,
- "subscr unauth %s class %s",
- sender->string,
- sub->zst_dest.classname->string);
- continue; /* the for loop */
- }
- if (wildcard_instance == sub->zst_dest.inst) {
- if (!access_check(sender->string, acl, INSTWILD)) {
- syslog(LOG_WARNING,
- "subscr unauth %s class %s wild inst",
- notice->z_sender,
- sub->zst_dest.classname->string);
- continue;
- }
- }
- }
}
- xremque(sub);
- retval = triplet_register(who, &sub->zst_dest);
- if (retval != ZERR_NONE) {
- xfree(sub);
- if (retval == ZSRV_CLASSXISTS) {
- continue;
- } else {
- free_subscriptions(subs_queue);
- END_CRITICAL_CODE;
- return(retval);
- }
- }
- xinsque(sub, who->zct_subs);
+ }
}
+ /* 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)
+ realm = realm_get_realm_by_name(subs->dest.recip->string + 1);
+ if (realm) {
+ retval = subscr_realm_sendit(who, subs, notice, realm);
+ if (retval != ZERR_NONE) {
+ free(subs);
+ return(retval);
+ }
+ }
+ retval = triplet_register(who, &subs->dest, realm);
+ if (retval != ZERR_NONE) {
+ free(subs);
+ if (retval == ZSRV_CLASSXISTS) {
+ continue;
+ } else {
+ free_subscriptions(next);
+ return retval;
+ }
+ }
+ LIST_INSERT(&who->subs, subs);
+ }
- END_CRITICAL_CODE;
-
- free_subscriptions(subs_queue);
- return(ZERR_NONE);
+ return ZERR_NONE;
}
/*
@@ -232,126 +211,101 @@ add_subscriptions(who, subs_queue, notice)
Code_t
subscr_def_subs(who)
- ZClient_t *who;
+ Client *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;
- who->zct_subs = subs;
- }
+ Destlist *subs;
- subs = subscr_copy_def_subs(who->zct_principal->string);
- return(add_subscriptions(who, subs, &default_notice));
+ subs = subscr_copy_def_subs(who->principal->string);
+ return add_subscriptions(who, subs, &default_notice);
}
void
subscr_reset()
{
#if 0
- zdbug((LOG_DEBUG, "subscr_reset()"));
+ zdbug((LOG_DEBUG, "subscr_reset()"));
#endif
- xfree(default_notice.z_message);
- default_notice.z_message = NULL;
- defaults_read = 0;
+ free(default_notice.z_message);
+ default_notice.z_message = NULL;
+ defaults_read = 0;
}
-static ZSubscr_t *
+static Destlist *
subscr_copy_def_subs(person)
- char *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) {
+ int retval, fd;
+ struct stat statbuf;
+ char *def_sub_area, *cp;
+ Destlist *subs, *sub;
+
+ if (!defaults_read) {
#if 0
- zdbug((LOG_DEBUG, "reading default subscription file"));
+ 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);
- }
+ fd = open(subs_file, O_RDONLY, 0666);
+ if (fd < 0) {
+ syslog(LOG_ERR, "can't open %s:%m", subs_file);
+ return NULL;
+ }
+ retval = fstat(fd, &statbuf);
+ if (retval < 0) {
+ syslog(LOG_ERR, "fstat failure on %s:%m", subs_file);
+ close(fd);
+ return NULL;
+ }
+ def_sub_area = (char *) malloc(statbuf.st_size + 1);
+ if (!def_sub_area) {
+ syslog(LOG_ERR, "no mem copy_def_subs");
+ close(fd);
+ return NULL;
+ }
+ retval = read(fd, def_sub_area, (size_t) statbuf.st_size);
+ if (retval != statbuf.st_size) {
+ syslog(LOG_ERR, "short read in copy_def_subs");
+ close(fd);
+ return NULL;
+ }
+
+ 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
- (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;
+ 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';
}
- /* 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);
- }
+ default_notice.z_message = def_sub_area;
+ default_notice.z_message_len = 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 (sub = subs; sub; sub = sub->next) {
+ /* if not a wildcard, replace it with person */
+ if (strcmp(sub->dest.recip->string, "*")) {
+ free_string(sub->dest.recip);
+ sub->dest.recip = make_string(person, 0);
+ } else { /* replace with null recipient */
+ free_string(sub->dest.recip);
+ sub->dest.recip = dup_string(empty);
}
- return(subs);
+ }
+ return subs;
}
/*
@@ -360,161 +314,163 @@ subscr_copy_def_subs(person)
Code_t
subscr_cancel(sin, notice)
- struct sockaddr_in *sin;
- ZNotice_t *notice;
+ struct sockaddr_in *sin;
+ ZNotice_t *notice;
{
- ZClient_t *who;
- register ZSubscr_t *cancel_queue, *cancel, *sub;
- Code_t retval;
- int found = 0;
- int relation;
+ Realm *realm;
+ Client *who;
+ Destlist *cancel_subs, *subs, *cancel_next, *client_subs, *client_next;
+ Code_t retval;
+ int found = 0;
+ int relation;
#if 0
- zdbug((LOG_DEBUG,"subscr_cancel"));
+ zdbug((LOG_DEBUG,"subscr_cancel"));
#endif
- who = client_which_client(sin, notice);
- if (!who)
- return(ZSRV_NOCLT);
-
- if (!who->zct_subs)
- return(ZSRV_NOSUB);
-
- cancel_queue = extract_subscriptions(notice);
- if (!cancel_queue)
- return(ZERR_NONE); /* no subscr -> no error */
-
- START_CRITICAL_CODE;
-
- for (cancel = cancel_queue->q_forw; cancel != cancel_queue;
- cancel = cancel->q_forw) {
- for (sub = who->zct_subs->q_forw; sub != who->zct_subs;
- sub = sub->q_forw) {
- if (ZDest_eq(&cancel->zst_dest, &sub->zst_dest)) {
- xremque(sub);
- triplet_deregister(who, &sub->zst_dest);
- free_zstring(sub->zst_dest.classname);
- free_zstring(sub->zst_dest.inst);
- free_zstring(sub->zst_dest.recip);
- xfree(sub);
- found = 1;
- break;
+ who = client_which_client(&sin->sin_addr, notice);
+ if (!who)
+ return ZSRV_NOCLT;
+
+ if (!who->subs)
+ return ZSRV_NOSUB;
+
+ cancel_subs = extract_subscriptions(notice);
+ if (!cancel_subs)
+ return ZERR_NONE; /* no subscr -> no error */
+
+ for (subs = cancel_subs; subs; subs = cancel_next) {
+ cancel_next = subs->next;
+ for (client_subs = who->subs; client_subs; client_subs = client_next) {
+ client_next = client_subs->next;
+ if (ZDest_eq(&client_subs->dest, &subs->dest)) {
+ LIST_DELETE(client_subs);
+ triplet_deregister(who, &client_subs->dest, NULL);
+ if (retval == ZSRV_EMPTYCLASS &&
+ client_subs->dest.recip->string[0] == '@') {
+ realm =
+ realm_get_realm_by_name(client_subs->dest.recip->string
+ + 1);
+ if (realm)
+ subscr_unsub_sendit(client_subs, realm);
+ realm = NULL;
}
+ free_string(client_subs->dest.classname);
+ free_string(client_subs->dest.inst);
+ free_string(client_subs->dest.recip);
+ free(client_subs);
+ found = 1;
+ break;
}
}
+ }
- END_CRITICAL_CODE;
+ free_subscriptions(cancel_subs);
- free_subscriptions(cancel_queue);
- if (found) {
+ if (found) {
#if 0
- zdbug((LOG_DEBUG, "found & removed"));
+ zdbug((LOG_DEBUG, "found & removed"));
#endif
- return(ZERR_NONE);
- } else {
+ return ZERR_NONE;
+ } else {
#if 0
- zdbug((LOG_DEBUG, "not found"));
+ zdbug((LOG_DEBUG, "not found"));
#endif
- return(ZSRV_NOSUB);
- }
+ return ZSRV_NOSUB;
+ }
}
-/*
- * Cancel all the subscriptions for this client.
- */
-
-void
-subscr_cancel_client(client)
- ZClient_t *client;
+Code_t
+subscr_realm_cancel(sin, notice, realm)
+ struct sockaddr_in *sin;
+ ZNotice_t *notice;
+ Realm *realm;
{
- register ZSubscr_t *subs;
-
+ Client *who;
+ Destlist *cancel_subs, *subs, *client_subs, *next, *next2;
+ Code_t retval;
+ int found = 0;
+
+ if (!realm)
+ return ZSRV_NORLM;
+
+ if (!realm->subs)
+ return ZSRV_NOSUB;
+
+ cancel_subs = extract_subscriptions(notice);
+ if (!cancel_subs)
+ return ZERR_NONE; /* no subscr -> no error */
+
+ for (subs = cancel_subs; subs; subs = next) {
+ next = subs->next;
+ for (client_subs = realm->subs; client_subs; client_subs = next2) {
+ next2 = client_subs->next;
+ if (ZDest_eq(&client_subs->dest, &subs->dest)) {
+ LIST_DELETE(client_subs);
+ retval = triplet_deregister(realm->client, &client_subs->dest, realm);
+ free_string(client_subs->dest.classname);
+ free_string(client_subs->dest.inst);
+ free_string(client_subs->dest.recip);
+ free(client_subs);
+ found = 1;
+ break;
+ }
+ }
+ }
+
+ free_subscriptions(cancel_subs);
+
+ if (found) {
#if 0
- zdbug((LOG_DEBUG,"subscr_cancel_client %s",
- inet_ntoa (client->zct_addr.sin_addr)));
+ zdbug((LOG_DEBUG, "found & removed"));
#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) {
+ return ZERR_NONE;
+ } else {
#if 0
- zdbug((LOG_DEBUG,"sub_can %s",
- subs->zst_dest.classname->string));
+ zdbug((LOG_DEBUG, "not found"));
#endif
- if (triplet_deregister(client, &subs->zst_dest) != 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;
+ return ZSRV_NOSUB;
+ }
}
-#ifdef notdef
-/* not used for the moment */
/*
- * Cancel all the subscriptions for clients at this addr.
+ * Cancel all the subscriptions for this client.
*/
-Code_t
-subscr_cancel_host(addr)
-struct in_addr *addr;
+void
+subscr_cancel_client(client)
+ Client *client;
{
- 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);
+ Destlist *subs, *next;
+ Code_t retval;
+ Realm *realm;
- END_CRITICAL_CODE;
-
- return(ZERR_NONE);
-}
+#if 0
+ zdbug((LOG_DEBUG,"subscr_cancel_client %s",
+ inet_ntoa(client->addr.sin_addr)));
#endif
+ if (!client->subs)
+ return;
-/*
- * 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);
+ for (subs = client->subs; subs; subs = next) {
+ next = subs->next;
+#if 0
+ zdbug((LOG_DEBUG,"sub_can %s", subs->dest.classname->string));
+#endif
+ retval = triplet_deregister(client, &subs->dest, NULL);
+ if (retval == ZSRV_EMPTYCLASS &&
+ subs->dest.recip->string[0] == '@') {
+ realm = realm_get_realm_by_name(subs->dest.recip->string + 1);
+ if (realm)
+ subscr_unsub_sendit(subs, realm);
+ realm = NULL;
}
- xfree(list);
- return;
+ free_string(subs->dest.classname);
+ free_string(subs->dest.inst);
+ free_string(subs->dest.recip);
+ free(subs);
+ }
+
+ client->subs = NULL;
}
/*
@@ -523,359 +479,349 @@ subscr_free_list(list)
void
subscr_sendlist(notice, auth, who)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *who;
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
{
- char **answer;
- int found;
- struct sockaddr_in send_to_who;
- Code_t retval;
+ 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;
- }
+ 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)) {
- /* we are talking to a new old client; use the new-old-style
- acknowledgement-message */
- new_old_compat_subscr_sendlist(notice, auth, who);
- return;
- }
+ 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 */
-
- if ((retval = ZSetDestAddr(&send_to_who)) != ZERR_NONE) {
- syslog(LOG_WARNING, "subscr_sendlist set addr: %s",
- error_message(retval));
- if (answer)
- xfree(answer);
- return;
- }
+ answer = subscr_marshal_subs(notice, auth, who, &found);
+ 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, "subscr_sendlist set addr: %s",
+ error_message(retval));
+ if (answer)
+ free(answer);
+ return;
+ }
- /* XXX for now, don't do authentication */
- auth = 0;
+ /* XXX for now, don't do authentication */
+ auth = 0;
- notice->z_kind = ACKED;
+ notice->z_kind = ACKED;
- /* use xmit_frag() to send each piece of the notice */
+ /* 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;
+ 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;
- register int *found;
+ ZNotice_t *notice;
+ int auth;
+ struct sockaddr_in *who;
+ 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;
+ ZNotice_t reply;
+ 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"));
+ zdbug((LOG_DEBUG, "subscr_marshal"));
#endif
- *found = 0;
+ *found = 0;
- /* Note that the following code is an incredible crock! */
+ /* 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. */
+ /* 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 */
-
+ /* 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);
- }
+ if (strcmp(notice->z_opcode, CLIENT_GIMMESUBS) == 0) {
+ /* 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. */
- /* 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);
+ retval = ZReadAscii16(notice->z_message, notice->z_message_len, &temp);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_marshal read port num: %s",
+ error_message(retval));
+ return(NULL);
}
- if (subs2) {
+ reply = *notice;
+ reply.z_port = htons(temp);
- /* 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. */
+ client = client_which_client(&who->sin_addr, &reply);
- if (!auth && !defsubs) {
- return((char **) 0);
- }
- if (!defsubs) {
- if (client && (strcmp(client->zct_principal->string,
- notice->z_sender) != 0)) {
- zdbug ((LOG_DEBUG,
+ if (client)
+ subs = client->subs;
+ } else if (strcmp(notice->z_opcode, CLIENT_GIMMEDEFS) == 0) {
+#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.*/
+ subs = subscr_copy_def_subs(notice->z_sender);
+ defsubs = 1;
+ } else {
+ syslog(LOG_ERR, "subscr_marshal bogus opcode %s",
+ notice->z_opcode);
+ return(NULL);
+ }
+
+ if (subs) {
+
+ /* 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->zct_principal->string,
- inet_ntoa (who->sin_addr),
- ntohs (who->sin_port)));
- return 0;
- }
- }
+ 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)++;
- 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;
- }
+ /* 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 == 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++;
+ }
}
- if (defsubs)
- free_subscriptions(subs2);
- return(answer);
+ }
+ if (defsubs)
+ free_subscriptions(subs);
+ return answer;
}
#ifdef NEW_COMPAT
static void
new_old_compat_subscr_sendlist(notice, auth, who)
- ZNotice_t *notice;
- int auth;
- struct sockaddr_in *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;
- }
+ 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;
+ 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);
+ /* 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 */
+ /* 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 */
+ /* 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));
+ 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;
+ 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_sendlist acked"));
#endif
- if (answer)
- xfree(answer);
- return;
+ 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;
+ 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;
- }
+ Client *client = client_which_client(&who->sin_addr, notice);
+ Destlist *subs;
+ Code_t retval;
+ ZNotice_t reply;
+ ZPacket_t reppacket;
+ int packlen, i, found = 0;
+ char **answer = NULL;
+
+ old_compat_count_subscr++;
+
+ syslog(LOG_INFO, "old old subscr, %s", inet_ntoa(who->sin_addr));
+ if (client && client->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;
}
- /* 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;
+ for (subs = client->subs; subs; subs = subs->next)
+ found++;
+ /* 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++;
+ }
}
-#if 0
- zdbug((LOG_DEBUG,"subscr_sendlist acked"));
-#endif
+ }
+
+ /* 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);
+ 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);
}
#endif /* OLD_COMPAT */
@@ -888,99 +834,89 @@ old_compat_subscr_sendlist(notice, auth, who)
/*ARGSUSED*/
Code_t
-subscr_send_subs(client, vers)
- ZClient_t *client;
- char *vers;
+subscr_send_subs(client)
+ Client *client;
{
- 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;
+ int i = 0;
+ Destlist *subs;
+#ifdef ZEPHYR_USES_KERBEROS
+ char buf[512];
+ C_Block cblock;
+#endif /* ZEPHYR_USES_KERBEROS */
+ char buf2[512];
+ char *list[7 * NUM_FIELDS];
+ int num = 0;
+ Code_t retval;
#if 0
- zdbug((LOG_DEBUG, "send_subs"));
+ zdbug((LOG_DEBUG, "send_subs"));
#endif
- (void) sprintf(buf2, "%d",ntohs(client->zct_sin.sin_port));
+ sprintf(buf2, "%d",ntohs(client->addr.sin_port));
- lyst[num++] = buf2;
+ list[num++] = buf2;
-#ifdef KERBEROS
+#ifdef ZEPHYR_USES_KERBEROS
#ifdef NOENCRYPTION
- (void) memcpy((caddr_t)cblock, (caddr_t)client->zct_cblock, sizeof(C_Block));
+ memcpy(cblock, client->session_key, sizeof(C_Block));
#else
- des_ecb_encrypt(client->zct_cblock, cblock, serv_ksched.s, DES_ENCRYPT);
+ des_ecb_encrypt(client->session_key, cblock, serv_ksched.s, DES_ENCRYPT);
#endif
- if ((retval = ZMakeAscii(buf, sizeof(buf), cblock,
- sizeof(C_Block))) != ZERR_NONE) {
+ retval = ZMakeAscii(buf, sizeof(buf), cblock, sizeof(C_Block));
+ if (retval != ZERR_NONE) {
#if 0
- zdbug((LOG_DEBUG,"zmakeascii failed: %s",
- error_message(retval)));
+ zdbug((LOG_DEBUG,"zmakeascii failed: %s", error_message(retval)));
#endif
- } else {
- lyst[num++] = buf;
+ } else {
+ list[num++] = buf;
#if 0
- zdbug((LOG_DEBUG,"cblock %s",buf));
+ 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",
+ }
+#endif /* ZEPHYR_USES_KERBEROS */
+ retval = bdump_send_list_tcp(SERVACK, &client->addr, ZEPHYR_ADMIN_CLASS,
+ num > 1 ? "CBLOCK" : "", ADMIN_NEWCLT,
+ client->principal->string, "", list, num);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "subscr_send_subs newclt: %s", error_message(retval));
+ return retval;
+ }
+
+ if (!client->subs)
+ return ZERR_NONE;
+
+ for (subs = client->subs; subs; subs = subs->next) {
+ /* for each subscription */
+ list[i * NUM_FIELDS] = subs->dest.classname->string;
+ list[i * NUM_FIELDS + 1] = subs->dest.inst->string;
+ list[i * NUM_FIELDS + 2] = subs->dest.recip->string;
+ i++;
+ if (i >= 7) {
+ /* we only put 7 in each packet, so we don't run out of room */
+ retval = bdump_send_list_tcp(ACKED, &client->addr,
+ ZEPHYR_CTL_CLASS, "",
+ CLIENT_SUBSCRIBE, "", "", list,
+ i * NUM_FIELDS);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "subscr_send_subs subs: %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;
- }
+ 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);
- }
+ }
+ if (i) {
+ retval = bdump_send_list_tcp(ACKED, &client->addr, ZEPHYR_CTL_CLASS,
+ "", CLIENT_SUBSCRIBE, "", "", list,
+ i * NUM_FIELDS);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "subscr_send_subs subs: %s",
+ error_message(retval));
+ return retval;
}
- return(ZERR_NONE);
+ }
+
+ return ZERR_NONE;
}
/*
@@ -989,85 +925,72 @@ subscr_send_subs(client, vers)
static void
free_subscriptions(subs)
- register ZSubscr_t *subs;
+ Destlist *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;
+ Destlist *next;
+
+ for (; subs; subs = next) {
+ next = subs->next;
+ free_string(subs->dest.classname);
+ free_string(subs->dest.inst);
+ free_string(subs->dest.recip);
+ free(subs);
+ }
}
#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); \
+ 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.
+ * NULL if there are no subscriptions there.
*/
-static ZSubscr_t *
+static Destlist *
extract_subscriptions(notice)
- register ZNotice_t *notice;
+ 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;
+ Destlist *subs = NULL, *sub;
+ char *recip, *class_name, *classinst;
+ 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));
+ 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;
- }
- 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);
-
- xinsque(subs2, subs);
+ cp += (strlen(cp) + 1);
+ if (cp > notice->z_message + notice->z_message_len) {
+ syslog(LOG_WARNING, "malformed sub 3");
+ return subs;
+ }
+ sub = (Destlist *) malloc(sizeof(Destlist));
+ if (!sub) {
+ syslog(LOG_WARNING, "ex_subs: no mem 2");
+ return subs;
}
- return(subs);
+ 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()))
+ sub->dest.recip = make_string("", 0);
+ else
+ sub->dest.recip = make_string(recip, 0);
+ LIST_INSERT(&subs, sub);
+ }
+ return subs;
}
/*
@@ -1078,24 +1001,538 @@ extract_subscriptions(notice)
void
subscr_dump_subs(fp, subs)
- FILE *fp;
- ZSubscr_t *subs;
+ FILE *fp;
+ Destlist *subs;
{
- register ZSubscr_t *ptr;
- register char *p;
+ char *p;
- if (!subs) /* no subscriptions to dump */
- return;
-
- for (ptr = subs->q_forw; ptr != subs; ptr = ptr->q_forw) {
- fputs("\t\t'", fp);
- subscr_quote(ptr->zst_dest.classname->string, fp);
- fputs("' '", fp);
- subscr_quote(ptr->zst_dest.inst->string, fp);
- fputs("' '", fp);
- subscr_quote(ptr->zst_dest.recip->string, fp);
- fputs("'\n", fp);
- }
+ if (!subs) /* no subscriptions to dump */
return;
+
+ for (; subs; subs = subs->next) {
+ fputs("\t\t'", fp);
+ dump_quote(subs->dest.classname->string, fp);
+ fputs("' '", fp);
+ dump_quote(subs->dest.inst->string, fp);
+ fputs("' '", fp);
+ dump_quote(subs->dest.recip->string, fp);
+ fputs("'\n", fp);
+ }
+}
+
+#define I_ADVANCE(xx) { cp += (strlen(cp) + 1); \
+ if (cp >= notice->z_message + notice->z_message_len) { \
+ syslog(LOG_WARNING, "malformed subscription %d", \
+ xx); \
+ return (ZERR_NONE); \
+ }}
+
+/* As it exists, this function expects to take only the first sub from the
+ * Destlist. At some point, it and the calling code should be replaced */
+static Code_t
+subscr_realm_sendit(who, subs, notice, realm)
+ Client *who;
+ Destlist *subs;
+ ZNotice_t *notice;
+ Realm *realm;
+{
+#if 0
+ Destlist *subs2;
+#endif
+ ZNotice_t snotice;
+ char *pack;
+ int packlen;
+ int found = 0, i;
+ char **text;
+ Code_t retval;
+ char addr[16]; /* xxx.xxx.xxx.xxx max */
+ char port[16];
+
+#if 0
+ zdbug((LOG_DEBUG, "subscr_rlm_sendit"));
+#endif
+
+
+#ifdef notdef
+ for (subs2 = subs; subs2; subs2 = subs2->next, found++);
+ /* found is now the number of subscriptions */
+
+ /* coalesce the subscription information into a list of char *'s */
+ /* one extra for client information */
+ if ((text = (char **) malloc((found * NUM_FIELDS + 2)
+ * sizeof(char *))) == (char **) 0)
+ {
+ syslog(LOG_ERR, "subscr_rlm_sendit malloc");
+ return(ENOMEM);
+ }
+#endif /* notdef */
+
+ if ((text=(char **)malloc((NUM_FIELDS + 2)*sizeof(char *))) == (char **)0) {
+ syslog(LOG_ERR, "subscr_rlm_sendit malloc");
+ return(ENOMEM);
+ }
+ /* convert the address to a string of the form x.x.x.x/port */
+ strcpy(addr, inet_ntoa(notice->z_sender_addr));
+ if ((retval = ZMakeAscii(port, sizeof(port), (unsigned char *)
+ &notice->z_port, sizeof(u_short))) != ZERR_NONE)
+ {
+ syslog(LOG_ERR, "subscr_rlm_sendit make ascii: %s",
+ error_message(retval));
+ return(ZERR_NONE);
+ }
+ text[0] = addr;
+ text[1] = port;
+
+#ifdef notdef
+ for (i = 0, subs2 = subs; subs2, i < found ; i++, subs2 = subs2->next) {
+ text[i*NUM_FIELDS + 2] = subs2->dest.classname->string;
+ text[i*NUM_FIELDS + 3] = subs2->dest.inst->string;
+ text[i*NUM_FIELDS + 4] = subs2->dest.recip->string;
+ }
+#endif /* notdef */
+
+ text[2] = subs->dest.classname->string;
+ text[3] = subs->dest.inst->string;
+ text[4] = subs->dest.recip->string;
+
+ /* format snotice */
+ snotice.z_class_inst = ZEPHYR_CTL_REALM;
+ snotice.z_opcode = REALM_REQ_SUBSCRIBE;
+ snotice.z_port = srv_addr.sin_port;
+
+ snotice.z_class = ZEPHYR_CTL_CLASS;
+
+ snotice.z_recipient = "";
+ snotice.z_kind = ACKED;
+ snotice.z_num_other_fields = 0;
+ snotice.z_default_format = "";
+ snotice.z_sender = notice->z_sender;
+ snotice.z_recipient = notice->z_recipient;
+ snotice.z_default_format = notice->z_default_format;
+
+#ifdef notdef
+ if ((retval = ZFormatNoticeList(&snotice, text, found * NUM_FIELDS + 2,
+ &pack, &packlen, ZNOAUTH)) != ZERR_NONE)
+#else
+ if ((retval = ZFormatNoticeList(&snotice, text, NUM_FIELDS + 2,
+ &pack, &packlen, ZNOAUTH)) != ZERR_NONE)
+#endif
+ {
+ syslog(LOG_WARNING, "subscr_rlm_sendit format: %s",
+ error_message(retval));
+ free(text);
+ return(ZERR_NONE);
+ }
+ free(text);
+
+ if ((retval = ZParseNotice(pack, packlen, &snotice)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_rlm_sendit parse: %s",
+ error_message(retval));
+ free(pack);
+ return(ZERR_NONE);
+ }
+
+#if 0
+ zdbug((LOG_DEBUG,"subscr_rlm_sendit len: %d", snotice.z_message_len));
+#endif
+ realm_handoff(&snotice, 1, &(who->addr), realm, 0);
+ free(pack);
+
+ return(ZERR_NONE);
+}
+
+static Code_t
+subscr_add_raw(client, realm, newsubs)
+ Client *client;
+ Realm *realm;
+ Destlist *newsubs;
+{
+ Destlist *subs, *subs2, *subs3, **head;
+ Code_t retval;
+
+#if 0
+ zdbug((LOG_DEBUG, "subscr_add_raw"));
+#endif
+ head = (realm) ? &realm->subs : &client->subs;
+
+ /* Loop over the new subscriptions. */
+ for (subs = newsubs; subs; subs = subs2) {
+ subs2 = subs->next;
+#ifdef DEBUG
+ zdbug((LOG_DEBUG,"subscr_add_raw: %s/%s/%s", subs->dest.classname->string, subs->dest.inst->string, subs->dest.recip->string));
+ if (realm)
+ zdbug((LOG_DEBUG,"subscr_add_raw: realm is %s", realm->name));
+#endif
+ retval = triplet_register(client, &subs->dest, realm);
+ if (retval != ZERR_NONE) {
+ free(subs);
+ if (retval == ZSRV_CLASSXISTS) {
+ continue;
+ } else {
+ free_subscriptions(subs2);
+ return retval;
+ }
+ }
+ LIST_INSERT(head, subs);
+ }
+ return ZERR_NONE;
+}
+
+Code_t
+subscr_realm(realm, notice)
+ Realm *realm;
+ ZNotice_t *notice;
+{
+ Destlist *newsubs;
+
+ newsubs = extract_subscriptions(notice);
+
+ if (!newsubs) {
+ syslog(LOG_WARNING, "empty subs in subscr_realm");
+ return(ZERR_NONE);
+ }
+
+ return(subscr_add_raw(realm->client, realm, newsubs));
+}
+
+/* Like realm_sendit, this only takes one item from subs */
+static void
+subscr_unsub_sendit(subs, realm)
+ Destlist *subs;
+ Realm *realm;
+{
+ ZNotice_t unotice;
+ Code_t retval;
+#ifdef notdef
+ char *list[7 * NUM_FIELDS];
+#else /* notdef */
+ char *list[NUM_FIELDS];
+#endif /* notdef */
+ char *pack;
+ int packlen;
+ int found = 0;
+ Destlist *subs2;
+
+ unotice.z_class = ZEPHYR_CTL_CLASS;
+ unotice.z_class_inst = ZEPHYR_CTL_REALM;
+ unotice.z_opcode = REALM_UNSUBSCRIBE;
+ unotice.z_recipient = "";
+ unotice.z_kind = ACKED;
+
+ unotice.z_sender = "";
+ unotice.z_port = srv_addr.sin_port;
+ unotice.z_num_other_fields = 0;
+ unotice.z_default_format = "";
+
+#ifdef notdef
+ found = 0;
+ for (subs2 = subs; subs2; subs2 = subs2->next) {
+ list[found * NUM_FIELDS] = subs2->dest.classname->string;
+ list[found * NUM_FIELDS + 1] = subs2->dest.inst->string;
+ list[found * NUM_FIELDS + 2] = "";
+
+ found++;
+
+ if (found >= 7) {
+ if ((retval = ZFormatNoticeList(&unotice, list, found * NUM_FIELDS, &pack, &packlen, ZNOAUTH)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_unsub_sendit format: %s",
+ error_message(retval));
+ return;
+ }
+ if ((retval = ZParseNotice(pack, packlen, &unotice)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_unsub_sendit parse: %s",
+ error_message(retval));
+ free(pack);
+ return;
+ }
+ free(pack);
+ realm_handoff(&unotice, 1, (struct sockaddr_in *) 0, realm, 0);
+ found = 0;
+ }
+ }
+
+ if (found == 0)
+ return;
+
+ if ((retval = ZFormatNoticeList(&unotice, list, found * NUM_FIELDS, &pack, &packlen, ZNOAUTH)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_unsub_sendit format: %s",
+ error_message(retval));
+ return;
+ }
+#else /* notdef */
+ list[0] = subs->dest.classname->string;
+ list[1] = subs->dest.inst->string;
+ list[2] = "";
+
+ if ((retval = ZFormatNoticeList(&unotice, list, NUM_FIELDS, &pack, &packlen, ZNOAUTH)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_unsub_sendit format: %s",
+ error_message(retval));
+ return;
+ }
+#endif /* notdef */
+
+ if ((retval = ZParseNotice(pack, packlen, &unotice)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_unsub_sendit parse: %s",
+ error_message(retval));
+ free(pack);
+ return;
+ }
+ free(pack);
+ realm_handoff(&unotice, 1, (struct sockaddr_in *) 0, realm, 0);
+}
+
+Code_t
+subscr_send_realm_subs(realm)
+ Realm *realm;
+{
+ int i = 0;
+ Destlist *subs, *next;
+ char buf[512];
+ char *list[7 * NUM_FIELDS];
+ int num = 0;
+ Code_t retval;
+
+#if 0
+ zdbug((LOG_DEBUG, "send_realm_subs"));
+#endif
+
+ strcpy(buf, realm->name);
+ list[num++] = buf;
+
+ retval = bdump_send_list_tcp(SERVACK, &srv_addr, ZEPHYR_ADMIN_CLASS,
+ "", ADMIN_NEWREALM, "", "", list, num);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "subscr_send_realm_subs newclt: %s", error_message(retval));
+ return retval;
+ }
+
+ if (!realm->subs)
+ return ZERR_NONE;
+
+ for (subs=realm->subs; subs; subs = next) {
+ next = subs->next;
+#ifdef DEBUG
+ zdbug ((LOG_DEBUG, "send_realm_subs: %s/%s/%s", subs->dest.classname->string,
+ subs->dest.inst->string, subs->dest.recip->string));
+#endif
+ /* for each subscription */
+ list[i * NUM_FIELDS] = subs->dest.classname->string;
+ list[i * NUM_FIELDS + 1] = subs->dest.inst->string;
+ list[i * NUM_FIELDS + 2] = subs->dest.recip->string;
+ i++;
+ if (i >= 7) {
+ /* we only put 7 in each packet, so we don't run out of room */
+ retval = bdump_send_list_tcp(ACKED, &srv_addr,
+ ZEPHYR_CTL_CLASS, "",
+ REALM_SUBSCRIBE, "", "", list,
+ i * NUM_FIELDS);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "subscr_send_realm_subs subs: %s",
+ error_message(retval));
+ return retval;
+ }
+ i = 0;
+ }
+ }
+ if (i) {
+ retval = bdump_send_list_tcp(ACKED, &srv_addr, ZEPHYR_CTL_CLASS,
+ "", REALM_SUBSCRIBE, "", "", list,
+ i * NUM_FIELDS);
+ if (retval != ZERR_NONE) {
+ syslog(LOG_ERR, "subscr_send_realm_subs subs: %s",
+ error_message(retval));
+ return retval;
+ }
+ }
+
+ return ZERR_NONE;
+}
+
+static Code_t
+subscr_check_foreign_subs(notice, who, realm, newsubs)
+ ZNotice_t *notice;
+ struct sockaddr_in *who;
+ Realm *realm;
+ Destlist *newsubs;
+{
+ Destlist *subs, *subs2, *next;
+ Acl *acl;
+ char **text;
+ int found = 0;
+ ZNotice_t snotice;
+ char *pack, *cp;
+ int packlen;
+ Code_t retval;
+ String *sender;
+
+ for (subs = newsubs; subs; subs = subs->next)
+ found++;
+
+ if (found == 0)
+ return(ZERR_NONE);
+
+ sender = make_string(notice->z_sender, 0);
+
+ if ((text = (char **)malloc((found * NUM_FIELDS + 2) * sizeof(char *))) == (char **) 0) {
+ syslog(LOG_ERR, "subscr_ck_forn_subs no mem(text)");
+ return(ENOMEM);
+ }
+
+ /* grab the client information from the incoming message */
+ cp = notice->z_message;
+ text[0] = cp;
+
+ I_ADVANCE(2);
+ text[1] = cp;
+
+ I_ADVANCE(3);
+
+ found = 0;
+ for (subs = newsubs; subs; subs = next) {
+ next=subs->next;
+ acl = class_get_acl(subs->dest.classname);
+ if (acl) {
+ if (!access_check(sender->string, acl, SUBSCRIBE)) {
+ syslog(LOG_WARNING, "subscr unauth %s class %s",
+ sender->string, subs->dest.classname->string);
+ continue; /* the for loop */
+ }
+ if (wildcard_instance == subs->dest.inst) {
+ if (!access_check(sender->string, acl, INSTWILD)) {
+ syslog(LOG_WARNING,
+ "subscr unauth %s class %s wild inst",
+ sender->string, subs->dest.classname->string);
+ continue;
+ }
+ }
+ }
+
+ /* okay to subscribe. save for return trip */
+ text[found*NUM_FIELDS + 2] = subs->dest.classname->string;
+ text[found*NUM_FIELDS + 3] = subs->dest.inst->string;
+ text[found*NUM_FIELDS + 4] = "";
+ found++;
+
+ retval = triplet_register(realm->client, &subs->dest, realm);
+#ifdef DEBUG
+ zdbug ((LOG_DEBUG, "ck_frn_subs: %s/%s/%s", subs->dest.classname->string,
+ subs->dest.inst->string, subs->dest.recip->string));
+#endif
+
+ if (retval != ZERR_NONE) {
+ if (retval == ZSRV_CLASSXISTS) {
+ continue;
+ } else {
+ free_subscriptions(subs->next);
+ free(text);
+ return retval;
+ }
+ }
+ LIST_INSERT(&realm->subs, subs);
+ }
+ /* don't send confirmation if we're not the initial server contacted */
+ if (!(server_which_server(who) || found == 0)) {
+ snotice = *notice;
+ snotice.z_opcode = REALM_ADD_SUBSCRIBE;
+ snotice.z_class_inst = ZEPHYR_CTL_REALM;
+ snotice.z_port = srv_addr.sin_port;
+ if ((retval = ZFormatNoticeList(&snotice, text, found * NUM_FIELDS + 2, &pack, &packlen, ZNOAUTH)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_ck_forn_subs format: %s",
+ error_message(retval));
+ free(text);
+ return(ZERR_NONE);
+ }
+ if ((retval = ZParseNotice(pack, packlen, &snotice)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_ck_forn_subs parse: %s",
+ error_message(retval));
+ free(text);
+ free(pack);
+ return(ZERR_NONE);
+ }
+ realm_handoff(&snotice, 1, who, realm, 0);
+ free(pack);
+ }
+ free(text);
+ return ZERR_NONE;
+}
+
+Code_t subscr_foreign_user(notice, who, realm)
+ ZNotice_t *notice;
+ struct sockaddr_in *who;
+ Realm *realm;
+{
+ Destlist *newsubs, *temp;
+ Acl *acl;
+ Code_t status;
+ Client *client;
+ ZNotice_t snotice;
+ struct sockaddr_in newwho;
+ char *cp;
+ char rlm_recipient[REALM_SZ + 1];
+
+#if 0
+ zdbug((LOG_DEBUG, "subscr_foreign_user"));
+#endif
+
+ cp = notice->z_message;
+
+ newwho.sin_addr.s_addr = inet_addr(cp);
+ if (newwho.sin_addr.s_addr == -1) {
+ syslog(LOG_ERR, "malformed addr from %s, notice->z_sender");
+ return(ZERR_NONE);
+ }
+
+ I_ADVANCE(0);
+
+ snotice = *notice;
+
+ if ((status = ZReadAscii(cp, strlen(cp), (unsigned char *)&snotice.z_port, sizeof(u_short)))
+ != ZERR_NONE)
+ {
+ syslog(LOG_ERR, "subscr_foreign_user read ascii: %s",
+ error_message(status));
+ return(ZERR_NONE);
+ }
+
+ I_ADVANCE(1);
+
+ snotice.z_message = cp;
+ snotice.z_message_len = notice->z_message_len - (cp - notice->z_message);
+
+ newsubs = extract_subscriptions(&snotice);
+ if (!newsubs) {
+ syslog(LOG_WARNING, "empty subscr for %s", notice->z_sender);
+ return(ZERR_NONE);
+ }
+
+ if (!strcmp(snotice.z_opcode, REALM_ADD_SUBSCRIBE)) {
+ /* this was approved by the other realm, add subscriptions */
+
+ client = client_which_client(&newwho.sin_addr, &snotice);
+ if (client == (Client *)0) {
+ syslog(LOG_WARNING, "no client at %s/%d",
+ inet_ntoa(newwho.sin_addr), ntohs(snotice.z_port));
+ free_subscriptions(newsubs);
+ return(ZERR_NONE);
+ }
+
+ /* translate the recipient to represent the foreign realm */
+ sprintf(rlm_recipient, "@%s", realm->name);
+ for (temp = newsubs; temp; temp = temp->next) {
+#if 0
+ syslog(LOG_DEBUG, "in foreign_user: class is %s", temp->dest.classname->string);
+#endif
+ temp->dest.recip = make_string(rlm_recipient, 0);
+ }
+
+ status = subscr_add_raw(client, (Realm *)0, newsubs);
+ } else if (!strcmp(snotice.z_opcode, REALM_REQ_SUBSCRIBE)) {
+ status = subscr_check_foreign_subs(notice, who, realm, newsubs);
+ } else {
+ syslog(LOG_ERR, "bogus opcode %s in subscr_forn_user",
+ snotice.z_opcode);
+ status = ZERR_NONE;
+ }
+ return(status);
}