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