+ return 1;
+}
+
+int faimtest_chatnav_info(struct aim_session_t *sess, struct command_rx_struct *command, ...)
+{
+ unsigned short type;
+ va_list ap;
+
+ va_start(ap, command);
+ type = va_arg(ap, int);
+
+ switch(type) {
+ case 0x0002: {
+ int maxrooms;
+ struct aim_chat_exchangeinfo *exchanges;
+ int exchangecount,i = 0;
+
+ maxrooms = va_arg(ap, int);
+ exchangecount = va_arg(ap, int);
+ exchanges = va_arg(ap, struct aim_chat_exchangeinfo *);
+ va_end(ap);
+
+ dprintf("faimtest: chat info: Chat Rights:\n");
+ dvprintf("faimtest: chat info: \tMax Concurrent Rooms: %d\n", maxrooms);
+
+ dvprintf("faimtest: chat info: \tExchange List: (%d total)\n", exchangecount);
+ for (i = 0; i < exchangecount; i++) {
+ dvprintf("faimtest: chat info: \t\t%x: %s (%s/%s)\n",
+ exchanges[i].number,
+ exchanges[i].name,
+ exchanges[i].charset1,
+ exchanges[i].lang1);
+ }
+
+ }
+ break;
+ case 0x0008: {
+ char *fqcn, *name, *ck;
+ unsigned short instance, flags, maxmsglen, maxoccupancy, unknown, exchange;
+ unsigned char createperms;
+ unsigned long createtime;
+
+ fqcn = va_arg(ap, char *);
+ instance = va_arg(ap, int);
+ exchange = va_arg(ap, int);
+ flags = va_arg(ap, int);
+ createtime = va_arg(ap, unsigned long);
+ maxmsglen = va_arg(ap, int);
+ maxoccupancy = va_arg(ap, int);
+ createperms = va_arg(ap, int);
+ unknown = va_arg(ap, int);
+ name = va_arg(ap, char *);
+ ck = va_arg(ap, char *);
+ va_end(ap);
+
+ dvprintf("faimtest: recieved room create reply for %s/0x%04x\n", fqcn, exchange);
+ }
+ break;
+ default:
+ va_end(ap);
+ dvprintf("faimtest: chatnav info: unknown type (%04x)\n", type);
+ }
+ return 1;
+}
+
+int faimtest_parse_connerr(struct aim_session_t *sess, struct command_rx_struct *command, ...)
+{
+ va_list ap;
+ unsigned short code;
+ char *msg = NULL;
+
+ va_start(ap, command);
+ code = va_arg(ap, int);
+ msg = va_arg(ap, char *);
+ va_end(ap);
+
+ dvprintf("faimtest: connerr: Code 0x%04x: %s\n", code, msg);
+ aim_conn_kill(sess, &command->conn); /* this will break the main loop */
+
+ return 1;
+}
+
+int faimtest_debugconn_connect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
+{
+ dprintf("faimtest: connecting to an aimdebugd!\n");
+
+ /* convert the authorizer connection to a BOS connection */
+ command->conn->type = AIM_CONN_TYPE_BOS;
+
+ aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_MSG, AIM_CB_MSG_INCOMING, faimtest_parse_incoming_im, 0);
+
+ /* tell the aimddebugd we're ready */
+ aim_debugconn_sendconnect(sess, command->conn);
+
+ /* go right into main loop (don't open a BOS connection, etc) */
+ return 1;
+}
+
+/*
+ * Recieved in response to an IM sent with the AIM_IMFLAGS_ACK option.
+ */
+int faimtest_parse_msgack(struct aim_session_t *sess, struct command_rx_struct *command, ...)
+{
+ va_list ap;
+ unsigned short type;
+ char *sn = NULL;
+
+ va_start(ap, command);
+ type = va_arg(ap, int);
+ sn = va_arg(ap, char *);
+ va_end(ap);
+
+ dvprintf("faimtest: msgack: 0x%04x / %s\n", type, sn);
+
+ return 1;
+}
+
+#ifdef FILESUPPORT
+int faimtest_getfile_filereq(struct aim_session_t *ses, struct command_rx_struct *command, ...)
+{
+ va_list ap;
+ struct aim_conn_t *oftconn;
+ struct aim_fileheader_t *fh;
+ char *cookie;
+
+ va_start(ap, command);
+ oftconn = va_arg(ap, struct aim_conn_t *);
+ fh = va_arg(ap, struct aim_fileheader_t *);
+ cookie = va_arg(ap, char *);
+ va_end(ap);
+
+ dvprintf("faimtest: request for file %s.\n", fh->name);
+
+ return 1;
+}
+
+
+int faimtest_getfile_filesend(struct aim_session_t *sess, struct command_rx_struct *command, ...)
+{
+ va_list ap;
+ struct aim_conn_t *oftconn;
+ struct aim_fileheader_t *fh;
+ char *path, *cookie;
+ int pos, bufpos, bufsize = 2048, i;
+ char buf[2048];
+
+ FILE *file;
+
+ va_start(ap, command);
+ oftconn = va_arg(ap, struct aim_conn_t *);
+ fh = va_arg(ap, struct aim_fileheader_t *);
+ cookie = va_arg(ap, char *);
+ va_end(ap);
+
+ dvprintf("faimtest: sending file %s(%ld).\n", fh->name, fh->size);
+
+ if( (path = (char *)calloc(1, strlen(listingpath) +strlen(fh->name)+2)) == NULL) {
+ dperror("calloc");
+ dprintf("faimtest: error in calloc of path\n");
+ return 0; /* XXX: no idea what winaim expects here =) */
+ }
+
+ snprintf(path, strlen(listingpath)+strlen(fh->name)+2, "%s/%s", listingpath, fh->name);
+
+
+ if( (file = fopen(path, "r")) == NULL) {
+ dvprintf("faimtest: getfile_send fopen failed for %s. damn.\n", path);
+ return 0;
+ }
+
+ for(pos = 0; pos < fh->size; pos++) {
+ bufpos = pos % bufsize;
+
+ if(bufpos == 0 && pos > 0) { /* filled our buffer. spit it across the wire */
+ if ( (i = send(oftconn->fd, buf, bufsize, 0)) != bufsize ) {
+ dperror("faim: getfile_send: write1");
+ dprintf("faim: getfile_send: whoopsy, didn't write it all...\n");
+ free(buf);
+ return -1;
+ }
+ }
+ if( (buf[bufpos] = fgetc(file)) == EOF) {
+ if(pos != fh->size) {
+ dvprintf("faim: getfile_send: hrm... apparent early EOF at pos 0x%x of 0x%lx\n", pos, fh->size);
+ free(buf);
+ return -1;
+ }
+ }
+ dvprintf("%c(0x%02x) ", buf[pos], buf[pos]);
+ }
+
+ if( (i = send(oftconn->fd, buf, bufpos+1, 0)) != (bufpos+1)) {
+ dperror("faim: getfile_send: write2");
+ dprintf("faim: getfile_send cleanup: whoopsy, didn't write it all...\n");
+ free(buf);
+ return -1;
+ }
+
+
+ free(fh);
+ return 1;
+}
+
+int faimtest_getfile_complete(struct aim_session_t *sess, struct command_rx_struct *command, ...)
+{
+ va_list ap;
+ struct aim_conn_t *conn;
+ struct aim_fileheader_t *fh;
+
+ va_start(ap, command);
+ conn = va_arg(ap, struct aim_conn_t *);
+ fh = va_arg(ap, struct aim_fileheader_t *);
+ va_end(ap);
+
+ dvprintf("faimtest: completed file transfer for %s.\n", fh->name);
+
+ aim_conn_close(conn);
+ aim_conn_kill(sess, &conn);
+ return 1;
+}
+
+int faimtest_getfile_disconnect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
+{
+ va_list ap;
+ struct aim_conn_t *conn;
+ char *sn;
+
+ va_start(ap, command);
+ conn = va_arg(ap, struct aim_conn_t *);
+ sn = va_arg(ap, char *);
+ va_end(ap);
+
+ aim_conn_kill(sess, &conn);
+
+ dvprintf("faimtest: getfile: disconnected from %s\n", sn);
+ return 1;
+}
+int faimtest_getfile_initiate(struct aim_session_t *sess, struct command_rx_struct *command, ...)
+{
+ va_list ap;
+ struct aim_conn_t *conn;
+ char *sn;
+ struct aim_filetransfer_priv *priv;
+
+ va_start(ap, command);
+ conn = va_arg(ap, struct aim_conn_t *);
+ sn = va_arg(ap, char *);
+ va_end(ap);
+
+ aim_conn_addhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEFILEREQ, faimtest_getfile_filereq, 0);
+ aim_conn_addhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEFILESEND, faimtest_getfile_filesend, 0);
+ aim_conn_addhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILECOMPLETE, faimtest_getfile_complete, 0);
+ aim_conn_addhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEDISCONNECT, faimtest_getfile_disconnect, 0);
+ aim_conn_addhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILELISTING, faimtest_getfile_listing, 0);
+ aim_conn_addhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILELISTINGREQ, faimtest_getfile_listingreq, 0);
+ aim_conn_addhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILERECIEVE, faimtest_getfile_recieve, 0);
+
+ priv = (struct aim_filetransfer_priv *)conn->priv;
+
+ dvprintf("faimtest: getfile: %s (%s) connected to us on %d\n", sn, priv->ip, conn->fd);
+ return 1;
+}
+
+int faimtest_getfile_listing(struct aim_session_t *sess, struct command_rx_struct *command, ...)
+{
+ va_list ap;
+ struct aim_conn_t *conn;
+ char *listing;
+ struct aim_filetransfer_priv *ft;
+ char *filename, *nameend, *sizec;
+ int filesize, namelen;
+
+ va_start(ap, command);
+ conn = va_arg(ap, struct aim_conn_t *);
+ ft = va_arg(ap, struct aim_filetransfer_priv *);
+ listing = va_arg(ap, char *);
+ va_end(ap);
+
+ dvprintf("listing on %d==================\n%s\n===========\n", conn->fd, listing);
+
+ nameend = strstr(listing+0x1a, "\r");
+
+ namelen = nameend - (listing + 0x1a);
+
+ filename = malloc(namelen + 1);
+ strncpy(filename, listing+0x1a, namelen);
+ filename[namelen] = 0x00;
+
+ sizec = malloc(8+1);
+ memcpy(sizec, listing + 0x11, 8);
+ sizec[8] = 0x00;
+
+ filesize = strtol(sizec, (char **)NULL, 10);
+
+ dvprintf("faimtest: requesting %d %s(%d long)\n", namelen, filename, filesize);
+
+ aim_oft_getfile_request(sess, conn, filename, filesize);
+
+ free(filename);
+ free(sizec);
+
+ return 0;
+}
+
+int faimtest_getfile_listingreq(struct aim_session_t *sess, struct command_rx_struct *command, ...)
+{
+ va_list ap;
+ struct aim_conn_t *oftconn;
+ struct aim_fileheader_t *fh;
+ int pos, bufpos, bufsize = 2048, i;
+ char buf[2048];
+
+
+ va_start(ap, command);
+ oftconn = va_arg(ap, struct aim_conn_t *);
+ fh = va_arg(ap, struct aim_fileheader_t *);
+ va_end(ap);
+
+ dvprintf("faimtest: sending listing of size %ld\n", fh->size);
+
+ for(pos = 0; pos < fh->size; pos++) {
+ bufpos = pos % bufsize;
+
+ if(bufpos == 0 && pos > 0) { /* filled our buffer. spit it across the wire */
+ if ( (i = send(oftconn->fd, buf, bufsize, 0)) != bufsize ) {
+ dperror("faim: getfile_send: write1");
+ dprintf("faim: getfile_send: whoopsy, didn't write it all...\n");
+ free(buf);
+ return -1;
+ }
+ }
+ if( (buf[bufpos] = fgetc(listingfile)) == EOF) {
+ if(pos != fh->size) {
+ dvprintf("faim: getfile_send: hrm... apparent early EOF at pos 0x%x of 0x%lx\n", pos, fh->size);
+ free(buf);
+ return -1;
+ }
+ }
+ }
+
+ if( (i = send(oftconn->fd, buf, bufpos+1, 0)) != (bufpos+1)) {
+ dperror("faim: getfile_send: write2");
+ dprintf("faim: getfile_send cleanup: whoopsy, didn't write it all...\n");
+ free(buf);
+ return -1;
+ }
+
+ dprintf("faimtest: sent listing\n");
+ return 0;
+}
+
+int faimtest_getfile_recieve(struct aim_session_t *sess, struct command_rx_struct *command, ...)
+{
+ va_list ap;
+ struct aim_conn_t *conn;
+ struct aim_filetransfer_priv *ft;
+ unsigned char data;
+ int pos;
+
+ va_start(ap, command);
+ conn = va_arg(ap, struct aim_conn_t *);
+ ft = va_arg(ap, struct aim_filetransfer_priv *);
+ va_end(ap);
+
+ dvprintf("faimtest: receiving %ld bytes of file data for %s:\n\t", ft->fh.size, ft->fh.name);
+
+ for(pos = 0; pos < ft->fh.size; pos++) {
+ read(conn->fd, &data, 1);
+ dvprintf("%c(%02x) ", data, data);
+ }
+
+ dprintf("\n");
+
+ aim_oft_getfile_ack(sess, conn);
+ aim_oft_getfile_end(sess, conn);
+