Mercurial > pidgin
annotate src/protocols/jabber/si.c @ 8262:b5dbd1839716
[gaim-migrate @ 8985]
this is jabber new-style file transfer receive support. this doesn't do much error checking or handling, but I managed to send pictures to myself from Exodus on my laptop in the living room, which would have taken twice as long were it not for VNC. i said i was going to bed 1, 2, and 3 hours ago. i should go to bed.
committer: Tailor Script <tailor@pidgin.im>
author | Nathan Walp <nwalp@pidgin.im> |
---|---|
date | Sun, 15 Feb 2004 10:11:38 +0000 |
parents | f50c059b6384 |
children | ba12d8b12ab0 |
rev | line source |
---|---|
7395 | 1 /* |
2 * gaim - Jabber Protocol Plugin | |
3 * | |
4 * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com> | |
5 * | |
6 * This program is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program; if not, write to the Free Software | |
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 * | |
20 */ | |
21 #include "internal.h" | |
22 #include "debug.h" | |
23 #include "ft.h" | |
8231
f50c059b6384
[gaim-migrate @ 8954]
Christian Hammond <chipx86@chipx86.com>
parents:
8135
diff
changeset
|
24 #include "network.h" |
7395 | 25 #include "notify.h" |
8262 | 26 #include "sha.h" |
7395 | 27 #include "util.h" |
28 | |
29 #include "buddy.h" | |
30 #include "jabber.h" | |
31 #include "iq.h" | |
32 #include "si.h" | |
33 | |
34 #include "si.h" | |
35 | |
8262 | 36 struct bytestreams_streamhost { |
37 char *jid; | |
38 char *host; | |
39 int port; | |
40 }; | |
41 | |
42 typedef struct _JabberSIXfer { | |
43 JabberStream *js; | |
44 | |
45 char *stream_id; | |
46 char *iq_id; | |
47 | |
48 enum { | |
49 STREAM_METHOD_UNKNOWN = 0, | |
50 STREAM_METHOD_BYTESTREAMS = 2 << 1, | |
51 STREAM_METHOD_IBB = 2 << 2, | |
52 STREAM_METHOD_UNSUPPORTED = 2 << 31 | |
53 } stream_method; | |
54 | |
55 GList *streamhosts; | |
56 GaimProxyInfo *gpi; | |
57 } JabberSIXfer; | |
58 | |
59 static GaimXfer* | |
60 jabber_si_xfer_find(JabberStream *js, const char *sid, const char *from) | |
7395 | 61 { |
62 GList *xfers; | |
63 | |
8262 | 64 if(!sid || !from) |
7395 | 65 return NULL; |
66 | |
67 for(xfers = js->file_transfers; xfers; xfers = xfers->next) { | |
68 GaimXfer *xfer = xfers->data; | |
69 JabberSIXfer *jsx = xfer->data; | |
8262 | 70 if(!strcmp(jsx->stream_id, sid) && !strcmp(xfer->who, from)) |
7395 | 71 return xfer; |
72 } | |
73 | |
74 return NULL; | |
75 } | |
76 | |
8262 | 77 |
78 static void jabber_si_bytestreams_attempt_connect(GaimXfer *xfer); | |
79 | |
80 static void jabber_si_bytestreams_connect_cb(gpointer data, gint source, GaimInputCondition cond) | |
81 { | |
7395 | 82 GaimXfer *xfer = data; |
83 JabberSIXfer *jsx = xfer->data; | |
8262 | 84 JabberIq *iq; |
85 xmlnode *query, *su; | |
86 struct bytestreams_streamhost *streamhost = jsx->streamhosts->data; | |
7395 | 87 |
8262 | 88 gaim_proxy_info_destroy(jsx->gpi); |
89 | |
90 if(source < 0) { | |
91 jsx->streamhosts = g_list_remove(jsx->streamhosts, streamhost); | |
92 g_free(streamhost->jid); | |
93 g_free(streamhost->host); | |
94 g_free(streamhost); | |
95 jabber_si_bytestreams_attempt_connect(xfer); | |
96 return; | |
97 } | |
98 | |
99 iq = jabber_iq_new_query(jsx->js, JABBER_IQ_RESULT, "http://jabber.org/protocol/bytestreams"); | |
100 xmlnode_set_attrib(iq->node, "to", xfer->who); | |
101 jabber_iq_set_id(iq, jsx->iq_id); | |
102 query = xmlnode_get_child(iq->node, "query"); | |
103 su = xmlnode_new_child(query, "streamhost-used"); | |
104 xmlnode_set_attrib(su, "jid", streamhost->jid); | |
105 | |
106 jabber_iq_send(iq); | |
107 | |
108 gaim_xfer_start(xfer, source, NULL, -1); | |
109 } | |
110 | |
111 static void jabber_si_bytestreams_attempt_connect(GaimXfer *xfer) | |
112 { | |
113 JabberSIXfer *jsx = xfer->data; | |
114 struct bytestreams_streamhost *streamhost; | |
115 char *dstaddr, *p; | |
116 int i; | |
117 unsigned char hashval[20]; | |
118 | |
119 if(!jsx->streamhosts) { | |
120 JabberIq *iq = jabber_iq_new(jsx->js, JABBER_IQ_ERROR); | |
121 xmlnode *error, *condition; | |
122 | |
123 if(jsx->iq_id) | |
124 jabber_iq_set_id(iq, jsx->iq_id); | |
125 | |
126 xmlnode_set_attrib(iq->node, "to", xfer->who); | |
127 error = xmlnode_new_child(iq->node, "error"); | |
128 xmlnode_set_attrib(error, "code", "404"); | |
129 xmlnode_set_attrib(error, "type", "cancel"); | |
130 condition = xmlnode_new_child(error, "condition"); | |
131 xmlnode_set_attrib(condition, "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas"); | |
132 xmlnode_new_child(condition, "item-not-found"); | |
133 | |
134 jabber_iq_send(iq); | |
135 | |
136 gaim_xfer_cancel_local(xfer); | |
137 | |
138 return; | |
139 } | |
140 | |
141 streamhost = jsx->streamhosts->data; | |
7395 | 142 |
8262 | 143 jsx->gpi = gaim_proxy_info_new(); |
144 gaim_proxy_info_set_type(jsx->gpi, GAIM_PROXY_SOCKS5); | |
145 gaim_proxy_info_set_host(jsx->gpi, streamhost->host); | |
146 gaim_proxy_info_set_port(jsx->gpi, streamhost->port); | |
147 | |
148 dstaddr = g_strdup_printf("%s%s%s@%s/%s", jsx->stream_id, xfer->who, jsx->js->user->node, | |
149 jsx->js->user->domain, jsx->js->user->resource); | |
150 shaBlock((unsigned char *)dstaddr, strlen(dstaddr), hashval); | |
151 g_free(dstaddr); | |
152 dstaddr = g_malloc(41); | |
153 p = dstaddr; | |
154 for(i=0; i<20; i++, p+=2) | |
155 snprintf(p, 3, "%02x", hashval[i]); | |
156 | |
157 gaim_proxy_connect_socks5(jsx->gpi, dstaddr, 0, jabber_si_bytestreams_connect_cb, xfer); | |
158 g_free(dstaddr); | |
159 } | |
160 | |
161 void jabber_bytestreams_parse(JabberStream *js, xmlnode *packet) | |
162 { | |
163 GaimXfer *xfer; | |
164 JabberSIXfer *jsx; | |
165 xmlnode *query, *streamhost; | |
166 const char *sid, *from; | |
167 | |
168 if(!(from = xmlnode_get_attrib(packet, "from"))) | |
169 return; | |
170 | |
171 if(!(query = xmlnode_get_child(packet, "query"))) | |
172 return; | |
173 | |
174 if(!(sid = xmlnode_get_attrib(query, "sid"))) | |
175 return; | |
176 | |
177 if(!(xfer = jabber_si_xfer_find(js, sid, from))) | |
178 return; | |
179 | |
180 jsx = xfer->data; | |
181 if(jsx->iq_id) | |
182 g_free(jsx->iq_id); | |
183 jsx->iq_id = g_strdup(xmlnode_get_attrib(packet, "id")); | |
184 | |
185 for(streamhost = xmlnode_get_child(query, "streamhost"); streamhost; | |
186 streamhost = xmlnode_get_next_twin(streamhost)) { | |
187 const char *jid, *host, *port; | |
188 int portnum; | |
189 | |
190 if((jid = xmlnode_get_attrib(streamhost, "jid")) && | |
191 (host = xmlnode_get_attrib(streamhost, "host")) && | |
192 (port = xmlnode_get_attrib(streamhost, "port")) && | |
193 (portnum = atoi(port))) { | |
194 struct bytestreams_streamhost *sh = g_new0(struct bytestreams_streamhost, 1); | |
195 sh->jid = g_strdup(jid); | |
196 sh->host = g_strdup(host); | |
197 sh->port = portnum; | |
198 jsx->streamhosts = g_list_append(jsx->streamhosts, sh); | |
199 } | |
200 } | |
201 | |
202 jabber_si_bytestreams_attempt_connect(xfer); | |
7395 | 203 } |
204 | |
8262 | 205 static void jabber_si_xfer_init(GaimXfer *xfer) |
206 { | |
207 JabberSIXfer *jsx = xfer->data; | |
208 JabberIq *iq; | |
209 xmlnode *si, *feature, *x, *field, *value; | |
210 | |
211 iq = jabber_iq_new(jsx->js, JABBER_IQ_RESULT); | |
212 xmlnode_set_attrib(iq->node, "to", xfer->who); | |
213 if(jsx->iq_id) | |
214 jabber_iq_set_id(iq, jsx->iq_id); | |
215 | |
216 si = xmlnode_new_child(iq->node, "si"); | |
217 xmlnode_set_attrib(si, "xmlns", "http://jabber.org/protocol/si"); | |
218 | |
219 feature = xmlnode_new_child(si, "feature"); | |
220 xmlnode_set_attrib(feature, "xmlns", "http://jabber.org/protocol/feature-neg"); | |
221 | |
222 x = xmlnode_new_child(feature, "x"); | |
223 xmlnode_set_attrib(x, "xmlns", "jabber:x:data"); | |
224 xmlnode_set_attrib(x, "type", "form"); | |
225 | |
226 field = xmlnode_new_child(x, "field"); | |
227 xmlnode_set_attrib(field, "var", "stream-method"); | |
228 | |
229 value = xmlnode_new_child(field, "value"); | |
230 if(jsx->stream_method & STREAM_METHOD_BYTESTREAMS) | |
231 xmlnode_insert_data(value, "http://jabber.org/protocol/bytestreams", -1); | |
232 /* | |
233 else if(jsx->stream_method & STREAM_METHOD_IBB) | |
234 xmlnode_insert_data(value, "http://jabber.org/protocol/ibb", -1); | |
235 */ | |
236 | |
237 jabber_iq_send(iq); | |
238 } | |
239 | |
240 static ssize_t jabber_si_xfer_read(char **buffer, GaimXfer *xfer) { | |
241 char buf; | |
242 | |
243 if(read(xfer->fd, &buf, 1) == 1) { | |
244 if(buf == 0x00) | |
245 gaim_xfer_set_read_fnc(xfer, NULL); | |
246 } else { | |
247 gaim_debug_error("jabber", "Read error on bytestream transfer!\n"); | |
248 gaim_xfer_cancel_local(xfer); | |
249 } | |
250 | |
251 return 0; | |
252 } | |
253 | |
254 | |
255 void jabber_si_parse(JabberStream *js, xmlnode *packet) | |
256 { | |
257 JabberSIXfer *jsx; | |
258 GaimXfer *xfer; | |
259 xmlnode *si, *file, *feature, *x, *field, *option, *value; | |
260 const char *stream_id, *filename, *filesize_c, *profile; | |
261 size_t filesize = 0; | |
262 | |
263 if(!(si = xmlnode_get_child(packet, "si"))) | |
264 return; | |
265 | |
266 if(!(profile = xmlnode_get_attrib(si, "profile")) || | |
267 strcmp(profile, "http://jabber.org/protocol/si/profile/file-transfer")) | |
268 return; | |
269 | |
270 if(!(stream_id = xmlnode_get_attrib(si, "id"))) | |
271 return; | |
272 | |
273 if(!(file = xmlnode_get_child(si, "file"))) | |
274 return; | |
275 | |
276 if(!(filename = xmlnode_get_attrib(file, "name"))) | |
277 return; | |
278 | |
279 if((filesize_c = xmlnode_get_attrib(file, "size"))) | |
280 filesize = atoi(filesize_c); | |
281 | |
282 if(!(feature = xmlnode_get_child(si, "feature"))) | |
283 return; | |
284 | |
285 if(!(x = xmlnode_get_child_with_namespace(feature, "x", "jabber:x:data"))) | |
286 return; | |
287 | |
288 jsx = g_new0(JabberSIXfer, 1); | |
289 | |
290 for(field = xmlnode_get_child(x, "field"); field; field = xmlnode_get_next_twin(field)) { | |
291 const char *var = xmlnode_get_attrib(field, "var"); | |
292 if(var && !strcmp(var, "stream-method")) { | |
293 for(option = xmlnode_get_child(field, "option"); option; | |
294 option = xmlnode_get_next_twin(option)) { | |
295 if((value = xmlnode_get_child(option, "value"))) { | |
296 char *val; | |
297 if((val = xmlnode_get_data(value))) { | |
298 if(!strcmp(val, "http://jabber.org/protocol/bytestreams")) { | |
299 jsx->stream_method |= STREAM_METHOD_BYTESTREAMS; | |
300 /* | |
301 } else if(!strcmp(val, "http://jabber.org/protocol/ibb")) { | |
302 jsx->stream_method |= STREAM_METHOD_IBB; | |
303 */ | |
304 } | |
305 g_free(val); | |
306 } | |
307 } | |
308 } | |
309 } | |
310 } | |
311 | |
312 if(jsx->stream_method == STREAM_METHOD_UNKNOWN) { | |
313 g_free(jsx); | |
314 return; | |
315 } | |
316 | |
317 jsx->js = js; | |
318 jsx->stream_id = g_strdup(stream_id); | |
319 jsx->iq_id = g_strdup(xmlnode_get_attrib(packet, "id")); | |
320 | |
321 xfer = gaim_xfer_new(js->gc->account, GAIM_XFER_RECEIVE, | |
322 xmlnode_get_attrib(packet, "from")); | |
323 xfer->data = jsx; | |
324 | |
325 gaim_xfer_set_filename(xfer, filename); | |
326 if(filesize > 0) | |
327 gaim_xfer_set_size(xfer, filesize); | |
328 | |
329 gaim_xfer_set_init_fnc(xfer, jabber_si_xfer_init); | |
330 gaim_xfer_set_read_fnc(xfer, jabber_si_xfer_read); | |
331 | |
332 js->file_transfers = g_list_append(js->file_transfers, xfer); | |
333 | |
334 gaim_xfer_request(xfer); | |
335 } | |
336 | |
337 #if 0 | |
7395 | 338 void jabber_si_parse(JabberStream *js, xmlnode *packet) |
339 { | |
340 GaimXfer *xfer; | |
341 JabberSIXfer *jsx; | |
342 xmlnode *si, *feature, *x, *field, *value; | |
8231
f50c059b6384
[gaim-migrate @ 8954]
Christian Hammond <chipx86@chipx86.com>
parents:
8135
diff
changeset
|
343 GaimAccount *account = gaim_connection_get_account(js->gc); |
7395 | 344 |
345 si = xmlnode_get_child(packet, "si"); | |
346 | |
347 xfer = jabber_si_xfer_find_by_id(js, xmlnode_get_attrib(si, "id")); | |
348 | |
349 if(!xfer) | |
350 return; | |
351 | |
352 jsx = xfer->data; | |
353 | |
354 if(!(feature = xmlnode_get_child(si, "feature"))) | |
355 return; | |
356 | |
8135 | 357 for(x = xmlnode_get_child(feature, "x"); x; x = xmlnode_get_next_twin(x)) { |
7395 | 358 const char *xmlns; |
359 if(!(xmlns = xmlnode_get_attrib(x, "xmlns"))) | |
360 continue; | |
361 if(strcmp(xmlns, "jabber:x:data")) | |
362 continue; | |
8135 | 363 for(field = xmlnode_get_child(x, "field"); field; |
364 field = xmlnode_get_next_twin(field)) { | |
7395 | 365 const char *var; |
366 if(!(var = xmlnode_get_attrib(field, "var"))) | |
367 continue; | |
368 if(!strcmp(var, "stream-method")) { | |
369 if((value = xmlnode_get_child(field, "value"))) { | |
370 char *val_data = xmlnode_get_data(value); | |
371 if(!val_data) | |
372 jsx->stream_method = STREAM_METHOD_UNKNOWN; | |
373 else if(!strcmp(val_data, | |
374 "http://jabber.org/protocol/bytestreams")) | |
375 jsx->stream_method = STREAM_METHOD_BYTESTREAMS; | |
376 else if(!strcmp(val_data, "http://jabber.org/protocol/ibb")) | |
377 jsx->stream_method = STREAM_METHOD_IBB; | |
378 else | |
379 jsx->stream_method = STREAM_METHOD_UNSUPPORTED; | |
380 g_free(val_data); | |
381 } | |
382 } | |
383 } | |
384 } | |
385 if(jsx->stream_method == STREAM_METHOD_UNKNOWN) { | |
386 /* XXX */ | |
387 } else if(jsx->stream_method == STREAM_METHOD_UNSUPPORTED) { | |
388 /* XXX */ | |
389 } else if(jsx->stream_method == STREAM_METHOD_BYTESTREAMS) { | |
390 /* XXX: open the port and stuff */ | |
391 char *buf; | |
392 xmlnode *query, *streamhost; | |
393 JabberIq *iq = jabber_iq_new_query(js, JABBER_IQ_SET, | |
394 "http://jabber.org/protocol/bytestreams"); | |
395 | |
396 buf = g_strdup_printf("%s/%s", xfer->who, jsx->resource); | |
397 xmlnode_set_attrib(iq->node, "to", buf); | |
398 g_free(buf); | |
399 | |
400 query = xmlnode_get_child(iq->node, "query"); | |
401 xmlnode_set_attrib(query, "sid", jsx->id); | |
402 streamhost = xmlnode_new_child(query, "streamhost"); | |
403 xmlnode_set_attrib(streamhost, "jid", | |
404 gaim_account_get_username(js->gc->account)); | |
8231
f50c059b6384
[gaim-migrate @ 8954]
Christian Hammond <chipx86@chipx86.com>
parents:
8135
diff
changeset
|
405 xmlnode_set_attrib(streamhost, "host", gaim_network_get_ip_for_account(account, js->fd)); |
7395 | 406 buf = g_strdup_printf("%d", xfer->local_port); |
407 xmlnode_set_attrib(streamhost, "port", buf); | |
408 g_free(buf); | |
409 jabber_iq_send(iq); | |
410 } else if(jsx->stream_method == STREAM_METHOD_IBB) { | |
411 char *buf; | |
412 xmlnode *open; | |
413 JabberIq *iq = jabber_iq_new(js, JABBER_IQ_SET); | |
414 buf = g_strdup_printf("%s/%s", xfer->who, jsx->resource); | |
415 xmlnode_set_attrib(iq->node, "to", buf); | |
416 g_free(buf); | |
417 | |
418 open = xmlnode_new_child(iq->node, "open"); | |
419 xmlnode_set_attrib(open, "xmlns", "http://jabber.org/protocol/ibb"); | |
420 xmlnode_set_attrib(open, "sid", jsx->id); | |
421 | |
422 jabber_iq_set_callback(iq, jabber_si_xfer_ibb_start, xfer); | |
423 | |
424 jabber_iq_send(iq); | |
425 | |
426 } | |
427 } | |
428 | |
429 static void jabber_si_xfer_send_request(GaimXfer *xfer) | |
430 { | |
431 JabberSIXfer *jsx = xfer->data; | |
432 JabberIq *iq; | |
433 xmlnode *si, *file, *feature, *x, *field, *option, *value; | |
434 char buf[32]; | |
435 char *to; | |
436 | |
437 xfer->filename = g_path_get_basename(xfer->local_filename); | |
438 | |
439 iq = jabber_iq_new(jsx->js, JABBER_IQ_SET); | |
440 to = g_strdup_printf("%s/%s", xfer->who, jsx->resource); | |
441 xmlnode_set_attrib(iq->node, "to", to); | |
442 g_free(to); | |
443 si = xmlnode_new_child(iq->node, "si"); | |
444 xmlnode_set_attrib(si, "xmlns", "http://jabber.org/protocol/si"); | |
445 jsx->id = jabber_get_next_id(jsx->js); | |
446 xmlnode_set_attrib(si, "id", jsx->id); | |
447 xmlnode_set_attrib(si, "profile", | |
448 "http://jabber.org/protocol/si/profile/file-transfer"); | |
449 | |
450 file = xmlnode_new_child(si, "file"); | |
451 xmlnode_set_attrib(file, "xmlns", | |
452 "http://jabber.org/protocol/si/profile/file-transfer"); | |
453 xmlnode_set_attrib(file, "name", xfer->filename); | |
454 g_snprintf(buf, sizeof(buf), "%d", xfer->size); | |
455 xmlnode_set_attrib(file, "size", buf); | |
456 /* maybe later we'll do hash and date attribs */ | |
457 | |
458 feature = xmlnode_new_child(si, "feature"); | |
459 xmlnode_set_attrib(feature, "xmlns", | |
460 "http://jabber.org/protocol/feature-neg"); | |
461 x = xmlnode_new_child(feature, "x"); | |
462 xmlnode_set_attrib(x, "xmlns", "jabber:x:data"); | |
463 xmlnode_set_attrib(x, "type", "form"); | |
464 field = xmlnode_new_child(x, "field"); | |
465 xmlnode_set_attrib(field, "var", "stream-method"); | |
466 xmlnode_set_attrib(field, "type", "list-single"); | |
467 option = xmlnode_new_child(field, "option"); | |
468 value = xmlnode_new_child(option, "value"); | |
469 xmlnode_insert_data(value, "http://jabber.org/protocol/bytestreams", | |
470 -1); | |
471 option = xmlnode_new_child(field, "option"); | |
472 value = xmlnode_new_child(option, "value"); | |
473 xmlnode_insert_data(value, "http://jabber.org/protocol/ibb", -1); | |
474 | |
475 jabber_iq_send(iq); | |
476 } | |
477 | |
478 void jabber_si_xfer_init(GaimXfer *xfer) | |
479 { | |
480 JabberSIXfer *jsx = xfer->data; | |
481 if(gaim_xfer_get_type(xfer) == GAIM_XFER_SEND) { | |
482 JabberBuddy *jb; | |
483 JabberBuddyResource *jbr = NULL; | |
484 GList *resources; | |
485 GList *xfer_resources = NULL; | |
486 | |
487 jb = jabber_buddy_find(jsx->js, xfer->who, TRUE); | |
488 if(!jb) | |
489 return; | |
490 | |
491 for(resources = jb->resources; resources; resources = resources->next) { | |
492 jbr = resources->data; | |
493 if(jbr->capabilities & JABBER_CAP_SI_FILE_XFER) | |
494 xfer_resources = g_list_append(xfer_resources, jbr); | |
495 } | |
496 | |
497 if(g_list_length(xfer_resources) == 1) { | |
498 jbr = xfer_resources->data; | |
499 jsx->resource = g_strdup(jbr->name); | |
500 jabber_si_xfer_send_request(xfer); | |
501 } else if(g_list_length(xfer_resources) == 0) { | |
502 char *buf = g_strdup_printf(_("Could not send %s to %s, protocol not supported."), xfer->filename, xfer->who); | |
503 gaim_notify_error(jsx->js->gc, _("File Send Failed"), | |
504 _("File Send Failed"), buf); | |
505 g_free(buf); | |
506 } else { | |
507 /* XXX: ask which resource to send to! */ | |
508 } | |
509 g_list_free(xfer_resources); | |
510 } | |
511 } | |
512 | |
513 void jabber_si_xfer_start(GaimXfer *xfer) | |
514 { | |
515 gaim_debug(GAIM_DEBUG_INFO, "jabber", "in jabber_si_xfer_start\n"); | |
516 } | |
517 | |
518 void jabber_si_xfer_end(GaimXfer *xfer) | |
519 { | |
520 gaim_debug(GAIM_DEBUG_INFO, "jabber", "in jabber_si_xfer_end\n"); | |
521 } | |
522 | |
523 void jabber_si_xfer_cancel_send(GaimXfer *xfer) | |
524 { | |
525 gaim_debug(GAIM_DEBUG_INFO, "jabber", "in jabber_si_xfer_cancel_send\n"); | |
526 } | |
527 | |
528 | |
529 void jabber_si_xfer_cancel_recv(GaimXfer *xfer) | |
530 { | |
531 gaim_debug(GAIM_DEBUG_INFO, "jabber", "in jabber_si_xfer_cancel_recv\n"); | |
532 } | |
533 | |
534 | |
535 void jabber_si_xfer_ack(GaimXfer *xfer, const char *buffer, size_t size) | |
536 { | |
537 gaim_debug(GAIM_DEBUG_INFO, "jabber", "in jabber_si_xfer_ack\n"); | |
538 } | |
539 | |
8262 | 540 #endif |