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