]> andersk Git - libfaim.git/blame - aim_misc.c
Initial Checkin. For real.
[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
14#include "aim.h"
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 */
24u_long aim_bos_setidle(struct aim_conn_t *conn, u_long idletime)
25{
26 return aim_genericreq_l(conn, 0x0001, 0x0011, &idletime);
27}
28
29
30/*
31 * aim_bos_changevisibility(conn, changtype, namelist)
32 *
33 * Changes your visibility depending on changetype:
34 *
35 * AIM_VISIBILITYCHANGE_PERMITADD: Lets provided list of names see you
36 * AIM_VISIBILITYCHANGE_PERMIDREMOVE: Removes listed names from permit list
37 * AIM_VISIBILITYCHANGE_DENYADD: Hides you from provided list of names
38 * AIM_VISIBILITYCHANGE_DENYREMOVE: Lets list see you again
39 *
40 * list should be a list of
41 * screen names in the form "Screen Name One&ScreenNameTwo&" etc.
42 *
43 * Equivelents to options in WinAIM:
44 * - Allow all users to contact me: Send an AIM_VISIBILITYCHANGE_DENYADD
45 * with only your name on it.
46 * - Allow only users on my Buddy List: Send an
47 * AIM_VISIBILITYCHANGE_PERMITADD with the list the same as your
48 * buddy list
49 * - Allow only the uesrs below: Send an AIM_VISIBILITYCHANGE_PERMITADD
50 * with everyone listed that you want to see you.
51 * - Block all users: Send an AIM_VISIBILITYCHANGE_PERMITADD with only
52 * yourself in the list
53 * - Block the users below: Send an AIM_VISIBILITYCHANGE_DENYADD with
54 * the list of users to be blocked
55 *
56 *
57 */
58u_long aim_bos_changevisibility(struct aim_conn_t *conn, int changetype, char *denylist)
59{
60 struct command_tx_struct newpacket;
61 u_short subtype;
62
63 char *localcpy = NULL;
64 char *tmpptr = NULL;
65 int i,j;
66 int listcount;
67
68 if (!denylist)
69 return 0;
70
71 newpacket.lock = 1;
72
73 if (conn)
74 newpacket.conn = conn;
75 else
76 newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
77
78 newpacket.type = 0x02;
79
80 localcpy = (char *) malloc(strlen(denylist)+1);
81 memcpy(localcpy, denylist, strlen(denylist)+1);
82
83 listcount = aimutil_itemcnt(localcpy, '&');
84 newpacket.commandlen = aimutil_tokslen(localcpy, 99, '&') + listcount + 9;
85
86
87 newpacket.data = (char *) malloc(newpacket.commandlen);
88 memset(newpacket.data, 0x00, newpacket.commandlen);
89
90 switch(changetype)
91 {
92 case AIM_VISIBILITYCHANGE_PERMITADD: subtype = 0x05; break;
93 case AIM_VISIBILITYCHANGE_PERMITREMOVE: subtype = 0x06; break;
94 case AIM_VISIBILITYCHANGE_DENYADD: subtype = 0x07; break;
95 case AIM_VISIBILITYCHANGE_DENYREMOVE: subtype = 0x08; break;
96 default:
97 free(newpacket.data);
98 return 0;
99 }
100
101 /* We actually DO NOT send a SNAC ID with this one! */
102 aim_putsnac(newpacket.data, 0x0009, subtype, 0x00, 0);
103
104 j = 10; /* the next byte */
105
106 for (i=0; (i < (listcount - 1)) && (i < 99); i++)
107 {
108 tmpptr = aimutil_itemidx(localcpy, i, '&');
109
110 newpacket.data[j] = strlen(tmpptr);
111 memcpy(&(newpacket.data[j+1]), tmpptr, strlen(tmpptr));
112 j += strlen(tmpptr)+1;
113 free(tmpptr);
114 }
115 free(localcpy);
116
117 newpacket.lock = 0;
118
119 aim_tx_enqueue(&newpacket);
120
121 return (aim_snac_nextid); /* dont increment */
122
123}
124
125
126
127/*
128 * aim_bos_setbuddylist(buddylist)
129 *
130 * This just builds the "set buddy list" command then queues it.
131 *
132 * buddy_list = "Screen Name One&ScreenNameTwo&";
133 *
134 * TODO: Clean this up.
135 *
136 */
137u_long aim_bos_setbuddylist(struct aim_conn_t *conn, char *buddy_list)
138{
139 int i, j;
140
141 struct command_tx_struct newpacket;
142
143 int packet_login_phase3c_hi_b_len = 0;
144
145 char *localcpy = NULL;
146 char *tmpptr = NULL;
147
148 packet_login_phase3c_hi_b_len = 16; /* 16b for FLAP and SNAC headers */
149
150 /* bail out if we can't make the packet */
151 if (buddy_list == NULL)
152 {
153 printf("\nNO BUDDIES! ARE YOU THAT LONELY???\n");
154 return 0;
155 }
156#if debug > 0
157 printf("****buddy list: %s\n", buddy_list);
158 printf("****buddy list len: %d (%x)\n", strlen(buddy_list), strlen(buddy_list));
159#endif
160
161 localcpy = (char *) malloc(strlen(buddy_list)+1);
162 memcpy(localcpy, buddy_list, strlen(buddy_list)+1);
163
164 i = 0;
165 tmpptr = strtok(localcpy, "&");
166 while ((tmpptr != NULL) && (i < 100))
167 {
168#if debug > 0
169 printf("---adding %s (%d)\n", tmpptr, strlen(tmpptr));
170#endif
171 packet_login_phase3c_hi_b_len += strlen(tmpptr)+1;
172 i++;
173 tmpptr = strtok(NULL, "&");
174 }
175#if debug > 0
176 printf("*** send buddy list len: %d (%x)\n", packet_login_phase3c_hi_b_len, packet_login_phase3c_hi_b_len);
177#endif
178 free(localcpy);
179
180 newpacket.type = 0x02;
181 if (conn)
182 newpacket.conn = conn;
183 else
184 newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
185 newpacket.commandlen = packet_login_phase3c_hi_b_len - 6;
186 newpacket.lock = 1;
187
188 newpacket.data = (char *) malloc(newpacket.commandlen);
189
190 aim_putsnac(newpacket.data, 0x0003, 0x0004, 0x0000, aim_snac_nextid);
191
192 j = 10; /* the next byte */
193
194 i = 0;
195 tmpptr = strtok(buddy_list, "&");
196 while ((tmpptr != NULL) & (i < 100))
197 {
198#if debug > 0
199 printf("---adding %s (%d)\n", tmpptr, strlen(tmpptr));
200#endif
201 newpacket.data[j] = strlen(tmpptr);
202 memcpy(&(newpacket.data[j+1]), tmpptr, strlen(tmpptr));
203 j += strlen(tmpptr)+1;
204 i++;
205 tmpptr = strtok(NULL, "&");
206 }
207
208 newpacket.lock = 0;
209
210 aim_tx_enqueue(&newpacket);
211
212 return (aim_snac_nextid++);
213}
214
215/*
216 * aim_bos_setprofile(profile)
217 *
218 * Gives BOS your profile.
219 *
220 */
221u_long aim_bos_setprofile(struct aim_conn_t *conn, char *profile)
222{
223 int packet_profile_len = 0;
224 struct command_tx_struct newpacket;
225 int i = 0;
226
227 /* len: SNAC */
228 packet_profile_len = 10;
229 /* len: T+L (where t(0001)) */
230 packet_profile_len += 2 + 2;
231 /* len: V (where t(0001)) */
232 packet_profile_len += strlen("text/x-aolrtf");
233 /* len: T+L (where t(0002)) */
234 packet_profile_len += 2 + 2;
235 /* len: V (where t(0002)) */
236 packet_profile_len += strlen(profile);
237
238 newpacket.type = 0x02;
239 if (conn)
240 newpacket.conn = conn;
241 else
242 newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
243 newpacket.commandlen = packet_profile_len;
244 newpacket.data = (char *) malloc(packet_profile_len);
245
246 i = 0;
247
248 i += aim_putsnac(newpacket.data, 0x0002, 0x004, 0x0000, aim_snac_nextid);
249
250 /* TLV t(0001) */
251 newpacket.data[i++] = 0x00;
252 newpacket.data[i++] = 0x01;
253 /* TLV l(000d) */
254 newpacket.data[i++] = 0x00;
255 newpacket.data[i++] = 0x0d;
256 /* TLV v(text/x-aolrtf) */
257 memcpy(&(newpacket.data[i]), "text/x-aolrtf", 0x000d);
258 i += 0x000d;
259
260 /* TLV t(0002) */
261 newpacket.data[i++] = 0x00;
262 newpacket.data[i++] = 0x02;
263 /* TLV l() */
264 newpacket.data[i++] = (strlen(profile) >> 8) & 0xFF;
265 newpacket.data[i++] = (strlen(profile) & 0xFF);
266 /* TLV v(profile) */
267 memcpy(&(newpacket.data[i]), profile, strlen(profile));
268
269 aim_tx_enqueue(&newpacket);
270
271 return (aim_snac_nextid++);
272}
273
274/*
275 * aim_bos_setgroupperm(mask)
276 *
277 * Set group permisson mask. Normally 0x1f.
278 *
279 */
280u_long aim_bos_setgroupperm(struct aim_conn_t *conn, u_long mask)
281{
282 return aim_genericreq_l(conn, 0x0009, 0x0004, &mask);
283}
284
285/*
286 * aim_bos_clientready()
287 *
288 * Send Client Ready.
289 *
290 * TODO: Dynamisize.
291 *
292 */
293u_long aim_bos_clientready(struct aim_conn_t *conn)
294{
295 u_char command_2[] = {
296 /* placeholders for dynamic data */
297 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
298 0xff, 0xff,
299 /* real data */
300 0x00, 0x01, 0x00, 0x02, 0x00, 0x01,
301 0x00, 0x13, 0x00, 0x09, 0x00, 0x01, 0x00, 0x01,
302 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01,
303 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x01,
304 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01,
305 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,
306 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x01,
307 0x00, 0x01, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x01,
308 0x00, 0x01, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x01,
309 0x00, 0x01
310 };
311 int command_2_len = 0x52;
312 struct command_tx_struct newpacket;
313
314 newpacket.lock = 1;
315 if (conn)
316 newpacket.conn = conn;
317 else
318 newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
319 newpacket.type = 0x02;
320 newpacket.commandlen = command_2_len;
321 newpacket.data = (char *) malloc (newpacket.commandlen);
322 memcpy(newpacket.data, command_2, newpacket.commandlen);
323
324 /* This write over the dynamic parts of the byte block */
325 aim_putsnac(newpacket.data, 0x0001, 0x0002, 0x0000, aim_snac_nextid);
326
327 aim_tx_enqueue(&newpacket);
328
329 return (aim_snac_nextid++);
330}
331
332/*
333 * send_login_phase3(int socket)
334 *
335 * Request Rate Information.
336 *
337 * TODO: Move to aim_conn.
338 * TODO: Move to SNAC interface.
339 */
340u_long aim_bos_reqrate(struct aim_conn_t *conn)
341{
342 return aim_genericreq_n(conn, 0x0001, 0x0006);
343}
344
345/*
346 * send_login_phase3b(int socket)
347 *
348 * Rate Information Response Acknowledge.
349 *
350 */
351u_long aim_bos_ackrateresp(struct aim_conn_t *conn)
352{
353 struct command_tx_struct newpacket;
354
355 newpacket.lock = 1;
356 if (conn)
357 newpacket.conn = conn;
358 else
359 newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
360 newpacket.type = 0x02;
361 newpacket.commandlen = 18;
362
363 newpacket.data = (char *) malloc(newpacket.commandlen);
364 aim_putsnac(newpacket.data, 0x0001, 0x0008, 0x0000, aim_snac_nextid);
365
366 newpacket.data[10] = 0x00;
367 newpacket.data[11] = 0x01;
368 newpacket.data[12] = 0x00;
369 newpacket.data[13] = 0x02;
370 newpacket.data[14] = 0x00;
371 newpacket.data[15] = 0x03;
372 newpacket.data[16] = 0x00;
373 newpacket.data[17] = 0x04;
374
375 aim_tx_enqueue(&newpacket);
376
377 return (aim_snac_nextid++);
378}
379
380/*
381 * aim_bos_setprivacyflags()
382 *
383 * Sets privacy flags. Normally 0x03.
384 *
385 * Bit 1: Allows other AIM users to see how long you've been idle.
386 *
387 *
388 */
389u_long aim_bos_setprivacyflags(struct aim_conn_t *conn, u_long flags)
390{
391 return aim_genericreq_l(conn, 0x0001, 0x0014, &flags);
392}
393
394/*
395 * aim_bos_reqpersonalinfo()
396 *
397 * Requests the current user's information. Can't go generic on this one
398 * because aparently it uses SNAC flags.
399 *
400 */
401u_long aim_bos_reqpersonalinfo(struct aim_conn_t *conn)
402{
403 struct command_tx_struct newpacket;
404
405 newpacket.lock = 1;
406 if (conn)
407 newpacket.conn = conn;
408 else
409 newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
410 newpacket.type = 0x02;
411 newpacket.commandlen = 12;
412
413 newpacket.data = (char *) malloc(newpacket.commandlen);
414 aim_putsnac(newpacket.data, 0x000a, 0x0001, 0x000e /* huh? */, aim_snac_nextid);
415
416 newpacket.data[10] = 0x0d;
417 newpacket.data[11] = 0xda;
418
419 aim_tx_enqueue(&newpacket);
420
421 return (aim_snac_nextid++);
422}
423
424/*
425 * aim_bos_reqservice(serviceid)
426 *
427 * Service request.
428 *
429 */
430u_long aim_bos_reqservice(struct aim_conn_t *conn, u_short serviceid)
431{
432 return aim_genericreq_s(conn, 0x0001, 0x0004, &serviceid);
433}
434
435/*
436 * aim_bos_reqrights()
437 *
438 * Request BOS rights.
439 *
440 */
441u_long aim_bos_reqrights(struct aim_conn_t *conn)
442{
443 return aim_genericreq_n(conn, 0x0009, 0x0002);
444}
445
446/*
447 * aim_bos_reqbuddyrights()
448 *
449 * Request Buddy List rights.
450 *
451 */
452u_long aim_bos_reqbuddyrights(struct aim_conn_t *conn)
453{
454 return aim_genericreq_n(conn, 0x0003, 0x0002);
455}
456
457/*
458 * Generic routine for sending commands.
459 *
460 *
461 * I know I can do this in a smarter way...but I'm not thinking straight
462 * right now...
463 *
464 * I had one big function that handled all three cases, but then it broke
465 * and I split it up into three. But then I fixed it. I just never went
466 * back to the single. I don't see any advantage to doing it either way.
467 *
468 */
469u_long aim_genericreq_n(struct aim_conn_t *conn, u_short family, u_short subtype)
470{
471 struct command_tx_struct newpacket;
472
473 newpacket.lock = 1;
474
475 if (conn)
476 newpacket.conn = conn;
477 else
478 newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
479 newpacket.type = 0x02;
480
481 newpacket.commandlen = 10;
482
483 newpacket.data = (char *) malloc(newpacket.commandlen);
484 memset(newpacket.data, 0x00, newpacket.commandlen);
485
486 aim_putsnac(newpacket.data, family, subtype, 0x0000, aim_snac_nextid);
487
488 aim_tx_enqueue(&newpacket);
489 return (aim_snac_nextid++);
490}
491
492/*
493 *
494 *
495 */
496u_long aim_genericreq_l(struct aim_conn_t *conn, u_short family, u_short subtype, u_long *longdata)
497{
498 struct command_tx_struct newpacket;
499 u_long newlong;
500
501 /* If we don't have data, there's no reason to use this function */
502 if (!longdata)
503 return aim_genericreq_n(conn, family, subtype);
504
505 newpacket.lock = 1;
506
507 if (conn)
508 newpacket.conn = conn;
509 else
510 newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
511 newpacket.type = 0x02;
512
513 newpacket.commandlen = 10+sizeof(u_long);
514
515 newpacket.data = (char *) malloc(newpacket.commandlen);
516 memset(newpacket.data, 0x00, newpacket.commandlen);
517
518 aim_putsnac(newpacket.data, family, subtype, 0x0000, aim_snac_nextid);
519
520 /* copy in data */
521 newlong = htonl(*longdata);
522 memcpy(&(newpacket.data[10]), &newlong, sizeof(u_long));
523
524 aim_tx_enqueue(&newpacket);
525 return (aim_snac_nextid++);
526}
527
528u_long aim_genericreq_s(struct aim_conn_t *conn, u_short family, u_short subtype, u_short *shortdata)
529{
530 struct command_tx_struct newpacket;
531 u_short newshort;
532
533 /* If we don't have data, there's no reason to use this function */
534 if (!shortdata)
535 return aim_genericreq_n(conn, family, subtype);
536
537 newpacket.lock = 1;
538
539 if (conn)
540 newpacket.conn = conn;
541 else
542 newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
543 newpacket.type = 0x02;
544
545 newpacket.commandlen = 10+sizeof(u_short);
546
547 newpacket.data = (char *) malloc(newpacket.commandlen);
548 memset(newpacket.data, 0x00, newpacket.commandlen);
549
550 aim_putsnac(newpacket.data, family, subtype, 0x0000, aim_snac_nextid);
551
552 /* copy in data */
553 newshort = htons(*shortdata);
554 memcpy(&(newpacket.data[10]), &newshort, sizeof(u_short));
555
556 aim_tx_enqueue(&newpacket);
557 return (aim_snac_nextid++);
558}
559
560/*
561 * aim_bos_reqlocaterights()
562 *
563 * Request Location services rights.
564 *
565 */
566u_long aim_bos_reqlocaterights(struct aim_conn_t *conn)
567{
568 return aim_genericreq_n(conn, 0x0002, 0x0002);
569}
570
571/*
572 * aim_bos_reqicbmparaminfo()
573 *
574 * Request ICBM parameter information.
575 *
576 */
577u_long aim_bos_reqicbmparaminfo(struct aim_conn_t *conn)
578{
579 return aim_genericreq_n(conn, 0x0004, 0x0004);
580}
This page took 0.499082 seconds and 5 git commands to generate.