1 /* This file is part of the Project Athena Zephyr Notification System.
2 * It contains source for the ZRetrieveSubscriptions and
3 * ZRetrieveDefaultSubscriptions functions.
5 * Created by: Robert French
7 * $Id: ZRetSubs.c,v 1.26 1999/01/22 23:19:23 ghudson Exp $
9 * Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology.
10 * For copying and distribution information, see the file
17 static const char rcsid_ZRetrieveSubscriptions_c[] =
18 "$Id: ZRetSubs.c,v 1.26 1999/01/22 23:19:23 ghudson Exp $";
21 static Code_t Z_RetSubs ();
23 /* Need STDC definition when possible for unsigned short argument. */
25 Code_t ZRetrieveSubscriptions(char *galaxy,
26 unsigned short port, int *nsubs)
28 Code_t ZRetrieveSubscriptions(galaxy,port,nsubs)
38 if (!port) /* use default port */
41 retval = ZMakeAscii16(asciiport, sizeof(asciiport), ntohs(port));
42 if (retval != ZERR_NONE)
45 (void) memset((char *)¬ice, 0, sizeof(notice));
46 notice.z_message = asciiport;
47 notice.z_message_len = strlen(asciiport)+1;
48 notice.z_opcode = CLIENT_GIMMESUBS;
49 notice.z_dest_galaxy = galaxy;
51 return(Z_RetSubs(¬ice, nsubs, ZAUTH));
54 Code_t ZRetrieveDefaultSubscriptions(galaxy, nsubs)
60 (void) memset((char *)¬ice, 0, sizeof(notice));
61 notice.z_message = (char *) 0;
62 notice.z_message_len = 0;
63 notice.z_opcode = CLIENT_GIMMEDEFS;
64 notice.z_dest_galaxy = galaxy;
66 return(Z_RetSubs(¬ice, nsubs, ZNOAUTH));
70 static Code_t Z_RetSubs(notice, nsubs, auth_routine)
71 register ZNotice_t *notice;
73 Z_AuthProc auth_routine;
76 int retval,nrecv,gimmeack;
79 ZSubscription_t *list = __subscriptions_list;
81 retval = ZFlushSubscriptions();
83 if (retval != ZERR_NONE && retval != ZERR_NOSUBSCRIPTIONS)
87 if ((retval = ZOpenPort((u_short *)0)) != ZERR_NONE)
90 notice->z_kind = ACKED;
91 notice->z_port = __Zephyr_port;
92 notice->z_class = ZEPHYR_CTL_CLASS;
93 notice->z_class_inst = ZEPHYR_CTL_CLIENT;
95 notice->z_recipient = "";
96 notice->z_default_format = "";
98 if ((retval = ZSendNotice(notice,auth_routine)) != ZERR_NONE)
103 list = (ZSubscription_t *) 0;
105 while (!nrecv || !gimmeack) {
106 retval = Z_WaitForNotice (&retnotice, ZCompareMultiUIDPred,
107 ¬ice->z_multiuid, SRV_TIMEOUT);
108 if (retval == ZERR_NONOTICE)
110 else if (retval != ZERR_NONE)
113 if (retnotice.z_kind == SERVNAK) {
114 ZFreeNotice(&retnotice);
115 return (ZERR_SERVNAK);
117 /* non-matching protocol version numbers means the
118 server is probably an older version--must punt */
119 if (strcmp(notice->z_version,retnotice.z_version)) {
120 ZFreeNotice(&retnotice);
123 if (retnotice.z_kind == SERVACK &&
124 !strcmp(retnotice.z_opcode,notice->z_opcode)) {
125 ZFreeNotice(&retnotice);
130 if (retnotice.z_kind != ACKED) {
131 ZFreeNotice(&retnotice);
132 return (ZERR_INTERNAL);
137 end = retnotice.z_message+retnotice.z_message_len;
139 __subscriptions_num = 0;
140 for (ptr=retnotice.z_message;ptr<end;ptr++)
142 __subscriptions_num++;
144 __subscriptions_num = __subscriptions_num / 3;
146 list = (ZSubscription_t *)
147 malloc(__subscriptions_num * sizeof(ZSubscription_t));
148 if (__subscriptions_num && !list) {
149 ZFreeNotice(&retnotice);
153 ptr = retnotice.z_message;
154 for (i = 0; i < __subscriptions_num; i++) {
155 list[i].zsub_class = (char *)
156 malloc(strlen(ptr) + 1);
157 if (!list[i].zsub_class) {
158 ZFreeNotice(&retnotice);
161 strcpy(list[i].zsub_class, ptr);
162 ptr += strlen(ptr)+1;
163 list[i].zsub_classinst = (char *)
164 malloc(strlen(ptr) + 1);
165 if (!list[i].zsub_classinst) {
166 ZFreeNotice(&retnotice);
169 strcpy(list[i].zsub_classinst, ptr);
170 ptr += strlen(ptr)+1;
172 list[i].zsub_recipient = (char *)
173 malloc(strlen(ptr2) + 2);
174 if (!list[i].zsub_recipient) {
175 ZFreeNotice(&retnotice);
178 if (*ptr2 == '@' || *ptr2 == 0) {
179 *list[i].zsub_recipient = '*';
180 strcpy(list[i].zsub_recipient + 1, ptr2);
182 strcpy(list[i].zsub_recipient, ptr2);
184 ptr += strlen(ptr)+1;
186 ZFreeNotice(&retnotice);
189 __subscriptions_list = list;
190 __subscriptions_next = 0;
191 *nsubs = __subscriptions_num;