# HG changeset patch # User Nathan Walp # Date 1065405895 0 # Node ID 1cf80749f2f082c70225274ed37e387028fe15c6 # Parent 85181c25cae3a5e0f7c25a3ee9ffafdecfe967d3 [gaim-migrate @ 7737] jabber gets file receive support again. jabber should now be able to do everything the old plugin did, and more. committer: Tailor Script diff -r 85181c25cae3 -r 1cf80749f2f0 src/protocols/jabber/Makefile.am --- a/src/protocols/jabber/Makefile.am Mon Oct 06 01:46:31 2003 +0000 +++ b/src/protocols/jabber/Makefile.am Mon Oct 06 02:04:55 2003 +0000 @@ -17,6 +17,8 @@ jutil.h \ message.c \ message.h \ + oob.c \ + oob.h \ parser.c \ parser.h \ presence.c \ diff -r 85181c25cae3 -r 1cf80749f2f0 src/protocols/jabber/Makefile.mingw --- a/src/protocols/jabber/Makefile.mingw Mon Oct 06 01:46:31 2003 +0000 +++ b/src/protocols/jabber/Makefile.mingw Mon Oct 06 02:04:55 2003 +0000 @@ -76,6 +76,7 @@ jabber.c \ jutil.c \ message.c \ + oob.c \ parser.c \ presence.c \ roster.c \ diff -r 85181c25cae3 -r 1cf80749f2f0 src/protocols/jabber/iq.c --- a/src/protocols/jabber/iq.c Mon Oct 06 01:46:31 2003 +0000 +++ b/src/protocols/jabber/iq.c Mon Oct 06 02:04:55 2003 +0000 @@ -23,6 +23,7 @@ #include "prefs.h" #include "iq.h" +#include "oob.h" #include "roster.h" #ifdef _WIN32 @@ -230,7 +231,7 @@ } else if(!strcmp(xmlns, "jabber:iq:register")) { jabber_register_parse(js, packet); } else if(!strcmp(xmlns, "jabber:iq:oob")) { - /* XXX: need to re-implement file receive for the old-skool way */ + jabber_oob_parse(js, packet); } else { gaim_debug(GAIM_DEBUG_WARNING, "jabber", "Unknown query: %s\n", xmlns); } diff -r 85181c25cae3 -r 1cf80749f2f0 src/protocols/jabber/iq.h --- a/src/protocols/jabber/iq.h Mon Oct 06 01:46:31 2003 +0000 +++ b/src/protocols/jabber/iq.h Mon Oct 06 02:04:55 2003 +0000 @@ -51,6 +51,7 @@ void jabber_iq_parse(JabberStream *js, xmlnode *packet); void jabber_iq_set_callback(JabberIq *iq, JabberCallback *cb); +void jabber_iq_set_id(JabberIq *iq, const char *id); void jabber_iq_send(JabberIq *iq); void jabber_iq_free(JabberIq *iq); diff -r 85181c25cae3 -r 1cf80749f2f0 src/protocols/jabber/jabber.h --- a/src/protocols/jabber/jabber.h Mon Oct 06 01:46:31 2003 +0000 +++ b/src/protocols/jabber/jabber.h Mon Oct 06 02:04:55 2003 +0000 @@ -63,6 +63,8 @@ GHashTable *callbacks; int next_id; + GList *file_transfers; + time_t idle; JabberID *user; diff -r 85181c25cae3 -r 1cf80749f2f0 src/protocols/jabber/oob.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/jabber/oob.c Mon Oct 06 02:04:55 2003 +0000 @@ -0,0 +1,180 @@ +/* + * gaim - Jabber Protocol Plugin + * + * Copyright (C) 2003, Nathan Walp + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include "internal.h" +#include "ft.h" +#include "util.h" + +#include "jabber.h" +#include "iq.h" + +typedef struct _JabberOOBXfer { + char *address; + int port; + char *page; + + GString *headers; + gboolean newline; + + char *iq_id; + + JabberStream *js; + +} JabberOOBXfer; + +static void jabber_oob_xfer_init(GaimXfer *xfer) +{ + JabberOOBXfer *jox = xfer->data; + gaim_xfer_start(xfer, -1, jox->address, jox->port); +} + +static void jabber_oob_xfer_free(GaimXfer *xfer) +{ + JabberOOBXfer *jox = xfer->data; + jox->js->file_transfers = g_list_remove(jox->js->file_transfers, xfer); + + g_string_free(jox->headers, TRUE); + g_free(jox->address); + g_free(jox->page); + g_free(jox->iq_id); + g_free(jox); + + xfer->data = NULL; +} + +static void jabber_oob_xfer_end(GaimXfer *xfer) +{ + JabberOOBXfer *jox = xfer->data; + JabberIq *iq; + + iq = jabber_iq_new(jox->js, JABBER_IQ_RESULT); + xmlnode_set_attrib(iq->node, "to", xfer->who); + jabber_iq_set_id(iq, jox->iq_id); + + jabber_iq_send(iq); + + jabber_oob_xfer_free(xfer); +} + +static void jabber_oob_xfer_start(GaimXfer *xfer) +{ + JabberOOBXfer *jox = xfer->data; + + char *buf = g_strdup_printf("GET /%s HTTP/1.1\r\nHost: %s\r\n\r\n", + jox->page, jox->address); + write(xfer->fd, buf, strlen(buf)); + g_free(buf); +} + +static size_t jabber_oob_xfer_read(char **buffer, GaimXfer *xfer) { + JabberOOBXfer *jox = xfer->data; + char test; + int size; + + if(read(xfer->fd, &test, sizeof(test)) > 0) { + jox->headers = g_string_append_c(jox->headers, test); + if(test == '\r') + return 0; + if(test == '\n') { + if(jox->newline) { + gchar *lenstr = strstr(jox->headers->str, "Content-Length: "); + if(lenstr) { + sscanf(lenstr, "Content-Length: %d", &size); + gaim_xfer_set_size(xfer, size); + } + gaim_xfer_set_read_fnc(xfer, NULL); + return 0; + } else + jox->newline = TRUE; + return 0; + } + jox->newline = FALSE; + return 0; + } + return 0; +} + +static void jabber_oob_xfer_cancel_send(GaimXfer *xfer) { +} + +static void jabber_oob_xfer_cancel_recv(GaimXfer *xfer) { + JabberOOBXfer *jox = xfer->data; + JabberIq *iq; + xmlnode *y; + + iq = jabber_iq_new(jox->js, JABBER_IQ_ERROR); + xmlnode_set_attrib(iq->node, "to", xfer->who); + jabber_iq_set_id(iq, jox->iq_id); + y = xmlnode_new_child(iq->node, "error"); + /* FIXME: need to handle other kinds of errors here */ + xmlnode_set_attrib(y, "code", "406"); + xmlnode_insert_data(y, "File Transfer Refused", -1); + + jabber_iq_send(iq); + + jabber_oob_xfer_free(xfer); +} + +void jabber_oob_parse(JabberStream *js, xmlnode *packet) { + JabberOOBXfer *jox; + GaimXfer *xfer; + char *filename; + char *url; + xmlnode *querynode, *urlnode; + + if(!(querynode = xmlnode_get_child(packet, "query"))) + return; + + if(!(urlnode = xmlnode_get_child(querynode, "url"))) + return; + + url = xmlnode_get_data(urlnode); + + jox = g_new0(JabberOOBXfer, 1); + gaim_url_parse(url, &jox->address, &jox->port, &jox->page); + g_free(url); + jox->js = js; + jox->headers = g_string_new(""); + jox->iq_id = g_strdup(xmlnode_get_attrib(packet, "id")); + + xfer = gaim_xfer_new(js->gc->account, GAIM_XFER_RECEIVE, + xmlnode_get_attrib(packet, "from")); + xfer->data = jox; + + if(!(filename = g_strdup(g_strrstr(jox->page, "/")))) + filename = g_strdup(jox->page); + + gaim_xfer_set_filename(xfer, filename); + + g_free(filename); + + gaim_xfer_set_init_fnc(xfer, jabber_oob_xfer_init); + gaim_xfer_set_end_fnc(xfer, jabber_oob_xfer_end); + gaim_xfer_set_cancel_send_fnc(xfer, jabber_oob_xfer_cancel_send); + gaim_xfer_set_cancel_recv_fnc(xfer, jabber_oob_xfer_cancel_recv); + gaim_xfer_set_read_fnc(xfer, jabber_oob_xfer_read); + gaim_xfer_set_start_fnc(xfer, jabber_oob_xfer_start); + + js->file_transfers = g_list_append(js->file_transfers, xfer); + + gaim_xfer_request(xfer); +} + + diff -r 85181c25cae3 -r 1cf80749f2f0 src/protocols/jabber/oob.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/jabber/oob.h Mon Oct 06 02:04:55 2003 +0000 @@ -0,0 +1,27 @@ +/** + * @file jutil.h utility functions + * + * gaim + * + * Copyright (C) 2003 Nathan Walp + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _GAIM_JABBER_OOB_H_ +#define _GAIM_JABBER_OOB_H_ + +void jabber_oob_parse(JabberStream *js, xmlnode *packet); + +#endif /* _GAIM_JABBER_JID_H_ */