]> andersk Git - libfaim.git/blob - utils/faimtest/faimtest.c
One more.
[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_msgack(struct aim_session_t *, struct command_rx_struct *command, ...);
61 int faimtest_parse_motd(struct aim_session_t *, struct command_rx_struct *command, ...);
62 int faimtest_parse_login(struct aim_session_t *, struct command_rx_struct *command, ...);
63 int faimtest_chatnav_info(struct aim_session_t *, struct command_rx_struct *command, ...);
64 int faimtest_chat_incomingmsg(struct aim_session_t *sess, struct command_rx_struct *command, ...);
65 int faimtest_chat_infoupdate(struct aim_session_t *sess, struct command_rx_struct *command, ...);
66 int faimtest_chat_leave(struct aim_session_t *sess, struct command_rx_struct *command, ...);
67 int faimtest_chat_join(struct aim_session_t *sess, struct command_rx_struct *command, ...);
68 int faimtest_parse_connerr(struct aim_session_t *sess, struct command_rx_struct *command, ...);
69 int faimtest_debugconn_connect(struct aim_session_t *sess, struct command_rx_struct *command, ...);
70
71 int faimtest_directim_request(struct aim_session_t *sess, struct command_rx_struct *command, ...);
72 int faimtest_directim_initiate(struct aim_session_t *sess, struct command_rx_struct *command, ...);
73 int faimtest_directim_connect(struct aim_session_t *sess, struct command_rx_struct *command, ...);
74 int faimtest_directim_incoming(struct aim_session_t *sess, struct command_rx_struct *command, ...);
75 int faimtest_directim_disconnect(struct aim_session_t *sess, struct command_rx_struct *command, ...);
76 int faimtest_directim_typing(struct aim_session_t *sess, struct command_rx_struct *command, ...);
77 int faimtest_parse_ratechange(struct aim_session_t *sess, struct command_rx_struct *command, ...);
78 int faimtest_parse_evilnotify(struct aim_session_t *sess, struct command_rx_struct *command, ...);
79 int faimtest_parse_msgerr(struct aim_session_t *sess, struct command_rx_struct *command, ...);
80 int faimtest_parse_buddyrights(struct aim_session_t *sess, struct command_rx_struct *command, ...);
81 int faimtest_parse_locerr(struct aim_session_t *sess, struct command_rx_struct *command, ...);
82
83 static char *msgerrreasons[] = {
84   "Invalid error",
85   "Invalid SNAC",
86   "Rate to host",
87   "Rate to client",
88   "Not logged on",
89   "Service unavailable",
90   "Service not defined",
91   "Obsolete SNAC",
92   "Not supported by host",
93   "Not supported by client",
94   "Refused by client",
95   "Reply too big",
96   "Responses lost",
97   "Request denied",
98   "Busted SNAC payload",
99   "Insufficient rights",
100   "In local permit/deny",
101   "Too evil (sender)",
102   "Too evil (receiver)",
103   "User temporarily unavailable",
104   "No match",
105   "List overflow",
106   "Request ambiguous",
107   "Queue full",
108   "Not while on AOL"};
109 static int msgerrreasonslen = 25;
110
111 int faimtest_reportinterval(struct aim_session_t *sess, struct command_rx_struct *command, ...)
112 {
113   if (command->data) {
114     printf("aim: minimum report interval: %d (seconds?)\n", aimutil_get16(command->data+10));
115   } else
116     printf("aim: NULL minimum report interval!\n");
117   return 1;
118 }
119
120 static char *screenname,*password,*server=NULL;
121
122 int main(void)
123 {
124   struct aim_session_t aimsess;
125   struct aim_conn_t *authconn = NULL, *waitingconn = NULL;
126   int keepgoing = 1;
127
128   int selstat = 0;
129
130   if ( !(screenname = getenv("SCREENNAME")) ||
131        !(password = getenv("PASSWORD")))
132     {
133       printf("Must specify SCREENAME and PASSWORD in environment.\n");
134       return -1;
135     }
136
137   server = getenv("AUTHSERVER");
138
139   aim_session_init(&aimsess);
140
141   authconn = aim_newconn(&aimsess, AIM_CONN_TYPE_AUTH, server?server:FAIM_LOGIN_SERVER);
142
143   if (authconn == NULL) {
144     fprintf(stderr, "faimtest: internal connection error while in aim_login.  bailing out.\n");
145     return -1;
146   } else if (authconn->fd == -1) {
147     if (authconn->status & AIM_CONN_STATUS_RESOLVERR)
148       fprintf(stderr, "faimtest: could not resolve authorizer name\n");
149     else if (authconn->status & AIM_CONN_STATUS_CONNERR)
150       fprintf(stderr, "faimtest: could not connect to authorizer\n");
151     aim_conn_kill(&aimsess, &authconn);
152     return -1;
153   }
154
155   aim_conn_addhandler(&aimsess, authconn, 0x0017, 0x0007, faimtest_parse_login, 0);
156   aim_conn_addhandler(&aimsess, authconn, 0x0017, 0x0003, faimtest_parse_authresp, 0);
157     
158   aim_sendconnack(&aimsess, authconn);
159   aim_request_login(&aimsess, authconn, screenname);
160
161   aim_conn_addhandler(&aimsess, authconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_DEBUGCONN_CONNECT, faimtest_debugconn_connect, 0);
162
163   printf("faimtest: login request sent\n");
164
165   while (keepgoing) {
166     waitingconn = aim_select(&aimsess, NULL, &selstat);
167
168     switch(selstat) {
169     case -1: /* error */
170       keepgoing = 0; /* fall through and hit the aim_logoff() */
171       break;
172
173     case 0: /* no events pending */
174       break;
175
176     case 1: /* outgoing data pending */
177       aim_tx_flushqueue(&aimsess);
178       break;
179
180     case 2: /* incoming data pending */
181       if (waitingconn->type == AIM_CONN_TYPE_RENDEZVOUS_OUT) {
182         if (aim_handlerendconnect(&aimsess, waitingconn) < 0) {
183           printf("connection error (rend)\n");
184         }
185       } else {
186         if (aim_get_command(&aimsess, waitingconn) >= 0) {
187           aim_rxdispatch(&aimsess);
188         } else {
189           printf("connection error\n");
190           aim_conn_kill(&aimsess, &waitingconn);
191           if (!aim_getconn_type(&aimsess, AIM_CONN_TYPE_BOS)) {
192             printf("major connetion error\n");
193             keepgoing = 0;
194           }
195         }
196       }
197       break;
198       
199     default:
200       break; /* invalid */
201     }
202   }
203
204   /* Close up */
205   printf("AIM just decided we didn't need to be here anymore, closing up...\n");
206   
207   /* close up all connections, dead or no */
208   aim_logoff(&aimsess); 
209
210   /* Get out */
211   exit(0);
212 }
213
214 int faimtest_rateresp(struct aim_session_t *sess, struct command_rx_struct *command, ...)
215 {
216
217   switch(command->conn->type) {
218   case AIM_CONN_TYPE_BOS: {
219     /* this is the new buddy list */
220     char buddies[] = "Buddy1&Buddy2&ThisHereIsAName2&";
221     /* this is the new profile */
222     char profile[] = "Hello";  
223
224     aim_bos_ackrateresp(sess, command->conn);  /* ack rate info response */
225     aim_bos_reqpersonalinfo(sess, command->conn);
226     aim_bos_reqlocaterights(sess, command->conn);
227     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);
228     aim_bos_reqbuddyrights(sess, command->conn);
229
230     /* send the buddy list and profile (required, even if empty) */
231     aim_bos_setbuddylist(sess, command->conn, buddies);
232
233     /* dont really know what this does */
234     aim_addicbmparam(sess, command->conn);
235     aim_bos_reqicbmparaminfo(sess, command->conn);  
236   
237     aim_bos_reqrights(sess, command->conn);  
238     /* set group permissions -- all user classes */
239     aim_bos_setgroupperm(sess, command->conn, AIM_CLASS_ALLUSERS);
240     aim_bos_setprivacyflags(sess, command->conn, AIM_PRIVFLAGS_ALLOWIDLE|AIM_PRIVFLAGS_ALLOWMEMBERSINCE);
241
242     break;  
243   }
244
245   default: 
246     printf("faimtest: got rate response for unhandled connection type %04x\n", command->conn->type);
247     break;
248   }
249
250   return 1;
251 }
252
253 int faimtest_serverready(struct aim_session_t *sess, struct command_rx_struct *command, ...)
254 {
255   switch (command->conn->type)
256     {
257     case AIM_CONN_TYPE_BOS:
258
259       aim_setversions(sess, command->conn);
260       aim_bos_reqrate(sess, command->conn); /* request rate info */
261
262       fprintf(stderr, "faimtest: done with BOS ServerReady\n");
263       break;
264
265     case AIM_CONN_TYPE_CHATNAV:
266       fprintf(stderr, "faimtest: chatnav: got server ready\n");
267       aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CTN, AIM_CB_CTN_INFO, faimtest_chatnav_info, 0);
268       aim_bos_reqrate(sess, command->conn);
269       aim_bos_ackrateresp(sess, command->conn);
270       aim_chatnav_clientready(sess, command->conn);
271       aim_chatnav_reqrights(sess, command->conn);
272
273       break;
274     case AIM_CONN_TYPE_CHAT:
275       aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_USERJOIN, faimtest_chat_join, 0);
276       aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_USERLEAVE, faimtest_chat_leave, 0);
277       aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_ROOMINFOUPDATE, faimtest_chat_infoupdate, 0);
278       aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_INCOMINGMSG, faimtest_chat_incomingmsg, 0);
279       aim_bos_reqrate(sess, command->conn);
280       aim_bos_ackrateresp(sess, command->conn);
281       aim_chat_clientready(sess, command->conn);
282       break;
283
284     case AIM_CONN_TYPE_RENDEZVOUS: /* this is an overloaded function?? - mid */
285       aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, faimtest_directim_incoming, 0);
286       aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMDISCONNECT, faimtest_directim_disconnect, 0);
287       break;
288
289     default:
290       fprintf(stderr, "faimtest: unknown connection type on Server Ready\n");
291     }
292   return 1;
293 }
294
295 int faimtest_parse_buddyrights(struct aim_session_t *sess, struct command_rx_struct *command, ...)
296 {       
297   va_list ap;
298   unsigned short maxbuddies, maxwatchers;
299
300   va_start(ap, command);
301   maxbuddies = va_arg(ap, unsigned short);
302   maxwatchers = va_arg(ap, unsigned short);
303   va_end(ap);
304
305   printf("faimtest: buddy list rights: Max buddies = %d / Max watchers = %d\n", maxbuddies, maxwatchers);
306
307   return 1;
308 }
309
310 int faimtest_bosrights(struct aim_session_t *sess, struct command_rx_struct *command, ...)
311 {
312   unsigned short maxpermits, maxdenies;
313   va_list ap;
314
315   va_start(ap, command);
316   maxpermits = va_arg(ap, unsigned short);
317   maxdenies = va_arg(ap, unsigned short);
318   va_end(ap);
319
320   printf("faimtest: BOS rights: Max permit = %d / Max deny = %d\n", maxpermits, maxdenies);
321
322   aim_bos_clientready(sess, command->conn);
323
324   printf("faimtest: officially connected to BOS.\n");
325
326   return 1;
327 }
328
329 /*
330   handleredirect()...
331
332   This, of course, handles Service Redirects from OSCAR.
333
334   Should get passed in the following:
335      struct command_rx_struct *command
336        the raw command data
337      int serviceid
338        the destination service ID
339      char *serverip
340        the IP address of the service's server
341      char *cookie
342        the raw auth cookie
343  */
344 int faimtest_handleredirect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
345 {
346   va_list ap;
347   int serviceid;
348   char *ip;
349   unsigned char *cookie;
350
351   va_start(ap, command);
352   serviceid = va_arg(ap, int);
353   ip = va_arg(ap, char *);
354   cookie = va_arg(ap, unsigned char *);
355  
356   switch(serviceid)
357     {
358     case 0x0007: /* Authorizer */
359       {
360         struct aim_conn_t *tstconn;
361         /* Open a connection to the Auth */
362         tstconn = aim_newconn(sess, AIM_CONN_TYPE_AUTH, ip);
363         if ( (tstconn==NULL) || (tstconn->status >= AIM_CONN_STATUS_RESOLVERR) )
364           fprintf(stderr, "faimtest: unable to reconnect with authorizer\n");
365         else
366           /* Send the cookie to the Auth */
367           aim_auth_sendcookie(sess, tstconn, cookie);
368
369       }  
370       break;
371     case 0x000d: /* ChatNav */
372       {
373         struct aim_conn_t *tstconn = NULL;
374         tstconn = aim_newconn(sess, AIM_CONN_TYPE_CHATNAV, ip);
375         if ( (tstconn==NULL) || (tstconn->status >= AIM_CONN_STATUS_RESOLVERR)) {
376           fprintf(stderr, "faimtest: unable to connect to chatnav server\n");
377           if (tstconn) aim_conn_kill(sess, &tstconn);
378           return 1;
379         }
380 #if 0
381         aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_CTN, AIM_CB_SPECIAL_DEFAULT, aim_parse_unknown, 0);
382         aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_GEN, AIM_CB_SPECIAL_DEFAULT, aim_parse_unknown, 0);
383 #endif
384         aim_conn_addhandler(sess, tstconn, 0x0001, 0x0003, faimtest_serverready, 0);
385         aim_auth_sendcookie(sess, tstconn, cookie);
386         fprintf(stderr, "\achatnav: connected\n");
387       }
388       break;
389     case 0x000e: /* Chat */
390       {
391         char *roomname = NULL;
392         struct aim_conn_t *tstconn = NULL;
393
394         roomname = va_arg(ap, char *);
395
396         tstconn = aim_newconn(sess, AIM_CONN_TYPE_CHAT, ip);
397         if ( (tstconn==NULL) || (tstconn->status >= AIM_CONN_STATUS_RESOLVERR))
398           {
399             fprintf(stderr, "faimtest: unable to connect to chat server\n");
400             if (tstconn) aim_conn_kill(sess, &tstconn);
401             return 1;
402           }             
403         printf("faimtest: chat: connected\n");
404
405         /*
406          * We must do this to attach the stored name to the connection!
407          */
408         aim_chat_attachname(tstconn, roomname);
409
410         aim_conn_addhandler(sess, tstconn, 0x0001, 0x0003, faimtest_serverready, 0);
411         aim_auth_sendcookie(sess, tstconn, cookie);
412       }
413       break;
414     default:
415       printf("uh oh... got redirect for unknown service 0x%04x!!\n", serviceid);
416       /* dunno */
417     }
418
419   va_end(ap);
420
421   return 1;
422 }
423
424 int faimtest_parse_authresp(struct aim_session_t *sess, struct command_rx_struct *command, ...)
425 {
426   struct aim_conn_t *bosconn = NULL;
427   
428
429   printf("Screen name: %s\n", sess->logininfo.screen_name);
430
431   /*
432    * Check for error.
433    */
434   if (sess->logininfo.errorcode)
435     {
436       printf("Login Error Code 0x%04x\n", sess->logininfo.errorcode);
437       printf("Error URL: %s\n", sess->logininfo.errorurl);
438       aim_conn_kill(sess, &command->conn);
439       exit(0); /* XXX: should return in order to let the above things get free()'d. */
440     }
441
442   printf("Reg status: %2d\n", sess->logininfo.regstatus);
443   printf("Email: %s\n", sess->logininfo.email);
444   printf("BOS IP: %s\n", sess->logininfo.BOSIP);
445
446   printf("Closing auth connection...\n");
447   aim_conn_kill(sess, &command->conn);
448   bosconn = aim_newconn(sess, AIM_CONN_TYPE_BOS, sess->logininfo.BOSIP);
449   if (bosconn == NULL) {
450     fprintf(stderr, "faimtest: could not connect to BOS: internal error\n");
451   } else if (bosconn->status != 0) {    
452     fprintf(stderr, "faimtest: could not connect to BOS\n");
453     aim_conn_kill(sess, &bosconn);
454   } else {
455     aim_conn_addhandler(sess, bosconn, 0x0009, 0x0003, faimtest_bosrights, 0);
456     aim_conn_addhandler(sess, bosconn, 0x0001, 0x0007, faimtest_rateresp, 0); /* rate info */
457     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ACK, AIM_CB_ACK_ACK, NULL, 0);
458     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_SERVERREADY, faimtest_serverready, 0);
459     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_RATEINFO, NULL, 0);
460     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_REDIRECT, faimtest_handleredirect, 0);
461     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_STS, AIM_CB_STS_SETREPORTINTERVAL, faimtest_reportinterval, 0);
462     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_RIGHTSINFO, faimtest_parse_buddyrights, 0);
463     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_ONCOMING, faimtest_parse_oncoming, 0);
464     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_OFFGOING, faimtest_parse_offgoing, 0);
465     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_INCOMING, faimtest_parse_incoming_im, 0);
466     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_ERROR, faimtest_parse_locerr, 0);
467     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_MISSEDCALL, faimtest_parse_misses, 0);
468     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_RATECHANGE, faimtest_parse_ratechange, 0);
469     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_EVIL, faimtest_parse_evilnotify, 0);
470     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ERROR, faimtest_parse_msgerr, 0);
471     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO, faimtest_parse_userinfo, 0);
472     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ACK, faimtest_parse_msgack, 0);
473
474     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_CTN, AIM_CB_CTN_DEFAULT, aim_parse_unknown, 0);
475     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_DEFAULT, aim_parse_unknown, 0);
476     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_MOTD, faimtest_parse_motd, 0);
477     
478     aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, faimtest_parse_connerr, 0);
479     
480     aim_auth_sendcookie(sess, bosconn, sess->logininfo.cookie);
481   }
482   return 1;
483 }
484
485 int faimtest_parse_userinfo(struct aim_session_t *sess, struct command_rx_struct *command, ...)
486 {
487   struct aim_userinfo_s *userinfo;
488   char *prof_encoding = NULL;
489   char *prof = NULL;
490   unsigned short inforeq = 0;
491
492   va_list ap;
493   va_start(ap, command);
494   userinfo = va_arg(ap, struct aim_userinfo_s *);
495   prof_encoding = va_arg(ap, char *);
496   prof = va_arg(ap, char *);
497   inforeq = va_arg(ap, unsigned short);
498   va_end(ap);
499   
500   printf("faimtest: userinfo: sn: %s\n", userinfo->sn);
501   printf("faimtest: userinfo: warnlevel: 0x%04x\n", userinfo->warnlevel);
502   printf("faimtest: userinfo: class: 0x%04x = ", userinfo->class);
503
504   /*
505    *  00000000  (binary)
506    *         1  Trial  
507    *        2   Unknown
508    *       3    AOL
509    *      4     Unknown
510    *     5      Free
511    * 
512    * ORed together.
513    *
514    */
515
516   if (userinfo->class & 0x0001)
517     printf("TRIAL ");
518   if (userinfo->class & 0x0002)
519     printf("ADMINISTRATOR ");
520   if (userinfo->class & 0x0004)
521     printf("AOL ");
522   if (userinfo->class & 0x0008)
523     printf("OSCAR_PAY ");
524   if (userinfo->class & 0x0010)
525     printf("FREE ");
526   if (userinfo->class & 0x0040)
527     printf("ICQ? ");
528   printf("\n");
529   
530   printf("faimtest: userinfo: membersince: %lu\n", userinfo->membersince);
531   printf("faimtest: userinfo: onlinesince: %lu\n", userinfo->onlinesince);
532   printf("faimtest: userinfo: idletime: 0x%04x\n", userinfo->idletime);
533   
534   if (inforeq == AIM_GETINFO_GENERALINFO) {
535     printf("faimtest: userinfo: profile_encoding: %s\n", prof_encoding ? prof_encoding : "[none]");
536     printf("faimtest: userinfo: prof: %s\n", prof ? prof : "[none]");
537   } else if (inforeq == AIM_GETINFO_AWAYMESSAGE) {
538     printf("faimtest: userinfo: awaymsg_encoding: %s\n", prof_encoding ? prof_encoding : "[none]");
539     printf("faimtest: userinfo: awaymsg: %s\n", prof ? prof : "[none]");
540   } else 
541     printf("faimtest: userinfo: unknown info request\n");
542   
543   return 1;
544 }
545
546 /*
547  * The user-level Incoming ICBM callback.
548  *
549  * Arguments:
550  *  struct command_rx_struct *  command     if you feel like doing it yourself
551  *  char *                      srcsn       the source name
552  *  char *                      msg         message
553  *  int                         warnlevel   warning/evil level
554  *  int                         class       user class
555  *  ulong                       membersince time_t of date of signup
556  *  ulong                       onsince     time_t of date of singon
557  *  int                         idletime    min (sec?) idle
558  *  u_int                       icbmflags   sets AIM_IMFLAGS_{AWAY,ACK}
559  *
560  */
561 int faimtest_parse_incoming_im(struct aim_session_t *sess, struct command_rx_struct *command, ...)
562 {
563   int channel;
564   va_list ap;
565
566   va_start(ap, command);
567   channel = va_arg(ap, int);
568
569   /*
570    * Channel 1: Standard Message
571    */
572   if (channel == 1) {
573     struct aim_userinfo_s *userinfo;
574     char *msg = NULL;
575     u_int icbmflags = 0;
576     char *tmpstr = NULL;
577     u_short flag1, flag2;
578     
579     userinfo = va_arg(ap, struct aim_userinfo_s *);
580     msg = va_arg(ap, char *);
581     icbmflags = va_arg(ap, u_int);
582     flag1 = va_arg(ap, u_short);
583     flag2 = va_arg(ap, u_short);
584     va_end(ap);
585     
586     printf("faimtest: icbm: sn = \"%s\"\n", userinfo->sn);
587     printf("faimtest: icbm: warnlevel = 0x%04x\n", userinfo->warnlevel);
588     printf("faimtest: icbm: class = 0x%04x ", userinfo->class);
589     if (userinfo->class & 0x0010)
590       printf("(FREE) ");
591     if (userinfo->class & 0x0001)
592       printf("(TRIAL) ");
593     if (userinfo->class & 0x0004)
594       printf("(AOL) ");
595     printf("\n");
596     printf("faimtest: icbm: membersince = %lu\n", userinfo->membersince);
597     printf("faimtest: icbm: onlinesince = %lu\n", userinfo->onlinesince);
598     printf("faimtest: icbm: idletime = 0x%04x\n", userinfo->idletime);
599     printf("faimtest: icbm: capabilities = 0x%04x\n", userinfo->capabilities);
600     
601     printf("faimtest: icbm: icbmflags = ");
602     if (icbmflags & AIM_IMFLAGS_AWAY)
603       printf("away ");
604     if (icbmflags & AIM_IMFLAGS_ACK)
605       printf("ackrequest ");
606     printf("\n");
607     
608     printf("faimtest: icbm: encoding flags = {%04x, %04x}\n", flag1, flag2);
609     
610     printf("faimtest: icbm: message: %s\n", msg);
611     
612     if (msg) {
613       int i = 0;
614
615       while (msg[i] == '<') {
616         if (msg[i] == '<') {
617           while (msg[i] != '>')
618             i++;
619           i++;
620         }
621       }
622       tmpstr = msg+i;
623
624       printf("tmpstr = %s\n", tmpstr);
625       
626       if ( (strlen(tmpstr) >= 10) &&
627            (!strncmp(tmpstr, "disconnect", 10)) ) {
628           aim_send_im(sess, command->conn, "midendian", 0, "ta ta...");
629           aim_logoff(sess);
630       } else if (strstr(tmpstr, "goodday")) {
631         printf("faimtest: icbm: sending response\n");
632         aim_send_im(sess, command->conn, userinfo->sn, AIM_IMFLAGS_ACK, "Good day to you too.");
633       } else if (strstr(tmpstr, "warnme")) {
634         printf("faimtest: icbm: sending non-anon warning\n");
635         aim_send_warning(sess, command->conn, userinfo->sn, 0);
636       } else if (strstr(tmpstr, "anonwarn")) {
637         printf("faimtest: icbm: sending anon warning\n");
638         aim_send_warning(sess, command->conn, userinfo->sn, AIM_WARN_ANON);
639       } else if (!strncmp(tmpstr, "open chatnav", 12)) {
640         aim_bos_reqservice(sess, command->conn, AIM_CONN_TYPE_CHATNAV);
641         //aim_chat_join(sess, command->conn, "thishereisaname2_chat85");
642       } else if (!strncmp(tmpstr, "create", 6)) {
643         aim_chatnav_createroom(sess,aim_getconn_type(sess, AIM_CONN_TYPE_CHATNAV), (strlen(tmpstr) < 7)?"WorldDomination":tmpstr+7, 0x0004);
644       } else if (!strncmp(tmpstr, "close chatnav", 13)) {
645         struct aim_conn_t *chatnavconn;
646         chatnavconn = aim_getconn_type(sess, AIM_CONN_TYPE_CHATNAV);
647         aim_conn_kill(sess, &chatnavconn);
648       } else if (!strncmp(tmpstr, "join", 4)) {
649           aim_chat_join(sess, command->conn, 0x0004, "worlddomination");
650       } else if (!strncmp(tmpstr, "leave", 5))
651             aim_chat_leaveroom(sess, "worlddomination");
652       else if (!strncmp(tmpstr, "getinfo", 7)) {
653         aim_getinfo(sess, command->conn, "75784102", AIM_GETINFO_GENERALINFO);
654         aim_getinfo(sess, command->conn, "15853637", AIM_GETINFO_AWAYMESSAGE);
655       } else if (!strncmp(tmpstr, "open directim", 13)) {
656         struct aim_conn_t *newconn;
657         newconn = aim_directim_initiate(sess, command->conn, NULL, userinfo->sn);
658         //aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINITIATE, faimtest_directim_initiate, 0);
659       } else if (!strncmp(tmpstr, "reqsendmsg", 10)) {
660         aim_send_im(sess, command->conn, "vaxherder", 0, "sendmsg 7900");
661       } else if (!strncmp(tmpstr, "sendmsg", 7)) {
662         int i;
663         i = atoi(tmpstr+8);
664         if (i < 10000) {
665           char *newbuf;
666           int z;
667
668           newbuf = malloc(i+1);
669           for (z = 0; z < i; z++) {
670             newbuf[z] = (z % 10)+0x30;
671           }
672           newbuf[i] = '\0';
673           aim_send_im(sess, command->conn, userinfo->sn, 0, newbuf);
674           free(newbuf);
675         }
676       } else {
677         printf("unknown command.\n");
678         aim_add_buddy(sess, command->conn, userinfo->sn);
679       }
680       
681     }
682   }
683   /*
684    * Channel 2: Rendevous Request
685    */
686   else if (channel == 2) {
687     struct aim_userinfo_s *userinfo;
688     unsigned short reqclass;
689     
690     reqclass = va_arg(ap, unsigned short);
691     switch (reqclass) {
692     case AIM_CAPS_VOICE: {
693       userinfo = va_arg(ap, struct aim_userinfo_s *);
694       va_end(ap);
695       
696       printf("faimtest: voice invitation: source sn = %s\n", userinfo->sn);
697       printf("faimtest: voice invitation: \twarnlevel = 0x%04x\n", userinfo->warnlevel);
698       printf("faimtest: voice invitation: \tclass = 0x%04x ", userinfo->class);
699       if (userinfo->class & 0x0010)
700         printf("(FREE) ");
701       if (userinfo->class & 0x0001)
702         printf("(TRIAL) ");
703       if (userinfo->class & 0x0004)
704         printf("(AOL) ");
705       printf("\n");
706       /* we dont get membersince on chat invites! */
707       printf("faimtest: voice invitation: \tonlinesince = %lu\n", userinfo->onlinesince);
708       printf("faimtest: voice invitation: \tidletime = 0x%04x\n", userinfo->idletime);
709       
710       break;
711     }
712     case AIM_CAPS_GETFILE: {
713       printf("faimtset: get file!\n");
714       break;
715     }
716     case AIM_CAPS_SENDFILE: {
717       printf("faimtest: send file!\n");
718       break;
719     }
720     case AIM_CAPS_CHAT: {
721       char *msg,*encoding,*lang;
722       struct aim_chat_roominfo *roominfo;
723       
724       userinfo = va_arg(ap, struct aim_userinfo_s *);
725       roominfo = va_arg(ap, struct aim_chat_roominfo *);
726       msg = va_arg(ap, char *);
727       encoding = va_arg(ap, char *);
728       lang = va_arg(ap, char *);
729       va_end(ap);
730       
731       printf("faimtest: chat invitation: source sn = %s\n", userinfo->sn);
732       printf("faimtest: chat invitation: \twarnlevel = 0x%04x\n", userinfo->warnlevel);
733       printf("faimtest: chat invitation: \tclass = 0x%04x ", userinfo->class);
734       if (userinfo->class & 0x0010)
735         printf("(FREE) ");
736       if (userinfo->class & 0x0001)
737         printf("(TRIAL) ");
738       if (userinfo->class & 0x0004)
739         printf("(AOL) ");
740       printf("\n");
741       /* we dont get membersince on chat invites! */
742       printf("faimtest: chat invitation: \tonlinesince = %lu\n", userinfo->onlinesince);
743       printf("faimtest: chat invitation: \tidletime = 0x%04x\n", userinfo->idletime);
744       
745       printf("faimtest: chat invitation: message = %s\n", msg);
746       printf("faimtest: chat invitation: room name = %s\n", roominfo->name);
747       printf("faimtest: chat invitation: encoding = %s\n", encoding);
748       printf("faimtest: chat invitation: language = %s\n", lang);
749       printf("faimtest: chat invitation: exchange = 0x%04x\n", roominfo->exchange);
750       printf("faimtest: chat invitation: instance = 0x%04x\n", roominfo->instance);
751       printf("faimtest: chat invitiation: autojoining %s...\n", roominfo->name);
752       /*
753        * Automatically join room...
754        */ 
755       aim_chat_join(sess, command->conn, 0x0004, roominfo->name);
756       break;
757     }   
758     case AIM_CAPS_IMIMAGE: {
759       struct aim_directim_priv *priv;
760       struct aim_conn_t *newconn;
761
762       printf("faimtest: icbm: rendezvous imimage\n");
763      
764       userinfo = va_arg(ap, struct aim_userinfo_s *);
765       priv = va_arg(ap, struct aim_directim_priv *);
766       va_end(ap);
767
768       printf("faimtest: OFT: DirectIM: request from %s (%s)\n", userinfo->sn, priv->ip);
769       
770       if (!(newconn = aim_directim_connect(sess, command->conn, priv))) {
771         printf("faimtest: icbm: imimage: could not connect\n");
772         break;
773       }
774       aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, faimtest_directim_incoming, 0);
775       aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMDISCONNECT, faimtest_directim_disconnect, 0);
776       aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, faimtest_directim_typing, 0);
777
778       aim_send_im_direct(sess, newconn, "goodday");
779
780       printf("faimtest: OFT: DirectIM: connected to %s\n", userinfo->sn);
781
782       break;
783     }
784     default:
785       printf("faimtest: icbm: unknown reqclass (%d)\n", reqclass);
786     } /* switch */
787   } else
788     printf("faimtest does not support channels > 2 (chan = %02x)\n", channel);
789   printf("faimtest: icbm: done with ICBM handling\n");
790
791   return 1;
792 }
793
794 #if 0
795 int faimtest_directim_initiate(struct aim_session_t *sess, struct command_rx_struct *command, ...)
796 {
797   va_list ap;
798   struct aim_directim_priv *priv;
799   struct aim_conn_t *newconn;
800
801   ap = va_start(ap, command);
802   newconn = va_arg(ap, struct aim_conn_t *);
803   va_end(ap);
804
805   priv = (struct aim_directim_priv *)newconn->priv;
806
807   printf("faimtest: OFT: DirectIM: intitiate success to %s\n", priv->ip);
808   
809   aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, faimtest_directim_incoming, 0);
810   aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMDISCONNECT, faimtest_directim_disconnect, 0);
811   aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, faimtest_directim_typing, 0);
812
813   aim_send_im_direct(sess, newconn, "goodday");
814
815   printf("faimtest: OFT: DirectIM: connected to %s\n", priv->sn);
816
817   return 1;
818 }
819 #endif
820
821 int faimtest_directim_connect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
822 {
823   va_list ap;
824   struct aim_directim_priv *priv;
825   
826   ap = va_start(ap, command);
827   priv = va_arg(ap, struct aim_directim_priv *);
828
829   va_end(ap);
830   
831   printf("faimtest: directim_connect\n");
832
833   return 1;
834 }
835
836 int faimtest_directim_incoming(struct aim_session_t *sess, struct command_rx_struct *command, ...)
837 {
838   va_list ap;
839   char *sn = NULL, *msg = NULL;
840   struct aim_conn_t *conn;
841
842   ap = va_start(ap, command);
843   conn = va_arg(ap, struct aim_conn_t *);
844   sn = va_arg(ap, char *);
845   msg = va_arg(ap, char *);
846   va_end(ap);
847
848   printf("faimtest: Directim from %s: %s\n", sn, msg);
849   if (!strncmp(msg, "sendmsg", 7)) {
850     int i;
851     i = atoi(msg+8);
852     if (i < 10000) {
853       char *newbuf;
854       int z;
855       
856       newbuf = malloc(i+1);
857       for (z = 0; z < i; z++) {
858         newbuf[z] = (z % 10)+0x30;
859       }
860       newbuf[i] = '\0';
861       aim_send_im_direct(sess, conn, newbuf);
862       free(newbuf);
863     }
864   } else if (!strncmp(msg, "goodday", 7)) {
865     aim_send_im_direct(sess, conn, "Good day to you, too");
866   } else {
867     char newmsg[1024];
868     snprintf(newmsg, sizeof(newmsg), "unknown (%s)\n", msg);
869     aim_send_im_direct(sess, conn, newmsg);
870   }
871   return 1;
872 }
873
874 int faimtest_directim_disconnect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
875 {
876   printf("faimtest: directim_disconnect\n");
877   return 1;
878 }
879
880 int faimtest_directim_typing(struct aim_session_t *sess, struct command_rx_struct *command, ...)
881 {
882   va_list ap;
883   char *sn;
884   
885   ap = va_start(ap, command);
886   sn = va_arg(ap, char *);
887   va_end(ap);
888
889   printf("faimtest: ohmigod! %s has started typing (DirectIM). He's going to send you a message! *squeal*\n", sn);
890   return 1;
891 }
892
893 int faimtest_authsvrready(struct aim_session_t *sess, struct command_rx_struct *command, ...)
894 {
895   printf("faimtest_authsvrready: called (contype: %d)\n", command->conn->type);
896   sleep(10);
897   /* should just be able to tell it we're ready too... */
898   aim_auth_clientready(sess, command->conn);
899
900 #if 0
901   /*
902    * This is where you'd really begin changing your password.
903    *   However, this callback may get called for reasons other
904    *   than you wanting to change your password.  You should 
905    *   probably check that before actually doing it.
906    */
907   aim_auth_changepasswd(sess, command->conn, "PWD1", "PWD2");
908 #endif
909
910   return 1;
911 }
912
913 int faimtest_pwdchngdone(struct aim_session_t *sess, struct command_rx_struct *command, ...)
914 {
915   printf("PASSWORD CHANGE SUCCESSFUL!!!\n");
916   return 1;
917 }
918
919 int faimtest_parse_oncoming(struct aim_session_t *sess, struct command_rx_struct *command, ...)
920 {
921   struct aim_userinfo_s *userinfo;
922    
923   va_list ap;
924   va_start(ap, command);
925   userinfo = va_arg(ap, struct aim_userinfo_s *);
926   va_end(ap);
927
928   printf("\n%s is now online (class: %04x = %s%s%s%s%s%s%s%s) (caps = 0x%04x)\n",
929          userinfo->sn, userinfo->class,
930          (userinfo->class&AIM_CLASS_TRIAL)?" TRIAL":"",
931          (userinfo->class&AIM_CLASS_ADMINISTRATOR)?" ADMINISTRATOR":"",
932          (userinfo->class&AIM_CLASS_AOL)?" AOL":"",
933          (userinfo->class&AIM_CLASS_OSCAR_PAY)?" OSCAR_PAY":"",
934          (userinfo->class&AIM_CLASS_FREE)?" FREE":"",
935          (userinfo->class&AIM_CLASS_AWAY)?" AWAY":"",
936          (userinfo->class&AIM_CLASS_UNKNOWN40)?" UNKNOWN40":"",
937          (userinfo->class&AIM_CLASS_UNKNOWN80)?" UNKNOWN80":"",
938          userinfo->capabilities);
939   return 1;
940 }
941
942 int faimtest_parse_offgoing(struct aim_session_t *sess, struct command_rx_struct *command, ...)
943 {
944   char *sn;
945   va_list ap;
946   
947   va_start(ap, command);
948   sn = va_arg(ap, char *);
949   va_end(ap);
950
951   printf("\n%s has left\n", sn);
952
953   return 1;
954 }
955
956 int faimtest_parse_motd(struct aim_session_t *sess, struct command_rx_struct *command, ...)
957 {
958   static char *codes[] = {
959     "Unknown",
960     "Mandatory upgrade",
961     "Advisory upgrade",
962     "System bulletin",
963     "Top o' the world!"};
964   static int codeslen = 5;
965
966   char *msg;
967   unsigned short id;
968   va_list ap;
969   
970   va_start(ap, command);
971   id = va_arg(ap, unsigned short);
972   msg = va_arg(ap, char *);
973   va_end(ap);
974
975   printf("faimtest: motd: %s (%d / %s)\n", msg, id, 
976          (id < codeslen)?codes[id]:"unknown");
977
978   return 1;
979 }
980
981 int faimtest_parse_msgerr(struct aim_session_t *sess, struct command_rx_struct *command, ...)
982 {
983   va_list ap;
984   char *destsn;
985   unsigned short reason;
986
987   va_start(ap, command);
988   destsn = va_arg(ap, char *);
989   reason = va_arg(ap, unsigned short);
990   va_end(ap);
991
992   printf("faimtest: message to %s bounced (reason 0x%04x: %s)\n", destsn, reason, (reason<msgerrreasonslen)?msgerrreasons[reason]:"unknown");
993   
994   return 1;
995 }
996
997 int faimtest_parse_locerr(struct aim_session_t *sess, struct command_rx_struct *command, ...)
998 {
999   va_list ap;
1000   char *destsn;
1001   unsigned short reason;
1002
1003   va_start(ap, command);
1004   destsn = va_arg(ap, char *);
1005   reason = va_arg(ap, unsigned short);
1006   va_end(ap);
1007
1008   printf("faimtest: user information for %s unavailable (reason 0x%04x: %s)\n", destsn, reason, (reason<msgerrreasonslen)?msgerrreasons[reason]:"unknown");
1009   
1010   return 1;
1011 }
1012
1013 /* 
1014  * Handles callbacks for AIM_CB_MISSED_CALL.
1015  */
1016 int faimtest_parse_misses(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1017 {
1018   static char *missedreasons[] = {
1019     "Unknown",
1020     "Message too large"};
1021   static int missedreasonslen = 2;
1022
1023   va_list ap;
1024   unsigned short chan, nummissed, reason;
1025   struct aim_userinfo_s *userinfo;
1026   
1027   va_start(ap, command);
1028   chan = va_arg(ap, unsigned short);
1029   userinfo = va_arg(ap, struct aim_userinfo_s *);
1030   nummissed = va_arg(ap, unsigned short);
1031   reason = va_arg(ap, unsigned short);
1032   va_end(ap);
1033
1034   printf("faimtest: missed %d messages from %s (reason %d: %s)\n", nummissed, userinfo->sn, reason, (reason<missedreasonslen)?missedreasons[reason]:"unknown");
1035   
1036   return 0;
1037 }
1038
1039 int faimtest_parse_login(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1040 {
1041   struct client_info_s info = {"faimtest (with SNAC login)", 4, 1, 2010, "us", "en", 0x0004, 0x0000, 0x0000004b}; /* 4.1.2010 */
1042   char *key;
1043   va_list ap;
1044   
1045   va_start(ap, command);
1046   key = va_arg(ap, char *);
1047   va_end(ap);
1048
1049   aim_send_login(sess, command->conn, screenname, password, &info, key);
1050  
1051   return 1;
1052 }
1053
1054 int faimtest_chat_join(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1055 {
1056   va_list ap;
1057   struct aim_userinfo_s *userinfo;
1058   int count = 0, i = 0;
1059   
1060   va_start(ap, command);
1061   count = va_arg(ap, int);
1062   userinfo = va_arg(ap, struct aim_userinfo_s *);
1063   va_end(ap);
1064
1065   printf("faimtest: chat: %s:  New occupants have joined:\n", (char *)command->conn->priv);
1066   while (i < count)
1067     printf("faimtest: chat: %s: \t%s\n", (char *)command->conn->priv, userinfo[i++].sn);
1068
1069   return 1;
1070 }
1071
1072 int faimtest_chat_leave(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1073 {
1074   va_list ap;
1075   struct aim_userinfo_s *userinfo;
1076   int count = 0, i = 0;
1077   
1078   va_start(ap, command);
1079   count = va_arg(ap, int);
1080   userinfo = va_arg(ap, struct aim_userinfo_s *);
1081   va_end(ap);
1082
1083   printf("faimtest: chat: %s:  Some occupants have left:\n", (char *)command->conn->priv);
1084   while (i < count)
1085     printf("faimtest: chat: %s: \t%s\n", (char *)command->conn->priv, userinfo[i++].sn);
1086
1087   return 1;
1088 }
1089
1090 int faimtest_chat_infoupdate(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1091 {
1092   va_list ap;
1093   struct aim_userinfo_s *userinfo;
1094   struct aim_chat_roominfo *roominfo;
1095   char *roomname;
1096   int usercount,i;
1097   char *roomdesc;
1098   unsigned short unknown_c9, unknown_d2, unknown_d5, maxmsglen;
1099   unsigned long creationtime;
1100
1101   va_start(ap, command);
1102   roominfo = va_arg(ap, struct aim_chat_roominfo *);
1103   roomname = va_arg(ap, char *);
1104   usercount= va_arg(ap, int);
1105   userinfo = va_arg(ap, struct aim_userinfo_s *);
1106   roomdesc = va_arg(ap, char *);
1107   unknown_c9 = va_arg(ap, unsigned short);
1108   creationtime = va_arg(ap, unsigned long);
1109   maxmsglen = va_arg(ap, unsigned short);
1110   unknown_d2 = va_arg(ap, unsigned short);
1111   unknown_d5 = va_arg(ap, unsigned short);
1112   va_end(ap);
1113
1114   printf("faimtest: chat: %s:  info update:\n", (char *)command->conn->priv);
1115   printf("faimtest: chat: %s:  \tRoominfo: {%04x, %s, %04x}\n", 
1116          (char *)command->conn->priv,
1117          roominfo->exchange,
1118          roominfo->name,
1119          roominfo->instance);
1120   printf("faimtest: chat: %s:  \tRoomname: %s\n", (char *)command->conn->priv, roomname);
1121   printf("faimtest: chat: %s:  \tRoomdesc: %s\n", (char *)command->conn->priv, roomdesc);
1122   printf("faimtest: chat: %s:  \tOccupants: (%d)\n", (char *)command->conn->priv, usercount);
1123   
1124   i = 0;
1125   while (i < usercount)
1126     printf("faimtest: chat: %s:  \t\t%s\n", (char *)command->conn->priv, userinfo[i++].sn);
1127
1128   printf("faimtest: chat: %s:  \tUnknown_c9: 0x%04x\n", (char *)command->conn->priv, unknown_c9);
1129   printf("faimtest: chat: %s:  \tCreation time: %lu (time_t)\n", (char *)command->conn->priv, creationtime);
1130   printf("faimtest: chat: %s:  \tMax message length: %d bytes\n", (char *)command->conn->priv, maxmsglen);
1131   printf("faimtest: chat: %s:  \tUnknown_d2: 0x%04x\n", (char *)command->conn->priv, unknown_d2);
1132   printf("faimtest: chat: %s:  \tUnknown_d5: 0x%02x\n", (char *)command->conn->priv, unknown_d5);
1133
1134   return 1;
1135 }
1136
1137 int faimtest_chat_incomingmsg(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1138 {
1139   va_list ap;
1140   struct aim_userinfo_s *userinfo;
1141   char *msg;
1142   char tmpbuf[1152];
1143  
1144   va_start(ap, command);
1145   userinfo = va_arg(ap, struct aim_userinfo_s *);       
1146   msg = va_arg(ap, char *);
1147   va_end(ap);
1148
1149   printf("faimtest: chat: %s: incoming msg from %s: %s\n", (char *)command->conn->priv, userinfo->sn, msg);
1150
1151   /*
1152    * Do an echo for testing purposes.  But not for ourselves ("oops!")
1153    */
1154   if (strcmp(userinfo->sn, sess->logininfo.screen_name) != 0)
1155     {
1156       sprintf(tmpbuf, "(%s said \"%s\")", userinfo->sn, msg);
1157       aim_chat_send_im(sess, command->conn, tmpbuf);
1158     }
1159
1160   return 1;
1161 }
1162
1163 int faimtest_chatnav_info(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1164 {
1165   u_short type;
1166   va_list ap;
1167
1168   ap = va_start(ap, command);
1169   type = va_arg(ap, u_short);
1170
1171   switch(type)
1172     {
1173     case 0x0002:
1174       {
1175         int maxrooms;
1176         struct aim_chat_exchangeinfo *exchanges;
1177         int exchangecount,i = 0;
1178         
1179         maxrooms = va_arg(ap, u_char);
1180         exchangecount = va_arg(ap, int);
1181         exchanges = va_arg(ap, struct aim_chat_exchangeinfo *);
1182         va_end(ap);
1183
1184         printf("faimtest: chat info: Chat Rights:\n");
1185         printf("faimtest: chat info: \tMax Concurrent Rooms: %d\n", maxrooms);
1186         
1187         printf("faimtest: chat info: \tExchange List: (%d total)\n", exchangecount);
1188         while (i < exchangecount)
1189           {
1190             printf("faimtest: chat info: \t\t%x: %s (%s/%s)\n", 
1191                    exchanges[i].number, 
1192                    exchanges[i].name,
1193                    exchanges[i].charset1,
1194                    exchanges[i].lang1);
1195             i++;
1196           }
1197         
1198       }
1199       break;
1200     default:
1201       va_end(ap);
1202       printf("faimtest: chatnav info: unknown type (%04x)\n", type);
1203     }
1204   return 1;
1205 }
1206
1207 int faimtest_parse_connerr(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1208 {
1209   va_list ap;
1210   unsigned short code;
1211   char *msg = NULL;
1212
1213   ap = va_start(ap, command);
1214   code = va_arg(ap, unsigned short);
1215   msg = va_arg(ap, char *);
1216   va_end(ap);
1217
1218   printf("faimtest: connerr: Code 0x%04x: %s\n", code, msg);
1219   aim_conn_kill(sess, &command->conn); /* this will break the main loop */
1220
1221   return 1;
1222 }
1223
1224 int faimtest_debugconn_connect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1225 {       
1226   printf("faimtest: connecting to an aimdebugd!\n");
1227
1228   /* convert the authorizer connection to a BOS connection */
1229   command->conn->type = AIM_CONN_TYPE_BOS;
1230
1231   aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_MSG, AIM_CB_MSG_INCOMING, faimtest_parse_incoming_im, 0);
1232
1233   /* tell the aimddebugd we're ready */
1234   aim_debugconn_sendconnect(sess, command->conn); 
1235
1236   /* go right into main loop (don't open a BOS connection, etc) */
1237   return 1;
1238 }
1239
1240 /*
1241  * Recieved in response to an IM sent with the AIM_IMFLAGS_ACK option.
1242  */
1243 int faimtest_parse_msgack(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1244 {
1245   va_list ap;
1246   unsigned short type;
1247   char *sn = NULL;
1248
1249   ap = va_start(ap, command);
1250   type = va_arg(ap, unsigned short);
1251   sn = va_arg(ap, char *);
1252   va_end(ap);
1253
1254   printf("faimtest: msgack: 0x%04x / %s\n", type, sn);
1255
1256   return 1;
1257 }
1258
1259 int faimtest_parse_ratechange(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1260 {
1261   va_list ap;
1262   unsigned long newrate;
1263   
1264   va_start(ap, command); 
1265   newrate = va_arg(ap, unsigned long);
1266   va_end(ap);
1267
1268   printf("faimtest: ratechange: %lu\n", newrate);
1269
1270   return (1);
1271 }
1272
1273 int faimtest_parse_evilnotify(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1274 {
1275   va_list ap;
1276   char *sn;
1277
1278   va_start(ap, command);
1279   sn = va_arg(ap, char *);
1280   va_end(ap);
1281
1282   printf("faimtest: warning from: %s\n", sn);
1283
1284   return 1;
1285 }
This page took 0.139614 seconds and 5 git commands to generate.