int mwFileTransfer_accept(struct mwFileTransfer *ft) { struct mwServiceFileTransfer *srvc; struct mwFileTransferHandler *handler; int ret; g_return_val_if_fail(ft != NULL, -1); g_return_val_if_fail(ft->channel != NULL, -1); g_return_val_if_fail(mwFileTransfer_isPending(ft), -1); g_return_val_if_fail(mwChannel_isIncoming(ft->channel), -1); g_return_val_if_fail(mwChannel_isState(ft->channel, mwChannel_WAIT), -1); g_return_val_if_fail(ft->service != NULL, -1); srvc = ft->service; g_return_val_if_fail(srvc->handler != NULL, -1); handler = srvc->handler; ret = mwChannel_accept(ft->channel); if(ret) { mwFileTransfer_close(ft, ERR_FAILURE); } else { ft_state(ft, mwFileTransfer_OPEN); if(handler->ft_opened) handler->ft_opened(ft); } return ret; }
void mwChannel_recvAccept(struct mwChannel *chan, struct mwMsgChannelAccept *msg) { struct mwService *srvc; g_return_if_fail(chan != NULL); g_return_if_fail(msg != NULL); g_return_if_fail(chan->id == msg->head.channel); if(mwChannel_isIncoming(chan)) { g_warning("channel 0x%08x not an outgoing channel", chan->id); mwChannel_destroy(chan, ERR_REQUEST_INVALID, NULL); return; } if(chan->state != mwChannel_WAIT) { g_warning("channel 0x%08x state not WAIT: %s", chan->id, state_str(chan->state)); mwChannel_destroy(chan, ERR_REQUEST_INVALID, NULL); return; } mwLoginInfo_clone(&chan->user, &msg->acceptor); srvc = mwSession_getService(chan->session, chan->service); if(! srvc) { g_warning("no service: 0x%08x", chan->service); mwChannel_destroy(chan, ERR_SERVICE_NO_SUPPORT, NULL); return; } chan->policy = msg->encrypt.mode; g_message("channel accepted with encrypt policy 0x%04x", chan->policy); if(! msg->encrypt.mode || ! msg->encrypt.item) { /* no mode or no item means no encryption */ mwChannel_selectCipherInstance(chan, NULL); } else { guint16 cid = msg->encrypt.item->id; struct mwCipherInstance *ci = get_supported(chan, cid); if(! ci) { g_warning("not an offered cipher: 0x%04x", cid); mwChannel_destroy(chan, ERR_REQUEST_INVALID, NULL); return; } mwCipherInstance_accepted(ci, msg->encrypt.item); mwChannel_selectCipherInstance(chan, ci); } /* mark it as open for the service */ state(chan, mwChannel_OPEN, 0); /* let the service know */ mwService_recvAccept(srvc, chan, msg); /* flush it if the service didn't just immediately close it */ if(mwChannel_isState(chan, mwChannel_OPEN)) { channel_open(chan); } }