]> andersk Git - libfaim.git/blob - aim_misc.c
Initial revision
[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 "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_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  */
58 u_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  */
137 u_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  */
221 u_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  */
280 u_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  */
293 u_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  */
340 u_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  */
351 u_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  */
389 u_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  */
401 u_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  */
430 u_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  */
441 u_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  */
452 u_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  */
469 u_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  */
496 u_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
528 u_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  */
566 u_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  */
577 u_long aim_bos_reqicbmparaminfo(struct aim_conn_t *conn)
578 {
579   return aim_genericreq_n(conn, 0x0004, 0x0004);
580 }
This page took 0.078251 seconds and 5 git commands to generate.