[gaim-migrate @ 3063]
[pidgin-git.git] / src / protocols / zephyr / ZRetSubs.c
blob3d8161152d77a58f04e15bad109ac472b14b1d3e
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 * $Source$
8 * $Author: warmenhoven $
10 * Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology.
11 * For copying and distribution information, see the file
12 * "mit-copyright.h".
14 /* $Header$ */
16 #include <internal.h>
18 #ifndef lint
19 static const char rcsid_ZRetrieveSubscriptions_c[] =
20 "$Id: ZRetSubs.c 2096 2001-07-31 01:00:39Z warmenhoven $";
21 #endif
23 static Code_t Z_RetSubs ();
25 /* Need STDC definition when possible for unsigned short argument. */
26 #ifdef __STDC__
27 Code_t ZRetrieveSubscriptions(unsigned short port, int *nsubs)
28 #else
29 Code_t ZRetrieveSubscriptions(port,nsubs)
30 unsigned short port;
31 int *nsubs;
32 #endif
34 int retval;
35 ZNotice_t notice;
36 char asciiport[50];
38 if (!port) /* use default port */
39 port = __Zephyr_port;
41 retval = ZMakeAscii16(asciiport, sizeof(asciiport), ntohs(port));
42 if (retval != ZERR_NONE)
43 return (retval);
45 (void) memset((char *)&notice, 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(&notice, nsubs, ZAUTH));
53 Code_t ZRetrieveDefaultSubscriptions(nsubs)
54 int *nsubs;
56 ZNotice_t notice;
58 (void) memset((char *)&notice, 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(&notice, nsubs, ZNOAUTH));
67 static Code_t Z_RetSubs(notice, nsubs, auth_routine)
68 register ZNotice_t *notice;
69 int *nsubs;
70 Z_AuthProc auth_routine;
72 register int i;
73 int retval,nrecv,gimmeack;
74 ZNotice_t retnotice;
75 char *ptr,*end,*ptr2;
77 retval = ZFlushSubscriptions();
79 if (retval != ZERR_NONE && retval != ZERR_NOSUBSCRIPTIONS)
80 return (retval);
82 if (ZGetFD() < 0)
83 if ((retval = ZOpenPort((u_short *)0)) != ZERR_NONE)
84 return (retval);
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;
90 notice->z_sender = 0;
91 notice->z_recipient = "";
92 notice->z_default_format = "";
94 if ((retval = ZSendNotice(notice,auth_routine)) != ZERR_NONE)
95 return (retval);
97 nrecv = 0;
98 gimmeack = 0;
99 __subscriptions_list = (ZSubscription_t *) 0;
101 while (!nrecv || !gimmeack) {
102 retval = Z_WaitForNotice (&retnotice, ZCompareMultiUIDPred,
103 &notice->z_multiuid, SRV_TIMEOUT);
104 if (retval == ZERR_NONOTICE)
105 return ETIMEDOUT;
106 else if (retval != ZERR_NONE)
107 return retval;
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);
117 return(ZERR_VERS);
119 if (retnotice.z_kind == SERVACK &&
120 !strcmp(retnotice.z_opcode,notice->z_opcode)) {
121 ZFreeNotice(&retnotice);
122 gimmeack = 1;
123 continue;
126 if (retnotice.z_kind != ACKED) {
127 ZFreeNotice(&retnotice);
128 return (ZERR_INTERNAL);
131 nrecv++;
133 end = retnotice.z_message+retnotice.z_message_len;
135 __subscriptions_num = 0;
136 for (ptr=retnotice.z_message;ptr<end;ptr++)
137 if (!*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);
147 return (ENOMEM);
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);
155 return (ENOMEM);
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);
163 return (ENOMEM);
165 (void) strcpy(__subscriptions_list[i].zsub_classinst,ptr);
166 ptr += strlen(ptr)+1;
167 ptr2 = ptr;
168 if (!*ptr2)
169 ptr2 = "*";
170 __subscriptions_list[i].zsub_recipient = (char *)
171 malloc((unsigned)strlen(ptr2)+1);
172 if (!__subscriptions_list[i].zsub_recipient) {
173 ZFreeNotice(&retnotice);
174 return (ENOMEM);
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;
185 return (ZERR_NONE);