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