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