Mercurial > pidgin
annotate src/protocols/oscar/tlv.c @ 12645:fc28451f5d96
[gaim-migrate @ 14983]
SF Patch #1314512 from Sadrul (who has a patch for everything)
"This patch introduces a flag for protocol plugins that
support offline messages (like Y!M and ICQ). This was
encouraged by the following conversation:
<sadrul> should offline buddies be listed/enabled in
the send-to menu?
<rekkanoryo> i would think only for protocols that
support offline messaging, if it's indicated that the
buddy is offline
-- <snip> --
<Bleeter> sadrul: personally, I'd like to see a
'supports offline' flag of some description
<Bleeter> one could then redirect (via plugins) through
email or alternative methods
<Bleeter> just a thought
<Paco-Paco> yeah, that sounds like a reasonble thing to have
This patch uses this flag to disable the buddies in the
send-to menu who are offline and the protocol doesn't
support offline messages."
I made this make the label insensitive instead of the whole menuitem. This
should address SimGuy's concerns about inconsistency (i.e. you could create a
conversation with someone via the buddy list that you couldn't create via the
Send To menu). I also hacked up some voodoo to show the label as sensitive when
moused-over, as that looks better (given the label-insensitive thing is itself a
hack). I think this works quite well.
BUG NOTE:
This makes more obvious an existing bug. The Send To menu isn't updated when
buddies sign on or off or change status (at least under some circumstances).
We need to fix that anyway, so I'm not going to let it hold up this commit.
Switching tabs will clear it up. I'm thinking we just might want to build the
contents of that menu when it is selected. That would save us a mess of
inefficient signal callbacks that update the Send To menus in open windows all
the time.
AIM NOTE:
This assumes that AIM can't offline message. That's not strictly true. You can
message invisible users on AIM. However, by design, we can't tell when a user
is invisible without resorting to dirty hackery. In practice, this isn't a
problem, as you can still select the AIM user from the menu. And really, how
often will you be choosing the Invisible contact, rather than the user going
Invisible in the middle of a conversation or IMing you while they're Invisible?
JABBER NOTE:
This assumes that Jabber can always offline message. This isn't strictly true.
Sadrul said:
I have updated Jabber according to this link which seems to
talk about how to determine the existence offline-message
support in a server:
http://www.jabber.org/jeps/jep-0013.html#discover
However, jabber.org doesn't seem to send the required
info. So I am not sure about it.
He later said:
I talked to Nathan and he said offline message support is
mostly assumed for most jabber servers. GTalk doesn't yet
support it, but they are working on it. So I have made
jabber to always return TRUE.
If there is truly no way to detect offline messaging capability, then this is
an acceptable solution. We could special case Google Talk because of its
popularity, and remove that later. It's probably not worth it though.
MSN NOTE:
This assumes that MSN can never offline message. That's effectively true, but
to be technically correct, MSN can offline message if there's already a
switchboard conversation open with a user. We could write an offline_message
function in the MSN prpl to detect that, but it'd be of limited usefulness,
especially given that under most circumstances (where this might matter), the
switchboard connection will be closed almost immediately.
CVS NOTE:
I'm writing to share a tragic little story.
I have a PC that I use for Gaim development. One day, I was writing a commit
message on it, when all of a suddent it went berserk. The screen started
flashing, and the whole commit message just disappeared. All of it. And it was
a good commit message! I had to cram and rewrite it really quickly. Needless to
say, my rushed commit message wasn't nearly as good, and I blame the PC for that.
Seriously, though, what kind of version control system loses your commit
message on a broken connection to the server? Stupid!
committer: Tailor Script <tailor@pidgin.im>
author | Richard Laager <rlaager@wiktel.com> |
---|---|
date | Fri, 23 Dec 2005 19:26:04 +0000 |
parents | bcd7bd6a42dd |
children | f2431a7e33aa |
rev | line source |
---|---|
2086 | 1 |
2 #define FAIM_INTERNAL | |
3 #include <aim.h> | |
4 | |
7158 | 5 static aim_tlv_t *createtlv(fu16_t type, fu16_t length, fu8_t *value) |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
6 { |
7158 | 7 aim_tlv_t *ret; |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
8 |
7158 | 9 if (!(ret = (aim_tlv_t *)malloc(sizeof(aim_tlv_t)))) |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
10 return NULL; |
7158 | 11 ret->type = type; |
12 ret->length = length; | |
13 ret->value = value; | |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
14 |
7158 | 15 return ret; |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
16 } |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
17 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
18 static void freetlv(aim_tlv_t **oldtlv) |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
19 { |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
20 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
21 if (!oldtlv || !*oldtlv) |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
22 return; |
10986 | 23 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
24 free((*oldtlv)->value); |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
25 free(*oldtlv); |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
26 *oldtlv = NULL; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
27 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
28 return; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
29 } |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
30 |
2086 | 31 /** |
7167 | 32 * Read a TLV chain from a buffer. |
2086 | 33 * |
34 * Reads and parses a series of TLV patterns from a data buffer; the | |
35 * returned structure is manipulatable with the rest of the TLV | |
7167 | 36 * routines. When done with a TLV chain, aim_tlvlist_free() should |
2086 | 37 * be called to free the dynamic substructures. |
38 * | |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
39 * XXX There should be a flag setable here to have the tlvlist contain |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
40 * bstream references, so that at least the ->value portion of each |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
41 * element doesn't need to be malloc/memcpy'd. This could prove to be |
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
42 * just as efficient as the in-place TLV parsing used in a couple places |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
43 * in libfaim. |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
44 * |
7158 | 45 * @param bs Input bstream |
8790 | 46 * @return Return the TLV chain read |
2086 | 47 */ |
7167 | 48 faim_internal aim_tlvlist_t *aim_tlvlist_read(aim_bstream_t *bs) |
2086 | 49 { |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
50 aim_tlvlist_t *list = NULL, *cur; |
10986 | 51 |
3459 | 52 while (aim_bstream_empty(bs) > 0) { |
53 fu16_t type, length; | |
2086 | 54 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
55 type = aimbs_get16(bs); |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
56 length = aimbs_get16(bs); |
2086 | 57 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
58 #if 0 /* temporarily disabled until I know if they're still doing it or not */ |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
59 /* |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
60 * Okay, so now AOL has decided that any TLV of |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
61 * type 0x0013 can only be two bytes, despite |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
62 * what the actual given length is. So here |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
63 * we dump any invalid TLVs of that sort. Hopefully |
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
64 * there's no special cases to this special case. |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
65 * - mid (30jun2000) |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
66 */ |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
67 if ((type == 0x0013) && (length != 0x0002)) |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
68 length = 0x0002; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
69 #else |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
70 if (0) |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
71 ; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
72 #endif |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
73 else { |
2086 | 74 |
3459 | 75 if (length > aim_bstream_empty(bs)) { |
7167 | 76 aim_tlvlist_free(&list); |
3459 | 77 return NULL; |
78 } | |
79 | |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
80 cur = (aim_tlvlist_t *)malloc(sizeof(aim_tlvlist_t)); |
3459 | 81 if (!cur) { |
7167 | 82 aim_tlvlist_free(&list); |
3459 | 83 return NULL; |
84 } | |
85 | |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
86 memset(cur, 0, sizeof(aim_tlvlist_t)); |
2086 | 87 |
7158 | 88 cur->tlv = createtlv(type, length, NULL); |
3459 | 89 if (!cur->tlv) { |
90 free(cur); | |
7167 | 91 aim_tlvlist_free(&list); |
3459 | 92 return NULL; |
93 } | |
7158 | 94 if (cur->tlv->length > 0) { |
11159 | 95 cur->tlv->value = aimbs_getraw(bs, length); |
7158 | 96 if (!cur->tlv->value) { |
97 freetlv(&cur->tlv); | |
98 free(cur); | |
7167 | 99 aim_tlvlist_free(&list); |
7158 | 100 return NULL; |
101 } | |
3459 | 102 } |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
103 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
104 cur->next = list; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
105 list = cur; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
106 } |
2086 | 107 } |
108 | |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
109 return list; |
2086 | 110 } |
111 | |
112 /** | |
7167 | 113 * Read a TLV chain from a buffer. |
4230 | 114 * |
3952 | 115 * Reads and parses a series of TLV patterns from a data buffer; the |
116 * returned structure is manipulatable with the rest of the TLV | |
7167 | 117 * routines. When done with a TLV chain, aim_tlvlist_free() should |
3952 | 118 * be called to free the dynamic substructures. |
119 * | |
120 * XXX There should be a flag setable here to have the tlvlist contain | |
121 * bstream references, so that at least the ->value portion of each | |
122 * element doesn't need to be malloc/memcpy'd. This could prove to be | |
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
123 * just as efficient as the in-place TLV parsing used in a couple places |
3952 | 124 * in libfaim. |
125 * | |
7158 | 126 * @param bs Input bstream |
127 * @param num The max number of TLVs that will be read, or -1 if unlimited. | |
128 * There are a number of places where you want to read in a tlvchain, | |
129 * but the chain is not at the end of the SNAC, and the chain is | |
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
130 * preceded by the number of TLVs. So you can limit that with this. |
8790 | 131 * @return Return the TLV chain read |
3952 | 132 */ |
7167 | 133 faim_internal aim_tlvlist_t *aim_tlvlist_readnum(aim_bstream_t *bs, fu16_t num) |
3952 | 134 { |
135 aim_tlvlist_t *list = NULL, *cur; | |
4317 | 136 |
3952 | 137 while ((aim_bstream_empty(bs) > 0) && (num != 0)) { |
138 fu16_t type, length; | |
139 | |
140 type = aimbs_get16(bs); | |
141 length = aimbs_get16(bs); | |
142 | |
143 if (length > aim_bstream_empty(bs)) { | |
7167 | 144 aim_tlvlist_free(&list); |
3952 | 145 return NULL; |
146 } | |
147 | |
148 cur = (aim_tlvlist_t *)malloc(sizeof(aim_tlvlist_t)); | |
149 if (!cur) { | |
7167 | 150 aim_tlvlist_free(&list); |
3952 | 151 return NULL; |
152 } | |
153 | |
154 memset(cur, 0, sizeof(aim_tlvlist_t)); | |
155 | |
7158 | 156 cur->tlv = createtlv(type, length, NULL); |
3952 | 157 if (!cur->tlv) { |
158 free(cur); | |
7167 | 159 aim_tlvlist_free(&list); |
3952 | 160 return NULL; |
161 } | |
7158 | 162 if (cur->tlv->length > 0) { |
163 cur->tlv->value = aimbs_getraw(bs, length); | |
164 if (!cur->tlv->value) { | |
165 freetlv(&cur->tlv); | |
166 free(cur); | |
7167 | 167 aim_tlvlist_free(&list); |
7158 | 168 return NULL; |
169 } | |
3952 | 170 } |
171 | |
7158 | 172 if (num > 0) |
173 num--; | |
3952 | 174 cur->next = list; |
175 list = cur; | |
176 } | |
177 | |
178 return list; | |
179 } | |
180 | |
181 /** | |
7167 | 182 * Read a TLV chain from a buffer. |
4230 | 183 * |
184 * Reads and parses a series of TLV patterns from a data buffer; the | |
185 * returned structure is manipulatable with the rest of the TLV | |
7167 | 186 * routines. When done with a TLV chain, aim_tlvlist_free() should |
4230 | 187 * be called to free the dynamic substructures. |
188 * | |
189 * XXX There should be a flag setable here to have the tlvlist contain | |
190 * bstream references, so that at least the ->value portion of each | |
191 * element doesn't need to be malloc/memcpy'd. This could prove to be | |
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
192 * just as efficient as the in-place TLV parsing used in a couple places |
4230 | 193 * in libfaim. |
194 * | |
7158 | 195 * @param bs Input bstream |
196 * @param len The max length in bytes that will be read. | |
197 * There are a number of places where you want to read in a tlvchain, | |
198 * but the chain is not at the end of the SNAC, and the chain is | |
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
199 * preceded by the length of the TLVs. So you can limit that with this. |
8790 | 200 * @return Return the TLV chain read |
4230 | 201 */ |
7167 | 202 faim_internal aim_tlvlist_t *aim_tlvlist_readlen(aim_bstream_t *bs, fu16_t len) |
4230 | 203 { |
204 aim_tlvlist_t *list = NULL, *cur; | |
4317 | 205 |
4230 | 206 while ((aim_bstream_empty(bs) > 0) && (len > 0)) { |
207 fu16_t type, length; | |
208 | |
209 type = aimbs_get16(bs); | |
210 length = aimbs_get16(bs); | |
211 | |
212 if (length > aim_bstream_empty(bs)) { | |
7167 | 213 aim_tlvlist_free(&list); |
4230 | 214 return NULL; |
215 } | |
216 | |
217 cur = (aim_tlvlist_t *)malloc(sizeof(aim_tlvlist_t)); | |
218 if (!cur) { | |
7167 | 219 aim_tlvlist_free(&list); |
4230 | 220 return NULL; |
221 } | |
222 | |
223 memset(cur, 0, sizeof(aim_tlvlist_t)); | |
224 | |
7158 | 225 cur->tlv = createtlv(type, length, NULL); |
4230 | 226 if (!cur->tlv) { |
227 free(cur); | |
7167 | 228 aim_tlvlist_free(&list); |
4230 | 229 return NULL; |
230 } | |
7158 | 231 if (cur->tlv->length > 0) { |
232 cur->tlv->value = aimbs_getraw(bs, length); | |
233 if (!cur->tlv->value) { | |
234 freetlv(&cur->tlv); | |
235 free(cur); | |
7167 | 236 aim_tlvlist_free(&list); |
7158 | 237 return NULL; |
238 } | |
4230 | 239 } |
240 | |
7167 | 241 len -= aim_tlvlist_size(&cur); |
4230 | 242 cur->next = list; |
243 list = cur; | |
244 } | |
245 | |
246 return list; | |
247 } | |
248 | |
249 /** | |
7167 | 250 * Duplicate a TLV chain. |
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
251 * This is pretty self explanatory. |
4230 | 252 * |
7158 | 253 * @param orig The TLV chain you want to make a copy of. |
254 * @return A newly allocated TLV chain. | |
4230 | 255 */ |
256 faim_internal aim_tlvlist_t *aim_tlvlist_copy(aim_tlvlist_t *orig) | |
257 { | |
258 aim_tlvlist_t *new = NULL; | |
259 | |
260 while (orig) { | |
7167 | 261 aim_tlvlist_add_raw(&new, orig->tlv->type, orig->tlv->length, orig->tlv->value); |
4230 | 262 orig = orig->next; |
263 } | |
264 | |
265 return new; | |
266 } | |
267 | |
6101 | 268 /* |
269 * Compare two TLV lists for equality. This probably is not the most | |
270 * efficient way to do this. | |
271 * | |
272 * @param one One of the TLV chains to compare. | |
273 * @param two The other TLV chain to compare. | |
8790 | 274 * @return Return 0 if the lists are the same, return 1 if they are different. |
6101 | 275 */ |
276 faim_internal int aim_tlvlist_cmp(aim_tlvlist_t *one, aim_tlvlist_t *two) | |
277 { | |
278 aim_bstream_t bs1, bs2; | |
279 | |
7167 | 280 if (aim_tlvlist_size(&one) != aim_tlvlist_size(&two)) |
6101 | 281 return 1; |
282 | |
7167 | 283 aim_bstream_init(&bs1, ((fu8_t *)malloc(aim_tlvlist_size(&one)*sizeof(fu8_t))), aim_tlvlist_size(&one)); |
284 aim_bstream_init(&bs2, ((fu8_t *)malloc(aim_tlvlist_size(&two)*sizeof(fu8_t))), aim_tlvlist_size(&two)); | |
6101 | 285 |
7167 | 286 aim_tlvlist_write(&bs1, &one); |
287 aim_tlvlist_write(&bs2, &two); | |
6101 | 288 |
289 if (memcmp(bs1.data, bs2.data, bs1.len)) { | |
290 free(bs1.data); | |
291 free(bs2.data); | |
292 return 1; | |
293 } | |
294 | |
295 free(bs1.data); | |
296 free(bs2.data); | |
297 | |
298 return 0; | |
299 } | |
300 | |
4230 | 301 /** |
7167 | 302 * Free a TLV chain structure |
2086 | 303 * |
304 * Walks the list of TLVs in the passed TLV chain and | |
305 * frees each one. Note that any references to this data | |
306 * should be removed before calling this. | |
307 * | |
8790 | 308 * @param list Chain to be freed |
2086 | 309 */ |
7167 | 310 faim_internal void aim_tlvlist_free(aim_tlvlist_t **list) |
2086 | 311 { |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
312 aim_tlvlist_t *cur; |
2086 | 313 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
314 if (!list || !*list) |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
315 return; |
2086 | 316 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
317 for (cur = *list; cur; ) { |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
318 aim_tlvlist_t *tmp; |
10986 | 319 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
320 freetlv(&cur->tlv); |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
321 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
322 tmp = cur->next; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
323 free(cur); |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
324 cur = tmp; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
325 } |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
326 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
327 list = NULL; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
328 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
329 return; |
2086 | 330 } |
331 | |
332 /** | |
7167 | 333 * Count the number of TLVs in a chain. |
2086 | 334 * |
7167 | 335 * @param list Chain to be counted. |
336 * @return The number of TLVs stored in the passed chain. | |
2086 | 337 */ |
7167 | 338 faim_internal int aim_tlvlist_count(aim_tlvlist_t **list) |
2086 | 339 { |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
340 aim_tlvlist_t *cur; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
341 int count; |
2086 | 342 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
343 if (!list || !*list) |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
344 return 0; |
2086 | 345 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
346 for (cur = *list, count = 0; cur; cur = cur->next) |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
347 count++; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
348 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
349 return count; |
2086 | 350 } |
351 | |
352 /** | |
7167 | 353 * Count the number of bytes in a TLV chain. |
2086 | 354 * |
7167 | 355 * @param list Chain to be sized |
356 * @return The number of bytes that would be needed to | |
357 * write the passed TLV chain to a data buffer. | |
2086 | 358 */ |
7167 | 359 faim_internal int aim_tlvlist_size(aim_tlvlist_t **list) |
2086 | 360 { |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
361 aim_tlvlist_t *cur; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
362 int size; |
2086 | 363 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
364 if (!list || !*list) |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
365 return 0; |
2086 | 366 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
367 for (cur = *list, size = 0; cur; cur = cur->next) |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
368 size += (4 + cur->tlv->length); |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
369 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
370 return size; |
2086 | 371 } |
372 | |
373 /** | |
374 * Adds the passed string as a TLV element of the passed type | |
375 * to the TLV chain. | |
376 * | |
7167 | 377 * @param list Desination chain (%NULL pointer if empty). |
378 * @param type TLV type. | |
8790 | 379 * @param length Length of string to add (not including %NULL). |
380 * @param value String to add. | |
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
381 * @return The size of the value added. |
2086 | 382 */ |
7167 | 383 faim_internal int aim_tlvlist_add_raw(aim_tlvlist_t **list, const fu16_t type, const fu16_t length, const fu8_t *value) |
2086 | 384 { |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
385 aim_tlvlist_t *newtlv, *cur; |
2086 | 386 |
7166 | 387 if (list == NULL) |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
388 return 0; |
2086 | 389 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
390 if (!(newtlv = (aim_tlvlist_t *)malloc(sizeof(aim_tlvlist_t)))) |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
391 return 0; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
392 memset(newtlv, 0x00, sizeof(aim_tlvlist_t)); |
2086 | 393 |
7158 | 394 if (!(newtlv->tlv = createtlv(type, length, NULL))) { |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
395 free(newtlv); |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
396 return 0; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
397 } |
7158 | 398 if (newtlv->tlv->length > 0) { |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
399 newtlv->tlv->value = (fu8_t *)malloc(newtlv->tlv->length); |
7158 | 400 memcpy(newtlv->tlv->value, value, newtlv->tlv->length); |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
401 } |
2086 | 402 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
403 if (!*list) |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
404 *list = newtlv; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
405 else { |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
406 for(cur = *list; cur->next; cur = cur->next) |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
407 ; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
408 cur->next = newtlv; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
409 } |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
410 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
411 return newtlv->tlv->length; |
2086 | 412 } |
413 | |
414 /** | |
7167 | 415 * Add a one byte integer to a TLV chain. |
2821
9467e4ee81be
[gaim-migrate @ 2834]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2421
diff
changeset
|
416 * |
7167 | 417 * @param list Destination chain. |
418 * @param type TLV type to add. | |
419 * @param value Value to add. | |
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
420 * @return The size of the value added. |
2821
9467e4ee81be
[gaim-migrate @ 2834]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2421
diff
changeset
|
421 */ |
7167 | 422 faim_internal int aim_tlvlist_add_8(aim_tlvlist_t **list, const fu16_t type, const fu8_t value) |
2821
9467e4ee81be
[gaim-migrate @ 2834]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2421
diff
changeset
|
423 { |
9467e4ee81be
[gaim-migrate @ 2834]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2421
diff
changeset
|
424 fu8_t v8[1]; |
9467e4ee81be
[gaim-migrate @ 2834]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2421
diff
changeset
|
425 |
7167 | 426 aimutil_put8(v8, value); |
2821
9467e4ee81be
[gaim-migrate @ 2834]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2421
diff
changeset
|
427 |
7167 | 428 return aim_tlvlist_add_raw(list, type, 1, v8); |
2821
9467e4ee81be
[gaim-migrate @ 2834]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2421
diff
changeset
|
429 } |
9467e4ee81be
[gaim-migrate @ 2834]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2421
diff
changeset
|
430 |
9467e4ee81be
[gaim-migrate @ 2834]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2421
diff
changeset
|
431 /** |
7167 | 432 * Add a two byte integer to a TLV chain. |
2086 | 433 * |
7167 | 434 * @param list Destination chain. |
435 * @param type TLV type to add. | |
436 * @param value Value to add. | |
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
437 * @return The size of the value added. |
2086 | 438 */ |
7167 | 439 faim_internal int aim_tlvlist_add_16(aim_tlvlist_t **list, const fu16_t type, const fu16_t value) |
2086 | 440 { |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
441 fu8_t v16[2]; |
2086 | 442 |
7167 | 443 aimutil_put16(v16, value); |
2086 | 444 |
7167 | 445 return aim_tlvlist_add_raw(list, type, 2, v16); |
2086 | 446 } |
447 | |
448 /** | |
7167 | 449 * Add a four byte integer to a TLV chain. |
2086 | 450 * |
7167 | 451 * @param list Destination chain. |
452 * @param type TLV type to add. | |
453 * @param value Value to add. | |
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
454 * @return The size of the value added. |
2086 | 455 */ |
7167 | 456 faim_internal int aim_tlvlist_add_32(aim_tlvlist_t **list, const fu16_t type, const fu32_t value) |
2086 | 457 { |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
458 fu8_t v32[4]; |
2086 | 459 |
7167 | 460 aimutil_put32(v32, value); |
2086 | 461 |
7167 | 462 return aim_tlvlist_add_raw(list, type, 4, v32); |
2086 | 463 } |
464 | |
465 /** | |
10986 | 466 * Add a string to a TLV chain. |
467 * | |
468 * @param list Destination chain. | |
469 * @param type TLV type to add. | |
470 * @param value Value to add. | |
471 * @return The size of the value added. | |
472 */ | |
10991 | 473 faim_internal int aim_tlvlist_add_str(aim_tlvlist_t **list, const fu16_t type, const char *value) |
10986 | 474 { |
10990 | 475 return aim_tlvlist_add_raw(list, type, strlen(value), (fu8_t *)value); |
10986 | 476 } |
477 | |
478 /** | |
2086 | 479 * Adds a block of capability blocks to a TLV chain. The bitfield |
480 * passed in should be a bitwise %OR of any of the %AIM_CAPS constants: | |
481 * | |
7158 | 482 * %AIM_CAPS_BUDDYICON Supports Buddy Icons |
8092 | 483 * %AIM_CAPS_TALK Supports Voice Chat |
7158 | 484 * %AIM_CAPS_IMIMAGE Supports DirectIM/IMImage |
485 * %AIM_CAPS_CHAT Supports Chat | |
486 * %AIM_CAPS_GETFILE Supports Get File functions | |
487 * %AIM_CAPS_SENDFILE Supports Send File functions | |
2086 | 488 * |
7158 | 489 * @param list Destination chain |
490 * @param type TLV type to add | |
491 * @param caps Bitfield of capability flags to send | |
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
492 * @return The size of the value added. |
2086 | 493 */ |
7167 | 494 faim_internal int aim_tlvlist_add_caps(aim_tlvlist_t **list, const fu16_t type, const fu32_t caps) |
2086 | 495 { |
2866
6d62d4520460
[gaim-migrate @ 2879]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2821
diff
changeset
|
496 fu8_t buf[16*16]; /* XXX icky fixed length buffer */ |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
497 aim_bstream_t bs; |
2086 | 498 |
2421
95b4ec08abec
[gaim-migrate @ 2434]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2270
diff
changeset
|
499 if (!caps) |
95b4ec08abec
[gaim-migrate @ 2434]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2270
diff
changeset
|
500 return 0; /* nothing there anyway */ |
95b4ec08abec
[gaim-migrate @ 2434]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2270
diff
changeset
|
501 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
502 aim_bstream_init(&bs, buf, sizeof(buf)); |
2086 | 503 |
11285 | 504 aimbs_putcaps(&bs, caps); |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
505 |
7167 | 506 return aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf); |
2086 | 507 } |
508 | |
7167 | 509 /** |
510 * Adds the given userinfo struct to a TLV chain. | |
511 * | |
512 * @param list Destination chain. | |
513 * @param type TLV type to add. | |
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
514 * @return The size of the value added. |
7167 | 515 */ |
516 faim_internal int aim_tlvlist_add_userinfo(aim_tlvlist_t **list, fu16_t type, aim_userinfo_t *userinfo) | |
2270
d82efea341ef
[gaim-migrate @ 2280]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2246
diff
changeset
|
517 { |
d82efea341ef
[gaim-migrate @ 2280]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2246
diff
changeset
|
518 fu8_t buf[1024]; /* bleh */ |
d82efea341ef
[gaim-migrate @ 2280]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2246
diff
changeset
|
519 aim_bstream_t bs; |
d82efea341ef
[gaim-migrate @ 2280]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2246
diff
changeset
|
520 |
d82efea341ef
[gaim-migrate @ 2280]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2246
diff
changeset
|
521 aim_bstream_init(&bs, buf, sizeof(buf)); |
d82efea341ef
[gaim-migrate @ 2280]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2246
diff
changeset
|
522 |
7167 | 523 aim_putuserinfo(&bs, userinfo); |
2270
d82efea341ef
[gaim-migrate @ 2280]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2246
diff
changeset
|
524 |
7167 | 525 return aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf); |
2270
d82efea341ef
[gaim-migrate @ 2280]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2246
diff
changeset
|
526 } |
d82efea341ef
[gaim-migrate @ 2280]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2246
diff
changeset
|
527 |
2086 | 528 /** |
8225 | 529 * Adds the given chatroom info to a TLV chain. |
530 * | |
531 * @param list Destination chain. | |
532 * @param type TLV type to add. | |
533 * @param roomname The name of the chat. | |
534 * @param instance The instance. | |
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
535 * @return The size of the value added. |
8225 | 536 */ |
537 faim_internal int aim_tlvlist_add_chatroom(aim_tlvlist_t **list, fu16_t type, fu16_t exchange, const char *roomname, fu16_t instance) | |
538 { | |
539 fu8_t *buf; | |
540 int len; | |
541 aim_bstream_t bs; | |
542 | |
543 len = 2 + 1 + strlen(roomname) + 2; | |
10986 | 544 |
8225 | 545 if (!(buf = malloc(len))) |
546 return 0; | |
547 | |
548 aim_bstream_init(&bs, buf, len); | |
549 | |
550 aimbs_put16(&bs, exchange); | |
551 aimbs_put8(&bs, strlen(roomname)); | |
10990 | 552 aimbs_putstr(&bs, roomname); |
8225 | 553 aimbs_put16(&bs, instance); |
554 | |
555 len = aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf); | |
556 | |
557 free(buf); | |
558 | |
559 return len; | |
560 } | |
561 | |
562 /** | |
2086 | 563 * Adds a TLV with a zero length to a TLV chain. |
564 * | |
7167 | 565 * @param list Destination chain. |
566 * @param type TLV type to add. | |
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8225
diff
changeset
|
567 * @return The size of the value added. |
2086 | 568 */ |
7167 | 569 faim_internal int aim_tlvlist_add_noval(aim_tlvlist_t **list, const fu16_t type) |
2086 | 570 { |
7167 | 571 return aim_tlvlist_add_raw(list, type, 0, NULL); |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
572 } |
2086 | 573 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
574 /* |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
575 * Note that the inner TLV chain will not be modifiable as a tlvchain once |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
576 * it is written using this. Or rather, it can be, but updates won't be |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
577 * made to this. |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
578 * |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
579 * XXX should probably support sublists for real. |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
580 * |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
581 * This is so neat. |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
582 * |
8790 | 583 * @param list Destination chain. |
584 * @param type TLV type to add. | |
585 * @param t1 The TLV chain you want to write. | |
8794 | 586 * @return The number of bytes written to the destination TLV chain. |
587 * 0 is returned if there was an error or if the destination | |
588 * TLV chain has length 0. | |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
589 */ |
7167 | 590 faim_internal int aim_tlvlist_add_frozentlvlist(aim_tlvlist_t **list, fu16_t type, aim_tlvlist_t **tl) |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
591 { |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
592 fu8_t *buf; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
593 int buflen; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
594 aim_bstream_t bs; |
2086 | 595 |
7167 | 596 buflen = aim_tlvlist_size(tl); |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
597 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
598 if (buflen <= 0) |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
599 return 0; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
600 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
601 if (!(buf = malloc(buflen))) |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
602 return 0; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
603 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
604 aim_bstream_init(&bs, buf, buflen); |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
605 |
7167 | 606 aim_tlvlist_write(&bs, tl); |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
607 |
7167 | 608 aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf); |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
609 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
610 free(buf); |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
611 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
612 return buflen; |
2086 | 613 } |
614 | |
615 /** | |
7166 | 616 * Substitute a TLV of a given type with a new TLV of the same type. If |
617 * you attempt to replace a TLV that does not exist, this function will | |
7167 | 618 * just add a new TLV as if you called aim_tlvlist_add_raw(). |
7166 | 619 * |
620 * @param list Desination chain (%NULL pointer if empty). | |
621 * @param type TLV type. | |
622 * @param length Length of string to add (not including %NULL). | |
623 * @param value String to add. | |
624 * @return The length of the TLV. | |
625 */ | |
626 faim_internal int aim_tlvlist_replace_raw(aim_tlvlist_t **list, const fu16_t type, const fu16_t length, const fu8_t *value) | |
627 { | |
628 aim_tlvlist_t *cur; | |
629 | |
630 if (list == NULL) | |
631 return 0; | |
632 | |
633 for (cur = *list; ((cur != NULL) && (cur->tlv->type != type)); cur = cur->next); | |
634 if (cur == NULL) | |
7167 | 635 return aim_tlvlist_add_raw(list, type, length, value); |
7166 | 636 |
637 free(cur->tlv->value); | |
638 cur->tlv->length = length; | |
639 if (cur->tlv->length > 0) { | |
640 cur->tlv->value = (fu8_t *)malloc(cur->tlv->length); | |
641 memcpy(cur->tlv->value, value, cur->tlv->length); | |
642 } else | |
643 cur->tlv->value = NULL; | |
644 | |
645 return cur->tlv->length; | |
646 } | |
647 | |
648 /** | |
11159 | 649 * Substitute a TLV of a given type with a new TLV of the same type. If |
650 * you attempt to replace a TLV that does not exist, this function will | |
10993 | 651 * just add a new TLV as if you called aim_tlvlist_add_str(). |
652 * | |
653 * @param list Desination chain (%NULL pointer if empty). | |
654 * @param type TLV type. | |
655 * @param str String to add. | |
656 * @return The length of the TLV. | |
657 */ | |
658 faim_internal int aim_tlvlist_replace_str(aim_tlvlist_t **list, const fu16_t type, const char *str) | |
659 { | |
11159 | 660 return aim_tlvlist_replace_raw(list, type, strlen(str), (const guchar *)str); |
10993 | 661 } |
662 | |
663 /** | |
11159 | 664 * Substitute a TLV of a given type with a new TLV of the same type. If |
665 * you attempt to replace a TLV that does not exist, this function will | |
7167 | 666 * just add a new TLV as if you called aim_tlvlist_add_raw(). |
7166 | 667 * |
668 * @param list Desination chain (%NULL pointer if empty). | |
669 * @param type TLV type. | |
670 * @return The length of the TLV. | |
671 */ | |
672 faim_internal int aim_tlvlist_replace_noval(aim_tlvlist_t **list, const fu16_t type) | |
673 { | |
674 return aim_tlvlist_replace_raw(list, type, 0, NULL); | |
675 } | |
676 | |
677 /** | |
11159 | 678 * Substitute a TLV of a given type with a new TLV of the same type. If |
679 * you attempt to replace a TLV that does not exist, this function will | |
7167 | 680 * just add a new TLV as if you called aim_tlvlist_add_raw(). |
7166 | 681 * |
682 * @param list Desination chain (%NULL pointer if empty). | |
683 * @param type TLV type. | |
684 * @param value 8 bit value to add. | |
685 * @return The length of the TLV. | |
686 */ | |
687 faim_internal int aim_tlvlist_replace_8(aim_tlvlist_t **list, const fu16_t type, const fu8_t value) | |
688 { | |
689 fu8_t v8[1]; | |
690 | |
691 aimutil_put8(v8, value); | |
692 | |
693 return aim_tlvlist_replace_raw(list, type, 1, v8); | |
694 } | |
695 | |
696 /** | |
697 * Substitute a TLV of a given type with a new TLV of the same type. If | |
698 * you attempt to replace a TLV that does not exist, this function will | |
7167 | 699 * just add a new TLV as if you called aim_tlvlist_add_raw(). |
7166 | 700 * |
701 * @param list Desination chain (%NULL pointer if empty). | |
702 * @param type TLV type. | |
703 * @param value 32 bit value to add. | |
704 * @return The length of the TLV. | |
705 */ | |
706 faim_internal int aim_tlvlist_replace_32(aim_tlvlist_t **list, const fu16_t type, const fu32_t value) | |
707 { | |
708 fu8_t v32[4]; | |
709 | |
710 aimutil_put32(v32, value); | |
711 | |
712 return aim_tlvlist_replace_raw(list, type, 4, v32); | |
713 } | |
714 | |
715 /** | |
716 * Remove a TLV of a given type. If you attempt to remove a TLV that | |
717 * does not exist, nothing happens. | |
718 * | |
719 * @param list Desination chain (%NULL pointer if empty). | |
720 * @param type TLV type. | |
721 */ | |
722 faim_internal void aim_tlvlist_remove(aim_tlvlist_t **list, const fu16_t type) | |
723 { | |
724 aim_tlvlist_t *del; | |
725 | |
726 if (!list || !(*list)) | |
727 return; | |
728 | |
729 /* Remove the item from the list */ | |
730 if ((*list)->tlv->type == type) { | |
731 del = *list; | |
732 *list = (*list)->next; | |
733 } else { | |
734 aim_tlvlist_t *cur; | |
735 for (cur=*list; (cur->next && (cur->next->tlv->type!=type)); cur=cur->next); | |
736 if (!cur->next) | |
737 return; | |
738 del = cur->next; | |
739 cur->next = del->next; | |
740 } | |
741 | |
742 /* Free the removed item */ | |
743 free(del->tlv->value); | |
744 free(del->tlv); | |
745 free(del); | |
746 } | |
747 | |
748 /** | |
8794 | 749 * Write a TLV chain into a data buffer. |
2086 | 750 * |
751 * Copies a TLV chain into a raw data buffer, writing only the number | |
752 * of bytes specified. This operation does not free the chain; | |
7167 | 753 * aim_tlvlist_free() must still be called to free up the memory used |
2086 | 754 * by the chain structures. |
755 * | |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
756 * XXX clean this up, make better use of bstreams |
8790 | 757 * |
758 * @param bs Input bstream | |
759 * @param list Source TLV chain | |
8794 | 760 * @return Return 0 if the destination bstream is too small. |
2086 | 761 */ |
7167 | 762 faim_internal int aim_tlvlist_write(aim_bstream_t *bs, aim_tlvlist_t **list) |
2086 | 763 { |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
764 int goodbuflen; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
765 aim_tlvlist_t *cur; |
2086 | 766 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
767 /* do an initial run to test total length */ |
7167 | 768 goodbuflen = aim_tlvlist_size(list); |
2086 | 769 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
770 if (goodbuflen > aim_bstream_empty(bs)) |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
771 return 0; /* not enough buffer */ |
2086 | 772 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
773 /* do the real write-out */ |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
774 for (cur = *list; cur; cur = cur->next) { |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
775 aimbs_put16(bs, cur->tlv->type); |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
776 aimbs_put16(bs, cur->tlv->length); |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
777 if (cur->tlv->length) |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
778 aimbs_putraw(bs, cur->tlv->value, cur->tlv->length); |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
779 } |
2086 | 780 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
781 return 1; /* XXX this is a nonsensical return */ |
2086 | 782 } |
783 | |
784 | |
785 /** | |
7166 | 786 * Grab the Nth TLV of type type in the TLV list list. |
2086 | 787 * |
788 * Returns a pointer to an aim_tlv_t of the specified type; | |
789 * %NULL on error. The @nth parameter is specified starting at %1. | |
790 * In most cases, there will be no more than one TLV of any type | |
791 * in a chain. | |
792 * | |
7167 | 793 * @param list Source chain. |
794 * @param type Requested TLV type. | |
795 * @param nth Index of TLV of type to get. | |
7166 | 796 * @return The TLV you were looking for, or NULL if one could not be found. |
2086 | 797 */ |
7167 | 798 faim_internal aim_tlv_t *aim_tlv_gettlv(aim_tlvlist_t *list, const fu16_t type, const int nth) |
2086 | 799 { |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
800 aim_tlvlist_t *cur; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
801 int i; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
802 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
803 for (cur = list, i = 0; cur; cur = cur->next) { |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
804 if (cur && cur->tlv) { |
7167 | 805 if (cur->tlv->type == type) |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
806 i++; |
7167 | 807 if (i >= nth) |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
808 return cur->tlv; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
809 } |
2086 | 810 } |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
811 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
812 return NULL; |
2086 | 813 } |
814 | |
815 /** | |
9933 | 816 * Get the length of the data of the nth TLV in the given TLV chain. |
817 * | |
818 * @param list Source chain. | |
819 * @param type Requested TLV type. | |
820 * @param nth Index of TLV of type to get. | |
821 * @return The length of the data in this TLV, or -1 if the TLV could not be | |
822 * found. Unless -1 is returned, this value will be 2 bytes. | |
823 */ | |
824 faim_internal int aim_tlv_getlength(aim_tlvlist_t *list, const fu16_t type, const int nth) | |
825 { | |
826 aim_tlvlist_t *cur; | |
827 int i; | |
828 | |
829 for (cur = list, i = 0; cur; cur = cur->next) { | |
830 if (cur && cur->tlv) { | |
831 if (cur->tlv->type == type) | |
832 i++; | |
833 if (i >= nth) | |
834 return cur->tlv->length; | |
835 } | |
836 } | |
837 | |
838 return -1; | |
839 } | |
840 | |
841 /** | |
7167 | 842 * Retrieve the data from the nth TLV in the given TLV chain as a string. |
2086 | 843 * |
7167 | 844 * @param list Source TLV chain. |
845 * @param type TLV type to search for. | |
846 * @param nth Index of TLV to return. | |
11159 | 847 * @return The value of the TLV you were looking for, or NULL if one could |
848 * not be found. This is a dynamic buffer and must be freed by the | |
7167 | 849 * caller. |
2086 | 850 */ |
7167 | 851 faim_internal char *aim_tlv_getstr(aim_tlvlist_t *list, const fu16_t type, const int nth) |
2086 | 852 { |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
853 aim_tlv_t *tlv; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
854 char *newstr; |
2086 | 855 |
7167 | 856 if (!(tlv = aim_tlv_gettlv(list, type, nth))) |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
857 return NULL; |
2086 | 858 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
859 newstr = (char *) malloc(tlv->length + 1); |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
860 memcpy(newstr, tlv->value, tlv->length); |
7011 | 861 newstr[tlv->length] = '\0'; |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
862 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
863 return newstr; |
2086 | 864 } |
865 | |
866 /** | |
7167 | 867 * Retrieve the data from the nth TLV in the given TLV chain as an 8bit |
868 * integer. | |
2086 | 869 * |
7167 | 870 * @param list Source TLV chain. |
871 * @param type TLV type to search for. | |
872 * @param nth Index of TLV to return. | |
873 * @return The value the TLV you were looking for, or 0 if one could | |
874 * not be found. | |
2086 | 875 */ |
7167 | 876 faim_internal fu8_t aim_tlv_get8(aim_tlvlist_t *list, const fu16_t type, const int nth) |
2086 | 877 { |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
878 aim_tlv_t *tlv; |
2086 | 879 |
7167 | 880 if (!(tlv = aim_tlv_gettlv(list, type, nth))) |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
881 return 0; /* erm */ |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
882 return aimutil_get8(tlv->value); |
2086 | 883 } |
884 | |
885 /** | |
7167 | 886 * Retrieve the data from the nth TLV in the given TLV chain as a 16bit |
887 * integer. | |
2086 | 888 * |
7167 | 889 * @param list Source TLV chain. |
890 * @param type TLV type to search for. | |
891 * @param nth Index of TLV to return. | |
892 * @return The value the TLV you were looking for, or 0 if one could | |
893 * not be found. | |
2086 | 894 */ |
7167 | 895 faim_internal fu16_t aim_tlv_get16(aim_tlvlist_t *list, const fu16_t type, const int nth) |
2086 | 896 { |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
897 aim_tlv_t *tlv; |
2086 | 898 |
7167 | 899 if (!(tlv = aim_tlv_gettlv(list, type, nth))) |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
900 return 0; /* erm */ |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
901 return aimutil_get16(tlv->value); |
2086 | 902 } |
903 | |
904 /** | |
7167 | 905 * Retrieve the data from the nth TLV in the given TLV chain as a 32bit |
906 * integer. | |
2086 | 907 * |
7167 | 908 * @param list Source TLV chain. |
909 * @param type TLV type to search for. | |
910 * @param nth Index of TLV to return. | |
911 * @return The value the TLV you were looking for, or 0 if one could | |
912 * not be found. | |
2086 | 913 */ |
7167 | 914 faim_internal fu32_t aim_tlv_get32(aim_tlvlist_t *list, const fu16_t type, const int nth) |
2086 | 915 { |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
916 aim_tlv_t *tlv; |
2086 | 917 |
7167 | 918 if (!(tlv = aim_tlv_gettlv(list, type, nth))) |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
919 return 0; /* erm */ |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
920 return aimutil_get32(tlv->value); |
2086 | 921 } |