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