]> andersk Git - libfaim.git/blame - utils/faimtest/faimtest.c
- Fri Dec 1 23:48:38 UTC 2000
[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
44
45 */
46
397055b1 47#include <faim/aim.h>
48
49int faimtest_parse_oncoming(struct aim_session_t *, struct command_rx_struct *, ...);
50int faimtest_parse_offgoing(struct aim_session_t *, struct command_rx_struct *, ...);
51int faimtest_parse_login_phase3d_f(struct aim_session_t *, struct command_rx_struct *, ...);
01b59e1e 52int faimtest_parse_authresp(struct aim_session_t *, struct command_rx_struct *, ...);
397055b1 53int faimtest_parse_incoming_im(struct aim_session_t *, struct command_rx_struct *command, ...);
54int faimtest_parse_userinfo(struct aim_session_t *, struct command_rx_struct *command, ...);
55int faimtest_handleredirect(struct aim_session_t *, struct command_rx_struct *command, ...);
56int faimtest_authsvrready(struct aim_session_t *, struct command_rx_struct *command, ...);
57int faimtest_pwdchngdone(struct aim_session_t *, struct command_rx_struct *command, ...);
58int faimtest_serverready(struct aim_session_t *, struct command_rx_struct *command, ...);
59int faimtest_parse_misses(struct aim_session_t *, struct command_rx_struct *command, ...);
1a8c261b 60int faimtest_parse_msgack(struct aim_session_t *, struct command_rx_struct *command, ...);
01b59e1e 61int faimtest_parse_motd(struct aim_session_t *, struct command_rx_struct *command, ...);
62int faimtest_parse_login(struct aim_session_t *, struct command_rx_struct *command, ...);
0c20631f 63int faimtest_chatnav_info(struct aim_session_t *, struct command_rx_struct *command, ...);
64int faimtest_chat_incomingmsg(struct aim_session_t *sess, struct command_rx_struct *command, ...);
65int faimtest_chat_infoupdate(struct aim_session_t *sess, struct command_rx_struct *command, ...);
66int faimtest_chat_leave(struct aim_session_t *sess, struct command_rx_struct *command, ...);
67int faimtest_chat_join(struct aim_session_t *sess, struct command_rx_struct *command, ...);
5e02cf44 68int faimtest_parse_connerr(struct aim_session_t *sess, struct command_rx_struct *command, ...);
e5012450 69int faimtest_debugconn_connect(struct aim_session_t *sess, struct command_rx_struct *command, ...);
49c8a2fa 70
7392c79f 71int faimtest_directim_request(struct aim_session_t *sess, struct command_rx_struct *command, ...);
72int faimtest_directim_initiate(struct aim_session_t *sess, struct command_rx_struct *command, ...);
73int faimtest_directim_connect(struct aim_session_t *sess, struct command_rx_struct *command, ...);
74int faimtest_directim_incoming(struct aim_session_t *sess, struct command_rx_struct *command, ...);
75int faimtest_directim_disconnect(struct aim_session_t *sess, struct command_rx_struct *command, ...);
76int faimtest_directim_typing(struct aim_session_t *sess, struct command_rx_struct *command, ...);
871e2fd0 77#define FILESUPPORT
78#ifdef FILESUPPORT
79int faimtest_getfile_filereq(struct aim_session_t *sess, struct command_rx_struct *command, ...);
80int faimtest_getfile_filesend(struct aim_session_t *sess, struct command_rx_struct *command, ...);
81int faimtest_getfile_complete(struct aim_session_t *sess, struct command_rx_struct *command, ...);
82int faimtest_getfile_disconnect(struct aim_session_t *sess, struct command_rx_struct *command, ...);
83#endif
84
1a8c261b 85int faimtest_parse_ratechange(struct aim_session_t *sess, struct command_rx_struct *command, ...);
98c88242 86int faimtest_parse_evilnotify(struct aim_session_t *sess, struct command_rx_struct *command, ...);
96f8b1ed 87int faimtest_parse_msgerr(struct aim_session_t *sess, struct command_rx_struct *command, ...);
88int faimtest_parse_buddyrights(struct aim_session_t *sess, struct command_rx_struct *command, ...);
89int faimtest_parse_locerr(struct aim_session_t *sess, struct command_rx_struct *command, ...);
90
91static char *msgerrreasons[] = {
92 "Invalid error",
93 "Invalid SNAC",
94 "Rate to host",
95 "Rate to client",
96 "Not logged on",
97 "Service unavailable",
98 "Service not defined",
99 "Obsolete SNAC",
100 "Not supported by host",
101 "Not supported by client",
102 "Refused by client",
103 "Reply too big",
104 "Responses lost",
105 "Request denied",
106 "Busted SNAC payload",
107 "Insufficient rights",
108 "In local permit/deny",
109 "Too evil (sender)",
110 "Too evil (receiver)",
111 "User temporarily unavailable",
112 "No match",
113 "List overflow",
114 "Request ambiguous",
115 "Queue full",
116 "Not while on AOL"};
117static int msgerrreasonslen = 25;
7392c79f 118
22517493 119static char *screenname,*password,*server=NULL;
120
f0a7908e 121int faimtest_reportinterval(struct aim_session_t *sess, struct command_rx_struct *command, ...)
122{
123 if (command->data) {
124 printf("aim: minimum report interval: %d (seconds?)\n", aimutil_get16(command->data+10));
125 } else
126 printf("aim: NULL minimum report interval!\n");
127 return 1;
128}
129
22517493 130int faimtest_flapversion(struct aim_session_t *sess, struct command_rx_struct *command, ...)
131{
132
133 printf("faimtest: using FLAP version %u\n", aimutil_get32(command->data));
134
135#if 0
136 /*
137 * This is an alternate location for starting the login process.
138 */
139 /* XXX should do more checking to make sure its really the right AUTH conn */
140 if (command->conn->type == AIM_CONN_TYPE_AUTH) {
141 /* do NOT send a connack/flapversion, request_login will send it if needed */
142 aim_request_login(sess, command->conn, screenname);
143 printf("faimtest: login request sent\n");
144 }
145#endif
146
147 return 1;
148}
149
150/*
151 * This is a frivilous callback. You don't need it. I only used it for
152 * debugging non-blocking connects.
153 *
154 * If packets are sent to a conn before its fully connected, they
155 * will be queued and then transmitted when the connection completes.
156 *
157 */
158int faimtest_conncomplete(struct aim_session_t *sess, struct command_rx_struct *command, ...)
159{
160 va_list ap;
161 struct aim_conn_t *conn;
162
163 va_start(ap, command);
164 conn = va_arg(ap, struct aim_conn_t *);
165 va_end(ap);
166
167 if (conn)
168 printf("faimtest: connection on %d completed\n", conn->fd);
169
170 return 1;
171}
172
999b6d5f 173#ifdef _WIN32
174/*
175 * This is really all thats needed to link against libfaim on win32.
176 *
177 * Note that this particular version of faimtest has never been tested
178 * on win32, but I'm fairly sure it should.
179 */
180int initwsa(void)
181{
182 WORD wVersionRequested;
183 WSADATA wsaData;
184
185 wVersionRequested = MAKEWORD(2,2);
186 return WSAStartup(wVersionRequested, &wsaData);
187}
188#endif /* _WIN32 */
189
9de3ca7e 190int main(void)
191{
397055b1 192 struct aim_session_t aimsess;
f1a5efe0 193 struct aim_conn_t *authconn = NULL, *waitingconn = NULL;
68ac63c2 194 int keepgoing = 1;
bb0dc593 195 char *proxy, *proxyusername, *proxypass;
5e02cf44 196
871e2fd0 197 char *listingpath;
198
b8d0da45 199 int selstat = 0;
200
871e2fd0 201#ifdef FILESUPPORT
202 FILE *listingfile;
203#endif
204
26af6789 205 if ( !(screenname = getenv("SCREENNAME")) ||
206 !(password = getenv("PASSWORD")))
207 {
208 printf("Must specify SCREENAME and PASSWORD in environment.\n");
209 return -1;
210 }
211
f1a5efe0 212 server = getenv("AUTHSERVER");
213
bb0dc593 214 proxy = getenv("SOCKSPROXY");
215 proxyusername = getenv("SOCKSNAME");
216 proxypass = getenv("SOCKSPASS");
217
871e2fd0 218#ifdef FILESUPPORT
219 listingpath = getenv("LISTINGPATH");
220#endif
221
999b6d5f 222#ifdef _WIN32
223 if (initwsa() != 0) {
224 printf("faimtest: could not initialize windows sockets\n");
225 return -1;
226 }
227#endif /* _WIN32 */
228
22517493 229 /* Pass zero as flags if you want blocking connects */
230 aim_session_init(&aimsess, AIM_SESS_FLAGS_NONBLOCKCONNECT);
68ac63c2 231
871e2fd0 232#ifdef FILESUPPORT
233 if(listingpath) {
234 char *listingname;
235 if(!(listingname = (char *)calloc(1, strlen(listingpath)+strlen("/listing.txt")))) {
236 perror("listingname calloc.");
237 exit(-1);
238 }
239 sprintf(listingname, "%s/listing.txt", listingpath);
240 if( (listingfile = fopen(listingname, "r")) == NULL) {
241 printf("Couldn't open %s... bombing.\n", listingname);
242 exit(-1);
243 }
244
245 aim_oft_registerlisting(&aimsess, listingfile, listingpath);
246
247 free(listingname);
248 }
249#endif
250
bb0dc593 251 if (proxy)
252 aim_setupproxy(&aimsess, proxy, proxyusername, proxypass);
253
f1a5efe0 254 authconn = aim_newconn(&aimsess, AIM_CONN_TYPE_AUTH, server?server:FAIM_LOGIN_SERVER);
397055b1 255
040457cc 256 if (authconn == NULL) {
257 fprintf(stderr, "faimtest: internal connection error while in aim_login. bailing out.\n");
258 return -1;
259 } else if (authconn->fd == -1) {
260 if (authconn->status & AIM_CONN_STATUS_RESOLVERR)
261 fprintf(stderr, "faimtest: could not resolve authorizer name\n");
262 else if (authconn->status & AIM_CONN_STATUS_CONNERR)
263 fprintf(stderr, "faimtest: could not connect to authorizer\n");
264 aim_conn_kill(&aimsess, &authconn);
265 return -1;
68ac63c2 266 }
b5bc2a8c 267
22517493 268 aim_conn_addhandler(&aimsess, authconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_FLAPVER, faimtest_flapversion, 0);
269 aim_conn_addhandler(&aimsess, authconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
68ac63c2 270 aim_conn_addhandler(&aimsess, authconn, 0x0017, 0x0007, faimtest_parse_login, 0);
22517493 271 aim_conn_addhandler(&aimsess, authconn, 0x0017, 0x0003, faimtest_parse_authresp, 0);
b5bc2a8c 272
e5012450 273 aim_conn_addhandler(&aimsess, authconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_DEBUGCONN_CONNECT, faimtest_debugconn_connect, 0);
b5bc2a8c 274
22517493 275 /* If the connection is in progress, this will just be queued */
276 aim_request_login(&aimsess, authconn, screenname);
b5bc2a8c 277 printf("faimtest: login request sent\n");
9de3ca7e 278
b8d0da45 279 while (keepgoing) {
f1a5efe0 280 waitingconn = aim_select(&aimsess, NULL, &selstat);
b8d0da45 281
282 switch(selstat) {
283 case -1: /* error */
68ac63c2 284 keepgoing = 0; /* fall through and hit the aim_logoff() */
b8d0da45 285 break;
9de3ca7e 286
b8d0da45 287 case 0: /* no events pending */
288 break;
289
290 case 1: /* outgoing data pending */
291 aim_tx_flushqueue(&aimsess);
292 break;
293
294 case 2: /* incoming data pending */
7392c79f 295 if (waitingconn->type == AIM_CONN_TYPE_RENDEZVOUS_OUT) {
296 if (aim_handlerendconnect(&aimsess, waitingconn) < 0) {
871e2fd0 297 printf("connection error (rend out)\n");
7392c79f 298 }
299 } else {
300 if (aim_get_command(&aimsess, waitingconn) >= 0) {
301 aim_rxdispatch(&aimsess);
302 } else {
871e2fd0 303 printf("connection error (type 0x%04x:0x%04x)\n", waitingconn->type, waitingconn->subtype);
3b101546 304 if(waitingconn->type == AIM_CONN_TYPE_RENDEZVOUS) {
305 /* we should have callbacks for all these, else the library will do the conn_kill for us. */
306 printf("connection error: rendezvous connection. you forgot register a disconnect callback, right?\n");
307 }
308 else
309 aim_conn_kill(&aimsess, &waitingconn);
7392c79f 310 if (!aim_getconn_type(&aimsess, AIM_CONN_TYPE_BOS)) {
871e2fd0 311 printf("major connection error\n");
7392c79f 312 keepgoing = 0;
313 }
314 }
315 }
b8d0da45 316 break;
317
318 default:
319 break; /* invalid */
9de3ca7e 320 }
b8d0da45 321 }
9de3ca7e 322
323 /* Close up */
b8d0da45 324 printf("AIM just decided we didn't need to be here anymore, closing up...\n");
9de3ca7e 325
326 /* close up all connections, dead or no */
397055b1 327 aim_logoff(&aimsess);
9de3ca7e 328
9de3ca7e 329 /* Get out */
330 exit(0);
331}
332
c78446b5 333int faimtest_rateresp(struct aim_session_t *sess, struct command_rx_struct *command, ...)
334{
335
336 switch(command->conn->type) {
337 case AIM_CONN_TYPE_BOS: {
338 /* this is the new buddy list */
339 char buddies[] = "Buddy1&Buddy2&ThisHereIsAName2&";
340 /* this is the new profile */
341 char profile[] = "Hello";
342
343 aim_bos_ackrateresp(sess, command->conn); /* ack rate info response */
344 aim_bos_reqpersonalinfo(sess, command->conn);
345 aim_bos_reqlocaterights(sess, command->conn);
346 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);
347 aim_bos_reqbuddyrights(sess, command->conn);
348
349 /* send the buddy list and profile (required, even if empty) */
350 aim_bos_setbuddylist(sess, command->conn, buddies);
351
352 /* dont really know what this does */
353 aim_addicbmparam(sess, command->conn);
354 aim_bos_reqicbmparaminfo(sess, command->conn);
355
356 aim_bos_reqrights(sess, command->conn);
357 /* set group permissions -- all user classes */
a15d82b1 358 aim_bos_setgroupperm(sess, command->conn, AIM_FLAG_ALLUSERS);
c78446b5 359 aim_bos_setprivacyflags(sess, command->conn, AIM_PRIVFLAGS_ALLOWIDLE|AIM_PRIVFLAGS_ALLOWMEMBERSINCE);
360
361 break;
362 }
363
364 default:
365 printf("faimtest: got rate response for unhandled connection type %04x\n", command->conn->type);
366 break;
367 }
368
369 return 1;
370}
371
397055b1 372int faimtest_serverready(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 373{
374 switch (command->conn->type)
375 {
376 case AIM_CONN_TYPE_BOS:
26af6789 377
01b59e1e 378 aim_setversions(sess, command->conn);
c78446b5 379 aim_bos_reqrate(sess, command->conn); /* request rate info */
9de3ca7e 380
9de3ca7e 381 fprintf(stderr, "faimtest: done with BOS ServerReady\n");
382 break;
0c20631f 383
9de3ca7e 384 case AIM_CONN_TYPE_CHATNAV:
385 fprintf(stderr, "faimtest: chatnav: got server ready\n");
0c20631f 386 aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CTN, AIM_CB_CTN_INFO, faimtest_chatnav_info, 0);
387 aim_bos_reqrate(sess, command->conn);
388 aim_bos_ackrateresp(sess, command->conn);
389 aim_chatnav_clientready(sess, command->conn);
390 aim_chatnav_reqrights(sess, command->conn);
391
392 break;
393 case AIM_CONN_TYPE_CHAT:
394 aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_USERJOIN, faimtest_chat_join, 0);
395 aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_USERLEAVE, faimtest_chat_leave, 0);
396 aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_ROOMINFOUPDATE, faimtest_chat_infoupdate, 0);
397 aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_INCOMINGMSG, faimtest_chat_incomingmsg, 0);
398 aim_bos_reqrate(sess, command->conn);
399 aim_bos_ackrateresp(sess, command->conn);
400 aim_chat_clientready(sess, command->conn);
9de3ca7e 401 break;
7392c79f 402
871e2fd0 403 case AIM_CONN_TYPE_RENDEZVOUS: /* empty */
7392c79f 404 break;
405
9de3ca7e 406 default:
407 fprintf(stderr, "faimtest: unknown connection type on Server Ready\n");
408 }
409 return 1;
410}
411
96f8b1ed 412int faimtest_parse_buddyrights(struct aim_session_t *sess, struct command_rx_struct *command, ...)
00f3b08b 413{
96f8b1ed 414 va_list ap;
415 unsigned short maxbuddies, maxwatchers;
416
417 va_start(ap, command);
e7fb57f5 418 maxbuddies = va_arg(ap, int);
419 maxwatchers = va_arg(ap, int);
96f8b1ed 420 va_end(ap);
421
422 printf("faimtest: buddy list rights: Max buddies = %d / Max watchers = %d\n", maxbuddies, maxwatchers);
423
424 return 1;
425}
426
c78446b5 427int faimtest_bosrights(struct aim_session_t *sess, struct command_rx_struct *command, ...)
428{
96f8b1ed 429 unsigned short maxpermits, maxdenies;
430 va_list ap;
431
432 va_start(ap, command);
e7fb57f5 433 maxpermits = va_arg(ap, int);
434 maxdenies = va_arg(ap, int);
96f8b1ed 435 va_end(ap);
436
437 printf("faimtest: BOS rights: Max permit = %d / Max deny = %d\n", maxpermits, maxdenies);
438
c78446b5 439 aim_bos_clientready(sess, command->conn);
440
441 printf("faimtest: officially connected to BOS.\n");
442
443 return 1;
444}
445
9de3ca7e 446/*
447 handleredirect()...
448
449 This, of course, handles Service Redirects from OSCAR.
450
451 Should get passed in the following:
452 struct command_rx_struct *command
453 the raw command data
454 int serviceid
455 the destination service ID
456 char *serverip
457 the IP address of the service's server
458 char *cookie
459 the raw auth cookie
460 */
397055b1 461int faimtest_handleredirect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 462{
463 va_list ap;
464 int serviceid;
465 char *ip;
78b3fb13 466 unsigned char *cookie;
9de3ca7e 467
9de3ca7e 468 va_start(ap, command);
469 serviceid = va_arg(ap, int);
470 ip = va_arg(ap, char *);
78b3fb13 471 cookie = va_arg(ap, unsigned char *);
0c20631f 472
9de3ca7e 473 switch(serviceid)
474 {
9de3ca7e 475 case 0x0007: /* Authorizer */
476 {
477 struct aim_conn_t *tstconn;
478 /* Open a connection to the Auth */
397055b1 479 tstconn = aim_newconn(sess, AIM_CONN_TYPE_AUTH, ip);
22517493 480 if ( (tstconn==NULL) || (tstconn->status & AIM_CONN_STATUS_RESOLVERR) )
9de3ca7e 481 fprintf(stderr, "faimtest: unable to reconnect with authorizer\n");
22517493 482 else {
483 aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
9de3ca7e 484 /* Send the cookie to the Auth */
397055b1 485 aim_auth_sendcookie(sess, tstconn, cookie);
22517493 486 }
9de3ca7e 487
488 }
489 break;
490 case 0x000d: /* ChatNav */
491 {
492 struct aim_conn_t *tstconn = NULL;
397055b1 493 tstconn = aim_newconn(sess, AIM_CONN_TYPE_CHATNAV, ip);
22517493 494 if ( (tstconn==NULL) || (tstconn->status & AIM_CONN_STATUS_RESOLVERR)) {
040457cc 495 fprintf(stderr, "faimtest: unable to connect to chatnav server\n");
496 if (tstconn) aim_conn_kill(sess, &tstconn);
497 return 1;
498 }
0c20631f 499#if 0
397055b1 500 aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_CTN, AIM_CB_SPECIAL_DEFAULT, aim_parse_unknown, 0);
501 aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_GEN, AIM_CB_SPECIAL_DEFAULT, aim_parse_unknown, 0);
0c20631f 502#endif
503 aim_conn_addhandler(sess, tstconn, 0x0001, 0x0003, faimtest_serverready, 0);
22517493 504 aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
397055b1 505 aim_auth_sendcookie(sess, tstconn, cookie);
9de3ca7e 506 fprintf(stderr, "\achatnav: connected\n");
507 }
508 break;
509 case 0x000e: /* Chat */
510 {
0c20631f 511 char *roomname = NULL;
9f20a4e3 512 int exchange;
9de3ca7e 513 struct aim_conn_t *tstconn = NULL;
0c20631f 514
515 roomname = va_arg(ap, char *);
9f20a4e3 516 exchange = va_arg(ap, int);
0c20631f 517
397055b1 518 tstconn = aim_newconn(sess, AIM_CONN_TYPE_CHAT, ip);
22517493 519 if ( (tstconn==NULL) || (tstconn->status & AIM_CONN_STATUS_RESOLVERR))
9de3ca7e 520 {
521 fprintf(stderr, "faimtest: unable to connect to chat server\n");
040457cc 522 if (tstconn) aim_conn_kill(sess, &tstconn);
9de3ca7e 523 return 1;
0c20631f 524 }
9f20a4e3 525 printf("faimtest: chat: connected to %s on exchange %d\n", roomname, exchange);
0c20631f 526
527 /*
528 * We must do this to attach the stored name to the connection!
529 */
530 aim_chat_attachname(tstconn, roomname);
531
532 aim_conn_addhandler(sess, tstconn, 0x0001, 0x0003, faimtest_serverready, 0);
22517493 533 aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
0c20631f 534 aim_auth_sendcookie(sess, tstconn, cookie);
9de3ca7e 535 }
536 break;
537 default:
538 printf("uh oh... got redirect for unknown service 0x%04x!!\n", serviceid);
539 /* dunno */
540 }
541
9de3ca7e 542 va_end(ap);
543
0c20631f 544 return 1;
9de3ca7e 545}
546
01b59e1e 547int faimtest_parse_authresp(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 548{
9de3ca7e 549 struct aim_conn_t *bosconn = NULL;
9de3ca7e 550
01b59e1e 551
397055b1 552 printf("Screen name: %s\n", sess->logininfo.screen_name);
01b59e1e 553
554 /*
555 * Check for error.
556 */
557 if (sess->logininfo.errorcode)
558 {
559 printf("Login Error Code 0x%04x\n", sess->logininfo.errorcode);
560 printf("Error URL: %s\n", sess->logininfo.errorurl);
040457cc 561 aim_conn_kill(sess, &command->conn);
01b59e1e 562 exit(0); /* XXX: should return in order to let the above things get free()'d. */
563 }
564
397055b1 565 printf("Reg status: %2d\n", sess->logininfo.regstatus);
566 printf("Email: %s\n", sess->logininfo.email);
397055b1 567 printf("BOS IP: %s\n", sess->logininfo.BOSIP);
9de3ca7e 568
569 printf("Closing auth connection...\n");
040457cc 570 aim_conn_kill(sess, &command->conn);
397055b1 571 bosconn = aim_newconn(sess, AIM_CONN_TYPE_BOS, sess->logininfo.BOSIP);
040457cc 572 if (bosconn == NULL) {
573 fprintf(stderr, "faimtest: could not connect to BOS: internal error\n");
22517493 574 } else if (bosconn->status & AIM_CONN_STATUS_CONNERR) {
040457cc 575 fprintf(stderr, "faimtest: could not connect to BOS\n");
576 aim_conn_kill(sess, &bosconn);
577 } else {
22517493 578 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
c78446b5 579 aim_conn_addhandler(sess, bosconn, 0x0009, 0x0003, faimtest_bosrights, 0);
580 aim_conn_addhandler(sess, bosconn, 0x0001, 0x0007, faimtest_rateresp, 0); /* rate info */
040457cc 581 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ACK, AIM_CB_ACK_ACK, NULL, 0);
582 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_SERVERREADY, faimtest_serverready, 0);
583 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_RATEINFO, NULL, 0);
584 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_REDIRECT, faimtest_handleredirect, 0);
f0a7908e 585 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_STS, AIM_CB_STS_SETREPORTINTERVAL, faimtest_reportinterval, 0);
96f8b1ed 586 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_RIGHTSINFO, faimtest_parse_buddyrights, 0);
040457cc 587 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_ONCOMING, faimtest_parse_oncoming, 0);
588 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_OFFGOING, faimtest_parse_offgoing, 0);
589 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_INCOMING, faimtest_parse_incoming_im, 0);
96f8b1ed 590 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_ERROR, faimtest_parse_locerr, 0);
040457cc 591 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_MISSEDCALL, faimtest_parse_misses, 0);
1a8c261b 592 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_RATECHANGE, faimtest_parse_ratechange, 0);
98c88242 593 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_EVIL, faimtest_parse_evilnotify, 0);
96f8b1ed 594 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ERROR, faimtest_parse_msgerr, 0);
040457cc 595 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO, faimtest_parse_userinfo, 0);
1a8c261b 596 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ACK, faimtest_parse_msgack, 0);
597
040457cc 598 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_CTN, AIM_CB_CTN_DEFAULT, aim_parse_unknown, 0);
599 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_DEFAULT, aim_parse_unknown, 0);
600 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_MOTD, faimtest_parse_motd, 0);
601
602 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, faimtest_parse_connerr, 0);
603
604 aim_auth_sendcookie(sess, bosconn, sess->logininfo.cookie);
605 }
9de3ca7e 606 return 1;
607}
608
a15d82b1 609static void printuserflags(unsigned short flags)
610{
611 if (flags & AIM_FLAG_UNCONFIRMED)
612 printf("UNCONFIRMED ");
613 if (flags & AIM_FLAG_ADMINISTRATOR)
614 printf("ADMINISTRATOR ");
615 if (flags & AIM_FLAG_AOL)
616 printf("AOL ");
617 if (flags & AIM_FLAG_OSCAR_PAY)
618 printf("OSCAR_PAY ");
619 if (flags & AIM_FLAG_FREE)
620 printf("FREE ");
621 if (flags & AIM_FLAG_AWAY)
622 printf("AWAY ");
623 if (flags & AIM_FLAG_UNKNOWN40)
624 printf("ICQ? ");
625 if (flags & AIM_FLAG_UNKNOWN80)
626 printf("UNKNOWN80 ");
627 return;
628}
629
397055b1 630int faimtest_parse_userinfo(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 631{
632 struct aim_userinfo_s *userinfo;
633 char *prof_encoding = NULL;
634 char *prof = NULL;
5e02cf44 635 unsigned short inforeq = 0;
9de3ca7e 636
637 va_list ap;
638 va_start(ap, command);
639 userinfo = va_arg(ap, struct aim_userinfo_s *);
640 prof_encoding = va_arg(ap, char *);
641 prof = va_arg(ap, char *);
e7fb57f5 642 inforeq = va_arg(ap, int);
9de3ca7e 643 va_end(ap);
644
645 printf("faimtest: userinfo: sn: %s\n", userinfo->sn);
646 printf("faimtest: userinfo: warnlevel: 0x%04x\n", userinfo->warnlevel);
a15d82b1 647 printf("faimtest: userinfo: flags: 0x%04x = ", userinfo->flags);
648 printuserflags(userinfo->flags);
9de3ca7e 649 printf("\n");
650
651 printf("faimtest: userinfo: membersince: %lu\n", userinfo->membersince);
652 printf("faimtest: userinfo: onlinesince: %lu\n", userinfo->onlinesince);
653 printf("faimtest: userinfo: idletime: 0x%04x\n", userinfo->idletime);
654
5e02cf44 655 if (inforeq == AIM_GETINFO_GENERALINFO) {
656 printf("faimtest: userinfo: profile_encoding: %s\n", prof_encoding ? prof_encoding : "[none]");
657 printf("faimtest: userinfo: prof: %s\n", prof ? prof : "[none]");
658 } else if (inforeq == AIM_GETINFO_AWAYMESSAGE) {
659 printf("faimtest: userinfo: awaymsg_encoding: %s\n", prof_encoding ? prof_encoding : "[none]");
660 printf("faimtest: userinfo: awaymsg: %s\n", prof ? prof : "[none]");
661 } else
662 printf("faimtest: userinfo: unknown info request\n");
9de3ca7e 663
664 return 1;
665}
666
667/*
668 * The user-level Incoming ICBM callback.
669 *
670 * Arguments:
671 * struct command_rx_struct * command if you feel like doing it yourself
672 * char * srcsn the source name
673 * char * msg message
674 * int warnlevel warning/evil level
a15d82b1 675 * int flags flags
9de3ca7e 676 * ulong membersince time_t of date of signup
677 * ulong onsince time_t of date of singon
678 * int idletime min (sec?) idle
24286d93 679 * u_int icbmflags sets AIM_IMFLAGS_{AWAY,ACK}
9de3ca7e 680 *
681 */
397055b1 682int faimtest_parse_incoming_im(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 683{
26af6789 684 int channel;
9de3ca7e 685 va_list ap;
9de3ca7e 686
687 va_start(ap, command);
26af6789 688 channel = va_arg(ap, int);
9de3ca7e 689
26af6789 690 /*
691 * Channel 1: Standard Message
692 */
040457cc 693 if (channel == 1) {
694 struct aim_userinfo_s *userinfo;
695 char *msg = NULL;
696 u_int icbmflags = 0;
697 char *tmpstr = NULL;
e7fb57f5 698 unsigned short flag1, flag2;
040457cc 699
700 userinfo = va_arg(ap, struct aim_userinfo_s *);
701 msg = va_arg(ap, char *);
702 icbmflags = va_arg(ap, u_int);
e7fb57f5 703 flag1 = va_arg(ap, int);
704 flag2 = va_arg(ap, int);
040457cc 705 va_end(ap);
706
707 printf("faimtest: icbm: sn = \"%s\"\n", userinfo->sn);
708 printf("faimtest: icbm: warnlevel = 0x%04x\n", userinfo->warnlevel);
a15d82b1 709 printf("faimtest: icbm: flags = 0x%04x = ", userinfo->flags);
710 printuserflags(userinfo->flags);
040457cc 711 printf("\n");
a15d82b1 712
040457cc 713 printf("faimtest: icbm: membersince = %lu\n", userinfo->membersince);
714 printf("faimtest: icbm: onlinesince = %lu\n", userinfo->onlinesince);
715 printf("faimtest: icbm: idletime = 0x%04x\n", userinfo->idletime);
b69540e3 716 printf("faimtest: icbm: capabilities = 0x%04x\n", userinfo->capabilities);
040457cc 717
718 printf("faimtest: icbm: icbmflags = ");
719 if (icbmflags & AIM_IMFLAGS_AWAY)
720 printf("away ");
721 if (icbmflags & AIM_IMFLAGS_ACK)
722 printf("ackrequest ");
723 printf("\n");
724
725 printf("faimtest: icbm: encoding flags = {%04x, %04x}\n", flag1, flag2);
726
727 printf("faimtest: icbm: message: %s\n", msg);
728
729 if (msg) {
b69540e3 730 int i = 0;
731
732 while (msg[i] == '<') {
733 if (msg[i] == '<') {
734 while (msg[i] != '>')
735 i++;
736 i++;
737 }
738 }
739 tmpstr = msg+i;
740
741 printf("tmpstr = %s\n", tmpstr);
040457cc 742
743 if ( (strlen(tmpstr) >= 10) &&
744 (!strncmp(tmpstr, "disconnect", 10)) ) {
745 aim_send_im(sess, command->conn, "midendian", 0, "ta ta...");
746 aim_logoff(sess);
747 } else if (strstr(tmpstr, "goodday")) {
748 printf("faimtest: icbm: sending response\n");
1a8c261b 749 aim_send_im(sess, command->conn, userinfo->sn, AIM_IMFLAGS_ACK, "Good day to you too.");
98c88242 750 } else if (strstr(tmpstr, "warnme")) {
751 printf("faimtest: icbm: sending non-anon warning\n");
752 aim_send_warning(sess, command->conn, userinfo->sn, 0);
753 } else if (strstr(tmpstr, "anonwarn")) {
754 printf("faimtest: icbm: sending anon warning\n");
755 aim_send_warning(sess, command->conn, userinfo->sn, AIM_WARN_ANON);
f2d214f9 756 } else if (strstr(tmpstr, "setdirectoryinfo")) {
757 printf("faimtest: icbm: sending backwards profile data\n");
758 aim_setdirectoryinfo(sess, command->conn, "tsrif", "elddim", "tsal", "nediam", "emankcin", "teerts", "ytic", "etats", "piz", 0, 1);
759 } else if (strstr(tmpstr, "setinterests")) {
760 printf("faimtest: icbm: setting fun interests\n");
761 aim_setuserinterests(sess, command->conn, "interest1", "interest2", "interest3", "interest4", "interest5", 1);
040457cc 762 } else if (!strncmp(tmpstr, "open chatnav", 12)) {
763 aim_bos_reqservice(sess, command->conn, AIM_CONN_TYPE_CHATNAV);
764 //aim_chat_join(sess, command->conn, "thishereisaname2_chat85");
765 } else if (!strncmp(tmpstr, "create", 6)) {
7392c79f 766 aim_chatnav_createroom(sess,aim_getconn_type(sess, AIM_CONN_TYPE_CHATNAV), (strlen(tmpstr) < 7)?"WorldDomination":tmpstr+7, 0x0004);
040457cc 767 } else if (!strncmp(tmpstr, "close chatnav", 13)) {
768 struct aim_conn_t *chatnavconn;
769 chatnavconn = aim_getconn_type(sess, AIM_CONN_TYPE_CHATNAV);
770 aim_conn_kill(sess, &chatnavconn);
771 } else if (!strncmp(tmpstr, "join", 4)) {
772 aim_chat_join(sess, command->conn, 0x0004, "worlddomination");
773 } else if (!strncmp(tmpstr, "leave", 5))
774 aim_chat_leaveroom(sess, "worlddomination");
775 else if (!strncmp(tmpstr, "getinfo", 7)) {
776 aim_getinfo(sess, command->conn, "75784102", AIM_GETINFO_GENERALINFO);
777 aim_getinfo(sess, command->conn, "15853637", AIM_GETINFO_AWAYMESSAGE);
7392c79f 778 } else if (!strncmp(tmpstr, "open directim", 13)) {
779 struct aim_conn_t *newconn;
780 newconn = aim_directim_initiate(sess, command->conn, NULL, userinfo->sn);
96f8b1ed 781 } else if (!strncmp(tmpstr, "reqsendmsg", 10)) {
a3619f23 782 aim_send_im(sess, command->conn, "vaxherder", 0, "sendmsg 7900");
b69540e3 783 } else if (!strncmp(tmpstr, "sendmsg", 7)) {
784 int i;
785 i = atoi(tmpstr+8);
786 if (i < 10000) {
787 char *newbuf;
788 int z;
789
790 newbuf = malloc(i+1);
791 for (z = 0; z < i; z++) {
792 newbuf[z] = (z % 10)+0x30;
793 }
794 newbuf[i] = '\0';
795 aim_send_im(sess, command->conn, userinfo->sn, 0, newbuf);
796 free(newbuf);
797 }
040457cc 798 } else {
799 printf("unknown command.\n");
b69540e3 800 aim_add_buddy(sess, command->conn, userinfo->sn);
040457cc 801 }
802
803 }
804 }
805 /*
806 * Channel 2: Rendevous Request
807 */
808 else if (channel == 2) {
809 struct aim_userinfo_s *userinfo;
810 unsigned short reqclass;
811
e7fb57f5 812 reqclass = va_arg(ap, int);
040457cc 813 switch (reqclass) {
b69540e3 814 case AIM_CAPS_VOICE: {
26af6789 815 userinfo = va_arg(ap, struct aim_userinfo_s *);
26af6789 816 va_end(ap);
9de3ca7e 817
040457cc 818 printf("faimtest: voice invitation: source sn = %s\n", userinfo->sn);
819 printf("faimtest: voice invitation: \twarnlevel = 0x%04x\n", userinfo->warnlevel);
a15d82b1 820 printf("faimtest: voice invitation: \tclass = 0x%04x = ", userinfo->flags);
821 printuserflags(userinfo->flags);
26af6789 822 printf("\n");
a15d82b1 823
040457cc 824 /* we dont get membersince on chat invites! */
825 printf("faimtest: voice invitation: \tonlinesince = %lu\n", userinfo->onlinesince);
826 printf("faimtest: voice invitation: \tidletime = 0x%04x\n", userinfo->idletime);
26af6789 827
040457cc 828 break;
829 }
b69540e3 830 case AIM_CAPS_GETFILE: {
871e2fd0 831#ifdef FILESUPPORT
832 char *ip, *cookie;
833 struct aim_conn_t *newconn;
834
835 userinfo = va_arg(ap, struct aim_userinfo_s *);
836 ip = va_arg(ap, char *);
837 cookie = va_arg(ap, char *);
838 va_end(ap);
839
840 printf("faimtest: get file request from %s (at %s)\n", userinfo->sn, ip);
841
842 sleep(1);
843
844 if( (newconn = aim_accepttransfer(sess, command->conn, userinfo->sn, cookie, ip, sess->oft.listing, reqclass)) == NULL ) {
845 printf("faimtest: getfile: requestconn: apparent error in accepttransfer\n");
846 break;
847 }
848
849 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEFILEREQ, faimtest_getfile_filereq, 0);
850 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEFILESEND, faimtest_getfile_filesend, 0);
851 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILECOMPLETE, faimtest_getfile_complete, 0);
852 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEDISCONNECT, faimtest_getfile_disconnect, 0);
853
854 printf("faimtest: getfile connect succeeded, handlers added.\n");
855
040457cc 856 break;
871e2fd0 857#endif
040457cc 858 }
b69540e3 859 case AIM_CAPS_SENDFILE: {
860 printf("faimtest: send file!\n");
861 break;
862 }
863 case AIM_CAPS_CHAT: {
040457cc 864 char *msg,*encoding,*lang;
865 struct aim_chat_roominfo *roominfo;
26af6789 866
040457cc 867 userinfo = va_arg(ap, struct aim_userinfo_s *);
868 roominfo = va_arg(ap, struct aim_chat_roominfo *);
869 msg = va_arg(ap, char *);
870 encoding = va_arg(ap, char *);
871 lang = va_arg(ap, char *);
872 va_end(ap);
26af6789 873
040457cc 874 printf("faimtest: chat invitation: source sn = %s\n", userinfo->sn);
875 printf("faimtest: chat invitation: \twarnlevel = 0x%04x\n", userinfo->warnlevel);
a15d82b1 876 printf("faimtest: chat invitation: \tclass = 0x%04x = ", userinfo->flags);
877 printuserflags(userinfo->flags);
040457cc 878 printf("\n");
a15d82b1 879
040457cc 880 /* we dont get membersince on chat invites! */
881 printf("faimtest: chat invitation: \tonlinesince = %lu\n", userinfo->onlinesince);
882 printf("faimtest: chat invitation: \tidletime = 0x%04x\n", userinfo->idletime);
26af6789 883
040457cc 884 printf("faimtest: chat invitation: message = %s\n", msg);
885 printf("faimtest: chat invitation: room name = %s\n", roominfo->name);
886 printf("faimtest: chat invitation: encoding = %s\n", encoding);
887 printf("faimtest: chat invitation: language = %s\n", lang);
888 printf("faimtest: chat invitation: exchange = 0x%04x\n", roominfo->exchange);
889 printf("faimtest: chat invitation: instance = 0x%04x\n", roominfo->instance);
890 printf("faimtest: chat invitiation: autojoining %s...\n", roominfo->name);
891 /*
892 * Automatically join room...
893 */
894 aim_chat_join(sess, command->conn, 0x0004, roominfo->name);
895 break;
896 }
7392c79f 897 case AIM_CAPS_IMIMAGE: {
898 struct aim_directim_priv *priv;
899 struct aim_conn_t *newconn;
900
901 printf("faimtest: icbm: rendezvous imimage\n");
902
903 userinfo = va_arg(ap, struct aim_userinfo_s *);
904 priv = va_arg(ap, struct aim_directim_priv *);
905 va_end(ap);
906
907 printf("faimtest: OFT: DirectIM: request from %s (%s)\n", userinfo->sn, priv->ip);
908
909 if (!(newconn = aim_directim_connect(sess, command->conn, priv))) {
910 printf("faimtest: icbm: imimage: could not connect\n");
911 break;
912 }
913 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, faimtest_directim_incoming, 0);
914 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMDISCONNECT, faimtest_directim_disconnect, 0);
915 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, faimtest_directim_typing, 0);
916
7392c79f 917 printf("faimtest: OFT: DirectIM: connected to %s\n", userinfo->sn);
918
3b101546 919 aim_send_im_direct(sess, newconn, "goodday");
920
7392c79f 921 break;
922 }
040457cc 923 default:
924 printf("faimtest: icbm: unknown reqclass (%d)\n", reqclass);
925 } /* switch */
926 } else
26af6789 927 printf("faimtest does not support channels > 2 (chan = %02x)\n", channel);
9de3ca7e 928 printf("faimtest: icbm: done with ICBM handling\n");
929
930 return 1;
931}
932
7392c79f 933int faimtest_directim_initiate(struct aim_session_t *sess, struct command_rx_struct *command, ...)
934{
935 va_list ap;
936 struct aim_directim_priv *priv;
937 struct aim_conn_t *newconn;
938
e7fb57f5 939 va_start(ap, command);
7392c79f 940 newconn = va_arg(ap, struct aim_conn_t *);
941 va_end(ap);
942
943 priv = (struct aim_directim_priv *)newconn->priv;
944
945 printf("faimtest: OFT: DirectIM: intitiate success to %s\n", priv->ip);
946
947 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, faimtest_directim_incoming, 0);
948 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMDISCONNECT, faimtest_directim_disconnect, 0);
949 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, faimtest_directim_typing, 0);
950
951 aim_send_im_direct(sess, newconn, "goodday");
952
953 printf("faimtest: OFT: DirectIM: connected to %s\n", priv->sn);
954
955 return 1;
956}
7392c79f 957
958int faimtest_directim_connect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
959{
960 va_list ap;
961 struct aim_directim_priv *priv;
962
e7fb57f5 963 va_start(ap, command);
7392c79f 964 priv = va_arg(ap, struct aim_directim_priv *);
965
966 va_end(ap);
967
968 printf("faimtest: directim_connect\n");
969
970 return 1;
971}
972
973int faimtest_directim_incoming(struct aim_session_t *sess, struct command_rx_struct *command, ...)
974{
975 va_list ap;
976 char *sn = NULL, *msg = NULL;
977 struct aim_conn_t *conn;
978
e7fb57f5 979 va_start(ap, command);
7392c79f 980 conn = va_arg(ap, struct aim_conn_t *);
981 sn = va_arg(ap, char *);
982 msg = va_arg(ap, char *);
983 va_end(ap);
984
985 printf("faimtest: Directim from %s: %s\n", sn, msg);
986 if (!strncmp(msg, "sendmsg", 7)) {
987 int i;
988 i = atoi(msg+8);
989 if (i < 10000) {
990 char *newbuf;
991 int z;
992
993 newbuf = malloc(i+1);
994 for (z = 0; z < i; z++) {
995 newbuf[z] = (z % 10)+0x30;
996 }
997 newbuf[i] = '\0';
998 aim_send_im_direct(sess, conn, newbuf);
999 free(newbuf);
1000 }
1001 } else if (!strncmp(msg, "goodday", 7)) {
1002 aim_send_im_direct(sess, conn, "Good day to you, too");
1003 } else {
1004 char newmsg[1024];
1005 snprintf(newmsg, sizeof(newmsg), "unknown (%s)\n", msg);
1006 aim_send_im_direct(sess, conn, newmsg);
1007 }
1008 return 1;
1009}
1010
1011int faimtest_directim_disconnect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1012{
871e2fd0 1013 va_list ap;
1014 struct aim_conn_t *conn;
1015 char *sn;
1016
e7fb57f5 1017 va_start(ap, command);
871e2fd0 1018 conn = va_arg(ap, struct aim_conn_t *);
1019 sn = va_arg(ap, char *);
1020 va_end(ap);
1021
871e2fd0 1022 printf("faimtest: directim: disconnected from %s\n", sn);
3b101546 1023
1024 aim_conn_kill(sess, &conn);
7392c79f 1025 return 1;
1026}
1027
1028int faimtest_directim_typing(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1029{
1030 va_list ap;
1031 char *sn;
1032
e7fb57f5 1033 va_start(ap, command);
7392c79f 1034 sn = va_arg(ap, char *);
1035 va_end(ap);
1036
1037 printf("faimtest: ohmigod! %s has started typing (DirectIM). He's going to send you a message! *squeal*\n", sn);
1038 return 1;
1039}
1040
397055b1 1041int faimtest_authsvrready(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 1042{
1043 printf("faimtest_authsvrready: called (contype: %d)\n", command->conn->type);
1044 sleep(10);
1045 /* should just be able to tell it we're ready too... */
397055b1 1046 aim_auth_clientready(sess, command->conn);
9de3ca7e 1047
1048#if 0
1049 /*
1050 * This is where you'd really begin changing your password.
1051 * However, this callback may get called for reasons other
1052 * than you wanting to change your password. You should
1053 * probably check that before actually doing it.
1054 */
397055b1 1055 aim_auth_changepasswd(sess, command->conn, "PWD1", "PWD2");
9de3ca7e 1056#endif
1057
1058 return 1;
1059}
1060
397055b1 1061int faimtest_pwdchngdone(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 1062{
1063 printf("PASSWORD CHANGE SUCCESSFUL!!!\n");
1064 return 1;
1065}
1066
397055b1 1067int faimtest_parse_oncoming(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 1068{
1069 struct aim_userinfo_s *userinfo;
1070
1071 va_list ap;
1072 va_start(ap, command);
1073 userinfo = va_arg(ap, struct aim_userinfo_s *);
1074 va_end(ap);
1075
a15d82b1 1076 printf("\n%s is now online (flags: %04x = %s%s%s%s%s%s%s%s) (caps = 0x%04x)\n",
1077 userinfo->sn, userinfo->flags,
1078 (userinfo->flags&AIM_FLAG_UNCONFIRMED)?" UNCONFIRMED":"",
1079 (userinfo->flags&AIM_FLAG_ADMINISTRATOR)?" ADMINISTRATOR":"",
1080 (userinfo->flags&AIM_FLAG_AOL)?" AOL":"",
1081 (userinfo->flags&AIM_FLAG_OSCAR_PAY)?" OSCAR_PAY":"",
1082 (userinfo->flags&AIM_FLAG_FREE)?" FREE":"",
1083 (userinfo->flags&AIM_FLAG_AWAY)?" AWAY":"",
1084 (userinfo->flags&AIM_FLAG_UNKNOWN40)?" UNKNOWN40":"",
1085 (userinfo->flags&AIM_FLAG_UNKNOWN80)?" UNKNOWN80":"",
b69540e3 1086 userinfo->capabilities);
9de3ca7e 1087 return 1;
1088}
1089
397055b1 1090int faimtest_parse_offgoing(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 1091{
397055b1 1092 char *sn;
1093 va_list ap;
1094
1095 va_start(ap, command);
1096 sn = va_arg(ap, char *);
1097 va_end(ap);
9de3ca7e 1098
397055b1 1099 printf("\n%s has left\n", sn);
9de3ca7e 1100
1101 return 1;
1102}
1103
01b59e1e 1104int faimtest_parse_motd(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1105{
96f8b1ed 1106 static char *codes[] = {
1107 "Unknown",
1108 "Mandatory upgrade",
1109 "Advisory upgrade",
1110 "System bulletin",
1111 "Top o' the world!"};
1112 static int codeslen = 5;
1113
01b59e1e 1114 char *msg;
96f8b1ed 1115 unsigned short id;
01b59e1e 1116 va_list ap;
1117
1118 va_start(ap, command);
e7fb57f5 1119 id = va_arg(ap, int);
01b59e1e 1120 msg = va_arg(ap, char *);
1121 va_end(ap);
1122
96f8b1ed 1123 printf("faimtest: motd: %s (%d / %s)\n", msg, id,
1124 (id < codeslen)?codes[id]:"unknown");
1125
1126 return 1;
1127}
1128
1129int faimtest_parse_msgerr(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1130{
1131 va_list ap;
1132 char *destsn;
1133 unsigned short reason;
1134
1135 va_start(ap, command);
1136 destsn = va_arg(ap, char *);
e7fb57f5 1137 reason = va_arg(ap, int);
96f8b1ed 1138 va_end(ap);
1139
1140 printf("faimtest: message to %s bounced (reason 0x%04x: %s)\n", destsn, reason, (reason<msgerrreasonslen)?msgerrreasons[reason]:"unknown");
1141
1142 return 1;
1143}
1144
1145int faimtest_parse_locerr(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1146{
1147 va_list ap;
1148 char *destsn;
1149 unsigned short reason;
1150
1151 va_start(ap, command);
1152 destsn = va_arg(ap, char *);
e7fb57f5 1153 reason = va_arg(ap, int);
96f8b1ed 1154 va_end(ap);
01b59e1e 1155
96f8b1ed 1156 printf("faimtest: user information for %s unavailable (reason 0x%04x: %s)\n", destsn, reason, (reason<msgerrreasonslen)?msgerrreasons[reason]:"unknown");
1157
01b59e1e 1158 return 1;
1159}
9de3ca7e 1160
1161/*
96f8b1ed 1162 * Handles callbacks for AIM_CB_MISSED_CALL.
9de3ca7e 1163 */
397055b1 1164int faimtest_parse_misses(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 1165{
96f8b1ed 1166 static char *missedreasons[] = {
1167 "Unknown",
1168 "Message too large"};
1169 static int missedreasonslen = 2;
9de3ca7e 1170
96f8b1ed 1171 va_list ap;
1172 unsigned short chan, nummissed, reason;
1173 struct aim_userinfo_s *userinfo;
9de3ca7e 1174
96f8b1ed 1175 va_start(ap, command);
e7fb57f5 1176 chan = va_arg(ap, int);
96f8b1ed 1177 userinfo = va_arg(ap, struct aim_userinfo_s *);
e7fb57f5 1178 nummissed = va_arg(ap, int);
1179 reason = va_arg(ap, int);
96f8b1ed 1180 va_end(ap);
9de3ca7e 1181
96f8b1ed 1182 printf("faimtest: missed %d messages from %s (reason %d: %s)\n", nummissed, userinfo->sn, reason, (reason<missedreasonslen)?missedreasons[reason]:"unknown");
1183
00f3b08b 1184 return 1;
9de3ca7e 1185}
1186
01b59e1e 1187int faimtest_parse_login(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1188{
b5bc2a8c 1189 struct client_info_s info = {"faimtest (with SNAC login)", 4, 1, 2010, "us", "en", 0x0004, 0x0000, 0x0000004b}; /* 4.1.2010 */
78b3fb13 1190 char *key;
b5bc2a8c 1191 va_list ap;
01b59e1e 1192
b5bc2a8c 1193 va_start(ap, command);
1194 key = va_arg(ap, char *);
1195 va_end(ap);
9de3ca7e 1196
b5bc2a8c 1197 aim_send_login(sess, command->conn, screenname, password, &info, key);
01b59e1e 1198
1199 return 1;
1200}
0c20631f 1201
1202int faimtest_chat_join(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1203{
1204 va_list ap;
1205 struct aim_userinfo_s *userinfo;
1206 int count = 0, i = 0;
1207
1208 va_start(ap, command);
1209 count = va_arg(ap, int);
1210 userinfo = va_arg(ap, struct aim_userinfo_s *);
1211 va_end(ap);
1212
1213 printf("faimtest: chat: %s: New occupants have joined:\n", (char *)command->conn->priv);
1214 while (i < count)
1215 printf("faimtest: chat: %s: \t%s\n", (char *)command->conn->priv, userinfo[i++].sn);
1216
1217 return 1;
1218}
1219
1220int faimtest_chat_leave(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1221{
1222 va_list ap;
1223 struct aim_userinfo_s *userinfo;
1224 int count = 0, i = 0;
1225
1226 va_start(ap, command);
1227 count = va_arg(ap, int);
1228 userinfo = va_arg(ap, struct aim_userinfo_s *);
1229 va_end(ap);
1230
1231 printf("faimtest: chat: %s: Some occupants have left:\n", (char *)command->conn->priv);
1232 while (i < count)
1233 printf("faimtest: chat: %s: \t%s\n", (char *)command->conn->priv, userinfo[i++].sn);
1234
1235 return 1;
1236}
1237
1238int faimtest_chat_infoupdate(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1239{
1240 va_list ap;
1241 struct aim_userinfo_s *userinfo;
1242 struct aim_chat_roominfo *roominfo;
1243 char *roomname;
1244 int usercount,i;
1245 char *roomdesc;
aa6efcfd 1246 unsigned short unknown_c9, unknown_d2, unknown_d5, maxmsglen;
1247 unsigned long creationtime;
0c20631f 1248
1249 va_start(ap, command);
1250 roominfo = va_arg(ap, struct aim_chat_roominfo *);
1251 roomname = va_arg(ap, char *);
1252 usercount= va_arg(ap, int);
1253 userinfo = va_arg(ap, struct aim_userinfo_s *);
1254 roomdesc = va_arg(ap, char *);
e7fb57f5 1255 unknown_c9 = va_arg(ap, int);
aa6efcfd 1256 creationtime = va_arg(ap, unsigned long);
e7fb57f5 1257 maxmsglen = va_arg(ap, int);
1258 unknown_d2 = va_arg(ap, int);
1259 unknown_d5 = va_arg(ap, int);
0c20631f 1260 va_end(ap);
1261
1262 printf("faimtest: chat: %s: info update:\n", (char *)command->conn->priv);
1263 printf("faimtest: chat: %s: \tRoominfo: {%04x, %s, %04x}\n",
1264 (char *)command->conn->priv,
1265 roominfo->exchange,
1266 roominfo->name,
1267 roominfo->instance);
1268 printf("faimtest: chat: %s: \tRoomname: %s\n", (char *)command->conn->priv, roomname);
1269 printf("faimtest: chat: %s: \tRoomdesc: %s\n", (char *)command->conn->priv, roomdesc);
1270 printf("faimtest: chat: %s: \tOccupants: (%d)\n", (char *)command->conn->priv, usercount);
1271
1272 i = 0;
1273 while (i < usercount)
1274 printf("faimtest: chat: %s: \t\t%s\n", (char *)command->conn->priv, userinfo[i++].sn);
1275
aa6efcfd 1276 printf("faimtest: chat: %s: \tUnknown_c9: 0x%04x\n", (char *)command->conn->priv, unknown_c9);
1277 printf("faimtest: chat: %s: \tCreation time: %lu (time_t)\n", (char *)command->conn->priv, creationtime);
1278 printf("faimtest: chat: %s: \tMax message length: %d bytes\n", (char *)command->conn->priv, maxmsglen);
1279 printf("faimtest: chat: %s: \tUnknown_d2: 0x%04x\n", (char *)command->conn->priv, unknown_d2);
1280 printf("faimtest: chat: %s: \tUnknown_d5: 0x%02x\n", (char *)command->conn->priv, unknown_d5);
1281
0c20631f 1282 return 1;
1283}
1284
1285int faimtest_chat_incomingmsg(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1286{
1287 va_list ap;
1288 struct aim_userinfo_s *userinfo;
1289 char *msg;
1290 char tmpbuf[1152];
1291
1292 va_start(ap, command);
1293 userinfo = va_arg(ap, struct aim_userinfo_s *);
1294 msg = va_arg(ap, char *);
1295 va_end(ap);
1296
1297 printf("faimtest: chat: %s: incoming msg from %s: %s\n", (char *)command->conn->priv, userinfo->sn, msg);
1298
1299 /*
1300 * Do an echo for testing purposes. But not for ourselves ("oops!")
1301 */
1302 if (strcmp(userinfo->sn, sess->logininfo.screen_name) != 0)
1303 {
1304 sprintf(tmpbuf, "(%s said \"%s\")", userinfo->sn, msg);
1305 aim_chat_send_im(sess, command->conn, tmpbuf);
1306 }
1307
1308 return 1;
1309}
1310
1311int faimtest_chatnav_info(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1312{
e7fb57f5 1313 unsigned short type;
0c20631f 1314 va_list ap;
1315
e7fb57f5 1316 va_start(ap, command);
1317 type = va_arg(ap, int);
0c20631f 1318
efe9513b 1319 switch(type) {
1320 case 0x0002: {
1321 int maxrooms;
1322 struct aim_chat_exchangeinfo *exchanges;
1323 int exchangecount,i = 0;
1324
e7fb57f5 1325 maxrooms = va_arg(ap, int);
efe9513b 1326 exchangecount = va_arg(ap, int);
1327 exchanges = va_arg(ap, struct aim_chat_exchangeinfo *);
1328 va_end(ap);
1329
1330 printf("faimtest: chat info: Chat Rights:\n");
1331 printf("faimtest: chat info: \tMax Concurrent Rooms: %d\n", maxrooms);
1332
1333 printf("faimtest: chat info: \tExchange List: (%d total)\n", exchangecount);
1334 while (i < exchangecount) {
1335 printf("faimtest: chat info: \t\t%x: %s (%s/%s)\n",
1336 exchanges[i].number,
1337 exchanges[i].name,
1338 exchanges[i].charset1,
1339 exchanges[i].lang1);
1340 i++;
0c20631f 1341 }
efe9513b 1342
1343 }
1344 break;
1345 case 0x0008: {
1346 char *fqcn, *name, *ck;
1347 unsigned short instance, flags, maxmsglen, maxoccupancy, unknown;
1348 unsigned char createperms;
1349 unsigned long createtime;
1350
1351 fqcn = va_arg(ap, char *);
e7fb57f5 1352 instance = va_arg(ap, int);
1353 flags = va_arg(ap, int);
efe9513b 1354 createtime = va_arg(ap, unsigned long);
e7fb57f5 1355 maxmsglen = va_arg(ap, int);
1356 maxoccupancy = va_arg(ap, int);
1357 createperms = va_arg(ap, int);
1358 unknown = va_arg(ap, int);
efe9513b 1359 name = va_arg(ap, char *);
1360 ck = va_arg(ap, char *);
1361 va_end(ap);
1362
1363 printf("faimtest: recieved room create reply for %s\n", fqcn);
1364 }
1365 break;
1366 default:
1367 va_end(ap);
1368 printf("faimtest: chatnav info: unknown type (%04x)\n", type);
1369 }
0c20631f 1370 return 1;
1371}
5e02cf44 1372
1373int faimtest_parse_connerr(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1374{
1375 va_list ap;
1376 unsigned short code;
1377 char *msg = NULL;
1378
e7fb57f5 1379 va_start(ap, command);
1380 code = va_arg(ap, int);
5e02cf44 1381 msg = va_arg(ap, char *);
1382 va_end(ap);
1383
1384 printf("faimtest: connerr: Code 0x%04x: %s\n", code, msg);
68ac63c2 1385 aim_conn_kill(sess, &command->conn); /* this will break the main loop */
5e02cf44 1386
1387 return 1;
1388}
e5012450 1389
1390int faimtest_debugconn_connect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1391{
1392 printf("faimtest: connecting to an aimdebugd!\n");
1393
1394 /* convert the authorizer connection to a BOS connection */
1395 command->conn->type = AIM_CONN_TYPE_BOS;
1396
1397 aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_MSG, AIM_CB_MSG_INCOMING, faimtest_parse_incoming_im, 0);
1398
1399 /* tell the aimddebugd we're ready */
1400 aim_debugconn_sendconnect(sess, command->conn);
1401
1402 /* go right into main loop (don't open a BOS connection, etc) */
1403 return 1;
1404}
1a8c261b 1405
1406/*
1407 * Recieved in response to an IM sent with the AIM_IMFLAGS_ACK option.
1408 */
1409int faimtest_parse_msgack(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1410{
1411 va_list ap;
1412 unsigned short type;
1413 char *sn = NULL;
1414
e7fb57f5 1415 va_start(ap, command);
1416 type = va_arg(ap, int);
1a8c261b 1417 sn = va_arg(ap, char *);
1418 va_end(ap);
1419
1420 printf("faimtest: msgack: 0x%04x / %s\n", type, sn);
1421
1422 return 1;
1423}
1424
871e2fd0 1425#ifdef FILESUPPORT
1426int faimtest_getfile_filereq(struct aim_session_t *ses, struct command_rx_struct *command, ...)
1427{
1428 va_list ap;
1429 struct aim_conn_t *oftconn;
1430 struct aim_fileheader_t *fh;
1431 char *cookie;
1432
e7fb57f5 1433 va_start(ap, command);
871e2fd0 1434 oftconn = va_arg(ap, struct aim_conn_t *);
1435 fh = va_arg(ap, struct aim_fileheader_t *);
1436 cookie = va_arg(ap, char *);
1437 va_end(ap);
1438
1439 printf("faimtest: request for file %s.\n", fh->name);
1440
1441 return 1;
1442}
1443
1444
1445int faimtest_getfile_filesend(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1446{
1447 va_list ap;
1448 struct aim_conn_t *oftconn;
1449 struct aim_fileheader_t *fh;
1450 char *path, *cookie;
1451
1452 FILE *file;
1453
e7fb57f5 1454 va_start(ap, command);
871e2fd0 1455 oftconn = va_arg(ap, struct aim_conn_t *);
1456 fh = va_arg(ap, struct aim_fileheader_t *);
1457 cookie = va_arg(ap, char *);
1458 va_end(ap);
1459
1460 printf("faimtest: sending file %s.\n", fh->name);
1461
1462 if( (path = (char *)calloc(1, strlen(sess->oft.listingdir) +strlen(fh->name)+2)) == NULL) {
1463 perror("calloc:");
1464 printf("faimtest: error in calloc of path\n");
1465 return 0; /* XXX: no idea what winaim expects here =) */
1466 }
1467
1468 snprintf(path, strlen(sess->oft.listingdir)+strlen(fh->name)+2, "%s/%s", sess->oft.listingdir, fh->name);
1469
1470
1471 if( (file = fopen(path, "r")) == NULL) {
1472 printf("faimtest: getfile_send fopen failed for %s. damn.\n", path);
1473 return 0;
1474 }
1475
1476 if (aim_getfile_send(oftconn, file, fh) == -1) {
1477 printf("faimtest: getfile_send failed. damn.\n");
1478 } else {
1479 printf("faimtest: looks like getfile went clean\n");
1480 }
1481
1482 free(fh);
1483 return 1;
1484}
1485
1486int faimtest_getfile_complete(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1487{
1488 va_list ap;
1489 struct aim_conn_t *conn;
1490 struct aim_fileheader_t *fh;
1491
e7fb57f5 1492 va_start(ap, command);
871e2fd0 1493 conn = va_arg(ap, struct aim_conn_t *);
1494 fh = va_arg(ap, struct aim_fileheader_t *);
1495 va_end(ap);
1496
1497 printf("faimtest: completed file transfer for %s.\n", fh->name);
1498
1499 /* aim_conn_kill(sess, &conn); */ /* we'll let winaim close the conn */
1500 return 1;
1501}
1502
1503int faimtest_getfile_disconnect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1504{
1505 va_list ap;
1506 struct aim_conn_t *conn;
1507 char *sn;
1508
e7fb57f5 1509 va_start(ap, command);
871e2fd0 1510 conn = va_arg(ap, struct aim_conn_t *);
1511 sn = va_arg(ap, char *);
1512 va_end(ap);
1513
1514 aim_conn_kill(sess, &conn);
1515
1516 printf("faimtest: getfile: disconnected from %s\n", sn);
1517 return 1;
1518}
1519#endif
1520
1a8c261b 1521int faimtest_parse_ratechange(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1522{
1523 va_list ap;
1524 unsigned long newrate;
1525
1526 va_start(ap, command);
1527 newrate = va_arg(ap, unsigned long);
1528 va_end(ap);
1529
1530 printf("faimtest: ratechange: %lu\n", newrate);
1531
871e2fd0 1532 return 1;
78b3fb13 1533}
98c88242 1534
1535int faimtest_parse_evilnotify(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1536{
1537 va_list ap;
1538 char *sn;
1539
1540 va_start(ap, command);
1541 sn = va_arg(ap, char *);
1542 va_end(ap);
1543
1544 printf("faimtest: warning from: %s\n", sn);
1545
98c88242 1546 return 1;
78b3fb13 1547}
This page took 5.291756 seconds and 5 git commands to generate.