]> andersk Git - libfaim.git/blame - utils/faimtest/faimtest.c
- Fri Nov 10 08:24:34 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;
9de3ca7e 512 struct aim_conn_t *tstconn = NULL;
0c20631f 513
514 roomname = va_arg(ap, char *);
515
397055b1 516 tstconn = aim_newconn(sess, AIM_CONN_TYPE_CHAT, ip);
22517493 517 if ( (tstconn==NULL) || (tstconn->status & AIM_CONN_STATUS_RESOLVERR))
9de3ca7e 518 {
519 fprintf(stderr, "faimtest: unable to connect to chat server\n");
040457cc 520 if (tstconn) aim_conn_kill(sess, &tstconn);
9de3ca7e 521 return 1;
0c20631f 522 }
523 printf("faimtest: chat: connected\n");
524
525 /*
526 * We must do this to attach the stored name to the connection!
527 */
528 aim_chat_attachname(tstconn, roomname);
529
530 aim_conn_addhandler(sess, tstconn, 0x0001, 0x0003, faimtest_serverready, 0);
22517493 531 aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
0c20631f 532 aim_auth_sendcookie(sess, tstconn, cookie);
9de3ca7e 533 }
534 break;
535 default:
536 printf("uh oh... got redirect for unknown service 0x%04x!!\n", serviceid);
537 /* dunno */
538 }
539
9de3ca7e 540 va_end(ap);
541
0c20631f 542 return 1;
9de3ca7e 543}
544
01b59e1e 545int faimtest_parse_authresp(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 546{
9de3ca7e 547 struct aim_conn_t *bosconn = NULL;
9de3ca7e 548
01b59e1e 549
397055b1 550 printf("Screen name: %s\n", sess->logininfo.screen_name);
01b59e1e 551
552 /*
553 * Check for error.
554 */
555 if (sess->logininfo.errorcode)
556 {
557 printf("Login Error Code 0x%04x\n", sess->logininfo.errorcode);
558 printf("Error URL: %s\n", sess->logininfo.errorurl);
040457cc 559 aim_conn_kill(sess, &command->conn);
01b59e1e 560 exit(0); /* XXX: should return in order to let the above things get free()'d. */
561 }
562
397055b1 563 printf("Reg status: %2d\n", sess->logininfo.regstatus);
564 printf("Email: %s\n", sess->logininfo.email);
397055b1 565 printf("BOS IP: %s\n", sess->logininfo.BOSIP);
9de3ca7e 566
567 printf("Closing auth connection...\n");
040457cc 568 aim_conn_kill(sess, &command->conn);
397055b1 569 bosconn = aim_newconn(sess, AIM_CONN_TYPE_BOS, sess->logininfo.BOSIP);
040457cc 570 if (bosconn == NULL) {
571 fprintf(stderr, "faimtest: could not connect to BOS: internal error\n");
22517493 572 } else if (bosconn->status & AIM_CONN_STATUS_CONNERR) {
040457cc 573 fprintf(stderr, "faimtest: could not connect to BOS\n");
574 aim_conn_kill(sess, &bosconn);
575 } else {
22517493 576 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
c78446b5 577 aim_conn_addhandler(sess, bosconn, 0x0009, 0x0003, faimtest_bosrights, 0);
578 aim_conn_addhandler(sess, bosconn, 0x0001, 0x0007, faimtest_rateresp, 0); /* rate info */
040457cc 579 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ACK, AIM_CB_ACK_ACK, NULL, 0);
580 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_SERVERREADY, faimtest_serverready, 0);
581 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_RATEINFO, NULL, 0);
582 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_REDIRECT, faimtest_handleredirect, 0);
f0a7908e 583 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_STS, AIM_CB_STS_SETREPORTINTERVAL, faimtest_reportinterval, 0);
96f8b1ed 584 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_RIGHTSINFO, faimtest_parse_buddyrights, 0);
040457cc 585 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_ONCOMING, faimtest_parse_oncoming, 0);
586 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_OFFGOING, faimtest_parse_offgoing, 0);
587 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_INCOMING, faimtest_parse_incoming_im, 0);
96f8b1ed 588 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_ERROR, faimtest_parse_locerr, 0);
040457cc 589 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_MISSEDCALL, faimtest_parse_misses, 0);
1a8c261b 590 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_RATECHANGE, faimtest_parse_ratechange, 0);
98c88242 591 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_EVIL, faimtest_parse_evilnotify, 0);
96f8b1ed 592 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ERROR, faimtest_parse_msgerr, 0);
040457cc 593 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO, faimtest_parse_userinfo, 0);
1a8c261b 594 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ACK, faimtest_parse_msgack, 0);
595
040457cc 596 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_CTN, AIM_CB_CTN_DEFAULT, aim_parse_unknown, 0);
597 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_DEFAULT, aim_parse_unknown, 0);
598 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_MOTD, faimtest_parse_motd, 0);
599
600 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, faimtest_parse_connerr, 0);
601
602 aim_auth_sendcookie(sess, bosconn, sess->logininfo.cookie);
603 }
9de3ca7e 604 return 1;
605}
606
a15d82b1 607static void printuserflags(unsigned short flags)
608{
609 if (flags & AIM_FLAG_UNCONFIRMED)
610 printf("UNCONFIRMED ");
611 if (flags & AIM_FLAG_ADMINISTRATOR)
612 printf("ADMINISTRATOR ");
613 if (flags & AIM_FLAG_AOL)
614 printf("AOL ");
615 if (flags & AIM_FLAG_OSCAR_PAY)
616 printf("OSCAR_PAY ");
617 if (flags & AIM_FLAG_FREE)
618 printf("FREE ");
619 if (flags & AIM_FLAG_AWAY)
620 printf("AWAY ");
621 if (flags & AIM_FLAG_UNKNOWN40)
622 printf("ICQ? ");
623 if (flags & AIM_FLAG_UNKNOWN80)
624 printf("UNKNOWN80 ");
625 return;
626}
627
397055b1 628int faimtest_parse_userinfo(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 629{
630 struct aim_userinfo_s *userinfo;
631 char *prof_encoding = NULL;
632 char *prof = NULL;
5e02cf44 633 unsigned short inforeq = 0;
9de3ca7e 634
635 va_list ap;
636 va_start(ap, command);
637 userinfo = va_arg(ap, struct aim_userinfo_s *);
638 prof_encoding = va_arg(ap, char *);
639 prof = va_arg(ap, char *);
e7fb57f5 640 inforeq = va_arg(ap, int);
9de3ca7e 641 va_end(ap);
642
643 printf("faimtest: userinfo: sn: %s\n", userinfo->sn);
644 printf("faimtest: userinfo: warnlevel: 0x%04x\n", userinfo->warnlevel);
a15d82b1 645 printf("faimtest: userinfo: flags: 0x%04x = ", userinfo->flags);
646 printuserflags(userinfo->flags);
9de3ca7e 647 printf("\n");
648
649 printf("faimtest: userinfo: membersince: %lu\n", userinfo->membersince);
650 printf("faimtest: userinfo: onlinesince: %lu\n", userinfo->onlinesince);
651 printf("faimtest: userinfo: idletime: 0x%04x\n", userinfo->idletime);
652
5e02cf44 653 if (inforeq == AIM_GETINFO_GENERALINFO) {
654 printf("faimtest: userinfo: profile_encoding: %s\n", prof_encoding ? prof_encoding : "[none]");
655 printf("faimtest: userinfo: prof: %s\n", prof ? prof : "[none]");
656 } else if (inforeq == AIM_GETINFO_AWAYMESSAGE) {
657 printf("faimtest: userinfo: awaymsg_encoding: %s\n", prof_encoding ? prof_encoding : "[none]");
658 printf("faimtest: userinfo: awaymsg: %s\n", prof ? prof : "[none]");
659 } else
660 printf("faimtest: userinfo: unknown info request\n");
9de3ca7e 661
662 return 1;
663}
664
665/*
666 * The user-level Incoming ICBM callback.
667 *
668 * Arguments:
669 * struct command_rx_struct * command if you feel like doing it yourself
670 * char * srcsn the source name
671 * char * msg message
672 * int warnlevel warning/evil level
a15d82b1 673 * int flags flags
9de3ca7e 674 * ulong membersince time_t of date of signup
675 * ulong onsince time_t of date of singon
676 * int idletime min (sec?) idle
24286d93 677 * u_int icbmflags sets AIM_IMFLAGS_{AWAY,ACK}
9de3ca7e 678 *
679 */
397055b1 680int faimtest_parse_incoming_im(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 681{
26af6789 682 int channel;
9de3ca7e 683 va_list ap;
9de3ca7e 684
685 va_start(ap, command);
26af6789 686 channel = va_arg(ap, int);
9de3ca7e 687
26af6789 688 /*
689 * Channel 1: Standard Message
690 */
040457cc 691 if (channel == 1) {
692 struct aim_userinfo_s *userinfo;
693 char *msg = NULL;
694 u_int icbmflags = 0;
695 char *tmpstr = NULL;
e7fb57f5 696 unsigned short flag1, flag2;
040457cc 697
698 userinfo = va_arg(ap, struct aim_userinfo_s *);
699 msg = va_arg(ap, char *);
700 icbmflags = va_arg(ap, u_int);
e7fb57f5 701 flag1 = va_arg(ap, int);
702 flag2 = va_arg(ap, int);
040457cc 703 va_end(ap);
704
705 printf("faimtest: icbm: sn = \"%s\"\n", userinfo->sn);
706 printf("faimtest: icbm: warnlevel = 0x%04x\n", userinfo->warnlevel);
a15d82b1 707 printf("faimtest: icbm: flags = 0x%04x = ", userinfo->flags);
708 printuserflags(userinfo->flags);
040457cc 709 printf("\n");
a15d82b1 710
040457cc 711 printf("faimtest: icbm: membersince = %lu\n", userinfo->membersince);
712 printf("faimtest: icbm: onlinesince = %lu\n", userinfo->onlinesince);
713 printf("faimtest: icbm: idletime = 0x%04x\n", userinfo->idletime);
b69540e3 714 printf("faimtest: icbm: capabilities = 0x%04x\n", userinfo->capabilities);
040457cc 715
716 printf("faimtest: icbm: icbmflags = ");
717 if (icbmflags & AIM_IMFLAGS_AWAY)
718 printf("away ");
719 if (icbmflags & AIM_IMFLAGS_ACK)
720 printf("ackrequest ");
721 printf("\n");
722
723 printf("faimtest: icbm: encoding flags = {%04x, %04x}\n", flag1, flag2);
724
725 printf("faimtest: icbm: message: %s\n", msg);
726
727 if (msg) {
b69540e3 728 int i = 0;
729
730 while (msg[i] == '<') {
731 if (msg[i] == '<') {
732 while (msg[i] != '>')
733 i++;
734 i++;
735 }
736 }
737 tmpstr = msg+i;
738
739 printf("tmpstr = %s\n", tmpstr);
040457cc 740
741 if ( (strlen(tmpstr) >= 10) &&
742 (!strncmp(tmpstr, "disconnect", 10)) ) {
743 aim_send_im(sess, command->conn, "midendian", 0, "ta ta...");
744 aim_logoff(sess);
745 } else if (strstr(tmpstr, "goodday")) {
746 printf("faimtest: icbm: sending response\n");
1a8c261b 747 aim_send_im(sess, command->conn, userinfo->sn, AIM_IMFLAGS_ACK, "Good day to you too.");
98c88242 748 } else if (strstr(tmpstr, "warnme")) {
749 printf("faimtest: icbm: sending non-anon warning\n");
750 aim_send_warning(sess, command->conn, userinfo->sn, 0);
751 } else if (strstr(tmpstr, "anonwarn")) {
752 printf("faimtest: icbm: sending anon warning\n");
753 aim_send_warning(sess, command->conn, userinfo->sn, AIM_WARN_ANON);
f2d214f9 754 } else if (strstr(tmpstr, "setdirectoryinfo")) {
755 printf("faimtest: icbm: sending backwards profile data\n");
756 aim_setdirectoryinfo(sess, command->conn, "tsrif", "elddim", "tsal", "nediam", "emankcin", "teerts", "ytic", "etats", "piz", 0, 1);
757 } else if (strstr(tmpstr, "setinterests")) {
758 printf("faimtest: icbm: setting fun interests\n");
759 aim_setuserinterests(sess, command->conn, "interest1", "interest2", "interest3", "interest4", "interest5", 1);
040457cc 760 } else if (!strncmp(tmpstr, "open chatnav", 12)) {
761 aim_bos_reqservice(sess, command->conn, AIM_CONN_TYPE_CHATNAV);
762 //aim_chat_join(sess, command->conn, "thishereisaname2_chat85");
763 } else if (!strncmp(tmpstr, "create", 6)) {
7392c79f 764 aim_chatnav_createroom(sess,aim_getconn_type(sess, AIM_CONN_TYPE_CHATNAV), (strlen(tmpstr) < 7)?"WorldDomination":tmpstr+7, 0x0004);
040457cc 765 } else if (!strncmp(tmpstr, "close chatnav", 13)) {
766 struct aim_conn_t *chatnavconn;
767 chatnavconn = aim_getconn_type(sess, AIM_CONN_TYPE_CHATNAV);
768 aim_conn_kill(sess, &chatnavconn);
769 } else if (!strncmp(tmpstr, "join", 4)) {
770 aim_chat_join(sess, command->conn, 0x0004, "worlddomination");
771 } else if (!strncmp(tmpstr, "leave", 5))
772 aim_chat_leaveroom(sess, "worlddomination");
773 else if (!strncmp(tmpstr, "getinfo", 7)) {
774 aim_getinfo(sess, command->conn, "75784102", AIM_GETINFO_GENERALINFO);
775 aim_getinfo(sess, command->conn, "15853637", AIM_GETINFO_AWAYMESSAGE);
7392c79f 776 } else if (!strncmp(tmpstr, "open directim", 13)) {
777 struct aim_conn_t *newconn;
778 newconn = aim_directim_initiate(sess, command->conn, NULL, userinfo->sn);
96f8b1ed 779 } else if (!strncmp(tmpstr, "reqsendmsg", 10)) {
a3619f23 780 aim_send_im(sess, command->conn, "vaxherder", 0, "sendmsg 7900");
b69540e3 781 } else if (!strncmp(tmpstr, "sendmsg", 7)) {
782 int i;
783 i = atoi(tmpstr+8);
784 if (i < 10000) {
785 char *newbuf;
786 int z;
787
788 newbuf = malloc(i+1);
789 for (z = 0; z < i; z++) {
790 newbuf[z] = (z % 10)+0x30;
791 }
792 newbuf[i] = '\0';
793 aim_send_im(sess, command->conn, userinfo->sn, 0, newbuf);
794 free(newbuf);
795 }
040457cc 796 } else {
797 printf("unknown command.\n");
b69540e3 798 aim_add_buddy(sess, command->conn, userinfo->sn);
040457cc 799 }
800
801 }
802 }
803 /*
804 * Channel 2: Rendevous Request
805 */
806 else if (channel == 2) {
807 struct aim_userinfo_s *userinfo;
808 unsigned short reqclass;
809
e7fb57f5 810 reqclass = va_arg(ap, int);
040457cc 811 switch (reqclass) {
b69540e3 812 case AIM_CAPS_VOICE: {
26af6789 813 userinfo = va_arg(ap, struct aim_userinfo_s *);
26af6789 814 va_end(ap);
9de3ca7e 815
040457cc 816 printf("faimtest: voice invitation: source sn = %s\n", userinfo->sn);
817 printf("faimtest: voice invitation: \twarnlevel = 0x%04x\n", userinfo->warnlevel);
a15d82b1 818 printf("faimtest: voice invitation: \tclass = 0x%04x = ", userinfo->flags);
819 printuserflags(userinfo->flags);
26af6789 820 printf("\n");
a15d82b1 821
040457cc 822 /* we dont get membersince on chat invites! */
823 printf("faimtest: voice invitation: \tonlinesince = %lu\n", userinfo->onlinesince);
824 printf("faimtest: voice invitation: \tidletime = 0x%04x\n", userinfo->idletime);
26af6789 825
040457cc 826 break;
827 }
b69540e3 828 case AIM_CAPS_GETFILE: {
871e2fd0 829#ifdef FILESUPPORT
830 char *ip, *cookie;
831 struct aim_conn_t *newconn;
832
833 userinfo = va_arg(ap, struct aim_userinfo_s *);
834 ip = va_arg(ap, char *);
835 cookie = va_arg(ap, char *);
836 va_end(ap);
837
838 printf("faimtest: get file request from %s (at %s)\n", userinfo->sn, ip);
839
840 sleep(1);
841
842 if( (newconn = aim_accepttransfer(sess, command->conn, userinfo->sn, cookie, ip, sess->oft.listing, reqclass)) == NULL ) {
843 printf("faimtest: getfile: requestconn: apparent error in accepttransfer\n");
844 break;
845 }
846
847 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEFILEREQ, faimtest_getfile_filereq, 0);
848 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEFILESEND, faimtest_getfile_filesend, 0);
849 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILECOMPLETE, faimtest_getfile_complete, 0);
850 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEDISCONNECT, faimtest_getfile_disconnect, 0);
851
852 printf("faimtest: getfile connect succeeded, handlers added.\n");
853
040457cc 854 break;
871e2fd0 855#endif
040457cc 856 }
b69540e3 857 case AIM_CAPS_SENDFILE: {
858 printf("faimtest: send file!\n");
859 break;
860 }
861 case AIM_CAPS_CHAT: {
040457cc 862 char *msg,*encoding,*lang;
863 struct aim_chat_roominfo *roominfo;
26af6789 864
040457cc 865 userinfo = va_arg(ap, struct aim_userinfo_s *);
866 roominfo = va_arg(ap, struct aim_chat_roominfo *);
867 msg = va_arg(ap, char *);
868 encoding = va_arg(ap, char *);
869 lang = va_arg(ap, char *);
870 va_end(ap);
26af6789 871
040457cc 872 printf("faimtest: chat invitation: source sn = %s\n", userinfo->sn);
873 printf("faimtest: chat invitation: \twarnlevel = 0x%04x\n", userinfo->warnlevel);
a15d82b1 874 printf("faimtest: chat invitation: \tclass = 0x%04x = ", userinfo->flags);
875 printuserflags(userinfo->flags);
040457cc 876 printf("\n");
a15d82b1 877
040457cc 878 /* we dont get membersince on chat invites! */
879 printf("faimtest: chat invitation: \tonlinesince = %lu\n", userinfo->onlinesince);
880 printf("faimtest: chat invitation: \tidletime = 0x%04x\n", userinfo->idletime);
26af6789 881
040457cc 882 printf("faimtest: chat invitation: message = %s\n", msg);
883 printf("faimtest: chat invitation: room name = %s\n", roominfo->name);
884 printf("faimtest: chat invitation: encoding = %s\n", encoding);
885 printf("faimtest: chat invitation: language = %s\n", lang);
886 printf("faimtest: chat invitation: exchange = 0x%04x\n", roominfo->exchange);
887 printf("faimtest: chat invitation: instance = 0x%04x\n", roominfo->instance);
888 printf("faimtest: chat invitiation: autojoining %s...\n", roominfo->name);
889 /*
890 * Automatically join room...
891 */
892 aim_chat_join(sess, command->conn, 0x0004, roominfo->name);
893 break;
894 }
7392c79f 895 case AIM_CAPS_IMIMAGE: {
896 struct aim_directim_priv *priv;
897 struct aim_conn_t *newconn;
898
899 printf("faimtest: icbm: rendezvous imimage\n");
900
901 userinfo = va_arg(ap, struct aim_userinfo_s *);
902 priv = va_arg(ap, struct aim_directim_priv *);
903 va_end(ap);
904
905 printf("faimtest: OFT: DirectIM: request from %s (%s)\n", userinfo->sn, priv->ip);
906
907 if (!(newconn = aim_directim_connect(sess, command->conn, priv))) {
908 printf("faimtest: icbm: imimage: could not connect\n");
909 break;
910 }
911 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, faimtest_directim_incoming, 0);
912 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMDISCONNECT, faimtest_directim_disconnect, 0);
913 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, faimtest_directim_typing, 0);
914
7392c79f 915 printf("faimtest: OFT: DirectIM: connected to %s\n", userinfo->sn);
916
3b101546 917 aim_send_im_direct(sess, newconn, "goodday");
918
7392c79f 919 break;
920 }
040457cc 921 default:
922 printf("faimtest: icbm: unknown reqclass (%d)\n", reqclass);
923 } /* switch */
924 } else
26af6789 925 printf("faimtest does not support channels > 2 (chan = %02x)\n", channel);
9de3ca7e 926 printf("faimtest: icbm: done with ICBM handling\n");
927
928 return 1;
929}
930
7392c79f 931int faimtest_directim_initiate(struct aim_session_t *sess, struct command_rx_struct *command, ...)
932{
933 va_list ap;
934 struct aim_directim_priv *priv;
935 struct aim_conn_t *newconn;
936
e7fb57f5 937 va_start(ap, command);
7392c79f 938 newconn = va_arg(ap, struct aim_conn_t *);
939 va_end(ap);
940
941 priv = (struct aim_directim_priv *)newconn->priv;
942
943 printf("faimtest: OFT: DirectIM: intitiate success to %s\n", priv->ip);
944
945 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, faimtest_directim_incoming, 0);
946 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMDISCONNECT, faimtest_directim_disconnect, 0);
947 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, faimtest_directim_typing, 0);
948
949 aim_send_im_direct(sess, newconn, "goodday");
950
951 printf("faimtest: OFT: DirectIM: connected to %s\n", priv->sn);
952
953 return 1;
954}
7392c79f 955
956int faimtest_directim_connect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
957{
958 va_list ap;
959 struct aim_directim_priv *priv;
960
e7fb57f5 961 va_start(ap, command);
7392c79f 962 priv = va_arg(ap, struct aim_directim_priv *);
963
964 va_end(ap);
965
966 printf("faimtest: directim_connect\n");
967
968 return 1;
969}
970
971int faimtest_directim_incoming(struct aim_session_t *sess, struct command_rx_struct *command, ...)
972{
973 va_list ap;
974 char *sn = NULL, *msg = NULL;
975 struct aim_conn_t *conn;
976
e7fb57f5 977 va_start(ap, command);
7392c79f 978 conn = va_arg(ap, struct aim_conn_t *);
979 sn = va_arg(ap, char *);
980 msg = va_arg(ap, char *);
981 va_end(ap);
982
983 printf("faimtest: Directim from %s: %s\n", sn, msg);
984 if (!strncmp(msg, "sendmsg", 7)) {
985 int i;
986 i = atoi(msg+8);
987 if (i < 10000) {
988 char *newbuf;
989 int z;
990
991 newbuf = malloc(i+1);
992 for (z = 0; z < i; z++) {
993 newbuf[z] = (z % 10)+0x30;
994 }
995 newbuf[i] = '\0';
996 aim_send_im_direct(sess, conn, newbuf);
997 free(newbuf);
998 }
999 } else if (!strncmp(msg, "goodday", 7)) {
1000 aim_send_im_direct(sess, conn, "Good day to you, too");
1001 } else {
1002 char newmsg[1024];
1003 snprintf(newmsg, sizeof(newmsg), "unknown (%s)\n", msg);
1004 aim_send_im_direct(sess, conn, newmsg);
1005 }
1006 return 1;
1007}
1008
1009int faimtest_directim_disconnect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1010{
871e2fd0 1011 va_list ap;
1012 struct aim_conn_t *conn;
1013 char *sn;
1014
e7fb57f5 1015 va_start(ap, command);
871e2fd0 1016 conn = va_arg(ap, struct aim_conn_t *);
1017 sn = va_arg(ap, char *);
1018 va_end(ap);
1019
871e2fd0 1020 printf("faimtest: directim: disconnected from %s\n", sn);
3b101546 1021
1022 aim_conn_kill(sess, &conn);
7392c79f 1023 return 1;
1024}
1025
1026int faimtest_directim_typing(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1027{
1028 va_list ap;
1029 char *sn;
1030
e7fb57f5 1031 va_start(ap, command);
7392c79f 1032 sn = va_arg(ap, char *);
1033 va_end(ap);
1034
1035 printf("faimtest: ohmigod! %s has started typing (DirectIM). He's going to send you a message! *squeal*\n", sn);
1036 return 1;
1037}
1038
397055b1 1039int faimtest_authsvrready(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 1040{
1041 printf("faimtest_authsvrready: called (contype: %d)\n", command->conn->type);
1042 sleep(10);
1043 /* should just be able to tell it we're ready too... */
397055b1 1044 aim_auth_clientready(sess, command->conn);
9de3ca7e 1045
1046#if 0
1047 /*
1048 * This is where you'd really begin changing your password.
1049 * However, this callback may get called for reasons other
1050 * than you wanting to change your password. You should
1051 * probably check that before actually doing it.
1052 */
397055b1 1053 aim_auth_changepasswd(sess, command->conn, "PWD1", "PWD2");
9de3ca7e 1054#endif
1055
1056 return 1;
1057}
1058
397055b1 1059int faimtest_pwdchngdone(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 1060{
1061 printf("PASSWORD CHANGE SUCCESSFUL!!!\n");
1062 return 1;
1063}
1064
397055b1 1065int faimtest_parse_oncoming(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 1066{
1067 struct aim_userinfo_s *userinfo;
1068
1069 va_list ap;
1070 va_start(ap, command);
1071 userinfo = va_arg(ap, struct aim_userinfo_s *);
1072 va_end(ap);
1073
a15d82b1 1074 printf("\n%s is now online (flags: %04x = %s%s%s%s%s%s%s%s) (caps = 0x%04x)\n",
1075 userinfo->sn, userinfo->flags,
1076 (userinfo->flags&AIM_FLAG_UNCONFIRMED)?" UNCONFIRMED":"",
1077 (userinfo->flags&AIM_FLAG_ADMINISTRATOR)?" ADMINISTRATOR":"",
1078 (userinfo->flags&AIM_FLAG_AOL)?" AOL":"",
1079 (userinfo->flags&AIM_FLAG_OSCAR_PAY)?" OSCAR_PAY":"",
1080 (userinfo->flags&AIM_FLAG_FREE)?" FREE":"",
1081 (userinfo->flags&AIM_FLAG_AWAY)?" AWAY":"",
1082 (userinfo->flags&AIM_FLAG_UNKNOWN40)?" UNKNOWN40":"",
1083 (userinfo->flags&AIM_FLAG_UNKNOWN80)?" UNKNOWN80":"",
b69540e3 1084 userinfo->capabilities);
9de3ca7e 1085 return 1;
1086}
1087
397055b1 1088int faimtest_parse_offgoing(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 1089{
397055b1 1090 char *sn;
1091 va_list ap;
1092
1093 va_start(ap, command);
1094 sn = va_arg(ap, char *);
1095 va_end(ap);
9de3ca7e 1096
397055b1 1097 printf("\n%s has left\n", sn);
9de3ca7e 1098
1099 return 1;
1100}
1101
01b59e1e 1102int faimtest_parse_motd(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1103{
96f8b1ed 1104 static char *codes[] = {
1105 "Unknown",
1106 "Mandatory upgrade",
1107 "Advisory upgrade",
1108 "System bulletin",
1109 "Top o' the world!"};
1110 static int codeslen = 5;
1111
01b59e1e 1112 char *msg;
96f8b1ed 1113 unsigned short id;
01b59e1e 1114 va_list ap;
1115
1116 va_start(ap, command);
e7fb57f5 1117 id = va_arg(ap, int);
01b59e1e 1118 msg = va_arg(ap, char *);
1119 va_end(ap);
1120
96f8b1ed 1121 printf("faimtest: motd: %s (%d / %s)\n", msg, id,
1122 (id < codeslen)?codes[id]:"unknown");
1123
1124 return 1;
1125}
1126
1127int faimtest_parse_msgerr(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1128{
1129 va_list ap;
1130 char *destsn;
1131 unsigned short reason;
1132
1133 va_start(ap, command);
1134 destsn = va_arg(ap, char *);
e7fb57f5 1135 reason = va_arg(ap, int);
96f8b1ed 1136 va_end(ap);
1137
1138 printf("faimtest: message to %s bounced (reason 0x%04x: %s)\n", destsn, reason, (reason<msgerrreasonslen)?msgerrreasons[reason]:"unknown");
1139
1140 return 1;
1141}
1142
1143int faimtest_parse_locerr(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1144{
1145 va_list ap;
1146 char *destsn;
1147 unsigned short reason;
1148
1149 va_start(ap, command);
1150 destsn = va_arg(ap, char *);
e7fb57f5 1151 reason = va_arg(ap, int);
96f8b1ed 1152 va_end(ap);
01b59e1e 1153
96f8b1ed 1154 printf("faimtest: user information for %s unavailable (reason 0x%04x: %s)\n", destsn, reason, (reason<msgerrreasonslen)?msgerrreasons[reason]:"unknown");
1155
01b59e1e 1156 return 1;
1157}
9de3ca7e 1158
1159/*
96f8b1ed 1160 * Handles callbacks for AIM_CB_MISSED_CALL.
9de3ca7e 1161 */
397055b1 1162int faimtest_parse_misses(struct aim_session_t *sess, struct command_rx_struct *command, ...)
9de3ca7e 1163{
96f8b1ed 1164 static char *missedreasons[] = {
1165 "Unknown",
1166 "Message too large"};
1167 static int missedreasonslen = 2;
9de3ca7e 1168
96f8b1ed 1169 va_list ap;
1170 unsigned short chan, nummissed, reason;
1171 struct aim_userinfo_s *userinfo;
9de3ca7e 1172
96f8b1ed 1173 va_start(ap, command);
e7fb57f5 1174 chan = va_arg(ap, int);
96f8b1ed 1175 userinfo = va_arg(ap, struct aim_userinfo_s *);
e7fb57f5 1176 nummissed = va_arg(ap, int);
1177 reason = va_arg(ap, int);
96f8b1ed 1178 va_end(ap);
9de3ca7e 1179
96f8b1ed 1180 printf("faimtest: missed %d messages from %s (reason %d: %s)\n", nummissed, userinfo->sn, reason, (reason<missedreasonslen)?missedreasons[reason]:"unknown");
1181
00f3b08b 1182 return 1;
9de3ca7e 1183}
1184
01b59e1e 1185int faimtest_parse_login(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1186{
b5bc2a8c 1187 struct client_info_s info = {"faimtest (with SNAC login)", 4, 1, 2010, "us", "en", 0x0004, 0x0000, 0x0000004b}; /* 4.1.2010 */
78b3fb13 1188 char *key;
b5bc2a8c 1189 va_list ap;
01b59e1e 1190
b5bc2a8c 1191 va_start(ap, command);
1192 key = va_arg(ap, char *);
1193 va_end(ap);
9de3ca7e 1194
b5bc2a8c 1195 aim_send_login(sess, command->conn, screenname, password, &info, key);
01b59e1e 1196
1197 return 1;
1198}
0c20631f 1199
1200int faimtest_chat_join(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1201{
1202 va_list ap;
1203 struct aim_userinfo_s *userinfo;
1204 int count = 0, i = 0;
1205
1206 va_start(ap, command);
1207 count = va_arg(ap, int);
1208 userinfo = va_arg(ap, struct aim_userinfo_s *);
1209 va_end(ap);
1210
1211 printf("faimtest: chat: %s: New occupants have joined:\n", (char *)command->conn->priv);
1212 while (i < count)
1213 printf("faimtest: chat: %s: \t%s\n", (char *)command->conn->priv, userinfo[i++].sn);
1214
1215 return 1;
1216}
1217
1218int faimtest_chat_leave(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1219{
1220 va_list ap;
1221 struct aim_userinfo_s *userinfo;
1222 int count = 0, i = 0;
1223
1224 va_start(ap, command);
1225 count = va_arg(ap, int);
1226 userinfo = va_arg(ap, struct aim_userinfo_s *);
1227 va_end(ap);
1228
1229 printf("faimtest: chat: %s: Some occupants have left:\n", (char *)command->conn->priv);
1230 while (i < count)
1231 printf("faimtest: chat: %s: \t%s\n", (char *)command->conn->priv, userinfo[i++].sn);
1232
1233 return 1;
1234}
1235
1236int faimtest_chat_infoupdate(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1237{
1238 va_list ap;
1239 struct aim_userinfo_s *userinfo;
1240 struct aim_chat_roominfo *roominfo;
1241 char *roomname;
1242 int usercount,i;
1243 char *roomdesc;
aa6efcfd 1244 unsigned short unknown_c9, unknown_d2, unknown_d5, maxmsglen;
1245 unsigned long creationtime;
0c20631f 1246
1247 va_start(ap, command);
1248 roominfo = va_arg(ap, struct aim_chat_roominfo *);
1249 roomname = va_arg(ap, char *);
1250 usercount= va_arg(ap, int);
1251 userinfo = va_arg(ap, struct aim_userinfo_s *);
1252 roomdesc = va_arg(ap, char *);
e7fb57f5 1253 unknown_c9 = va_arg(ap, int);
aa6efcfd 1254 creationtime = va_arg(ap, unsigned long);
e7fb57f5 1255 maxmsglen = va_arg(ap, int);
1256 unknown_d2 = va_arg(ap, int);
1257 unknown_d5 = va_arg(ap, int);
0c20631f 1258 va_end(ap);
1259
1260 printf("faimtest: chat: %s: info update:\n", (char *)command->conn->priv);
1261 printf("faimtest: chat: %s: \tRoominfo: {%04x, %s, %04x}\n",
1262 (char *)command->conn->priv,
1263 roominfo->exchange,
1264 roominfo->name,
1265 roominfo->instance);
1266 printf("faimtest: chat: %s: \tRoomname: %s\n", (char *)command->conn->priv, roomname);
1267 printf("faimtest: chat: %s: \tRoomdesc: %s\n", (char *)command->conn->priv, roomdesc);
1268 printf("faimtest: chat: %s: \tOccupants: (%d)\n", (char *)command->conn->priv, usercount);
1269
1270 i = 0;
1271 while (i < usercount)
1272 printf("faimtest: chat: %s: \t\t%s\n", (char *)command->conn->priv, userinfo[i++].sn);
1273
aa6efcfd 1274 printf("faimtest: chat: %s: \tUnknown_c9: 0x%04x\n", (char *)command->conn->priv, unknown_c9);
1275 printf("faimtest: chat: %s: \tCreation time: %lu (time_t)\n", (char *)command->conn->priv, creationtime);
1276 printf("faimtest: chat: %s: \tMax message length: %d bytes\n", (char *)command->conn->priv, maxmsglen);
1277 printf("faimtest: chat: %s: \tUnknown_d2: 0x%04x\n", (char *)command->conn->priv, unknown_d2);
1278 printf("faimtest: chat: %s: \tUnknown_d5: 0x%02x\n", (char *)command->conn->priv, unknown_d5);
1279
0c20631f 1280 return 1;
1281}
1282
1283int faimtest_chat_incomingmsg(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1284{
1285 va_list ap;
1286 struct aim_userinfo_s *userinfo;
1287 char *msg;
1288 char tmpbuf[1152];
1289
1290 va_start(ap, command);
1291 userinfo = va_arg(ap, struct aim_userinfo_s *);
1292 msg = va_arg(ap, char *);
1293 va_end(ap);
1294
1295 printf("faimtest: chat: %s: incoming msg from %s: %s\n", (char *)command->conn->priv, userinfo->sn, msg);
1296
1297 /*
1298 * Do an echo for testing purposes. But not for ourselves ("oops!")
1299 */
1300 if (strcmp(userinfo->sn, sess->logininfo.screen_name) != 0)
1301 {
1302 sprintf(tmpbuf, "(%s said \"%s\")", userinfo->sn, msg);
1303 aim_chat_send_im(sess, command->conn, tmpbuf);
1304 }
1305
1306 return 1;
1307}
1308
1309int faimtest_chatnav_info(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1310{
e7fb57f5 1311 unsigned short type;
0c20631f 1312 va_list ap;
1313
e7fb57f5 1314 va_start(ap, command);
1315 type = va_arg(ap, int);
0c20631f 1316
efe9513b 1317 switch(type) {
1318 case 0x0002: {
1319 int maxrooms;
1320 struct aim_chat_exchangeinfo *exchanges;
1321 int exchangecount,i = 0;
1322
e7fb57f5 1323 maxrooms = va_arg(ap, int);
efe9513b 1324 exchangecount = va_arg(ap, int);
1325 exchanges = va_arg(ap, struct aim_chat_exchangeinfo *);
1326 va_end(ap);
1327
1328 printf("faimtest: chat info: Chat Rights:\n");
1329 printf("faimtest: chat info: \tMax Concurrent Rooms: %d\n", maxrooms);
1330
1331 printf("faimtest: chat info: \tExchange List: (%d total)\n", exchangecount);
1332 while (i < exchangecount) {
1333 printf("faimtest: chat info: \t\t%x: %s (%s/%s)\n",
1334 exchanges[i].number,
1335 exchanges[i].name,
1336 exchanges[i].charset1,
1337 exchanges[i].lang1);
1338 i++;
0c20631f 1339 }
efe9513b 1340
1341 }
1342 break;
1343 case 0x0008: {
1344 char *fqcn, *name, *ck;
1345 unsigned short instance, flags, maxmsglen, maxoccupancy, unknown;
1346 unsigned char createperms;
1347 unsigned long createtime;
1348
1349 fqcn = va_arg(ap, char *);
e7fb57f5 1350 instance = va_arg(ap, int);
1351 flags = va_arg(ap, int);
efe9513b 1352 createtime = va_arg(ap, unsigned long);
e7fb57f5 1353 maxmsglen = va_arg(ap, int);
1354 maxoccupancy = va_arg(ap, int);
1355 createperms = va_arg(ap, int);
1356 unknown = va_arg(ap, int);
efe9513b 1357 name = va_arg(ap, char *);
1358 ck = va_arg(ap, char *);
1359 va_end(ap);
1360
1361 printf("faimtest: recieved room create reply for %s\n", fqcn);
1362 }
1363 break;
1364 default:
1365 va_end(ap);
1366 printf("faimtest: chatnav info: unknown type (%04x)\n", type);
1367 }
0c20631f 1368 return 1;
1369}
5e02cf44 1370
1371int faimtest_parse_connerr(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1372{
1373 va_list ap;
1374 unsigned short code;
1375 char *msg = NULL;
1376
e7fb57f5 1377 va_start(ap, command);
1378 code = va_arg(ap, int);
5e02cf44 1379 msg = va_arg(ap, char *);
1380 va_end(ap);
1381
1382 printf("faimtest: connerr: Code 0x%04x: %s\n", code, msg);
68ac63c2 1383 aim_conn_kill(sess, &command->conn); /* this will break the main loop */
5e02cf44 1384
1385 return 1;
1386}
e5012450 1387
1388int faimtest_debugconn_connect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1389{
1390 printf("faimtest: connecting to an aimdebugd!\n");
1391
1392 /* convert the authorizer connection to a BOS connection */
1393 command->conn->type = AIM_CONN_TYPE_BOS;
1394
1395 aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_MSG, AIM_CB_MSG_INCOMING, faimtest_parse_incoming_im, 0);
1396
1397 /* tell the aimddebugd we're ready */
1398 aim_debugconn_sendconnect(sess, command->conn);
1399
1400 /* go right into main loop (don't open a BOS connection, etc) */
1401 return 1;
1402}
1a8c261b 1403
1404/*
1405 * Recieved in response to an IM sent with the AIM_IMFLAGS_ACK option.
1406 */
1407int faimtest_parse_msgack(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1408{
1409 va_list ap;
1410 unsigned short type;
1411 char *sn = NULL;
1412
e7fb57f5 1413 va_start(ap, command);
1414 type = va_arg(ap, int);
1a8c261b 1415 sn = va_arg(ap, char *);
1416 va_end(ap);
1417
1418 printf("faimtest: msgack: 0x%04x / %s\n", type, sn);
1419
1420 return 1;
1421}
1422
871e2fd0 1423#ifdef FILESUPPORT
1424int faimtest_getfile_filereq(struct aim_session_t *ses, struct command_rx_struct *command, ...)
1425{
1426 va_list ap;
1427 struct aim_conn_t *oftconn;
1428 struct aim_fileheader_t *fh;
1429 char *cookie;
1430
e7fb57f5 1431 va_start(ap, command);
871e2fd0 1432 oftconn = va_arg(ap, struct aim_conn_t *);
1433 fh = va_arg(ap, struct aim_fileheader_t *);
1434 cookie = va_arg(ap, char *);
1435 va_end(ap);
1436
1437 printf("faimtest: request for file %s.\n", fh->name);
1438
1439 return 1;
1440}
1441
1442
1443int faimtest_getfile_filesend(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1444{
1445 va_list ap;
1446 struct aim_conn_t *oftconn;
1447 struct aim_fileheader_t *fh;
1448 char *path, *cookie;
1449
1450 FILE *file;
1451
e7fb57f5 1452 va_start(ap, command);
871e2fd0 1453 oftconn = va_arg(ap, struct aim_conn_t *);
1454 fh = va_arg(ap, struct aim_fileheader_t *);
1455 cookie = va_arg(ap, char *);
1456 va_end(ap);
1457
1458 printf("faimtest: sending file %s.\n", fh->name);
1459
1460 if( (path = (char *)calloc(1, strlen(sess->oft.listingdir) +strlen(fh->name)+2)) == NULL) {
1461 perror("calloc:");
1462 printf("faimtest: error in calloc of path\n");
1463 return 0; /* XXX: no idea what winaim expects here =) */
1464 }
1465
1466 snprintf(path, strlen(sess->oft.listingdir)+strlen(fh->name)+2, "%s/%s", sess->oft.listingdir, fh->name);
1467
1468
1469 if( (file = fopen(path, "r")) == NULL) {
1470 printf("faimtest: getfile_send fopen failed for %s. damn.\n", path);
1471 return 0;
1472 }
1473
1474 if (aim_getfile_send(oftconn, file, fh) == -1) {
1475 printf("faimtest: getfile_send failed. damn.\n");
1476 } else {
1477 printf("faimtest: looks like getfile went clean\n");
1478 }
1479
1480 free(fh);
1481 return 1;
1482}
1483
1484int faimtest_getfile_complete(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1485{
1486 va_list ap;
1487 struct aim_conn_t *conn;
1488 struct aim_fileheader_t *fh;
1489
e7fb57f5 1490 va_start(ap, command);
871e2fd0 1491 conn = va_arg(ap, struct aim_conn_t *);
1492 fh = va_arg(ap, struct aim_fileheader_t *);
1493 va_end(ap);
1494
1495 printf("faimtest: completed file transfer for %s.\n", fh->name);
1496
1497 /* aim_conn_kill(sess, &conn); */ /* we'll let winaim close the conn */
1498 return 1;
1499}
1500
1501int faimtest_getfile_disconnect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1502{
1503 va_list ap;
1504 struct aim_conn_t *conn;
1505 char *sn;
1506
e7fb57f5 1507 va_start(ap, command);
871e2fd0 1508 conn = va_arg(ap, struct aim_conn_t *);
1509 sn = va_arg(ap, char *);
1510 va_end(ap);
1511
1512 aim_conn_kill(sess, &conn);
1513
1514 printf("faimtest: getfile: disconnected from %s\n", sn);
1515 return 1;
1516}
1517#endif
1518
1a8c261b 1519int faimtest_parse_ratechange(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1520{
1521 va_list ap;
1522 unsigned long newrate;
1523
1524 va_start(ap, command);
1525 newrate = va_arg(ap, unsigned long);
1526 va_end(ap);
1527
1528 printf("faimtest: ratechange: %lu\n", newrate);
1529
871e2fd0 1530 return 1;
78b3fb13 1531}
98c88242 1532
1533int faimtest_parse_evilnotify(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1534{
1535 va_list ap;
1536 char *sn;
1537
1538 va_start(ap, command);
1539 sn = va_arg(ap, char *);
1540 va_end(ap);
1541
1542 printf("faimtest: warning from: %s\n", sn);
1543
98c88242 1544 return 1;
78b3fb13 1545}
This page took 0.300692 seconds and 5 git commands to generate.