]> andersk Git - libfaim.git/blame - aim_misc.c
*** empty log message ***
[libfaim.git] / aim_misc.c
CommitLineData
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 24u_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 60u_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 141u_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 *
226 */
a25832e6 227u_long aim_bos_setprofile(struct aim_session_t *sess,
228 struct aim_conn_t *conn,
229 char *profile)
9de3ca7e 230{
231 int packet_profile_len = 0;
232 struct command_tx_struct newpacket;
233 int i = 0;
234
235 /* len: SNAC */
236 packet_profile_len = 10;
237 /* len: T+L (where t(0001)) */
238 packet_profile_len += 2 + 2;
239 /* len: V (where t(0001)) */
240 packet_profile_len += strlen("text/x-aolrtf");
241 /* len: T+L (where t(0002)) */
242 packet_profile_len += 2 + 2;
243 /* len: V (where t(0002)) */
244 packet_profile_len += strlen(profile);
245
246 newpacket.type = 0x02;
247 if (conn)
248 newpacket.conn = conn;
249 else
a25832e6 250 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
251
9de3ca7e 252 newpacket.commandlen = packet_profile_len;
253 newpacket.data = (char *) malloc(packet_profile_len);
254
255 i = 0;
256
a25832e6 257 i += aim_putsnac(newpacket.data, 0x0002, 0x004, 0x0000, sess->snac_nextid);
9de3ca7e 258
259 /* TLV t(0001) */
260 newpacket.data[i++] = 0x00;
261 newpacket.data[i++] = 0x01;
262 /* TLV l(000d) */
263 newpacket.data[i++] = 0x00;
264 newpacket.data[i++] = 0x0d;
265 /* TLV v(text/x-aolrtf) */
266 memcpy(&(newpacket.data[i]), "text/x-aolrtf", 0x000d);
267 i += 0x000d;
268
269 /* TLV t(0002) */
270 newpacket.data[i++] = 0x00;
271 newpacket.data[i++] = 0x02;
272 /* TLV l() */
273 newpacket.data[i++] = (strlen(profile) >> 8) & 0xFF;
274 newpacket.data[i++] = (strlen(profile) & 0xFF);
275 /* TLV v(profile) */
276 memcpy(&(newpacket.data[i]), profile, strlen(profile));
277
a25832e6 278 aim_tx_enqueue(sess, &newpacket);
9de3ca7e 279
a25832e6 280 return (sess->snac_nextid++);
9de3ca7e 281}
282
283/*
284 * aim_bos_setgroupperm(mask)
285 *
286 * Set group permisson mask. Normally 0x1f.
287 *
288 */
a25832e6 289u_long aim_bos_setgroupperm(struct aim_session_t *sess,
290 struct aim_conn_t *conn,
291 u_long mask)
9de3ca7e 292{
a25832e6 293 return aim_genericreq_l(sess, conn, 0x0009, 0x0004, &mask);
9de3ca7e 294}
295
296/*
297 * aim_bos_clientready()
298 *
299 * Send Client Ready.
300 *
301 * TODO: Dynamisize.
302 *
303 */
a25832e6 304u_long aim_bos_clientready(struct aim_session_t *sess,
305 struct aim_conn_t *conn)
9de3ca7e 306{
307 u_char command_2[] = {
308 /* placeholders for dynamic data */
309 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
310 0xff, 0xff,
311 /* real data */
312 0x00, 0x01, 0x00, 0x02, 0x00, 0x01,
313 0x00, 0x13, 0x00, 0x09, 0x00, 0x01, 0x00, 0x01,
314 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01,
315 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x01,
316 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01,
317 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,
318 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x01,
319 0x00, 0x01, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x01,
320 0x00, 0x01, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x01,
321 0x00, 0x01
322 };
323 int command_2_len = 0x52;
324 struct command_tx_struct newpacket;
325
326 newpacket.lock = 1;
327 if (conn)
328 newpacket.conn = conn;
329 else
a25832e6 330 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
9de3ca7e 331 newpacket.type = 0x02;
332 newpacket.commandlen = command_2_len;
333 newpacket.data = (char *) malloc (newpacket.commandlen);
334 memcpy(newpacket.data, command_2, newpacket.commandlen);
335
336 /* This write over the dynamic parts of the byte block */
a25832e6 337 aim_putsnac(newpacket.data, 0x0001, 0x0002, 0x0000, sess->snac_nextid);
9de3ca7e 338
a25832e6 339 aim_tx_enqueue(sess, &newpacket);
9de3ca7e 340
a25832e6 341 return (sess->snac_nextid++);
9de3ca7e 342}
343
344/*
345 * send_login_phase3(int socket)
346 *
347 * Request Rate Information.
348 *
349 * TODO: Move to aim_conn.
350 * TODO: Move to SNAC interface.
351 */
a25832e6 352u_long aim_bos_reqrate(struct aim_session_t *sess,
353 struct aim_conn_t *conn)
9de3ca7e 354{
a25832e6 355 return aim_genericreq_n(sess, conn, 0x0001, 0x0006);
9de3ca7e 356}
357
358/*
359 * send_login_phase3b(int socket)
360 *
361 * Rate Information Response Acknowledge.
362 *
363 */
a25832e6 364u_long aim_bos_ackrateresp(struct aim_session_t *sess,
365 struct aim_conn_t *conn)
9de3ca7e 366{
367 struct command_tx_struct newpacket;
368
369 newpacket.lock = 1;
370 if (conn)
371 newpacket.conn = conn;
372 else
a25832e6 373 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
9de3ca7e 374 newpacket.type = 0x02;
375 newpacket.commandlen = 18;
376
377 newpacket.data = (char *) malloc(newpacket.commandlen);
a25832e6 378 aim_putsnac(newpacket.data, 0x0001, 0x0008, 0x0000, sess->snac_nextid);
9de3ca7e 379
380 newpacket.data[10] = 0x00;
381 newpacket.data[11] = 0x01;
382 newpacket.data[12] = 0x00;
383 newpacket.data[13] = 0x02;
384 newpacket.data[14] = 0x00;
385 newpacket.data[15] = 0x03;
386 newpacket.data[16] = 0x00;
387 newpacket.data[17] = 0x04;
388
a25832e6 389 aim_tx_enqueue(sess, &newpacket);
9de3ca7e 390
a25832e6 391 return (sess->snac_nextid++);
9de3ca7e 392}
393
394/*
395 * aim_bos_setprivacyflags()
396 *
397 * Sets privacy flags. Normally 0x03.
398 *
399 * Bit 1: Allows other AIM users to see how long you've been idle.
400 *
401 *
402 */
a25832e6 403u_long aim_bos_setprivacyflags(struct aim_session_t *sess,
404 struct aim_conn_t *conn,
405 u_long flags)
9de3ca7e 406{
a25832e6 407 return aim_genericreq_l(sess, conn, 0x0001, 0x0014, &flags);
9de3ca7e 408}
409
410/*
411 * aim_bos_reqpersonalinfo()
412 *
413 * Requests the current user's information. Can't go generic on this one
414 * because aparently it uses SNAC flags.
415 *
416 */
a25832e6 417u_long aim_bos_reqpersonalinfo(struct aim_session_t *sess,
418 struct aim_conn_t *conn)
9de3ca7e 419{
420 struct command_tx_struct newpacket;
421
422 newpacket.lock = 1;
423 if (conn)
424 newpacket.conn = conn;
425 else
a25832e6 426 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
9de3ca7e 427 newpacket.type = 0x02;
428 newpacket.commandlen = 12;
429
430 newpacket.data = (char *) malloc(newpacket.commandlen);
a25832e6 431 aim_putsnac(newpacket.data, 0x000a, 0x0001, 0x000e /* huh? */, sess->snac_nextid);
9de3ca7e 432
433 newpacket.data[10] = 0x0d;
434 newpacket.data[11] = 0xda;
435
a25832e6 436 aim_tx_enqueue(sess, &newpacket);
9de3ca7e 437
a25832e6 438 return (sess->snac_nextid++);
9de3ca7e 439}
440
441/*
442 * aim_bos_reqservice(serviceid)
443 *
444 * Service request.
445 *
446 */
a25832e6 447u_long aim_bos_reqservice(struct aim_session_t *sess,
448 struct aim_conn_t *conn,
449 u_short serviceid)
9de3ca7e 450{
a25832e6 451 return aim_genericreq_s(sess, conn, 0x0001, 0x0004, &serviceid);
9de3ca7e 452}
453
454/*
455 * aim_bos_reqrights()
456 *
457 * Request BOS rights.
458 *
459 */
a25832e6 460u_long aim_bos_reqrights(struct aim_session_t *sess,
461 struct aim_conn_t *conn)
9de3ca7e 462{
a25832e6 463 return aim_genericreq_n(sess, conn, 0x0009, 0x0002);
9de3ca7e 464}
465
466/*
467 * aim_bos_reqbuddyrights()
468 *
469 * Request Buddy List rights.
470 *
471 */
a25832e6 472u_long aim_bos_reqbuddyrights(struct aim_session_t *sess,
473 struct aim_conn_t *conn)
9de3ca7e 474{
a25832e6 475 return aim_genericreq_n(sess, conn, 0x0003, 0x0002);
9de3ca7e 476}
477
478/*
479 * Generic routine for sending commands.
480 *
481 *
482 * I know I can do this in a smarter way...but I'm not thinking straight
483 * right now...
484 *
485 * I had one big function that handled all three cases, but then it broke
486 * and I split it up into three. But then I fixed it. I just never went
487 * back to the single. I don't see any advantage to doing it either way.
488 *
489 */
a25832e6 490u_long aim_genericreq_n(struct aim_session_t *sess,
491 struct aim_conn_t *conn,
492 u_short family, u_short subtype)
9de3ca7e 493{
494 struct command_tx_struct newpacket;
495
496 newpacket.lock = 1;
497
498 if (conn)
499 newpacket.conn = conn;
500 else
a25832e6 501 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
9de3ca7e 502 newpacket.type = 0x02;
503
504 newpacket.commandlen = 10;
505
506 newpacket.data = (char *) malloc(newpacket.commandlen);
507 memset(newpacket.data, 0x00, newpacket.commandlen);
508
a25832e6 509 aim_putsnac(newpacket.data, family, subtype, 0x0000, sess->snac_nextid);
9de3ca7e 510
a25832e6 511 aim_tx_enqueue(sess, &newpacket);
512 return (sess->snac_nextid++);
9de3ca7e 513}
514
515/*
516 *
517 *
518 */
a25832e6 519u_long aim_genericreq_l(struct aim_session_t *sess,
520 struct aim_conn_t *conn,
521 u_short family, u_short subtype, u_long *longdata)
9de3ca7e 522{
523 struct command_tx_struct newpacket;
524 u_long newlong;
525
526 /* If we don't have data, there's no reason to use this function */
527 if (!longdata)
a25832e6 528 return aim_genericreq_n(sess, conn, family, subtype);
9de3ca7e 529
530 newpacket.lock = 1;
531
532 if (conn)
533 newpacket.conn = conn;
534 else
a25832e6 535 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
536
9de3ca7e 537 newpacket.type = 0x02;
538
539 newpacket.commandlen = 10+sizeof(u_long);
540
541 newpacket.data = (char *) malloc(newpacket.commandlen);
542 memset(newpacket.data, 0x00, newpacket.commandlen);
543
a25832e6 544 aim_putsnac(newpacket.data, family, subtype, 0x0000, sess->snac_nextid);
9de3ca7e 545
546 /* copy in data */
547 newlong = htonl(*longdata);
548 memcpy(&(newpacket.data[10]), &newlong, sizeof(u_long));
549
a25832e6 550 aim_tx_enqueue(sess, &newpacket);
551 return (sess->snac_nextid++);
9de3ca7e 552}
553
a25832e6 554u_long aim_genericreq_s(struct aim_session_t *sess,
555 struct aim_conn_t *conn,
556 u_short family, u_short subtype, u_short *shortdata)
9de3ca7e 557{
558 struct command_tx_struct newpacket;
559 u_short newshort;
560
561 /* If we don't have data, there's no reason to use this function */
562 if (!shortdata)
a25832e6 563 return aim_genericreq_n(sess, conn, family, subtype);
9de3ca7e 564
565 newpacket.lock = 1;
566
567 if (conn)
568 newpacket.conn = conn;
569 else
a25832e6 570 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
571
9de3ca7e 572 newpacket.type = 0x02;
573
574 newpacket.commandlen = 10+sizeof(u_short);
575
576 newpacket.data = (char *) malloc(newpacket.commandlen);
577 memset(newpacket.data, 0x00, newpacket.commandlen);
578
a25832e6 579 aim_putsnac(newpacket.data, family, subtype, 0x0000, sess->snac_nextid);
9de3ca7e 580
581 /* copy in data */
582 newshort = htons(*shortdata);
583 memcpy(&(newpacket.data[10]), &newshort, sizeof(u_short));
584
a25832e6 585 aim_tx_enqueue(sess, &newpacket);
586 return (sess->snac_nextid++);
9de3ca7e 587}
588
589/*
590 * aim_bos_reqlocaterights()
591 *
592 * Request Location services rights.
593 *
594 */
a25832e6 595u_long aim_bos_reqlocaterights(struct aim_session_t *sess,
596 struct aim_conn_t *conn)
9de3ca7e 597{
a25832e6 598 return aim_genericreq_n(sess, conn, 0x0002, 0x0002);
9de3ca7e 599}
600
601/*
602 * aim_bos_reqicbmparaminfo()
603 *
604 * Request ICBM parameter information.
605 *
606 */
a25832e6 607u_long aim_bos_reqicbmparaminfo(struct aim_session_t *sess,
608 struct aim_conn_t *conn)
9de3ca7e 609{
a25832e6 610 return aim_genericreq_n(sess, conn, 0x0004, 0x0004);
9de3ca7e 611}
This page took 0.13191 seconds and 5 git commands to generate.