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