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