]> andersk Git - libfaim.git/blame_incremental - utils/faimtest/faimtest.c
- Wed Dec 13 00:38:56 UTC 2000
[libfaim.git] / utils / faimtest / faimtest.c
... / ...
CommitLineData
1/*
2 * -----------------------------------------------------------
3 * ProtoFAIM: v1.xx.xxplxx
4 * -----------------------------------------------------------
5 *
6 * This is ProtoFAIM v1.xx.xxplxx!!! Its nearly completely
7 * different than that ugly thing called v0. This app is
8 * compatible with the latest version of the libfaim library.
9 * Work is continuing.
10 *
11 * ProtoFAIM should only be used for two things...
12 * 1) Testing the libfaim backend.
13 * 2) For reference on the libfaim API when developing clients.
14 *
15 * Its very ugly. Probably always will be. Nothing is more
16 * ugly than the backend itself, however.
17 *
18 * -----------------------------------------------------------
19 *
20 * I'm releasing this code and all it's associated linkage
21 * under the GNU General Public License. For more information,
22 * please refer to http://www.fsf.org. For any questions,
23 * please contact me at the address below.
24 *
25 * Most everything:
26 * (c) 1998 Adam Fritzler, PST, 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
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 *, ...);
52int faimtest_parse_authresp(struct aim_session_t *, struct command_rx_struct *, ...);
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, ...);
60int faimtest_parse_msgack(struct aim_session_t *, struct command_rx_struct *command, ...);
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, ...);
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, ...);
68int faimtest_parse_connerr(struct aim_session_t *sess, struct command_rx_struct *command, ...);
69int faimtest_debugconn_connect(struct aim_session_t *sess, struct command_rx_struct *command, ...);
70
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, ...);
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
85int faimtest_parse_ratechange(struct aim_session_t *sess, struct command_rx_struct *command, ...);
86int faimtest_parse_evilnotify(struct aim_session_t *sess, struct command_rx_struct *command, ...);
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;
118
119static char *screenname,*password,*server=NULL;
120
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
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
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
190int main(void)
191{
192 struct aim_session_t aimsess;
193 struct aim_conn_t *authconn = NULL, *waitingconn = NULL;
194 int keepgoing = 1;
195 char *proxy, *proxyusername, *proxypass;
196
197 char *listingpath;
198
199 int selstat = 0;
200
201#ifdef FILESUPPORT
202 FILE *listingfile;
203#endif
204
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
212 server = getenv("AUTHSERVER");
213
214 proxy = getenv("SOCKSPROXY");
215 proxyusername = getenv("SOCKSNAME");
216 proxypass = getenv("SOCKSPASS");
217
218#ifdef FILESUPPORT
219 listingpath = getenv("LISTINGPATH");
220#endif
221
222#ifdef _WIN32
223 if (initwsa() != 0) {
224 printf("faimtest: could not initialize windows sockets\n");
225 return -1;
226 }
227#endif /* _WIN32 */
228
229 /* Pass zero as flags if you want blocking connects */
230 aim_session_init(&aimsess, AIM_SESS_FLAGS_NONBLOCKCONNECT);
231
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
251 if (proxy)
252 aim_setupproxy(&aimsess, proxy, proxyusername, proxypass);
253
254 authconn = aim_newconn(&aimsess, AIM_CONN_TYPE_AUTH, server?server:FAIM_LOGIN_SERVER);
255
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;
266 }
267
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);
270 aim_conn_addhandler(&aimsess, authconn, 0x0017, 0x0007, faimtest_parse_login, 0);
271 aim_conn_addhandler(&aimsess, authconn, 0x0017, 0x0003, faimtest_parse_authresp, 0);
272
273 aim_conn_addhandler(&aimsess, authconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_DEBUGCONN_CONNECT, faimtest_debugconn_connect, 0);
274
275 /* If the connection is in progress, this will just be queued */
276 aim_request_login(&aimsess, authconn, screenname);
277 printf("faimtest: login request sent\n");
278
279 while (keepgoing) {
280 waitingconn = aim_select(&aimsess, NULL, &selstat);
281
282 switch(selstat) {
283 case -1: /* error */
284 keepgoing = 0; /* fall through and hit the aim_logoff() */
285 break;
286
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 */
295 if (waitingconn->type == AIM_CONN_TYPE_RENDEZVOUS_OUT) {
296 if (aim_handlerendconnect(&aimsess, waitingconn) < 0) {
297 printf("connection error (rend out)\n");
298 }
299 } else {
300 if (aim_get_command(&aimsess, waitingconn) >= 0) {
301 aim_rxdispatch(&aimsess);
302 } else {
303 printf("connection error (type 0x%04x:0x%04x)\n", waitingconn->type, waitingconn->subtype);
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);
310 if (!aim_getconn_type(&aimsess, AIM_CONN_TYPE_BOS)) {
311 printf("major connection error\n");
312 keepgoing = 0;
313 }
314 }
315 }
316 break;
317
318 default:
319 break; /* invalid */
320 }
321 }
322
323 /* Close up */
324 printf("AIM just decided we didn't need to be here anymore, closing up...\n");
325
326 /* close up all connections, dead or no */
327 aim_logoff(&aimsess);
328
329 /* Get out */
330 exit(0);
331}
332
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 */
358 aim_bos_setgroupperm(sess, command->conn, AIM_FLAG_ALLUSERS);
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
372int faimtest_serverready(struct aim_session_t *sess, struct command_rx_struct *command, ...)
373{
374 switch (command->conn->type)
375 {
376 case AIM_CONN_TYPE_BOS:
377
378 aim_setversions(sess, command->conn);
379 aim_bos_reqrate(sess, command->conn); /* request rate info */
380
381 fprintf(stderr, "faimtest: done with BOS ServerReady\n");
382 break;
383
384 case AIM_CONN_TYPE_CHATNAV:
385 fprintf(stderr, "faimtest: chatnav: got server ready\n");
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);
401 break;
402
403 case AIM_CONN_TYPE_RENDEZVOUS: /* empty */
404 break;
405
406 default:
407 fprintf(stderr, "faimtest: unknown connection type on Server Ready\n");
408 }
409 return 1;
410}
411
412int faimtest_parse_buddyrights(struct aim_session_t *sess, struct command_rx_struct *command, ...)
413{
414 va_list ap;
415 unsigned short maxbuddies, maxwatchers;
416
417 va_start(ap, command);
418 maxbuddies = va_arg(ap, int);
419 maxwatchers = va_arg(ap, int);
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
427int faimtest_bosrights(struct aim_session_t *sess, struct command_rx_struct *command, ...)
428{
429 unsigned short maxpermits, maxdenies;
430 va_list ap;
431
432 va_start(ap, command);
433 maxpermits = va_arg(ap, int);
434 maxdenies = va_arg(ap, int);
435 va_end(ap);
436
437 printf("faimtest: BOS rights: Max permit = %d / Max deny = %d\n", maxpermits, maxdenies);
438
439 aim_bos_clientready(sess, command->conn);
440
441 printf("faimtest: officially connected to BOS.\n");
442
443 return 1;
444}
445
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 */
461int faimtest_handleredirect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
462{
463 va_list ap;
464 int serviceid;
465 char *ip;
466 unsigned char *cookie;
467
468 va_start(ap, command);
469 serviceid = va_arg(ap, int);
470 ip = va_arg(ap, char *);
471 cookie = va_arg(ap, unsigned char *);
472
473 switch(serviceid)
474 {
475 case 0x0007: /* Authorizer */
476 {
477 struct aim_conn_t *tstconn;
478 /* Open a connection to the Auth */
479 tstconn = aim_newconn(sess, AIM_CONN_TYPE_AUTH, ip);
480 if ( (tstconn==NULL) || (tstconn->status & AIM_CONN_STATUS_RESOLVERR) )
481 fprintf(stderr, "faimtest: unable to reconnect with authorizer\n");
482 else {
483 aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
484 /* Send the cookie to the Auth */
485 aim_auth_sendcookie(sess, tstconn, cookie);
486 }
487
488 }
489 break;
490 case 0x000d: /* ChatNav */
491 {
492 struct aim_conn_t *tstconn = NULL;
493 tstconn = aim_newconn(sess, AIM_CONN_TYPE_CHATNAV, ip);
494 if ( (tstconn==NULL) || (tstconn->status & AIM_CONN_STATUS_RESOLVERR)) {
495 fprintf(stderr, "faimtest: unable to connect to chatnav server\n");
496 if (tstconn) aim_conn_kill(sess, &tstconn);
497 return 1;
498 }
499#if 0
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);
502#endif
503 aim_conn_addhandler(sess, tstconn, 0x0001, 0x0003, faimtest_serverready, 0);
504 aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
505 aim_auth_sendcookie(sess, tstconn, cookie);
506 fprintf(stderr, "\achatnav: connected\n");
507 }
508 break;
509 case 0x000e: /* Chat */
510 {
511 char *roomname = NULL;
512 int exchange;
513 struct aim_conn_t *tstconn = NULL;
514
515 roomname = va_arg(ap, char *);
516 exchange = va_arg(ap, int);
517
518 tstconn = aim_newconn(sess, AIM_CONN_TYPE_CHAT, ip);
519 if ( (tstconn==NULL) || (tstconn->status & AIM_CONN_STATUS_RESOLVERR))
520 {
521 fprintf(stderr, "faimtest: unable to connect to chat server\n");
522 if (tstconn) aim_conn_kill(sess, &tstconn);
523 return 1;
524 }
525 printf("faimtest: chat: connected to %s on exchange %d\n", roomname, exchange);
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);
533 aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
534 aim_auth_sendcookie(sess, tstconn, cookie);
535 }
536 break;
537 default:
538 printf("uh oh... got redirect for unknown service 0x%04x!!\n", serviceid);
539 /* dunno */
540 }
541
542 va_end(ap);
543
544 return 1;
545}
546
547int faimtest_parse_authresp(struct aim_session_t *sess, struct command_rx_struct *command, ...)
548{
549 va_list ap;
550 struct aim_conn_t *bosconn = NULL;
551 char *sn = NULL, *bosip = NULL, *errurl = NULL, *email = NULL;
552 unsigned char *cookie = NULL;
553 int errorcode = 0, regstatus = 0;
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
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 *);
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
578 va_end(ap);
579
580 printf("Screen name: %s\n", sn);
581
582 /*
583 * Check for error.
584 */
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 }
591
592 printf("Reg status: %2d\n", regstatus);
593 printf("Email: %s\n", email);
594 printf("BOS IP: %s\n", bosip);
595
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
602 printf("Closing auth connection...\n");
603 aim_conn_kill(sess, &command->conn);
604 if (!(bosconn = aim_newconn(sess, AIM_CONN_TYPE_BOS, bosip))) {
605 fprintf(stderr, "faimtest: could not connect to BOS: internal error\n");
606 return 1;
607 } else if (bosconn->status & AIM_CONN_STATUS_CONNERR) {
608 fprintf(stderr, "faimtest: could not connect to BOS\n");
609 aim_conn_kill(sess, &bosconn);
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);
636
637 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, faimtest_parse_connerr, 0);
638
639 aim_auth_sendcookie(sess, bosconn, cookie);
640
641 return 1;
642}
643
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
665int faimtest_parse_userinfo(struct aim_session_t *sess, struct command_rx_struct *command, ...)
666{
667 struct aim_userinfo_s *userinfo;
668 char *prof_encoding = NULL;
669 char *prof = NULL;
670 unsigned short inforeq = 0;
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 *);
677 inforeq = va_arg(ap, int);
678 va_end(ap);
679
680 printf("faimtest: userinfo: sn: %s\n", userinfo->sn);
681 printf("faimtest: userinfo: warnlevel: 0x%04x\n", userinfo->warnlevel);
682 printf("faimtest: userinfo: flags: 0x%04x = ", userinfo->flags);
683 printuserflags(userinfo->flags);
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
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");
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
710 * int flags flags
711 * ulong membersince time_t of date of signup
712 * ulong onsince time_t of date of singon
713 * int idletime min (sec?) idle
714 * u_int icbmflags sets AIM_IMFLAGS_{AWAY,ACK}
715 *
716 */
717int faimtest_parse_incoming_im(struct aim_session_t *sess, struct command_rx_struct *command, ...)
718{
719 int channel;
720 va_list ap;
721
722 va_start(ap, command);
723 channel = va_arg(ap, int);
724
725 /*
726 * Channel 1: Standard Message
727 */
728 if (channel == 1) {
729 struct aim_userinfo_s *userinfo;
730 char *msg = NULL;
731 u_int icbmflags = 0;
732 char *tmpstr = NULL;
733 unsigned short flag1, flag2;
734
735 userinfo = va_arg(ap, struct aim_userinfo_s *);
736 msg = va_arg(ap, char *);
737 icbmflags = va_arg(ap, u_int);
738 flag1 = va_arg(ap, int);
739 flag2 = va_arg(ap, int);
740 va_end(ap);
741
742 printf("faimtest: icbm: sn = \"%s\"\n", userinfo->sn);
743 printf("faimtest: icbm: warnlevel = 0x%04x\n", userinfo->warnlevel);
744 printf("faimtest: icbm: flags = 0x%04x = ", userinfo->flags);
745 printuserflags(userinfo->flags);
746 printf("\n");
747
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);
751 printf("faimtest: icbm: capabilities = 0x%04x\n", userinfo->capabilities);
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) {
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);
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");
784 aim_send_im(sess, command->conn, userinfo->sn, AIM_IMFLAGS_ACK, "Good day to you too.");
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);
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);
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)) {
801 aim_chatnav_createroom(sess,aim_getconn_type(sess, AIM_CONN_TYPE_CHATNAV), (strlen(tmpstr) < 7)?"WorldDomination":tmpstr+7, 0x0004);
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);
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);
816 } else if (!strncmp(tmpstr, "reqsendmsg", 10)) {
817 aim_send_im(sess, command->conn, "vaxherder", 0, "sendmsg 7900");
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 }
833 } else {
834 printf("unknown command.\n");
835 aim_add_buddy(sess, command->conn, userinfo->sn);
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
847 reqclass = va_arg(ap, int);
848 switch (reqclass) {
849 case AIM_CAPS_VOICE: {
850 userinfo = va_arg(ap, struct aim_userinfo_s *);
851 va_end(ap);
852
853 printf("faimtest: voice invitation: source sn = %s\n", userinfo->sn);
854 printf("faimtest: voice invitation: \twarnlevel = 0x%04x\n", userinfo->warnlevel);
855 printf("faimtest: voice invitation: \tclass = 0x%04x = ", userinfo->flags);
856 printuserflags(userinfo->flags);
857 printf("\n");
858
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);
862
863 break;
864 }
865 case AIM_CAPS_GETFILE: {
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
891 break;
892#endif
893 }
894 case AIM_CAPS_SENDFILE: {
895 printf("faimtest: send file!\n");
896 break;
897 }
898 case AIM_CAPS_CHAT: {
899 char *msg,*encoding,*lang;
900 struct aim_chat_roominfo *roominfo;
901
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);
908
909 printf("faimtest: chat invitation: source sn = %s\n", userinfo->sn);
910 printf("faimtest: chat invitation: \twarnlevel = 0x%04x\n", userinfo->warnlevel);
911 printf("faimtest: chat invitation: \tclass = 0x%04x = ", userinfo->flags);
912 printuserflags(userinfo->flags);
913 printf("\n");
914
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);
918
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 }
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
952 printf("faimtest: OFT: DirectIM: connected to %s\n", userinfo->sn);
953
954 aim_send_im_direct(sess, newconn, "goodday");
955
956 break;
957 }
958 default:
959 printf("faimtest: icbm: unknown reqclass (%d)\n", reqclass);
960 } /* switch */
961 } else
962 printf("faimtest does not support channels > 2 (chan = %02x)\n", channel);
963 printf("faimtest: icbm: done with ICBM handling\n");
964
965 return 1;
966}
967
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
974 va_start(ap, command);
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}
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
998 va_start(ap, command);
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
1014 va_start(ap, command);
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{
1048 va_list ap;
1049 struct aim_conn_t *conn;
1050 char *sn;
1051
1052 va_start(ap, command);
1053 conn = va_arg(ap, struct aim_conn_t *);
1054 sn = va_arg(ap, char *);
1055 va_end(ap);
1056
1057 printf("faimtest: directim: disconnected from %s\n", sn);
1058
1059 aim_conn_kill(sess, &conn);
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
1068 va_start(ap, command);
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
1076int faimtest_authsvrready(struct aim_session_t *sess, struct command_rx_struct *command, ...)
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... */
1081 aim_auth_clientready(sess, command->conn);
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 */
1090 aim_auth_changepasswd(sess, command->conn, "PWD1", "PWD2");
1091#endif
1092
1093 return 1;
1094}
1095
1096int faimtest_pwdchngdone(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1097{
1098 printf("PASSWORD CHANGE SUCCESSFUL!!!\n");
1099 return 1;
1100}
1101
1102int faimtest_parse_oncoming(struct aim_session_t *sess, struct command_rx_struct *command, ...)
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
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":"",
1121 userinfo->capabilities);
1122 return 1;
1123}
1124
1125int faimtest_parse_offgoing(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1126{
1127 char *sn;
1128 va_list ap;
1129
1130 va_start(ap, command);
1131 sn = va_arg(ap, char *);
1132 va_end(ap);
1133
1134 printf("\n%s has left\n", sn);
1135
1136 return 1;
1137}
1138
1139int faimtest_parse_motd(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1140{
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
1149 char *msg;
1150 unsigned short id;
1151 va_list ap;
1152
1153 va_start(ap, command);
1154 id = va_arg(ap, int);
1155 msg = va_arg(ap, char *);
1156 va_end(ap);
1157
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 *);
1172 reason = va_arg(ap, int);
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 *);
1188 reason = va_arg(ap, int);
1189 va_end(ap);
1190
1191 printf("faimtest: user information for %s unavailable (reason 0x%04x: %s)\n", destsn, reason, (reason<msgerrreasonslen)?msgerrreasons[reason]:"unknown");
1192
1193 return 1;
1194}
1195
1196/*
1197 * Handles callbacks for AIM_CB_MISSED_CALL.
1198 */
1199int faimtest_parse_misses(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1200{
1201 static char *missedreasons[] = {
1202 "Unknown",
1203 "Message too large"};
1204 static int missedreasonslen = 2;
1205
1206 va_list ap;
1207 unsigned short chan, nummissed, reason;
1208 struct aim_userinfo_s *userinfo;
1209
1210 va_start(ap, command);
1211 chan = va_arg(ap, int);
1212 userinfo = va_arg(ap, struct aim_userinfo_s *);
1213 nummissed = va_arg(ap, int);
1214 reason = va_arg(ap, int);
1215 va_end(ap);
1216
1217 printf("faimtest: missed %d messages from %s (reason %d: %s)\n", nummissed, userinfo->sn, reason, (reason<missedreasonslen)?missedreasons[reason]:"unknown");
1218
1219 return 1;
1220}
1221
1222int faimtest_parse_login(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1223{
1224 struct client_info_s info = {"faimtest (with SNAC login)", 4, 1, 2010, "us", "en", 0x0004, 0x0000, 0x0000004b}; /* 4.1.2010 */
1225 char *key;
1226 va_list ap;
1227
1228 va_start(ap, command);
1229 key = va_arg(ap, char *);
1230 va_end(ap);
1231
1232 aim_send_login(sess, command->conn, screenname, password, &info, key);
1233
1234 return 1;
1235}
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;
1281 unsigned short unknown_c9, unknown_d2, unknown_d5, maxmsglen;
1282 unsigned long creationtime;
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 *);
1290 unknown_c9 = va_arg(ap, int);
1291 creationtime = va_arg(ap, unsigned long);
1292 maxmsglen = va_arg(ap, int);
1293 unknown_d2 = va_arg(ap, int);
1294 unknown_d5 = va_arg(ap, int);
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
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
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 */
1337 if (strcmp(userinfo->sn, sess->sn) != 0)
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{
1348 unsigned short type;
1349 va_list ap;
1350
1351 va_start(ap, command);
1352 type = va_arg(ap, int);
1353
1354 switch(type) {
1355 case 0x0002: {
1356 int maxrooms;
1357 struct aim_chat_exchangeinfo *exchanges;
1358 int exchangecount,i = 0;
1359
1360 maxrooms = va_arg(ap, int);
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++;
1376 }
1377
1378 }
1379 break;
1380 case 0x0008: {
1381 char *fqcn, *name, *ck;
1382 unsigned short instance, flags, maxmsglen, maxoccupancy, unknown, exchange;
1383 unsigned char createperms;
1384 unsigned long createtime;
1385
1386 fqcn = va_arg(ap, char *);
1387 instance = va_arg(ap, int);
1388 exchange = va_arg(ap, int);
1389 flags = va_arg(ap, int);
1390 createtime = va_arg(ap, unsigned long);
1391 maxmsglen = va_arg(ap, int);
1392 maxoccupancy = va_arg(ap, int);
1393 createperms = va_arg(ap, int);
1394 unknown = va_arg(ap, int);
1395 name = va_arg(ap, char *);
1396 ck = va_arg(ap, char *);
1397 va_end(ap);
1398
1399 printf("faimtest: recieved room create reply for %s/0x%04x\n", fqcn, exchange);
1400 }
1401 break;
1402 default:
1403 va_end(ap);
1404 printf("faimtest: chatnav info: unknown type (%04x)\n", type);
1405 }
1406 return 1;
1407}
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
1415 va_start(ap, command);
1416 code = va_arg(ap, int);
1417 msg = va_arg(ap, char *);
1418 va_end(ap);
1419
1420 printf("faimtest: connerr: Code 0x%04x: %s\n", code, msg);
1421 aim_conn_kill(sess, &command->conn); /* this will break the main loop */
1422
1423 return 1;
1424}
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}
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
1451 va_start(ap, command);
1452 type = va_arg(ap, int);
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
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
1469 va_start(ap, command);
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
1490 va_start(ap, command);
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
1528 va_start(ap, command);
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
1545 va_start(ap, command);
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
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
1568 return 1;
1569}
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
1582 return 1;
1583}
This page took 0.363473 seconds and 5 git commands to generate.