Standardize all protocol header guard macros.
[pidgin-git.git] / libpurple / protocols / jabber / oob.c
blobe90a90c4756b8e1112e532207e43565e4d76181e
1 /*
2 * purple - Jabber Protocol Plugin
4 * Purple is the legal property of its developers, whose names are too numerous
5 * to list here. Please refer to the COPYRIGHT file distributed with this
6 * source distribution.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
23 #include "internal.h"
24 #include "debug.h"
25 #include "xfer.h"
26 #include "http.h"
27 #include "util.h"
29 #include "jabber.h"
30 #include "iq.h"
31 #include "oob.h"
33 struct _JabberOOBXfer {
34 JabberStream *js;
35 gchar *iq_id;
36 gchar *url;
37 PurpleHttpConnection *hc;
40 G_DEFINE_DYNAMIC_TYPE(JabberOOBXfer, jabber_oob_xfer, PURPLE_TYPE_XFER);
42 static void jabber_oob_xfer_xfer_init(PurpleXfer *xfer)
44 purple_xfer_start(xfer, -1, NULL, 0);
47 static void jabber_oob_xfer_end(PurpleXfer *xfer)
49 JabberOOBXfer *jox = JABBER_OOB_XFER(xfer);
50 JabberIq *iq;
52 iq = jabber_iq_new(jox->js, JABBER_IQ_RESULT);
53 purple_xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer));
54 jabber_iq_set_id(iq, jox->iq_id);
56 jabber_iq_send(iq);
59 static void
60 jabber_oob_xfer_got(PurpleHttpConnection *hc, PurpleHttpResponse *response,
61 gpointer _xfer)
63 PurpleXfer *xfer = _xfer;
64 JabberOOBXfer *jox;
66 if (purple_xfer_is_cancelled(xfer))
67 return;
69 jox = JABBER_OOB_XFER(xfer);
70 jox->hc = NULL;
72 if (!purple_http_response_is_successful(response) ||
73 purple_xfer_get_bytes_remaining(xfer) > 0)
75 purple_xfer_set_status(xfer, PURPLE_XFER_STATUS_CANCEL_REMOTE);
76 purple_xfer_end(xfer);
77 } else {
78 purple_xfer_set_completed(xfer, TRUE);
79 purple_xfer_end(xfer);
83 static void
84 jabber_oob_xfer_progress_watcher(PurpleHttpConnection *hc,
85 gboolean reading_state, int processed, int total, gpointer _xfer)
87 PurpleXfer *xfer = _xfer;
89 if (!reading_state)
90 return;
92 purple_xfer_set_size(xfer, total);
93 purple_xfer_update_progress(xfer);
96 static gboolean
97 jabber_oob_xfer_writer(PurpleHttpConnection *http_conn,
98 PurpleHttpResponse *response, const gchar *buffer, size_t offset,
99 size_t length, gpointer _xfer)
101 PurpleXfer *xfer = _xfer;
103 return purple_xfer_write_file(xfer, (const guchar*)buffer, length);
106 static void jabber_oob_xfer_start(PurpleXfer *xfer)
108 PurpleHttpRequest *req;
109 JabberOOBXfer *jox = JABBER_OOB_XFER(xfer);
111 req = purple_http_request_new(jox->url);
112 purple_http_request_set_timeout(req, -1);
113 purple_http_request_set_max_len(req, -1);
114 purple_http_request_set_response_writer(req, jabber_oob_xfer_writer,
115 xfer);
116 jox->hc = purple_http_request(jox->js->gc, req, jabber_oob_xfer_got,
117 xfer);
119 purple_http_conn_set_progress_watcher(jox->hc,
120 jabber_oob_xfer_progress_watcher, xfer, -1);
123 static void jabber_oob_xfer_recv_error(PurpleXfer *xfer, const char *code) {
124 JabberOOBXfer *jox = JABBER_OOB_XFER(xfer);
125 JabberIq *iq;
126 PurpleXmlNode *y, *z;
128 iq = jabber_iq_new(jox->js, JABBER_IQ_ERROR);
129 purple_xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer));
130 jabber_iq_set_id(iq, jox->iq_id);
131 y = purple_xmlnode_new_child(iq->node, "error");
132 purple_xmlnode_set_attrib(y, "code", code);
133 if(purple_strequal(code, "406")) {
134 z = purple_xmlnode_new_child(y, "not-acceptable");
135 purple_xmlnode_set_attrib(y, "type", "modify");
136 purple_xmlnode_set_namespace(z, NS_XMPP_STANZAS);
137 } else if(purple_strequal(code, "404")) {
138 z = purple_xmlnode_new_child(y, "not-found");
139 purple_xmlnode_set_attrib(y, "type", "cancel");
140 purple_xmlnode_set_namespace(z, NS_XMPP_STANZAS);
142 jabber_iq_send(iq);
145 static void jabber_oob_xfer_recv_denied(PurpleXfer *xfer) {
146 jabber_oob_xfer_recv_error(xfer, "406");
149 static void jabber_oob_xfer_recv_cancelled(PurpleXfer *xfer) {
150 JabberOOBXfer *jox = JABBER_OOB_XFER(xfer);
152 purple_http_conn_cancel(jox->hc);
153 jabber_oob_xfer_recv_error(xfer, "404");
156 void jabber_oob_parse(JabberStream *js, const char *from, JabberIqType type,
157 const char *id, PurpleXmlNode *querynode) {
158 JabberOOBXfer *jox;
159 const gchar *filename, *slash;
160 gchar *url;
161 PurpleXmlNode *urlnode;
163 if(type != JABBER_IQ_SET)
164 return;
166 if(!from)
167 return;
169 if(!(urlnode = purple_xmlnode_get_child(querynode, "url")))
170 return;
172 url = purple_xmlnode_get_data(urlnode);
173 if (!url)
174 return;
176 jox = g_object_new(
177 JABBER_TYPE_OOB_XFER,
178 "account", purple_connection_get_account(js->gc),
179 "type", PURPLE_XFER_TYPE_RECEIVE,
180 "remote-user", from,
181 NULL
184 jox->iq_id = g_strdup(id);
185 jox->js = js;
186 jox->url = url;
188 slash = strrchr(url, '/');
189 if (slash == NULL) {
190 filename = url;
191 } else {
192 filename = slash + 1;
195 purple_xfer_set_filename(PURPLE_XFER(jox), filename);
197 js->oob_file_transfers = g_list_append(js->oob_file_transfers, jox);
199 purple_xfer_request(PURPLE_XFER(jox));
202 static void
203 jabber_oob_xfer_init(JabberOOBXfer *xfer) {
207 static void
208 jabber_oob_xfer_finalize(GObject *obj) {
209 JabberOOBXfer *jox = JABBER_OOB_XFER(obj);
211 jox->js->oob_file_transfers = g_list_remove(jox->js->oob_file_transfers,
212 jox);
214 g_free(jox->iq_id);
215 g_free(jox->url);
217 G_OBJECT_CLASS(jabber_oob_xfer_parent_class)->finalize(obj);
220 static void
221 jabber_oob_xfer_class_finalize(JabberOOBXferClass *klass) {
225 static void
226 jabber_oob_xfer_class_init(JabberOOBXferClass *klass) {
227 GObjectClass *obj_class = G_OBJECT_CLASS(klass);
228 PurpleXferClass *xfer_class = PURPLE_XFER_CLASS(klass);
230 obj_class->finalize = jabber_oob_xfer_finalize;
232 xfer_class->init = jabber_oob_xfer_xfer_init;
233 xfer_class->end = jabber_oob_xfer_end;
234 xfer_class->request_denied = jabber_oob_xfer_recv_denied;
235 xfer_class->cancel_recv = jabber_oob_xfer_recv_cancelled;
236 xfer_class->start = jabber_oob_xfer_start;
239 void
240 jabber_oob_xfer_register(GTypeModule *module) {
241 jabber_oob_xfer_register_type(module);