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