]> andersk Git - libfaim.git/blob - aim_misc.c
- Thu Dec 14 03:39:34 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 faim_export unsigned 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 faim_export unsigned long aim_bos_changevisibility(struct aim_session_t *sess,
61                                                    struct aim_conn_t *conn, 
62                                                    int changetype, 
63                                                    char *denylist)
64 {
65   struct command_tx_struct *newpacket;
66   int packlen = 0;
67   u_short subtype;
68
69   char *localcpy = NULL;
70   char *tmpptr = NULL;
71   int i,j;
72   int listcount;
73
74   if (!denylist)
75     return 0;
76
77   localcpy = (char *) malloc(strlen(denylist)+1);
78   memcpy(localcpy, denylist, strlen(denylist)+1);
79   
80   listcount = aimutil_itemcnt(localcpy, '&');
81   packlen = aimutil_tokslen(localcpy, 99, '&') + listcount + 9;
82
83   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, packlen)))
84     return -1;
85
86   newpacket->lock = 1;
87
88   switch(changetype)
89     {
90     case AIM_VISIBILITYCHANGE_PERMITADD:    subtype = 0x05; break;
91     case AIM_VISIBILITYCHANGE_PERMITREMOVE: subtype = 0x06; break;
92     case AIM_VISIBILITYCHANGE_DENYADD:      subtype = 0x07; break;
93     case AIM_VISIBILITYCHANGE_DENYREMOVE:   subtype = 0x08; break;
94     default:
95       free(newpacket->data);
96       free(newpacket);
97       return 0;
98     }
99
100   /* We actually DO NOT send a SNAC ID with this one! */
101   aim_putsnac(newpacket->data, 0x0009, subtype, 0x00, 0);
102  
103   j = 10;  /* the next byte */
104   
105   for (i=0; (i < (listcount - 1)) && (i < 99); i++)
106     {
107       tmpptr = aimutil_itemidx(localcpy, i, '&');
108
109       newpacket->data[j] = strlen(tmpptr);
110       memcpy(&(newpacket->data[j+1]), tmpptr, strlen(tmpptr));
111       j += strlen(tmpptr)+1;
112       free(tmpptr);
113     }
114   free(localcpy);
115
116   newpacket->lock = 0;
117
118   aim_tx_enqueue(sess, newpacket);
119
120   return (sess->snac_nextid); /* dont increment */
121
122 }
123
124
125
126 /*
127  * aim_bos_setbuddylist(buddylist)
128  *
129  * This just builds the "set buddy list" command then queues it.
130  *
131  * buddy_list = "Screen Name One&ScreenNameTwo&";
132  *
133  * TODO: Clean this up.  
134  *
135  * XXX: I can't stress the TODO enough.
136  *
137  */
138 faim_export unsigned long aim_bos_setbuddylist(struct aim_session_t *sess,
139                                                struct aim_conn_t *conn, 
140                                                char *buddy_list)
141 {
142   int i, j;
143
144   struct command_tx_struct *newpacket;
145
146   int len = 0;
147
148   char *localcpy = NULL;
149   char *tmpptr = NULL;
150
151   len = 10; /* 10B SNAC headers */
152
153   if (!buddy_list || !(localcpy = (char *) malloc(strlen(buddy_list)+1))) 
154     return -1;
155   strncpy(localcpy, buddy_list, strlen(buddy_list)+1);
156
157   i = 0;
158   tmpptr = strtok(localcpy, "&");
159   while ((tmpptr != NULL) && (i < 150)) {
160 #if debug > 0
161     printf("---adding %d: %s (%d)\n", i, tmpptr, strlen(tmpptr));
162 #endif
163     len += 1+strlen(tmpptr);
164     i++;
165     tmpptr = strtok(NULL, "&");
166   }
167 #if debug > 0
168   printf("*** send buddy list len: %d (%x)\n", len, len);
169 #endif
170
171   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, len)))
172     return -1;
173
174   newpacket->lock = 1;
175   
176   aim_putsnac(newpacket->data, 0x0003, 0x0004, 0x0000, 0);
177
178   j = 10;  /* the next byte */
179
180   strncpy(localcpy, buddy_list, strlen(buddy_list)+1);
181   i = 0;
182   tmpptr = strtok(localcpy, "&");
183   while ((tmpptr != NULL) & (i < 150)) {
184 #if debug > 0
185     printf("---adding %d: %s (%d)\n", i, tmpptr, strlen(tmpptr));
186 #endif
187     newpacket->data[j] = strlen(tmpptr);
188     memcpy(&(newpacket->data[j+1]), tmpptr, strlen(tmpptr));
189     j += 1+strlen(tmpptr);
190     i++;
191     tmpptr = strtok(NULL, "&");
192   }
193
194   newpacket->lock = 0;
195
196   aim_tx_enqueue(sess, newpacket);
197
198   free(localcpy);
199
200   return (sess->snac_nextid);
201 }
202
203 /* 
204  * aim_bos_setprofile(profile)
205  *
206  * Gives BOS your profile.
207  *
208  * 
209  */
210 faim_export unsigned long aim_bos_setprofile(struct aim_session_t *sess,
211                                              struct aim_conn_t *conn, 
212                                              char *profile,
213                                              char *awaymsg,
214                                              unsigned short caps)
215 {
216   struct command_tx_struct *newpacket;
217   int i = 0, tmp, caplen;
218
219   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 1152+strlen(profile)+1+(awaymsg?strlen(awaymsg):0))))
220     return -1;
221
222   i += aim_putsnac(newpacket->data, 0x0002, 0x004, 0x0000, sess->snac_nextid);
223   i += aim_puttlv_str(newpacket->data+i, 0x0001, strlen("text/x-aolrtf; charset=\"us-ascii\""), "text/x-aolrtf; charset=\"us-ascii\"");
224   i += aim_puttlv_str(newpacket->data+i, 0x0002, strlen(profile), profile);
225   /* why do we send this twice?  */
226   i += aim_puttlv_str(newpacket->data+i, 0x0003, strlen("text/x-aolrtf; charset=\"us-ascii\""), "text/x-aolrtf; charset=\"us-ascii\"");
227   
228   /* Away message -- we send this no matter what, even if its blank */
229   if (awaymsg)
230     i += aim_puttlv_str(newpacket->data+i, 0x0004, strlen(awaymsg), awaymsg);
231   else
232     i += aim_puttlv_str(newpacket->data+i, 0x0004, 0x0000, NULL);
233
234   /* Capability information. */
235  
236   tmp = (i += aimutil_put16(newpacket->data+i, 0x0005));
237   i += aimutil_put16(newpacket->data+i, 0x0000); /* rewritten later */
238   i += (caplen = aim_putcap(newpacket->data+i, 512, caps));
239   aimutil_put16(newpacket->data+tmp, caplen); /* rewrite TLV size */
240
241   newpacket->commandlen = i;
242   aim_tx_enqueue(sess, newpacket);
243   
244   return (sess->snac_nextid++);
245 }
246
247 /* 
248  * aim_bos_setgroupperm(mask)
249  * 
250  * Set group permisson mask.  Normally 0x1f (all classes).
251  *
252  * The group permission mask allows you to keep users of a certain
253  * class or classes from talking to you.  The mask should be
254  * a bitwise OR of all the user classes you want to see you.
255  *
256  */
257 faim_export unsigned long aim_bos_setgroupperm(struct aim_session_t *sess,
258                                                struct aim_conn_t *conn, 
259                                                u_long mask)
260 {
261   return aim_genericreq_l(sess, conn, 0x0009, 0x0004, &mask);
262 }
263
264 faim_internal int aim_parse_bosrights(struct aim_session_t *sess,
265                                       struct command_rx_struct *command, ...)
266 {
267   rxcallback_t userfunc = NULL;
268   int ret=1;
269   struct aim_tlvlist_t *tlvlist;
270   unsigned short maxpermits = 0, maxdenies = 0;
271
272   /* 
273    * TLVs follow 
274    */
275   if (!(tlvlist = aim_readtlvchain(command->data+10, command->commandlen-10)))
276     return ret;
277
278   /*
279    * TLV type 0x0001: Maximum number of buddies on permit list.
280    */
281   if (aim_gettlv(tlvlist, 0x0001, 1))
282     maxpermits = aim_gettlv16(tlvlist, 0x0001, 1);
283
284   /*
285    * TLV type 0x0002: Maximum number of buddies on deny list.
286    *
287    */
288   if (aim_gettlv(tlvlist, 0x0002, 1)) 
289     maxdenies = aim_gettlv16(tlvlist, 0x0002, 1);
290   
291   if ((userfunc = aim_callhandler(command->conn, 0x0009, 0x0003)))
292     ret = userfunc(sess, command, maxpermits, maxdenies);
293
294   aim_freetlvchain(&tlvlist);
295
296   return ret;  
297 }
298
299 /*
300  * aim_bos_clientready()
301  * 
302  * Send Client Ready.  
303  *
304  * TODO: Dynamisize.
305  *
306  */
307 faim_export unsigned long aim_bos_clientready(struct aim_session_t *sess,
308                                               struct aim_conn_t *conn)
309 {
310   u_char command_2[] = {
311      /* placeholders for dynamic data */
312      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
313      0xff, 0xff, 
314      /* real data */
315      0x00, 0x01,   
316      0x00, 0x03, 
317      0x00, 0x04, 
318      0x06, 0x86, /* the good ones */
319 #if 0
320      0x07, 0xda, /* DUPLE OF DEATH! */
321 #endif
322
323      0x00, 0x02, 
324      0x00, 0x01,  
325      0x00, 0x04, 
326      0x00, 0x01, 
327  
328      0x00, 0x03, 
329      0x00, 0x01,  
330      0x00, 0x04, 
331      0x00, 0x01,
332  
333      0x00, 0x04, 
334      0x00, 0x01, 
335      0x00, 0x04,
336      0x00, 0x01,
337  
338      0x00, 0x06, 
339      0x00, 0x01, 
340      0x00, 0x04,  
341      0x00, 0x01, 
342      0x00, 0x08, 
343      0x00, 0x01, 
344      0x00, 0x04,
345      0x00, 0x01,
346  
347      0x00, 0x09, 
348      0x00, 0x01, 
349      0x00, 0x04,
350      0x00, 0x01, 
351      0x00, 0x0a, 
352      0x00, 0x01, 
353      0x00, 0x04,
354      0x00, 0x01,
355  
356      0x00, 0x0b,
357      0x00, 0x01, 
358      0x00, 0x04,
359      0x00, 0x01
360   };
361   int command_2_len = 0x52;
362   struct command_tx_struct *newpacket;
363   
364   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, command_2_len)))
365     return -1;
366
367   newpacket->lock = 1;
368
369   memcpy(newpacket->data, command_2, command_2_len);
370   
371   /* This write over the dynamic parts of the byte block */
372   aim_putsnac(newpacket->data, 0x0001, 0x0002, 0x0000, sess->snac_nextid);
373
374   aim_tx_enqueue(sess, newpacket);
375
376   return (sess->snac_nextid++);
377 }
378
379 /* 
380  *  Request Rate Information.
381  * 
382  */
383 faim_export unsigned long aim_bos_reqrate(struct aim_session_t *sess,
384                                           struct aim_conn_t *conn)
385 {
386   return aim_genericreq_n(sess, conn, 0x0001, 0x0006);
387 }
388
389 /* 
390  *  Rate Information Response Acknowledge.
391  *
392  */
393 faim_export unsigned long aim_bos_ackrateresp(struct aim_session_t *sess,
394                                               struct aim_conn_t *conn)
395 {
396   struct command_tx_struct *newpacket;
397   int packlen = 20, i=0;
398
399   if(!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, packlen)))
400     return (sess->snac_nextid);
401   
402   newpacket->lock = 1;
403
404   i = aim_putsnac(newpacket->data, 0x0001, 0x0008, 0x0000, 0);
405   i += aimutil_put16(newpacket->data+i, 0x0001); 
406   i += aimutil_put16(newpacket->data+i, 0x0002);
407   i += aimutil_put16(newpacket->data+i, 0x0003);
408   i += aimutil_put16(newpacket->data+i, 0x0004);
409   i += aimutil_put16(newpacket->data+i, 0x0005);
410
411   newpacket->commandlen = i;
412   newpacket->lock = 0;
413
414   aim_tx_enqueue(sess, newpacket);
415
416   return (sess->snac_nextid);
417 }
418
419 /* 
420  * aim_bos_setprivacyflags()
421  *
422  * Sets privacy flags. Normally 0x03.
423  *
424  *  Bit 1:  Allows other AIM users to see how long you've been idle.
425  *  Bit 2:  Allows other AIM users to see how long you've been a member.
426  *
427  */
428 faim_export unsigned long aim_bos_setprivacyflags(struct aim_session_t *sess,
429                                                   struct aim_conn_t *conn, 
430                                                   u_long flags)
431 {
432   return aim_genericreq_l(sess, conn, 0x0001, 0x0014, &flags);
433 }
434
435 /*
436  * aim_bos_reqpersonalinfo()
437  *
438  * Requests the current user's information. Can't go generic on this one
439  * because aparently it uses SNAC flags.
440  *
441  */
442 faim_export unsigned long aim_bos_reqpersonalinfo(struct aim_session_t *sess,
443                                                   struct aim_conn_t *conn)
444 {
445   return aim_genericreq_n(sess, conn, 0x0001, 0x000e);
446 }
447
448 faim_export unsigned long aim_setversions(struct aim_session_t *sess,
449                                           struct aim_conn_t *conn)
450 {
451   struct command_tx_struct *newpacket;
452   int i;
453
454   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10 + (4*12))))
455     return -1;
456
457   newpacket->lock = 1;
458
459   i = aim_putsnac(newpacket->data, 0x0001, 0x0017, 0x0000, sess->snac_nextid);
460   aim_cachesnac(sess, 0x0001, 0x0017, 0x0000, NULL, 0);
461
462   i += aimutil_put16(newpacket->data+i, 0x0001);
463   i += aimutil_put16(newpacket->data+i, 0x0003);
464
465   i += aimutil_put16(newpacket->data+i, 0x0013);
466   i += aimutil_put16(newpacket->data+i, 0x0001);
467
468   i += aimutil_put16(newpacket->data+i, 0x0002);
469   i += aimutil_put16(newpacket->data+i, 0x0001);
470
471   i += aimutil_put16(newpacket->data+i, 0x0003);
472   i += aimutil_put16(newpacket->data+i, 0x0001);
473
474   i += aimutil_put16(newpacket->data+i, 0x0004);
475   i += aimutil_put16(newpacket->data+i, 0x0001);
476
477   i += aimutil_put16(newpacket->data+i, 0x0006);
478   i += aimutil_put16(newpacket->data+i, 0x0001);
479
480   i += aimutil_put16(newpacket->data+i, 0x0008);
481   i += aimutil_put16(newpacket->data+i, 0x0001);
482
483   i += aimutil_put16(newpacket->data+i, 0x0009);
484   i += aimutil_put16(newpacket->data+i, 0x0001);
485
486   i += aimutil_put16(newpacket->data+i, 0x000a);
487   i += aimutil_put16(newpacket->data+i, 0x0001);
488
489   i += aimutil_put16(newpacket->data+i, 0x000b);
490   i += aimutil_put16(newpacket->data+i, 0x0001);
491
492   i += aimutil_put16(newpacket->data+i, 0x000c);
493   i += aimutil_put16(newpacket->data+i, 0x0001);
494
495   newpacket->commandlen = i;
496   newpacket->lock = 0;
497   aim_tx_enqueue(sess, newpacket);
498
499   return sess->snac_nextid;
500 }
501
502
503 /*
504  * aim_bos_reqservice(serviceid)
505  *
506  * Service request. 
507  *
508  */
509 faim_export unsigned long aim_bos_reqservice(struct aim_session_t *sess,
510                           struct aim_conn_t *conn, 
511                           u_short serviceid)
512 {
513   return aim_genericreq_s(sess, conn, 0x0001, 0x0004, &serviceid);
514 }
515
516 /*
517  * aim_bos_nop()
518  *
519  * No-op.  WinAIM sends these every 4min or so to keep
520  * the connection alive.  Its not real necessary.
521  *
522  */
523 faim_export unsigned long aim_bos_nop(struct aim_session_t *sess,
524                                       struct aim_conn_t *conn)
525 {
526   return aim_genericreq_n(sess, conn, 0x0001, 0x0016);
527 }
528
529 /*
530  * aim_flap_nop()
531  *
532  * No-op.  WinAIM 4.x sends these _every minute_ to keep
533  * the connection alive.  
534  */
535 faim_export unsigned long aim_flap_nop(struct aim_session_t *sess,
536                                        struct aim_conn_t *conn)
537 {
538   struct command_tx_struct *newpacket;
539
540   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0005, conn, 0)))
541     return sess->snac_nextid;
542
543   newpacket->lock = 1;
544   newpacket->commandlen = 0;
545   newpacket->lock = 0;
546
547   aim_tx_enqueue(sess, newpacket);
548
549   return (sess->snac_nextid);
550 }
551
552 /*
553  * aim_bos_reqrights()
554  *
555  * Request BOS rights.
556  *
557  */
558 faim_export unsigned long aim_bos_reqrights(struct aim_session_t *sess,
559                                             struct aim_conn_t *conn)
560 {
561   return aim_genericreq_n(sess, conn, 0x0009, 0x0002);
562 }
563
564 /*
565  * aim_bos_reqbuddyrights()
566  *
567  * Request Buddy List rights.
568  *
569  */
570 faim_export unsigned long aim_bos_reqbuddyrights(struct aim_session_t *sess,
571                                                  struct aim_conn_t *conn)
572 {
573   return aim_genericreq_n(sess, conn, 0x0003, 0x0002);
574 }
575
576 /*
577  * aim_send_warning(struct aim_session_t *sess, 
578  *                  struct aim_conn_t *conn, char *destsn, int anon)
579  * send a warning to destsn.
580  * anon is anonymous or not;
581  *  AIM_WARN_ANON anonymous
582  *
583  * returns -1 on error (couldn't alloc packet), next snacid on success.
584  *
585  */
586 faim_export int aim_send_warning(struct aim_session_t *sess, struct aim_conn_t *conn, char *destsn, int anon)
587 {
588   struct command_tx_struct *newpacket;
589   int curbyte;
590
591   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, strlen(destsn)+13)))
592     return -1;
593
594   newpacket->lock = 1;
595
596   curbyte  = 0;
597   curbyte += aim_putsnac(newpacket->data+curbyte,
598                         0x0004, 0x0008, 0x0000, sess->snac_nextid);
599
600   curbyte += aimutil_put16(newpacket->data+curbyte, (anon & AIM_WARN_ANON)?1:0);
601
602   curbyte += aimutil_put8(newpacket->data+curbyte, strlen(destsn));
603
604   curbyte += aimutil_putstr(newpacket->data+curbyte, destsn, strlen(destsn));
605
606   newpacket->commandlen = curbyte;
607   newpacket->lock = 0;
608
609   aim_tx_enqueue(sess, newpacket);
610
611   return (sess->snac_nextid++);
612 }
613
614 /*
615  * aim_debugconn_sendconnect()
616  *
617  * For aimdebugd.  If you don't know what it is, you don't want to.
618  */
619 faim_export unsigned long aim_debugconn_sendconnect(struct aim_session_t *sess,
620                                                     struct aim_conn_t *conn)
621 {
622   return aim_genericreq_n(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_DEBUGCONN_CONNECT);
623 }
624
625 /*
626  * Generic routine for sending commands.
627  *
628  *
629  * I know I can do this in a smarter way...but I'm not thinking straight
630  * right now...
631  *
632  * I had one big function that handled all three cases, but then it broke
633  * and I split it up into three.  But then I fixed it.  I just never went
634  * back to the single.  I don't see any advantage to doing it either way.
635  *
636  */
637 faim_internal unsigned long aim_genericreq_n(struct aim_session_t *sess,
638                                              struct aim_conn_t *conn, 
639                                              u_short family, u_short subtype)
640 {
641   struct command_tx_struct *newpacket;
642
643   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10)))
644     return 0;
645
646   newpacket->lock = 1;
647
648   aim_putsnac(newpacket->data, family, subtype, 0x0000, sess->snac_nextid);
649
650   aim_cachesnac(sess, family, subtype, 0x0000, NULL, 0);
651
652   aim_tx_enqueue(sess, newpacket);
653   return sess->snac_nextid;
654 }
655
656 /*
657  *
658  *
659  */
660 faim_internal unsigned long aim_genericreq_l(struct aim_session_t *sess,
661                                              struct aim_conn_t *conn, 
662                                              u_short family, u_short subtype, 
663                                              u_long *longdata)
664 {
665   struct command_tx_struct *newpacket;
666   u_long newlong;
667
668   /* If we don't have data, there's no reason to use this function */
669   if (!longdata)
670     return aim_genericreq_n(sess, conn, family, subtype);
671
672   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10+sizeof(u_long))))
673     return -1;
674
675   newpacket->lock = 1;
676
677   aim_putsnac(newpacket->data, family, subtype, 0x0000, sess->snac_nextid);
678   aim_cachesnac(sess, family, subtype, 0x0000, NULL, 0);
679
680   /* copy in data */
681   newlong = htonl(*longdata);
682   memcpy(&(newpacket->data[10]), &newlong, sizeof(u_long));
683
684   aim_tx_enqueue(sess, newpacket);
685   return sess->snac_nextid;
686 }
687
688 faim_internal unsigned long aim_genericreq_s(struct aim_session_t *sess,
689                                              struct aim_conn_t *conn, 
690                                              u_short family, u_short subtype, 
691                                              u_short *shortdata)
692 {
693   struct command_tx_struct *newpacket;
694   u_short newshort;
695
696   /* If we don't have data, there's no reason to use this function */
697   if (!shortdata)
698     return aim_genericreq_n(sess, conn, family, subtype);
699
700   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10+sizeof(u_short))))
701     return -1;
702
703   newpacket->lock = 1;
704
705   aim_putsnac(newpacket->data, family, subtype, 0x0000, sess->snac_nextid);
706   aim_cachesnac(sess, family, subtype, 0x0000, NULL, 0);
707
708   /* copy in data */
709   newshort = htons(*shortdata);
710   memcpy(&(newpacket->data[10]), &newshort, sizeof(u_short));
711
712   aim_tx_enqueue(sess, newpacket);
713   return sess->snac_nextid;
714 }
715
716 /*
717  * aim_bos_reqlocaterights()
718  *
719  * Request Location services rights.
720  *
721  */
722 faim_export unsigned long aim_bos_reqlocaterights(struct aim_session_t *sess,
723                                                   struct aim_conn_t *conn)
724 {
725   return aim_genericreq_n(sess, conn, 0x0002, 0x0002);
726 }
727
728 /*
729 * aim_bos_reqicbmparaminfo()
730  *
731  * Request ICBM parameter information.
732  *
733  */
734 faim_export unsigned long aim_bos_reqicbmparaminfo(struct aim_session_t *sess,
735                                                    struct aim_conn_t *conn)
736 {
737   return aim_genericreq_n(sess, conn, 0x0004, 0x0004);
738 }
739
740 /*
741  * Add ICBM parameter? Huh?
742  */
743 faim_export unsigned long aim_addicbmparam(struct aim_session_t *sess,
744                                            struct aim_conn_t *conn)
745 {
746   struct command_tx_struct *newpacket;
747   int packlen = 10+16, i=0;
748
749   if(!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, packlen)))
750     return (sess->snac_nextid);
751   
752   newpacket->lock = 1;
753
754   i = aim_putsnac(newpacket->data, 0x0004, 0x0002, 0x0000, sess->snac_nextid);
755   aim_cachesnac(sess, 0x0004, 0x0002, 0x0000, NULL, 0);
756
757   i += aimutil_put16(newpacket->data+i, 0x0000); 
758   i += aimutil_put16(newpacket->data+i, 0x0000);
759   i += aimutil_put16(newpacket->data+i, 0x0003);
760   i += aimutil_put16(newpacket->data+i, 0x1f40);
761   i += aimutil_put16(newpacket->data+i, 0x03e7);
762   i += aimutil_put16(newpacket->data+i, 0x03e7);
763   i += aimutil_put16(newpacket->data+i, 0x0000); 
764   i += aimutil_put16(newpacket->data+i, 0x0000); 
765   
766   aim_tx_enqueue(sess, newpacket);
767
768   return sess->snac_nextid;
769 }
770
771 /* 
772  * Set directory profile data (not the same as aim_bos_setprofile!)
773  */
774 faim_export unsigned long aim_setdirectoryinfo(struct aim_session_t *sess, struct aim_conn_t *conn, char *first, char *middle, char *last, char *maiden, char *nickname, char *street, char *city, char *state, char *zip, int country, unsigned short privacy) 
775 {
776   struct command_tx_struct *newpacket;
777   int packlen = 0, i = 0;
778
779   packlen += 2+2+2;
780
781   if(first) /* TLV 0001 */
782     packlen += (strlen(first) + 4);
783   if(middle) 
784     packlen += (strlen(middle) + 4);
785   if(last)
786     packlen += (strlen(last) + 4);
787   if(maiden)
788     packlen += (strlen(maiden) + 4);
789   if(nickname)
790     packlen += (strlen(nickname) + 4);
791   if(street)
792     packlen += (strlen(street) + 4);
793   if(state)
794     packlen += (strlen(state) + 4);
795   if(city)
796     packlen += (strlen(city) + 4);
797   if(zip)
798     packlen += (strlen(zip) + 4);
799     
800   if(!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, packlen+10)))
801     return -1;
802
803   newpacket->lock = 1;
804
805   i = aim_putsnac(newpacket->data, 0x0002, 0x0009, 0x0000, 0);
806
807   /* 000a/0002: privacy: 1 to allow search/disp, 0 to disallow */
808   i += aim_puttlv_16(newpacket->data+i, 0x000a, privacy);
809
810
811   if (first)
812     i += aim_puttlv_str(newpacket->data+i, 0x0001, strlen(first), first);
813   if (middle)
814     i += aim_puttlv_str(newpacket->data+i, 0x0003, strlen(middle), middle);
815   if (last)
816     i += aim_puttlv_str(newpacket->data+i, 0x0002, strlen(last), last);
817   if (maiden)
818     i += aim_puttlv_str(newpacket->data+i, 0x0004, strlen(maiden), maiden);
819   if (nickname)
820     i += aim_puttlv_str(newpacket->data+i, 0x000c, strlen(nickname), nickname);
821   if (street)
822     i += aim_puttlv_str(newpacket->data+i, 0x0021, strlen(street), street);
823   if (city)
824     i += aim_puttlv_str(newpacket->data+i, 0x0008, strlen(city), city);
825   if (state)
826     i += aim_puttlv_str(newpacket->data+i, 0x0007, strlen(state), state);
827   if (zip)
828     i += aim_puttlv_str(newpacket->data+i, 0x000d, strlen(zip), zip);
829
830   newpacket->commandlen = i;
831   newpacket->lock = 0;
832
833   aim_tx_enqueue(sess, newpacket);
834    
835   return(sess->snac_nextid);
836 }
837
838 faim_export unsigned long aim_setuserinterests(struct aim_session_t *sess, struct aim_conn_t *conn, char *interest1, char *interest2, char *interest3, char *interest4, char *interest5, unsigned short privacy)
839 {
840   struct command_tx_struct *newpacket;
841   int packlen = 0, i = 0;
842
843   packlen += 2+2+2;
844
845   if(interest1)
846     packlen += (strlen(interest1) + 4);
847   if(interest2)
848     packlen += (strlen(interest2) + 4);
849   if(interest3)
850     packlen += (strlen(interest3) + 4);
851   if(interest4)
852     packlen += (strlen(interest4) + 4);
853   if(interest5)
854     packlen += (strlen(interest5) + 4) ;
855
856     
857   if(!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, packlen+10)))
858     return -1;
859
860   newpacket->lock = 1;
861
862   i = aim_putsnac(newpacket->data, 0x0002, 0x000f, 0x0000, 0);
863
864   /* 000a/0002: 0000 ?? ?privacy? */
865   i += aim_puttlv_16(newpacket->data+i, 0x000a, privacy); 
866
867   if(interest1) 
868     i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest1), interest1);
869   if(interest2) 
870     i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest2), interest2);
871   if(interest3) 
872     i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest3), interest3);
873   if(interest4) 
874     i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest4), interest4);
875   if(interest5) 
876     i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest1), interest5);
877
878   newpacket->commandlen = i;
879   newpacket->lock = 0;
880     
881   aim_tx_enqueue(sess, newpacket);
882     
883   return(sess->snac_nextid);
884 }
885
886 faim_export unsigned long aim_icq_setstatus(struct aim_session_t *sess,
887                                             struct aim_conn_t *conn, 
888                                             unsigned long status)
889 {
890   struct command_tx_struct *newpacket;
891   int i;
892   unsigned long data;
893   
894   data = 0x00030000 | status; /* yay for error checking ;^) */
895
896   if(!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10 + 4)))
897     return -1;
898
899   newpacket->lock = 1;
900
901   i = aim_putsnac(newpacket->data, 0x0001, 0x001e, 0x0000, 0x0000001e);
902   i += aim_puttlv_32(newpacket->data+i, 0x0006, data);
903
904   newpacket->commandlen = i;
905   newpacket->lock = 0;
906
907   aim_tx_enqueue(sess, newpacket);
908
909   return(sess->snac_nextid);
910 }
This page took 1.029489 seconds and 5 git commands to generate.