]>
Commit | Line | Data |
---|---|---|
9de3ca7e | 1 | |
2 | /* | |
3 | * aim_misc.c | |
4 | * | |
5 | * TODO: Seperate a lot of this into an aim_bos.c. | |
6 | * | |
7 | * Other things... | |
8 | * | |
9 | * - Idle setting | |
10 | * | |
11 | * | |
12 | */ | |
13 | ||
a25832e6 | 14 | #include <faim/aim.h> |
9de3ca7e | 15 | |
16 | /* | |
17 | * aim_bos_setidle() | |
18 | * | |
19 | * Should set your current idle time in seconds. Idealy, OSCAR should | |
20 | * do this for us. But, it doesn't. The client must call this to set idle | |
21 | * time. | |
22 | * | |
23 | */ | |
a25832e6 | 24 | u_long aim_bos_setidle(struct aim_session_t *sess, |
25 | struct aim_conn_t *conn, | |
26 | u_long idletime) | |
9de3ca7e | 27 | { |
a25832e6 | 28 | return aim_genericreq_l(sess, conn, 0x0001, 0x0011, &idletime); |
9de3ca7e | 29 | } |
30 | ||
31 | ||
32 | /* | |
33 | * aim_bos_changevisibility(conn, changtype, namelist) | |
34 | * | |
35 | * Changes your visibility depending on changetype: | |
36 | * | |
37 | * AIM_VISIBILITYCHANGE_PERMITADD: Lets provided list of names see you | |
38 | * AIM_VISIBILITYCHANGE_PERMIDREMOVE: Removes listed names from permit list | |
39 | * AIM_VISIBILITYCHANGE_DENYADD: Hides you from provided list of names | |
40 | * AIM_VISIBILITYCHANGE_DENYREMOVE: Lets list see you again | |
41 | * | |
42 | * list should be a list of | |
43 | * screen names in the form "Screen Name One&ScreenNameTwo&" etc. | |
44 | * | |
45 | * Equivelents to options in WinAIM: | |
46 | * - Allow all users to contact me: Send an AIM_VISIBILITYCHANGE_DENYADD | |
47 | * with only your name on it. | |
48 | * - Allow only users on my Buddy List: Send an | |
49 | * AIM_VISIBILITYCHANGE_PERMITADD with the list the same as your | |
50 | * buddy list | |
51 | * - Allow only the uesrs below: Send an AIM_VISIBILITYCHANGE_PERMITADD | |
52 | * with everyone listed that you want to see you. | |
53 | * - Block all users: Send an AIM_VISIBILITYCHANGE_PERMITADD with only | |
54 | * yourself in the list | |
55 | * - Block the users below: Send an AIM_VISIBILITYCHANGE_DENYADD with | |
56 | * the list of users to be blocked | |
57 | * | |
58 | * | |
59 | */ | |
a25832e6 | 60 | u_long aim_bos_changevisibility(struct aim_session_t *sess, |
61 | struct aim_conn_t *conn, | |
62 | int changetype, char *denylist) | |
9de3ca7e | 63 | { |
64 | struct command_tx_struct newpacket; | |
65 | u_short subtype; | |
66 | ||
67 | char *localcpy = NULL; | |
68 | char *tmpptr = NULL; | |
69 | int i,j; | |
70 | int listcount; | |
71 | ||
72 | if (!denylist) | |
73 | return 0; | |
74 | ||
75 | newpacket.lock = 1; | |
76 | ||
77 | if (conn) | |
78 | newpacket.conn = conn; | |
79 | else | |
a25832e6 | 80 | newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); |
9de3ca7e | 81 | |
82 | newpacket.type = 0x02; | |
83 | ||
84 | localcpy = (char *) malloc(strlen(denylist)+1); | |
85 | memcpy(localcpy, denylist, strlen(denylist)+1); | |
86 | ||
87 | listcount = aimutil_itemcnt(localcpy, '&'); | |
88 | newpacket.commandlen = aimutil_tokslen(localcpy, 99, '&') + listcount + 9; | |
89 | ||
90 | ||
91 | newpacket.data = (char *) malloc(newpacket.commandlen); | |
92 | memset(newpacket.data, 0x00, newpacket.commandlen); | |
93 | ||
94 | switch(changetype) | |
95 | { | |
96 | case AIM_VISIBILITYCHANGE_PERMITADD: subtype = 0x05; break; | |
97 | case AIM_VISIBILITYCHANGE_PERMITREMOVE: subtype = 0x06; break; | |
98 | case AIM_VISIBILITYCHANGE_DENYADD: subtype = 0x07; break; | |
99 | case AIM_VISIBILITYCHANGE_DENYREMOVE: subtype = 0x08; break; | |
100 | default: | |
101 | free(newpacket.data); | |
102 | return 0; | |
103 | } | |
104 | ||
105 | /* We actually DO NOT send a SNAC ID with this one! */ | |
106 | aim_putsnac(newpacket.data, 0x0009, subtype, 0x00, 0); | |
107 | ||
108 | j = 10; /* the next byte */ | |
109 | ||
110 | for (i=0; (i < (listcount - 1)) && (i < 99); i++) | |
111 | { | |
112 | tmpptr = aimutil_itemidx(localcpy, i, '&'); | |
113 | ||
114 | newpacket.data[j] = strlen(tmpptr); | |
115 | memcpy(&(newpacket.data[j+1]), tmpptr, strlen(tmpptr)); | |
116 | j += strlen(tmpptr)+1; | |
117 | free(tmpptr); | |
118 | } | |
119 | free(localcpy); | |
120 | ||
121 | newpacket.lock = 0; | |
122 | ||
a25832e6 | 123 | aim_tx_enqueue(sess, &newpacket); |
9de3ca7e | 124 | |
a25832e6 | 125 | return (sess->snac_nextid); /* dont increment */ |
9de3ca7e | 126 | |
127 | } | |
128 | ||
129 | ||
130 | ||
131 | /* | |
132 | * aim_bos_setbuddylist(buddylist) | |
133 | * | |
134 | * This just builds the "set buddy list" command then queues it. | |
135 | * | |
136 | * buddy_list = "Screen Name One&ScreenNameTwo&"; | |
137 | * | |
138 | * TODO: Clean this up. | |
139 | * | |
140 | */ | |
a25832e6 | 141 | u_long aim_bos_setbuddylist(struct aim_session_t *sess, |
142 | struct aim_conn_t *conn, | |
143 | char *buddy_list) | |
9de3ca7e | 144 | { |
145 | int i, j; | |
146 | ||
147 | struct command_tx_struct newpacket; | |
148 | ||
149 | int packet_login_phase3c_hi_b_len = 0; | |
150 | ||
151 | char *localcpy = NULL; | |
152 | char *tmpptr = NULL; | |
153 | ||
154 | packet_login_phase3c_hi_b_len = 16; /* 16b for FLAP and SNAC headers */ | |
155 | ||
156 | /* bail out if we can't make the packet */ | |
157 | if (buddy_list == NULL) | |
158 | { | |
159 | printf("\nNO BUDDIES! ARE YOU THAT LONELY???\n"); | |
160 | return 0; | |
161 | } | |
162 | #if debug > 0 | |
163 | printf("****buddy list: %s\n", buddy_list); | |
164 | printf("****buddy list len: %d (%x)\n", strlen(buddy_list), strlen(buddy_list)); | |
165 | #endif | |
166 | ||
167 | localcpy = (char *) malloc(strlen(buddy_list)+1); | |
168 | memcpy(localcpy, buddy_list, strlen(buddy_list)+1); | |
169 | ||
170 | i = 0; | |
171 | tmpptr = strtok(localcpy, "&"); | |
172 | while ((tmpptr != NULL) && (i < 100)) | |
173 | { | |
174 | #if debug > 0 | |
175 | printf("---adding %s (%d)\n", tmpptr, strlen(tmpptr)); | |
176 | #endif | |
177 | packet_login_phase3c_hi_b_len += strlen(tmpptr)+1; | |
178 | i++; | |
179 | tmpptr = strtok(NULL, "&"); | |
180 | } | |
181 | #if debug > 0 | |
182 | printf("*** send buddy list len: %d (%x)\n", packet_login_phase3c_hi_b_len, packet_login_phase3c_hi_b_len); | |
183 | #endif | |
184 | free(localcpy); | |
185 | ||
186 | newpacket.type = 0x02; | |
187 | if (conn) | |
188 | newpacket.conn = conn; | |
189 | else | |
a25832e6 | 190 | newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); |
9de3ca7e | 191 | newpacket.commandlen = packet_login_phase3c_hi_b_len - 6; |
192 | newpacket.lock = 1; | |
193 | ||
194 | newpacket.data = (char *) malloc(newpacket.commandlen); | |
195 | ||
a25832e6 | 196 | aim_putsnac(newpacket.data, 0x0003, 0x0004, 0x0000, sess->snac_nextid); |
9de3ca7e | 197 | |
198 | j = 10; /* the next byte */ | |
199 | ||
200 | i = 0; | |
201 | tmpptr = strtok(buddy_list, "&"); | |
202 | while ((tmpptr != NULL) & (i < 100)) | |
203 | { | |
204 | #if debug > 0 | |
205 | printf("---adding %s (%d)\n", tmpptr, strlen(tmpptr)); | |
206 | #endif | |
207 | newpacket.data[j] = strlen(tmpptr); | |
208 | memcpy(&(newpacket.data[j+1]), tmpptr, strlen(tmpptr)); | |
209 | j += strlen(tmpptr)+1; | |
210 | i++; | |
211 | tmpptr = strtok(NULL, "&"); | |
212 | } | |
213 | ||
214 | newpacket.lock = 0; | |
215 | ||
a25832e6 | 216 | aim_tx_enqueue(sess, &newpacket); |
9de3ca7e | 217 | |
a25832e6 | 218 | return (sess->snac_nextid++); |
9de3ca7e | 219 | } |
220 | ||
221 | /* | |
222 | * aim_bos_setprofile(profile) | |
223 | * | |
224 | * Gives BOS your profile. | |
225 | * | |
26af6789 | 226 | * |
227 | * The large data chunk given here is of unknown decoding. | |
228 | * What I do know is that each 0x20 byte repetition | |
229 | * represents a capability. People with only the | |
230 | * first two reptitions can support normal messaging | |
231 | * and chat (client version 2.0 or 3.0). People with | |
232 | * the third as well can also support voice chat (client | |
233 | * version 3.5 or higher). IOW, if we don't send this, | |
234 | * we won't get chat invitations (get "software doesn't | |
235 | * support chat" error). | |
236 | * | |
237 | * This data is broadcast along with your oncoming | |
238 | * buddy command to everyone who has you on their | |
239 | * buddy list, as a type 0x0002 TLV. | |
240 | * | |
9de3ca7e | 241 | */ |
a25832e6 | 242 | u_long aim_bos_setprofile(struct aim_session_t *sess, |
243 | struct aim_conn_t *conn, | |
244 | char *profile) | |
9de3ca7e | 245 | { |
9de3ca7e | 246 | struct command_tx_struct newpacket; |
247 | int i = 0; | |
26af6789 | 248 | u_char funkydata[] = { |
249 | 0x09, 0x46, 0x13, 0x46, 0x4c, 0x7f, 0x11, 0xd1, | |
250 | 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00, | |
251 | 0x09, 0x46, 0x13, 0x41, 0x4c, 0x7f, 0x11, 0xd1, | |
252 | 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00, | |
253 | ||
254 | 0x09, 0x46, 0x13, 0x45, 0x4c, 0x7f, 0x11, 0xd1, | |
255 | 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00, | |
256 | 0x74, 0x8f, 0x24, 0x20, 0x62, 0x87, 0x11, 0xd1, | |
257 | 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00, | |
258 | ||
259 | 0x09, 0x46, 0x13, 0x48, 0x4c, 0x7f, 0x11, 0xd1, | |
260 | 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00, | |
261 | 0x09, 0x46, 0x13, 0x43, 0x4c, 0x7f, 0x11, 0xd1, | |
262 | 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 | |
263 | }; | |
9de3ca7e | 264 | |
265 | newpacket.type = 0x02; | |
266 | if (conn) | |
267 | newpacket.conn = conn; | |
268 | else | |
a25832e6 | 269 | newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); |
270 | ||
26af6789 | 271 | newpacket.commandlen = 1152+strlen(profile)+1; /*arbitrarily large */ |
272 | newpacket.data = (char *) malloc(newpacket.commandlen); | |
9de3ca7e | 273 | |
a25832e6 | 274 | i += aim_putsnac(newpacket.data, 0x0002, 0x004, 0x0000, sess->snac_nextid); |
26af6789 | 275 | i += aim_puttlv_str(newpacket.data+i, 0x0001, strlen("text/x-aolrtf; charset=\"us-ascii\""), "text/x-aolrtf; charset=\"us-ascii\""); |
276 | i += aim_puttlv_str(newpacket.data+i, 0x0002, strlen(profile), profile); | |
277 | /* why do we send this twice? */ | |
278 | i += aim_puttlv_str(newpacket.data+i, 0x0003, strlen("text/x-aolrtf; charset=\"us-ascii\""), "text/x-aolrtf; charset=\"us-ascii\""); | |
9de3ca7e | 279 | |
26af6789 | 280 | /* a blank TLV 0x0004 --- not sure what this is either */ |
281 | i += aimutil_put16(newpacket.data+i, 0x0004); | |
282 | i += aimutil_put16(newpacket.data+i, 0x0000); | |
283 | ||
284 | /* Capability information. */ | |
285 | i += aim_puttlv_str(newpacket.data+i, 0x0005, 0x0060, funkydata); | |
9de3ca7e | 286 | |
26af6789 | 287 | newpacket.commandlen = i; |
a25832e6 | 288 | aim_tx_enqueue(sess, &newpacket); |
9de3ca7e | 289 | |
a25832e6 | 290 | return (sess->snac_nextid++); |
9de3ca7e | 291 | } |
292 | ||
293 | /* | |
294 | * aim_bos_setgroupperm(mask) | |
295 | * | |
296 | * Set group permisson mask. Normally 0x1f. | |
297 | * | |
298 | */ | |
a25832e6 | 299 | u_long aim_bos_setgroupperm(struct aim_session_t *sess, |
300 | struct aim_conn_t *conn, | |
301 | u_long mask) | |
9de3ca7e | 302 | { |
a25832e6 | 303 | return aim_genericreq_l(sess, conn, 0x0009, 0x0004, &mask); |
9de3ca7e | 304 | } |
305 | ||
306 | /* | |
307 | * aim_bos_clientready() | |
308 | * | |
309 | * Send Client Ready. | |
310 | * | |
311 | * TODO: Dynamisize. | |
312 | * | |
313 | */ | |
a25832e6 | 314 | u_long aim_bos_clientready(struct aim_session_t *sess, |
315 | struct aim_conn_t *conn) | |
9de3ca7e | 316 | { |
317 | u_char command_2[] = { | |
318 | /* placeholders for dynamic data */ | |
319 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
320 | 0xff, 0xff, | |
321 | /* real data */ | |
01b59e1e | 322 | 0x00, 0x01, |
323 | 0x00, 0x03, | |
324 | 0x00, 0x04, | |
325 | 0x06, 0x86, | |
326 | 0x00, 0x02, | |
327 | 0x00, 0x01, | |
328 | 0x00, 0x04, | |
329 | 0x00, 0x01, | |
330 | ||
331 | 0x00, 0x03, | |
332 | 0x00, 0x01, | |
333 | 0x00, 0x04, | |
334 | 0x00, 0x01, | |
335 | 0x00, 0x04, | |
336 | 0x00, 0x01, | |
337 | 0x00, 0x04, | |
338 | 0x00, 0x01, | |
339 | ||
340 | 0x00, 0x06, | |
341 | 0x00, 0x01, | |
342 | 0x00, 0x04, | |
343 | 0x00, 0x01, | |
344 | 0x00, 0x08, | |
345 | 0x00, 0x01, | |
346 | 0x00, 0x04, | |
347 | 0x00, 0x01, | |
348 | ||
349 | 0x00, 0x09, | |
350 | 0x00, 0x01, | |
351 | 0x00, 0x04, | |
352 | 0x00, 0x01, | |
353 | 0x00, 0x0a, | |
354 | 0x00, 0x01, | |
355 | 0x00, 0x04, | |
356 | 0x00, 0x01, | |
357 | ||
358 | 0x00, 0x0b, | |
359 | 0x00, 0x01, | |
360 | 0x00, 0x04, | |
9de3ca7e | 361 | 0x00, 0x01 |
362 | }; | |
363 | int command_2_len = 0x52; | |
364 | struct command_tx_struct newpacket; | |
365 | ||
366 | newpacket.lock = 1; | |
367 | if (conn) | |
368 | newpacket.conn = conn; | |
369 | else | |
a25832e6 | 370 | newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); |
9de3ca7e | 371 | newpacket.type = 0x02; |
372 | newpacket.commandlen = command_2_len; | |
373 | newpacket.data = (char *) malloc (newpacket.commandlen); | |
374 | memcpy(newpacket.data, command_2, newpacket.commandlen); | |
375 | ||
376 | /* This write over the dynamic parts of the byte block */ | |
a25832e6 | 377 | aim_putsnac(newpacket.data, 0x0001, 0x0002, 0x0000, sess->snac_nextid); |
9de3ca7e | 378 | |
a25832e6 | 379 | aim_tx_enqueue(sess, &newpacket); |
9de3ca7e | 380 | |
a25832e6 | 381 | return (sess->snac_nextid++); |
9de3ca7e | 382 | } |
383 | ||
384 | /* | |
385 | * send_login_phase3(int socket) | |
386 | * | |
387 | * Request Rate Information. | |
388 | * | |
389 | * TODO: Move to aim_conn. | |
390 | * TODO: Move to SNAC interface. | |
391 | */ | |
a25832e6 | 392 | u_long aim_bos_reqrate(struct aim_session_t *sess, |
393 | struct aim_conn_t *conn) | |
9de3ca7e | 394 | { |
a25832e6 | 395 | return aim_genericreq_n(sess, conn, 0x0001, 0x0006); |
9de3ca7e | 396 | } |
397 | ||
398 | /* | |
399 | * send_login_phase3b(int socket) | |
400 | * | |
401 | * Rate Information Response Acknowledge. | |
402 | * | |
403 | */ | |
a25832e6 | 404 | u_long aim_bos_ackrateresp(struct aim_session_t *sess, |
405 | struct aim_conn_t *conn) | |
9de3ca7e | 406 | { |
407 | struct command_tx_struct newpacket; | |
408 | ||
409 | newpacket.lock = 1; | |
410 | if (conn) | |
411 | newpacket.conn = conn; | |
412 | else | |
a25832e6 | 413 | newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); |
9de3ca7e | 414 | newpacket.type = 0x02; |
415 | newpacket.commandlen = 18; | |
416 | ||
417 | newpacket.data = (char *) malloc(newpacket.commandlen); | |
a25832e6 | 418 | aim_putsnac(newpacket.data, 0x0001, 0x0008, 0x0000, sess->snac_nextid); |
9de3ca7e | 419 | |
420 | newpacket.data[10] = 0x00; | |
421 | newpacket.data[11] = 0x01; | |
422 | newpacket.data[12] = 0x00; | |
423 | newpacket.data[13] = 0x02; | |
424 | newpacket.data[14] = 0x00; | |
425 | newpacket.data[15] = 0x03; | |
426 | newpacket.data[16] = 0x00; | |
427 | newpacket.data[17] = 0x04; | |
428 | ||
a25832e6 | 429 | aim_tx_enqueue(sess, &newpacket); |
9de3ca7e | 430 | |
a25832e6 | 431 | return (sess->snac_nextid++); |
9de3ca7e | 432 | } |
433 | ||
434 | /* | |
435 | * aim_bos_setprivacyflags() | |
436 | * | |
437 | * Sets privacy flags. Normally 0x03. | |
438 | * | |
439 | * Bit 1: Allows other AIM users to see how long you've been idle. | |
440 | * | |
441 | * | |
442 | */ | |
a25832e6 | 443 | u_long aim_bos_setprivacyflags(struct aim_session_t *sess, |
444 | struct aim_conn_t *conn, | |
445 | u_long flags) | |
9de3ca7e | 446 | { |
a25832e6 | 447 | return aim_genericreq_l(sess, conn, 0x0001, 0x0014, &flags); |
9de3ca7e | 448 | } |
449 | ||
450 | /* | |
451 | * aim_bos_reqpersonalinfo() | |
452 | * | |
453 | * Requests the current user's information. Can't go generic on this one | |
454 | * because aparently it uses SNAC flags. | |
455 | * | |
456 | */ | |
a25832e6 | 457 | u_long aim_bos_reqpersonalinfo(struct aim_session_t *sess, |
458 | struct aim_conn_t *conn) | |
9de3ca7e | 459 | { |
460 | struct command_tx_struct newpacket; | |
461 | ||
462 | newpacket.lock = 1; | |
463 | if (conn) | |
464 | newpacket.conn = conn; | |
465 | else | |
a25832e6 | 466 | newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); |
9de3ca7e | 467 | newpacket.type = 0x02; |
468 | newpacket.commandlen = 12; | |
469 | ||
470 | newpacket.data = (char *) malloc(newpacket.commandlen); | |
a25832e6 | 471 | aim_putsnac(newpacket.data, 0x000a, 0x0001, 0x000e /* huh? */, sess->snac_nextid); |
9de3ca7e | 472 | |
473 | newpacket.data[10] = 0x0d; | |
474 | newpacket.data[11] = 0xda; | |
475 | ||
01b59e1e | 476 | newpacket.lock = 0; |
a25832e6 | 477 | aim_tx_enqueue(sess, &newpacket); |
9de3ca7e | 478 | |
a25832e6 | 479 | return (sess->snac_nextid++); |
9de3ca7e | 480 | } |
481 | ||
01b59e1e | 482 | u_long aim_setversions(struct aim_session_t *sess, |
483 | struct aim_conn_t *conn) | |
484 | { | |
485 | struct command_tx_struct newpacket; | |
486 | int i,j; | |
487 | ||
488 | newpacket.lock = 1; | |
489 | if (conn) | |
490 | newpacket.conn = conn; | |
491 | else | |
492 | newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); | |
493 | newpacket.type = 0x02; | |
26af6789 | 494 | newpacket.commandlen = 10 + (4*11); |
01b59e1e | 495 | |
496 | newpacket.data = (char *) malloc(newpacket.commandlen); | |
497 | i = aim_putsnac(newpacket.data, 0x0001, 0x0017, 0x0000, sess->snac_nextid); | |
498 | ||
499 | i += aimutil_put16(newpacket.data+i, 0x0001); | |
500 | i += aimutil_put16(newpacket.data+i, 0x0003); | |
26af6789 | 501 | |
01b59e1e | 502 | i += aimutil_put16(newpacket.data+i, 0x0002); |
503 | i += aimutil_put16(newpacket.data+i, 0x0001); | |
26af6789 | 504 | |
01b59e1e | 505 | i += aimutil_put16(newpacket.data+i, 0x0003); |
506 | i += aimutil_put16(newpacket.data+i, 0x0001); | |
26af6789 | 507 | |
01b59e1e | 508 | i += aimutil_put16(newpacket.data+i, 0x0004); |
509 | i += aimutil_put16(newpacket.data+i, 0x0001); | |
26af6789 | 510 | |
01b59e1e | 511 | i += aimutil_put16(newpacket.data+i, 0x0006); |
512 | i += aimutil_put16(newpacket.data+i, 0x0001); | |
26af6789 | 513 | |
01b59e1e | 514 | i += aimutil_put16(newpacket.data+i, 0x0008); |
515 | i += aimutil_put16(newpacket.data+i, 0x0001); | |
26af6789 | 516 | |
01b59e1e | 517 | i += aimutil_put16(newpacket.data+i, 0x0009); |
518 | i += aimutil_put16(newpacket.data+i, 0x0001); | |
26af6789 | 519 | |
01b59e1e | 520 | i += aimutil_put16(newpacket.data+i, 0x000a); |
521 | i += aimutil_put16(newpacket.data+i, 0x0001); | |
26af6789 | 522 | |
01b59e1e | 523 | i += aimutil_put16(newpacket.data+i, 0x000b); |
524 | i += aimutil_put16(newpacket.data+i, 0x0002); | |
26af6789 | 525 | |
01b59e1e | 526 | i += aimutil_put16(newpacket.data+i, 0x000c); |
527 | i += aimutil_put16(newpacket.data+i, 0x0001); | |
26af6789 | 528 | |
01b59e1e | 529 | i += aimutil_put16(newpacket.data+i, 0x0015); |
01b59e1e | 530 | i += aimutil_put16(newpacket.data+i, 0x0001); |
531 | ||
532 | #if 0 | |
533 | for (j = 0; j < 0x10; j++) | |
534 | A | |
535 | { | |
536 | i += aimutil_put16(newpacket.data+i, j); /* family */ | |
537 | i += aimutil_put16(newpacket.data+i, 0x0003); /* version */ | |
538 | } | |
539 | #endif | |
540 | newpacket.lock = 0; | |
541 | aim_tx_enqueue(sess, &newpacket); | |
542 | ||
543 | return (sess->snac_nextid++); | |
544 | } | |
545 | ||
546 | ||
9de3ca7e | 547 | /* |
548 | * aim_bos_reqservice(serviceid) | |
549 | * | |
550 | * Service request. | |
551 | * | |
552 | */ | |
a25832e6 | 553 | u_long aim_bos_reqservice(struct aim_session_t *sess, |
554 | struct aim_conn_t *conn, | |
555 | u_short serviceid) | |
9de3ca7e | 556 | { |
a25832e6 | 557 | return aim_genericreq_s(sess, conn, 0x0001, 0x0004, &serviceid); |
9de3ca7e | 558 | } |
559 | ||
560 | /* | |
561 | * aim_bos_reqrights() | |
562 | * | |
563 | * Request BOS rights. | |
564 | * | |
565 | */ | |
a25832e6 | 566 | u_long aim_bos_reqrights(struct aim_session_t *sess, |
567 | struct aim_conn_t *conn) | |
9de3ca7e | 568 | { |
a25832e6 | 569 | return aim_genericreq_n(sess, conn, 0x0009, 0x0002); |
9de3ca7e | 570 | } |
571 | ||
572 | /* | |
573 | * aim_bos_reqbuddyrights() | |
574 | * | |
575 | * Request Buddy List rights. | |
576 | * | |
577 | */ | |
a25832e6 | 578 | u_long aim_bos_reqbuddyrights(struct aim_session_t *sess, |
579 | struct aim_conn_t *conn) | |
9de3ca7e | 580 | { |
a25832e6 | 581 | return aim_genericreq_n(sess, conn, 0x0003, 0x0002); |
9de3ca7e | 582 | } |
583 | ||
584 | /* | |
585 | * Generic routine for sending commands. | |
586 | * | |
587 | * | |
588 | * I know I can do this in a smarter way...but I'm not thinking straight | |
589 | * right now... | |
590 | * | |
591 | * I had one big function that handled all three cases, but then it broke | |
592 | * and I split it up into three. But then I fixed it. I just never went | |
593 | * back to the single. I don't see any advantage to doing it either way. | |
594 | * | |
595 | */ | |
a25832e6 | 596 | u_long aim_genericreq_n(struct aim_session_t *sess, |
597 | struct aim_conn_t *conn, | |
598 | u_short family, u_short subtype) | |
9de3ca7e | 599 | { |
600 | struct command_tx_struct newpacket; | |
601 | ||
602 | newpacket.lock = 1; | |
603 | ||
604 | if (conn) | |
605 | newpacket.conn = conn; | |
606 | else | |
a25832e6 | 607 | newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); |
9de3ca7e | 608 | newpacket.type = 0x02; |
609 | ||
610 | newpacket.commandlen = 10; | |
611 | ||
612 | newpacket.data = (char *) malloc(newpacket.commandlen); | |
613 | memset(newpacket.data, 0x00, newpacket.commandlen); | |
614 | ||
a25832e6 | 615 | aim_putsnac(newpacket.data, family, subtype, 0x0000, sess->snac_nextid); |
9de3ca7e | 616 | |
a25832e6 | 617 | aim_tx_enqueue(sess, &newpacket); |
618 | return (sess->snac_nextid++); | |
9de3ca7e | 619 | } |
620 | ||
621 | /* | |
622 | * | |
623 | * | |
624 | */ | |
a25832e6 | 625 | u_long aim_genericreq_l(struct aim_session_t *sess, |
626 | struct aim_conn_t *conn, | |
627 | u_short family, u_short subtype, u_long *longdata) | |
9de3ca7e | 628 | { |
629 | struct command_tx_struct newpacket; | |
630 | u_long newlong; | |
631 | ||
632 | /* If we don't have data, there's no reason to use this function */ | |
633 | if (!longdata) | |
a25832e6 | 634 | return aim_genericreq_n(sess, conn, family, subtype); |
9de3ca7e | 635 | |
636 | newpacket.lock = 1; | |
637 | ||
638 | if (conn) | |
639 | newpacket.conn = conn; | |
640 | else | |
a25832e6 | 641 | newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); |
642 | ||
9de3ca7e | 643 | newpacket.type = 0x02; |
644 | ||
645 | newpacket.commandlen = 10+sizeof(u_long); | |
646 | ||
647 | newpacket.data = (char *) malloc(newpacket.commandlen); | |
648 | memset(newpacket.data, 0x00, newpacket.commandlen); | |
649 | ||
a25832e6 | 650 | aim_putsnac(newpacket.data, family, subtype, 0x0000, sess->snac_nextid); |
9de3ca7e | 651 | |
652 | /* copy in data */ | |
653 | newlong = htonl(*longdata); | |
654 | memcpy(&(newpacket.data[10]), &newlong, sizeof(u_long)); | |
655 | ||
a25832e6 | 656 | aim_tx_enqueue(sess, &newpacket); |
657 | return (sess->snac_nextid++); | |
9de3ca7e | 658 | } |
659 | ||
a25832e6 | 660 | u_long aim_genericreq_s(struct aim_session_t *sess, |
661 | struct aim_conn_t *conn, | |
662 | u_short family, u_short subtype, u_short *shortdata) | |
9de3ca7e | 663 | { |
664 | struct command_tx_struct newpacket; | |
665 | u_short newshort; | |
666 | ||
667 | /* If we don't have data, there's no reason to use this function */ | |
668 | if (!shortdata) | |
a25832e6 | 669 | return aim_genericreq_n(sess, conn, family, subtype); |
9de3ca7e | 670 | |
671 | newpacket.lock = 1; | |
672 | ||
673 | if (conn) | |
674 | newpacket.conn = conn; | |
675 | else | |
a25832e6 | 676 | newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); |
677 | ||
9de3ca7e | 678 | newpacket.type = 0x02; |
679 | ||
680 | newpacket.commandlen = 10+sizeof(u_short); | |
681 | ||
682 | newpacket.data = (char *) malloc(newpacket.commandlen); | |
683 | memset(newpacket.data, 0x00, newpacket.commandlen); | |
684 | ||
a25832e6 | 685 | aim_putsnac(newpacket.data, family, subtype, 0x0000, sess->snac_nextid); |
9de3ca7e | 686 | |
687 | /* copy in data */ | |
688 | newshort = htons(*shortdata); | |
689 | memcpy(&(newpacket.data[10]), &newshort, sizeof(u_short)); | |
690 | ||
a25832e6 | 691 | aim_tx_enqueue(sess, &newpacket); |
692 | return (sess->snac_nextid++); | |
9de3ca7e | 693 | } |
694 | ||
695 | /* | |
696 | * aim_bos_reqlocaterights() | |
697 | * | |
698 | * Request Location services rights. | |
699 | * | |
700 | */ | |
a25832e6 | 701 | u_long aim_bos_reqlocaterights(struct aim_session_t *sess, |
702 | struct aim_conn_t *conn) | |
9de3ca7e | 703 | { |
a25832e6 | 704 | return aim_genericreq_n(sess, conn, 0x0002, 0x0002); |
9de3ca7e | 705 | } |
706 | ||
707 | /* | |
708 | * aim_bos_reqicbmparaminfo() | |
709 | * | |
710 | * Request ICBM parameter information. | |
711 | * | |
712 | */ | |
a25832e6 | 713 | u_long aim_bos_reqicbmparaminfo(struct aim_session_t *sess, |
714 | struct aim_conn_t *conn) | |
9de3ca7e | 715 | { |
a25832e6 | 716 | return aim_genericreq_n(sess, conn, 0x0004, 0x0004); |
9de3ca7e | 717 | } |