Replace functions which called once with their bodies
[pidgin-git.git] / libpurple / protocols / zephyr / ZSubs.c
blob9cf5ee954881b94ed242fbe8a85f42755e2e4da4
1 /* This file is part of the Project Athena Zephyr Notification System.
2 * It contains source for the ZSubscribeTo, ZUnsubscribeTo, and
3 * ZCancelSubscriptions functions.
5 * Created by: Robert French
7 * Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
8 * For copying and distribution information, see the file
9 * "mit-copyright.h".
12 #include "internal.h"
14 static Code_t Z_Subscriptions(register ZSubscription_t *sublist, int nitems,
15 unsigned int port, char *opcode, int authit);
16 static Code_t subscr_sendoff(ZNotice_t *notice, char **lyst, int num,
17 int authit);
19 Code_t ZSubscribeTo(sublist, nitems, port)
20 ZSubscription_t *sublist;
21 int nitems;
22 unsigned int port;
24 return (Z_Subscriptions(sublist, nitems, port, CLIENT_SUBSCRIBE, 1));
27 Code_t ZSubscribeToSansDefaults(sublist, nitems, port)
28 ZSubscription_t *sublist;
29 int nitems;
30 unsigned int port;
32 return (Z_Subscriptions(sublist, nitems, port, CLIENT_SUBSCRIBE_NODEFS,
33 1));
36 Code_t ZUnsubscribeTo(sublist, nitems, port)
37 ZSubscription_t *sublist;
38 int nitems;
39 unsigned int port;
41 return (Z_Subscriptions(sublist, nitems, port, CLIENT_UNSUBSCRIBE, 1));
44 Code_t ZCancelSubscriptions(port)
45 unsigned int port;
47 return (Z_Subscriptions((ZSubscription_t *)0, 0, port,
48 CLIENT_CANCELSUB, 0));
52 * This routine must do its own fragmentation. Subscriptions must
53 * not be broken across packet boundaries, or else the server will
54 * mis-interpret them.
57 static Code_t
58 Z_Subscriptions(sublist, nitems, port, opcode, authit)
59 register ZSubscription_t *sublist;
60 int nitems;
61 unsigned int port;
62 char *opcode;
63 int authit;
65 register int i, j;
66 int retval;
67 ZNotice_t notice;
68 char header[Z_MAXHEADERLEN];
69 char **list;
70 char *recip;
71 int hdrlen;
72 int size_avail = Z_MAXPKTLEN-Z_FRAGFUDGE; /* space avail for data,
73 adjusted below */
74 int size, start, numok;
76 /* nitems = 0 means cancel all subscriptions; still need to allocate a */
77 /* array for one item so we can cancel, however. */
79 list = (char **)malloc((unsigned)((nitems==0)?1:nitems)*3*sizeof(char *));
80 if (!list)
81 return (ENOMEM);
83 (void) memset((char *)&notice, 0, sizeof(notice));
84 notice.z_kind = ACKED;
85 notice.z_port = port;
86 notice.z_class = ZEPHYR_CTL_CLASS;
87 notice.z_class_inst = ZEPHYR_CTL_CLIENT;
88 notice.z_opcode = opcode;
89 notice.z_sender = 0;
90 notice.z_recipient = "";
91 notice.z_default_format = "";
92 notice.z_message_len = 0;
94 /* format the header to figure out how long it is */
95 retval = Z_FormatHeader(&notice, header, sizeof(header), &hdrlen, ZAUTH);
96 if (retval != ZERR_NONE && !authit)
97 retval = Z_FormatHeader(&notice, header, sizeof(header),
98 &hdrlen, ZNOAUTH);
99 if (retval != ZERR_NONE) {
100 free((char *)list);
101 return(retval);
104 /* compute amount of room left */
105 size_avail -= hdrlen;
106 size = size_avail;
108 /* assemble subs into an array of pointers */
109 for (i=0;i<nitems;i++) {
110 list[i*3] = sublist[i].zsub_class;
111 list[i*3+1] = sublist[i].zsub_classinst;
112 recip = sublist[i].zsub_recipient;
113 if (recip && *recip == '*')
114 recip++;
115 if (!recip || (*recip != 0 && *recip != '@'))
116 recip = ZGetSender();
117 list[i*3+2] = recip;
120 start = -1;
121 i = 0;
122 numok = 0;
123 if (!nitems) {
124 /* there aren't really any, but we need to xmit anyway */
125 retval = subscr_sendoff(&notice, list, 0, authit);
126 free((char *)list);
127 return(retval);
129 while(i < nitems) {
130 if (start == -1) {
131 size = size_avail;
132 start = i;
133 numok = 0;
135 if ((j = strlen(list[i*3])
136 + strlen(list[i*3+1])
137 + strlen(list[i*3+2]) + 3) <= size) {
138 /* it will fit in this packet */
139 size -= j;
140 numok++;
141 i++;
142 continue;
144 if (!numok) { /* a single subscription won't
145 fit into one packet */
146 free((char *)list);
147 return(ZERR_FIELDLEN);
149 retval = subscr_sendoff(&notice, &list[start*3], numok, authit);
150 if (retval) {
151 free((char *)list);
152 return(retval);
154 start = -1;
156 if (numok)
157 retval = subscr_sendoff(&notice, &list[start*3], numok, authit);
158 free((char *)list);
159 return(retval);
162 static Code_t
163 subscr_sendoff(notice, lyst, num, authit)
164 ZNotice_t *notice;
165 char **lyst;
166 int num;
167 int authit;
169 register Code_t retval;
170 ZNotice_t retnotice;
172 retval = ZSendList(notice, lyst, num*3, ZAUTH);
173 if (retval != ZERR_NONE && !authit)
174 retval = ZSendList(notice, lyst, num*3, ZNOAUTH);
176 if (retval != ZERR_NONE)
177 return (retval);
178 if ((retval = ZIfNotice(&retnotice, (struct sockaddr_in *)0,
179 ZCompareUIDPred, (char *)&notice->z_uid)) !=
180 ZERR_NONE)
181 return (retval);
182 if (retnotice.z_kind == SERVNAK) {
183 ZFreeNotice(&retnotice);
184 return (ZERR_SERVNAK);
186 if (retnotice.z_kind != SERVACK) {
187 ZFreeNotice(&retnotice);
188 return (ZERR_INTERNAL);
190 ZFreeNotice(&retnotice);
191 return (ZERR_NONE);