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