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