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