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
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[] =
21 static Code_t Z_RetSubs (register ZNotice_t *, int *, Z_AuthProc);
23 /* Need STDC definition when possible for unsigned short argument. */
25 ZRetrieveSubscriptions(unsigned short port,
32 if (!port) /* use default port */
35 retval = ZMakeAscii16(asciiport, sizeof(asciiport), ntohs(port));
36 if (retval != ZERR_NONE)
39 (void) memset((char *)¬ice, 0, sizeof(notice));
40 notice.z_message = asciiport;
41 notice.z_message_len = strlen(asciiport)+1;
42 notice.z_opcode = CLIENT_GIMMESUBS;
44 return(Z_RetSubs(¬ice, nsubs, ZAUTH));
48 ZRetrieveDefaultSubscriptions(int *nsubs)
52 (void) memset((char *)¬ice, 0, sizeof(notice));
53 notice.z_message = (char *) 0;
54 notice.z_message_len = 0;
55 notice.z_opcode = CLIENT_GIMMEDEFS;
57 return(Z_RetSubs(¬ice, nsubs, ZNOAUTH));
62 Z_RetSubs(register ZNotice_t *notice,
64 Z_AuthProc auth_routine)
67 int retval,nrecv,gimmeack;
70 ZSubscription_t *list = __subscriptions_list;
72 retval = ZFlushSubscriptions();
74 if (retval != ZERR_NONE && retval != ZERR_NOSUBSCRIPTIONS)
78 if ((retval = ZOpenPort((u_short *)0)) != ZERR_NONE)
81 notice->z_kind = ACKED;
82 notice->z_port = __Zephyr_port;
83 notice->z_class = ZEPHYR_CTL_CLASS;
84 notice->z_class_inst = ZEPHYR_CTL_CLIENT;
86 notice->z_recipient = "";
87 notice->z_default_format = "";
89 if ((retval = ZSendNotice(notice,auth_routine)) != ZERR_NONE)
94 list = (ZSubscription_t *) 0;
96 while (!nrecv || !gimmeack) {
97 retval = Z_WaitForNotice (&retnotice, ZCompareMultiUIDPred,
98 ¬ice->z_multiuid, SRV_TIMEOUT);
99 if (retval == ZERR_NONOTICE)
101 else if (retval != ZERR_NONE)
104 if (retnotice.z_kind == SERVNAK) {
105 ZFreeNotice(&retnotice);
106 return (ZERR_SERVNAK);
108 /* non-matching protocol version numbers means the
109 server is probably an older version--must punt */
110 if (strcmp(notice->z_version,retnotice.z_version)) {
111 ZFreeNotice(&retnotice);
114 if (retnotice.z_kind == SERVACK &&
115 !strcmp(retnotice.z_opcode,notice->z_opcode)) {
116 ZFreeNotice(&retnotice);
121 if (retnotice.z_kind != ACKED) {
122 ZFreeNotice(&retnotice);
123 return (ZERR_INTERNAL);
128 end = retnotice.z_message+retnotice.z_message_len;
130 __subscriptions_num = 0;
131 for (ptr=retnotice.z_message;ptr<end;ptr++)
133 __subscriptions_num++;
135 __subscriptions_num = __subscriptions_num / 3;
137 list = (ZSubscription_t *)
138 malloc(__subscriptions_num * sizeof(ZSubscription_t));
139 if (__subscriptions_num && !list) {
140 ZFreeNotice(&retnotice);
144 ptr = retnotice.z_message;
145 for (i = 0; i < __subscriptions_num; i++) {
146 list[i].zsub_class = (char *)
147 malloc(strlen(ptr) + 1);
148 if (!list[i].zsub_class) {
149 ZFreeNotice(&retnotice);
152 strcpy(list[i].zsub_class, ptr);
153 ptr += strlen(ptr)+1;
154 list[i].zsub_classinst = (char *)
155 malloc(strlen(ptr) + 1);
156 if (!list[i].zsub_classinst) {
157 ZFreeNotice(&retnotice);
160 strcpy(list[i].zsub_classinst, ptr);
161 ptr += strlen(ptr)+1;
163 list[i].zsub_recipient = (char *)
164 malloc(strlen(ptr2) + 2);
165 if (!list[i].zsub_recipient) {
166 ZFreeNotice(&retnotice);
169 if (*ptr2 == '@' || *ptr2 == 0) {
170 *list[i].zsub_recipient = '*';
171 strcpy(list[i].zsub_recipient + 1, ptr2);
173 strcpy(list[i].zsub_recipient, ptr2);
175 ptr += strlen(ptr)+1;
177 ZFreeNotice(&retnotice);
180 __subscriptions_list = list;
181 __subscriptions_next = 0;
182 *nsubs = __subscriptions_num;