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 }