Mercurial > pidgin
comparison src/protocols/oscar/misc.c @ 2246:933346315b9b
[gaim-migrate @ 2256]
heh.
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Sun, 09 Sep 2001 10:07:14 +0000 |
parents | edf8c5a70e5b |
children | 227cc42ffa6e |
comparison
equal
deleted
inserted
replaced
2245:31157c54fe6e | 2246:933346315b9b |
---|---|
20 * Should set your current idle time in seconds. Idealy, OSCAR should | 20 * Should set your current idle time in seconds. Idealy, OSCAR should |
21 * do this for us. But, it doesn't. The client must call this to set idle | 21 * do this for us. But, it doesn't. The client must call this to set idle |
22 * time. | 22 * time. |
23 * | 23 * |
24 */ | 24 */ |
25 faim_export unsigned long aim_bos_setidle(struct aim_session_t *sess, | 25 faim_export int aim_bos_setidle(aim_session_t *sess, aim_conn_t *conn, fu32_t idletime) |
26 struct aim_conn_t *conn, | 26 { |
27 u_long idletime) | 27 return aim_genericreq_l(sess, conn, 0x0001, 0x0011, &idletime); |
28 { | |
29 return aim_genericreq_l(sess, conn, 0x0001, 0x0011, &idletime); | |
30 } | 28 } |
31 | 29 |
32 | 30 |
33 /* | 31 /* |
34 * aim_bos_changevisibility(conn, changtype, namelist) | 32 * aim_bos_changevisibility(conn, changtype, namelist) |
54 * - Block all users: Send an AIM_VISIBILITYCHANGE_PERMITADD with only | 52 * - Block all users: Send an AIM_VISIBILITYCHANGE_PERMITADD with only |
55 * yourself in the list | 53 * yourself in the list |
56 * - Block the users below: Send an AIM_VISIBILITYCHANGE_DENYADD with | 54 * - Block the users below: Send an AIM_VISIBILITYCHANGE_DENYADD with |
57 * the list of users to be blocked | 55 * the list of users to be blocked |
58 * | 56 * |
59 * | 57 * XXX ye gods. |
60 */ | 58 */ |
61 faim_export unsigned long aim_bos_changevisibility(struct aim_session_t *sess, | 59 faim_export int aim_bos_changevisibility(aim_session_t *sess, aim_conn_t *conn, int changetype, const char *denylist) |
62 struct aim_conn_t *conn, | 60 { |
63 int changetype, | 61 aim_frame_t *fr; |
64 char *denylist) | 62 int packlen = 0; |
65 { | 63 fu16_t subtype; |
66 struct command_tx_struct *newpacket; | 64 char *localcpy = NULL, *tmpptr = NULL; |
67 int packlen = 0; | 65 int i; |
68 u_short subtype; | 66 int listcount; |
69 | 67 aim_snacid_t snacid; |
70 char *localcpy = NULL; | 68 |
71 char *tmpptr = NULL; | 69 if (!denylist) |
72 int i,j; | 70 return -EINVAL; |
73 int listcount; | 71 |
74 | 72 if (changetype == AIM_VISIBILITYCHANGE_PERMITADD) |
75 if (!denylist) | 73 subtype = 0x05; |
76 return 0; | 74 else if (changetype == AIM_VISIBILITYCHANGE_PERMITREMOVE) |
77 | 75 subtype = 0x06; |
78 localcpy = (char *) malloc(strlen(denylist)+1); | 76 else if (changetype == AIM_VISIBILITYCHANGE_DENYADD) |
79 memcpy(localcpy, denylist, strlen(denylist)+1); | 77 subtype = 0x07; |
80 | 78 else if (changetype == AIM_VISIBILITYCHANGE_DENYREMOVE) |
81 listcount = aimutil_itemcnt(localcpy, '&'); | 79 subtype = 0x08; |
82 packlen = aimutil_tokslen(localcpy, 99, '&') + listcount + 9; | 80 else |
83 | 81 return -EINVAL; |
84 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, packlen))) | 82 |
85 return -1; | 83 localcpy = strdup(denylist); |
86 | 84 |
87 newpacket->lock = 1; | 85 listcount = aimutil_itemcnt(localcpy, '&'); |
88 | 86 packlen = aimutil_tokslen(localcpy, 99, '&') + listcount + 9; |
89 switch(changetype) | 87 |
90 { | 88 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, packlen))) { |
91 case AIM_VISIBILITYCHANGE_PERMITADD: subtype = 0x05; break; | 89 free(localcpy); |
92 case AIM_VISIBILITYCHANGE_PERMITREMOVE: subtype = 0x06; break; | 90 return -ENOMEM; |
93 case AIM_VISIBILITYCHANGE_DENYADD: subtype = 0x07; break; | 91 } |
94 case AIM_VISIBILITYCHANGE_DENYREMOVE: subtype = 0x08; break; | 92 |
95 default: | 93 snacid = aim_cachesnac(sess, 0x0009, subtype, 0x0000, NULL, 0); |
96 free(newpacket->data); | 94 aim_putsnac(&fr->data, 0x0009, subtype, 0x00, snacid); |
97 free(newpacket); | 95 |
98 return 0; | 96 for (i = 0; (i < (listcount - 1)) && (i < 99); i++) { |
99 } | 97 tmpptr = aimutil_itemidx(localcpy, i, '&'); |
100 | 98 |
101 /* We actually DO NOT send a SNAC ID with this one! */ | 99 aimbs_put8(&fr->data, strlen(tmpptr)); |
102 aim_putsnac(newpacket->data, 0x0009, subtype, 0x00, 0); | 100 aimbs_putraw(&fr->data, tmpptr, strlen(tmpptr)); |
103 | 101 |
104 j = 10; /* the next byte */ | 102 free(tmpptr); |
105 | 103 } |
106 for (i=0; (i < (listcount - 1)) && (i < 99); i++) | 104 free(localcpy); |
107 { | 105 |
108 tmpptr = aimutil_itemidx(localcpy, i, '&'); | 106 aim_tx_enqueue(sess, fr); |
109 | 107 |
110 newpacket->data[j] = strlen(tmpptr); | 108 return 0; |
111 memcpy(&(newpacket->data[j+1]), tmpptr, strlen(tmpptr)); | |
112 j += strlen(tmpptr)+1; | |
113 free(tmpptr); | |
114 } | |
115 free(localcpy); | |
116 | |
117 newpacket->lock = 0; | |
118 | |
119 aim_tx_enqueue(sess, newpacket); | |
120 | |
121 return (sess->snac_nextid); /* dont increment */ | |
122 | |
123 } | 109 } |
124 | 110 |
125 | 111 |
126 | 112 |
127 /* | 113 /* |
134 * TODO: Clean this up. | 120 * TODO: Clean this up. |
135 * | 121 * |
136 * XXX: I can't stress the TODO enough. | 122 * XXX: I can't stress the TODO enough. |
137 * | 123 * |
138 */ | 124 */ |
139 faim_export unsigned long aim_bos_setbuddylist(struct aim_session_t *sess, | 125 faim_export int aim_bos_setbuddylist(aim_session_t *sess, aim_conn_t *conn, const char *buddy_list) |
140 struct aim_conn_t *conn, | 126 { |
141 char *buddy_list) | 127 aim_frame_t *fr; |
142 { | 128 aim_snacid_t snacid; |
143 int i, j; | 129 int i, len = 0; |
144 | 130 char *localcpy = NULL; |
145 struct command_tx_struct *newpacket; | 131 char *tmpptr = NULL; |
146 | 132 |
147 int len = 0; | 133 if (!buddy_list || !(localcpy = strdup(buddy_list))) |
148 | 134 return -EINVAL; |
149 char *localcpy = NULL; | 135 |
150 char *tmpptr = NULL; | 136 i = 0; |
151 | 137 tmpptr = strtok(localcpy, "&"); |
152 len = 10; /* 10B SNAC headers */ | 138 while ((tmpptr != NULL) && (i < 150)) { |
153 | 139 faimdprintf(sess, 2, "---adding %d: %s (%d)\n", i, tmpptr, strlen(tmpptr)); |
154 if (!buddy_list || !(localcpy = (char *) malloc(strlen(buddy_list)+1))) | 140 len += 1+strlen(tmpptr); |
155 return -1; | 141 i++; |
156 strncpy(localcpy, buddy_list, strlen(buddy_list)+1); | 142 tmpptr = strtok(NULL, "&"); |
157 | 143 } |
158 i = 0; | 144 |
159 tmpptr = strtok(localcpy, "&"); | 145 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+len))) |
160 while ((tmpptr != NULL) && (i < 150)) { | 146 return -ENOMEM; |
161 faimdprintf(sess, 2, "---adding %d: %s (%d)\n", i, tmpptr, strlen(tmpptr)); | 147 |
162 len += 1+strlen(tmpptr); | 148 snacid = aim_cachesnac(sess, 0x0003, 0x0004, 0x0000, NULL, 0); |
163 i++; | 149 |
164 tmpptr = strtok(NULL, "&"); | 150 aim_putsnac(&fr->data, 0x0003, 0x0004, 0x0000, snacid); |
165 } | 151 |
166 faimdprintf(sess, 2, "*** send buddy list len: %d (%x)\n", len, len); | 152 strncpy(localcpy, buddy_list, strlen(buddy_list)+1); |
167 | 153 i = 0; |
168 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, len))) | 154 tmpptr = strtok(localcpy, "&"); |
169 return -1; | 155 while ((tmpptr != NULL) & (i < 150)) { |
170 | 156 faimdprintf(sess, 2, "---adding %d: %s (%d)\n", i, tmpptr, strlen(tmpptr)); |
171 newpacket->lock = 1; | 157 |
172 | 158 aimbs_put8(&fr->data, strlen(tmpptr)); |
173 aim_putsnac(newpacket->data, 0x0003, 0x0004, 0x0000, 0); | 159 aimbs_putraw(&fr->data, tmpptr, strlen(tmpptr)); |
174 | 160 i++; |
175 j = 10; /* the next byte */ | 161 tmpptr = strtok(NULL, "&"); |
176 | 162 } |
177 strncpy(localcpy, buddy_list, strlen(buddy_list)+1); | 163 |
178 i = 0; | 164 aim_tx_enqueue(sess, fr); |
179 tmpptr = strtok(localcpy, "&"); | 165 |
180 while ((tmpptr != NULL) & (i < 150)) { | 166 free(localcpy); |
181 faimdprintf(sess, 2, "---adding %d: %s (%d)\n", i, tmpptr, strlen(tmpptr)); | 167 |
182 newpacket->data[j] = strlen(tmpptr); | 168 return 0; |
183 memcpy(&(newpacket->data[j+1]), tmpptr, strlen(tmpptr)); | |
184 j += 1+strlen(tmpptr); | |
185 i++; | |
186 tmpptr = strtok(NULL, "&"); | |
187 } | |
188 | |
189 newpacket->lock = 0; | |
190 | |
191 aim_tx_enqueue(sess, newpacket); | |
192 | |
193 free(localcpy); | |
194 | |
195 return (sess->snac_nextid); | |
196 } | 169 } |
197 | 170 |
198 /* | 171 /* |
199 * aim_bos_setprofile(profile) | 172 * aim_bos_setprofile(profile) |
200 * | 173 * |
201 * Gives BOS your profile. | 174 * Gives BOS your profile. |
202 * | 175 * |
203 * | 176 * |
204 */ | 177 */ |
205 faim_export unsigned long aim_bos_setprofile(struct aim_session_t *sess, | 178 faim_export int aim_bos_setprofile(aim_session_t *sess, aim_conn_t *conn, const char *profile, const char *awaymsg, fu16_t caps) |
206 struct aim_conn_t *conn, | 179 { |
207 const char *profile, | 180 static const char defencoding[] = {"text/aolrtf; charset=\"us-ascii\""}; |
208 const char *awaymsg, | 181 aim_frame_t *fr; |
209 unsigned short caps) | 182 aim_tlvlist_t *tl = NULL; |
210 { | 183 aim_snacid_t snacid; |
211 struct command_tx_struct *newpacket; | 184 |
212 int i = 0, tmp, caplen; | 185 /* Build to packet first to get real length */ |
213 static const char defencoding[] = {"text/aolrtf; charset=\"us-ascii\""}; | 186 if (profile) { |
214 | 187 aim_addtlvtochain_raw(&tl, 0x0001, strlen(defencoding), defencoding); |
215 i = 10; | 188 aim_addtlvtochain_raw(&tl, 0x0002, strlen(profile), profile); |
216 if (profile) | 189 } |
217 i += 4+strlen(defencoding)+4+strlen(profile); | 190 |
218 if (awaymsg) | 191 if (awaymsg) { |
219 i += 4+strlen(defencoding)+4+strlen(awaymsg); | 192 aim_addtlvtochain_raw(&tl, 0x0003, strlen(defencoding), defencoding); |
220 i += 4+512; /* for capabilities */ | 193 aim_addtlvtochain_raw(&tl, 0x0004, strlen(awaymsg), awaymsg); |
221 | 194 } |
222 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, i))) | 195 |
223 return -1; | 196 aim_addtlvtochain_caps(&tl, 0x0005, caps); |
224 | 197 |
225 i = aim_putsnac(newpacket->data, 0x0002, 0x004, 0x0000, sess->snac_nextid); | 198 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + aim_sizetlvchain(&tl)))) |
226 | 199 return -ENOMEM; |
227 if (profile) { | 200 |
228 i += aim_puttlv_str(newpacket->data+i, 0x0001, strlen(defencoding), defencoding); | 201 snacid = aim_cachesnac(sess, 0x0002, 0x0004, 0x0000, NULL, 0); |
229 i += aim_puttlv_str(newpacket->data+i, 0x0002, strlen(profile), profile); | 202 |
230 } | 203 aim_putsnac(&fr->data, 0x0002, 0x004, 0x0000, snacid); |
231 | 204 aim_writetlvchain(&fr->data, &tl); |
232 if (awaymsg) { | 205 aim_freetlvchain(&tl); |
233 i += aim_puttlv_str(newpacket->data+i, 0x0003, strlen(defencoding), defencoding); | 206 |
234 i += aim_puttlv_str(newpacket->data+i, 0x0004, strlen(awaymsg), awaymsg); | 207 aim_tx_enqueue(sess, fr); |
235 } | 208 |
236 | 209 return 0; |
237 /* Capability information. */ | |
238 | |
239 tmp = (i += aimutil_put16(newpacket->data+i, 0x0005)); | |
240 i += aimutil_put16(newpacket->data+i, 0x0000); /* rewritten later */ | |
241 i += (caplen = aim_putcap(newpacket->data+i, 512, caps)); | |
242 aimutil_put16(newpacket->data+tmp, caplen); /* rewrite TLV size */ | |
243 | |
244 newpacket->commandlen = i; | |
245 aim_tx_enqueue(sess, newpacket); | |
246 | |
247 return (sess->snac_nextid++); | |
248 } | 210 } |
249 | 211 |
250 /* | 212 /* |
251 * aim_bos_clientready() | 213 * aim_bos_clientready() |
252 * | 214 * |
253 * Send Client Ready. | 215 * Send Client Ready. |
254 * | 216 * |
255 */ | 217 */ |
256 faim_export unsigned long aim_bos_clientready(struct aim_session_t *sess, | 218 faim_export int aim_bos_clientready(aim_session_t *sess, aim_conn_t *conn) |
257 struct aim_conn_t *conn) | 219 { |
258 { | 220 struct aim_tool_version tools[] = { |
259 struct aim_tool_version tools[] = { | 221 {0x0001, 0x0003, AIM_TOOL_WIN32, 0x0686}, |
260 {0x0001, 0x0003, AIM_TOOL_WIN32, 0x0686}, | 222 {0x0002, 0x0001, AIM_TOOL_WIN32, 0x0001}, |
261 {0x0002, 0x0001, AIM_TOOL_WIN32, 0x0001}, | 223 {0x0003, 0x0001, AIM_TOOL_WIN32, 0x0001}, |
262 {0x0003, 0x0001, AIM_TOOL_WIN32, 0x0001}, | 224 {0x0004, 0x0001, AIM_TOOL_WIN32, 0x0001}, |
263 {0x0004, 0x0001, AIM_TOOL_WIN32, 0x0001}, | 225 {0x0006, 0x0001, AIM_TOOL_WIN32, 0x0001}, |
264 {0x0006, 0x0001, AIM_TOOL_WIN32, 0x0001}, | 226 {0x0008, 0x0001, AIM_TOOL_WIN32, 0x0001}, |
265 {0x0008, 0x0001, AIM_TOOL_WIN32, 0x0001}, | 227 {0x0009, 0x0001, AIM_TOOL_WIN32, 0x0001}, |
266 {0x0009, 0x0001, AIM_TOOL_WIN32, 0x0001}, | 228 {0x000a, 0x0001, AIM_TOOL_WIN32, 0x0001}, |
267 {0x000a, 0x0001, AIM_TOOL_WIN32, 0x0001}, | 229 {0x000b, 0x0001, AIM_TOOL_WIN32, 0x0001} |
268 {0x000b, 0x0001, AIM_TOOL_WIN32, 0x0001} | 230 }; |
269 }; | 231 int j; |
270 int i,j; | 232 aim_frame_t *fr; |
271 struct command_tx_struct *newpacket; | 233 aim_snacid_t snacid; |
272 int toolcount = sizeof(tools)/sizeof(struct aim_tool_version); | 234 int toolcount = sizeof(tools)/sizeof(struct aim_tool_version); |
273 | 235 |
274 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 1152))) | 236 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152))) |
275 return -1; | 237 return -ENOMEM; |
276 | 238 |
277 newpacket->lock = 1; | 239 snacid = aim_cachesnac(sess, 0x0001, 0x0002, 0x0000, NULL, 0); |
278 | 240 aim_putsnac(&fr->data, 0x0001, 0x0002, 0x0000, snacid); |
279 i = aim_putsnac(newpacket->data, 0x0001, 0x0002, 0x0000, sess->snac_nextid); | 241 |
280 aim_cachesnac(sess, 0x0001, 0x0002, 0x0000, NULL, 0); | 242 for (j = 0; j < toolcount; j++) { |
281 | 243 aimbs_put16(&fr->data, tools[j].group); |
282 for (j = 0; j < toolcount; j++) { | 244 aimbs_put16(&fr->data, tools[j].version); |
283 i += aimutil_put16(newpacket->data+i, tools[j].group); | 245 aimbs_put16(&fr->data, tools[j].tool); |
284 i += aimutil_put16(newpacket->data+i, tools[j].version); | 246 aimbs_put16(&fr->data, tools[j].toolversion); |
285 i += aimutil_put16(newpacket->data+i, tools[j].tool); | 247 } |
286 i += aimutil_put16(newpacket->data+i, tools[j].toolversion); | 248 |
287 } | 249 aim_tx_enqueue(sess, fr); |
288 | 250 |
289 newpacket->commandlen = i; | 251 return 0; |
290 newpacket->lock = 0; | |
291 | |
292 aim_tx_enqueue(sess, newpacket); | |
293 | |
294 return sess->snac_nextid; | |
295 } | 252 } |
296 | 253 |
297 /* | 254 /* |
298 * Request Rate Information. | 255 * Request Rate Information. |
299 * | 256 * |
300 */ | 257 */ |
301 faim_export unsigned long aim_bos_reqrate(struct aim_session_t *sess, | 258 faim_export int aim_bos_reqrate(aim_session_t *sess, aim_conn_t *conn) |
302 struct aim_conn_t *conn) | 259 { |
303 { | 260 return aim_genericreq_n(sess, conn, 0x0001, 0x0006); |
304 return aim_genericreq_n(sess, conn, 0x0001, 0x0006); | |
305 } | 261 } |
306 | 262 |
307 /* | 263 /* |
308 * Rate Information Response Acknowledge. | 264 * Rate Information Response Acknowledge. |
309 * | 265 * |
310 */ | 266 */ |
311 faim_export unsigned long aim_bos_ackrateresp(struct aim_session_t *sess, | 267 faim_export int aim_bos_ackrateresp(aim_session_t *sess, aim_conn_t *conn) |
312 struct aim_conn_t *conn) | 268 { |
313 { | 269 aim_frame_t *fr; |
314 struct command_tx_struct *newpacket; | 270 aim_snacid_t snacid; |
315 int packlen = 20, i=0; | 271 |
316 | 272 if(!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+10))) |
317 if(!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, packlen))) | 273 return -ENOMEM; |
318 return (sess->snac_nextid); | 274 |
319 | 275 snacid = aim_cachesnac(sess, 0x0001, 0x0008, 0x0000, NULL, 0); |
320 newpacket->lock = 1; | 276 |
321 | 277 aim_putsnac(&fr->data, 0x0001, 0x0008, 0x0000, snacid); |
322 i = aim_putsnac(newpacket->data, 0x0001, 0x0008, 0x0000, 0); | 278 aimbs_put16(&fr->data, 0x0001); |
323 i += aimutil_put16(newpacket->data+i, 0x0001); | 279 aimbs_put16(&fr->data, 0x0002); |
324 i += aimutil_put16(newpacket->data+i, 0x0002); | 280 aimbs_put16(&fr->data, 0x0003); |
325 i += aimutil_put16(newpacket->data+i, 0x0003); | 281 aimbs_put16(&fr->data, 0x0004); |
326 i += aimutil_put16(newpacket->data+i, 0x0004); | 282 aimbs_put16(&fr->data, 0x0005); |
327 i += aimutil_put16(newpacket->data+i, 0x0005); | 283 |
328 | 284 aim_tx_enqueue(sess, fr); |
329 newpacket->commandlen = i; | 285 |
330 newpacket->lock = 0; | 286 return 0; |
331 | |
332 aim_tx_enqueue(sess, newpacket); | |
333 | |
334 return (sess->snac_nextid); | |
335 } | 287 } |
336 | 288 |
337 /* | 289 /* |
338 * aim_bos_setprivacyflags() | 290 * aim_bos_setprivacyflags() |
339 * | 291 * |
341 * | 293 * |
342 * Bit 1: Allows other AIM users to see how long you've been idle. | 294 * Bit 1: Allows other AIM users to see how long you've been idle. |
343 * Bit 2: Allows other AIM users to see how long you've been a member. | 295 * Bit 2: Allows other AIM users to see how long you've been a member. |
344 * | 296 * |
345 */ | 297 */ |
346 faim_export unsigned long aim_bos_setprivacyflags(struct aim_session_t *sess, | 298 faim_export int aim_bos_setprivacyflags(aim_session_t *sess, aim_conn_t *conn, fu32_t flags) |
347 struct aim_conn_t *conn, | 299 { |
348 u_long flags) | 300 return aim_genericreq_l(sess, conn, 0x0001, 0x0014, &flags); |
349 { | |
350 return aim_genericreq_l(sess, conn, 0x0001, 0x0014, &flags); | |
351 } | 301 } |
352 | 302 |
353 /* | 303 /* |
354 * aim_bos_reqpersonalinfo() | 304 * aim_bos_reqpersonalinfo() |
355 * | 305 * |
356 * Requests the current user's information. Can't go generic on this one | 306 */ |
357 * because aparently it uses SNAC flags. | 307 faim_export int aim_bos_reqpersonalinfo(aim_session_t *sess, aim_conn_t *conn) |
358 * | 308 { |
359 */ | 309 return aim_genericreq_n(sess, conn, 0x0001, 0x000e); |
360 faim_export unsigned long aim_bos_reqpersonalinfo(struct aim_session_t *sess, | 310 } |
361 struct aim_conn_t *conn) | 311 |
362 { | 312 faim_export int aim_setversions(aim_session_t *sess, aim_conn_t *conn) |
363 return aim_genericreq_n(sess, conn, 0x0001, 0x000e); | 313 { |
364 } | 314 aim_frame_t *fr; |
365 | 315 aim_snacid_t snacid; |
366 faim_export unsigned long aim_setversions(struct aim_session_t *sess, | 316 static const struct version { |
367 struct aim_conn_t *conn) | 317 fu16_t group; |
368 { | 318 fu16_t version; |
369 struct command_tx_struct *newpacket; | 319 } versions[] = { |
370 int i; | 320 {0x0001, 0x0003}, |
371 | 321 {0x0002, 0x0001}, |
372 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 10 + (4*16)))) | 322 {0x0003, 0x0001}, |
373 return -1; | 323 {0x0004, 0x0001}, |
374 | 324 {0x0006, 0x0001}, |
375 newpacket->lock = 1; | 325 {0x0008, 0x0001}, |
376 | 326 {0x0009, 0x0001}, |
377 i = aim_putsnac(newpacket->data, 0x0001, 0x0017, 0x0000, sess->snac_nextid); | 327 {0x000a, 0x0001}, |
378 aim_cachesnac(sess, 0x0001, 0x0017, 0x0000, NULL, 0); | 328 {0x000b, 0x0002}, |
379 | 329 {0x000c, 0x0001}, |
380 i += aimutil_put16(newpacket->data+i, 0x0001); | 330 {0x0013, 0x0001}, |
381 i += aimutil_put16(newpacket->data+i, 0x0003); | 331 {0x0015, 0x0001}, |
382 | 332 }; |
383 i += aimutil_put16(newpacket->data+i, 0x0002); | 333 int numversions = sizeof(versions) / sizeof(struct version); |
384 i += aimutil_put16(newpacket->data+i, 0x0001); | 334 int i; |
385 | 335 |
386 i += aimutil_put16(newpacket->data+i, 0x0003); | 336 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + (4*numversions)))) |
387 i += aimutil_put16(newpacket->data+i, 0x0001); | 337 return -ENOMEM; |
388 | 338 |
389 i += aimutil_put16(newpacket->data+i, 0x0004); | 339 snacid = aim_cachesnac(sess, 0x0001, 0x0017, 0x0000, NULL, 0); |
390 i += aimutil_put16(newpacket->data+i, 0x0001); | 340 |
391 | 341 aim_putsnac(&fr->data, 0x0001, 0x0017, 0x0000, snacid); |
392 i += aimutil_put16(newpacket->data+i, 0x0006); | 342 for (i = 0; i < numversions; i++) { |
393 i += aimutil_put16(newpacket->data+i, 0x0001); | 343 aimbs_put16(&fr->data, versions[i].group); |
394 | 344 aimbs_put16(&fr->data, versions[i].version); |
395 i += aimutil_put16(newpacket->data+i, 0x0008); | 345 } |
396 i += aimutil_put16(newpacket->data+i, 0x0001); | 346 |
397 | 347 aim_tx_enqueue(sess, fr); |
398 i += aimutil_put16(newpacket->data+i, 0x0009); | 348 |
399 i += aimutil_put16(newpacket->data+i, 0x0001); | 349 return 0; |
400 | |
401 i += aimutil_put16(newpacket->data+i, 0x000a); | |
402 i += aimutil_put16(newpacket->data+i, 0x0001); | |
403 | |
404 i += aimutil_put16(newpacket->data+i, 0x000b); | |
405 i += aimutil_put16(newpacket->data+i, 0x0002); | |
406 | |
407 i += aimutil_put16(newpacket->data+i, 0x000c); | |
408 i += aimutil_put16(newpacket->data+i, 0x0001); | |
409 | |
410 i += aimutil_put16(newpacket->data+i, 0x0013); | |
411 i += aimutil_put16(newpacket->data+i, 0x0001); | |
412 | |
413 i += aimutil_put16(newpacket->data+i, 0x0015); | |
414 i += aimutil_put16(newpacket->data+i, 0x0001); | |
415 | |
416 newpacket->commandlen = i; | |
417 newpacket->lock = 0; | |
418 aim_tx_enqueue(sess, newpacket); | |
419 | |
420 return sess->snac_nextid; | |
421 } | 350 } |
422 | 351 |
423 | 352 |
424 /* | 353 /* |
425 * aim_bos_reqservice(serviceid) | 354 * aim_bos_reqservice(serviceid) |
426 * | 355 * |
427 * Service request. | 356 * Service request. |
428 * | 357 * |
429 */ | 358 */ |
430 faim_export unsigned long aim_bos_reqservice(struct aim_session_t *sess, | 359 faim_export int aim_bos_reqservice(aim_session_t *sess, aim_conn_t *conn, fu16_t serviceid) |
431 struct aim_conn_t *conn, | 360 { |
432 u_short serviceid) | 361 return aim_genericreq_s(sess, conn, 0x0001, 0x0004, &serviceid); |
433 { | |
434 return aim_genericreq_s(sess, conn, 0x0001, 0x0004, &serviceid); | |
435 } | 362 } |
436 | 363 |
437 /* | 364 /* |
438 * aim_bos_nop() | 365 * aim_bos_nop() |
439 * | 366 * |
440 * No-op. WinAIM sends these every 4min or so to keep | 367 * No-op. WinAIM sends these every 4min or so to keep |
441 * the connection alive. Its not real necessary. | 368 * the connection alive. Its not real necessary. |
442 * | 369 * |
443 */ | 370 */ |
444 faim_export unsigned long aim_bos_nop(struct aim_session_t *sess, | 371 faim_export int aim_bos_nop(aim_session_t *sess, aim_conn_t *conn) |
445 struct aim_conn_t *conn) | 372 { |
446 { | 373 return aim_genericreq_n(sess, conn, 0x0001, 0x0016); |
447 return aim_genericreq_n(sess, conn, 0x0001, 0x0016); | |
448 } | 374 } |
449 | 375 |
450 /* | 376 /* |
451 * aim_flap_nop() | 377 * aim_flap_nop() |
452 * | 378 * |
453 * No-op. WinAIM 4.x sends these _every minute_ to keep | 379 * No-op. WinAIM 4.x sends these _every minute_ to keep |
454 * the connection alive. | 380 * the connection alive. |
455 */ | 381 */ |
456 faim_export unsigned long aim_flap_nop(struct aim_session_t *sess, | 382 faim_export int aim_flap_nop(aim_session_t *sess, aim_conn_t *conn) |
457 struct aim_conn_t *conn) | 383 { |
458 { | 384 aim_frame_t *fr; |
459 struct command_tx_struct *newpacket; | 385 |
460 | 386 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x05, 0))) |
461 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0005, 0))) | 387 return -ENOMEM; |
462 return sess->snac_nextid; | 388 |
463 | 389 aim_tx_enqueue(sess, fr); |
464 newpacket->lock = 1; | 390 |
465 newpacket->commandlen = 0; | 391 return 0; |
466 newpacket->lock = 0; | |
467 | |
468 aim_tx_enqueue(sess, newpacket); | |
469 | |
470 return (sess->snac_nextid); | |
471 } | 392 } |
472 | 393 |
473 /* | 394 /* |
474 * aim_bos_reqrights() | 395 * aim_bos_reqrights() |
475 * | 396 * |
476 * Request BOS rights. | 397 * Request BOS rights. |
477 * | 398 * |
478 */ | 399 */ |
479 faim_export unsigned long aim_bos_reqrights(struct aim_session_t *sess, | 400 faim_export int aim_bos_reqrights(aim_session_t *sess, aim_conn_t *conn) |
480 struct aim_conn_t *conn) | 401 { |
481 { | 402 return aim_genericreq_n(sess, conn, 0x0009, 0x0002); |
482 return aim_genericreq_n(sess, conn, 0x0009, 0x0002); | |
483 } | 403 } |
484 | 404 |
485 /* | 405 /* |
486 * aim_bos_reqbuddyrights() | 406 * aim_bos_reqbuddyrights() |
487 * | 407 * |
488 * Request Buddy List rights. | 408 * Request Buddy List rights. |
489 * | 409 * |
490 */ | 410 */ |
491 faim_export unsigned long aim_bos_reqbuddyrights(struct aim_session_t *sess, | 411 faim_export int aim_bos_reqbuddyrights(aim_session_t *sess, aim_conn_t *conn) |
492 struct aim_conn_t *conn) | 412 { |
493 { | 413 return aim_genericreq_n(sess, conn, 0x0003, 0x0002); |
494 return aim_genericreq_n(sess, conn, 0x0003, 0x0002); | |
495 } | 414 } |
496 | 415 |
497 /* | 416 /* |
498 * Send a warning to destsn. | 417 * Send a warning to destsn. |
499 * | 418 * |
501 * AIM_WARN_ANON Send as an anonymous (doesn't count as much) | 420 * AIM_WARN_ANON Send as an anonymous (doesn't count as much) |
502 * | 421 * |
503 * returns -1 on error (couldn't alloc packet), 0 on success. | 422 * returns -1 on error (couldn't alloc packet), 0 on success. |
504 * | 423 * |
505 */ | 424 */ |
506 faim_export int aim_send_warning(struct aim_session_t *sess, struct aim_conn_t *conn, const char *destsn, unsigned long flags) | 425 faim_export int aim_send_warning(aim_session_t *sess, aim_conn_t *conn, const char *destsn, fu32_t flags) |
507 { | 426 { |
508 struct command_tx_struct *newpacket; | 427 aim_frame_t *fr; |
509 int curbyte; | 428 aim_snacid_t snacid; |
510 unsigned short outflags = 0x0000; | 429 fu16_t outflags = 0x0000; |
511 | 430 |
512 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, | 431 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, strlen(destsn)+13))) |
513 strlen(destsn)+13))) | 432 return -ENOMEM; |
514 return -1; | 433 |
515 | 434 snacid = aim_cachesnac(sess, 0x0004, 0x0008, 0x0000, destsn, strlen(destsn)+1); |
516 newpacket->lock = 1; | 435 |
517 | 436 aim_putsnac(&fr->data, 0x0004, 0x0008, 0x0000, snacid); |
518 curbyte = 0; | |
519 curbyte += aim_putsnac(newpacket->data+curbyte, | |
520 0x0004, 0x0008, 0x0000, sess->snac_nextid); | |
521 | 437 |
522 if (flags & AIM_WARN_ANON) | 438 if (flags & AIM_WARN_ANON) |
523 outflags |= 0x0001; | 439 outflags |= 0x0001; |
524 | 440 |
525 curbyte += aimutil_put16(newpacket->data+curbyte, outflags); | 441 aimbs_put16(&fr->data, outflags); |
526 curbyte += aimutil_put8(newpacket->data+curbyte, strlen(destsn)); | 442 aimbs_put8(&fr->data, strlen(destsn)); |
527 curbyte += aimutil_putstr(newpacket->data+curbyte, destsn, strlen(destsn)); | 443 aimbs_putraw(&fr->data, destsn, strlen(destsn)); |
528 | 444 |
529 newpacket->commandlen = curbyte; | 445 aim_tx_enqueue(sess, fr); |
530 newpacket->lock = 0; | |
531 | |
532 aim_tx_enqueue(sess, newpacket); | |
533 | |
534 aim_cachesnac(sess, 0x0004, 0x0008, 0x0000, destsn, strlen(destsn)+1); | |
535 | 446 |
536 return 0; | 447 return 0; |
537 } | 448 } |
538 | 449 |
539 /* | 450 /* |
540 * aim_debugconn_sendconnect() | 451 * aim_debugconn_sendconnect() |
541 * | 452 * |
542 * For aimdebugd. If you don't know what it is, you don't want to. | 453 * For aimdebugd. If you don't know what it is, you don't want to. |
543 */ | 454 */ |
544 faim_export unsigned long aim_debugconn_sendconnect(struct aim_session_t *sess, | 455 faim_export int aim_debugconn_sendconnect(aim_session_t *sess, aim_conn_t *conn) |
545 struct aim_conn_t *conn) | 456 { |
546 { | 457 return aim_genericreq_n(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_DEBUGCONN_CONNECT); |
547 return aim_genericreq_n(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_DEBUGCONN_CONNECT); | |
548 } | 458 } |
549 | 459 |
550 /* | 460 /* |
551 * Generic routine for sending commands. | 461 * Generic routine for sending commands. |
552 * | 462 * |
557 * I had one big function that handled all three cases, but then it broke | 467 * I had one big function that handled all three cases, but then it broke |
558 * and I split it up into three. But then I fixed it. I just never went | 468 * and I split it up into three. But then I fixed it. I just never went |
559 * back to the single. I don't see any advantage to doing it either way. | 469 * back to the single. I don't see any advantage to doing it either way. |
560 * | 470 * |
561 */ | 471 */ |
562 faim_internal unsigned long aim_genericreq_n(struct aim_session_t *sess, | 472 faim_internal int aim_genericreq_n(aim_session_t *sess, aim_conn_t *conn, fu16_t family, fu16_t subtype) |
563 struct aim_conn_t *conn, | 473 { |
564 u_short family, u_short subtype) | 474 aim_frame_t *fr; |
565 { | 475 aim_snacid_t snacid = 0x00000000; |
566 struct command_tx_struct *newpacket; | 476 |
567 | 477 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10))) |
568 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 10))) | 478 return -ENOMEM; |
569 return 0; | 479 |
570 | 480 aim_putsnac(&fr->data, family, subtype, 0x0000, snacid); |
571 newpacket->lock = 1; | 481 |
572 | 482 aim_tx_enqueue(sess, fr); |
573 aim_putsnac(newpacket->data, family, subtype, 0x0000, 0x00000000); | 483 |
574 | 484 return 0; |
575 aim_tx_enqueue(sess, newpacket); | 485 } |
576 | 486 |
577 return sess->snac_nextid; | 487 faim_internal int aim_genericreq_n_snacid(aim_session_t *sess, aim_conn_t *conn, fu16_t family, fu16_t subtype) |
578 } | 488 { |
579 | 489 aim_frame_t *fr; |
580 faim_internal unsigned long aim_genericreq_n_snacid(struct aim_session_t *sess, | 490 aim_snacid_t snacid; |
581 struct aim_conn_t *conn, | 491 |
582 unsigned short family, | 492 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10))) |
583 unsigned short subtype) | 493 return -ENOMEM; |
584 { | 494 |
585 struct command_tx_struct *newpacket; | 495 snacid = aim_cachesnac(sess, family, subtype, 0x0000, NULL, 0); |
586 | 496 aim_putsnac(&fr->data, family, subtype, 0x0000, snacid); |
587 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 10))) | 497 |
588 return 0; | 498 aim_tx_enqueue(sess, fr); |
589 | 499 |
590 newpacket->lock = 1; | 500 return 0; |
591 | 501 } |
592 aim_putsnac(newpacket->data, family, subtype, 0x0000, sess->snac_nextid); | 502 |
593 aim_cachesnac(sess, family, subtype, 0x0000, NULL, 0); | 503 /* |
594 | 504 * |
595 aim_tx_enqueue(sess, newpacket); | 505 * |
596 | 506 */ |
597 return sess->snac_nextid++; | 507 faim_internal int aim_genericreq_l(aim_session_t *sess, aim_conn_t *conn, fu16_t family, fu16_t subtype, fu32_t *longdata) |
598 } | 508 { |
599 | 509 aim_frame_t *fr; |
600 /* | 510 aim_snacid_t snacid; |
601 * | 511 |
602 * | 512 if (!longdata) |
603 */ | 513 return aim_genericreq_n(sess, conn, family, subtype); |
604 faim_internal unsigned long aim_genericreq_l(struct aim_session_t *sess, | 514 |
605 struct aim_conn_t *conn, | 515 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+4))) |
606 u_short family, u_short subtype, | 516 return -ENOMEM; |
607 u_long *longdata) | 517 |
608 { | 518 snacid = aim_cachesnac(sess, family, subtype, 0x0000, NULL, 0); |
609 struct command_tx_struct *newpacket; | 519 |
610 u_long newlong; | 520 aim_putsnac(&fr->data, family, subtype, 0x0000, snacid); |
611 | 521 aimbs_put32(&fr->data, *longdata); |
612 /* If we don't have data, there's no reason to use this function */ | 522 |
613 if (!longdata) | 523 aim_tx_enqueue(sess, fr); |
614 return aim_genericreq_n(sess, conn, family, subtype); | 524 |
615 | 525 return 0; |
616 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 10+sizeof(u_long)))) | 526 } |
617 return -1; | 527 |
618 | 528 faim_internal int aim_genericreq_s(aim_session_t *sess, aim_conn_t *conn, fu16_t family, fu16_t subtype, fu16_t *shortdata) |
619 newpacket->lock = 1; | 529 { |
620 | 530 aim_frame_t *fr; |
621 aim_putsnac(newpacket->data, family, subtype, 0x0000, 0x00000000); | 531 aim_snacid_t snacid; |
622 | 532 |
623 /* copy in data */ | 533 if (!shortdata) |
624 newlong = htonl(*longdata); | 534 return aim_genericreq_n(sess, conn, family, subtype); |
625 memcpy(&(newpacket->data[10]), &newlong, sizeof(u_long)); | 535 |
626 | 536 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+2))) |
627 aim_tx_enqueue(sess, newpacket); | 537 return -ENOMEM; |
628 | 538 |
629 return sess->snac_nextid; | 539 snacid = aim_cachesnac(sess, family, subtype, 0x0000, NULL, 0); |
630 } | 540 |
631 | 541 aim_putsnac(&fr->data, family, subtype, 0x0000, snacid); |
632 faim_internal unsigned long aim_genericreq_s(struct aim_session_t *sess, | 542 aimbs_put16(&fr->data, *shortdata); |
633 struct aim_conn_t *conn, | 543 |
634 u_short family, u_short subtype, | 544 aim_tx_enqueue(sess, fr); |
635 u_short *shortdata) | 545 |
636 { | 546 return 0; |
637 struct command_tx_struct *newpacket; | |
638 u_short newshort; | |
639 | |
640 /* If we don't have data, there's no reason to use this function */ | |
641 if (!shortdata) | |
642 return aim_genericreq_n(sess, conn, family, subtype); | |
643 | |
644 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 10+sizeof(u_short)))) | |
645 return -1; | |
646 | |
647 newpacket->lock = 1; | |
648 | |
649 aim_putsnac(newpacket->data, family, subtype, 0x0000, 0x00000000); | |
650 | |
651 /* copy in data */ | |
652 newshort = htons(*shortdata); | |
653 memcpy(&(newpacket->data[10]), &newshort, sizeof(u_short)); | |
654 | |
655 aim_tx_enqueue(sess, newpacket); | |
656 | |
657 return sess->snac_nextid; | |
658 } | 547 } |
659 | 548 |
660 /* | 549 /* |
661 * aim_bos_reqlocaterights() | 550 * aim_bos_reqlocaterights() |
662 * | 551 * |
663 * Request Location services rights. | 552 * Request Location services rights. |
664 * | 553 * |
665 */ | 554 */ |
666 faim_export unsigned long aim_bos_reqlocaterights(struct aim_session_t *sess, | 555 faim_export int aim_bos_reqlocaterights(aim_session_t *sess, aim_conn_t *conn) |
667 struct aim_conn_t *conn) | 556 { |
668 { | 557 return aim_genericreq_n(sess, conn, 0x0002, 0x0002); |
669 return aim_genericreq_n(sess, conn, 0x0002, 0x0002); | |
670 } | 558 } |
671 | 559 |
672 /* | 560 /* |
673 * Set directory profile data (not the same as aim_bos_setprofile!) | 561 * Set directory profile data (not the same as aim_bos_setprofile!) |
674 */ | 562 * |
675 faim_export unsigned long aim_setdirectoryinfo(struct aim_session_t *sess, struct aim_conn_t *conn, char *first, char *middle, char *last, char *maiden, char *nickname, char *street, char *city, char *state, char *zip, int country, unsigned short privacy) | 563 * privacy: 1 to allow searching, 0 to disallow. |
676 { | 564 */ |
677 struct command_tx_struct *newpacket; | 565 faim_export int aim_setdirectoryinfo(aim_session_t *sess, aim_conn_t *conn, const char *first, const char *middle, const char *last, const char *maiden, const char *nickname, const char *street, const char *city, const char *state, const char *zip, int country, fu16_t privacy) |
678 int packlen = 0, i = 0; | 566 { |
679 | 567 aim_frame_t *fr; |
680 packlen += 2+2+2; | 568 aim_snacid_t snacid; |
681 | 569 aim_tlvlist_t *tl = NULL; |
682 if(first) /* TLV 0001 */ | 570 |
683 packlen += (strlen(first) + 4); | 571 |
684 if(middle) | 572 aim_addtlvtochain16(&tl, 0x000a, privacy); |
685 packlen += (strlen(middle) + 4); | 573 |
686 if(last) | 574 if (first) |
687 packlen += (strlen(last) + 4); | 575 aim_addtlvtochain_raw(&tl, 0x0001, strlen(first), first); |
688 if(maiden) | 576 if (last) |
689 packlen += (strlen(maiden) + 4); | 577 aim_addtlvtochain_raw(&tl, 0x0002, strlen(last), last); |
690 if(nickname) | 578 if (middle) |
691 packlen += (strlen(nickname) + 4); | 579 aim_addtlvtochain_raw(&tl, 0x0003, strlen(middle), middle); |
692 if(street) | 580 if (maiden) |
693 packlen += (strlen(street) + 4); | 581 aim_addtlvtochain_raw(&tl, 0x0004, strlen(maiden), maiden); |
694 if(state) | 582 |
695 packlen += (strlen(state) + 4); | 583 if (state) |
696 if(city) | 584 aim_addtlvtochain_raw(&tl, 0x0007, strlen(state), state); |
697 packlen += (strlen(city) + 4); | 585 if (city) |
698 if(zip) | 586 aim_addtlvtochain_raw(&tl, 0x0008, strlen(city), city); |
699 packlen += (strlen(zip) + 4); | 587 |
700 | 588 if (nickname) |
701 if(!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, packlen+10))) | 589 aim_addtlvtochain_raw(&tl, 0x000c, strlen(nickname), nickname); |
702 return -1; | 590 if (zip) |
703 | 591 aim_addtlvtochain_raw(&tl, 0x000d, strlen(zip), zip); |
704 newpacket->lock = 1; | 592 |
705 | 593 if (street) |
706 i = aim_putsnac(newpacket->data, 0x0002, 0x0009, 0x0000, 0); | 594 aim_addtlvtochain_raw(&tl, 0x0021, strlen(street), street); |
707 | 595 |
708 /* 000a/0002: privacy: 1 to allow search/disp, 0 to disallow */ | 596 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_sizetlvchain(&tl)))) |
709 i += aim_puttlv_16(newpacket->data+i, 0x000a, privacy); | 597 return -ENOMEM; |
710 | 598 |
711 | 599 snacid = aim_cachesnac(sess, 0x0002, 0x0009, 0x0000, NULL, 0); |
712 if (first) | 600 |
713 i += aim_puttlv_str(newpacket->data+i, 0x0001, strlen(first), first); | 601 aim_putsnac(&fr->data, 0x0002, 0x0009, 0x0000, snacid); |
714 if (middle) | 602 aim_writetlvchain(&fr->data, &tl); |
715 i += aim_puttlv_str(newpacket->data+i, 0x0003, strlen(middle), middle); | 603 aim_freetlvchain(&tl); |
716 if (last) | 604 |
717 i += aim_puttlv_str(newpacket->data+i, 0x0002, strlen(last), last); | 605 aim_tx_enqueue(sess, fr); |
718 if (maiden) | 606 |
719 i += aim_puttlv_str(newpacket->data+i, 0x0004, strlen(maiden), maiden); | 607 return 0; |
720 if (nickname) | 608 } |
721 i += aim_puttlv_str(newpacket->data+i, 0x000c, strlen(nickname), nickname); | 609 |
722 if (street) | 610 /* XXX pass these in better */ |
723 i += aim_puttlv_str(newpacket->data+i, 0x0021, strlen(street), street); | 611 faim_export int aim_setuserinterests(aim_session_t *sess, aim_conn_t *conn, const char *interest1, const char *interest2, const char *interest3, const char *interest4, const char *interest5, fu16_t privacy) |
724 if (city) | 612 { |
725 i += aim_puttlv_str(newpacket->data+i, 0x0008, strlen(city), city); | 613 aim_frame_t *fr; |
726 if (state) | 614 aim_snacid_t snacid; |
727 i += aim_puttlv_str(newpacket->data+i, 0x0007, strlen(state), state); | 615 aim_tlvlist_t *tl = NULL; |
728 if (zip) | 616 |
729 i += aim_puttlv_str(newpacket->data+i, 0x000d, strlen(zip), zip); | 617 /* ?? privacy ?? */ |
730 | 618 aim_addtlvtochain16(&tl, 0x000a, privacy); |
731 newpacket->commandlen = i; | 619 |
732 newpacket->lock = 0; | 620 if (interest1) |
733 | 621 aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest1), interest1); |
734 aim_tx_enqueue(sess, newpacket); | 622 if (interest2) |
735 | 623 aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest2), interest2); |
736 return(sess->snac_nextid); | 624 if (interest3) |
737 } | 625 aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest3), interest3); |
738 | 626 if (interest4) |
739 faim_export unsigned long aim_setuserinterests(struct aim_session_t *sess, struct aim_conn_t *conn, char *interest1, char *interest2, char *interest3, char *interest4, char *interest5, unsigned short privacy) | 627 aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest4), interest4); |
740 { | 628 if (interest5) |
741 struct command_tx_struct *newpacket; | 629 aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest5), interest5); |
742 int packlen = 0, i = 0; | 630 |
743 | 631 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_sizetlvchain(&tl)))) |
744 packlen += 2+2+2; | 632 return -ENOMEM; |
745 | 633 |
746 if(interest1) | 634 snacid = aim_cachesnac(sess, 0x0002, 0x000f, 0x0000, NULL, 0); |
747 packlen += (strlen(interest1) + 4); | 635 |
748 if(interest2) | 636 aim_putsnac(&fr->data, 0x0002, 0x000f, 0x0000, 0); |
749 packlen += (strlen(interest2) + 4); | 637 aim_writetlvchain(&fr->data, &tl); |
750 if(interest3) | 638 aim_freetlvchain(&tl); |
751 packlen += (strlen(interest3) + 4); | 639 |
752 if(interest4) | 640 aim_tx_enqueue(sess, fr); |
753 packlen += (strlen(interest4) + 4); | 641 |
754 if(interest5) | 642 return 0; |
755 packlen += (strlen(interest5) + 4) ; | 643 } |
756 | 644 |
757 | 645 faim_export int aim_icq_setstatus(aim_session_t *sess, aim_conn_t *conn, fu32_t status) |
758 if(!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, packlen+10))) | 646 { |
759 return -1; | 647 aim_frame_t *fr; |
760 | 648 aim_snacid_t snacid; |
761 newpacket->lock = 1; | 649 aim_tlvlist_t *tl = NULL; |
762 | 650 fu32_t data; |
763 i = aim_putsnac(newpacket->data, 0x0002, 0x000f, 0x0000, 0); | 651 |
764 | 652 data = 0x00030000 | status; /* yay for error checking ;^) */ |
765 /* 000a/0002: 0000 ?? ?privacy? */ | 653 |
766 i += aim_puttlv_16(newpacket->data+i, 0x000a, privacy); | 654 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4))) |
767 | 655 return -ENOMEM; |
768 if(interest1) | 656 |
769 i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest1), interest1); | 657 snacid = aim_cachesnac(sess, 0x0001, 0x001e, 0x0000, NULL, 0); |
770 if(interest2) | 658 aim_putsnac(&fr->data, 0x0001, 0x001e, 0x0000, snacid); |
771 i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest2), interest2); | 659 |
772 if(interest3) | 660 aim_addtlvtochain32(&tl, 0x0006, data); |
773 i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest3), interest3); | 661 aim_writetlvchain(&fr->data, &tl); |
774 if(interest4) | 662 aim_freetlvchain(&tl); |
775 i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest4), interest4); | 663 |
776 if(interest5) | 664 aim_tx_enqueue(sess, fr); |
777 i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest1), interest5); | 665 |
778 | 666 return 0; |
779 newpacket->commandlen = i; | |
780 newpacket->lock = 0; | |
781 | |
782 aim_tx_enqueue(sess, newpacket); | |
783 | |
784 return(sess->snac_nextid); | |
785 } | |
786 | |
787 faim_export unsigned long aim_icq_setstatus(struct aim_session_t *sess, | |
788 struct aim_conn_t *conn, | |
789 unsigned long status) | |
790 { | |
791 struct command_tx_struct *newpacket; | |
792 int i; | |
793 unsigned long data; | |
794 | |
795 data = 0x00030000 | status; /* yay for error checking ;^) */ | |
796 | |
797 if(!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 10 + 4))) | |
798 return -1; | |
799 | |
800 newpacket->lock = 1; | |
801 | |
802 i = aim_putsnac(newpacket->data, 0x0001, 0x001e, 0x0000, 0x0000001e); | |
803 i += aim_puttlv_32(newpacket->data+i, 0x0006, data); | |
804 | |
805 newpacket->commandlen = i; | |
806 newpacket->lock = 0; | |
807 | |
808 aim_tx_enqueue(sess, newpacket); | |
809 | |
810 return(sess->snac_nextid); | |
811 } | 667 } |
812 | 668 |
813 /* | 669 /* |
814 * Should be generic enough to handle the errors for all families... | 670 * Should be generic enough to handle the errors for all families... |
815 * | 671 * |
816 */ | 672 */ |
817 static int generror(struct aim_session_t *sess, aim_module_t *mod, struct command_rx_struct *rx, aim_modsnac_t *snac, unsigned char *data, int datalen) | 673 static int generror(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) |
818 { | 674 { |
819 int ret = 0; | 675 int ret = 0; |
820 int error = 0; | 676 int error = 0; |
821 aim_rxcallback_t userfunc; | 677 aim_rxcallback_t userfunc; |
822 struct aim_snac_t *snac2; | 678 aim_snac_t *snac2; |
823 | 679 |
824 snac2 = aim_remsnac(sess, snac->id); | 680 snac2 = aim_remsnac(sess, snac->id); |
825 | 681 |
826 if (datalen) | 682 if (aim_bstream_empty(bs)) |
827 error = aimutil_get16(data); | 683 error = aimbs_get16(bs); |
828 | 684 |
829 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) | 685 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) |
830 ret = userfunc(sess, rx, error, snac2?snac2->data:NULL); | 686 ret = userfunc(sess, rx, error, snac2 ? snac2->data : NULL); |
831 | 687 |
832 if (snac2) | 688 if (snac2) |
833 free(snac2->data); | 689 free(snac2->data); |
834 free(snac2); | 690 free(snac2); |
835 | 691 |
836 return ret; | 692 return ret; |
837 } | 693 } |
838 | 694 |
839 static int snachandler(struct aim_session_t *sess, aim_module_t *mod, struct command_rx_struct *rx, aim_modsnac_t *snac, unsigned char *data, int datalen) | 695 static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) |
840 { | 696 { |
841 | 697 |
842 if (snac->subtype == 0x0001) | 698 if (snac->subtype == 0x0001) |
843 return generror(sess, mod, rx, snac, data, datalen); | 699 return generror(sess, mod, rx, snac, bs); |
844 else if ((snac->family == 0xffff) && (snac->subtype == 0xffff)) { | 700 else if ((snac->family == 0xffff) && (snac->subtype == 0xffff)) { |
845 aim_rxcallback_t userfunc; | 701 aim_rxcallback_t userfunc; |
846 | 702 |
847 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) | 703 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) |
848 return userfunc(sess, rx); | 704 return userfunc(sess, rx); |
849 } | 705 } |
850 | 706 |
851 return 0; | 707 return 0; |
852 } | 708 } |
853 | 709 |
854 faim_internal int misc_modfirst(struct aim_session_t *sess, aim_module_t *mod) | 710 faim_internal int misc_modfirst(aim_session_t *sess, aim_module_t *mod) |
855 { | 711 { |
856 | 712 |
857 mod->family = 0xffff; | 713 mod->family = 0xffff; |
858 mod->version = 0x0000; | 714 mod->version = 0x0000; |
859 mod->flags = AIM_MODFLAG_MULTIFAMILY; | 715 mod->flags = AIM_MODFLAG_MULTIFAMILY; |
860 strncpy(mod->name, "misc", sizeof(mod->name)); | 716 strncpy(mod->name, "misc", sizeof(mod->name)); |
861 mod->snachandler = snachandler; | 717 mod->snachandler = snachandler; |
862 | 718 |
863 return 0; | 719 return 0; |
864 } | 720 } |