]> andersk Git - libfaim.git/blob - aim_misc.c
- Wed Dec 13 02:26:39 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
461   i += aimutil_put16(newpacket->data+i, 0x0001);
462   i += aimutil_put16(newpacket->data+i, 0x0003);
463
464   i += aimutil_put16(newpacket->data+i, 0x0002);
465   i += aimutil_put16(newpacket->data+i, 0x0001);
466
467   i += aimutil_put16(newpacket->data+i, 0x0003);
468   i += aimutil_put16(newpacket->data+i, 0x0001);
469
470   i += aimutil_put16(newpacket->data+i, 0x0004);
471   i += aimutil_put16(newpacket->data+i, 0x0001);
472
473   i += aimutil_put16(newpacket->data+i, 0x0006);
474   i += aimutil_put16(newpacket->data+i, 0x0001);
475
476   i += aimutil_put16(newpacket->data+i, 0x0008);
477   i += aimutil_put16(newpacket->data+i, 0x0001);
478
479   i += aimutil_put16(newpacket->data+i, 0x0009);
480   i += aimutil_put16(newpacket->data+i, 0x0001);
481
482   i += aimutil_put16(newpacket->data+i, 0x000a);
483   i += aimutil_put16(newpacket->data+i, 0x0001);
484
485   i += aimutil_put16(newpacket->data+i, 0x000b);
486   i += aimutil_put16(newpacket->data+i, 0x0002);
487
488   i += aimutil_put16(newpacket->data+i, 0x000c);
489   i += aimutil_put16(newpacket->data+i, 0x0001);
490
491   i += aimutil_put16(newpacket->data+i, 0x0013);
492   i += aimutil_put16(newpacket->data+i, 0x0001);
493
494   i += aimutil_put16(newpacket->data+i, 0x0015);
495   i += aimutil_put16(newpacket->data+i, 0x0001);
496
497 #if 0
498   for (j = 0; j < 0x10; j++) {
499     i += aimutil_put16(newpacket->data+i, j); /* family */
500     i += aimutil_put16(newpacket->data+i, 0x0003); /* version */
501   }
502 #endif
503
504   newpacket->commandlen = i;
505   newpacket->lock = 0;
506   aim_tx_enqueue(sess, newpacket);
507
508   return (sess->snac_nextid++);
509 }
510
511
512 /*
513  * aim_bos_reqservice(serviceid)
514  *
515  * Service request. 
516  *
517  */
518 faim_export unsigned long aim_bos_reqservice(struct aim_session_t *sess,
519                           struct aim_conn_t *conn, 
520                           u_short serviceid)
521 {
522   return aim_genericreq_s(sess, conn, 0x0001, 0x0004, &serviceid);
523 }
524
525 /*
526  * aim_bos_nop()
527  *
528  * No-op.  WinAIM sends these every 4min or so to keep
529  * the connection alive.  Its not real necessary.
530  *
531  */
532 faim_export unsigned long aim_bos_nop(struct aim_session_t *sess,
533                                       struct aim_conn_t *conn)
534 {
535   return aim_genericreq_n(sess, conn, 0x0001, 0x0016);
536 }
537
538 /*
539  * aim_flap_nop()
540  *
541  * No-op.  WinAIM 4.x sends these _every minute_ to keep
542  * the connection alive.  
543  */
544 faim_export unsigned long aim_flap_nop(struct aim_session_t *sess,
545                                        struct aim_conn_t *conn)
546 {
547   struct command_tx_struct *newpacket;
548
549   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0005, conn, 0)))
550     return sess->snac_nextid;
551
552   newpacket->lock = 1;
553   newpacket->commandlen = 0;
554   newpacket->lock = 0;
555
556   aim_tx_enqueue(sess, newpacket);
557
558   return (sess->snac_nextid);
559 }
560
561 /*
562  * aim_bos_reqrights()
563  *
564  * Request BOS rights.
565  *
566  */
567 faim_export unsigned long aim_bos_reqrights(struct aim_session_t *sess,
568                                             struct aim_conn_t *conn)
569 {
570   return aim_genericreq_n(sess, conn, 0x0009, 0x0002);
571 }
572
573 /*
574  * aim_bos_reqbuddyrights()
575  *
576  * Request Buddy List rights.
577  *
578  */
579 faim_export unsigned long aim_bos_reqbuddyrights(struct aim_session_t *sess,
580                                                  struct aim_conn_t *conn)
581 {
582   return aim_genericreq_n(sess, conn, 0x0003, 0x0002);
583 }
584
585 /*
586  * aim_send_warning(struct aim_session_t *sess, 
587  *                  struct aim_conn_t *conn, char *destsn, int anon)
588  * send a warning to destsn.
589  * anon is anonymous or not;
590  *  AIM_WARN_ANON anonymous
591  *
592  * returns -1 on error (couldn't alloc packet), next snacid on success.
593  *
594  */
595 faim_export int aim_send_warning(struct aim_session_t *sess, struct aim_conn_t *conn, char *destsn, int anon)
596 {
597   struct command_tx_struct *newpacket;
598   int curbyte;
599
600   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, strlen(destsn)+13)))
601     return -1;
602
603   newpacket->lock = 1;
604
605   curbyte  = 0;
606   curbyte += aim_putsnac(newpacket->data+curbyte,
607                         0x0004, 0x0008, 0x0000, sess->snac_nextid);
608
609   curbyte += aimutil_put16(newpacket->data+curbyte, (anon & AIM_WARN_ANON)?1:0);
610
611   curbyte += aimutil_put8(newpacket->data+curbyte, strlen(destsn));
612
613   curbyte += aimutil_putstr(newpacket->data+curbyte, destsn, strlen(destsn));
614
615   newpacket->commandlen = curbyte;
616   newpacket->lock = 0;
617
618   aim_tx_enqueue(sess, newpacket);
619
620   return (sess->snac_nextid++);
621 }
622
623 /*
624  * aim_debugconn_sendconnect()
625  *
626  * For aimdebugd.  If you don't know what it is, you don't want to.
627  */
628 faim_export unsigned long aim_debugconn_sendconnect(struct aim_session_t *sess,
629                                                     struct aim_conn_t *conn)
630 {
631   return aim_genericreq_n(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_DEBUGCONN_CONNECT);
632 }
633
634 /*
635  * Generic routine for sending commands.
636  *
637  *
638  * I know I can do this in a smarter way...but I'm not thinking straight
639  * right now...
640  *
641  * I had one big function that handled all three cases, but then it broke
642  * and I split it up into three.  But then I fixed it.  I just never went
643  * back to the single.  I don't see any advantage to doing it either way.
644  *
645  */
646 faim_internal unsigned long aim_genericreq_n(struct aim_session_t *sess,
647                                              struct aim_conn_t *conn, 
648                                              u_short family, u_short subtype)
649 {
650   struct command_tx_struct *newpacket;
651
652   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10)))
653     return 0;
654
655   newpacket->lock = 1;
656
657   aim_putsnac(newpacket->data, family, subtype, 0x0000, sess->snac_nextid);
658  
659   aim_tx_enqueue(sess, newpacket);
660   return (sess->snac_nextid++);
661 }
662
663 /*
664  *
665  *
666  */
667 faim_internal unsigned long aim_genericreq_l(struct aim_session_t *sess,
668                                              struct aim_conn_t *conn, 
669                                              u_short family, u_short subtype, 
670                                              u_long *longdata)
671 {
672   struct command_tx_struct *newpacket;
673   u_long newlong;
674
675   /* If we don't have data, there's no reason to use this function */
676   if (!longdata)
677     return aim_genericreq_n(sess, conn, family, subtype);
678
679   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10+sizeof(u_long))))
680     return -1;
681
682   newpacket->lock = 1;
683
684   aim_putsnac(newpacket->data, family, subtype, 0x0000, sess->snac_nextid);
685
686   /* copy in data */
687   newlong = htonl(*longdata);
688   memcpy(&(newpacket->data[10]), &newlong, sizeof(u_long));
689
690   aim_tx_enqueue(sess, newpacket);
691   return (sess->snac_nextid++);
692 }
693
694 faim_internal unsigned long aim_genericreq_s(struct aim_session_t *sess,
695                                              struct aim_conn_t *conn, 
696                                              u_short family, u_short subtype, 
697                                              u_short *shortdata)
698 {
699   struct command_tx_struct *newpacket;
700   u_short newshort;
701
702   /* If we don't have data, there's no reason to use this function */
703   if (!shortdata)
704     return aim_genericreq_n(sess, conn, family, subtype);
705
706   if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10+sizeof(u_short))))
707     return -1;
708
709   newpacket->lock = 1;
710
711   aim_putsnac(newpacket->data, family, subtype, 0x0000, sess->snac_nextid);
712
713   /* copy in data */
714   newshort = htons(*shortdata);
715   memcpy(&(newpacket->data[10]), &newshort, sizeof(u_short));
716
717   aim_tx_enqueue(sess, newpacket);
718   return (sess->snac_nextid++);
719 }
720
721 /*
722  * aim_bos_reqlocaterights()
723  *
724  * Request Location services rights.
725  *
726  */
727 faim_export unsigned long aim_bos_reqlocaterights(struct aim_session_t *sess,
728                                                   struct aim_conn_t *conn)
729 {
730   return aim_genericreq_n(sess, conn, 0x0002, 0x0002);
731 }
732
733 /*
734 * aim_bos_reqicbmparaminfo()
735  *
736  * Request ICBM parameter information.
737  *
738  */
739 faim_export unsigned long aim_bos_reqicbmparaminfo(struct aim_session_t *sess,
740                                                    struct aim_conn_t *conn)
741 {
742   return aim_genericreq_n(sess, conn, 0x0004, 0x0004);
743 }
744
745 /*
746  * Add ICBM parameter? Huh?
747  */
748 faim_export unsigned long aim_addicbmparam(struct aim_session_t *sess,
749                                            struct aim_conn_t *conn)
750 {
751   struct command_tx_struct *newpacket;
752   int packlen = 10+16, i=0;
753
754   if(!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, packlen)))
755     return (sess->snac_nextid);
756   
757   newpacket->lock = 1;
758
759   i = aim_putsnac(newpacket->data, 0x0004, 0x0002, 0x0000, sess->snac_nextid);
760   i += aimutil_put16(newpacket->data+i, 0x0000); 
761   i += aimutil_put16(newpacket->data+i, 0x0000);
762   i += aimutil_put16(newpacket->data+i, 0x0003);
763   i += aimutil_put16(newpacket->data+i, 0x1f40);
764   i += aimutil_put16(newpacket->data+i, 0x03e7);
765   i += aimutil_put16(newpacket->data+i, 0x03e7);
766   i += aimutil_put16(newpacket->data+i, 0x0000); 
767   i += aimutil_put16(newpacket->data+i, 0x0000); 
768   
769   aim_tx_enqueue(sess, newpacket);
770
771   return (sess->snac_nextid);
772 }
773
774 /* 
775  * Set directory profile data (not the same as aim_bos_setprofile!)
776  */
777 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) 
778 {
779   struct command_tx_struct *newpacket;
780   int packlen = 0, i = 0;
781
782   packlen += 2+2+2;
783
784   if(first) /* TLV 0001 */
785     packlen += (strlen(first) + 4);
786   if(middle) 
787     packlen += (strlen(middle) + 4);
788   if(last)
789     packlen += (strlen(last) + 4);
790   if(maiden)
791     packlen += (strlen(maiden) + 4);
792   if(nickname)
793     packlen += (strlen(nickname) + 4);
794   if(street)
795     packlen += (strlen(street) + 4);
796   if(state)
797     packlen += (strlen(state) + 4);
798   if(city)
799     packlen += (strlen(city) + 4);
800   if(zip)
801     packlen += (strlen(zip) + 4);
802     
803   if(!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, packlen+10)))
804     return -1;
805
806   newpacket->lock = 1;
807
808   i = aim_putsnac(newpacket->data, 0x0002, 0x0009, 0x0000, 0);
809
810   /* 000a/0002: privacy: 1 to allow search/disp, 0 to disallow */
811   i += aim_puttlv_16(newpacket->data+i, 0x000a, privacy);
812
813
814   if (first)
815     i += aim_puttlv_str(newpacket->data+i, 0x0001, strlen(first), first);
816   if (middle)
817     i += aim_puttlv_str(newpacket->data+i, 0x0003, strlen(middle), middle);
818   if (last)
819     i += aim_puttlv_str(newpacket->data+i, 0x0002, strlen(last), last);
820   if (maiden)
821     i += aim_puttlv_str(newpacket->data+i, 0x0004, strlen(maiden), maiden);
822   if (nickname)
823     i += aim_puttlv_str(newpacket->data+i, 0x000c, strlen(nickname), nickname);
824   if (street)
825     i += aim_puttlv_str(newpacket->data+i, 0x0021, strlen(street), street);
826   if (city)
827     i += aim_puttlv_str(newpacket->data+i, 0x0008, strlen(city), city);
828   if (state)
829     i += aim_puttlv_str(newpacket->data+i, 0x0007, strlen(state), state);
830   if (zip)
831     i += aim_puttlv_str(newpacket->data+i, 0x000d, strlen(zip), zip);
832
833   newpacket->commandlen = i;
834   newpacket->lock = 0;
835
836   aim_tx_enqueue(sess, newpacket);
837    
838   return(sess->snac_nextid);
839 }
840
841 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)
842 {
843   struct command_tx_struct *newpacket;
844   int packlen = 0, i = 0;
845
846   packlen += 2+2+2;
847
848   if(interest1)
849     packlen += (strlen(interest1) + 4);
850   if(interest2)
851     packlen += (strlen(interest2) + 4);
852   if(interest3)
853     packlen += (strlen(interest3) + 4);
854   if(interest4)
855     packlen += (strlen(interest4) + 4);
856   if(interest5)
857     packlen += (strlen(interest5) + 4) ;
858
859     
860   if(!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, packlen+10)))
861     return -1;
862
863   newpacket->lock = 1;
864
865   i = aim_putsnac(newpacket->data, 0x0002, 0x000f, 0x0000, 0);
866
867   /* 000a/0002: 0000 ?? ?privacy? */
868   i += aim_puttlv_16(newpacket->data+i, 0x000a, privacy); 
869
870   if(interest1) 
871     i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest1), interest1);
872   if(interest2) 
873     i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest2), interest2);
874   if(interest3) 
875     i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest3), interest3);
876   if(interest4) 
877     i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest4), interest4);
878   if(interest5) 
879     i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest1), interest5);
880
881   newpacket->commandlen = i;
882   newpacket->lock = 0;
883     
884   aim_tx_enqueue(sess, newpacket);
885     
886   return(sess->snac_nextid);
887 }
888
889 faim_export unsigned long aim_icq_setstatus(struct aim_session_t *sess,
890                                             struct aim_conn_t *conn, 
891                                             unsigned long status)
892 {
893   struct command_tx_struct *newpacket;
894   int i;
895   unsigned long data;
896   
897   data = 0x00030000 | status; /* yay for error checking ;^) */
898
899   if(!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10 + 4)))
900     return -1;
901
902   newpacket->lock = 1;
903
904   i = aim_putsnac(newpacket->data, 0x0001, 0x001e, 0x0000, 0x0000001e);
905   i += aim_puttlv_32(newpacket->data+i, 0x0006, data);
906
907   newpacket->commandlen = i;
908   newpacket->lock = 0;
909
910   aim_tx_enqueue(sess, newpacket);
911
912   return(sess->snac_nextid);
913 }
This page took 0.122631 seconds and 5 git commands to generate.