]> andersk Git - libfaim.git/blob - aim_misc.c
Lots of minor cleanups. Adds new (disabled) SNAC-based login.
[libfaim.git] / aim_misc.c
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  */
24 u_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  */
60 u_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  */
141 u_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  */
227 u_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  */
289 u_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  */
304 u_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,   
313      0x00, 0x03, 
314      0x00, 0x04, 
315      0x06, 0x86,  
316      0x00, 0x02, 
317      0x00, 0x01,  
318      0x00, 0x04, 
319      0x00, 0x01, 
320  
321      0x00, 0x03, 
322      0x00, 0x01,  
323      0x00, 0x04, 
324      0x00, 0x01, 
325      0x00, 0x04, 
326      0x00, 0x01, 
327      0x00, 0x04,
328      0x00, 0x01,
329  
330      0x00, 0x06, 
331      0x00, 0x01, 
332      0x00, 0x04,  
333      0x00, 0x01, 
334      0x00, 0x08, 
335      0x00, 0x01, 
336      0x00, 0x04,
337      0x00, 0x01,
338  
339      0x00, 0x09, 
340      0x00, 0x01, 
341      0x00, 0x04,
342      0x00, 0x01, 
343      0x00, 0x0a, 
344      0x00, 0x01, 
345      0x00, 0x04,
346      0x00, 0x01,
347  
348      0x00, 0x0b,
349      0x00, 0x01, 
350      0x00, 0x04,
351      0x00, 0x01
352   };
353   int command_2_len = 0x52;
354   struct command_tx_struct newpacket;
355   
356   newpacket.lock = 1;
357   if (conn)
358     newpacket.conn = conn;
359   else
360     newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
361   newpacket.type = 0x02;
362   newpacket.commandlen = command_2_len;
363   newpacket.data = (char *) malloc (newpacket.commandlen);
364   memcpy(newpacket.data, command_2, newpacket.commandlen);
365   
366   /* This write over the dynamic parts of the byte block */
367   aim_putsnac(newpacket.data, 0x0001, 0x0002, 0x0000, sess->snac_nextid);
368
369   aim_tx_enqueue(sess, &newpacket);
370
371   return (sess->snac_nextid++);
372 }
373
374 /* 
375  *  send_login_phase3(int socket)   
376  *
377  *  Request Rate Information.
378  * 
379  *  TODO: Move to aim_conn.
380  *  TODO: Move to SNAC interface.
381  */
382 u_long aim_bos_reqrate(struct aim_session_t *sess,
383                        struct aim_conn_t *conn)
384 {
385   return aim_genericreq_n(sess, conn, 0x0001, 0x0006);
386 }
387
388 /* 
389  *  send_login_phase3b(int socket)   
390  *
391  *  Rate Information Response Acknowledge.
392  *
393  */
394 u_long aim_bos_ackrateresp(struct aim_session_t *sess,
395                            struct aim_conn_t *conn)
396 {
397   struct command_tx_struct newpacket;
398
399   newpacket.lock = 1;
400   if (conn)
401     newpacket.conn = conn;
402   else
403     newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
404   newpacket.type = 0x02;
405   newpacket.commandlen = 18;
406
407   newpacket.data = (char *) malloc(newpacket.commandlen);
408   aim_putsnac(newpacket.data, 0x0001, 0x0008, 0x0000, sess->snac_nextid);
409
410   newpacket.data[10] = 0x00;
411   newpacket.data[11] = 0x01;
412   newpacket.data[12] = 0x00;
413   newpacket.data[13] = 0x02;
414   newpacket.data[14] = 0x00;
415   newpacket.data[15] = 0x03;
416   newpacket.data[16] = 0x00;
417   newpacket.data[17] = 0x04;
418
419   aim_tx_enqueue(sess, &newpacket);
420
421   return (sess->snac_nextid++);
422 }
423
424 /* 
425  * aim_bos_setprivacyflags()
426  *
427  * Sets privacy flags. Normally 0x03.
428  *
429  *  Bit 1:  Allows other AIM users to see how long you've been idle.
430  *
431  *
432  */
433 u_long aim_bos_setprivacyflags(struct aim_session_t *sess,
434                                struct aim_conn_t *conn, 
435                                u_long flags)
436 {
437   return aim_genericreq_l(sess, conn, 0x0001, 0x0014, &flags);
438 }
439
440 /*
441  * aim_bos_reqpersonalinfo()
442  *
443  * Requests the current user's information. Can't go generic on this one
444  * because aparently it uses SNAC flags.
445  *
446  */
447 u_long aim_bos_reqpersonalinfo(struct aim_session_t *sess,
448                                struct aim_conn_t *conn)
449 {
450   struct command_tx_struct newpacket;
451   
452   newpacket.lock = 1;
453   if (conn)
454     newpacket.conn = conn;
455   else
456     newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
457   newpacket.type = 0x02;
458   newpacket.commandlen = 12;
459
460   newpacket.data = (char *) malloc(newpacket.commandlen);
461   aim_putsnac(newpacket.data, 0x000a, 0x0001, 0x000e /* huh? */, sess->snac_nextid);
462   
463   newpacket.data[10] = 0x0d;
464   newpacket.data[11] = 0xda;
465
466   newpacket.lock = 0;
467   aim_tx_enqueue(sess, &newpacket);
468
469   return (sess->snac_nextid++);
470 }
471
472 u_long aim_setversions(struct aim_session_t *sess,
473                                struct aim_conn_t *conn)
474 {
475   struct command_tx_struct newpacket;
476   int i,j;
477
478   newpacket.lock = 1;
479   if (conn)
480     newpacket.conn = conn;
481   else
482     newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
483   newpacket.type = 0x02;
484   newpacket.commandlen = 10 + (4*13);
485
486   newpacket.data = (char *) malloc(newpacket.commandlen);
487   i = aim_putsnac(newpacket.data, 0x0001, 0x0017, 0x0000, sess->snac_nextid);
488
489   i += aimutil_put16(newpacket.data+i, 0x0001);
490   i += aimutil_put16(newpacket.data+i, 0x0003);
491   i += aimutil_put16(newpacket.data+i, 0x0002);
492   i += aimutil_put16(newpacket.data+i, 0x0001);
493   i += aimutil_put16(newpacket.data+i, 0x0003);
494   i += aimutil_put16(newpacket.data+i, 0x0001);
495   i += aimutil_put16(newpacket.data+i, 0x0004);
496   i += aimutil_put16(newpacket.data+i, 0x0001);
497   i += aimutil_put16(newpacket.data+i, 0x0006);
498   i += aimutil_put16(newpacket.data+i, 0x0001);
499   i += aimutil_put16(newpacket.data+i, 0x0008);
500   i += aimutil_put16(newpacket.data+i, 0x0001);
501   i += aimutil_put16(newpacket.data+i, 0x0009);
502   i += aimutil_put16(newpacket.data+i, 0x0001);
503   i += aimutil_put16(newpacket.data+i, 0x000a);
504   i += aimutil_put16(newpacket.data+i, 0x0001);
505   i += aimutil_put16(newpacket.data+i, 0x000b);
506   i += aimutil_put16(newpacket.data+i, 0x0002);
507   i += aimutil_put16(newpacket.data+i, 0x000c);
508   i += aimutil_put16(newpacket.data+i, 0x0001);
509   i += aimutil_put16(newpacket.data+i, 0x0015);
510   i += aimutil_put16(newpacket.data+i, 0x0003);
511   i += aimutil_put16(newpacket.data+i, 0x000f);
512   i += aimutil_put16(newpacket.data+i, 0x0001);
513   i += aimutil_put16(newpacket.data+i, 0x0005);
514   i += aimutil_put16(newpacket.data+i, 0x0001);
515
516 #if 0
517   for (j = 0; j < 0x10; j++)
518 A
519     {
520       i += aimutil_put16(newpacket.data+i, j); /* family */
521       i += aimutil_put16(newpacket.data+i, 0x0003); /* version */
522     }
523 #endif
524   newpacket.lock = 0;
525   aim_tx_enqueue(sess, &newpacket);
526
527   return (sess->snac_nextid++);
528 }
529
530
531 /*
532  * aim_bos_reqservice(serviceid)
533  *
534  * Service request. 
535  *
536  */
537 u_long aim_bos_reqservice(struct aim_session_t *sess,
538                           struct aim_conn_t *conn, 
539                           u_short serviceid)
540 {
541   return aim_genericreq_s(sess, conn, 0x0001, 0x0004, &serviceid);
542 }
543
544 /*
545  * aim_bos_reqrights()
546  *
547  * Request BOS rights.
548  *
549  */
550 u_long aim_bos_reqrights(struct aim_session_t *sess,
551                          struct aim_conn_t *conn)
552 {
553   return aim_genericreq_n(sess, conn, 0x0009, 0x0002);
554 }
555
556 /*
557  * aim_bos_reqbuddyrights()
558  *
559  * Request Buddy List rights.
560  *
561  */
562 u_long aim_bos_reqbuddyrights(struct aim_session_t *sess,
563                               struct aim_conn_t *conn)
564 {
565   return aim_genericreq_n(sess, conn, 0x0003, 0x0002);
566 }
567
568 /*
569  * Generic routine for sending commands.
570  *
571  *
572  * I know I can do this in a smarter way...but I'm not thinking straight
573  * right now...
574  *
575  * I had one big function that handled all three cases, but then it broke
576  * and I split it up into three.  But then I fixed it.  I just never went
577  * back to the single.  I don't see any advantage to doing it either way.
578  *
579  */
580 u_long aim_genericreq_n(struct aim_session_t *sess,
581                         struct aim_conn_t *conn, 
582                         u_short family, u_short subtype)
583 {
584   struct command_tx_struct newpacket;
585
586   newpacket.lock = 1;
587
588   if (conn)
589     newpacket.conn = conn;
590   else
591     newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
592   newpacket.type = 0x02;
593
594   newpacket.commandlen = 10;
595
596   newpacket.data = (char *) malloc(newpacket.commandlen);
597   memset(newpacket.data, 0x00, newpacket.commandlen);
598
599   aim_putsnac(newpacket.data, family, subtype, 0x0000, sess->snac_nextid);
600  
601   aim_tx_enqueue(sess, &newpacket);
602   return (sess->snac_nextid++);
603 }
604
605 /*
606  *
607  *
608  */
609 u_long aim_genericreq_l(struct aim_session_t *sess,
610                         struct aim_conn_t *conn, 
611                         u_short family, u_short subtype, u_long *longdata)
612 {
613   struct command_tx_struct newpacket;
614   u_long newlong;
615
616   /* If we don't have data, there's no reason to use this function */
617   if (!longdata)
618     return aim_genericreq_n(sess, conn, family, subtype);
619
620   newpacket.lock = 1;
621
622   if (conn)
623     newpacket.conn = conn;
624   else
625     newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
626
627   newpacket.type = 0x02;
628
629   newpacket.commandlen = 10+sizeof(u_long);
630
631   newpacket.data = (char *) malloc(newpacket.commandlen);
632   memset(newpacket.data, 0x00, newpacket.commandlen);
633
634   aim_putsnac(newpacket.data, family, subtype, 0x0000, sess->snac_nextid);
635
636   /* copy in data */
637   newlong = htonl(*longdata);
638   memcpy(&(newpacket.data[10]), &newlong, sizeof(u_long));
639
640   aim_tx_enqueue(sess, &newpacket);
641   return (sess->snac_nextid++);
642 }
643
644 u_long aim_genericreq_s(struct aim_session_t *sess,
645                         struct aim_conn_t *conn, 
646                         u_short family, u_short subtype, u_short *shortdata)
647 {
648   struct command_tx_struct newpacket;
649   u_short newshort;
650
651   /* If we don't have data, there's no reason to use this function */
652   if (!shortdata)
653     return aim_genericreq_n(sess, conn, family, subtype);
654
655   newpacket.lock = 1;
656
657   if (conn)
658     newpacket.conn = conn;
659   else
660     newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
661
662   newpacket.type = 0x02;
663
664   newpacket.commandlen = 10+sizeof(u_short);
665
666   newpacket.data = (char *) malloc(newpacket.commandlen);
667   memset(newpacket.data, 0x00, newpacket.commandlen);
668
669   aim_putsnac(newpacket.data, family, subtype, 0x0000, sess->snac_nextid);
670
671   /* copy in data */
672   newshort = htons(*shortdata);
673   memcpy(&(newpacket.data[10]), &newshort, sizeof(u_short));
674
675   aim_tx_enqueue(sess, &newpacket);
676   return (sess->snac_nextid++);
677 }
678
679 /*
680  * aim_bos_reqlocaterights()
681  *
682  * Request Location services rights.
683  *
684  */
685 u_long aim_bos_reqlocaterights(struct aim_session_t *sess,
686                                struct aim_conn_t *conn)
687 {
688   return aim_genericreq_n(sess, conn, 0x0002, 0x0002);
689 }
690
691 /*
692  * aim_bos_reqicbmparaminfo()
693  *
694  * Request ICBM parameter information.
695  *
696  */
697 u_long aim_bos_reqicbmparaminfo(struct aim_session_t *sess,
698                                 struct aim_conn_t *conn)
699 {
700   return aim_genericreq_n(sess, conn, 0x0004, 0x0004);
701 }
This page took 0.128844 seconds and 5 git commands to generate.