]> andersk Git - libfaim.git/blob - aim_misc.c
- Mon Dec 4 23:46:35 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   struct aim_tlv_t *tlv;
271   unsigned short maxpermits = 0, maxdenies = 0;
272
273   /* 
274    * TLVs follow 
275    */
276   if (!(tlvlist = aim_readtlvchain(command->data+10, command->commandlen-10)))
277     return ret;
278
279   /*
280    * TLV type 0x0001: Maximum number of buddies on permit list.
281    */
282   if ((tlv = aim_gettlv(tlvlist, 0x0001, 1))) {
283     maxpermits = aimutil_get16(tlv->value);
284   }
285
286   /*
287    * TLV type 0x0002: Maximum number of buddies on deny list.
288    *
289    */
290   if ((tlv = aim_gettlv(tlvlist, 0x0002, 1))) {
291     maxdenies = aimutil_get16(tlv->value);
292   }
293   
294   userfunc = aim_callhandler(command->conn, 0x0009, 0x0003);
295   if (userfunc)
296     ret =  userfunc(sess, command, maxpermits, maxdenies);
297
298   aim_freetlvchain(&tlvlist);
299
300   return ret;  
301 }
302
303 /*
304  * aim_bos_clientready()
305  * 
306  * Send Client Ready.  
307  *
308  * TODO: Dynamisize.
309  *
310  */
311 faim_export unsigned long aim_bos_clientready(struct aim_session_t *sess,
312                                               struct aim_conn_t *conn)
313 {
314   u_char command_2[] = {
315      /* placeholders for dynamic data */
316      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
317      0xff, 0xff, 
318      /* real data */
319      0x00, 0x01,   
320      0x00, 0x03, 
321      0x00, 0x04, 
322      0x06, 0x86, /* the good ones */
323 #if 0
324      0x07, 0xda, /* DUPLE OF DEATH! */
325 #endif
326
327      0x00, 0x02, 
328      0x00, 0x01,  
329      0x00, 0x04, 
330      0x00, 0x01, 
331  
332      0x00, 0x03, 
333      0x00, 0x01,  
334      0x00, 0x04, 
335      0x00, 0x01,
336  
337      0x00, 0x04, 
338      0x00, 0x01, 
339      0x00, 0x04,
340      0x00, 0x01,
341  
342      0x00, 0x06, 
343      0x00, 0x01, 
344      0x00, 0x04,  
345      0x00, 0x01, 
346      0x00, 0x08, 
347      0x00, 0x01, 
348      0x00, 0x04,
349      0x00, 0x01,
350  
351      0x00, 0x09, 
352      0x00, 0x01, 
353      0x00, 0x04,
354      0x00, 0x01, 
355      0x00, 0x0a, 
356      0x00, 0x01, 
357      0x00, 0x04,
358      0x00, 0x01,
359  
360      0x00, 0x0b,
361      0x00, 0x01, 
362      0x00, 0x04,
363      0x00, 0x01
364   };
365   int command_2_len = 0x52;
366   struct command_tx_struct *newpacket;
367   
368   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, command_2_len)))
369     return -1;
370
371   newpacket->lock = 1;
372
373   memcpy(newpacket->data, command_2, command_2_len);
374   
375   /* This write over the dynamic parts of the byte block */
376   aim_putsnac(newpacket->data, 0x0001, 0x0002, 0x0000, sess->snac_nextid);
377
378   aim_tx_enqueue(sess, newpacket);
379
380   return (sess->snac_nextid++);
381 }
382
383 /* 
384  *  Request Rate Information.
385  * 
386  */
387 faim_export unsigned long aim_bos_reqrate(struct aim_session_t *sess,
388                                           struct aim_conn_t *conn)
389 {
390   return aim_genericreq_n(sess, conn, 0x0001, 0x0006);
391 }
392
393 /* 
394  *  Rate Information Response Acknowledge.
395  *
396  */
397 faim_export unsigned long aim_bos_ackrateresp(struct aim_session_t *sess,
398                                               struct aim_conn_t *conn)
399 {
400   struct command_tx_struct *newpacket;
401   int packlen = 20, i=0;
402
403   if(!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, packlen)))
404     return (sess->snac_nextid);
405   
406   newpacket->lock = 1;
407
408   i = aim_putsnac(newpacket->data, 0x0001, 0x0008, 0x0000, 0);
409   i += aimutil_put16(newpacket->data+i, 0x0001); 
410   i += aimutil_put16(newpacket->data+i, 0x0002);
411   i += aimutil_put16(newpacket->data+i, 0x0003);
412   i += aimutil_put16(newpacket->data+i, 0x0004);
413   i += aimutil_put16(newpacket->data+i, 0x0005);
414
415   newpacket->commandlen = i;
416   newpacket->lock = 0;
417
418   aim_tx_enqueue(sess, newpacket);
419
420   return (sess->snac_nextid);
421 }
422
423 /* 
424  * aim_bos_setprivacyflags()
425  *
426  * Sets privacy flags. Normally 0x03.
427  *
428  *  Bit 1:  Allows other AIM users to see how long you've been idle.
429  *  Bit 2:  Allows other AIM users to see how long you've been a member.
430  *
431  */
432 faim_export unsigned long aim_bos_setprivacyflags(struct aim_session_t *sess,
433                                                   struct aim_conn_t *conn, 
434                                                   u_long flags)
435 {
436   return aim_genericreq_l(sess, conn, 0x0001, 0x0014, &flags);
437 }
438
439 /*
440  * aim_bos_reqpersonalinfo()
441  *
442  * Requests the current user's information. Can't go generic on this one
443  * because aparently it uses SNAC flags.
444  *
445  */
446 faim_export unsigned long aim_bos_reqpersonalinfo(struct aim_session_t *sess,
447                                                   struct aim_conn_t *conn)
448 {
449   return aim_genericreq_n(sess, conn, 0x0001, 0x000e);
450 }
451
452 faim_export unsigned long aim_setversions(struct aim_session_t *sess,
453                                           struct aim_conn_t *conn)
454 {
455   struct command_tx_struct *newpacket;
456   int i;
457
458   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10 + (4*12))))
459     return -1;
460
461   newpacket->lock = 1;
462
463   i = aim_putsnac(newpacket->data, 0x0001, 0x0017, 0x0000, sess->snac_nextid);
464
465   i += aimutil_put16(newpacket->data+i, 0x0001);
466   i += aimutil_put16(newpacket->data+i, 0x0003);
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, 0x0002);
491
492   i += aimutil_put16(newpacket->data+i, 0x000c);
493   i += aimutil_put16(newpacket->data+i, 0x0001);
494
495   i += aimutil_put16(newpacket->data+i, 0x0013);
496   i += aimutil_put16(newpacket->data+i, 0x0001);
497
498   i += aimutil_put16(newpacket->data+i, 0x0015);
499   i += aimutil_put16(newpacket->data+i, 0x0001);
500
501 #if 0
502   for (j = 0; j < 0x10; j++) {
503     i += aimutil_put16(newpacket->data+i, j); /* family */
504     i += aimutil_put16(newpacket->data+i, 0x0003); /* version */
505   }
506 #endif
507
508   newpacket->commandlen = i;
509   newpacket->lock = 0;
510   aim_tx_enqueue(sess, newpacket);
511
512   return (sess->snac_nextid++);
513 }
514
515
516 /*
517  * aim_bos_reqservice(serviceid)
518  *
519  * Service request. 
520  *
521  */
522 faim_export unsigned long aim_bos_reqservice(struct aim_session_t *sess,
523                           struct aim_conn_t *conn, 
524                           u_short serviceid)
525 {
526   return aim_genericreq_s(sess, conn, 0x0001, 0x0004, &serviceid);
527 }
528
529 /*
530  * aim_bos_nop()
531  *
532  * No-op.  WinAIM sends these every 4min or so to keep
533  * the connection alive.  Its not real necessary.
534  *
535  */
536 faim_export unsigned long aim_bos_nop(struct aim_session_t *sess,
537                                       struct aim_conn_t *conn)
538 {
539   return aim_genericreq_n(sess, conn, 0x0001, 0x0016);
540 }
541
542 /*
543  * aim_flap_nop()
544  *
545  * No-op.  WinAIM 4.x sends these _every minute_ to keep
546  * the connection alive.  
547  */
548 faim_export unsigned long aim_flap_nop(struct aim_session_t *sess,
549                                        struct aim_conn_t *conn)
550 {
551   struct command_tx_struct *newpacket;
552
553   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0005, conn, 0)))
554     return sess->snac_nextid;
555
556   newpacket->lock = 1;
557   newpacket->commandlen = 0;
558   newpacket->lock = 0;
559
560   aim_tx_enqueue(sess, newpacket);
561
562   return (sess->snac_nextid);
563 }
564
565 /*
566  * aim_bos_reqrights()
567  *
568  * Request BOS rights.
569  *
570  */
571 faim_export unsigned long aim_bos_reqrights(struct aim_session_t *sess,
572                                             struct aim_conn_t *conn)
573 {
574   return aim_genericreq_n(sess, conn, 0x0009, 0x0002);
575 }
576
577 /*
578  * aim_bos_reqbuddyrights()
579  *
580  * Request Buddy List rights.
581  *
582  */
583 faim_export unsigned long aim_bos_reqbuddyrights(struct aim_session_t *sess,
584                                                  struct aim_conn_t *conn)
585 {
586   return aim_genericreq_n(sess, conn, 0x0003, 0x0002);
587 }
588
589 /*
590  * aim_send_warning(struct aim_session_t *sess, 
591  *                  struct aim_conn_t *conn, char *destsn, int anon)
592  * send a warning to destsn.
593  * anon is anonymous or not;
594  *  AIM_WARN_ANON anonymous
595  *
596  * returns -1 on error (couldn't alloc packet), next snacid on success.
597  *
598  */
599 faim_export int aim_send_warning(struct aim_session_t *sess, struct aim_conn_t *conn, char *destsn, int anon)
600 {
601   struct command_tx_struct *newpacket;
602   int curbyte;
603
604   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, strlen(destsn)+13)))
605     return -1;
606
607   newpacket->lock = 1;
608
609   curbyte  = 0;
610   curbyte += aim_putsnac(newpacket->data+curbyte,
611                         0x0004, 0x0008, 0x0000, sess->snac_nextid);
612
613   curbyte += aimutil_put16(newpacket->data+curbyte, (anon & AIM_WARN_ANON)?1:0);
614
615   curbyte += aimutil_put8(newpacket->data+curbyte, strlen(destsn));
616
617   curbyte += aimutil_putstr(newpacket->data+curbyte, destsn, strlen(destsn));
618
619   newpacket->commandlen = curbyte;
620   newpacket->lock = 0;
621
622   aim_tx_enqueue(sess, newpacket);
623
624   return (sess->snac_nextid++);
625 }
626
627 /*
628  * aim_debugconn_sendconnect()
629  *
630  * For aimdebugd.  If you don't know what it is, you don't want to.
631  */
632 faim_export unsigned long aim_debugconn_sendconnect(struct aim_session_t *sess,
633                                                     struct aim_conn_t *conn)
634 {
635   return aim_genericreq_n(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_DEBUGCONN_CONNECT);
636 }
637
638 /*
639  * Generic routine for sending commands.
640  *
641  *
642  * I know I can do this in a smarter way...but I'm not thinking straight
643  * right now...
644  *
645  * I had one big function that handled all three cases, but then it broke
646  * and I split it up into three.  But then I fixed it.  I just never went
647  * back to the single.  I don't see any advantage to doing it either way.
648  *
649  */
650 faim_internal unsigned long aim_genericreq_n(struct aim_session_t *sess,
651                                              struct aim_conn_t *conn, 
652                                              u_short family, u_short subtype)
653 {
654   struct command_tx_struct *newpacket;
655
656   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10)))
657     return 0;
658
659   newpacket->lock = 1;
660
661   aim_putsnac(newpacket->data, family, subtype, 0x0000, sess->snac_nextid);
662  
663   aim_tx_enqueue(sess, newpacket);
664   return (sess->snac_nextid++);
665 }
666
667 /*
668  *
669  *
670  */
671 faim_internal unsigned long aim_genericreq_l(struct aim_session_t *sess,
672                                              struct aim_conn_t *conn, 
673                                              u_short family, u_short subtype, 
674                                              u_long *longdata)
675 {
676   struct command_tx_struct *newpacket;
677   u_long newlong;
678
679   /* If we don't have data, there's no reason to use this function */
680   if (!longdata)
681     return aim_genericreq_n(sess, conn, family, subtype);
682
683   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10+sizeof(u_long))))
684     return -1;
685
686   newpacket->lock = 1;
687
688   aim_putsnac(newpacket->data, family, subtype, 0x0000, sess->snac_nextid);
689
690   /* copy in data */
691   newlong = htonl(*longdata);
692   memcpy(&(newpacket->data[10]), &newlong, sizeof(u_long));
693
694   aim_tx_enqueue(sess, newpacket);
695   return (sess->snac_nextid++);
696 }
697
698 faim_internal unsigned long aim_genericreq_s(struct aim_session_t *sess,
699                                              struct aim_conn_t *conn, 
700                                              u_short family, u_short subtype, 
701                                              u_short *shortdata)
702 {
703   struct command_tx_struct *newpacket;
704   u_short newshort;
705
706   /* If we don't have data, there's no reason to use this function */
707   if (!shortdata)
708     return aim_genericreq_n(sess, conn, family, subtype);
709
710   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10+sizeof(u_short))))
711     return -1;
712
713   newpacket->lock = 1;
714
715   aim_putsnac(newpacket->data, family, subtype, 0x0000, sess->snac_nextid);
716
717   /* copy in data */
718   newshort = htons(*shortdata);
719   memcpy(&(newpacket->data[10]), &newshort, sizeof(u_short));
720
721   aim_tx_enqueue(sess, newpacket);
722   return (sess->snac_nextid++);
723 }
724
725 /*
726  * aim_bos_reqlocaterights()
727  *
728  * Request Location services rights.
729  *
730  */
731 faim_export unsigned long aim_bos_reqlocaterights(struct aim_session_t *sess,
732                                                   struct aim_conn_t *conn)
733 {
734   return aim_genericreq_n(sess, conn, 0x0002, 0x0002);
735 }
736
737 /*
738 * aim_bos_reqicbmparaminfo()
739  *
740  * Request ICBM parameter information.
741  *
742  */
743 faim_export unsigned long aim_bos_reqicbmparaminfo(struct aim_session_t *sess,
744                                                    struct aim_conn_t *conn)
745 {
746   return aim_genericreq_n(sess, conn, 0x0004, 0x0004);
747 }
748
749 /*
750  * Add ICBM parameter? Huh?
751  */
752 faim_export unsigned long aim_addicbmparam(struct aim_session_t *sess,
753                                            struct aim_conn_t *conn)
754 {
755   struct command_tx_struct *newpacket;
756   int packlen = 10+16, i=0;
757
758   if(!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, packlen)))
759     return (sess->snac_nextid);
760   
761   newpacket->lock = 1;
762
763   i = aim_putsnac(newpacket->data, 0x0004, 0x0002, 0x0000, sess->snac_nextid);
764   i += aimutil_put16(newpacket->data+i, 0x0000); 
765   i += aimutil_put16(newpacket->data+i, 0x0000);
766   i += aimutil_put16(newpacket->data+i, 0x0003);
767   i += aimutil_put16(newpacket->data+i, 0x1f40);
768   i += aimutil_put16(newpacket->data+i, 0x03e7);
769   i += aimutil_put16(newpacket->data+i, 0x03e7);
770   i += aimutil_put16(newpacket->data+i, 0x0000); 
771   i += aimutil_put16(newpacket->data+i, 0x0000); 
772   
773   aim_tx_enqueue(sess, newpacket);
774
775   return (sess->snac_nextid);
776 }
777
778 /* 
779  * Set directory profile data (not the same as aim_bos_setprofile!)
780  */
781 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) 
782 {
783   struct command_tx_struct *newpacket;
784   int packlen = 0, i = 0;
785
786   packlen += 2+2+2;
787
788   if(first) /* TLV 0001 */
789     packlen += (strlen(first) + 4);
790   if(middle) 
791     packlen += (strlen(middle) + 4);
792   if(last)
793     packlen += (strlen(last) + 4);
794   if(maiden)
795     packlen += (strlen(maiden) + 4);
796   if(nickname)
797     packlen += (strlen(nickname) + 4);
798   if(street)
799     packlen += (strlen(street) + 4);
800   if(state)
801     packlen += (strlen(state) + 4);
802   if(city)
803     packlen += (strlen(city) + 4);
804   if(zip)
805     packlen += (strlen(zip) + 4);
806     
807   if(!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, packlen+10)))
808     return -1;
809
810   newpacket->lock = 1;
811
812   i = aim_putsnac(newpacket->data, 0x0002, 0x0009, 0x0000, 0);
813
814   /* 000a/0002: privacy: 1 to allow search/disp, 0 to disallow */
815   i += aim_puttlv_16(newpacket->data+i, 0x000a, privacy);
816
817
818   if (first)
819     i += aim_puttlv_str(newpacket->data+i, 0x0001, strlen(first), first);
820   if (middle)
821     i += aim_puttlv_str(newpacket->data+i, 0x0003, strlen(middle), middle);
822   if (last)
823     i += aim_puttlv_str(newpacket->data+i, 0x0002, strlen(last), last);
824   if (maiden)
825     i += aim_puttlv_str(newpacket->data+i, 0x0004, strlen(maiden), maiden);
826   if (nickname)
827     i += aim_puttlv_str(newpacket->data+i, 0x000c, strlen(nickname), nickname);
828   if (street)
829     i += aim_puttlv_str(newpacket->data+i, 0x0021, strlen(street), street);
830   if (city)
831     i += aim_puttlv_str(newpacket->data+i, 0x0008, strlen(city), city);
832   if (state)
833     i += aim_puttlv_str(newpacket->data+i, 0x0007, strlen(state), state);
834   if (zip)
835     i += aim_puttlv_str(newpacket->data+i, 0x000d, strlen(zip), zip);
836
837   newpacket->commandlen = i;
838   newpacket->lock = 0;
839
840   aim_tx_enqueue(sess, newpacket);
841    
842   return(sess->snac_nextid);
843 }
844
845 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)
846 {
847   struct command_tx_struct *newpacket;
848   int packlen = 0, i = 0;
849
850   packlen += 2+2+2;
851
852   if(interest1)
853     packlen += (strlen(interest1) + 4);
854   if(interest2)
855     packlen += (strlen(interest2) + 4);
856   if(interest3)
857     packlen += (strlen(interest3) + 4);
858   if(interest4)
859     packlen += (strlen(interest4) + 4);
860   if(interest5)
861     packlen += (strlen(interest5) + 4) ;
862
863     
864   if(!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, packlen+10)))
865     return -1;
866
867   newpacket->lock = 1;
868
869   i = aim_putsnac(newpacket->data, 0x0002, 0x000f, 0x0000, 0);
870
871   /* 000a/0002: 0000 ?? ?privacy? */
872   i += aim_puttlv_16(newpacket->data+i, 0x000a, privacy); 
873
874   if(interest1) 
875     i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest1), interest1);
876   if(interest2) 
877     i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest2), interest2);
878   if(interest3) 
879     i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest3), interest3);
880   if(interest4) 
881     i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest4), interest4);
882   if(interest5) 
883     i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest1), interest5);
884
885   newpacket->commandlen = i;
886   newpacket->lock = 0;
887     
888   aim_tx_enqueue(sess, newpacket);
889     
890   return(sess->snac_nextid);
891 }
892
893 faim_export unsigned long aim_icq_setstatus(struct aim_session_t *sess,
894                                             struct aim_conn_t *conn, 
895                                             unsigned long status)
896 {
897   struct command_tx_struct *newpacket;
898   int i;
899   unsigned long data;
900   
901   data = 0x00030000 | status; /* yay for error checking ;^) */
902
903   if(!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10 + 4)))
904     return -1;
905
906   newpacket->lock = 1;
907
908   i = aim_putsnac(newpacket->data, 0x0001, 0x001e, 0x0000, 0x0000001e);
909   i += aim_puttlv_32(newpacket->data+i, 0x0006, data);
910
911   newpacket->commandlen = i;
912   newpacket->lock = 0;
913
914   aim_tx_enqueue(sess, newpacket);
915
916   return(sess->snac_nextid);
917 }
This page took 0.274926 seconds and 5 git commands to generate.