* purple - Jabber Protocol Plugin * Purple is the legal property of its developers, whose names are too numerous * to list here. Please refer to the COPYRIGHT file distributed with this * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA G_DEFINE_DYNAMIC_TYPE(JabberOOBXfer, jabber_oob_xfer, PURPLE_TYPE_XFER); static void jabber_oob_xfer_xfer_init(PurpleXfer *xfer) purple_xfer_start(xfer, -1, NULL, 0); static void jabber_oob_xfer_end(PurpleXfer *xfer) JabberOOBXfer *jox = JABBER_OOB_XFER(xfer); iq = jabber_iq_new(jox->js, JABBER_IQ_RESULT); purple_xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer)); jabber_iq_set_id(iq, jox->iq_id); jabber_oob_xfer_got(G_GNUC_UNUSED SoupSession *session, SoupMessage *msg, PurpleXfer *xfer = user_data; if (purple_xfer_is_cancelled(xfer)) jox = JABBER_OOB_XFER(xfer); if (!SOUP_STATUS_IS_SUCCESSFUL(msg->status_code) || purple_xfer_get_bytes_remaining(xfer) > 0) { purple_xfer_set_status(xfer, PURPLE_XFER_STATUS_CANCEL_REMOTE); purple_xfer_set_completed(xfer, TRUE); jabber_oob_xfer_got_content_length(SoupMessage *msg, gpointer user_data) PurpleXfer *xfer = user_data; total = soup_message_headers_get_content_length(msg->response_headers); purple_xfer_set_size(xfer, total); purple_xfer_update_progress(xfer); jabber_oob_xfer_writer(SoupMessage *msg, SoupBuffer *chunk, gpointer user_data) PurpleXfer *xfer = user_data; if (!purple_xfer_write_file(xfer, (const guchar *)chunk->data, JabberOOBXfer *jox = JABBER_OOB_XFER(xfer); soup_session_cancel_message(jox->js->http_conns, msg, static void jabber_oob_xfer_start(PurpleXfer *xfer) JabberOOBXfer *jox = JABBER_OOB_XFER(xfer); msg = soup_message_new("GET", jox->url); soup_message_add_header_handler( msg, "got-headers", "Content-Length", G_CALLBACK(jabber_oob_xfer_got_content_length), xfer); soup_message_body_set_accumulate(msg->response_body, FALSE); g_signal_connect(msg, "got-chunk", G_CALLBACK(jabber_oob_xfer_writer), soup_session_queue_message(jox->js->http_conns, msg, jabber_oob_xfer_got, static void jabber_oob_xfer_recv_error(PurpleXfer *xfer, const char *code) { JabberOOBXfer *jox = JABBER_OOB_XFER(xfer); iq = jabber_iq_new(jox->js, JABBER_IQ_ERROR); purple_xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer)); jabber_iq_set_id(iq, jox->iq_id); y = purple_xmlnode_new_child(iq->node, "error"); purple_xmlnode_set_attrib(y, "code", code); if(purple_strequal(code, "406")) { z = purple_xmlnode_new_child(y, "not-acceptable"); purple_xmlnode_set_attrib(y, "type", "modify"); purple_xmlnode_set_namespace(z, NS_XMPP_STANZAS); } else if(purple_strequal(code, "404")) { z = purple_xmlnode_new_child(y, "not-found"); purple_xmlnode_set_attrib(y, "type", "cancel"); purple_xmlnode_set_namespace(z, NS_XMPP_STANZAS); static void jabber_oob_xfer_recv_denied(PurpleXfer *xfer) { jabber_oob_xfer_recv_error(xfer, "406"); static void jabber_oob_xfer_recv_cancelled(PurpleXfer *xfer) { JabberOOBXfer *jox = JABBER_OOB_XFER(xfer); soup_session_cancel_message(jox->js->http_conns, jox->msg, jabber_oob_xfer_recv_error(xfer, "404"); void jabber_oob_parse(JabberStream *js, const char *from, JabberIqType type, const char *id, PurpleXmlNode *querynode) { const gchar *filename, *slash; if(type != JABBER_IQ_SET) if(!(urlnode = purple_xmlnode_get_child(querynode, "url"))) url = purple_xmlnode_get_data(urlnode); "account", purple_connection_get_account(js->gc), "type", PURPLE_XFER_TYPE_RECEIVE, jox->iq_id = g_strdup(id); slash = strrchr(url, '/'); purple_xfer_set_filename(PURPLE_XFER(jox), filename); js->oob_file_transfers = g_list_append(js->oob_file_transfers, jox); purple_xfer_request(PURPLE_XFER(jox)); jabber_oob_xfer_init(JabberOOBXfer *xfer) { jabber_oob_xfer_finalize(GObject *obj) { JabberOOBXfer *jox = JABBER_OOB_XFER(obj); jox->js->oob_file_transfers = g_list_remove(jox->js->oob_file_transfers, G_OBJECT_CLASS(jabber_oob_xfer_parent_class)->finalize(obj); jabber_oob_xfer_class_finalize(JabberOOBXferClass *klass) { jabber_oob_xfer_class_init(JabberOOBXferClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS(klass); PurpleXferClass *xfer_class = PURPLE_XFER_CLASS(klass); obj_class->finalize = jabber_oob_xfer_finalize; xfer_class->init = jabber_oob_xfer_xfer_init; xfer_class->end = jabber_oob_xfer_end; xfer_class->request_denied = jabber_oob_xfer_recv_denied; xfer_class->cancel_recv = jabber_oob_xfer_recv_cancelled; xfer_class->start = jabber_oob_xfer_start; jabber_oob_xfer_register(GTypeModule *module) { jabber_oob_xfer_register_type(module);