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
8 * $Author: warmenhoven $
10 * Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology.
11 * For copying and distribution information, see the file
19 static const char rcsid_ZRetrieveSubscriptions_c
[] =
20 "$Id: ZRetSubs.c 2096 2001-07-31 01:00:39Z warmenhoven $";
23 static Code_t
Z_RetSubs ();
25 /* Need STDC definition when possible for unsigned short argument. */
27 Code_t
ZRetrieveSubscriptions(unsigned short port
, int *nsubs
)
29 Code_t
ZRetrieveSubscriptions(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
;
50 return(Z_RetSubs(¬ice
, nsubs
, ZAUTH
));
53 Code_t
ZRetrieveDefaultSubscriptions(nsubs
)
58 (void) memset((char *)¬ice
, 0, sizeof(notice
));
59 notice
.z_message
= (char *) 0;
60 notice
.z_message_len
= 0;
61 notice
.z_opcode
= CLIENT_GIMMEDEFS
;
63 return(Z_RetSubs(¬ice
, nsubs
, ZNOAUTH
));
67 static Code_t
Z_RetSubs(notice
, nsubs
, auth_routine
)
68 register ZNotice_t
*notice
;
70 Z_AuthProc auth_routine
;
73 int retval
,nrecv
,gimmeack
;
77 retval
= ZFlushSubscriptions();
79 if (retval
!= ZERR_NONE
&& retval
!= ZERR_NOSUBSCRIPTIONS
)
83 if ((retval
= ZOpenPort((u_short
*)0)) != ZERR_NONE
)
86 notice
->z_kind
= ACKED
;
87 notice
->z_port
= __Zephyr_port
;
88 notice
->z_class
= ZEPHYR_CTL_CLASS
;
89 notice
->z_class_inst
= ZEPHYR_CTL_CLIENT
;
91 notice
->z_recipient
= "";
92 notice
->z_default_format
= "";
94 if ((retval
= ZSendNotice(notice
,auth_routine
)) != ZERR_NONE
)
99 __subscriptions_list
= (ZSubscription_t
*) 0;
101 while (!nrecv
|| !gimmeack
) {
102 retval
= Z_WaitForNotice (&retnotice
, ZCompareMultiUIDPred
,
103 ¬ice
->z_multiuid
, SRV_TIMEOUT
);
104 if (retval
== ZERR_NONOTICE
)
106 else if (retval
!= ZERR_NONE
)
109 if (retnotice
.z_kind
== SERVNAK
) {
110 ZFreeNotice(&retnotice
);
111 return (ZERR_SERVNAK
);
113 /* non-matching protocol version numbers means the
114 server is probably an older version--must punt */
115 if (strcmp(notice
->z_version
,retnotice
.z_version
)) {
116 ZFreeNotice(&retnotice
);
119 if (retnotice
.z_kind
== SERVACK
&&
120 !strcmp(retnotice
.z_opcode
,notice
->z_opcode
)) {
121 ZFreeNotice(&retnotice
);
126 if (retnotice
.z_kind
!= ACKED
) {
127 ZFreeNotice(&retnotice
);
128 return (ZERR_INTERNAL
);
133 end
= retnotice
.z_message
+retnotice
.z_message_len
;
135 __subscriptions_num
= 0;
136 for (ptr
=retnotice
.z_message
;ptr
<end
;ptr
++)
138 __subscriptions_num
++;
140 __subscriptions_num
= __subscriptions_num
/ 3;
142 __subscriptions_list
= (ZSubscription_t
*)
143 malloc((unsigned)(__subscriptions_num
*
144 sizeof(ZSubscription_t
)));
145 if (__subscriptions_num
&& !__subscriptions_list
) {
146 ZFreeNotice(&retnotice
);
150 for (ptr
=retnotice
.z_message
,i
= 0; i
< __subscriptions_num
; i
++) {
151 __subscriptions_list
[i
].zsub_class
= (char *)
152 malloc((unsigned)strlen(ptr
)+1);
153 if (!__subscriptions_list
[i
].zsub_class
) {
154 ZFreeNotice(&retnotice
);
157 (void) strcpy(__subscriptions_list
[i
].zsub_class
,ptr
);
158 ptr
+= strlen(ptr
)+1;
159 __subscriptions_list
[i
].zsub_classinst
= (char *)
160 malloc((unsigned)strlen(ptr
)+1);
161 if (!__subscriptions_list
[i
].zsub_classinst
) {
162 ZFreeNotice(&retnotice
);
165 (void) strcpy(__subscriptions_list
[i
].zsub_classinst
,ptr
);
166 ptr
+= strlen(ptr
)+1;
170 __subscriptions_list
[i
].zsub_recipient
= (char *)
171 malloc((unsigned)strlen(ptr2
)+1);
172 if (!__subscriptions_list
[i
].zsub_recipient
) {
173 ZFreeNotice(&retnotice
);
176 (void) strcpy(__subscriptions_list
[i
].zsub_recipient
,ptr2
);
177 ptr
+= strlen(ptr
)+1;
179 ZFreeNotice(&retnotice
);
182 __subscriptions_next
= 0;
183 *nsubs
= __subscriptions_num
;