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