]> andersk Git - libfaim.git/blob - aim_misc.c
- Sat Jun 24 02:14:07 UTC 2000
[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   int packlen = 0;
66   u_short subtype;
67
68   char *localcpy = NULL;
69   char *tmpptr = NULL;
70   int i,j;
71   int listcount;
72
73   if (!denylist)
74     return 0;
75
76   localcpy = (char *) malloc(strlen(denylist)+1);
77   memcpy(localcpy, denylist, strlen(denylist)+1);
78   
79   listcount = aimutil_itemcnt(localcpy, '&');
80   packlen = aimutil_tokslen(localcpy, 99, '&') + listcount + 9;
81
82   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, packlen)))
83     return -1;
84
85   newpacket->lock = 1;
86
87   switch(changetype)
88     {
89     case AIM_VISIBILITYCHANGE_PERMITADD:    subtype = 0x05; break;
90     case AIM_VISIBILITYCHANGE_PERMITREMOVE: subtype = 0x06; break;
91     case AIM_VISIBILITYCHANGE_DENYADD:      subtype = 0x07; break;
92     case AIM_VISIBILITYCHANGE_DENYREMOVE:   subtype = 0x08; break;
93     default:
94       free(newpacket->data);
95       free(newpacket);
96       return 0;
97     }
98
99   /* We actually DO NOT send a SNAC ID with this one! */
100   aim_putsnac(newpacket->data, 0x0009, subtype, 0x00, 0);
101  
102   j = 10;  /* the next byte */
103   
104   for (i=0; (i < (listcount - 1)) && (i < 99); i++)
105     {
106       tmpptr = aimutil_itemidx(localcpy, i, '&');
107
108       newpacket->data[j] = strlen(tmpptr);
109       memcpy(&(newpacket->data[j+1]), tmpptr, strlen(tmpptr));
110       j += strlen(tmpptr)+1;
111       free(tmpptr);
112     }
113   free(localcpy);
114
115   newpacket->lock = 0;
116
117   aim_tx_enqueue(sess, newpacket);
118
119   return (sess->snac_nextid); /* dont increment */
120
121 }
122
123
124
125 /*
126  * aim_bos_setbuddylist(buddylist)
127  *
128  * This just builds the "set buddy list" command then queues it.
129  *
130  * buddy_list = "Screen Name One&ScreenNameTwo&";
131  *
132  * TODO: Clean this up.  
133  *
134  * XXX: I can't stress the TODO enough.
135  *
136  */
137 u_long aim_bos_setbuddylist(struct aim_session_t *sess,
138                             struct aim_conn_t *conn, 
139                             char *buddy_list)
140 {
141   int i, j;
142
143   struct command_tx_struct *newpacket;
144
145   int packet_login_phase3c_hi_b_len = 0;
146
147   char *localcpy = NULL;
148   char *tmpptr = NULL;
149
150   packet_login_phase3c_hi_b_len = 16; /* 16b for FLAP and SNAC headers */
151
152   /* bail out if we can't make the packet */
153   if (!buddy_list) {
154     return -1;
155   }
156
157   localcpy = (char *) malloc(strlen(buddy_list)+1);
158   memcpy(localcpy, buddy_list, strlen(buddy_list)+1);
159
160   i = 0;
161   tmpptr = strtok(localcpy, "&");
162   while ((tmpptr != NULL) && (i < 100))
163     {
164 #if debug > 0
165       printf("---adding %s (%d)\n", tmpptr, strlen(tmpptr));
166 #endif
167       packet_login_phase3c_hi_b_len += strlen(tmpptr)+1;
168       i++;
169       tmpptr = strtok(NULL, "&");
170     }
171 #if debug > 0
172   printf("*** send buddy list len: %d (%x)\n", packet_login_phase3c_hi_b_len, packet_login_phase3c_hi_b_len);
173 #endif
174   free(localcpy);
175
176   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, packet_login_phase3c_hi_b_len - 6)))
177     return -1;
178
179   newpacket->lock = 1;
180   
181   aim_putsnac(newpacket->data, 0x0003, 0x0004, 0x0000, sess->snac_nextid);
182
183   j = 10;  /* the next byte */
184
185   i = 0;
186   tmpptr = strtok(buddy_list, "&");
187   while ((tmpptr != NULL) & (i < 100))
188     {
189 #if debug > 0
190       printf("---adding %s (%d)\n", tmpptr, strlen(tmpptr));
191 #endif
192       newpacket->data[j] = strlen(tmpptr);
193       memcpy(&(newpacket->data[j+1]), tmpptr, strlen(tmpptr));
194       j += strlen(tmpptr)+1;
195       i++;
196       tmpptr = strtok(NULL, "&");
197     }
198
199   newpacket->lock = 0;
200
201   aim_tx_enqueue(sess, newpacket);
202
203   return (sess->snac_nextid++);
204 }
205
206 /* 
207  * aim_bos_setprofile(profile)
208  *
209  * Gives BOS your profile.
210  *
211  * 
212  */
213 u_long aim_bos_setprofile(struct aim_session_t *sess,
214                           struct aim_conn_t *conn, 
215                           char *profile,
216                           char *awaymsg,
217                           unsigned int caps)
218 {
219   struct command_tx_struct *newpacket;
220   int i = 0, tmp, caplen;
221
222   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 1152+strlen(profile)+1+(awaymsg?strlen(awaymsg):0))))
223     return -1;
224
225   i += aim_putsnac(newpacket->data, 0x0002, 0x004, 0x0000, sess->snac_nextid);
226   i += aim_puttlv_str(newpacket->data+i, 0x0001, strlen("text/x-aolrtf; charset=\"us-ascii\""), "text/x-aolrtf; charset=\"us-ascii\"");
227   i += aim_puttlv_str(newpacket->data+i, 0x0002, strlen(profile), profile);
228   /* why do we send this twice?  */
229   i += aim_puttlv_str(newpacket->data+i, 0x0003, strlen("text/x-aolrtf; charset=\"us-ascii\""), "text/x-aolrtf; charset=\"us-ascii\"");
230   
231   /* Away message -- we send this no matter what, even if its blank */
232   if (awaymsg)
233     i += aim_puttlv_str(newpacket->data+i, 0x0004, strlen(awaymsg), awaymsg);
234   else
235     i += aim_puttlv_str(newpacket->data+i, 0x0004, 0x0000, NULL);
236
237   /* Capability information. */
238  
239   tmp = (i += aimutil_put16(newpacket->data+i, 0x0005));
240   i += aimutil_put16(newpacket->data+i, 0x0000); /* rewritten later */
241   i += (caplen = aim_putcap(newpacket->data+i, 512, caps));
242   aimutil_put16(newpacket->data+tmp, caplen); /* rewrite TLV size */
243
244   newpacket->commandlen = i;
245   aim_tx_enqueue(sess, newpacket);
246   
247   return (sess->snac_nextid++);
248 }
249
250 /* 
251  * aim_bos_setgroupperm(mask)
252  * 
253  * Set group permisson mask.  Normally 0x1f.
254  *
255  */
256 u_long aim_bos_setgroupperm(struct aim_session_t *sess,
257                             struct aim_conn_t *conn, 
258                             u_long mask)
259 {
260   return aim_genericreq_l(sess, conn, 0x0009, 0x0004, &mask);
261 }
262
263 /*
264  * aim_bos_clientready()
265  * 
266  * Send Client Ready.  
267  *
268  * TODO: Dynamisize.
269  *
270  */
271 u_long aim_bos_clientready(struct aim_session_t *sess,
272                            struct aim_conn_t *conn)
273 {
274   u_char command_2[] = {
275      /* placeholders for dynamic data */
276      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
277      0xff, 0xff, 
278      /* real data */
279      0x00, 0x01,   
280      0x00, 0x03, 
281      0x00, 0x04, 
282      0x06, 0x86,  
283      0x00, 0x02, 
284      0x00, 0x01,  
285      0x00, 0x04, 
286      0x00, 0x01, 
287  
288      0x00, 0x03, 
289      0x00, 0x01,  
290      0x00, 0x04, 
291      0x00, 0x01, 
292      0x00, 0x04, 
293      0x00, 0x01, 
294      0x00, 0x04,
295      0x00, 0x01,
296  
297      0x00, 0x06, 
298      0x00, 0x01, 
299      0x00, 0x04,  
300      0x00, 0x01, 
301      0x00, 0x08, 
302      0x00, 0x01, 
303      0x00, 0x04,
304      0x00, 0x01,
305  
306      0x00, 0x09, 
307      0x00, 0x01, 
308      0x00, 0x04,
309      0x00, 0x01, 
310      0x00, 0x0a, 
311      0x00, 0x01, 
312      0x00, 0x04,
313      0x00, 0x01,
314  
315      0x00, 0x0b,
316      0x00, 0x01, 
317      0x00, 0x04,
318      0x00, 0x01
319   };
320   int command_2_len = 0x52;
321   struct command_tx_struct *newpacket;
322   
323   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, command_2_len)))
324     return -1;
325
326   newpacket->lock = 1;
327
328   memcpy(newpacket->data, command_2, command_2_len);
329   
330   /* This write over the dynamic parts of the byte block */
331   aim_putsnac(newpacket->data, 0x0001, 0x0002, 0x0000, sess->snac_nextid);
332
333   aim_tx_enqueue(sess, newpacket);
334
335   return (sess->snac_nextid++);
336 }
337
338 /* 
339  *  send_login_phase3(int socket)   
340  *
341  *  Request Rate Information.
342  * 
343  *  TODO: Move to aim_conn.
344  *  TODO: Move to SNAC interface.
345  */
346 u_long aim_bos_reqrate(struct aim_session_t *sess,
347                        struct aim_conn_t *conn)
348 {
349   return aim_genericreq_n(sess, conn, 0x0001, 0x0006);
350 }
351
352 /* 
353  *  send_login_phase3b(int socket)   
354  *
355  *  Rate Information Response Acknowledge.
356  *
357  */
358 u_long aim_bos_ackrateresp(struct aim_session_t *sess,
359                            struct aim_conn_t *conn)
360 {
361   struct command_tx_struct *newpacket;
362   int packlen = 18, i=0;
363
364   if (conn->type != AIM_CONN_TYPE_BOS)
365     packlen += 2;
366
367   if(!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, packlen)));
368   
369   newpacket->lock = 1;
370
371   i = aim_putsnac(newpacket->data, 0x0001, 0x0008, 0x0000, sess->snac_nextid);
372   i += aimutil_put16(newpacket->data+i, 0x0001); 
373   i += aimutil_put16(newpacket->data+i, 0x0002);
374   i += aimutil_put16(newpacket->data+i, 0x0003);
375   i += aimutil_put16(newpacket->data+i, 0x0004);
376   
377   if (conn->type != AIM_CONN_TYPE_BOS) {
378     i += aimutil_put16(newpacket->data+i, 0x0005);
379   }
380
381   aim_tx_enqueue(sess, newpacket);
382
383   return (sess->snac_nextid++);
384 }
385
386 /* 
387  * aim_bos_setprivacyflags()
388  *
389  * Sets privacy flags. Normally 0x03.
390  *
391  *  Bit 1:  Allows other AIM users to see how long you've been idle.
392  *
393  *
394  */
395 u_long aim_bos_setprivacyflags(struct aim_session_t *sess,
396                                struct aim_conn_t *conn, 
397                                u_long flags)
398 {
399   return aim_genericreq_l(sess, conn, 0x0001, 0x0014, &flags);
400 }
401
402 /*
403  * aim_bos_reqpersonalinfo()
404  *
405  * Requests the current user's information. Can't go generic on this one
406  * because aparently it uses SNAC flags.
407  *
408  */
409 u_long aim_bos_reqpersonalinfo(struct aim_session_t *sess,
410                                struct aim_conn_t *conn)
411 {
412   struct command_tx_struct *newpacket;
413   
414   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 12)))
415     return -1;
416
417   newpacket->lock = 1;
418
419   aim_putsnac(newpacket->data, 0x000a, 0x0001, 0x000e /* huh? */, sess->snac_nextid);
420   
421   newpacket->data[10] = 0x0d;
422   newpacket->data[11] = 0xda;
423
424   newpacket->lock = 0;
425   aim_tx_enqueue(sess, newpacket);
426
427   return (sess->snac_nextid++);
428 }
429
430 u_long aim_setversions(struct aim_session_t *sess,
431                                struct aim_conn_t *conn)
432 {
433   struct command_tx_struct *newpacket;
434   int i;
435
436   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10 + (4*11))))
437     return -1;
438
439   newpacket->lock = 1;
440
441   i = aim_putsnac(newpacket->data, 0x0001, 0x0017, 0x0000, sess->snac_nextid);
442
443   i += aimutil_put16(newpacket->data+i, 0x0001);
444   i += aimutil_put16(newpacket->data+i, 0x0003);
445
446   i += aimutil_put16(newpacket->data+i, 0x0002);
447   i += aimutil_put16(newpacket->data+i, 0x0001);
448
449   i += aimutil_put16(newpacket->data+i, 0x0003);
450   i += aimutil_put16(newpacket->data+i, 0x0001);
451
452   i += aimutil_put16(newpacket->data+i, 0x0004);
453   i += aimutil_put16(newpacket->data+i, 0x0001);
454
455   i += aimutil_put16(newpacket->data+i, 0x0006);
456   i += aimutil_put16(newpacket->data+i, 0x0001);
457
458   i += aimutil_put16(newpacket->data+i, 0x0008);
459   i += aimutil_put16(newpacket->data+i, 0x0001);
460
461   i += aimutil_put16(newpacket->data+i, 0x0009);
462   i += aimutil_put16(newpacket->data+i, 0x0001);
463
464   i += aimutil_put16(newpacket->data+i, 0x000a);
465   i += aimutil_put16(newpacket->data+i, 0x0001);
466
467   i += aimutil_put16(newpacket->data+i, 0x000b);
468   i += aimutil_put16(newpacket->data+i, 0x0002);
469
470   i += aimutil_put16(newpacket->data+i, 0x000c);
471   i += aimutil_put16(newpacket->data+i, 0x0001);
472
473   i += aimutil_put16(newpacket->data+i, 0x0015);
474   i += aimutil_put16(newpacket->data+i, 0x0001);
475
476 #if 0
477   for (j = 0; j < 0x10; j++) {
478     i += aimutil_put16(newpacket->data+i, j); /* family */
479     i += aimutil_put16(newpacket->data+i, 0x0003); /* version */
480   }
481 #endif
482   newpacket->lock = 0;
483   aim_tx_enqueue(sess, newpacket);
484
485   return (sess->snac_nextid++);
486 }
487
488
489 /*
490  * aim_bos_reqservice(serviceid)
491  *
492  * Service request. 
493  *
494  */
495 u_long aim_bos_reqservice(struct aim_session_t *sess,
496                           struct aim_conn_t *conn, 
497                           u_short serviceid)
498 {
499   return aim_genericreq_s(sess, conn, 0x0001, 0x0004, &serviceid);
500 }
501
502 /*
503  * aim_bos_nop()
504  *
505  * No-op.  WinAIM sends these every 4min or so to keep
506  * the connection alive.  With the recent changes
507  * in the OSCAR servers, it looks like we must do the
508  * same or be disconnected with a mysterious 'you logged
509  * on from another client' message.
510  *
511  */
512 u_long aim_bos_nop(struct aim_session_t *sess,
513                    struct aim_conn_t *conn)
514 {
515   return aim_genericreq_n(sess, conn, 0x0001, 0x0016);
516 }
517
518 /*
519  * aim_bos_reqrights()
520  *
521  * Request BOS rights.
522  *
523  */
524 u_long aim_bos_reqrights(struct aim_session_t *sess,
525                          struct aim_conn_t *conn)
526 {
527   return aim_genericreq_n(sess, conn, 0x0009, 0x0002);
528 }
529
530 /*
531  * aim_bos_reqbuddyrights()
532  *
533  * Request Buddy List rights.
534  *
535  */
536 u_long aim_bos_reqbuddyrights(struct aim_session_t *sess,
537                               struct aim_conn_t *conn)
538 {
539   return aim_genericreq_n(sess, conn, 0x0003, 0x0002);
540 }
541
542 /*
543  * Generic routine for sending commands.
544  *
545  *
546  * I know I can do this in a smarter way...but I'm not thinking straight
547  * right now...
548  *
549  * I had one big function that handled all three cases, but then it broke
550  * and I split it up into three.  But then I fixed it.  I just never went
551  * back to the single.  I don't see any advantage to doing it either way.
552  *
553  */
554 u_long aim_genericreq_n(struct aim_session_t *sess,
555                         struct aim_conn_t *conn, 
556                         u_short family, u_short subtype)
557 {
558   struct command_tx_struct *newpacket;
559
560   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10)))
561     return 0;
562
563   newpacket->lock = 1;
564
565   aim_putsnac(newpacket->data, family, subtype, 0x0000, sess->snac_nextid);
566  
567   aim_tx_enqueue(sess, newpacket);
568   return (sess->snac_nextid++);
569 }
570
571 /*
572  *
573  *
574  */
575 u_long aim_genericreq_l(struct aim_session_t *sess,
576                         struct aim_conn_t *conn, 
577                         u_short family, u_short subtype, u_long *longdata)
578 {
579   struct command_tx_struct *newpacket;
580   u_long newlong;
581
582   /* If we don't have data, there's no reason to use this function */
583   if (!longdata)
584     return aim_genericreq_n(sess, conn, family, subtype);
585
586   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10+sizeof(u_long))))
587     return -1;
588
589   newpacket->lock = 1;
590
591   aim_putsnac(newpacket->data, family, subtype, 0x0000, sess->snac_nextid);
592
593   /* copy in data */
594   newlong = htonl(*longdata);
595   memcpy(&(newpacket->data[10]), &newlong, sizeof(u_long));
596
597   aim_tx_enqueue(sess, newpacket);
598   return (sess->snac_nextid++);
599 }
600
601 u_long aim_genericreq_s(struct aim_session_t *sess,
602                         struct aim_conn_t *conn, 
603                         u_short family, u_short subtype, u_short *shortdata)
604 {
605   struct command_tx_struct *newpacket;
606   u_short newshort;
607
608   /* If we don't have data, there's no reason to use this function */
609   if (!shortdata)
610     return aim_genericreq_n(sess, conn, family, subtype);
611
612   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10+sizeof(u_short))))
613     return -1;
614
615   newpacket->lock = 1;
616
617   aim_putsnac(newpacket->data, family, subtype, 0x0000, sess->snac_nextid);
618
619   /* copy in data */
620   newshort = htons(*shortdata);
621   memcpy(&(newpacket->data[10]), &newshort, sizeof(u_short));
622
623   aim_tx_enqueue(sess, newpacket);
624   return (sess->snac_nextid++);
625 }
626
627 /*
628  * aim_bos_reqlocaterights()
629  *
630  * Request Location services rights.
631  *
632  */
633 u_long aim_bos_reqlocaterights(struct aim_session_t *sess,
634                                struct aim_conn_t *conn)
635 {
636   return aim_genericreq_n(sess, conn, 0x0002, 0x0002);
637 }
638
639 /*
640 * aim_bos_reqicbmparaminfo()
641  *
642  * Request ICBM parameter information.
643  *
644  */
645 u_long aim_bos_reqicbmparaminfo(struct aim_session_t *sess,
646                                 struct aim_conn_t *conn)
647 {
648   return aim_genericreq_n(sess, conn, 0x0004, 0x0004);
649 }
650
This page took 0.085789 seconds and 5 git commands to generate.