X-Git-Url: http://andersk.mit.edu/gitweb/libfaim.git/blobdiff_plain/b8d0da450de7ce933bd9cf9622baa650e469693d..7392c79fff9e408331844fcfb9dc6e6533ebe3e4:/aim_rxhandlers.c diff --git a/aim_rxhandlers.c b/aim_rxhandlers.c index 7b0a0f9..e030402 100644 --- a/aim_rxhandlers.c +++ b/aim_rxhandlers.c @@ -304,10 +304,26 @@ int aim_rxdispatch(struct aim_session_t *sess) return 0; } else { workingPtr = sess->queue_incoming; - for (i = 0; workingPtr != NULL; i++) { + for (i = 0; workingPtr != NULL; workingPtr = workingPtr->next, i++) { /* * XXX: This is still fairly ugly. */ + if (workingPtr->handled) + continue; + + /* + * This is a debugging/sanity check only and probably could/should be removed + * for stable code. + */ + if (((workingPtr->hdrtype == AIM_FRAMETYPE_OFT) && + (workingPtr->conn->type != AIM_CONN_TYPE_RENDEZVOUS)) || + ((workingPtr->hdrtype == AIM_FRAMETYPE_OSCAR) && + (workingPtr->conn->type == AIM_CONN_TYPE_RENDEZVOUS))) { + printf("faim: rxhandlers: incompatible frame type %d on connection type 0x%04x\n", workingPtr->hdrtype, workingPtr->conn->type); + workingPtr->handled = 1; + continue; + } + switch(workingPtr->conn->type) { case -1: /* @@ -326,7 +342,9 @@ int aim_rxdispatch(struct aim_session_t *sess) if (head == 0x00000001) { faimdprintf(1, "got connection ack on auth line\n"); workingPtr->handled = 1; - } else { + } else if (workingPtr->hdr.oscar.type == 0x0004) { + workingPtr->handled = aim_authparse(sess, workingPtr); + } else { u_short family,subtype; family = aimutil_get16(workingPtr->data); @@ -348,15 +366,17 @@ int aim_rxdispatch(struct aim_session_t *sess) #else /* XXX: this isnt foolproof */ case 0x0001: - if (subtype == 0x0003) - workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_GEN, AIM_CB_GEN_SERVERREADY, workingPtr); - else - workingPtr->handled = aim_authparse(sess, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_GEN, AIM_CB_GEN_SERVERREADY, workingPtr); break; case 0x0007: if (subtype == 0x0005) workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_ADM, AIM_CB_ADM_INFOCHANGE_REPLY, workingPtr); break; + case AIM_CB_FAM_SPECIAL: + if (subtype == AIM_CB_SPECIAL_DEBUGCONN_CONNECT) { + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, family, subtype, workingPtr); + break; + } /* others fall through */ default: /* Old login protocol */ /* any user callbacks will be called from here */ @@ -369,7 +389,12 @@ int aim_rxdispatch(struct aim_session_t *sess) case AIM_CONN_TYPE_BOS: { u_short family; u_short subtype; - + + if (workingPtr->hdr.oscar.type == 0x04) { + workingPtr->handled = aim_negchan_middle(sess, workingPtr); + break; + } + family = aimutil_get16(workingPtr->data); subtype = aimutil_get16(workingPtr->data+2); @@ -448,6 +473,9 @@ int aim_rxdispatch(struct aim_session_t *sess) case 0x0005: workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0004, 0x0005, workingPtr); break; + case 0x0006: + workingPtr->handled = aim_parse_outgoing_im_middle(sess, workingPtr); + break; case 0x0007: workingPtr->handled = aim_parse_incoming_im_middle(sess, workingPtr); break; @@ -486,6 +514,9 @@ int aim_rxdispatch(struct aim_session_t *sess) else workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_STS, AIM_CB_STS_DEFAULT, workingPtr); break; + case AIM_CB_FAM_SPECIAL: + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, family, subtype, workingPtr); + break; default: workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, workingPtr); break; @@ -524,7 +555,7 @@ int aim_rxdispatch(struct aim_session_t *sess) else if (subtype == 0x0007) workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0007, workingPtr); else - printf("Chat: unknown snac %04x/%04x\n", family, subtype); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, family, subtype, workingPtr); } else if (family == 0x000e) { if (subtype == 0x0002) workingPtr->handled = aim_chat_parse_infoupdate(sess, workingPtr); @@ -542,13 +573,28 @@ int aim_rxdispatch(struct aim_session_t *sess) } break; } + case AIM_CONN_TYPE_RENDEZVOUS: { + /* make sure that we only get OFT frames on these connections */ + if (workingPtr->hdrtype != AIM_FRAMETYPE_OFT) { + printf("faim: internal error: non-OFT frames on OFT connection\n"); + workingPtr->handled = 1; /* get rid of it */ + break; + } + + /* XXX: implement this */ + printf("faim: OFT frame!\n"); + + break; + } + case AIM_CONN_TYPE_RENDEZVOUS_OUT: { + /* not possible */ + break; + } default: - printf("\ninternal error: unknown connection type (very bad.) (type = %d, fd = %d, channel = %02x, commandlen = %02x)\n\n", workingPtr->conn->type, workingPtr->conn->fd, workingPtr->type, workingPtr->commandlen); + printf("\ninternal error: unknown connection type (very bad.) (type = %d, fd = %d, commandlen = %02x)\n\n", workingPtr->conn->type, workingPtr->conn->fd, workingPtr->commandlen); workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, workingPtr); break; } - /* move to next command */ - workingPtr = workingPtr->next; } } @@ -564,7 +610,7 @@ int aim_rxdispatch(struct aim_session_t *sess) } int aim_parsemotd_middle(struct aim_session_t *sess, - struct command_rx_struct *command, ...) + struct command_rx_struct *command, ...) { rxcallback_t userfunc = NULL; char *msg; @@ -671,17 +717,46 @@ int aim_parse_unknown(struct aim_session_t *sess, for (i = 0; i < command->commandlen; i++) { if ((i % 8) == 0) - printf("\n\t"); + faimdprintf(1, "\n\t"); - printf("0x%2x ", command->data[i]); + faimdprintf(1, "0x%2x ", command->data[i]); } - printf("\n\n"); + faimdprintf(1, "\n\n"); return 1; } +int aim_negchan_middle(struct aim_session_t *sess, + struct command_rx_struct *command) +{ + struct aim_tlvlist_t *tlvlist; + char *msg = NULL; + unsigned short code = 0; + struct aim_tlv_t *tmptlv; + rxcallback_t userfunc = NULL; + int ret = 1; + + tlvlist = aim_readtlvchain(command->data, command->commandlen); + + if ((tmptlv = aim_gettlv(tlvlist, 0x0009, 1))) + code = aimutil_get16(tmptlv->value); + + if ((tmptlv = aim_gettlv(tlvlist, 0x000b, 1))) + msg = aim_gettlv_str(tlvlist, 0x000b, 1); + + userfunc = aim_callhandler(command->conn, + AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR); + if (userfunc) + ret = userfunc(sess, command, code, msg); + + aim_freetlvchain(&tlvlist); + free(msg); + + return ret; +} + /* * aim_parse_generalerrs() *