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