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