]> andersk Git - libfaim.git/blob - utils/faimtest/faimtest.c
- Sun Jul 16 11:03:28 GMT 2000
[libfaim.git] / utils / faimtest / faimtest.c
1 /* 
2  *  -----------------------------------------------------------
3  *  ProtoFAIM: v1.xx.xxplxx
4  *  -----------------------------------------------------------
5  *
6  *  This is ProtoFAIM v1.xx.xxplxx!!! Its nearly completely 
7  *  different than that ugly thing called v0.  This app is
8  *  compatible with the latest version of the libfaim library.
9  *  Work is continuing. 
10  *
11  *  ProtoFAIM should only be used for two things...
12  *   1) Testing the libfaim backend.
13  *   2) For reference on the libfaim API when developing clients.
14  * 
15  *  Its very ugly.  Probably always will be.  Nothing is more
16  *  ugly than the backend itself, however.
17  *
18  *  -----------------------------------------------------------
19  *
20  *  I'm releasing this code and all it's associated linkage
21  *  under the GNU General Public License.  For more information,
22  *  please refer to http://www.fsf.org.  For any questions,
23  *  please contact me at the address below.
24  *
25  *  Most everything:
26  *  (c) 1998 Adam Fritzler, PST, afritz@iname.com
27  *
28  *  The password algorithms
29  *  (c) 1998 Brock Wilcox, awwaiid@iname.com
30  *
31  *  THERE IS NO CODE FROM AOL'S AIM IN THIS CODE, NOR
32  *  WAS THERE ANY DISASSEMBLAGE TO DEFINE PROTOCOL.  All
33  *  information was gained through painstakingly comparing
34  *  TCP dumps while the AIM Java client was running.  Nothing
35  *  more than that, except for a lot of experimenting.
36  *
37  *  -----------------------------------------------------------
38  *
39  */
40
41 /*
42   Current status:
43
44
45  */
46
47 #include <faim/aim.h> 
48
49 int faimtest_parse_oncoming(struct aim_session_t *, struct command_rx_struct *, ...);
50 int faimtest_parse_offgoing(struct aim_session_t *, struct command_rx_struct *, ...);
51 int faimtest_parse_login_phase3d_f(struct aim_session_t *, struct command_rx_struct *, ...);
52 int faimtest_parse_authresp(struct aim_session_t *, struct command_rx_struct *, ...);
53 int faimtest_parse_incoming_im(struct aim_session_t *, struct command_rx_struct *command, ...);
54 int faimtest_parse_userinfo(struct aim_session_t *, struct command_rx_struct *command, ...);
55 int faimtest_handleredirect(struct aim_session_t *, struct command_rx_struct *command, ...);
56 int faimtest_authsvrready(struct aim_session_t *, struct command_rx_struct *command, ...);
57 int faimtest_pwdchngdone(struct aim_session_t *, struct command_rx_struct *command, ...);
58 int faimtest_serverready(struct aim_session_t *, struct command_rx_struct *command, ...);
59 int faimtest_parse_misses(struct aim_session_t *, struct command_rx_struct *command, ...);
60 int faimtest_parse_motd(struct aim_session_t *, struct command_rx_struct *command, ...);
61 int faimtest_parse_login(struct aim_session_t *, struct command_rx_struct *command, ...);
62 int faimtest_chatnav_info(struct aim_session_t *, struct command_rx_struct *command, ...);
63 int faimtest_chat_incomingmsg(struct aim_session_t *sess, struct command_rx_struct *command, ...);
64 int faimtest_chat_infoupdate(struct aim_session_t *sess, struct command_rx_struct *command, ...);
65 int faimtest_chat_leave(struct aim_session_t *sess, struct command_rx_struct *command, ...);
66 int faimtest_chat_join(struct aim_session_t *sess, struct command_rx_struct *command, ...);
67 int faimtest_parse_connerr(struct aim_session_t *sess, struct command_rx_struct *command, ...);
68 int faimtest_debugconn_connect(struct aim_session_t *sess, struct command_rx_struct *command, ...);
69
70 int faimtest_directim_request(struct aim_session_t *sess, struct command_rx_struct *command, ...);
71 int faimtest_directim_initiate(struct aim_session_t *sess, struct command_rx_struct *command, ...);
72 int faimtest_directim_connect(struct aim_session_t *sess, struct command_rx_struct *command, ...);
73 int faimtest_directim_incoming(struct aim_session_t *sess, struct command_rx_struct *command, ...);
74 int faimtest_directim_disconnect(struct aim_session_t *sess, struct command_rx_struct *command, ...);
75 int faimtest_directim_typing(struct aim_session_t *sess, struct command_rx_struct *command, ...);
76
77 int faimtest_reportinterval(struct aim_session_t *sess, struct command_rx_struct *command, ...)
78 {
79   if (command->data) {
80     printf("aim: minimum report interval: %d (seconds?)\n", aimutil_get16(command->data+10));
81   } else
82     printf("aim: NULL minimum report interval!\n");
83   return 1;
84 }
85
86 static char *screenname,*password,*server=NULL;
87
88 int main(void)
89 {
90   struct aim_session_t aimsess;
91   struct aim_conn_t *authconn = NULL, *waitingconn = NULL;
92   int keepgoing = 1;
93
94   struct client_info_s info = {"FAIMtest (Hi guys!)", 4, 3, 3141, "us", "en", 0x0004, 0x0001, 0x00000055};
95
96   int selstat = 0;
97
98   if ( !(screenname = getenv("SCREENNAME")) ||
99        !(password = getenv("PASSWORD")))
100     {
101       printf("Must specify SCREENAME and PASSWORD in environment.\n");
102       return -1;
103     }
104
105   server = getenv("AUTHSERVER");
106
107   aim_session_init(&aimsess);
108
109   authconn = aim_newconn(&aimsess, AIM_CONN_TYPE_AUTH, server?server:FAIM_LOGIN_SERVER);
110
111   if (authconn == NULL) {
112     fprintf(stderr, "faimtest: internal connection error while in aim_login.  bailing out.\n");
113     return -1;
114   } else if (authconn->fd == -1) {
115     if (authconn->status & AIM_CONN_STATUS_RESOLVERR)
116       fprintf(stderr, "faimtest: could not resolve authorizer name\n");
117     else if (authconn->status & AIM_CONN_STATUS_CONNERR)
118       fprintf(stderr, "faimtest: could not connect to authorizer\n");
119     aim_conn_kill(&aimsess, &authconn);
120     return -1;
121   }
122 #ifdef SNACLOGIN
123   /* new login code -- not default -- pending new password encryption algo */
124   aim_conn_addhandler(&aimsess, authconn, 0x0017, 0x0007, faimtest_parse_login, 0);
125   aim_conn_addhandler(&aimsess, authconn, 0x0017, 0x0003, faimtest_parse_authresp, 0);
126     
127   aim_sendconnack(&aimsess, authconn);
128   aim_request_login(&aimsess, authconn, FAIMTEST_SCREENNAME);
129 #else
130   aim_conn_addhandler(&aimsess, authconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_AUTHSUCCESS, faimtest_parse_authresp, 0);
131   aim_conn_addhandler(&aimsess, authconn, AIM_CB_FAM_GEN, AIM_CB_GEN_SERVERREADY, faimtest_authsvrready, 0);
132   aim_send_login(&aimsess, authconn, screenname, password, &info);
133 #endif
134   aim_conn_addhandler(&aimsess, authconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_DEBUGCONN_CONNECT, faimtest_debugconn_connect, 0);
135   printf("faimtest: login sent\n");
136
137   while (keepgoing) {
138     waitingconn = aim_select(&aimsess, NULL, &selstat);
139
140     switch(selstat) {
141     case -1: /* error */
142       keepgoing = 0; /* fall through and hit the aim_logoff() */
143       break;
144
145     case 0: /* no events pending */
146       break;
147
148     case 1: /* outgoing data pending */
149       aim_tx_flushqueue(&aimsess);
150       break;
151
152     case 2: /* incoming data pending */
153       if (waitingconn->type == AIM_CONN_TYPE_RENDEZVOUS_OUT) {
154         if (aim_handlerendconnect(&aimsess, waitingconn) < 0) {
155           printf("connection error (rend)\n");
156         }
157       } else {
158         if (aim_get_command(&aimsess, waitingconn) >= 0) {
159           aim_rxdispatch(&aimsess);
160         } else {
161           printf("connection error\n");
162           if (!aim_getconn_type(&aimsess, AIM_CONN_TYPE_BOS)) {
163             printf("major connetion error\n");
164             keepgoing = 0;
165           }
166         }
167       }
168       break;
169       
170     default:
171       break; /* invalid */
172     }
173   }
174
175   /* Close up */
176   printf("AIM just decided we didn't need to be here anymore, closing up...\n");
177   
178   /* close up all connections, dead or no */
179   aim_logoff(&aimsess); 
180
181   /* Get out */
182   exit(0);
183 }
184
185 int faimtest_serverready(struct aim_session_t *sess, struct command_rx_struct *command, ...)
186 {
187   switch (command->conn->type)
188     {
189     case AIM_CONN_TYPE_BOS:
190
191       aim_bos_reqrate(sess, command->conn); /* request rate info */
192       aim_bos_ackrateresp(sess, command->conn);  /* ack rate info response -- can we say timing? */
193       aim_bos_setprivacyflags(sess, command->conn, 0x00000003);
194       
195 #if 0
196       aim_bos_reqpersonalinfo(sess, command->conn);
197 #endif
198       
199       /* Request advertisement service -- see comment in handleredirect */
200       aim_bos_reqservice(sess, command->conn, AIM_CONN_TYPE_ADS);
201       aim_setversions(sess, command->conn);
202
203 #if 0
204       aim_bos_reqrights(sess, command->conn);
205       aim_bos_reqbuddyrights(sess, command->conn);
206       aim_bos_reqlocaterights(sess, command->conn);
207       aim_bos_reqicbmparaminfo(sess, command->conn);
208 #endif
209       
210       /* set group permissions */
211       aim_bos_setgroupperm(sess, command->conn, 0x1f);
212       fprintf(stderr, "faimtest: done with BOS ServerReady\n");
213       break;
214
215     case AIM_CONN_TYPE_CHATNAV:
216       fprintf(stderr, "faimtest: chatnav: got server ready\n");
217       aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CTN, AIM_CB_CTN_INFO, faimtest_chatnav_info, 0);
218       aim_bos_reqrate(sess, command->conn);
219       aim_bos_ackrateresp(sess, command->conn);
220       aim_chatnav_clientready(sess, command->conn);
221       aim_chatnav_reqrights(sess, command->conn);
222
223       break;
224     case AIM_CONN_TYPE_CHAT:
225       aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_USERJOIN, faimtest_chat_join, 0);
226       aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_USERLEAVE, faimtest_chat_leave, 0);
227       aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_ROOMINFOUPDATE, faimtest_chat_infoupdate, 0);
228       aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_INCOMINGMSG, faimtest_chat_incomingmsg, 0);
229       aim_bos_reqrate(sess, command->conn);
230       aim_bos_ackrateresp(sess, command->conn);
231       aim_chat_clientready(sess, command->conn);
232       break;
233
234     case AIM_CONN_TYPE_RENDEZVOUS: /* this is an overloaded function?? - mid */
235       aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, faimtest_directim_incoming, 0);
236       aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMDISCONNECT, faimtest_directim_disconnect, 0);
237       break;
238
239     default:
240       fprintf(stderr, "faimtest: unknown connection type on Server Ready\n");
241     }
242   return 1;
243 }
244
245 /*
246   handleredirect()...
247
248   This, of course, handles Service Redirects from OSCAR.
249
250   Should get passed in the following:
251      struct command_rx_struct *command
252        the raw command data
253      int serviceid
254        the destination service ID
255      char *serverip
256        the IP address of the service's server
257      char *cookie
258        the raw auth cookie
259  */
260 int faimtest_handleredirect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
261 {
262   va_list ap;
263   int serviceid;
264   char *ip;
265   char *cookie;
266
267   /* this is the new buddy list */
268   char buddies[] = "Buddy1&Buddy2&ThisHereIsAName2&";
269   /* this is the new profile */
270   char profile[] = "Hello";  
271
272   va_start(ap, command);
273   serviceid = va_arg(ap, int);
274   ip = va_arg(ap, char *);
275   cookie = va_arg(ap, char *);
276  
277   switch(serviceid)
278     {
279     case 0x0005: /* Advertisements */
280       /*
281        * The craziest explanation yet as to why we finish logging in when
282        * we get the advertisements redirect, of which we don't use anyway....
283        *                    IT WAS EASY!
284        */
285
286       /* send the buddy list and profile (required, even if empty) */
287       aim_bos_setbuddylist(sess, command->conn, buddies);
288       aim_bos_setprofile(sess, command->conn, profile, NULL, AIM_CAPS_BUDDYICON | AIM_CAPS_CHAT | AIM_CAPS_VOICE | AIM_CAPS_GETFILE | AIM_CAPS_SENDFILE | AIM_CAPS_IMIMAGE);
289
290       /* send final login command (required) */
291       aim_bos_clientready(sess, command->conn); /* tell BOS we're ready to go live */
292
293       /* you should now be ready to go */
294       printf("\nYou are now officially online.\n");      
295
296       break;
297     case 0x0007: /* Authorizer */
298       {
299         struct aim_conn_t *tstconn;
300         /* Open a connection to the Auth */
301         tstconn = aim_newconn(sess, AIM_CONN_TYPE_AUTH, ip);
302         if ( (tstconn==NULL) || (tstconn->status >= AIM_CONN_STATUS_RESOLVERR) )
303           fprintf(stderr, "faimtest: unable to reconnect with authorizer\n");
304         else
305           /* Send the cookie to the Auth */
306           aim_auth_sendcookie(sess, tstconn, cookie);
307
308       }  
309       break;
310     case 0x000d: /* ChatNav */
311       {
312         struct aim_conn_t *tstconn = NULL;
313         tstconn = aim_newconn(sess, AIM_CONN_TYPE_CHATNAV, ip);
314         if ( (tstconn==NULL) || (tstconn->status >= AIM_CONN_STATUS_RESOLVERR)) {
315           fprintf(stderr, "faimtest: unable to connect to chatnav server\n");
316           if (tstconn) aim_conn_kill(sess, &tstconn);
317           return 1;
318         }
319 #if 0
320         aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_CTN, AIM_CB_SPECIAL_DEFAULT, aim_parse_unknown, 0);
321         aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_GEN, AIM_CB_SPECIAL_DEFAULT, aim_parse_unknown, 0);
322 #endif
323         aim_conn_addhandler(sess, tstconn, 0x0001, 0x0003, faimtest_serverready, 0);
324         aim_auth_sendcookie(sess, tstconn, cookie);
325         fprintf(stderr, "\achatnav: connected\n");
326       }
327       break;
328     case 0x000e: /* Chat */
329       {
330         char *roomname = NULL;
331         struct aim_conn_t *tstconn = NULL;
332
333         roomname = va_arg(ap, char *);
334
335         tstconn = aim_newconn(sess, AIM_CONN_TYPE_CHAT, ip);
336         if ( (tstconn==NULL) || (tstconn->status >= AIM_CONN_STATUS_RESOLVERR))
337           {
338             fprintf(stderr, "faimtest: unable to connect to chat server\n");
339             if (tstconn) aim_conn_kill(sess, &tstconn);
340             return 1;
341           }             
342         printf("faimtest: chat: connected\n");
343
344         /*
345          * We must do this to attach the stored name to the connection!
346          */
347         aim_chat_attachname(tstconn, roomname);
348
349         aim_conn_addhandler(sess, tstconn, 0x0001, 0x0003, faimtest_serverready, 0);
350         aim_auth_sendcookie(sess, tstconn, cookie);
351       }
352       break;
353     default:
354       printf("uh oh... got redirect for unknown service 0x%04x!!\n", serviceid);
355       /* dunno */
356     }
357
358   va_end(ap);
359
360   return 1;
361 }
362
363 int faimtest_parse_authresp(struct aim_session_t *sess, struct command_rx_struct *command, ...)
364 {
365   struct aim_conn_t *bosconn = NULL;
366   
367
368   printf("Screen name: %s\n", sess->logininfo.screen_name);
369
370   /*
371    * Check for error.
372    */
373   if (sess->logininfo.errorcode)
374     {
375       printf("Login Error Code 0x%04x\n", sess->logininfo.errorcode);
376       printf("Error URL: %s\n", sess->logininfo.errorurl);
377       aim_conn_kill(sess, &command->conn);
378       exit(0); /* XXX: should return in order to let the above things get free()'d. */
379     }
380
381   printf("Reg status: %2d\n", sess->logininfo.regstatus);
382   printf("Email: %s\n", sess->logininfo.email);
383   printf("BOS IP: %s\n", sess->logininfo.BOSIP);
384
385   printf("Closing auth connection...\n");
386   aim_conn_kill(sess, &command->conn);
387   bosconn = aim_newconn(sess, AIM_CONN_TYPE_BOS, sess->logininfo.BOSIP);
388   if (bosconn == NULL) {
389     fprintf(stderr, "faimtest: could not connect to BOS: internal error\n");
390   } else if (bosconn->status != 0) {    
391     fprintf(stderr, "faimtest: could not connect to BOS\n");
392     aim_conn_kill(sess, &bosconn);
393   } else {
394     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ACK, AIM_CB_ACK_ACK, NULL, 0);
395     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_SERVERREADY, faimtest_serverready, 0);
396     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_RATEINFO, NULL, 0);
397     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_REDIRECT, faimtest_handleredirect, 0);
398     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_STS, AIM_CB_STS_SETREPORTINTERVAL, faimtest_reportinterval, 0);
399     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_ONCOMING, faimtest_parse_oncoming, 0);
400     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_OFFGOING, faimtest_parse_offgoing, 0);
401     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_INCOMING, faimtest_parse_incoming_im, 0);
402     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_ERROR, faimtest_parse_misses, 0);
403     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_MISSEDCALL, faimtest_parse_misses, 0);
404     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_RATECHANGE, faimtest_parse_misses, 0);
405     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ERROR, faimtest_parse_misses, 0);
406     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO, faimtest_parse_userinfo, 0);
407     
408     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_CTN, AIM_CB_CTN_DEFAULT, aim_parse_unknown, 0);
409     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_DEFAULT, aim_parse_unknown, 0);
410     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_MOTD, faimtest_parse_motd, 0);
411     
412     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, faimtest_parse_connerr, 0);
413     
414     aim_auth_sendcookie(sess, bosconn, sess->logininfo.cookie);
415   }
416   return 1;
417 }
418
419 int faimtest_parse_userinfo(struct aim_session_t *sess, struct command_rx_struct *command, ...)
420 {
421   struct aim_userinfo_s *userinfo;
422   char *prof_encoding = NULL;
423   char *prof = NULL;
424   unsigned short inforeq = 0;
425
426   va_list ap;
427   va_start(ap, command);
428   userinfo = va_arg(ap, struct aim_userinfo_s *);
429   prof_encoding = va_arg(ap, char *);
430   prof = va_arg(ap, char *);
431   inforeq = va_arg(ap, unsigned short);
432   va_end(ap);
433   
434   printf("faimtest: userinfo: sn: %s\n", userinfo->sn);
435   printf("faimtest: userinfo: warnlevel: 0x%04x\n", userinfo->warnlevel);
436   printf("faimtest: userinfo: class: 0x%04x = ", userinfo->class);
437
438   /*
439    *  00000000  (binary)
440    *         1  Trial  
441    *        2   Unknown
442    *       3    AOL
443    *      4     Unknown
444    *     5      Free
445    * 
446    * ORed together.
447    *
448    */
449
450   if (userinfo->class & 0x0001)
451     printf("TRIAL ");
452   if (userinfo->class & 0x0002)
453     printf("UNKNOWN_BIT2 ");
454   if (userinfo->class & 0x0004)
455     printf("AOL ");
456   if (userinfo->class & 0x0008)
457     printf("UNKNOWN_BIT4 ");
458   if (userinfo->class & 0x0010)
459     printf("FREE ");
460   if (userinfo->class & 0x0040)
461     printf("ICQ? ");
462   printf("\n");
463   
464   printf("faimtest: userinfo: membersince: %lu\n", userinfo->membersince);
465   printf("faimtest: userinfo: onlinesince: %lu\n", userinfo->onlinesince);
466   printf("faimtest: userinfo: idletime: 0x%04x\n", userinfo->idletime);
467   
468   if (inforeq == AIM_GETINFO_GENERALINFO) {
469     printf("faimtest: userinfo: profile_encoding: %s\n", prof_encoding ? prof_encoding : "[none]");
470     printf("faimtest: userinfo: prof: %s\n", prof ? prof : "[none]");
471   } else if (inforeq == AIM_GETINFO_AWAYMESSAGE) {
472     printf("faimtest: userinfo: awaymsg_encoding: %s\n", prof_encoding ? prof_encoding : "[none]");
473     printf("faimtest: userinfo: awaymsg: %s\n", prof ? prof : "[none]");
474   } else 
475     printf("faimtest: userinfo: unknown info request\n");
476   
477   return 1;
478 }
479
480 /*
481  * The user-level Incoming ICBM callback.
482  *
483  * Arguments:
484  *  struct command_rx_struct *  command     if you feel like doing it yourself
485  *  char *                      srcsn       the source name
486  *  char *                      msg         message
487  *  int                         warnlevel   warning/evil level
488  *  int                         class       user class
489  *  ulong                       membersince time_t of date of signup
490  *  ulong                       onsince     time_t of date of singon
491  *  int                         idletime    min (sec?) idle
492  *  u_int                       icbmflags   sets AIM_IMFLAGS_{AWAY,ACK}
493  *
494  */
495 int faimtest_parse_incoming_im(struct aim_session_t *sess, struct command_rx_struct *command, ...)
496 {
497   int channel;
498   va_list ap;
499
500   va_start(ap, command);
501   channel = va_arg(ap, int);
502
503   /*
504    * Channel 1: Standard Message
505    */
506   if (channel == 1) {
507     struct aim_userinfo_s *userinfo;
508     char *msg = NULL;
509     u_int icbmflags = 0;
510     char *tmpstr = NULL;
511     u_short flag1, flag2;
512     
513     userinfo = va_arg(ap, struct aim_userinfo_s *);
514     msg = va_arg(ap, char *);
515     icbmflags = va_arg(ap, u_int);
516     flag1 = va_arg(ap, u_short);
517     flag2 = va_arg(ap, u_short);
518     va_end(ap);
519     
520     printf("faimtest: icbm: sn = \"%s\"\n", userinfo->sn);
521     printf("faimtest: icbm: warnlevel = 0x%04x\n", userinfo->warnlevel);
522     printf("faimtest: icbm: class = 0x%04x ", userinfo->class);
523     if (userinfo->class & 0x0010)
524       printf("(FREE) ");
525     if (userinfo->class & 0x0001)
526       printf("(TRIAL) ");
527     if (userinfo->class & 0x0004)
528       printf("(AOL) ");
529     printf("\n");
530     printf("faimtest: icbm: membersince = %lu\n", userinfo->membersince);
531     printf("faimtest: icbm: onlinesince = %lu\n", userinfo->onlinesince);
532     printf("faimtest: icbm: idletime = 0x%04x\n", userinfo->idletime);
533     printf("faimtest: icbm: capabilities = 0x%04x\n", userinfo->capabilities);
534     
535     printf("faimtest: icbm: icbmflags = ");
536     if (icbmflags & AIM_IMFLAGS_AWAY)
537       printf("away ");
538     if (icbmflags & AIM_IMFLAGS_ACK)
539       printf("ackrequest ");
540     printf("\n");
541     
542     printf("faimtest: icbm: encoding flags = {%04x, %04x}\n", flag1, flag2);
543     
544     printf("faimtest: icbm: message: %s\n", msg);
545     
546     if (msg) {
547       int i = 0;
548
549       while (msg[i] == '<') {
550         if (msg[i] == '<') {
551           while (msg[i] != '>')
552             i++;
553           i++;
554         }
555       }
556       tmpstr = msg+i;
557
558       printf("tmpstr = %s\n", tmpstr);
559       
560       if ( (strlen(tmpstr) >= 10) &&
561            (!strncmp(tmpstr, "disconnect", 10)) ) {
562           aim_send_im(sess, command->conn, "midendian", 0, "ta ta...");
563           aim_logoff(sess);
564       } else if (strstr(tmpstr, "goodday")) {
565         printf("faimtest: icbm: sending response\n");
566         aim_send_im(sess, command->conn, userinfo->sn, 0, "Good day to you too.");
567       } else if (!strncmp(tmpstr, "open chatnav", 12)) {
568         aim_bos_reqservice(sess, command->conn, AIM_CONN_TYPE_CHATNAV);
569         //aim_chat_join(sess, command->conn, "thishereisaname2_chat85");
570       } else if (!strncmp(tmpstr, "create", 6)) {
571         aim_chatnav_createroom(sess,aim_getconn_type(sess, AIM_CONN_TYPE_CHATNAV), (strlen(tmpstr) < 7)?"WorldDomination":tmpstr+7, 0x0004);
572       } else if (!strncmp(tmpstr, "close chatnav", 13)) {
573         struct aim_conn_t *chatnavconn;
574         chatnavconn = aim_getconn_type(sess, AIM_CONN_TYPE_CHATNAV);
575         aim_conn_kill(sess, &chatnavconn);
576       } else if (!strncmp(tmpstr, "join", 4)) {
577           aim_chat_join(sess, command->conn, 0x0004, "worlddomination");
578       } else if (!strncmp(tmpstr, "leave", 5))
579             aim_chat_leaveroom(sess, "worlddomination");
580       else if (!strncmp(tmpstr, "getinfo", 7)) {
581         aim_getinfo(sess, command->conn, "75784102", AIM_GETINFO_GENERALINFO);
582         aim_getinfo(sess, command->conn, "15853637", AIM_GETINFO_AWAYMESSAGE);
583       } else if (!strncmp(tmpstr, "open directim", 13)) {
584         struct aim_conn_t *newconn;
585         newconn = aim_directim_initiate(sess, command->conn, NULL, userinfo->sn);
586         //aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINITIATE, faimtest_directim_initiate, 0);
587       } else if (!strncmp(tmpstr, "sendmsg", 7)) {
588         int i;
589         i = atoi(tmpstr+8);
590         if (i < 10000) {
591           char *newbuf;
592           int z;
593
594           newbuf = malloc(i+1);
595           for (z = 0; z < i; z++) {
596             newbuf[z] = (z % 10)+0x30;
597           }
598           newbuf[i] = '\0';
599           aim_send_im(sess, command->conn, userinfo->sn, 0, newbuf);
600           free(newbuf);
601         }
602       } else {
603         printf("unknown command.\n");
604         aim_add_buddy(sess, command->conn, userinfo->sn);
605       }
606       
607     }
608   }
609   /*
610    * Channel 2: Rendevous Request
611    */
612   else if (channel == 2) {
613     struct aim_userinfo_s *userinfo;
614     unsigned short reqclass;
615     
616     reqclass = va_arg(ap, unsigned short);
617     switch (reqclass) {
618     case AIM_CAPS_VOICE: {
619       userinfo = va_arg(ap, struct aim_userinfo_s *);
620       va_end(ap);
621       
622       printf("faimtest: voice invitation: source sn = %s\n", userinfo->sn);
623       printf("faimtest: voice invitation: \twarnlevel = 0x%04x\n", userinfo->warnlevel);
624       printf("faimtest: voice invitation: \tclass = 0x%04x ", userinfo->class);
625       if (userinfo->class & 0x0010)
626         printf("(FREE) ");
627       if (userinfo->class & 0x0001)
628         printf("(TRIAL) ");
629       if (userinfo->class & 0x0004)
630         printf("(AOL) ");
631       printf("\n");
632       /* we dont get membersince on chat invites! */
633       printf("faimtest: voice invitation: \tonlinesince = %lu\n", userinfo->onlinesince);
634       printf("faimtest: voice invitation: \tidletime = 0x%04x\n", userinfo->idletime);
635       
636       break;
637     }
638     case AIM_CAPS_GETFILE: {
639       printf("faimtset: get file!\n");
640       break;
641     }
642     case AIM_CAPS_SENDFILE: {
643       printf("faimtest: send file!\n");
644       break;
645     }
646     case AIM_CAPS_CHAT: {
647       char *msg,*encoding,*lang;
648       struct aim_chat_roominfo *roominfo;
649       
650       userinfo = va_arg(ap, struct aim_userinfo_s *);
651       roominfo = va_arg(ap, struct aim_chat_roominfo *);
652       msg = va_arg(ap, char *);
653       encoding = va_arg(ap, char *);
654       lang = va_arg(ap, char *);
655       va_end(ap);
656       
657       printf("faimtest: chat invitation: source sn = %s\n", userinfo->sn);
658       printf("faimtest: chat invitation: \twarnlevel = 0x%04x\n", userinfo->warnlevel);
659       printf("faimtest: chat invitation: \tclass = 0x%04x ", userinfo->class);
660       if (userinfo->class & 0x0010)
661         printf("(FREE) ");
662       if (userinfo->class & 0x0001)
663         printf("(TRIAL) ");
664       if (userinfo->class & 0x0004)
665         printf("(AOL) ");
666       printf("\n");
667       /* we dont get membersince on chat invites! */
668       printf("faimtest: chat invitation: \tonlinesince = %lu\n", userinfo->onlinesince);
669       printf("faimtest: chat invitation: \tidletime = 0x%04x\n", userinfo->idletime);
670       
671       printf("faimtest: chat invitation: message = %s\n", msg);
672       printf("faimtest: chat invitation: room name = %s\n", roominfo->name);
673       printf("faimtest: chat invitation: encoding = %s\n", encoding);
674       printf("faimtest: chat invitation: language = %s\n", lang);
675       printf("faimtest: chat invitation: exchange = 0x%04x\n", roominfo->exchange);
676       printf("faimtest: chat invitation: instance = 0x%04x\n", roominfo->instance);
677       printf("faimtest: chat invitiation: autojoining %s...\n", roominfo->name);
678       /*
679        * Automatically join room...
680        */ 
681       aim_chat_join(sess, command->conn, 0x0004, roominfo->name);
682       break;
683     }   
684     case AIM_CAPS_IMIMAGE: {
685       struct aim_directim_priv *priv;
686       struct aim_conn_t *newconn;
687
688       printf("faimtest: icbm: rendezvous imimage\n");
689      
690       userinfo = va_arg(ap, struct aim_userinfo_s *);
691       priv = va_arg(ap, struct aim_directim_priv *);
692       va_end(ap);
693
694       printf("faimtest: OFT: DirectIM: request from %s (%s)\n", userinfo->sn, priv->ip);
695       
696       if (!(newconn = aim_directim_connect(sess, command->conn, priv))) {
697         printf("faimtest: icbm: imimage: could not connect\n");
698         break;
699       }
700       aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, faimtest_directim_incoming, 0);
701       aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMDISCONNECT, faimtest_directim_disconnect, 0);
702       aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, faimtest_directim_typing, 0);
703
704       aim_send_im_direct(sess, newconn, "goodday");
705
706       printf("faimtest: OFT: DirectIM: connected to %s\n", userinfo->sn);
707
708       break;
709     }
710     default:
711       printf("faimtest: icbm: unknown reqclass (%d)\n", reqclass);
712     } /* switch */
713   } else
714     printf("faimtest does not support channels > 2 (chan = %02x)\n", channel);
715   printf("faimtest: icbm: done with ICBM handling\n");
716
717   return 1;
718 }
719
720 #if 0
721 int faimtest_directim_initiate(struct aim_session_t *sess, struct command_rx_struct *command, ...)
722 {
723   va_list ap;
724   struct aim_directim_priv *priv;
725   struct aim_conn_t *newconn;
726
727   ap = va_start(ap, command);
728   newconn = va_arg(ap, struct aim_conn_t *);
729   va_end(ap);
730
731   priv = (struct aim_directim_priv *)newconn->priv;
732
733   printf("faimtest: OFT: DirectIM: intitiate success to %s\n", priv->ip);
734   
735   aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, faimtest_directim_incoming, 0);
736   aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMDISCONNECT, faimtest_directim_disconnect, 0);
737   aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, faimtest_directim_typing, 0);
738
739   aim_send_im_direct(sess, newconn, "goodday");
740
741   printf("faimtest: OFT: DirectIM: connected to %s\n", priv->sn);
742
743   return 1;
744 }
745 #endif
746
747 int faimtest_directim_connect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
748 {
749   va_list ap;
750   struct aim_directim_priv *priv;
751   
752   ap = va_start(ap, command);
753   priv = va_arg(ap, struct aim_directim_priv *);
754
755   va_end(ap);
756   
757   printf("faimtest: directim_connect\n");
758
759   return 1;
760 }
761
762 int faimtest_directim_incoming(struct aim_session_t *sess, struct command_rx_struct *command, ...)
763 {
764   va_list ap;
765   char *sn = NULL, *msg = NULL;
766   struct aim_conn_t *conn;
767
768   ap = va_start(ap, command);
769   conn = va_arg(ap, struct aim_conn_t *);
770   sn = va_arg(ap, char *);
771   msg = va_arg(ap, char *);
772   va_end(ap);
773
774   printf("faimtest: Directim from %s: %s\n", sn, msg);
775   if (!strncmp(msg, "sendmsg", 7)) {
776     int i;
777     i = atoi(msg+8);
778     if (i < 10000) {
779       char *newbuf;
780       int z;
781       
782       newbuf = malloc(i+1);
783       for (z = 0; z < i; z++) {
784         newbuf[z] = (z % 10)+0x30;
785       }
786       newbuf[i] = '\0';
787       aim_send_im_direct(sess, conn, newbuf);
788       free(newbuf);
789     }
790   } else if (!strncmp(msg, "goodday", 7)) {
791     aim_send_im_direct(sess, conn, "Good day to you, too");
792   } else {
793     char newmsg[1024];
794     snprintf(newmsg, sizeof(newmsg), "unknown (%s)\n", msg);
795     aim_send_im_direct(sess, conn, newmsg);
796   }
797   return 1;
798 }
799
800 int faimtest_directim_disconnect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
801 {
802   printf("faimtest: directim_disconnect\n");
803   return 1;
804 }
805
806 int faimtest_directim_typing(struct aim_session_t *sess, struct command_rx_struct *command, ...)
807 {
808   va_list ap;
809   char *sn;
810   
811   ap = va_start(ap, command);
812   sn = va_arg(ap, char *);
813   va_end(ap);
814
815   printf("faimtest: ohmigod! %s has started typing (DirectIM). He's going to send you a message! *squeal*\n", sn);
816   return 1;
817 }
818
819 int faimtest_authsvrready(struct aim_session_t *sess, struct command_rx_struct *command, ...)
820 {
821   printf("faimtest_authsvrready: called (contype: %d)\n", command->conn->type);
822   sleep(10);
823   /* should just be able to tell it we're ready too... */
824   aim_auth_clientready(sess, command->conn);
825
826 #if 0
827   /*
828    * This is where you'd really begin changing your password.
829    *   However, this callback may get called for reasons other
830    *   than you wanting to change your password.  You should 
831    *   probably check that before actually doing it.
832    */
833   aim_auth_changepasswd(sess, command->conn, "PWD1", "PWD2");
834 #endif
835
836   return 1;
837 }
838
839 int faimtest_pwdchngdone(struct aim_session_t *sess, struct command_rx_struct *command, ...)
840 {
841   printf("PASSWORD CHANGE SUCCESSFUL!!!\n");
842   return 1;
843 }
844
845 int faimtest_parse_oncoming(struct aim_session_t *sess, struct command_rx_struct *command, ...)
846 {
847   struct aim_userinfo_s *userinfo;
848    
849   va_list ap;
850   va_start(ap, command);
851   userinfo = va_arg(ap, struct aim_userinfo_s *);
852   va_end(ap);
853
854   printf("\n%s is now online (class: %04x = %s%s%s%s%s%s%s%s) (caps = 0x%04x)\n",
855          userinfo->sn, userinfo->class,
856          (userinfo->class&AIM_CLASS_TRIAL)?" TRIAL":"",
857          (userinfo->class&AIM_CLASS_UNKNOWN2)?" UNKNOWN2":"",
858          (userinfo->class&AIM_CLASS_AOL)?" AOL":"",
859          (userinfo->class&AIM_CLASS_UNKNOWN4)?" UNKNOWN4":"",
860          (userinfo->class&AIM_CLASS_FREE)?" FREE":"",
861          (userinfo->class&AIM_CLASS_AWAY)?" AWAY":"",
862          (userinfo->class&AIM_CLASS_UNKNOWN40)?" UNKNOWN40":"",
863          (userinfo->class&AIM_CLASS_UNKNOWN80)?" UNKNOWN80":"",
864          userinfo->capabilities);
865   return 1;
866 }
867
868 int faimtest_parse_offgoing(struct aim_session_t *sess, struct command_rx_struct *command, ...)
869 {
870   char *sn;
871   va_list ap;
872   
873   va_start(ap, command);
874   sn = va_arg(ap, char *);
875   va_end(ap);
876
877   printf("\n%s has left\n", sn);
878
879   return 1;
880 }
881
882 int faimtest_parse_motd(struct aim_session_t *sess, struct command_rx_struct *command, ...)
883 {
884   char *msg;
885   u_short id;
886   va_list ap;
887   
888   va_start(ap, command);
889   id = va_arg(ap, u_short);
890   msg = va_arg(ap, char *);
891   va_end(ap);
892
893   printf("faimtest: motd: %s\n", msg);
894
895   return 1;
896 }
897
898 /* 
899  * Handles callbacks for: AIM_CB_RATECHANGE, AIM_CB_USERERROR, 
900  *   AIM_CB_MISSED_IM, and AIM_CB_MISSED_CALL.
901  */
902 int faimtest_parse_misses(struct aim_session_t *sess, struct command_rx_struct *command, ...)
903 {
904   u_short family;
905   u_short subtype;
906
907   family = aimutil_get16(command->data+0);
908   subtype= aimutil_get16(command->data+2);
909   
910   switch (family)
911     {
912     case 0x0001:
913       if (subtype == 0x000a) /* or AIM_CB_RATECHANGE */
914         printf("\n****STOP SENDING/RECIEVING MESSAGES SO FAST!****\n\n");
915       break;
916     case 0x0002:
917       if (subtype == 0x0001) /* or AIM_CB_USERERROR */
918         {
919           u_long snacid = 0x00000000;
920           
921           snacid = aimutil_get32(&command->data[6]);
922           
923           printf("Received unknown error in SNAC family 0x0002 (snacid = %08lx)\n", snacid);
924         }
925       break;
926     case 0x0004:
927       if (subtype == 0x0001) /* or AIM_CB_MISSED_IM */
928         printf("\n***LAST IM DIDN\'T MAKE IT BECAUSE THE BUDDY IS NOT ONLINE***\n\n");
929       else if (subtype == 0x000a) /* or AIM_CB_MISSED_CALL */
930         printf("You missed some messages from %s because they were sent too fast\n", &(command->data[13]));
931       break;
932     }
933
934   return 0;
935 }
936
937 #ifdef SNACLOGIN
938 int faimtest_parse_login(struct aim_session_t *sess, struct command_rx_struct *command, ...)
939 {
940   struct client_info_s info = {"FAIMtest (Hi guys!)", 3, 5, 1670, "us", "en"};
941   u_char authcookie[11];
942   int i;
943   
944   for (i = 0; i < (int)command->data[11]; i++)
945     authcookie[i] = command->data[12+i];
946   authcookie[i] = '\0';
947
948   printf("faimtest: logincookie: %s\n", authcookie);
949   
950   aim_send_login(sess, command->conn, FAIMTEST_SCREENNAME, FAIMTEST_PASSWORD, &info);
951  
952   return 1;
953 }
954 #endif
955
956 int faimtest_chat_join(struct aim_session_t *sess, struct command_rx_struct *command, ...)
957 {
958   va_list ap;
959   struct aim_userinfo_s *userinfo;
960   int count = 0, i = 0;
961   
962   va_start(ap, command);
963   count = va_arg(ap, int);
964   userinfo = va_arg(ap, struct aim_userinfo_s *);
965   va_end(ap);
966
967   printf("faimtest: chat: %s:  New occupants have joined:\n", (char *)command->conn->priv);
968   while (i < count)
969     printf("faimtest: chat: %s: \t%s\n", (char *)command->conn->priv, userinfo[i++].sn);
970
971   return 1;
972 }
973
974 int faimtest_chat_leave(struct aim_session_t *sess, struct command_rx_struct *command, ...)
975 {
976   va_list ap;
977   struct aim_userinfo_s *userinfo;
978   int count = 0, i = 0;
979   
980   va_start(ap, command);
981   count = va_arg(ap, int);
982   userinfo = va_arg(ap, struct aim_userinfo_s *);
983   va_end(ap);
984
985   printf("faimtest: chat: %s:  Some occupants have left:\n", (char *)command->conn->priv);
986   while (i < count)
987     printf("faimtest: chat: %s: \t%s\n", (char *)command->conn->priv, userinfo[i++].sn);
988
989   return 1;
990 }
991
992 int faimtest_chat_infoupdate(struct aim_session_t *sess, struct command_rx_struct *command, ...)
993 {
994   va_list ap;
995   struct aim_userinfo_s *userinfo;
996   struct aim_chat_roominfo *roominfo;
997   char *roomname;
998   int usercount,i;
999   char *roomdesc;
1000   unsigned short unknown_c9, unknown_d2, unknown_d5, maxmsglen;
1001   unsigned long creationtime;
1002
1003   va_start(ap, command);
1004   roominfo = va_arg(ap, struct aim_chat_roominfo *);
1005   roomname = va_arg(ap, char *);
1006   usercount= va_arg(ap, int);
1007   userinfo = va_arg(ap, struct aim_userinfo_s *);
1008   roomdesc = va_arg(ap, char *);
1009   unknown_c9 = va_arg(ap, unsigned short);
1010   creationtime = va_arg(ap, unsigned long);
1011   maxmsglen = va_arg(ap, unsigned short);
1012   unknown_d2 = va_arg(ap, unsigned short);
1013   unknown_d5 = va_arg(ap, unsigned short);
1014   va_end(ap);
1015
1016   printf("faimtest: chat: %s:  info update:\n", (char *)command->conn->priv);
1017   printf("faimtest: chat: %s:  \tRoominfo: {%04x, %s, %04x}\n", 
1018          (char *)command->conn->priv,
1019          roominfo->exchange,
1020          roominfo->name,
1021          roominfo->instance);
1022   printf("faimtest: chat: %s:  \tRoomname: %s\n", (char *)command->conn->priv, roomname);
1023   printf("faimtest: chat: %s:  \tRoomdesc: %s\n", (char *)command->conn->priv, roomdesc);
1024   printf("faimtest: chat: %s:  \tOccupants: (%d)\n", (char *)command->conn->priv, usercount);
1025   
1026   i = 0;
1027   while (i < usercount)
1028     printf("faimtest: chat: %s:  \t\t%s\n", (char *)command->conn->priv, userinfo[i++].sn);
1029
1030   printf("faimtest: chat: %s:  \tUnknown_c9: 0x%04x\n", (char *)command->conn->priv, unknown_c9);
1031   printf("faimtest: chat: %s:  \tCreation time: %lu (time_t)\n", (char *)command->conn->priv, creationtime);
1032   printf("faimtest: chat: %s:  \tMax message length: %d bytes\n", (char *)command->conn->priv, maxmsglen);
1033   printf("faimtest: chat: %s:  \tUnknown_d2: 0x%04x\n", (char *)command->conn->priv, unknown_d2);
1034   printf("faimtest: chat: %s:  \tUnknown_d5: 0x%02x\n", (char *)command->conn->priv, unknown_d5);
1035
1036   return 1;
1037 }
1038
1039 int faimtest_chat_incomingmsg(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1040 {
1041   va_list ap;
1042   struct aim_userinfo_s *userinfo;
1043   char *msg;
1044   char tmpbuf[1152];
1045  
1046   va_start(ap, command);
1047   userinfo = va_arg(ap, struct aim_userinfo_s *);       
1048   msg = va_arg(ap, char *);
1049   va_end(ap);
1050
1051   printf("faimtest: chat: %s: incoming msg from %s: %s\n", (char *)command->conn->priv, userinfo->sn, msg);
1052
1053   /*
1054    * Do an echo for testing purposes.  But not for ourselves ("oops!")
1055    */
1056   if (strcmp(userinfo->sn, sess->logininfo.screen_name) != 0)
1057     {
1058       sprintf(tmpbuf, "(%s said \"%s\")", userinfo->sn, msg);
1059       aim_chat_send_im(sess, command->conn, tmpbuf);
1060     }
1061
1062   return 1;
1063 }
1064
1065 int faimtest_chatnav_info(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1066 {
1067   u_short type;
1068   va_list ap;
1069
1070   ap = va_start(ap, command);
1071   type = va_arg(ap, u_short);
1072
1073   switch(type)
1074     {
1075     case 0x0002:
1076       {
1077         int maxrooms;
1078         struct aim_chat_exchangeinfo *exchanges;
1079         int exchangecount,i = 0;
1080         
1081         maxrooms = va_arg(ap, u_char);
1082         exchangecount = va_arg(ap, int);
1083         exchanges = va_arg(ap, struct aim_chat_exchangeinfo *);
1084         va_end(ap);
1085
1086         printf("faimtest: chat info: Chat Rights:\n");
1087         printf("faimtest: chat info: \tMax Concurrent Rooms: %d\n", maxrooms);
1088         
1089         printf("faimtest: chat info: \tExchange List: (%d total)\n", exchangecount);
1090         while (i < exchangecount)
1091           {
1092             printf("faimtest: chat info: \t\t%x: %s (%s/%s)\n", 
1093                    exchanges[i].number, 
1094                    exchanges[i].name,
1095                    exchanges[i].charset1,
1096                    exchanges[i].lang1);
1097             i++;
1098           }
1099         
1100       }
1101       break;
1102     default:
1103       va_end(ap);
1104       printf("faimtest: chatnav info: unknown type (%04x)\n", type);
1105     }
1106   return 1;
1107 }
1108
1109 int faimtest_parse_connerr(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1110 {
1111   va_list ap;
1112   unsigned short code;
1113   char *msg = NULL;
1114
1115   ap = va_start(ap, command);
1116   code = va_arg(ap, unsigned short);
1117   msg = va_arg(ap, char *);
1118   va_end(ap);
1119
1120   printf("faimtest: connerr: Code 0x%04x: %s\n", code, msg);
1121   aim_conn_kill(sess, &command->conn); /* this will break the main loop */
1122
1123   return 1;
1124 }
1125
1126 int faimtest_debugconn_connect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1127 {       
1128   printf("faimtest: connecting to an aimdebugd!\n");
1129
1130   /* convert the authorizer connection to a BOS connection */
1131   command->conn->type = AIM_CONN_TYPE_BOS;
1132
1133   aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_MSG, AIM_CB_MSG_INCOMING, faimtest_parse_incoming_im, 0);
1134
1135   /* tell the aimddebugd we're ready */
1136   aim_debugconn_sendconnect(sess, command->conn); 
1137
1138   /* go right into main loop (don't open a BOS connection, etc) */
1139   return 1;
1140 }
This page took 0.121317 seconds and 5 git commands to generate.