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