Mercurial > pidgin
annotate src/protocols/zephyr/ZSubs.c @ 6982:083d1e4a9c78
[gaim-migrate @ 7538]
This is Mr. Holland's Opus. And by Mr. Holland I mean Robot101. He
rewrote the coreish IM image support so that the binary data gets
ripped out in the prpl and put in an imgstore instead of just being
passed in the same huge as char string as the actual message. This
is good because it's prpl agnostic, or something. It also means
we don't have a silly length of "-1" with pretty much every send or
receive IM function.
It should be crash free, bug free, and memleak free, but additional
testing is always a good thing.
If you like good stuff then you'll love this patch. But don't take
my word for it--ba dun dunt!
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Sat, 27 Sep 2003 19:17:21 +0000 |
parents | ec20536eaeb0 |
children | 43d6c08d7e96 |
rev | line source |
---|---|
2086 | 1 /* This file is part of the Project Athena Zephyr Notification System. |
2 * It contains source for the ZSubscribeTo, ZUnsubscribeTo, and | |
3 * ZCancelSubscriptions functions. | |
4 * | |
5 * Created by: Robert French | |
6 * | |
7 * $Source$ | |
3277 | 8 * $Author: seanegan $ |
2086 | 9 * |
10 * Copyright (c) 1987,1988 by the Massachusetts Institute of Technology. | |
11 * For copying and distribution information, see the file | |
12 * "mit-copyright.h". | |
13 */ | |
14 /* $Header$ */ | |
15 | |
16 #include <internal.h> | |
17 | |
18 #ifndef lint | |
3277 | 19 static const char rcsid_ZSubscriptions_c[] = "$Id: ZSubs.c 3295 2002-05-28 08:40:48Z seanegan $"; |
2086 | 20 #endif |
21 | |
22 static Code_t Z_Subscriptions __P((register ZSubscription_t *sublist, | |
23 int nitems, unsigned int port, | |
24 char *opcode, int authit)); | |
25 static Code_t subscr_sendoff __P((ZNotice_t *notice, char **lyst, int num, | |
26 int authit)); | |
27 | |
28 Code_t ZSubscribeTo(sublist, nitems, port) | |
29 ZSubscription_t *sublist; | |
30 int nitems; | |
31 unsigned int port; | |
32 { | |
33 return (Z_Subscriptions(sublist, nitems, port, CLIENT_SUBSCRIBE, 1)); | |
34 } | |
35 | |
36 Code_t ZSubscribeToSansDefaults(sublist, nitems, port) | |
37 ZSubscription_t *sublist; | |
38 int nitems; | |
39 unsigned int port; | |
40 { | |
41 return (Z_Subscriptions(sublist, nitems, port, CLIENT_SUBSCRIBE_NODEFS, | |
42 1)); | |
43 } | |
44 | |
45 Code_t ZUnsubscribeTo(sublist, nitems, port) | |
46 ZSubscription_t *sublist; | |
47 int nitems; | |
48 unsigned int port; | |
49 { | |
50 return (Z_Subscriptions(sublist, nitems, port, CLIENT_UNSUBSCRIBE, 1)); | |
51 } | |
52 | |
53 Code_t ZCancelSubscriptions(port) | |
54 unsigned int port; | |
55 { | |
56 return (Z_Subscriptions((ZSubscription_t *)0, 0, port, | |
57 CLIENT_CANCELSUB, 0)); | |
58 } | |
59 | |
60 /* | |
61 * This routine must do its own fragmentation. Subscriptions must | |
62 * not be broken across packet boundaries, or else the server will | |
63 * mis-interpret them. | |
64 */ | |
65 | |
66 static Code_t | |
67 Z_Subscriptions(sublist, nitems, port, opcode, authit) | |
68 register ZSubscription_t *sublist; | |
69 int nitems; | |
70 unsigned int port; | |
71 char *opcode; | |
72 int authit; | |
73 { | |
74 register int i, j; | |
75 int retval; | |
76 ZNotice_t notice; | |
77 char header[Z_MAXHEADERLEN]; | |
78 char **list; | |
3277 | 79 char *recip; |
2086 | 80 int hdrlen; |
81 int size_avail = Z_MAXPKTLEN-Z_FRAGFUDGE; /* space avail for data, | |
82 adjusted below */ | |
83 int size, start, numok; | |
84 | |
85 /* nitems = 0 means cancel all subscriptions; still need to allocate a */ | |
86 /* array for one item so we can cancel, however. */ | |
87 | |
88 list = (char **)malloc((unsigned)((nitems==0)?1:nitems)*3*sizeof(char *)); | |
89 if (!list) | |
90 return (ENOMEM); | |
91 | |
92 (void) memset((char *)¬ice, 0, sizeof(notice)); | |
93 notice.z_kind = ACKED; | |
94 notice.z_port = port; | |
95 notice.z_class = ZEPHYR_CTL_CLASS; | |
96 notice.z_class_inst = ZEPHYR_CTL_CLIENT; | |
97 notice.z_opcode = opcode; | |
98 notice.z_sender = 0; | |
99 notice.z_recipient = ""; | |
100 notice.z_default_format = ""; | |
101 notice.z_message_len = 0; | |
102 | |
103 /* format the header to figure out how long it is */ | |
104 retval = Z_FormatHeader(¬ice, header, sizeof(header), &hdrlen, ZAUTH); | |
105 if (retval != ZERR_NONE && !authit) | |
106 retval = Z_FormatHeader(¬ice, header, sizeof(header), | |
2419
7ba69b8e0de5
[gaim-migrate @ 2432]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
107 &hdrlen, ZNOAUTH); |
2086 | 108 if (retval != ZERR_NONE) { |
109 free((char *)list); | |
110 return(retval); | |
111 } | |
112 | |
113 /* compute amount of room left */ | |
114 size_avail -= hdrlen; | |
115 size = size_avail; | |
116 | |
117 /* assemble subs into an array of pointers */ | |
118 for (i=0;i<nitems;i++) { | |
119 list[i*3] = sublist[i].zsub_class; | |
120 list[i*3+1] = sublist[i].zsub_classinst; | |
3277 | 121 recip = sublist[i].zsub_recipient; |
122 if (recip && *recip == '*') | |
123 recip++; | |
124 if (!recip || (*recip != 0 && *recip != '@')) | |
125 recip = ZGetSender(); | |
126 list[i*3+2] = recip; | |
2086 | 127 } |
128 | |
129 start = -1; | |
130 i = 0; | |
131 numok = 0; | |
132 if (!nitems) { | |
133 /* there aren't really any, but we need to xmit anyway */ | |
134 retval = subscr_sendoff(¬ice, list, 0, authit); | |
135 free((char *)list); | |
136 return(retval); | |
137 } | |
138 while(i < nitems) { | |
139 if (start == -1) { | |
140 size = size_avail; | |
141 start = i; | |
142 numok = 0; | |
143 } | |
144 if ((j = strlen(list[i*3]) | |
145 + strlen(list[i*3+1]) | |
146 + strlen(list[i*3+2]) + 3) <= size) { | |
147 /* it will fit in this packet */ | |
148 size -= j; | |
149 numok++; | |
150 i++; | |
151 continue; | |
152 } | |
153 if (!numok) { /* a single subscription won't | |
154 fit into one packet */ | |
155 free((char *)list); | |
156 return(ZERR_FIELDLEN); | |
157 } | |
158 retval = subscr_sendoff(¬ice, &list[start*3], numok, authit); | |
159 if (retval) { | |
160 free((char *)list); | |
161 return(retval); | |
162 } | |
163 start = -1; | |
164 } | |
165 if (numok) | |
166 retval = subscr_sendoff(¬ice, &list[start*3], numok, authit); | |
167 free((char *)list); | |
168 return(retval); | |
169 } | |
170 | |
171 static Code_t | |
172 subscr_sendoff(notice, lyst, num, authit) | |
173 ZNotice_t *notice; | |
174 char **lyst; | |
175 int num; | |
176 int authit; | |
177 { | |
178 register Code_t retval; | |
179 ZNotice_t retnotice; | |
180 | |
181 retval = ZSendList(notice, lyst, num*3, ZAUTH); | |
182 if (retval != ZERR_NONE && !authit) | |
183 retval = ZSendList(notice, lyst, num*3, ZNOAUTH); | |
184 | |
185 if (retval != ZERR_NONE) | |
186 return (retval); | |
187 if ((retval = ZIfNotice(&retnotice, (struct sockaddr_in *)0, | |
188 ZCompareUIDPred, (char *)¬ice->z_uid)) != | |
189 ZERR_NONE) | |
190 return (retval); | |
191 if (retnotice.z_kind == SERVNAK) { | |
192 ZFreeNotice(&retnotice); | |
193 return (ZERR_SERVNAK); | |
194 } | |
195 if (retnotice.z_kind != SERVACK) { | |
196 ZFreeNotice(&retnotice); | |
197 return (ZERR_INTERNAL); | |
198 } | |
199 ZFreeNotice(&retnotice); | |
200 return (ZERR_NONE); | |
201 } |