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