]> andersk Git - libfaim.git/blame - utils/faimtest/faimtest.c
Rearrange.
[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;
040457cc 917
918 userinfo = va_arg(ap, struct aim_userinfo_s *);
919 msg = va_arg(ap, char *);
920 icbmflags = va_arg(ap, u_int);
e7fb57f5 921 flag1 = va_arg(ap, int);
922 flag2 = va_arg(ap, int);
040457cc 923 va_end(ap);
924
37ee990e 925 dvprintf("faimtest: icbm: sn = \"%s\"\n", userinfo->sn);
926 dvprintf("faimtest: icbm: warnlevel = 0x%04x\n", userinfo->warnlevel);
927 dvprintf("faimtest: icbm: flags = 0x%04x = ", userinfo->flags);
a15d82b1 928 printuserflags(userinfo->flags);
37ee990e 929 dinlineprintf("\n");
a15d82b1 930
37ee990e 931 dvprintf("faimtest: icbm: membersince = %lu\n", userinfo->membersince);
932 dvprintf("faimtest: icbm: onlinesince = %lu\n", userinfo->onlinesince);
933 dvprintf("faimtest: icbm: idletime = 0x%04x\n", userinfo->idletime);
934 dvprintf("faimtest: icbm: capabilities = 0x%04x\n", userinfo->capabilities);
040457cc 935
37ee990e 936 dprintf("faimtest: icbm: icbmflags = ");
040457cc 937 if (icbmflags & AIM_IMFLAGS_AWAY)
37ee990e 938 dinlineprintf("away ");
040457cc 939 if (icbmflags & AIM_IMFLAGS_ACK)
37ee990e 940 dinlineprintf("ackrequest ");
941 dinlineprintf("\n");
040457cc 942
37ee990e 943 dvprintf("faimtest: icbm: encoding flags = {%04x, %04x}\n", flag1, flag2);
040457cc 944
37ee990e 945 dvprintf("faimtest: icbm: message: %s\n", msg);
040457cc 946
947 if (msg) {
b69540e3 948 int i = 0;
949
950 while (msg[i] == '<') {
951 if (msg[i] == '<') {
952 while (msg[i] != '>')
953 i++;
954 i++;
955 }
956 }
957 tmpstr = msg+i;
958
37ee990e 959 dvprintf("tmpstr = %s\n", tmpstr);
040457cc 960
961 if ( (strlen(tmpstr) >= 10) &&
962 (!strncmp(tmpstr, "disconnect", 10)) ) {
37ee990e 963 if (ohcaptainmycaptain)
964 aim_send_im(sess, command->conn, ohcaptainmycaptain, 0, "ta ta...");
965 aim_logoff(sess);
040457cc 966 } else if (strstr(tmpstr, "goodday")) {
37ee990e 967 dprintf("faimtest: icbm: sending response\n");
1a8c261b 968 aim_send_im(sess, command->conn, userinfo->sn, AIM_IMFLAGS_ACK, "Good day to you too.");
98c88242 969 } else if (strstr(tmpstr, "warnme")) {
37ee990e 970 dprintf("faimtest: icbm: sending non-anon warning\n");
98c88242 971 aim_send_warning(sess, command->conn, userinfo->sn, 0);
972 } else if (strstr(tmpstr, "anonwarn")) {
37ee990e 973 dprintf("faimtest: icbm: sending anon warning\n");
98c88242 974 aim_send_warning(sess, command->conn, userinfo->sn, AIM_WARN_ANON);
f2d214f9 975 } else if (strstr(tmpstr, "setdirectoryinfo")) {
37ee990e 976 dprintf("faimtest: icbm: sending backwards profile data\n");
f2d214f9 977 aim_setdirectoryinfo(sess, command->conn, "tsrif", "elddim", "tsal", "nediam", "emankcin", "teerts", "ytic", "etats", "piz", 0, 1);
978 } else if (strstr(tmpstr, "setinterests")) {
37ee990e 979 dprintf("faimtest: icbm: setting fun interests\n");
f2d214f9 980 aim_setuserinterests(sess, command->conn, "interest1", "interest2", "interest3", "interest4", "interest5", 1);
37ee990e 981 } else if (!strncmp(tmpstr, "getfile", 7)) {
982 if (!ohcaptainmycaptain) {
983 aim_send_im(sess, command->conn, userinfo->sn, AIM_IMFLAGS_ACK, "I have no owner!");
984 } else {
985 struct aim_conn_t *newconn;
986 newconn = aim_getfile_initiate(sess, command->conn, (strlen(tmpstr) < 8)?ohcaptainmycaptain:tmpstr+8);
987 dvprintf("faimtest: getting file listing from %s\n", (strlen(tmpstr) < 8)?ohcaptainmycaptain:tmpstr+8);
988 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEINITIATE, faimtest_getfile_initiate,0);
989 }
040457cc 990 } else if (!strncmp(tmpstr, "open chatnav", 12)) {
991 aim_bos_reqservice(sess, command->conn, AIM_CONN_TYPE_CHATNAV);
040457cc 992 } else if (!strncmp(tmpstr, "create", 6)) {
7392c79f 993 aim_chatnav_createroom(sess,aim_getconn_type(sess, AIM_CONN_TYPE_CHATNAV), (strlen(tmpstr) < 7)?"WorldDomination":tmpstr+7, 0x0004);
040457cc 994 } else if (!strncmp(tmpstr, "close chatnav", 13)) {
995 struct aim_conn_t *chatnavconn;
996 chatnavconn = aim_getconn_type(sess, AIM_CONN_TYPE_CHATNAV);
997 aim_conn_kill(sess, &chatnavconn);
998 } else if (!strncmp(tmpstr, "join", 4)) {
999 aim_chat_join(sess, command->conn, 0x0004, "worlddomination");
1000 } else if (!strncmp(tmpstr, "leave", 5))
1001 aim_chat_leaveroom(sess, "worlddomination");
1002 else if (!strncmp(tmpstr, "getinfo", 7)) {
1003 aim_getinfo(sess, command->conn, "75784102", AIM_GETINFO_GENERALINFO);
1004 aim_getinfo(sess, command->conn, "15853637", AIM_GETINFO_AWAYMESSAGE);
7392c79f 1005 } else if (!strncmp(tmpstr, "open directim", 13)) {
1006 struct aim_conn_t *newconn;
1007 newconn = aim_directim_initiate(sess, command->conn, NULL, userinfo->sn);
37ee990e 1008 } else if(!(strncmp(tmpstr, "lookup", 6))) {
1009 aim_usersearch_address(sess, command->conn, tmpstr+7);
96f8b1ed 1010 } else if (!strncmp(tmpstr, "reqsendmsg", 10)) {
37ee990e 1011 aim_send_im(sess, command->conn, ohcaptainmycaptain, 0, "sendmsg 7900");
64c78745 1012 } else if (!strncmp(tmpstr, "reqauth", 7)) {
1013 aim_bos_reqservice(sess, command->conn, AIM_CONN_TYPE_AUTH);
1014 } else if (!strncmp(tmpstr, "reqconfirm", 10)) {
1015 aim_auth_reqconfirm(sess, aim_getconn_type(sess, AIM_CONN_TYPE_AUTH));
1016 } else if (!strncmp(tmpstr, "reqemail", 8)) {
1017 aim_auth_getinfo(sess, aim_getconn_type(sess, AIM_CONN_TYPE_AUTH), 0x0011);
1018 } else if (!strncmp(tmpstr, "changepass", 8)) {
1019 aim_auth_changepasswd(sess, aim_getconn_type(sess, AIM_CONN_TYPE_AUTH), "NEWPASSWORD", "OLDPASSWORD");
1020 } else if (!strncmp(tmpstr, "setemail", 8)) {
1021 aim_auth_setemail(sess, aim_getconn_type(sess, AIM_CONN_TYPE_AUTH), "NEWEMAILADDRESS");
b69540e3 1022 } else if (!strncmp(tmpstr, "sendmsg", 7)) {
1023 int i;
1024 i = atoi(tmpstr+8);
1025 if (i < 10000) {
1026 char *newbuf;
1027 int z;
1028
1029 newbuf = malloc(i+1);
1030 for (z = 0; z < i; z++) {
1031 newbuf[z] = (z % 10)+0x30;
1032 }
1033 newbuf[i] = '\0';
1034 aim_send_im(sess, command->conn, userinfo->sn, 0, newbuf);
1035 free(newbuf);
1036 }
040457cc 1037 } else {
37ee990e 1038 dprintf("unknown command.\n");
b69540e3 1039 aim_add_buddy(sess, command->conn, userinfo->sn);
040457cc 1040 }
1041
1042 }
1043 }
1044 /*
1045 * Channel 2: Rendevous Request
1046 */
1047 else if (channel == 2) {
1048 struct aim_userinfo_s *userinfo;
1049 unsigned short reqclass;
1050
e7fb57f5 1051 reqclass = va_arg(ap, int);
040457cc 1052 switch (reqclass) {
b69540e3 1053 case AIM_CAPS_VOICE: {
26af6789 1054 userinfo = va_arg(ap, struct aim_userinfo_s *);
26af6789 1055 va_end(ap);
9de3ca7e 1056
37ee990e 1057 dvprintf("faimtest: voice invitation: source sn = %s\n", userinfo->sn);
1058 dvprintf("faimtest: voice invitation: \twarnlevel = 0x%04x\n", userinfo->warnlevel);
1059 dvprintf("faimtest: voice invitation: \tclass = 0x%04x = ", userinfo->flags);
a15d82b1 1060 printuserflags(userinfo->flags);
37ee990e 1061 dinlineprintf("\n");
a15d82b1 1062
040457cc 1063 /* we dont get membersince on chat invites! */
37ee990e 1064 dvprintf("faimtest: voice invitation: \tonlinesince = %lu\n", userinfo->onlinesince);
1065 dvprintf("faimtest: voice invitation: \tidletime = 0x%04x\n", userinfo->idletime);
26af6789 1066
040457cc 1067 break;
1068 }
b69540e3 1069 case AIM_CAPS_GETFILE: {
871e2fd0 1070#ifdef FILESUPPORT
1071 char *ip, *cookie;
1072 struct aim_conn_t *newconn;
37ee990e 1073 struct aim_fileheader_t *fh;
871e2fd0 1074
1075 userinfo = va_arg(ap, struct aim_userinfo_s *);
1076 ip = va_arg(ap, char *);
1077 cookie = va_arg(ap, char *);
1078 va_end(ap);
1079
37ee990e 1080 dvprintf("faimtest: get file request from %s (at %s)\n", userinfo->sn, ip);
871e2fd0 1081
37ee990e 1082 fh = aim_getlisting(listingfile);
871e2fd0 1083
37ee990e 1084 if( (newconn = aim_accepttransfer(sess, command->conn, userinfo->sn, cookie, ip, fh->totfiles, fh->totsize, fh->size, fh->checksum, reqclass)) == NULL ) {
1085 dprintf("faimtest: getfile: requestconn: apparent error in accepttransfer\n");
871e2fd0 1086 break;
1087 }
37ee990e 1088
1089 free(fh);
1090
1091 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILELISTINGREQ, faimtest_getfile_listingreq, 0);
871e2fd0 1092 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEFILEREQ, faimtest_getfile_filereq, 0);
1093 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEFILESEND, faimtest_getfile_filesend, 0);
1094 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILECOMPLETE, faimtest_getfile_complete, 0);
37ee990e 1095
871e2fd0 1096 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEDISCONNECT, faimtest_getfile_disconnect, 0);
1097
37ee990e 1098 dprintf("faimtest: getfile connect succeeded, handlers added.\n");
871e2fd0 1099
040457cc 1100 break;
871e2fd0 1101#endif
040457cc 1102 }
b69540e3 1103 case AIM_CAPS_SENDFILE: {
37ee990e 1104 dprintf("faimtest: send file!\n");
b69540e3 1105 break;
1106 }
1107 case AIM_CAPS_CHAT: {
040457cc 1108 char *msg,*encoding,*lang;
1109 struct aim_chat_roominfo *roominfo;
26af6789 1110
040457cc 1111 userinfo = va_arg(ap, struct aim_userinfo_s *);
1112 roominfo = va_arg(ap, struct aim_chat_roominfo *);
1113 msg = va_arg(ap, char *);
1114 encoding = va_arg(ap, char *);
1115 lang = va_arg(ap, char *);
1116 va_end(ap);
26af6789 1117
37ee990e 1118 dvprintf("faimtest: chat invitation: source sn = %s\n", userinfo->sn);
1119 dvprintf("faimtest: chat invitation: \twarnlevel = 0x%04x\n", userinfo->warnlevel);
1120 dvprintf("faimtest: chat invitation: \tclass = 0x%04x = ", userinfo->flags);
a15d82b1 1121 printuserflags(userinfo->flags);
37ee990e 1122 dinlineprintf("\n");
a15d82b1 1123
040457cc 1124 /* we dont get membersince on chat invites! */
37ee990e 1125 dvprintf("faimtest: chat invitation: \tonlinesince = %lu\n", userinfo->onlinesince);
1126 dvprintf("faimtest: chat invitation: \tidletime = 0x%04x\n", userinfo->idletime);
26af6789 1127
37ee990e 1128 dvprintf("faimtest: chat invitation: message = %s\n", msg);
1129 dvprintf("faimtest: chat invitation: room name = %s\n", roominfo->name);
1130 dvprintf("faimtest: chat invitation: encoding = %s\n", encoding);
1131 dvprintf("faimtest: chat invitation: language = %s\n", lang);
1132 dvprintf("faimtest: chat invitation: exchange = 0x%04x\n", roominfo->exchange);
1133 dvprintf("faimtest: chat invitation: instance = 0x%04x\n", roominfo->instance);
1134 dvprintf("faimtest: chat invitiation: autojoining %s...\n", roominfo->name);
040457cc 1135 /*
1136 * Automatically join room...
1137 */
1138 aim_chat_join(sess, command->conn, 0x0004, roominfo->name);
1139 break;
1140 }
7392c79f 1141 case AIM_CAPS_IMIMAGE: {
1142 struct aim_directim_priv *priv;
1143 struct aim_conn_t *newconn;
1144
37ee990e 1145 dprintf("faimtest: icbm: rendezvous imimage\n");
7392c79f 1146
1147 userinfo = va_arg(ap, struct aim_userinfo_s *);
1148 priv = va_arg(ap, struct aim_directim_priv *);
1149 va_end(ap);
1150
37ee990e 1151 dvprintf("faimtest: OFT: DirectIM: request from %s (%s)\n", userinfo->sn, priv->ip);
7392c79f 1152
1153 if (!(newconn = aim_directim_connect(sess, command->conn, priv))) {
37ee990e 1154 dprintf("faimtest: icbm: imimage: could not connect\n");
7392c79f 1155 break;
1156 }
1157 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, faimtest_directim_incoming, 0);
1158 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMDISCONNECT, faimtest_directim_disconnect, 0);
1159 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, faimtest_directim_typing, 0);
1160
37ee990e 1161 dvprintf("faimtest: OFT: DirectIM: connected to %s\n", userinfo->sn);
7392c79f 1162
3b101546 1163 aim_send_im_direct(sess, newconn, "goodday");
1164
7392c79f 1165 break;
1166 }
040457cc 1167 default:
37ee990e 1168 dvprintf("faimtest: icbm: unknown reqclass (%d)\n", reqclass);
040457cc 1169 } /* switch */
1170 } else
37ee990e 1171 dvprintf("faimtest does not support channels > 2 (chan = %02x)\n", channel);
1172 dprintf("faimtest: icbm: done with ICBM handling\n");
9de3ca7e 1173
1174 return 1;
1175}
1176
7392c79f 1177int faimtest_directim_initiate(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1178{
1179 va_list ap;
1180 struct aim_directim_priv *priv;
1181 struct aim_conn_t *newconn;
1182
e7fb57f5 1183 va_start(ap, command);
7392c79f 1184 newconn = va_arg(ap, struct aim_conn_t *);
1185 va_end(ap);
1186
1187 priv = (struct aim_directim_priv *)newconn->priv;
1188
37ee990e 1189 dvprintf("faimtest: OFT: DirectIM: intitiate success to %s\n", priv->ip);
7392c79f 1190
1191 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, faimtest_directim_incoming, 0);
1192 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMDISCONNECT, faimtest_directim_disconnect, 0);
1193 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, faimtest_directim_typing, 0);
1194
1195 aim_send_im_direct(sess, newconn, "goodday");
1196
37ee990e 1197 dvprintf("faimtest: OFT: DirectIM: connected to %s\n", priv->sn);
7392c79f 1198
1199 return 1;
1200}
7392c79f 1201
1202int faimtest_directim_connect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1203{
1204 va_list ap;
1205 struct aim_directim_priv *priv;
1206
e7fb57f5 1207 va_start(ap, command);
7392c79f 1208 priv = va_arg(ap, struct aim_directim_priv *);
1209
1210 va_end(ap);
1211
37ee990e 1212 dprintf("faimtest: directim_connect\n");
7392c79f 1213
1214 return 1;
1215}
1216
1217int faimtest_directim_incoming(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1218{
1219 va_list ap;
1220 char *sn = NULL, *msg = NULL;
1221 struct aim_conn_t *conn;
1222
e7fb57f5 1223 va_start(ap, command);
7392c79f 1224 conn = va_arg(ap, struct aim_conn_t *);
1225 sn = va_arg(ap, char *);
1226 msg = va_arg(ap, char *);
1227 va_end(ap);
1228
37ee990e 1229 dvprintf("faimtest: Directim from %s: %s\n", sn, msg);
7392c79f 1230 if (!strncmp(msg, "sendmsg", 7)) {
1231 int i;
1232 i = atoi(msg+8);
1233 if (i < 10000) {
1234 char *newbuf;
1235 int z;
1236
1237 newbuf = malloc(i+1);
1238 for (z = 0; z < i; z++) {
1239 newbuf[z] = (z % 10)+0x30;
1240 }
1241 newbuf[i] = '\0';
1242 aim_send_im_direct(sess, conn, newbuf);
1243 free(newbuf);
1244 }
1245 } else if (!strncmp(msg, "goodday", 7)) {
1246 aim_send_im_direct(sess, conn, "Good day to you, too");
1247 } else {
1248 char newmsg[1024];
1249 snprintf(newmsg, sizeof(newmsg), "unknown (%s)\n", msg);
1250 aim_send_im_direct(sess, conn, newmsg);
1251 }
1252 return 1;
1253}
1254
1255int faimtest_directim_disconnect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1256{
871e2fd0 1257 va_list ap;
1258 struct aim_conn_t *conn;
1259 char *sn;
1260
e7fb57f5 1261 va_start(ap, command);
871e2fd0 1262 conn = va_arg(ap, struct aim_conn_t *);
1263 sn = va_arg(ap, char *);
1264 va_end(ap);
1265
37ee990e 1266 dvprintf("faimtest: directim: disconnected from %s\n", sn);
3b101546 1267
1268 aim_conn_kill(sess, &conn);
7392c79f 1269 return 1;
1270}
1271
1272int faimtest_directim_typing(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1273{
1274 va_list ap;
1275 char *sn;
1276
e7fb57f5 1277 va_start(ap, command);
7392c79f 1278 sn = va_arg(ap, char *);
1279 va_end(ap);
1280
37ee990e 1281 dvprintf("faimtest: ohmigod! %s has started typing (DirectIM). He's going to send you a message! *squeal*\n", sn);
7392c79f 1282 return 1;
1283}
1284
64c78745 1285int faimtest_infochange(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 1286{
64c78745 1287 unsigned short change = 0;
1288 int perms, type, length, str;
1289 char *val;
1290 va_list ap;
9de3ca7e 1291
64c78745 1292 va_start(ap, command);
1293 perms = va_arg(ap, int);
1294 type = va_arg(ap, int);
1295 length = va_arg(ap, int);
1296 val = va_arg(ap, char *);
1297 str = va_arg(ap, int);
1298 va_end(ap);
9de3ca7e 1299
64c78745 1300 if (aimutil_get16(command->data+2) == 0x0005)
1301 change = 1;
1302
1303 dvprintf("info%s: perms = %d, type = %x, length = %d, val = %s\n", change?" change":"", perms, type, length, str?val:"(not string)");
9de3ca7e 1304
9de3ca7e 1305 return 1;
1306}
1307
397055b1 1308int faimtest_parse_oncoming(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 1309{
1310 struct aim_userinfo_s *userinfo;
1311
1312 va_list ap;
1313 va_start(ap, command);
1314 userinfo = va_arg(ap, struct aim_userinfo_s *);
1315 va_end(ap);
1316
37ee990e 1317 dvprintf("%ld %s is now online (flags: %04x = %s%s%s%s%s%s%s%s) (caps = 0x%04x)\n",
ee49b735 1318 time(NULL),
a15d82b1 1319 userinfo->sn, userinfo->flags,
1320 (userinfo->flags&AIM_FLAG_UNCONFIRMED)?" UNCONFIRMED":"",
1321 (userinfo->flags&AIM_FLAG_ADMINISTRATOR)?" ADMINISTRATOR":"",
1322 (userinfo->flags&AIM_FLAG_AOL)?" AOL":"",
1323 (userinfo->flags&AIM_FLAG_OSCAR_PAY)?" OSCAR_PAY":"",
1324 (userinfo->flags&AIM_FLAG_FREE)?" FREE":"",
1325 (userinfo->flags&AIM_FLAG_AWAY)?" AWAY":"",
1326 (userinfo->flags&AIM_FLAG_UNKNOWN40)?" UNKNOWN40":"",
1327 (userinfo->flags&AIM_FLAG_UNKNOWN80)?" UNKNOWN80":"",
b69540e3 1328 userinfo->capabilities);
9de3ca7e 1329 return 1;
1330}
1331
397055b1 1332int faimtest_parse_offgoing(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 1333{
397055b1 1334 char *sn;
1335 va_list ap;
1336
1337 va_start(ap, command);
1338 sn = va_arg(ap, char *);
1339 va_end(ap);
9de3ca7e 1340
37ee990e 1341 dvprintf("\n%s has left\n", sn);
9de3ca7e 1342
1343 return 1;
1344}
1345
01b59e1e 1346int faimtest_parse_motd(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1347{
96f8b1ed 1348 static char *codes[] = {
1349 "Unknown",
1350 "Mandatory upgrade",
1351 "Advisory upgrade",
1352 "System bulletin",
1353 "Top o' the world!"};
1354 static int codeslen = 5;
1355
01b59e1e 1356 char *msg;
96f8b1ed 1357 unsigned short id;
01b59e1e 1358 va_list ap;
1359
1360 va_start(ap, command);
e7fb57f5 1361 id = va_arg(ap, int);
01b59e1e 1362 msg = va_arg(ap, char *);
1363 va_end(ap);
1364
37ee990e 1365 dvprintf("faimtest: motd: %s (%d / %s)\n", msg, id,
1366 (id < codeslen)?codes[id]:"unknown");
96f8b1ed 1367
ee49b735 1368 if (!connected)
1369 connected++;
1370
96f8b1ed 1371 return 1;
1372}
1373
1449ad2b 1374int faimtest_parse_genericerr(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1375{
1376 va_list ap;
1377 unsigned short reason;
1378
1379 va_start(ap, command);
1380 reason = va_arg(ap, int);
1381 va_end(ap);
1382
37ee990e 1383 dvprintf("faimtest: snac threw error (reason 0x%04x: %s)\n", reason, (reason<msgerrreasonslen)?msgerrreasons[reason]:"unknown");
1449ad2b 1384
1385 return 1;
1386}
1387
96f8b1ed 1388int faimtest_parse_msgerr(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1389{
1390 va_list ap;
1391 char *destsn;
1392 unsigned short reason;
1393
1394 va_start(ap, command);
1395 destsn = va_arg(ap, char *);
e7fb57f5 1396 reason = va_arg(ap, int);
96f8b1ed 1397 va_end(ap);
1398
37ee990e 1399 dvprintf("faimtest: message to %s bounced (reason 0x%04x: %s)\n", destsn, reason, (reason<msgerrreasonslen)?msgerrreasons[reason]:"unknown");
96f8b1ed 1400
1401 return 1;
1402}
1403
1404int faimtest_parse_locerr(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1405{
1406 va_list ap;
1407 char *destsn;
1408 unsigned short reason;
1409
1410 va_start(ap, command);
1411 destsn = va_arg(ap, char *);
e7fb57f5 1412 reason = va_arg(ap, int);
96f8b1ed 1413 va_end(ap);
01b59e1e 1414
37ee990e 1415 dvprintf("faimtest: user information for %s unavailable (reason 0x%04x: %s)\n", destsn, reason, (reason<msgerrreasonslen)?msgerrreasons[reason]:"unknown");
96f8b1ed 1416
01b59e1e 1417 return 1;
1418}
9de3ca7e 1419
1420/*
96f8b1ed 1421 * Handles callbacks for AIM_CB_MISSED_CALL.
9de3ca7e 1422 */
397055b1 1423int faimtest_parse_misses(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 1424{
96f8b1ed 1425 static char *missedreasons[] = {
1426 "Unknown",
1427 "Message too large"};
1428 static int missedreasonslen = 2;
9de3ca7e 1429
96f8b1ed 1430 va_list ap;
1431 unsigned short chan, nummissed, reason;
1432 struct aim_userinfo_s *userinfo;
9de3ca7e 1433
96f8b1ed 1434 va_start(ap, command);
e7fb57f5 1435 chan = va_arg(ap, int);
96f8b1ed 1436 userinfo = va_arg(ap, struct aim_userinfo_s *);
e7fb57f5 1437 nummissed = va_arg(ap, int);
1438 reason = va_arg(ap, int);
96f8b1ed 1439 va_end(ap);
9de3ca7e 1440
37ee990e 1441 dvprintf("faimtest: missed %d messages from %s (reason %d: %s)\n", nummissed, userinfo->sn, reason, (reason<missedreasonslen)?missedreasons[reason]:"unknown");
96f8b1ed 1442
00f3b08b 1443 return 1;
9de3ca7e 1444}
1445
01b59e1e 1446int faimtest_parse_login(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1447{
b5bc2a8c 1448 struct client_info_s info = {"faimtest (with SNAC login)", 4, 1, 2010, "us", "en", 0x0004, 0x0000, 0x0000004b}; /* 4.1.2010 */
78b3fb13 1449 char *key;
b5bc2a8c 1450 va_list ap;
01b59e1e 1451
b5bc2a8c 1452 va_start(ap, command);
1453 key = va_arg(ap, char *);
1454 va_end(ap);
9de3ca7e 1455
b5bc2a8c 1456 aim_send_login(sess, command->conn, screenname, password, &info, key);
01b59e1e 1457
1458 return 1;
1459}
0c20631f 1460
1461int faimtest_chat_join(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1462{
1463 va_list ap;
1464 struct aim_userinfo_s *userinfo;
1465 int count = 0, i = 0;
1466
1467 va_start(ap, command);
1468 count = va_arg(ap, int);
1469 userinfo = va_arg(ap, struct aim_userinfo_s *);
1470 va_end(ap);
1471
37ee990e 1472 dvprintf("faimtest: chat: %s: New occupants have joined:\n", (char *)command->conn->priv);
0c20631f 1473 while (i < count)
37ee990e 1474 dvprintf("faimtest: chat: %s: \t%s\n", (char *)command->conn->priv, userinfo[i++].sn);
0c20631f 1475
1476 return 1;
1477}
1478
1479int faimtest_chat_leave(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1480{
1481 va_list ap;
1482 struct aim_userinfo_s *userinfo;
1483 int count = 0, i = 0;
1484
1485 va_start(ap, command);
1486 count = va_arg(ap, int);
1487 userinfo = va_arg(ap, struct aim_userinfo_s *);
1488 va_end(ap);
1489
37ee990e 1490 dvprintf("faimtest: chat: %s: Some occupants have left:\n", (char *)command->conn->priv);
1491
1492 for (i = 0; i < count; )
1493 dvprintf("faimtest: chat: %s: \t%s\n", (char *)command->conn->priv, userinfo[i++].sn);
0c20631f 1494
1495 return 1;
1496}
1497
1498int faimtest_chat_infoupdate(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1499{
1500 va_list ap;
1501 struct aim_userinfo_s *userinfo;
1502 struct aim_chat_roominfo *roominfo;
1503 char *roomname;
1504 int usercount,i;
1505 char *roomdesc;
aa6efcfd 1506 unsigned short unknown_c9, unknown_d2, unknown_d5, maxmsglen;
1507 unsigned long creationtime;
0c20631f 1508
1509 va_start(ap, command);
1510 roominfo = va_arg(ap, struct aim_chat_roominfo *);
1511 roomname = va_arg(ap, char *);
1512 usercount= va_arg(ap, int);
1513 userinfo = va_arg(ap, struct aim_userinfo_s *);
1514 roomdesc = va_arg(ap, char *);
e7fb57f5 1515 unknown_c9 = va_arg(ap, int);
aa6efcfd 1516 creationtime = va_arg(ap, unsigned long);
e7fb57f5 1517 maxmsglen = va_arg(ap, int);
1518 unknown_d2 = va_arg(ap, int);
1519 unknown_d5 = va_arg(ap, int);
0c20631f 1520 va_end(ap);
1521
37ee990e 1522 dvprintf("faimtest: chat: %s: info update:\n", (char *)command->conn->priv);
1523 dvprintf("faimtest: chat: %s: \tRoominfo: {%04x, %s, %04x}\n",
0c20631f 1524 (char *)command->conn->priv,
1525 roominfo->exchange,
1526 roominfo->name,
1527 roominfo->instance);
37ee990e 1528 dvprintf("faimtest: chat: %s: \tRoomname: %s\n", (char *)command->conn->priv, roomname);
1529 dvprintf("faimtest: chat: %s: \tRoomdesc: %s\n", (char *)command->conn->priv, roomdesc);
1530 dvprintf("faimtest: chat: %s: \tOccupants: (%d)\n", (char *)command->conn->priv, usercount);
0c20631f 1531
37ee990e 1532 for (i = 0; i < usercount; )
1533 dvprintf("faimtest: chat: %s: \t\t%s\n", (char *)command->conn->priv, userinfo[i++].sn);
0c20631f 1534
37ee990e 1535 dvprintf("faimtest: chat: %s: \tUnknown_c9: 0x%04x\n", (char *)command->conn->priv, unknown_c9);
1536 dvprintf("faimtest: chat: %s: \tCreation time: %lu (time_t)\n", (char *)command->conn->priv, creationtime);
1537 dvprintf("faimtest: chat: %s: \tMax message length: %d bytes\n", (char *)command->conn->priv, maxmsglen);
1538 dvprintf("faimtest: chat: %s: \tUnknown_d2: 0x%04x\n", (char *)command->conn->priv, unknown_d2);
1539 dvprintf("faimtest: chat: %s: \tUnknown_d5: 0x%02x\n", (char *)command->conn->priv, unknown_d5);
aa6efcfd 1540
0c20631f 1541 return 1;
1542}
1543
1544int faimtest_chat_incomingmsg(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1545{
1546 va_list ap;
1547 struct aim_userinfo_s *userinfo;
1548 char *msg;
1549 char tmpbuf[1152];
1550
1551 va_start(ap, command);
1552 userinfo = va_arg(ap, struct aim_userinfo_s *);
1553 msg = va_arg(ap, char *);
1554 va_end(ap);
1555
37ee990e 1556 dvprintf("faimtest: chat: %s: incoming msg from %s: %s\n", (char *)command->conn->priv, userinfo->sn, msg);
0c20631f 1557
1558 /*
1559 * Do an echo for testing purposes. But not for ourselves ("oops!")
1560 */
355982c5 1561 if (strcmp(userinfo->sn, sess->sn) != 0)
0c20631f 1562 {
1563 sprintf(tmpbuf, "(%s said \"%s\")", userinfo->sn, msg);
1564 aim_chat_send_im(sess, command->conn, tmpbuf);
1565 }
1566
1567 return 1;
1568}
1569
1570int faimtest_chatnav_info(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1571{
e7fb57f5 1572 unsigned short type;
0c20631f 1573 va_list ap;
1574
e7fb57f5 1575 va_start(ap, command);
1576 type = va_arg(ap, int);
0c20631f 1577
efe9513b 1578 switch(type) {
1579 case 0x0002: {
1580 int maxrooms;
1581 struct aim_chat_exchangeinfo *exchanges;
1582 int exchangecount,i = 0;
1583
e7fb57f5 1584 maxrooms = va_arg(ap, int);
efe9513b 1585 exchangecount = va_arg(ap, int);
1586 exchanges = va_arg(ap, struct aim_chat_exchangeinfo *);
1587 va_end(ap);
1588
37ee990e 1589 dprintf("faimtest: chat info: Chat Rights:\n");
1590 dvprintf("faimtest: chat info: \tMax Concurrent Rooms: %d\n", maxrooms);
efe9513b 1591
37ee990e 1592 dvprintf("faimtest: chat info: \tExchange List: (%d total)\n", exchangecount);
1593 for (i = 0; i < exchangecount; i++) {
1594 dvprintf("faimtest: chat info: \t\t%x: %s (%s/%s)\n",
1595 exchanges[i].number,
1596 exchanges[i].name,
1597 exchanges[i].charset1,
1598 exchanges[i].lang1);
0c20631f 1599 }
efe9513b 1600
1601 }
1602 break;
1603 case 0x0008: {
1604 char *fqcn, *name, *ck;
9dbda50b 1605 unsigned short instance, flags, maxmsglen, maxoccupancy, unknown, exchange;
efe9513b 1606 unsigned char createperms;
1607 unsigned long createtime;
1608
1609 fqcn = va_arg(ap, char *);
e7fb57f5 1610 instance = va_arg(ap, int);
9dbda50b 1611 exchange = va_arg(ap, int);
e7fb57f5 1612 flags = va_arg(ap, int);
efe9513b 1613 createtime = va_arg(ap, unsigned long);
e7fb57f5 1614 maxmsglen = va_arg(ap, int);
1615 maxoccupancy = va_arg(ap, int);
1616 createperms = va_arg(ap, int);
1617 unknown = va_arg(ap, int);
efe9513b 1618 name = va_arg(ap, char *);
1619 ck = va_arg(ap, char *);
1620 va_end(ap);
1621
37ee990e 1622 dvprintf("faimtest: recieved room create reply for %s/0x%04x\n", fqcn, exchange);
efe9513b 1623 }
1624 break;
1625 default:
1626 va_end(ap);
37ee990e 1627 dvprintf("faimtest: chatnav info: unknown type (%04x)\n", type);
efe9513b 1628 }
0c20631f 1629 return 1;
1630}
5e02cf44 1631
1632int faimtest_parse_connerr(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1633{
1634 va_list ap;
1635 unsigned short code;
1636 char *msg = NULL;
1637
e7fb57f5 1638 va_start(ap, command);
1639 code = va_arg(ap, int);
5e02cf44 1640 msg = va_arg(ap, char *);
1641 va_end(ap);
1642
37ee990e 1643 dvprintf("faimtest: connerr: Code 0x%04x: %s\n", code, msg);
68ac63c2 1644 aim_conn_kill(sess, &command->conn); /* this will break the main loop */
5e02cf44 1645
1646 return 1;
1647}
e5012450 1648
1649int faimtest_debugconn_connect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1650{
37ee990e 1651 dprintf("faimtest: connecting to an aimdebugd!\n");
e5012450 1652
1653 /* convert the authorizer connection to a BOS connection */
1654 command->conn->type = AIM_CONN_TYPE_BOS;
1655
1656 aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_MSG, AIM_CB_MSG_INCOMING, faimtest_parse_incoming_im, 0);
1657
1658 /* tell the aimddebugd we're ready */
1659 aim_debugconn_sendconnect(sess, command->conn);
1660
1661 /* go right into main loop (don't open a BOS connection, etc) */
1662 return 1;
1663}
1a8c261b 1664
1665/*
1666 * Recieved in response to an IM sent with the AIM_IMFLAGS_ACK option.
1667 */
1668int faimtest_parse_msgack(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1669{
1670 va_list ap;
1671 unsigned short type;
1672 char *sn = NULL;
1673
e7fb57f5 1674 va_start(ap, command);
1675 type = va_arg(ap, int);
1a8c261b 1676 sn = va_arg(ap, char *);
1677 va_end(ap);
1678
37ee990e 1679 dvprintf("faimtest: msgack: 0x%04x / %s\n", type, sn);
1a8c261b 1680
1681 return 1;
1682}
1683
871e2fd0 1684#ifdef FILESUPPORT
1685int faimtest_getfile_filereq(struct aim_session_t *ses, struct command_rx_struct *command, ...)
1686{
1687 va_list ap;
1688 struct aim_conn_t *oftconn;
1689 struct aim_fileheader_t *fh;
1690 char *cookie;
1691
e7fb57f5 1692 va_start(ap, command);
871e2fd0 1693 oftconn = va_arg(ap, struct aim_conn_t *);
1694 fh = va_arg(ap, struct aim_fileheader_t *);
1695 cookie = va_arg(ap, char *);
1696 va_end(ap);
1697
37ee990e 1698 dvprintf("faimtest: request for file %s.\n", fh->name);
871e2fd0 1699
1700 return 1;
1701}
1702
1703
1704int faimtest_getfile_filesend(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1705{
1706 va_list ap;
1707 struct aim_conn_t *oftconn;
1708 struct aim_fileheader_t *fh;
1709 char *path, *cookie;
37ee990e 1710 int pos, bufpos, bufsize = 2048, i;
1711 char buf[2048];
871e2fd0 1712
1713 FILE *file;
1714
e7fb57f5 1715 va_start(ap, command);
871e2fd0 1716 oftconn = va_arg(ap, struct aim_conn_t *);
1717 fh = va_arg(ap, struct aim_fileheader_t *);
1718 cookie = va_arg(ap, char *);
1719 va_end(ap);
1720
37ee990e 1721 dvprintf("faimtest: sending file %s(%ld).\n", fh->name, fh->size);
871e2fd0 1722
37ee990e 1723 if( (path = (char *)calloc(1, strlen(listingpath) +strlen(fh->name)+2)) == NULL) {
1724 dperror("calloc");
1725 dprintf("faimtest: error in calloc of path\n");
871e2fd0 1726 return 0; /* XXX: no idea what winaim expects here =) */
1727 }
1728
37ee990e 1729 snprintf(path, strlen(listingpath)+strlen(fh->name)+2, "%s/%s", listingpath, fh->name);
871e2fd0 1730
1731
1732 if( (file = fopen(path, "r")) == NULL) {
37ee990e 1733 dvprintf("faimtest: getfile_send fopen failed for %s. damn.\n", path);
871e2fd0 1734 return 0;
1735 }
37ee990e 1736
1737 for(pos = 0; pos < fh->size; pos++) {
1738 bufpos = pos % bufsize;
1739
1740 if(bufpos == 0 && pos > 0) { /* filled our buffer. spit it across the wire */
1741 if ( (i = send(oftconn->fd, buf, bufsize, 0)) != bufsize ) {
1742 dperror("faim: getfile_send: write1");
1743 dprintf("faim: getfile_send: whoopsy, didn't write it all...\n");
1744 free(buf);
1745 return -1;
1746 }
1747 }
1748 if( (buf[bufpos] = fgetc(file)) == EOF) {
1749 if(pos != fh->size) {
1750 dvprintf("faim: getfile_send: hrm... apparent early EOF at pos 0x%x of 0x%lx\n", pos, fh->size);
1751 free(buf);
1752 return -1;
1753 }
1754 }
1755 dvprintf("%c(0x%02x) ", buf[pos], buf[pos]);
1756 }
871e2fd0 1757
37ee990e 1758 if( (i = send(oftconn->fd, buf, bufpos+1, 0)) != (bufpos+1)) {
1759 dperror("faim: getfile_send: write2");
1760 dprintf("faim: getfile_send cleanup: whoopsy, didn't write it all...\n");
1761 free(buf);
1762 return -1;
871e2fd0 1763 }
1764
37ee990e 1765
871e2fd0 1766 free(fh);
1767 return 1;
1768}
1769
1770int faimtest_getfile_complete(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1771{
1772 va_list ap;
1773 struct aim_conn_t *conn;
1774 struct aim_fileheader_t *fh;
1775
e7fb57f5 1776 va_start(ap, command);
871e2fd0 1777 conn = va_arg(ap, struct aim_conn_t *);
1778 fh = va_arg(ap, struct aim_fileheader_t *);
1779 va_end(ap);
1780
37ee990e 1781 dvprintf("faimtest: completed file transfer for %s.\n", fh->name);
871e2fd0 1782
37ee990e 1783 aim_conn_close(conn);
1784 aim_conn_kill(sess, &conn);
871e2fd0 1785 return 1;
1786}
1787
1788int faimtest_getfile_disconnect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1789{
1790 va_list ap;
1791 struct aim_conn_t *conn;
1792 char *sn;
1793
e7fb57f5 1794 va_start(ap, command);
871e2fd0 1795 conn = va_arg(ap, struct aim_conn_t *);
1796 sn = va_arg(ap, char *);
1797 va_end(ap);
1798
1799 aim_conn_kill(sess, &conn);
1800
37ee990e 1801 dvprintf("faimtest: getfile: disconnected from %s\n", sn);
1802 return 1;
1803}
1804int faimtest_getfile_initiate(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1805{
1806 va_list ap;
1807 struct aim_conn_t *conn;
1808 char *sn;
1809 struct aim_filetransfer_priv *priv;
1810
1811 va_start(ap, command);
1812 conn = va_arg(ap, struct aim_conn_t *);
1813 sn = va_arg(ap, char *);
1814 va_end(ap);
1815
1816 aim_conn_addhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEFILEREQ, faimtest_getfile_filereq, 0);
1817 aim_conn_addhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEFILESEND, faimtest_getfile_filesend, 0);
1818 aim_conn_addhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILECOMPLETE, faimtest_getfile_complete, 0);
1819 aim_conn_addhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEDISCONNECT, faimtest_getfile_disconnect, 0);
1820 aim_conn_addhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILELISTING, faimtest_getfile_listing, 0);
1821 aim_conn_addhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILELISTINGREQ, faimtest_getfile_listingreq, 0);
1822 aim_conn_addhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILERECIEVE, faimtest_getfile_recieve, 0);
1823
1824 priv = (struct aim_filetransfer_priv *)conn->priv;
1825
1826 dvprintf("faimtest: getfile: %s (%s) connected to us on %d\n", sn, priv->ip, conn->fd);
871e2fd0 1827 return 1;
1828}
871e2fd0 1829
37ee990e 1830int faimtest_getfile_listing(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1831{
1832 va_list ap;
1833 struct aim_conn_t *conn;
1834 char *listing;
1835 struct aim_filetransfer_priv *ft;
1836 char *filename, *nameend, *sizec;
1837 int filesize, namelen;
1838
1839 va_start(ap, command);
1840 conn = va_arg(ap, struct aim_conn_t *);
1841 ft = va_arg(ap, struct aim_filetransfer_priv *);
1842 listing = va_arg(ap, char *);
1843 va_end(ap);
1844
1845 dvprintf("listing on %d==================\n%s\n===========\n", conn->fd, listing);
1846
1847 nameend = strstr(listing+0x1a, "\r");
1848
1849 namelen = nameend - (listing + 0x1a);
1850
1851 filename = malloc(namelen + 1);
1852 strncpy(filename, listing+0x1a, namelen);
1853 filename[namelen] = 0x00;
1854
1855 sizec = malloc(8+1);
1856 memcpy(sizec, listing + 0x11, 8);
1857 sizec[8] = 0x00;
1858
1859 filesize = strtol(sizec, (char **)NULL, 10);
1860
1861 dvprintf("faimtest: requesting %d %s(%d long)\n", namelen, filename, filesize);
1862
1863 aim_oft_getfile_request(sess, conn, filename, filesize);
1864
1865 free(filename);
1866 free(sizec);
1867
1868 return 0;
1869}
1870
1871int faimtest_getfile_listingreq(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1872{
1873 va_list ap;
1874 struct aim_conn_t *oftconn;
1875 struct aim_fileheader_t *fh;
1876 int pos, bufpos, bufsize = 2048, i;
1877 char buf[2048];
1878
1879
1880 va_start(ap, command);
1881 oftconn = va_arg(ap, struct aim_conn_t *);
1882 fh = va_arg(ap, struct aim_fileheader_t *);
1883 va_end(ap);
1884
1885 dvprintf("faimtest: sending listing of size %ld\n", fh->size);
1886
1887 for(pos = 0; pos < fh->size; pos++) {
1888 bufpos = pos % bufsize;
1889
1890 if(bufpos == 0 && pos > 0) { /* filled our buffer. spit it across the wire */
1891 if ( (i = send(oftconn->fd, buf, bufsize, 0)) != bufsize ) {
1892 dperror("faim: getfile_send: write1");
1893 dprintf("faim: getfile_send: whoopsy, didn't write it all...\n");
1894 free(buf);
1895 return -1;
1896 }
1897 }
1898 if( (buf[bufpos] = fgetc(listingfile)) == EOF) {
1899 if(pos != fh->size) {
1900 dvprintf("faim: getfile_send: hrm... apparent early EOF at pos 0x%x of 0x%lx\n", pos, fh->size);
1901 free(buf);
1902 return -1;
1903 }
1904 }
1905 }
1906
1907 if( (i = send(oftconn->fd, buf, bufpos+1, 0)) != (bufpos+1)) {
1908 dperror("faim: getfile_send: write2");
1909 dprintf("faim: getfile_send cleanup: whoopsy, didn't write it all...\n");
1910 free(buf);
1911 return -1;
1912 }
1913
1914 dprintf("faimtest: sent listing\n");
1915 return 0;
1916}
1917
1918int faimtest_getfile_recieve(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1919{
1920 va_list ap;
1921 struct aim_conn_t *conn;
1922 struct aim_filetransfer_priv *ft;
1923 unsigned char data;
1924 int pos;
1925
1926 va_start(ap, command);
1927 conn = va_arg(ap, struct aim_conn_t *);
1928 ft = va_arg(ap, struct aim_filetransfer_priv *);
1929 va_end(ap);
1930
1931 dvprintf("faimtest: receiving %ld bytes of file data for %s:\n\t", ft->fh.size, ft->fh.name);
1932
1933 for(pos = 0; pos < ft->fh.size; pos++) {
1934 read(conn->fd, &data, 1);
1935 dvprintf("%c(%02x) ", data, data);
1936 }
1937
1938 dprintf("\n");
1939
1940 aim_oft_getfile_ack(sess, conn);
1941 aim_oft_getfile_end(sess, conn);
1942
1943 return 0;
1944}
1945#endif
1a8c261b 1946int faimtest_parse_ratechange(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1947{
275a2ff8 1948 static char *codes[5] = {"invalid",
1949 "change",
1950 "warning",
1951 "limit",
1952 "limit cleared"};
1a8c261b 1953 va_list ap;
275a2ff8 1954 int code;
d6c9fcf0 1955 unsigned long rateclass, windowsize, clear, alert, limit, disconnect;
275a2ff8 1956 unsigned long currentavg, maxavg;
1957
1a8c261b 1958 va_start(ap, command);
275a2ff8 1959
1960 /* See code explanations below */
1961 code = va_arg(ap, int);
1962
1963 /*
d6c9fcf0 1964 * See comments above aim_parse_ratechange_middle() in aim_rxhandlers.c.
275a2ff8 1965 */
d6c9fcf0 1966 rateclass = va_arg(ap, unsigned long);
275a2ff8 1967
1968 /*
1969 * Not sure what this is exactly. I think its the temporal
1970 * relation factor (ie, how to make the rest of the numbers
1971 * make sense in the real world).
1972 */
1973 windowsize = va_arg(ap, unsigned long);
1974
1975 /* Explained below */
1976 clear = va_arg(ap, unsigned long);
1977 alert = va_arg(ap, unsigned long);
1978 limit = va_arg(ap, unsigned long);
1979 disconnect = va_arg(ap, unsigned long);
1980 currentavg = va_arg(ap, unsigned long);
1981 maxavg = va_arg(ap, unsigned long);
1982
1a8c261b 1983 va_end(ap);
1984
275a2ff8 1985
37ee990e 1986 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 1987 (code < 5)?codes[code]:"invalid",
d6c9fcf0 1988 rateclass,
275a2ff8 1989 currentavg, maxavg,
1990 alert, clear,
1991 limit, disconnect,
1992 windowsize);
1993
1994 if (code == AIM_RATE_CODE_CHANGE) {
1995 /*
1996 * Not real sure when these get sent.
1997 */
1998 if (currentavg >= clear)
1999 aim_conn_setlatency(command->conn, 0);
2000
2001 } else if (code == AIM_RATE_CODE_WARNING) {
2002 /*
2003 * We start getting WARNINGs the first time we go below the 'alert'
2004 * limit (currentavg < alert) and they stop when either we pause
2005 * long enough for currentavg to go above 'clear', or until we
2006 * flood it bad enough to go below 'limit' (and start getting
2007 * LIMITs instead) or even further and go below 'disconnect' and
2008 * get disconnected completely (and won't be able to login right
2009 * away either).
2010 */
2011 aim_conn_setlatency(command->conn, windowsize/4); /* XXX this is bogus! */
2012
2013 } else if (code == AIM_RATE_CODE_LIMIT) {
2014 /*
2015 * When we hit LIMIT, messages will start getting dropped.
2016 */
2017 aim_conn_setlatency(command->conn, windowsize/2); /* XXX this is bogus! */
2018
2019 } else if (code == AIM_RATE_CODE_CLEARLIMIT) {
2020 /*
2021 * The limit is cleared when curavg goes above 'clear'.
2022 */
2023 aim_conn_setlatency(command->conn, 0);
2024 }
1a8c261b 2025
871e2fd0 2026 return 1;
78b3fb13 2027}
98c88242 2028
2029int faimtest_parse_evilnotify(struct aim_session_t *sess, struct command_rx_struct *command, ...)
2030{
2031 va_list ap;
06bc8607 2032 int newevil;
2033 struct aim_userinfo_s *userinfo;
98c88242 2034
2035 va_start(ap, command);
06bc8607 2036 newevil = va_arg(ap, int);
2037 userinfo = va_arg(ap, struct aim_userinfo_s *);
98c88242 2038 va_end(ap);
2039
06bc8607 2040 /*
2041 * Evil Notifications that are lacking userinfo->sn are anon-warns
2042 * if they are an evil increases, but are not warnings at all if its
2043 * a decrease (its the natural backoff happening).
2044 *
2045 * newevil is passed as an int representing the new evil value times
2046 * ten.
2047 */
37ee990e 2048 dvprintf("faimtest: evil level change: new value = %2.1f%% (caused by %s)\n", ((float)newevil)/10, (userinfo && strlen(userinfo->sn))?userinfo->sn:"anonymous");
2049
2050 return 1;
2051}
2052
2053int faimtest_parse_searchreply(struct aim_session_t *sess, struct command_rx_struct *command, ...)
2054{
2055 va_list ap;
2056 char *address, *SNs;
2057 int i, num;
2058
2059 va_start(ap, command);
2060 address = va_arg(ap, char *);
2061 num = va_arg(ap, int);
2062 SNs = va_arg(ap, char *);
2063 va_end(ap);
2064
2065 dvprintf("faimtest: E-Mail Search Results for %s: ", address);
2066
2067 for(i = 0; i < num; i++)
2068 dvinlineprintf("%s, ", &SNs[i*(MAXSNLEN+1)]);
2069 dinlineprintf("\n");
2070
2071 return 1;
2072}
2073
2074int faimtest_parse_searcherror(struct aim_session_t *sess, struct command_rx_struct *command, ...)
2075{
2076 va_list ap;
2077 char *address;
2078
2079 va_start(ap, command);
2080 address = va_arg(ap, char *);
2081 va_end(ap);
2082
2083 dvprintf("faimtest: E-Mail Search Results for %s: No Results or Invalid Email\n", address);
98c88242 2084
98c88242 2085 return 1;
78b3fb13 2086}
This page took 1.898522 seconds and 5 git commands to generate.