14192
|
1 /* This file is part of the Project Athena Zephyr Notification System.
|
|
2 * It contains source for the ZRetrieveSubscriptions and
|
|
3 * ZRetrieveDefaultSubscriptions functions.
|
|
4 *
|
|
5 * Created by: Robert French
|
|
6 *
|
|
7 * Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology.
|
|
8 * For copying and distribution information, see the file
|
|
9 * "mit-copyright.h".
|
|
10 */
|
|
11
|
|
12 #include "internal.h"
|
|
13
|
|
14 static Code_t Z_RetSubs(ZNotice_t *notice, int *nsubs, Z_AuthProc auth_routine);
|
|
15
|
|
16 /* Need STDC definition when possible for unsigned short argument. */
|
|
17 #ifdef __STDC__
|
|
18 Code_t ZRetrieveSubscriptions(unsigned short port, int *nsubs)
|
|
19 #else
|
|
20 Code_t ZRetrieveSubscriptions(port,nsubs)
|
|
21 unsigned short port;
|
|
22 int *nsubs;
|
|
23 #endif
|
|
24 {
|
|
25 int retval;
|
|
26 ZNotice_t notice;
|
|
27 char asciiport[50];
|
|
28
|
|
29 if (!port) /* use default port */
|
|
30 port = __Zephyr_port;
|
|
31
|
|
32 retval = ZMakeAscii16(asciiport, sizeof(asciiport), ntohs(port));
|
|
33 if (retval != ZERR_NONE)
|
|
34 return (retval);
|
|
35
|
|
36 (void) memset((char *)¬ice, 0, sizeof(notice));
|
|
37 notice.z_message = asciiport;
|
|
38 notice.z_message_len = strlen(asciiport)+1;
|
|
39 notice.z_opcode = CLIENT_GIMMESUBS;
|
|
40
|
|
41 return(Z_RetSubs(¬ice, nsubs, ZAUTH));
|
|
42 }
|
|
43
|
|
44 #if 0
|
|
45 Code_t ZRetrieveDefaultSubscriptions(nsubs)
|
|
46 int *nsubs;
|
|
47 {
|
|
48 ZNotice_t notice;
|
|
49
|
|
50 (void) memset((char *)¬ice, 0, sizeof(notice));
|
|
51 notice.z_message = (char *) 0;
|
|
52 notice.z_message_len = 0;
|
|
53 notice.z_opcode = CLIENT_GIMMEDEFS;
|
|
54
|
|
55 return(Z_RetSubs(¬ice, nsubs, ZNOAUTH));
|
|
56
|
|
57 }
|
|
58 #endif
|
|
59
|
|
60 static Code_t Z_RetSubs(notice, nsubs, auth_routine)
|
|
61 register ZNotice_t *notice;
|
|
62 int *nsubs;
|
|
63 Z_AuthProc auth_routine;
|
|
64 {
|
|
65 register int i;
|
|
66 int retval,nrecv,gimmeack;
|
|
67 ZNotice_t retnotice;
|
|
68 char *ptr,*end,*ptr2;
|
|
69
|
|
70 retval = ZFlushSubscriptions();
|
|
71
|
|
72 if (retval != ZERR_NONE && retval != ZERR_NOSUBSCRIPTIONS)
|
|
73 return (retval);
|
|
74
|
|
75 if (ZGetFD() < 0)
|
|
76 if ((retval = ZOpenPort((unsigned short *)0)) != ZERR_NONE)
|
|
77 return (retval);
|
|
78
|
|
79 notice->z_kind = ACKED;
|
|
80 notice->z_port = __Zephyr_port;
|
|
81 notice->z_class = ZEPHYR_CTL_CLASS;
|
|
82 notice->z_class_inst = ZEPHYR_CTL_CLIENT;
|
|
83 notice->z_sender = 0;
|
|
84 notice->z_recipient = "";
|
|
85 notice->z_default_format = "";
|
|
86
|
|
87 if ((retval = ZSendNotice(notice,auth_routine)) != ZERR_NONE)
|
|
88 return (retval);
|
|
89
|
|
90 nrecv = 0;
|
|
91 gimmeack = 0;
|
|
92 __subscriptions_list = (ZSubscription_t *) 0;
|
|
93
|
|
94 while (!nrecv || !gimmeack) {
|
|
95 retval = Z_WaitForNotice (&retnotice, ZCompareMultiUIDPred,
|
|
96 ¬ice->z_multiuid, SRV_TIMEOUT);
|
|
97 if (retval == ZERR_NONOTICE)
|
|
98 return ETIMEDOUT;
|
|
99 else if (retval != ZERR_NONE)
|
|
100 return retval;
|
|
101
|
|
102 if (retnotice.z_kind == SERVNAK) {
|
|
103 ZFreeNotice(&retnotice);
|
|
104 return (ZERR_SERVNAK);
|
|
105 }
|
|
106 /* non-matching protocol version numbers means the
|
|
107 server is probably an older version--must punt */
|
|
108 if (strcmp(notice->z_version,retnotice.z_version)) {
|
|
109 ZFreeNotice(&retnotice);
|
|
110 return(ZERR_VERS);
|
|
111 }
|
|
112 if (retnotice.z_kind == SERVACK &&
|
|
113 !strcmp(retnotice.z_opcode,notice->z_opcode)) {
|
|
114 ZFreeNotice(&retnotice);
|
|
115 gimmeack = 1;
|
|
116 continue;
|
|
117 }
|
|
118
|
|
119 if (retnotice.z_kind != ACKED) {
|
|
120 ZFreeNotice(&retnotice);
|
|
121 return (ZERR_INTERNAL);
|
|
122 }
|
|
123
|
|
124 nrecv++;
|
|
125
|
|
126 end = retnotice.z_message+retnotice.z_message_len;
|
|
127
|
|
128 __subscriptions_num = 0;
|
|
129 for (ptr=retnotice.z_message;ptr<end;ptr++)
|
|
130 if (!*ptr)
|
|
131 __subscriptions_num++;
|
|
132
|
|
133 __subscriptions_num = __subscriptions_num / 3;
|
|
134
|
|
135 __subscriptions_list = (ZSubscription_t *)
|
|
136 malloc((unsigned)(__subscriptions_num*
|
|
137 sizeof(ZSubscription_t)));
|
|
138 if (__subscriptions_num && !__subscriptions_list) {
|
|
139 ZFreeNotice(&retnotice);
|
|
140 return (ENOMEM);
|
|
141 }
|
|
142
|
|
143 for (ptr=retnotice.z_message,i = 0; i< __subscriptions_num; i++) {
|
|
144 __subscriptions_list[i].zsub_class = (char *)
|
|
145 malloc((unsigned)strlen(ptr)+1);
|
|
146 if (!__subscriptions_list[i].zsub_class) {
|
|
147 ZFreeNotice(&retnotice);
|
|
148 return (ENOMEM);
|
|
149 }
|
|
150 (void) strcpy(__subscriptions_list[i].zsub_class,ptr);
|
|
151 ptr += strlen(ptr)+1;
|
|
152 __subscriptions_list[i].zsub_classinst = (char *)
|
|
153 malloc((unsigned)strlen(ptr)+1);
|
|
154 if (!__subscriptions_list[i].zsub_classinst) {
|
|
155 ZFreeNotice(&retnotice);
|
|
156 return (ENOMEM);
|
|
157 }
|
|
158 (void) strcpy(__subscriptions_list[i].zsub_classinst,ptr);
|
|
159 ptr += strlen(ptr)+1;
|
|
160 ptr2 = ptr;
|
|
161 if (!*ptr2)
|
|
162 ptr2 = "*";
|
|
163 __subscriptions_list[i].zsub_recipient = (char *)
|
|
164 malloc((unsigned)strlen(ptr2)+1);
|
|
165 if (!__subscriptions_list[i].zsub_recipient) {
|
|
166 ZFreeNotice(&retnotice);
|
|
167 return (ENOMEM);
|
|
168 }
|
|
169 (void) strcpy(__subscriptions_list[i].zsub_recipient,ptr2);
|
|
170 ptr += strlen(ptr)+1;
|
|
171 }
|
|
172 ZFreeNotice(&retnotice);
|
|
173 }
|
|
174
|
|
175 __subscriptions_next = 0;
|
|
176 *nsubs = __subscriptions_num;
|
|
177
|
|
178 return (ZERR_NONE);
|
|
179 }
|