]> andersk Git - libfaim.git/blame_incremental - aim_misc.c
Fix last bugfix.
[libfaim.git] / aim_misc.c
... / ...
CommitLineData
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 <faim/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_session_t *sess,
25 struct aim_conn_t *conn,
26 u_long idletime)
27{
28 return aim_genericreq_l(sess, conn, 0x0001, 0x0011, &idletime);
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 */
60u_long aim_bos_changevisibility(struct aim_session_t *sess,
61 struct aim_conn_t *conn,
62 int changetype, char *denylist)
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
80 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
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
123 aim_tx_enqueue(sess, &newpacket);
124
125 return (sess->snac_nextid); /* dont increment */
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 */
141u_long aim_bos_setbuddylist(struct aim_session_t *sess,
142 struct aim_conn_t *conn,
143 char *buddy_list)
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
190 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
191 newpacket.commandlen = packet_login_phase3c_hi_b_len - 6;
192 newpacket.lock = 1;
193
194 newpacket.data = (char *) malloc(newpacket.commandlen);
195
196 aim_putsnac(newpacket.data, 0x0003, 0x0004, 0x0000, sess->snac_nextid);
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
216 aim_tx_enqueue(sess, &newpacket);
217
218 return (sess->snac_nextid++);
219}
220
221/*
222 * aim_bos_setprofile(profile)
223 *
224 * Gives BOS your profile.
225 *
226 */
227u_long aim_bos_setprofile(struct aim_session_t *sess,
228 struct aim_conn_t *conn,
229 char *profile)
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
250 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
251
252 newpacket.commandlen = packet_profile_len;
253 newpacket.data = (char *) malloc(packet_profile_len);
254
255 i = 0;
256
257 i += aim_putsnac(newpacket.data, 0x0002, 0x004, 0x0000, sess->snac_nextid);
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
278 aim_tx_enqueue(sess, &newpacket);
279
280 return (sess->snac_nextid++);
281}
282
283/*
284 * aim_bos_setgroupperm(mask)
285 *
286 * Set group permisson mask. Normally 0x1f.
287 *
288 */
289u_long aim_bos_setgroupperm(struct aim_session_t *sess,
290 struct aim_conn_t *conn,
291 u_long mask)
292{
293 return aim_genericreq_l(sess, conn, 0x0009, 0x0004, &mask);
294}
295
296/*
297 * aim_bos_clientready()
298 *
299 * Send Client Ready.
300 *
301 * TODO: Dynamisize.
302 *
303 */
304u_long aim_bos_clientready(struct aim_session_t *sess,
305 struct aim_conn_t *conn)
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
330 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
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 */
337 aim_putsnac(newpacket.data, 0x0001, 0x0002, 0x0000, sess->snac_nextid);
338
339 aim_tx_enqueue(sess, &newpacket);
340
341 return (sess->snac_nextid++);
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 */
352u_long aim_bos_reqrate(struct aim_session_t *sess,
353 struct aim_conn_t *conn)
354{
355 return aim_genericreq_n(sess, conn, 0x0001, 0x0006);
356}
357
358/*
359 * send_login_phase3b(int socket)
360 *
361 * Rate Information Response Acknowledge.
362 *
363 */
364u_long aim_bos_ackrateresp(struct aim_session_t *sess,
365 struct aim_conn_t *conn)
366{
367 struct command_tx_struct newpacket;
368
369 newpacket.lock = 1;
370 if (conn)
371 newpacket.conn = conn;
372 else
373 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
374 newpacket.type = 0x02;
375 newpacket.commandlen = 18;
376
377 newpacket.data = (char *) malloc(newpacket.commandlen);
378 aim_putsnac(newpacket.data, 0x0001, 0x0008, 0x0000, sess->snac_nextid);
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
389 aim_tx_enqueue(sess, &newpacket);
390
391 return (sess->snac_nextid++);
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 */
403u_long aim_bos_setprivacyflags(struct aim_session_t *sess,
404 struct aim_conn_t *conn,
405 u_long flags)
406{
407 return aim_genericreq_l(sess, conn, 0x0001, 0x0014, &flags);
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 */
417u_long aim_bos_reqpersonalinfo(struct aim_session_t *sess,
418 struct aim_conn_t *conn)
419{
420 struct command_tx_struct newpacket;
421
422 newpacket.lock = 1;
423 if (conn)
424 newpacket.conn = conn;
425 else
426 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
427 newpacket.type = 0x02;
428 newpacket.commandlen = 12;
429
430 newpacket.data = (char *) malloc(newpacket.commandlen);
431 aim_putsnac(newpacket.data, 0x000a, 0x0001, 0x000e /* huh? */, sess->snac_nextid);
432
433 newpacket.data[10] = 0x0d;
434 newpacket.data[11] = 0xda;
435
436 aim_tx_enqueue(sess, &newpacket);
437
438 return (sess->snac_nextid++);
439}
440
441/*
442 * aim_bos_reqservice(serviceid)
443 *
444 * Service request.
445 *
446 */
447u_long aim_bos_reqservice(struct aim_session_t *sess,
448 struct aim_conn_t *conn,
449 u_short serviceid)
450{
451 return aim_genericreq_s(sess, conn, 0x0001, 0x0004, &serviceid);
452}
453
454/*
455 * aim_bos_reqrights()
456 *
457 * Request BOS rights.
458 *
459 */
460u_long aim_bos_reqrights(struct aim_session_t *sess,
461 struct aim_conn_t *conn)
462{
463 return aim_genericreq_n(sess, conn, 0x0009, 0x0002);
464}
465
466/*
467 * aim_bos_reqbuddyrights()
468 *
469 * Request Buddy List rights.
470 *
471 */
472u_long aim_bos_reqbuddyrights(struct aim_session_t *sess,
473 struct aim_conn_t *conn)
474{
475 return aim_genericreq_n(sess, conn, 0x0003, 0x0002);
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 */
490u_long aim_genericreq_n(struct aim_session_t *sess,
491 struct aim_conn_t *conn,
492 u_short family, u_short subtype)
493{
494 struct command_tx_struct newpacket;
495
496 newpacket.lock = 1;
497
498 if (conn)
499 newpacket.conn = conn;
500 else
501 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
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
509 aim_putsnac(newpacket.data, family, subtype, 0x0000, sess->snac_nextid);
510
511 aim_tx_enqueue(sess, &newpacket);
512 return (sess->snac_nextid++);
513}
514
515/*
516 *
517 *
518 */
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)
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)
528 return aim_genericreq_n(sess, conn, family, subtype);
529
530 newpacket.lock = 1;
531
532 if (conn)
533 newpacket.conn = conn;
534 else
535 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
536
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
544 aim_putsnac(newpacket.data, family, subtype, 0x0000, sess->snac_nextid);
545
546 /* copy in data */
547 newlong = htonl(*longdata);
548 memcpy(&(newpacket.data[10]), &newlong, sizeof(u_long));
549
550 aim_tx_enqueue(sess, &newpacket);
551 return (sess->snac_nextid++);
552}
553
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)
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)
563 return aim_genericreq_n(sess, conn, family, subtype);
564
565 newpacket.lock = 1;
566
567 if (conn)
568 newpacket.conn = conn;
569 else
570 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
571
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
579 aim_putsnac(newpacket.data, family, subtype, 0x0000, sess->snac_nextid);
580
581 /* copy in data */
582 newshort = htons(*shortdata);
583 memcpy(&(newpacket.data[10]), &newshort, sizeof(u_short));
584
585 aim_tx_enqueue(sess, &newpacket);
586 return (sess->snac_nextid++);
587}
588
589/*
590 * aim_bos_reqlocaterights()
591 *
592 * Request Location services rights.
593 *
594 */
595u_long aim_bos_reqlocaterights(struct aim_session_t *sess,
596 struct aim_conn_t *conn)
597{
598 return aim_genericreq_n(sess, conn, 0x0002, 0x0002);
599}
600
601/*
602 * aim_bos_reqicbmparaminfo()
603 *
604 * Request ICBM parameter information.
605 *
606 */
607u_long aim_bos_reqicbmparaminfo(struct aim_session_t *sess,
608 struct aim_conn_t *conn)
609{
610 return aim_genericreq_n(sess, conn, 0x0004, 0x0004);
611}
This page took 0.038846 seconds and 5 git commands to generate.