]>
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, | |
0c20631f | 244 | char *profile, |
245 | char *awaymsg) | |
9de3ca7e | 246 | { |
9de3ca7e | 247 | struct command_tx_struct newpacket; |
248 | int i = 0; | |
26af6789 | 249 | u_char funkydata[] = { |
250 | 0x09, 0x46, 0x13, 0x46, 0x4c, 0x7f, 0x11, 0xd1, | |
251 | 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00, | |
252 | 0x09, 0x46, 0x13, 0x41, 0x4c, 0x7f, 0x11, 0xd1, | |
253 | 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00, | |
254 | ||
255 | 0x09, 0x46, 0x13, 0x45, 0x4c, 0x7f, 0x11, 0xd1, | |
256 | 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00, | |
257 | 0x74, 0x8f, 0x24, 0x20, 0x62, 0x87, 0x11, 0xd1, | |
258 | 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00, | |
259 | ||
260 | 0x09, 0x46, 0x13, 0x48, 0x4c, 0x7f, 0x11, 0xd1, | |
261 | 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00, | |
262 | 0x09, 0x46, 0x13, 0x43, 0x4c, 0x7f, 0x11, 0xd1, | |
263 | 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 | |
264 | }; | |
9de3ca7e | 265 | |
266 | newpacket.type = 0x02; | |
267 | if (conn) | |
268 | newpacket.conn = conn; | |
269 | else | |
a25832e6 | 270 | newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); |
271 | ||
26af6789 | 272 | newpacket.commandlen = 1152+strlen(profile)+1; /*arbitrarily large */ |
0c20631f | 273 | if (awaymsg) |
274 | newpacket.commandlen += strlen(awaymsg); | |
275 | ||
26af6789 | 276 | newpacket.data = (char *) malloc(newpacket.commandlen); |
9de3ca7e | 277 | |
a25832e6 | 278 | i += aim_putsnac(newpacket.data, 0x0002, 0x004, 0x0000, sess->snac_nextid); |
26af6789 | 279 | i += aim_puttlv_str(newpacket.data+i, 0x0001, strlen("text/x-aolrtf; charset=\"us-ascii\""), "text/x-aolrtf; charset=\"us-ascii\""); |
280 | i += aim_puttlv_str(newpacket.data+i, 0x0002, strlen(profile), profile); | |
281 | /* why do we send this twice? */ | |
282 | i += aim_puttlv_str(newpacket.data+i, 0x0003, strlen("text/x-aolrtf; charset=\"us-ascii\""), "text/x-aolrtf; charset=\"us-ascii\""); | |
9de3ca7e | 283 | |
0c20631f | 284 | /* Away message -- we send this no matter what, even if its blank */ |
285 | if (awaymsg) | |
286 | i += aim_puttlv_str(newpacket.data+i, 0x0004, strlen(awaymsg), awaymsg); | |
287 | else | |
288 | i += aim_puttlv_str(newpacket.data+i, 0x0004, 0x0000, NULL); | |
26af6789 | 289 | |
290 | /* Capability information. */ | |
291 | i += aim_puttlv_str(newpacket.data+i, 0x0005, 0x0060, funkydata); | |
9de3ca7e | 292 | |
26af6789 | 293 | newpacket.commandlen = i; |
a25832e6 | 294 | aim_tx_enqueue(sess, &newpacket); |
9de3ca7e | 295 | |
a25832e6 | 296 | return (sess->snac_nextid++); |
9de3ca7e | 297 | } |
298 | ||
299 | /* | |
300 | * aim_bos_setgroupperm(mask) | |
301 | * | |
302 | * Set group permisson mask. Normally 0x1f. | |
303 | * | |
304 | */ | |
a25832e6 | 305 | u_long aim_bos_setgroupperm(struct aim_session_t *sess, |
306 | struct aim_conn_t *conn, | |
307 | u_long mask) | |
9de3ca7e | 308 | { |
a25832e6 | 309 | return aim_genericreq_l(sess, conn, 0x0009, 0x0004, &mask); |
9de3ca7e | 310 | } |
311 | ||
312 | /* | |
313 | * aim_bos_clientready() | |
314 | * | |
315 | * Send Client Ready. | |
316 | * | |
317 | * TODO: Dynamisize. | |
318 | * | |
319 | */ | |
a25832e6 | 320 | u_long aim_bos_clientready(struct aim_session_t *sess, |
321 | struct aim_conn_t *conn) | |
9de3ca7e | 322 | { |
323 | u_char command_2[] = { | |
324 | /* placeholders for dynamic data */ | |
325 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
326 | 0xff, 0xff, | |
327 | /* real data */ | |
01b59e1e | 328 | 0x00, 0x01, |
329 | 0x00, 0x03, | |
330 | 0x00, 0x04, | |
331 | 0x06, 0x86, | |
332 | 0x00, 0x02, | |
333 | 0x00, 0x01, | |
334 | 0x00, 0x04, | |
335 | 0x00, 0x01, | |
336 | ||
337 | 0x00, 0x03, | |
338 | 0x00, 0x01, | |
339 | 0x00, 0x04, | |
340 | 0x00, 0x01, | |
341 | 0x00, 0x04, | |
342 | 0x00, 0x01, | |
343 | 0x00, 0x04, | |
344 | 0x00, 0x01, | |
345 | ||
346 | 0x00, 0x06, | |
347 | 0x00, 0x01, | |
348 | 0x00, 0x04, | |
349 | 0x00, 0x01, | |
350 | 0x00, 0x08, | |
351 | 0x00, 0x01, | |
352 | 0x00, 0x04, | |
353 | 0x00, 0x01, | |
354 | ||
355 | 0x00, 0x09, | |
356 | 0x00, 0x01, | |
357 | 0x00, 0x04, | |
358 | 0x00, 0x01, | |
359 | 0x00, 0x0a, | |
360 | 0x00, 0x01, | |
361 | 0x00, 0x04, | |
362 | 0x00, 0x01, | |
363 | ||
364 | 0x00, 0x0b, | |
365 | 0x00, 0x01, | |
366 | 0x00, 0x04, | |
9de3ca7e | 367 | 0x00, 0x01 |
368 | }; | |
369 | int command_2_len = 0x52; | |
370 | struct command_tx_struct newpacket; | |
371 | ||
372 | newpacket.lock = 1; | |
373 | if (conn) | |
374 | newpacket.conn = conn; | |
375 | else | |
a25832e6 | 376 | newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); |
9de3ca7e | 377 | newpacket.type = 0x02; |
378 | newpacket.commandlen = command_2_len; | |
379 | newpacket.data = (char *) malloc (newpacket.commandlen); | |
380 | memcpy(newpacket.data, command_2, newpacket.commandlen); | |
381 | ||
382 | /* This write over the dynamic parts of the byte block */ | |
a25832e6 | 383 | aim_putsnac(newpacket.data, 0x0001, 0x0002, 0x0000, sess->snac_nextid); |
9de3ca7e | 384 | |
a25832e6 | 385 | aim_tx_enqueue(sess, &newpacket); |
9de3ca7e | 386 | |
a25832e6 | 387 | return (sess->snac_nextid++); |
9de3ca7e | 388 | } |
389 | ||
390 | /* | |
391 | * send_login_phase3(int socket) | |
392 | * | |
393 | * Request Rate Information. | |
394 | * | |
395 | * TODO: Move to aim_conn. | |
396 | * TODO: Move to SNAC interface. | |
397 | */ | |
a25832e6 | 398 | u_long aim_bos_reqrate(struct aim_session_t *sess, |
399 | struct aim_conn_t *conn) | |
9de3ca7e | 400 | { |
a25832e6 | 401 | return aim_genericreq_n(sess, conn, 0x0001, 0x0006); |
9de3ca7e | 402 | } |
403 | ||
404 | /* | |
405 | * send_login_phase3b(int socket) | |
406 | * | |
407 | * Rate Information Response Acknowledge. | |
408 | * | |
409 | */ | |
a25832e6 | 410 | u_long aim_bos_ackrateresp(struct aim_session_t *sess, |
411 | struct aim_conn_t *conn) | |
9de3ca7e | 412 | { |
413 | struct command_tx_struct newpacket; | |
414 | ||
415 | newpacket.lock = 1; | |
416 | if (conn) | |
417 | newpacket.conn = conn; | |
418 | else | |
a25832e6 | 419 | newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); |
9de3ca7e | 420 | newpacket.type = 0x02; |
421 | newpacket.commandlen = 18; | |
0c20631f | 422 | if (conn->type != AIM_CONN_TYPE_BOS) |
423 | newpacket.commandlen += 2; | |
9de3ca7e | 424 | |
425 | newpacket.data = (char *) malloc(newpacket.commandlen); | |
a25832e6 | 426 | aim_putsnac(newpacket.data, 0x0001, 0x0008, 0x0000, sess->snac_nextid); |
9de3ca7e | 427 | |
428 | newpacket.data[10] = 0x00; | |
429 | newpacket.data[11] = 0x01; | |
430 | newpacket.data[12] = 0x00; | |
431 | newpacket.data[13] = 0x02; | |
432 | newpacket.data[14] = 0x00; | |
433 | newpacket.data[15] = 0x03; | |
434 | newpacket.data[16] = 0x00; | |
435 | newpacket.data[17] = 0x04; | |
0c20631f | 436 | if (conn->type != AIM_CONN_TYPE_BOS) |
437 | { | |
438 | newpacket.data[16] = 0x00; | |
439 | newpacket.data[17] = 0x05; | |
440 | } | |
9de3ca7e | 441 | |
a25832e6 | 442 | aim_tx_enqueue(sess, &newpacket); |
9de3ca7e | 443 | |
a25832e6 | 444 | return (sess->snac_nextid++); |
9de3ca7e | 445 | } |
446 | ||
447 | /* | |
448 | * aim_bos_setprivacyflags() | |
449 | * | |
450 | * Sets privacy flags. Normally 0x03. | |
451 | * | |
452 | * Bit 1: Allows other AIM users to see how long you've been idle. | |
453 | * | |
454 | * | |
455 | */ | |
a25832e6 | 456 | u_long aim_bos_setprivacyflags(struct aim_session_t *sess, |
457 | struct aim_conn_t *conn, | |
458 | u_long flags) | |
9de3ca7e | 459 | { |
a25832e6 | 460 | return aim_genericreq_l(sess, conn, 0x0001, 0x0014, &flags); |
9de3ca7e | 461 | } |
462 | ||
463 | /* | |
464 | * aim_bos_reqpersonalinfo() | |
465 | * | |
466 | * Requests the current user's information. Can't go generic on this one | |
467 | * because aparently it uses SNAC flags. | |
468 | * | |
469 | */ | |
a25832e6 | 470 | u_long aim_bos_reqpersonalinfo(struct aim_session_t *sess, |
471 | struct aim_conn_t *conn) | |
9de3ca7e | 472 | { |
473 | struct command_tx_struct newpacket; | |
474 | ||
475 | newpacket.lock = 1; | |
476 | if (conn) | |
477 | newpacket.conn = conn; | |
478 | else | |
a25832e6 | 479 | newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); |
9de3ca7e | 480 | newpacket.type = 0x02; |
481 | newpacket.commandlen = 12; | |
482 | ||
483 | newpacket.data = (char *) malloc(newpacket.commandlen); | |
a25832e6 | 484 | aim_putsnac(newpacket.data, 0x000a, 0x0001, 0x000e /* huh? */, sess->snac_nextid); |
9de3ca7e | 485 | |
486 | newpacket.data[10] = 0x0d; | |
487 | newpacket.data[11] = 0xda; | |
488 | ||
01b59e1e | 489 | newpacket.lock = 0; |
a25832e6 | 490 | aim_tx_enqueue(sess, &newpacket); |
9de3ca7e | 491 | |
a25832e6 | 492 | return (sess->snac_nextid++); |
9de3ca7e | 493 | } |
494 | ||
01b59e1e | 495 | u_long aim_setversions(struct aim_session_t *sess, |
496 | struct aim_conn_t *conn) | |
497 | { | |
498 | struct command_tx_struct newpacket; | |
0c20631f | 499 | int i; |
01b59e1e | 500 | |
501 | newpacket.lock = 1; | |
502 | if (conn) | |
503 | newpacket.conn = conn; | |
504 | else | |
505 | newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); | |
506 | newpacket.type = 0x02; | |
26af6789 | 507 | newpacket.commandlen = 10 + (4*11); |
01b59e1e | 508 | |
509 | newpacket.data = (char *) malloc(newpacket.commandlen); | |
510 | i = aim_putsnac(newpacket.data, 0x0001, 0x0017, 0x0000, sess->snac_nextid); | |
511 | ||
512 | i += aimutil_put16(newpacket.data+i, 0x0001); | |
513 | i += aimutil_put16(newpacket.data+i, 0x0003); | |
26af6789 | 514 | |
01b59e1e | 515 | i += aimutil_put16(newpacket.data+i, 0x0002); |
516 | i += aimutil_put16(newpacket.data+i, 0x0001); | |
26af6789 | 517 | |
01b59e1e | 518 | i += aimutil_put16(newpacket.data+i, 0x0003); |
519 | i += aimutil_put16(newpacket.data+i, 0x0001); | |
26af6789 | 520 | |
01b59e1e | 521 | i += aimutil_put16(newpacket.data+i, 0x0004); |
522 | i += aimutil_put16(newpacket.data+i, 0x0001); | |
26af6789 | 523 | |
01b59e1e | 524 | i += aimutil_put16(newpacket.data+i, 0x0006); |
525 | i += aimutil_put16(newpacket.data+i, 0x0001); | |
26af6789 | 526 | |
01b59e1e | 527 | i += aimutil_put16(newpacket.data+i, 0x0008); |
528 | i += aimutil_put16(newpacket.data+i, 0x0001); | |
26af6789 | 529 | |
01b59e1e | 530 | i += aimutil_put16(newpacket.data+i, 0x0009); |
531 | i += aimutil_put16(newpacket.data+i, 0x0001); | |
26af6789 | 532 | |
01b59e1e | 533 | i += aimutil_put16(newpacket.data+i, 0x000a); |
534 | i += aimutil_put16(newpacket.data+i, 0x0001); | |
26af6789 | 535 | |
01b59e1e | 536 | i += aimutil_put16(newpacket.data+i, 0x000b); |
537 | i += aimutil_put16(newpacket.data+i, 0x0002); | |
26af6789 | 538 | |
01b59e1e | 539 | i += aimutil_put16(newpacket.data+i, 0x000c); |
540 | i += aimutil_put16(newpacket.data+i, 0x0001); | |
26af6789 | 541 | |
01b59e1e | 542 | i += aimutil_put16(newpacket.data+i, 0x0015); |
01b59e1e | 543 | i += aimutil_put16(newpacket.data+i, 0x0001); |
544 | ||
545 | #if 0 | |
546 | for (j = 0; j < 0x10; j++) | |
01b59e1e | 547 | { |
548 | i += aimutil_put16(newpacket.data+i, j); /* family */ | |
549 | i += aimutil_put16(newpacket.data+i, 0x0003); /* version */ | |
550 | } | |
551 | #endif | |
552 | newpacket.lock = 0; | |
553 | aim_tx_enqueue(sess, &newpacket); | |
554 | ||
555 | return (sess->snac_nextid++); | |
556 | } | |
557 | ||
558 | ||
9de3ca7e | 559 | /* |
560 | * aim_bos_reqservice(serviceid) | |
561 | * | |
562 | * Service request. | |
563 | * | |
564 | */ | |
a25832e6 | 565 | u_long aim_bos_reqservice(struct aim_session_t *sess, |
566 | struct aim_conn_t *conn, | |
567 | u_short serviceid) | |
9de3ca7e | 568 | { |
a25832e6 | 569 | return aim_genericreq_s(sess, conn, 0x0001, 0x0004, &serviceid); |
9de3ca7e | 570 | } |
571 | ||
572 | /* | |
573 | * aim_bos_reqrights() | |
574 | * | |
575 | * Request BOS rights. | |
576 | * | |
577 | */ | |
a25832e6 | 578 | u_long aim_bos_reqrights(struct aim_session_t *sess, |
579 | struct aim_conn_t *conn) | |
9de3ca7e | 580 | { |
a25832e6 | 581 | return aim_genericreq_n(sess, conn, 0x0009, 0x0002); |
9de3ca7e | 582 | } |
583 | ||
584 | /* | |
585 | * aim_bos_reqbuddyrights() | |
586 | * | |
587 | * Request Buddy List rights. | |
588 | * | |
589 | */ | |
a25832e6 | 590 | u_long aim_bos_reqbuddyrights(struct aim_session_t *sess, |
591 | struct aim_conn_t *conn) | |
9de3ca7e | 592 | { |
a25832e6 | 593 | return aim_genericreq_n(sess, conn, 0x0003, 0x0002); |
9de3ca7e | 594 | } |
595 | ||
596 | /* | |
597 | * Generic routine for sending commands. | |
598 | * | |
599 | * | |
600 | * I know I can do this in a smarter way...but I'm not thinking straight | |
601 | * right now... | |
602 | * | |
603 | * I had one big function that handled all three cases, but then it broke | |
604 | * and I split it up into three. But then I fixed it. I just never went | |
605 | * back to the single. I don't see any advantage to doing it either way. | |
606 | * | |
607 | */ | |
a25832e6 | 608 | u_long aim_genericreq_n(struct aim_session_t *sess, |
609 | struct aim_conn_t *conn, | |
610 | u_short family, u_short subtype) | |
9de3ca7e | 611 | { |
612 | struct command_tx_struct newpacket; | |
613 | ||
614 | newpacket.lock = 1; | |
615 | ||
616 | if (conn) | |
617 | newpacket.conn = conn; | |
618 | else | |
a25832e6 | 619 | newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); |
9de3ca7e | 620 | newpacket.type = 0x02; |
621 | ||
622 | newpacket.commandlen = 10; | |
623 | ||
624 | newpacket.data = (char *) malloc(newpacket.commandlen); | |
625 | memset(newpacket.data, 0x00, newpacket.commandlen); | |
626 | ||
a25832e6 | 627 | aim_putsnac(newpacket.data, family, subtype, 0x0000, sess->snac_nextid); |
9de3ca7e | 628 | |
a25832e6 | 629 | aim_tx_enqueue(sess, &newpacket); |
630 | return (sess->snac_nextid++); | |
9de3ca7e | 631 | } |
632 | ||
633 | /* | |
634 | * | |
635 | * | |
636 | */ | |
a25832e6 | 637 | u_long aim_genericreq_l(struct aim_session_t *sess, |
638 | struct aim_conn_t *conn, | |
639 | u_short family, u_short subtype, u_long *longdata) | |
9de3ca7e | 640 | { |
641 | struct command_tx_struct newpacket; | |
642 | u_long newlong; | |
643 | ||
644 | /* If we don't have data, there's no reason to use this function */ | |
645 | if (!longdata) | |
a25832e6 | 646 | return aim_genericreq_n(sess, conn, family, subtype); |
9de3ca7e | 647 | |
648 | newpacket.lock = 1; | |
649 | ||
650 | if (conn) | |
651 | newpacket.conn = conn; | |
652 | else | |
a25832e6 | 653 | newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); |
654 | ||
9de3ca7e | 655 | newpacket.type = 0x02; |
656 | ||
657 | newpacket.commandlen = 10+sizeof(u_long); | |
658 | ||
659 | newpacket.data = (char *) malloc(newpacket.commandlen); | |
660 | memset(newpacket.data, 0x00, newpacket.commandlen); | |
661 | ||
a25832e6 | 662 | aim_putsnac(newpacket.data, family, subtype, 0x0000, sess->snac_nextid); |
9de3ca7e | 663 | |
664 | /* copy in data */ | |
665 | newlong = htonl(*longdata); | |
666 | memcpy(&(newpacket.data[10]), &newlong, sizeof(u_long)); | |
667 | ||
a25832e6 | 668 | aim_tx_enqueue(sess, &newpacket); |
669 | return (sess->snac_nextid++); | |
9de3ca7e | 670 | } |
671 | ||
a25832e6 | 672 | u_long aim_genericreq_s(struct aim_session_t *sess, |
673 | struct aim_conn_t *conn, | |
674 | u_short family, u_short subtype, u_short *shortdata) | |
9de3ca7e | 675 | { |
676 | struct command_tx_struct newpacket; | |
677 | u_short newshort; | |
678 | ||
679 | /* If we don't have data, there's no reason to use this function */ | |
680 | if (!shortdata) | |
a25832e6 | 681 | return aim_genericreq_n(sess, conn, family, subtype); |
9de3ca7e | 682 | |
683 | newpacket.lock = 1; | |
684 | ||
685 | if (conn) | |
686 | newpacket.conn = conn; | |
687 | else | |
a25832e6 | 688 | newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); |
689 | ||
9de3ca7e | 690 | newpacket.type = 0x02; |
691 | ||
692 | newpacket.commandlen = 10+sizeof(u_short); | |
693 | ||
694 | newpacket.data = (char *) malloc(newpacket.commandlen); | |
695 | memset(newpacket.data, 0x00, newpacket.commandlen); | |
696 | ||
a25832e6 | 697 | aim_putsnac(newpacket.data, family, subtype, 0x0000, sess->snac_nextid); |
9de3ca7e | 698 | |
699 | /* copy in data */ | |
700 | newshort = htons(*shortdata); | |
701 | memcpy(&(newpacket.data[10]), &newshort, sizeof(u_short)); | |
702 | ||
a25832e6 | 703 | aim_tx_enqueue(sess, &newpacket); |
704 | return (sess->snac_nextid++); | |
9de3ca7e | 705 | } |
706 | ||
707 | /* | |
708 | * aim_bos_reqlocaterights() | |
709 | * | |
710 | * Request Location services rights. | |
711 | * | |
712 | */ | |
a25832e6 | 713 | u_long aim_bos_reqlocaterights(struct aim_session_t *sess, |
714 | struct aim_conn_t *conn) | |
9de3ca7e | 715 | { |
a25832e6 | 716 | return aim_genericreq_n(sess, conn, 0x0002, 0x0002); |
9de3ca7e | 717 | } |
718 | ||
719 | /* | |
720 | * aim_bos_reqicbmparaminfo() | |
721 | * | |
722 | * Request ICBM parameter information. | |
723 | * | |
724 | */ | |
a25832e6 | 725 | u_long aim_bos_reqicbmparaminfo(struct aim_session_t *sess, |
726 | struct aim_conn_t *conn) | |
9de3ca7e | 727 | { |
a25832e6 | 728 | return aim_genericreq_n(sess, conn, 0x0004, 0x0004); |
9de3ca7e | 729 | } |