2
|
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
|
237
|
14 #include <aim.h>
|
2
|
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 */
|
237
|
24 u_long aim_bos_setidle(struct aim_session_t *sess,
|
|
25 struct aim_conn_t *conn,
|
|
26 u_long idletime)
|
2
|
27 {
|
237
|
28 return aim_genericreq_l(sess, conn, 0x0001, 0x0011, &idletime);
|
2
|
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 */
|
237
|
60 u_long aim_bos_changevisibility(struct aim_session_t *sess,
|
|
61 struct aim_conn_t *conn,
|
|
62 int changetype, char *denylist)
|
2
|
63 {
|
237
|
64 struct command_tx_struct *newpacket;
|
|
65 int packlen = 0;
|
|
66 u_short subtype;
|
2
|
67
|
|
68 char *localcpy = NULL;
|
|
69 char *tmpptr = NULL;
|
|
70 int i,j;
|
237
|
71 int listcount;
|
2
|
72
|
|
73 if (!denylist)
|
|
74 return 0;
|
|
75
|
|
76 localcpy = (char *) malloc(strlen(denylist)+1);
|
|
77 memcpy(localcpy, denylist, strlen(denylist)+1);
|
237
|
78
|
|
79 listcount = aimutil_itemcnt(localcpy, '&');
|
|
80 packlen = aimutil_tokslen(localcpy, 99, '&') + listcount + 9;
|
2
|
81
|
237
|
82 if (!(newpacket = aim_tx_new(0x0002, conn, packlen)))
|
|
83 return -1;
|
2
|
84
|
237
|
85 newpacket->lock = 1;
|
2
|
86
|
|
87 switch(changetype)
|
|
88 {
|
237
|
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;
|
2
|
93 default:
|
237
|
94 free(newpacket->data);
|
|
95 free(newpacket);
|
2
|
96 return 0;
|
|
97 }
|
237
|
98
|
|
99 /* We actually DO NOT send a SNAC ID with this one! */
|
|
100 aim_putsnac(newpacket->data, 0x0009, subtype, 0x00, 0);
|
2
|
101
|
|
102 j = 10; /* the next byte */
|
237
|
103
|
|
104 for (i=0; (i < (listcount - 1)) && (i < 99); i++)
|
2
|
105 {
|
237
|
106 tmpptr = aimutil_itemidx(localcpy, i, '&');
|
|
107
|
|
108 newpacket->data[j] = strlen(tmpptr);
|
|
109 memcpy(&(newpacket->data[j+1]), tmpptr, strlen(tmpptr));
|
2
|
110 j += strlen(tmpptr)+1;
|
237
|
111 free(tmpptr);
|
2
|
112 }
|
237
|
113 free(localcpy);
|
2
|
114
|
237
|
115 newpacket->lock = 0;
|
2
|
116
|
237
|
117 aim_tx_enqueue(sess, newpacket);
|
2
|
118
|
237
|
119 return (sess->snac_nextid); /* dont increment */
|
2
|
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 *
|
237
|
132 * TODO: Clean this up.
|
|
133 *
|
|
134 * XXX: I can't stress the TODO enough.
|
2
|
135 *
|
|
136 */
|
237
|
137 u_long aim_bos_setbuddylist(struct aim_session_t *sess,
|
|
138 struct aim_conn_t *conn,
|
|
139 char *buddy_list)
|
2
|
140 {
|
|
141 int i, j;
|
|
142
|
237
|
143 struct command_tx_struct *newpacket;
|
2
|
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 */
|
237
|
153 if (!buddy_list) {
|
|
154 return -1;
|
|
155 }
|
2
|
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
|
237
|
176 if (!(newpacket = aim_tx_new(0x0002, conn, packet_login_phase3c_hi_b_len - 6)))
|
|
177 return -1;
|
2
|
178
|
237
|
179 newpacket->lock = 1;
|
|
180
|
|
181 aim_putsnac(newpacket->data, 0x0003, 0x0004, 0x0000, sess->snac_nextid);
|
2
|
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
|
237
|
192 newpacket->data[j] = strlen(tmpptr);
|
|
193 memcpy(&(newpacket->data[j+1]), tmpptr, strlen(tmpptr));
|
2
|
194 j += strlen(tmpptr)+1;
|
|
195 i++;
|
|
196 tmpptr = strtok(NULL, "&");
|
|
197 }
|
|
198
|
237
|
199 newpacket->lock = 0;
|
2
|
200
|
237
|
201 aim_tx_enqueue(sess, newpacket);
|
2
|
202
|
237
|
203 return (sess->snac_nextid++);
|
2
|
204 }
|
|
205
|
|
206 /*
|
|
207 * aim_bos_setprofile(profile)
|
|
208 *
|
|
209 * Gives BOS your profile.
|
|
210 *
|
237
|
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 *
|
2
|
226 */
|
237
|
227 u_long aim_bos_setprofile(struct aim_session_t *sess,
|
|
228 struct aim_conn_t *conn,
|
|
229 char *profile,
|
|
230 char *awaymsg,
|
|
231 unsigned int caps)
|
2
|
232 {
|
237
|
233 struct command_tx_struct *newpacket;
|
2
|
234 int i = 0;
|
|
235
|
237
|
236 if (!(newpacket = aim_tx_new(0x0002, conn, 1152+strlen(profile)+1+(awaymsg?strlen(awaymsg):0))))
|
|
237 return -1;
|
2
|
238
|
237
|
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);
|
|
242 /* why do we send this twice? */
|
|
243 i += aim_puttlv_str(newpacket->data+i, 0x0003, strlen("text/x-aolrtf; charset=\"us-ascii\""), "text/x-aolrtf; charset=\"us-ascii\"");
|
|
244
|
|
245 /* Away message -- we send this no matter what, even if its blank */
|
|
246 if (awaymsg)
|
|
247 i += aim_puttlv_str(newpacket->data+i, 0x0004, strlen(awaymsg), awaymsg);
|
2
|
248 else
|
237
|
249 i += aim_puttlv_str(newpacket->data+i, 0x0004, 0x0000, NULL);
|
2
|
250
|
237
|
251 /* Capability information. */
|
|
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);
|
2
|
273
|
237
|
274 return (sess->snac_nextid++);
|
2
|
275 }
|
|
276
|
|
277 /*
|
|
278 * aim_bos_setgroupperm(mask)
|
|
279 *
|
|
280 * Set group permisson mask. Normally 0x1f.
|
|
281 *
|
|
282 */
|
237
|
283 u_long aim_bos_setgroupperm(struct aim_session_t *sess,
|
|
284 struct aim_conn_t *conn,
|
|
285 u_long mask)
|
2
|
286 {
|
237
|
287 return aim_genericreq_l(sess, conn, 0x0009, 0x0004, &mask);
|
2
|
288 }
|
|
289
|
|
290 /*
|
|
291 * aim_bos_clientready()
|
|
292 *
|
|
293 * Send Client Ready.
|
|
294 *
|
|
295 * TODO: Dynamisize.
|
|
296 *
|
|
297 */
|
237
|
298 u_long aim_bos_clientready(struct aim_session_t *sess,
|
|
299 struct aim_conn_t *conn)
|
2
|
300 {
|
237
|
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 */
|
|
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,
|
2
|
345 0x00, 0x01
|
|
346 };
|
|
347 int command_2_len = 0x52;
|
237
|
348 struct command_tx_struct *newpacket;
|
2
|
349
|
237
|
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);
|
2
|
356
|
237
|
357 /* This write over the dynamic parts of the byte block */
|
|
358 aim_putsnac(newpacket->data, 0x0001, 0x0002, 0x0000, sess->snac_nextid);
|
2
|
359
|
237
|
360 aim_tx_enqueue(sess, newpacket);
|
2
|
361
|
237
|
362 return (sess->snac_nextid++);
|
2
|
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 */
|
237
|
373 u_long aim_bos_reqrate(struct aim_session_t *sess,
|
|
374 struct aim_conn_t *conn)
|
2
|
375 {
|
237
|
376 return aim_genericreq_n(sess, conn, 0x0001, 0x0006);
|
2
|
377 }
|
|
378
|
|
379 /*
|
|
380 * send_login_phase3b(int socket)
|
|
381 *
|
|
382 * Rate Information Response Acknowledge.
|
|
383 *
|
|
384 */
|
237
|
385 u_long aim_bos_ackrateresp(struct aim_session_t *sess,
|
|
386 struct aim_conn_t *conn)
|
2
|
387 {
|
237
|
388 struct command_tx_struct *newpacket;
|
|
389 int packlen = 18, i=0;
|
2
|
390
|
237
|
391 if (conn->type != AIM_CONN_TYPE_BOS)
|
|
392 packlen += 2;
|
|
393
|
|
394 if(!(newpacket = aim_tx_new(0x0002, conn, packlen)));
|
|
395
|
|
396 newpacket->lock = 1;
|
2
|
397
|
237
|
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 }
|
2
|
407
|
237
|
408 aim_tx_enqueue(sess, newpacket);
|
2
|
409
|
237
|
410 return (sess->snac_nextid++);
|
2
|
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 */
|
237
|
422 u_long aim_bos_setprivacyflags(struct aim_session_t *sess,
|
|
423 struct aim_conn_t *conn,
|
|
424 u_long flags)
|
2
|
425 {
|
237
|
426 return aim_genericreq_l(sess, conn, 0x0001, 0x0014, &flags);
|
2
|
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 */
|
237
|
436 u_long aim_bos_reqpersonalinfo(struct aim_session_t *sess,
|
|
437 struct aim_conn_t *conn)
|
2
|
438 {
|
237
|
439 struct command_tx_struct *newpacket;
|
2
|
440
|
237
|
441 if (!(newpacket = aim_tx_new(0x0002, conn, 12)))
|
|
442 return -1;
|
2
|
443
|
237
|
444 newpacket->lock = 1;
|
|
445
|
|
446 aim_putsnac(newpacket->data, 0x000a, 0x0001, 0x000e /* huh? */, sess->snac_nextid);
|
2
|
447
|
237
|
448 newpacket->data[10] = 0x0d;
|
|
449 newpacket->data[11] = 0xda;
|
|
450
|
|
451 newpacket->lock = 0;
|
|
452 aim_tx_enqueue(sess, newpacket);
|
|
453
|
|
454 return (sess->snac_nextid++);
|
|
455 }
|
|
456
|
|
457 u_long aim_setversions(struct aim_session_t *sess,
|
|
458 struct aim_conn_t *conn)
|
|
459 {
|
|
460 struct command_tx_struct *newpacket;
|
|
461 int i;
|
|
462
|
|
463 if (!(newpacket = aim_tx_new(0x0002, conn, 10 + (4*11))))
|
|
464 return -1;
|
|
465
|
|
466 newpacket->lock = 1;
|
|
467
|
|
468 i = aim_putsnac(newpacket->data, 0x0001, 0x0017, 0x0000, sess->snac_nextid);
|
|
469
|
|
470 i += aimutil_put16(newpacket->data+i, 0x0001);
|
|
471 i += aimutil_put16(newpacket->data+i, 0x0003);
|
|
472
|
|
473 i += aimutil_put16(newpacket->data+i, 0x0002);
|
|
474 i += aimutil_put16(newpacket->data+i, 0x0001);
|
|
475
|
|
476 i += aimutil_put16(newpacket->data+i, 0x0003);
|
|
477 i += aimutil_put16(newpacket->data+i, 0x0001);
|
|
478
|
|
479 i += aimutil_put16(newpacket->data+i, 0x0004);
|
|
480 i += aimutil_put16(newpacket->data+i, 0x0001);
|
2
|
481
|
237
|
482 i += aimutil_put16(newpacket->data+i, 0x0006);
|
|
483 i += aimutil_put16(newpacket->data+i, 0x0001);
|
|
484
|
|
485 i += aimutil_put16(newpacket->data+i, 0x0008);
|
|
486 i += aimutil_put16(newpacket->data+i, 0x0001);
|
|
487
|
|
488 i += aimutil_put16(newpacket->data+i, 0x0009);
|
|
489 i += aimutil_put16(newpacket->data+i, 0x0001);
|
|
490
|
|
491 i += aimutil_put16(newpacket->data+i, 0x000a);
|
|
492 i += aimutil_put16(newpacket->data+i, 0x0001);
|
|
493
|
|
494 i += aimutil_put16(newpacket->data+i, 0x000b);
|
|
495 i += aimutil_put16(newpacket->data+i, 0x0002);
|
2
|
496
|
237
|
497 i += aimutil_put16(newpacket->data+i, 0x000c);
|
|
498 i += aimutil_put16(newpacket->data+i, 0x0001);
|
|
499
|
|
500 i += aimutil_put16(newpacket->data+i, 0x0015);
|
|
501 i += aimutil_put16(newpacket->data+i, 0x0001);
|
2
|
502
|
237
|
503 #if 0
|
|
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 }
|
|
508 #endif
|
|
509 newpacket->lock = 0;
|
|
510 aim_tx_enqueue(sess, newpacket);
|
2
|
511
|
237
|
512 return (sess->snac_nextid++);
|
2
|
513 }
|
|
514
|
237
|
515
|
2
|
516 /*
|
|
517 * aim_bos_reqservice(serviceid)
|
|
518 *
|
|
519 * Service request.
|
|
520 *
|
|
521 */
|
237
|
522 u_long aim_bos_reqservice(struct aim_session_t *sess,
|
|
523 struct aim_conn_t *conn,
|
|
524 u_short serviceid)
|
2
|
525 {
|
237
|
526 return aim_genericreq_s(sess, conn, 0x0001, 0x0004, &serviceid);
|
2
|
527 }
|
|
528
|
|
529 /*
|
|
530 * aim_bos_reqrights()
|
|
531 *
|
|
532 * Request BOS rights.
|
|
533 *
|
|
534 */
|
237
|
535 u_long aim_bos_reqrights(struct aim_session_t *sess,
|
|
536 struct aim_conn_t *conn)
|
2
|
537 {
|
237
|
538 return aim_genericreq_n(sess, conn, 0x0009, 0x0002);
|
2
|
539 }
|
|
540
|
|
541 /*
|
|
542 * aim_bos_reqbuddyrights()
|
|
543 *
|
|
544 * Request Buddy List rights.
|
|
545 *
|
|
546 */
|
237
|
547 u_long aim_bos_reqbuddyrights(struct aim_session_t *sess,
|
|
548 struct aim_conn_t *conn)
|
2
|
549 {
|
237
|
550 return aim_genericreq_n(sess, conn, 0x0003, 0x0002);
|
2
|
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 */
|
237
|
565 u_long aim_genericreq_n(struct aim_session_t *sess,
|
|
566 struct aim_conn_t *conn,
|
|
567 u_short family, u_short subtype)
|
2
|
568 {
|
237
|
569 struct command_tx_struct *newpacket;
|
2
|
570
|
237
|
571 if (!(newpacket = aim_tx_new(0x0002, conn, 10)))
|
|
572 return 0;
|
|
573
|
|
574 newpacket->lock = 1;
|
2
|
575
|
237
|
576 aim_putsnac(newpacket->data, family, subtype, 0x0000, sess->snac_nextid);
|
|
577
|
|
578 aim_tx_enqueue(sess, newpacket);
|
|
579 return (sess->snac_nextid++);
|
2
|
580 }
|
|
581
|
|
582 /*
|
|
583 *
|
|
584 *
|
|
585 */
|
237
|
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)
|
2
|
589 {
|
237
|
590 struct command_tx_struct *newpacket;
|
2
|
591 u_long newlong;
|
|
592
|
|
593 /* If we don't have data, there's no reason to use this function */
|
|
594 if (!longdata)
|
237
|
595 return aim_genericreq_n(sess, conn, family, subtype);
|
2
|
596
|
237
|
597 if (!(newpacket = aim_tx_new(0x0002, conn, 10+sizeof(u_long))))
|
|
598 return -1;
|
2
|
599
|
237
|
600 newpacket->lock = 1;
|
|
601
|
|
602 aim_putsnac(newpacket->data, family, subtype, 0x0000, sess->snac_nextid);
|
2
|
603
|
|
604 /* copy in data */
|
|
605 newlong = htonl(*longdata);
|
237
|
606 memcpy(&(newpacket->data[10]), &newlong, sizeof(u_long));
|
2
|
607
|
237
|
608 aim_tx_enqueue(sess, newpacket);
|
|
609 return (sess->snac_nextid++);
|
2
|
610 }
|
|
611
|
237
|
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)
|
2
|
615 {
|
237
|
616 struct command_tx_struct *newpacket;
|
2
|
617 u_short newshort;
|
|
618
|
|
619 /* If we don't have data, there's no reason to use this function */
|
|
620 if (!shortdata)
|
237
|
621 return aim_genericreq_n(sess, conn, family, subtype);
|
2
|
622
|
237
|
623 if (!(newpacket = aim_tx_new(0x0002, conn, 10+sizeof(u_short))))
|
|
624 return -1;
|
2
|
625
|
237
|
626 newpacket->lock = 1;
|
|
627
|
|
628 aim_putsnac(newpacket->data, family, subtype, 0x0000, sess->snac_nextid);
|
2
|
629
|
|
630 /* copy in data */
|
|
631 newshort = htons(*shortdata);
|
237
|
632 memcpy(&(newpacket->data[10]), &newshort, sizeof(u_short));
|
2
|
633
|
237
|
634 aim_tx_enqueue(sess, newpacket);
|
|
635 return (sess->snac_nextid++);
|
2
|
636 }
|
|
637
|
|
638 /*
|
|
639 * aim_bos_reqlocaterights()
|
|
640 *
|
|
641 * Request Location services rights.
|
|
642 *
|
|
643 */
|
237
|
644 u_long aim_bos_reqlocaterights(struct aim_session_t *sess,
|
|
645 struct aim_conn_t *conn)
|
2
|
646 {
|
237
|
647 return aim_genericreq_n(sess, conn, 0x0002, 0x0002);
|
2
|
648 }
|
|
649
|
|
650 /*
|
|
651 * aim_bos_reqicbmparaminfo()
|
|
652 *
|
|
653 * Request ICBM parameter information.
|
|
654 *
|
|
655 */
|
237
|
656 u_long aim_bos_reqicbmparaminfo(struct aim_session_t *sess,
|
|
657 struct aim_conn_t *conn)
|
2
|
658 {
|
237
|
659 return aim_genericreq_n(sess, conn, 0x0004, 0x0004);
|
2
|
660 }
|