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