]> andersk Git - libfaim.git/blame - utils/faimtest/faimtest.c
- Fri Dec 15 02:04:12 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, ...);
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;
7392c79f 119
22517493 120static char *screenname,*password,*server=NULL;
ee49b735 121static int connected = 0;
22517493 122
f0a7908e 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
22517493 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
999b6d5f 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
9de3ca7e 192int main(void)
193{
397055b1 194 struct aim_session_t aimsess;
f1a5efe0 195 struct aim_conn_t *authconn = NULL, *waitingconn = NULL;
68ac63c2 196 int keepgoing = 1;
bb0dc593 197 char *proxy, *proxyusername, *proxypass;
5e02cf44 198
871e2fd0 199 char *listingpath;
200
b8d0da45 201 int selstat = 0;
202
871e2fd0 203#ifdef FILESUPPORT
204 FILE *listingfile;
205#endif
206
26af6789 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
f1a5efe0 214 server = getenv("AUTHSERVER");
215
bb0dc593 216 proxy = getenv("SOCKSPROXY");
217 proxyusername = getenv("SOCKSNAME");
218 proxypass = getenv("SOCKSPASS");
219
871e2fd0 220#ifdef FILESUPPORT
221 listingpath = getenv("LISTINGPATH");
222#endif
223
999b6d5f 224#ifdef _WIN32
225 if (initwsa() != 0) {
226 printf("faimtest: could not initialize windows sockets\n");
227 return -1;
228 }
229#endif /* _WIN32 */
230
22517493 231 /* Pass zero as flags if you want blocking connects */
232 aim_session_init(&aimsess, AIM_SESS_FLAGS_NONBLOCKCONNECT);
68ac63c2 233
871e2fd0 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
bb0dc593 253 if (proxy)
254 aim_setupproxy(&aimsess, proxy, proxyusername, proxypass);
255
f1a5efe0 256 authconn = aim_newconn(&aimsess, AIM_CONN_TYPE_AUTH, server?server:FAIM_LOGIN_SERVER);
397055b1 257
040457cc 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;
68ac63c2 268 }
b5bc2a8c 269
22517493 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);
68ac63c2 272 aim_conn_addhandler(&aimsess, authconn, 0x0017, 0x0007, faimtest_parse_login, 0);
22517493 273 aim_conn_addhandler(&aimsess, authconn, 0x0017, 0x0003, faimtest_parse_authresp, 0);
b5bc2a8c 274
e5012450 275 aim_conn_addhandler(&aimsess, authconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_DEBUGCONN_CONNECT, faimtest_debugconn_connect, 0);
b5bc2a8c 276
22517493 277 /* If the connection is in progress, this will just be queued */
278 aim_request_login(&aimsess, authconn, screenname);
b5bc2a8c 279 printf("faimtest: login request sent\n");
9de3ca7e 280
b8d0da45 281 while (keepgoing) {
f1a5efe0 282 waitingconn = aim_select(&aimsess, NULL, &selstat);
b8d0da45 283
284 switch(selstat) {
285 case -1: /* error */
68ac63c2 286 keepgoing = 0; /* fall through and hit the aim_logoff() */
b8d0da45 287 break;
9de3ca7e 288
b8d0da45 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 */
7392c79f 297 if (waitingconn->type == AIM_CONN_TYPE_RENDEZVOUS_OUT) {
298 if (aim_handlerendconnect(&aimsess, waitingconn) < 0) {
871e2fd0 299 printf("connection error (rend out)\n");
7392c79f 300 }
301 } else {
302 if (aim_get_command(&aimsess, waitingconn) >= 0) {
303 aim_rxdispatch(&aimsess);
304 } else {
871e2fd0 305 printf("connection error (type 0x%04x:0x%04x)\n", waitingconn->type, waitingconn->subtype);
3b101546 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);
7392c79f 312 if (!aim_getconn_type(&aimsess, AIM_CONN_TYPE_BOS)) {
871e2fd0 313 printf("major connection error\n");
7392c79f 314 keepgoing = 0;
315 }
316 }
317 }
b8d0da45 318 break;
319
320 default:
321 break; /* invalid */
9de3ca7e 322 }
b8d0da45 323 }
9de3ca7e 324
325 /* Close up */
b8d0da45 326 printf("AIM just decided we didn't need to be here anymore, closing up...\n");
9de3ca7e 327
328 /* close up all connections, dead or no */
397055b1 329 aim_logoff(&aimsess);
9de3ca7e 330
9de3ca7e 331 /* Get out */
332 exit(0);
333}
334
c78446b5 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 */
ee49b735 341 char buddies[] = "Buddy1&Buddy2&ThisHereIsAName2&midendian&ewarmenhoven&";
c78446b5 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 */
a15d82b1 360 aim_bos_setgroupperm(sess, command->conn, AIM_FLAG_ALLUSERS);
c78446b5 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
ee49b735 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
397055b1 395int faimtest_serverready(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 396{
ee49b735 397 int famcount, i;
398 unsigned short *families;
399 va_list ap;
26af6789 400
ee49b735 401 va_start(ap, command);
402 famcount = va_arg(ap, int);
403 families = va_arg(ap, unsigned short *);
404 va_end(ap);
9de3ca7e 405
ee49b735 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");
0c20631f 410
ee49b735 411 switch (command->conn->type) {
412 case AIM_CONN_TYPE_BOS:
0c20631f 413
ee49b735 414 aim_setversions(sess, command->conn);
415 aim_bos_reqrate(sess, command->conn); /* request rate info */
7392c79f 416
ee49b735 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 }
7392c79f 446
9de3ca7e 447 return 1;
448}
449
96f8b1ed 450int faimtest_parse_buddyrights(struct aim_session_t *sess, struct command_rx_struct *command, ...)
00f3b08b 451{
96f8b1ed 452 va_list ap;
453 unsigned short maxbuddies, maxwatchers;
454
455 va_start(ap, command);
e7fb57f5 456 maxbuddies = va_arg(ap, int);
457 maxwatchers = va_arg(ap, int);
96f8b1ed 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
c78446b5 465int faimtest_bosrights(struct aim_session_t *sess, struct command_rx_struct *command, ...)
466{
96f8b1ed 467 unsigned short maxpermits, maxdenies;
468 va_list ap;
469
470 va_start(ap, command);
e7fb57f5 471 maxpermits = va_arg(ap, int);
472 maxdenies = va_arg(ap, int);
96f8b1ed 473 va_end(ap);
474
475 printf("faimtest: BOS rights: Max permit = %d / Max deny = %d\n", maxpermits, maxdenies);
476
c78446b5 477 aim_bos_clientready(sess, command->conn);
478
479 printf("faimtest: officially connected to BOS.\n");
480
481 return 1;
482}
483
9de3ca7e 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 */
397055b1 499int faimtest_handleredirect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 500{
501 va_list ap;
502 int serviceid;
503 char *ip;
78b3fb13 504 unsigned char *cookie;
9de3ca7e 505
9de3ca7e 506 va_start(ap, command);
507 serviceid = va_arg(ap, int);
508 ip = va_arg(ap, char *);
78b3fb13 509 cookie = va_arg(ap, unsigned char *);
0c20631f 510
9de3ca7e 511 switch(serviceid)
512 {
9de3ca7e 513 case 0x0007: /* Authorizer */
514 {
515 struct aim_conn_t *tstconn;
516 /* Open a connection to the Auth */
397055b1 517 tstconn = aim_newconn(sess, AIM_CONN_TYPE_AUTH, ip);
22517493 518 if ( (tstconn==NULL) || (tstconn->status & AIM_CONN_STATUS_RESOLVERR) )
9de3ca7e 519 fprintf(stderr, "faimtest: unable to reconnect with authorizer\n");
22517493 520 else {
ee49b735 521 aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_FLAPVER, faimtest_flapversion, 0);
22517493 522 aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
9de3ca7e 523 /* Send the cookie to the Auth */
397055b1 524 aim_auth_sendcookie(sess, tstconn, cookie);
22517493 525 }
9de3ca7e 526
527 }
528 break;
529 case 0x000d: /* ChatNav */
530 {
531 struct aim_conn_t *tstconn = NULL;
397055b1 532 tstconn = aim_newconn(sess, AIM_CONN_TYPE_CHATNAV, ip);
22517493 533 if ( (tstconn==NULL) || (tstconn->status & AIM_CONN_STATUS_RESOLVERR)) {
040457cc 534 fprintf(stderr, "faimtest: unable to connect to chatnav server\n");
535 if (tstconn) aim_conn_kill(sess, &tstconn);
536 return 1;
537 }
0c20631f 538#if 0
397055b1 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);
0c20631f 541#endif
542 aim_conn_addhandler(sess, tstconn, 0x0001, 0x0003, faimtest_serverready, 0);
22517493 543 aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
397055b1 544 aim_auth_sendcookie(sess, tstconn, cookie);
9de3ca7e 545 fprintf(stderr, "\achatnav: connected\n");
546 }
547 break;
548 case 0x000e: /* Chat */
549 {
0c20631f 550 char *roomname = NULL;
9f20a4e3 551 int exchange;
9de3ca7e 552 struct aim_conn_t *tstconn = NULL;
0c20631f 553
554 roomname = va_arg(ap, char *);
9f20a4e3 555 exchange = va_arg(ap, int);
0c20631f 556
397055b1 557 tstconn = aim_newconn(sess, AIM_CONN_TYPE_CHAT, ip);
22517493 558 if ( (tstconn==NULL) || (tstconn->status & AIM_CONN_STATUS_RESOLVERR))
9de3ca7e 559 {
560 fprintf(stderr, "faimtest: unable to connect to chat server\n");
040457cc 561 if (tstconn) aim_conn_kill(sess, &tstconn);
9de3ca7e 562 return 1;
0c20631f 563 }
9f20a4e3 564 printf("faimtest: chat: connected to %s on exchange %d\n", roomname, exchange);
0c20631f 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);
22517493 572 aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
0c20631f 573 aim_auth_sendcookie(sess, tstconn, cookie);
9de3ca7e 574 }
575 break;
576 default:
577 printf("uh oh... got redirect for unknown service 0x%04x!!\n", serviceid);
578 /* dunno */
579 }
580
9de3ca7e 581 va_end(ap);
582
0c20631f 583 return 1;
9de3ca7e 584}
585
01b59e1e 586int faimtest_parse_authresp(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 587{
355982c5 588 va_list ap;
9de3ca7e 589 struct aim_conn_t *bosconn = NULL;
355982c5 590 char *sn = NULL, *bosip = NULL, *errurl = NULL, *email = NULL;
591 unsigned char *cookie = NULL;
592 int errorcode = 0, regstatus = 0;
89bce177 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
355982c5 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 *);
89bce177 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
355982c5 617 va_end(ap);
01b59e1e 618
355982c5 619 printf("Screen name: %s\n", sn);
01b59e1e 620
621 /*
622 * Check for error.
623 */
355982c5 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 }
01b59e1e 630
355982c5 631 printf("Reg status: %2d\n", regstatus);
632 printf("Email: %s\n", email);
633 printf("BOS IP: %s\n", bosip);
9de3ca7e 634
89bce177 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
9de3ca7e 641 printf("Closing auth connection...\n");
040457cc 642 aim_conn_kill(sess, &command->conn);
355982c5 643 if (!(bosconn = aim_newconn(sess, AIM_CONN_TYPE_BOS, bosip))) {
040457cc 644 fprintf(stderr, "faimtest: could not connect to BOS: internal error\n");
355982c5 645 return 1;
22517493 646 } else if (bosconn->status & AIM_CONN_STATUS_CONNERR) {
040457cc 647 fprintf(stderr, "faimtest: could not connect to BOS\n");
648 aim_conn_kill(sess, &bosconn);
355982c5 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);
ee49b735 656 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, 0x0018, faimtest_hostversions, 0);
355982c5 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);
040457cc 676
355982c5 677 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, faimtest_parse_connerr, 0);
040457cc 678
355982c5 679 aim_auth_sendcookie(sess, bosconn, cookie);
680
9de3ca7e 681 return 1;
682}
683
a15d82b1 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
397055b1 705int faimtest_parse_userinfo(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 706{
707 struct aim_userinfo_s *userinfo;
708 char *prof_encoding = NULL;
709 char *prof = NULL;
5e02cf44 710 unsigned short inforeq = 0;
9de3ca7e 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 *);
e7fb57f5 717 inforeq = va_arg(ap, int);
9de3ca7e 718 va_end(ap);
719
720 printf("faimtest: userinfo: sn: %s\n", userinfo->sn);
721 printf("faimtest: userinfo: warnlevel: 0x%04x\n", userinfo->warnlevel);
a15d82b1 722 printf("faimtest: userinfo: flags: 0x%04x = ", userinfo->flags);
723 printuserflags(userinfo->flags);
9de3ca7e 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
5e02cf44 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");
9de3ca7e 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
a15d82b1 750 * int flags flags
9de3ca7e 751 * ulong membersince time_t of date of signup
752 * ulong onsince time_t of date of singon
753 * int idletime min (sec?) idle
24286d93 754 * u_int icbmflags sets AIM_IMFLAGS_{AWAY,ACK}
9de3ca7e 755 *
756 */
397055b1 757int faimtest_parse_incoming_im(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 758{
26af6789 759 int channel;
9de3ca7e 760 va_list ap;
9de3ca7e 761
762 va_start(ap, command);
26af6789 763 channel = va_arg(ap, int);
9de3ca7e 764
26af6789 765 /*
766 * Channel 1: Standard Message
767 */
040457cc 768 if (channel == 1) {
769 struct aim_userinfo_s *userinfo;
770 char *msg = NULL;
771 u_int icbmflags = 0;
772 char *tmpstr = NULL;
e7fb57f5 773 unsigned short flag1, flag2;
040457cc 774
775 userinfo = va_arg(ap, struct aim_userinfo_s *);
776 msg = va_arg(ap, char *);
777 icbmflags = va_arg(ap, u_int);
e7fb57f5 778 flag1 = va_arg(ap, int);
779 flag2 = va_arg(ap, int);
040457cc 780 va_end(ap);
781
782 printf("faimtest: icbm: sn = \"%s\"\n", userinfo->sn);
783 printf("faimtest: icbm: warnlevel = 0x%04x\n", userinfo->warnlevel);
a15d82b1 784 printf("faimtest: icbm: flags = 0x%04x = ", userinfo->flags);
785 printuserflags(userinfo->flags);
040457cc 786 printf("\n");
a15d82b1 787
040457cc 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);
b69540e3 791 printf("faimtest: icbm: capabilities = 0x%04x\n", userinfo->capabilities);
040457cc 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) {
b69540e3 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);
040457cc 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");
1a8c261b 824 aim_send_im(sess, command->conn, userinfo->sn, AIM_IMFLAGS_ACK, "Good day to you too.");
98c88242 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);
f2d214f9 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);
040457cc 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)) {
7392c79f 841 aim_chatnav_createroom(sess,aim_getconn_type(sess, AIM_CONN_TYPE_CHATNAV), (strlen(tmpstr) < 7)?"WorldDomination":tmpstr+7, 0x0004);
040457cc 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);
7392c79f 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);
ee49b735 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);
96f8b1ed 860 } else if (!strncmp(tmpstr, "reqsendmsg", 10)) {
a3619f23 861 aim_send_im(sess, command->conn, "vaxherder", 0, "sendmsg 7900");
b69540e3 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 }
040457cc 877 } else {
878 printf("unknown command.\n");
b69540e3 879 aim_add_buddy(sess, command->conn, userinfo->sn);
040457cc 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
e7fb57f5 891 reqclass = va_arg(ap, int);
040457cc 892 switch (reqclass) {
b69540e3 893 case AIM_CAPS_VOICE: {
26af6789 894 userinfo = va_arg(ap, struct aim_userinfo_s *);
26af6789 895 va_end(ap);
9de3ca7e 896
040457cc 897 printf("faimtest: voice invitation: source sn = %s\n", userinfo->sn);
898 printf("faimtest: voice invitation: \twarnlevel = 0x%04x\n", userinfo->warnlevel);
a15d82b1 899 printf("faimtest: voice invitation: \tclass = 0x%04x = ", userinfo->flags);
900 printuserflags(userinfo->flags);
26af6789 901 printf("\n");
a15d82b1 902
040457cc 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);
26af6789 906
040457cc 907 break;
908 }
b69540e3 909 case AIM_CAPS_GETFILE: {
871e2fd0 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
040457cc 935 break;
871e2fd0 936#endif
040457cc 937 }
b69540e3 938 case AIM_CAPS_SENDFILE: {
939 printf("faimtest: send file!\n");
940 break;
941 }
942 case AIM_CAPS_CHAT: {
040457cc 943 char *msg,*encoding,*lang;
944 struct aim_chat_roominfo *roominfo;
26af6789 945
040457cc 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);
26af6789 952
040457cc 953 printf("faimtest: chat invitation: source sn = %s\n", userinfo->sn);
954 printf("faimtest: chat invitation: \twarnlevel = 0x%04x\n", userinfo->warnlevel);
a15d82b1 955 printf("faimtest: chat invitation: \tclass = 0x%04x = ", userinfo->flags);
956 printuserflags(userinfo->flags);
040457cc 957 printf("\n");
a15d82b1 958
040457cc 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);
26af6789 962
040457cc 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 }
7392c79f 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
7392c79f 996 printf("faimtest: OFT: DirectIM: connected to %s\n", userinfo->sn);
997
3b101546 998 aim_send_im_direct(sess, newconn, "goodday");
999
7392c79f 1000 break;
1001 }
040457cc 1002 default:
1003 printf("faimtest: icbm: unknown reqclass (%d)\n", reqclass);
1004 } /* switch */
1005 } else
26af6789 1006 printf("faimtest does not support channels > 2 (chan = %02x)\n", channel);
9de3ca7e 1007 printf("faimtest: icbm: done with ICBM handling\n");
1008
1009 return 1;
1010}
1011
7392c79f 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
e7fb57f5 1018 va_start(ap, command);
7392c79f 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}
7392c79f 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
e7fb57f5 1042 va_start(ap, command);
7392c79f 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
e7fb57f5 1058 va_start(ap, command);
7392c79f 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{
871e2fd0 1092 va_list ap;
1093 struct aim_conn_t *conn;
1094 char *sn;
1095
e7fb57f5 1096 va_start(ap, command);
871e2fd0 1097 conn = va_arg(ap, struct aim_conn_t *);
1098 sn = va_arg(ap, char *);
1099 va_end(ap);
1100
871e2fd0 1101 printf("faimtest: directim: disconnected from %s\n", sn);
3b101546 1102
1103 aim_conn_kill(sess, &conn);
7392c79f 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
e7fb57f5 1112 va_start(ap, command);
7392c79f 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
397055b1 1120int faimtest_authsvrready(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 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... */
397055b1 1125 aim_auth_clientready(sess, command->conn);
9de3ca7e 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 */
397055b1 1134 aim_auth_changepasswd(sess, command->conn, "PWD1", "PWD2");
9de3ca7e 1135#endif
1136
1137 return 1;
1138}
1139
397055b1 1140int faimtest_pwdchngdone(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 1141{
1142 printf("PASSWORD CHANGE SUCCESSFUL!!!\n");
1143 return 1;
1144}
1145
397055b1 1146int faimtest_parse_oncoming(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 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
ee49b735 1155 printf("%ld %s is now online (flags: %04x = %s%s%s%s%s%s%s%s) (caps = 0x%04x)\n",
1156 time(NULL),
a15d82b1 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":"",
b69540e3 1166 userinfo->capabilities);
9de3ca7e 1167 return 1;
1168}
1169
397055b1 1170int faimtest_parse_offgoing(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 1171{
397055b1 1172 char *sn;
1173 va_list ap;
1174
1175 va_start(ap, command);
1176 sn = va_arg(ap, char *);
1177 va_end(ap);
9de3ca7e 1178
397055b1 1179 printf("\n%s has left\n", sn);
9de3ca7e 1180
1181 return 1;
1182}
1183
01b59e1e 1184int faimtest_parse_motd(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1185{
96f8b1ed 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
01b59e1e 1194 char *msg;
96f8b1ed 1195 unsigned short id;
01b59e1e 1196 va_list ap;
1197
1198 va_start(ap, command);
e7fb57f5 1199 id = va_arg(ap, int);
01b59e1e 1200 msg = va_arg(ap, char *);
1201 va_end(ap);
1202
96f8b1ed 1203 printf("faimtest: motd: %s (%d / %s)\n", msg, id,
1204 (id < codeslen)?codes[id]:"unknown");
1205
ee49b735 1206 if (!connected)
1207 connected++;
1208
96f8b1ed 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 *);
e7fb57f5 1220 reason = va_arg(ap, int);
96f8b1ed 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 *);
e7fb57f5 1236 reason = va_arg(ap, int);
96f8b1ed 1237 va_end(ap);
01b59e1e 1238
96f8b1ed 1239 printf("faimtest: user information for %s unavailable (reason 0x%04x: %s)\n", destsn, reason, (reason<msgerrreasonslen)?msgerrreasons[reason]:"unknown");
1240
01b59e1e 1241 return 1;
1242}
9de3ca7e 1243
1244/*
96f8b1ed 1245 * Handles callbacks for AIM_CB_MISSED_CALL.
9de3ca7e 1246 */
397055b1 1247int faimtest_parse_misses(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 1248{
96f8b1ed 1249 static char *missedreasons[] = {
1250 "Unknown",
1251 "Message too large"};
1252 static int missedreasonslen = 2;
9de3ca7e 1253
96f8b1ed 1254 va_list ap;
1255 unsigned short chan, nummissed, reason;
1256 struct aim_userinfo_s *userinfo;
9de3ca7e 1257
96f8b1ed 1258 va_start(ap, command);
e7fb57f5 1259 chan = va_arg(ap, int);
96f8b1ed 1260 userinfo = va_arg(ap, struct aim_userinfo_s *);
e7fb57f5 1261 nummissed = va_arg(ap, int);
1262 reason = va_arg(ap, int);
96f8b1ed 1263 va_end(ap);
9de3ca7e 1264
96f8b1ed 1265 printf("faimtest: missed %d messages from %s (reason %d: %s)\n", nummissed, userinfo->sn, reason, (reason<missedreasonslen)?missedreasons[reason]:"unknown");
1266
00f3b08b 1267 return 1;
9de3ca7e 1268}
1269
01b59e1e 1270int faimtest_parse_login(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1271{
b5bc2a8c 1272 struct client_info_s info = {"faimtest (with SNAC login)", 4, 1, 2010, "us", "en", 0x0004, 0x0000, 0x0000004b}; /* 4.1.2010 */
78b3fb13 1273 char *key;
b5bc2a8c 1274 va_list ap;
01b59e1e 1275
b5bc2a8c 1276 va_start(ap, command);
1277 key = va_arg(ap, char *);
1278 va_end(ap);
9de3ca7e 1279
b5bc2a8c 1280 aim_send_login(sess, command->conn, screenname, password, &info, key);
01b59e1e 1281
1282 return 1;
1283}
0c20631f 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;
aa6efcfd 1329 unsigned short unknown_c9, unknown_d2, unknown_d5, maxmsglen;
1330 unsigned long creationtime;
0c20631f 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 *);
e7fb57f5 1338 unknown_c9 = va_arg(ap, int);
aa6efcfd 1339 creationtime = va_arg(ap, unsigned long);
e7fb57f5 1340 maxmsglen = va_arg(ap, int);
1341 unknown_d2 = va_arg(ap, int);
1342 unknown_d5 = va_arg(ap, int);
0c20631f 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
aa6efcfd 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
0c20631f 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 */
355982c5 1385 if (strcmp(userinfo->sn, sess->sn) != 0)
0c20631f 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{
e7fb57f5 1396 unsigned short type;
0c20631f 1397 va_list ap;
1398
e7fb57f5 1399 va_start(ap, command);
1400 type = va_arg(ap, int);
0c20631f 1401
efe9513b 1402 switch(type) {
1403 case 0x0002: {
1404 int maxrooms;
1405 struct aim_chat_exchangeinfo *exchanges;
1406 int exchangecount,i = 0;
1407
e7fb57f5 1408 maxrooms = va_arg(ap, int);
efe9513b 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++;
0c20631f 1424 }
efe9513b 1425
1426 }
1427 break;
1428 case 0x0008: {
1429 char *fqcn, *name, *ck;
9dbda50b 1430 unsigned short instance, flags, maxmsglen, maxoccupancy, unknown, exchange;
efe9513b 1431 unsigned char createperms;
1432 unsigned long createtime;
1433
1434 fqcn = va_arg(ap, char *);
e7fb57f5 1435 instance = va_arg(ap, int);
9dbda50b 1436 exchange = va_arg(ap, int);
e7fb57f5 1437 flags = va_arg(ap, int);
efe9513b 1438 createtime = va_arg(ap, unsigned long);
e7fb57f5 1439 maxmsglen = va_arg(ap, int);
1440 maxoccupancy = va_arg(ap, int);
1441 createperms = va_arg(ap, int);
1442 unknown = va_arg(ap, int);
efe9513b 1443 name = va_arg(ap, char *);
1444 ck = va_arg(ap, char *);
1445 va_end(ap);
1446
9dbda50b 1447 printf("faimtest: recieved room create reply for %s/0x%04x\n", fqcn, exchange);
efe9513b 1448 }
1449 break;
1450 default:
1451 va_end(ap);
1452 printf("faimtest: chatnav info: unknown type (%04x)\n", type);
1453 }
0c20631f 1454 return 1;
1455}
5e02cf44 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
e7fb57f5 1463 va_start(ap, command);
1464 code = va_arg(ap, int);
5e02cf44 1465 msg = va_arg(ap, char *);
1466 va_end(ap);
1467
1468 printf("faimtest: connerr: Code 0x%04x: %s\n", code, msg);
68ac63c2 1469 aim_conn_kill(sess, &command->conn); /* this will break the main loop */
5e02cf44 1470
1471 return 1;
1472}
e5012450 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}
1a8c261b 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
e7fb57f5 1499 va_start(ap, command);
1500 type = va_arg(ap, int);
1a8c261b 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
871e2fd0 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
e7fb57f5 1517 va_start(ap, command);
871e2fd0 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
e7fb57f5 1538 va_start(ap, command);
871e2fd0 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
e7fb57f5 1576 va_start(ap, command);
871e2fd0 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
e7fb57f5 1593 va_start(ap, command);
871e2fd0 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
1a8c261b 1605int faimtest_parse_ratechange(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1606{
275a2ff8 1607 static char *codes[5] = {"invalid",
1608 "change",
1609 "warning",
1610 "limit",
1611 "limit cleared"};
1a8c261b 1612 va_list ap;
275a2ff8 1613 int code;
1614 unsigned long parmid, windowsize, clear, alert, limit, disconnect;
1615 unsigned long currentavg, maxavg;
1616
1a8c261b 1617 va_start(ap, command);
275a2ff8 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
1a8c261b 1644 va_end(ap);
1645
275a2ff8 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 }
1a8c261b 1686
871e2fd0 1687 return 1;
78b3fb13 1688}
98c88242 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
98c88242 1701 return 1;
78b3fb13 1702}
This page took 0.481537 seconds and 5 git commands to generate.