]> andersk Git - libfaim.git/blob - aim_misc.c
aimdump bugfix.
[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, 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  */
352 u_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  */
364 u_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  */
403 u_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  */
417 u_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  */
447 u_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  */
460 u_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  */
472 u_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  */
490 u_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  */
519 u_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
554 u_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  */
595 u_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  */
607 u_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 1.002815 seconds and 5 git commands to generate.