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