int mwFileTransfer_send(struct mwFileTransfer *ft, struct mwOpaque *data) { struct mwChannel *chan; int ret; g_return_val_if_fail(ft != NULL, -1); g_return_val_if_fail(mwFileTransfer_isOpen(ft), -1); g_return_val_if_fail(ft->channel != NULL, -1); chan = ft->channel; g_return_val_if_fail(mwChannel_isOutgoing(chan), -1); if(data->len > ft->remaining) { /* @todo handle error */ return -1; } ret = mwChannel_send(chan, msg_TRANSFER, data); if(! ret) ft->remaining -= data->len; /* we're not done until we receive an ACK for the last piece of outgoing data */ return ret; }
void mwChannel_recvCreate(struct mwChannel *chan, struct mwMsgChannelCreate *msg) { struct mwSession *session; GList *list; struct mwService *srvc; g_return_if_fail(chan != NULL); g_return_if_fail(msg != NULL); g_return_if_fail(chan->id == msg->channel); session = chan->session; g_return_if_fail(session != NULL); if(mwChannel_isOutgoing(chan)) { g_warning("channel 0x%08x not an incoming channel", chan->id); mwChannel_destroy(chan, ERR_REQUEST_INVALID, NULL); return; } chan->offered_policy = msg->encrypt.mode; g_message("channel offered with encrypt policy 0x%04x", chan->policy); for(list = msg->encrypt.items; list; list = list->next) { struct mwEncryptItem *ei = list->data; struct mwCipher *cipher; struct mwCipherInstance *ci; g_message("channel offered cipher id 0x%04x", ei->id); cipher = mwSession_getCipher(session, ei->id); if(! cipher) { g_message("no such cipher found in session"); continue; } ci = mwCipher_newInstance(cipher, chan); mwCipherInstance_offered(ci, ei); mwChannel_addSupportedCipherInstance(chan, ci); } mwLoginInfo_clone(&chan->user, &msg->creator); chan->service = msg->service; chan->proto_type = msg->proto_type; chan->proto_ver = msg->proto_ver; srvc = mwSession_getService(session, msg->service); if(srvc) { mwService_recvCreate(srvc, chan, msg); } else { mwChannel_destroy(chan, ERR_SERVICE_NO_SUPPORT, NULL); } }
/* send a channel create message */ int mwChannel_create(struct mwChannel *chan) { struct mwMsgChannelCreate *msg; GList *list, *l; int ret; g_return_val_if_fail(chan != NULL, -1); g_return_val_if_fail(chan->state == mwChannel_INIT, -1); g_return_val_if_fail(mwChannel_isOutgoing(chan), -1); msg = (struct mwMsgChannelCreate *) mwMessage_new(mwMessage_CHANNEL_CREATE); msg->channel = chan->id; msg->target.user = g_strdup(chan->user.user_id); msg->target.community = g_strdup(chan->user.community); msg->service = chan->service; msg->proto_type = chan->proto_type; msg->proto_ver = chan->proto_ver; msg->options = chan->options; mwOpaque_clone(&msg->addtl, &chan->addtl_create); list = mwChannel_getSupportedCipherInstances(chan); if(list) { /* offer what we have */ for(l = list; l; l = l->next) { struct mwEncryptItem *ei = mwCipherInstance_offer(l->data); msg->encrypt.items = g_list_append(msg->encrypt.items, ei); } /* we're easy to get along with */ chan->offered_policy = mwEncrypt_WHATEVER; g_list_free(list); } else { /* we apparently don't support anything */ chan->offered_policy = mwEncrypt_NONE; } msg->encrypt.mode = chan->offered_policy; msg->encrypt.extra = chan->offered_policy; ret = mwSession_send(chan->session, MW_MESSAGE(msg)); mwMessage_free(MW_MESSAGE(msg)); state(chan, (ret)? mwChannel_ERROR: mwChannel_WAIT, ret); return ret; }