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 * Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology.
8 * For copying and distribution information, see the file
15 static Code_t
Z_RetSubs(ZNotice_t
*notice
, int *nsubs
, Z_AuthProc auth_routine
);
17 Code_t
ZRetrieveSubscriptions(unsigned short port
, int *nsubs
)
23 if (!port
) /* use default port */
26 retval
= ZMakeAscii16(asciiport
, sizeof(asciiport
), ntohs(port
));
27 if (retval
!= ZERR_NONE
)
30 (void) memset((char *)¬ice
, 0, sizeof(notice
));
31 notice
.z_message
= asciiport
;
32 notice
.z_message_len
= strlen(asciiport
)+1;
33 notice
.z_opcode
= CLIENT_GIMMESUBS
;
35 return(Z_RetSubs(¬ice
, nsubs
, ZAUTH
));
38 static Code_t
Z_RetSubs(notice
, nsubs
, auth_routine
)
39 register ZNotice_t
*notice
;
41 Z_AuthProc auth_routine
;
44 int retval
,nrecv
,gimmeack
;
48 retval
= ZFlushSubscriptions();
50 if (retval
!= ZERR_NONE
&& retval
!= ZERR_NOSUBSCRIPTIONS
)
54 if ((retval
= ZOpenPort((unsigned short *)0)) != ZERR_NONE
)
57 notice
->z_kind
= ACKED
;
58 notice
->z_port
= __Zephyr_port
;
59 notice
->z_class
= ZEPHYR_CTL_CLASS
;
60 notice
->z_class_inst
= ZEPHYR_CTL_CLIENT
;
62 notice
->z_recipient
= "";
63 notice
->z_default_format
= "";
65 if ((retval
= ZSendNotice(notice
,auth_routine
)) != ZERR_NONE
)
70 __subscriptions_list
= (ZSubscription_t
*) 0;
72 while (!nrecv
|| !gimmeack
) {
73 retval
= Z_WaitForNotice (&retnotice
, ZCompareMultiUIDPred
,
74 ¬ice
->z_multiuid
, SRV_TIMEOUT
);
75 if (retval
== ZERR_NONOTICE
)
77 else if (retval
!= ZERR_NONE
)
80 if (retnotice
.z_kind
== SERVNAK
) {
81 ZFreeNotice(&retnotice
);
82 return (ZERR_SERVNAK
);
84 /* non-matching protocol version numbers means the
85 server is probably an older version--must punt */
86 if (!purple_strequal(notice
->z_version
,retnotice
.z_version
)) {
87 ZFreeNotice(&retnotice
);
90 if (retnotice
.z_kind
== SERVACK
&&
91 purple_strequal(retnotice
.z_opcode
,notice
->z_opcode
)) {
92 ZFreeNotice(&retnotice
);
97 if (retnotice
.z_kind
!= ACKED
) {
98 ZFreeNotice(&retnotice
);
99 return (ZERR_INTERNAL
);
104 end
= retnotice
.z_message
+retnotice
.z_message_len
;
106 __subscriptions_num
= 0;
107 for (ptr
=retnotice
.z_message
;ptr
<end
;ptr
++)
109 __subscriptions_num
++;
111 __subscriptions_num
= __subscriptions_num
/ 3;
113 if (!__subscriptions_num
) {
114 ZFreeNotice(&retnotice
);
118 free(__subscriptions_list
);
119 __subscriptions_list
= (ZSubscription_t
*)
120 malloc((unsigned)(__subscriptions_num
*
121 sizeof(ZSubscription_t
)));
122 if (!__subscriptions_list
) {
123 ZFreeNotice(&retnotice
);
127 for (ptr
=retnotice
.z_message
,i
= 0; i
< __subscriptions_num
; i
++) {
130 len
= strlen(ptr
) + 1;
131 __subscriptions_list
[i
].zsub_class
= (char *)
133 if (!__subscriptions_list
[i
].zsub_class
) {
134 ZFreeNotice(&retnotice
);
137 g_strlcpy(__subscriptions_list
[i
].zsub_class
,ptr
,len
);
139 len
= strlen(ptr
) + 1;
140 __subscriptions_list
[i
].zsub_classinst
= (char *)
142 if (!__subscriptions_list
[i
].zsub_classinst
) {
143 ZFreeNotice(&retnotice
);
146 g_strlcpy(__subscriptions_list
[i
].zsub_classinst
,ptr
,len
);
151 len
= strlen(ptr2
) + 1;
152 __subscriptions_list
[i
].zsub_recipient
= (char *)
154 if (!__subscriptions_list
[i
].zsub_recipient
) {
155 ZFreeNotice(&retnotice
);
158 g_strlcpy(__subscriptions_list
[i
].zsub_recipient
,ptr2
,len
);
159 ptr
+= strlen(ptr
)+1;
161 ZFreeNotice(&retnotice
);
164 __subscriptions_next
= 0;
165 *nsubs
= __subscriptions_num
;