Mercurial > pidgin.yaz
changeset 4538:009e206f260c
[gaim-migrate @ 4817]
Jabber can receive files again.
I'm sure everyone was losing as much sleep over this as I was.
committer: Tailor Script <tailor@pidgin.im>
author | Nathan Walp <nwalp@pidgin.im> |
---|---|
date | Thu, 06 Feb 2003 04:32:54 +0000 |
parents | 741a18f2fb23 |
children | 05476ef20d58 |
files | src/ft.c src/ft.h src/protocols/jabber/jabber.c |
diffstat | 3 files changed, 137 insertions(+), 169 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ft.c Wed Feb 05 23:54:11 2003 +0000 +++ b/src/ft.c Thu Feb 06 04:32:54 2003 +0000 @@ -4,7 +4,7 @@ * gaim * * Copyright (C) 2002-2003, Christian Hammond <chipx86@gnupdate.org> - * + * * 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 @@ -63,7 +63,7 @@ if (xfer == NULL) return; - if (xfer->bytes_remaining > 0) { + if (!xfer->completed) { gaim_xfer_cancel(xfer); return; } @@ -282,6 +282,15 @@ } void +gaim_xfer_set_completed(struct gaim_xfer *xfer, gboolean completed) +{ + if(xfer == NULL) + return; + + xfer->completed = completed; +} + +void gaim_xfer_set_filename(struct gaim_xfer *xfer, const char *filename) { if (xfer == NULL) @@ -311,6 +320,9 @@ if (xfer == NULL) return; + if(xfer->size == 0) + xfer->bytes_remaining = size - xfer->bytes_sent; + xfer->size = size; } @@ -414,6 +426,9 @@ *buffer = g_malloc0(s); r = read(xfer->fd, *buffer, s); + + if(r == 0) + gaim_xfer_set_completed(xfer, TRUE); } return r; @@ -472,7 +487,8 @@ if (r < 0) return; - xfer->bytes_remaining -= r; + if(gaim_xfer_get_size(xfer) > 0) + xfer->bytes_remaining -= r; xfer->bytes_sent += r; if (xfer->ops.ack != NULL) @@ -483,7 +499,7 @@ if (ui_ops != NULL && ui_ops->update_progress != NULL) ui_ops->update_progress(xfer, gaim_xfer_get_progress(xfer)); - if (r == 0) + if (xfer->completed) gaim_xfer_end(xfer); } @@ -575,7 +591,7 @@ return; /* See if we are actually trying to cancel this. */ - if (gaim_xfer_get_bytes_remaining(xfer) > 0) { + if (!xfer->completed) { gaim_xfer_cancel(xfer); return; }
--- a/src/ft.h Wed Feb 05 23:54:11 2003 +0000 +++ b/src/ft.h Thu Feb 06 04:32:54 2003 +0000 @@ -84,6 +84,8 @@ size_t bytes_sent; /**< The number of bytes sent. */ size_t bytes_remaining; /**< The number of bytes remaining. */ + gboolean completed; /**< File Transfer is completed. */ + /* I/O operations. */ struct { @@ -261,6 +263,14 @@ unsigned int gaim_xfer_get_remote_port(const struct gaim_xfer *xfer); /** + * Sets the completed state for the file transfer. + * + * @param xfer The file transfer. + * @param completed The completed state. + */ +void gaim_xfer_set_completed(struct gaim_xfer *xfer, gboolean completed); + +/** * Sets the filename for the file transfer. * * @param xfer The file transfer.
--- a/src/protocols/jabber/jabber.c Wed Feb 05 23:54:11 2003 +0000 +++ b/src/protocols/jabber/jabber.c Thu Feb 06 04:32:54 2003 +0000 @@ -1932,176 +1932,114 @@ xmlnode_free(x); } -#if 0 -struct jabber_file_transfer { - enum { JFT_SENDFILE_IN, JFT_SENDFILE_OUT } type; - struct file_transfer *xfer; - char *from; +struct jabber_xfer_data { struct g_url *url; - char *name; GString *headers; - - int len; - int fd; - int watcher; - - gboolean sentreq; gboolean newline; - gboolean startsaving; - - struct gaim_connection *gc; + + char *iq_id; + + struct jabber_data *jd; }; -static struct jabber_file_transfer *find_jft_by_xfer(struct gaim_connection *gc, - struct file_transfer *xfer) { - GSList *g = ((struct jabber_data *)gc->proto_data)->file_transfers; - struct jabber_file_transfer *f = NULL; - - while(g) { - f = (struct jabber_file_transfer *)g->data; - if(f->xfer == xfer) - break; - g = g->next; - f = NULL; - } - - return f; +static void jabber_xfer_init(struct gaim_xfer *xfer) +{ + struct jabber_xfer_data *data = xfer->data; + gaim_xfer_start(xfer, -1, data->url->address, data->url->port); +} + +static void jabber_xfer_free(struct gaim_xfer *xfer) +{ + struct jabber_xfer_data *data = xfer->data; + data->jd->file_transfers = g_slist_remove(data->jd->file_transfers, xfer); + + g_string_free(data->headers, TRUE); + g_free(data->url); + g_free(data->iq_id); + g_free(data); + + xfer->data = NULL; } -static void jabber_http_recv_callback(gpointer data, gint source, GaimInputCondition condition) { - struct jabber_file_transfer *jft = data; +static void jabber_xfer_end(struct gaim_xfer *xfer) +{ + struct jabber_xfer_data *data = xfer->data; + xmlnode x; + + x = xmlnode_new_tag("iq"); + xmlnode_put_attrib(x, "type", "result"); + xmlnode_put_attrib(x, "to", xfer->who); + xmlnode_put_attrib(x, "id", data->iq_id); + + gjab_send(data->jd->gjc, x); + + xmlnode_free(x); + + jabber_xfer_free(xfer); +} + +static void jabber_xfer_start(struct gaim_xfer *xfer) +{ + struct jabber_xfer_data *data = xfer->data; + char *buf = g_strdup_printf("GET /%s HTTP/1.1\r\nHost: %s\r\n\r\n", + data->url->page, data->url->address); + write(xfer->fd, buf, strlen(buf)); + g_free(buf); +} + +static size_t jabber_xfer_read(char **buffer, struct gaim_xfer *xfer) { + struct jabber_xfer_data *data = xfer->data; char test; - - jft->fd = source; - if(!jft->sentreq) { - char buf[1024]; - g_snprintf(buf, sizeof(buf), "GET /%s HTTP/1.1\r\nHost: %s\r\n\r\n", jft->url->page, jft->url->address); - write(source, buf, strlen(buf)); -#ifndef _WIN32 - fcntl(source, F_SETFL, O_NONBLOCK); -#else - { - u_long imode = 1; - ioctlsocket(source, FIONBIO, (u_long*)&imode); - } -#endif - jft->sentreq = TRUE; - jft->watcher = gaim_input_add(source, GAIM_INPUT_READ, jabber_http_recv_callback,data); - return; - } - - if(!jft->startsaving) { -#ifndef _WIN32 - if(read(source, &test, sizeof(test)) > 0 || errno == EWOULDBLOCK) { - if(errno == EWOULDBLOCK) -#else - if(recv(source, &test, sizeof(test), 0) > 0 || WSAGetLastError() == WSAEWOULDBLOCK) { - if(WSAEWOULDBLOCK == WSAGetLastError()) -#endif - { - errno = 0; - return; + size_t size; + + if(read(xfer->fd, &test, sizeof(test)) > 0) { + data->headers = g_string_append_c(data->headers, test); + if(test == '\r') + return 0; + if(test == '\n') { + if(data->newline) { + gchar *lenstr = strstr(data->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 + data->newline = TRUE; + return 0; } - - jft->headers = g_string_append_c(jft->headers, test); - if(test == '\r') - return; - if(test == '\n') { - if(jft->newline) { - gchar *lenstr = strstr(jft->headers->str, "Content-Length: "); - if(lenstr) { - sscanf(lenstr, "Content-Length: %d", &jft->len); - } - jft->startsaving = TRUE; - } else - jft->newline = TRUE; - return; - } - jft->newline = FALSE; - return; - } else { - gaim_input_remove(jft->watcher); - close(source); - //FIXME: ft_cancel(NULL, jft->xfer); - } - return; + data->newline = FALSE; + return 0; } - - /* we've parsed the headers, gotten the size, all is good. now we pass the reception of - * the file off to the core, and leave it in it's capable...err...hands?? */ - gaim_input_remove(jft->watcher); - jft->watcher = 0; - transfer_in_do(jft->xfer, jft->fd, jft->name, jft->len); + return 0; } -static void jabber_file_transfer_cancel(struct gaim_connection *gc, struct file_transfer *xfer) { - struct jabber_data *jd = gc->proto_data; - struct jabber_file_transfer *jft = find_jft_by_xfer(gc, xfer);\ +static void jabber_xfer_cancel(struct gaim_xfer *xfer) { + struct jabber_xfer_data *data = xfer->data; xmlnode x,y; - jd->file_transfers = g_slist_remove(jd->file_transfers, jft); - - gaim_input_remove(jft->watcher); - close(jft->fd); - x = xmlnode_new_tag("iq"); xmlnode_put_attrib(x, "type", "error"); - xmlnode_put_attrib(x, "to", jft->from); + xmlnode_put_attrib(x, "to", xfer->who); + xmlnode_put_attrib(x, "id", data->iq_id); y = xmlnode_insert_tag(x, "error"); /* FIXME: need to handle other kinds of errors here */ xmlnode_put_attrib(y, "code", "406"); xmlnode_insert_cdata(y, "File Transfer Refused", -1); - gjab_send(jd->gjc, x); + gjab_send(data->jd->gjc, x); xmlnode_free(x); - g_string_free(jft->headers, TRUE); - g_free(jft->from); - g_free(jft->url); - g_free(jft->name); - - g_free(jft); + jabber_xfer_free(xfer); } -static void jabber_file_transfer_done(struct gaim_connection *gc, struct file_transfer *xfer) { - struct jabber_data *jd = gc->proto_data; - struct jabber_file_transfer *jft = find_jft_by_xfer(gc, xfer); - xmlnode x; - - jd->file_transfers = g_slist_remove(jd->file_transfers, jft); - - gaim_input_remove(jft->watcher); - close(jft->fd); - - x = xmlnode_new_tag("iq"); - xmlnode_put_attrib(x, "type", "result"); - xmlnode_put_attrib(x, "to", jft->from); - - gjab_send(jd->gjc, x); - - xmlnode_free(x); - - g_string_free(jft->headers, TRUE); - g_free(jft->from); - g_free(jft->url); - g_free(jft->name); - - g_free(jft); -} - -static void jabber_file_transfer_in(struct gaim_connection *gc, struct file_transfer *xfer, int offset) { - struct jabber_file_transfer *jft = find_jft_by_xfer(gc, xfer); - - proxy_connect(jft->url->address, jft->url->port, jabber_http_recv_callback, jft); -} -#endif - static void jabber_handleoob(gjconn gjc, xmlnode iqnode) { -#if 0 - struct jabber_file_transfer *jft; + struct jabber_xfer_data *xfer_data; struct jabber_data *jd = GJ_GC(gjc)->proto_data; char *msg = NULL; + char *filename; xmlnode querynode = xmlnode_get_tag(iqnode, "query"); xmlnode urlnode,descnode; @@ -2114,21 +2052,33 @@ if(descnode) msg = xmlnode_get_data(descnode); - jft = g_new0(struct jabber_file_transfer, 1); - jft->type = JFT_SENDFILE_IN; - jft->gc = GJ_GC(gjc); - jft->url = parse_url(xmlnode_get_data(urlnode)); - jft->from = g_strdup(xmlnode_get_attrib(iqnode, "from")); - jft->name = g_strdup(g_strrstr(jft->url->page,"/")); - if (!jft->name) - jft->name = g_strdup(jft->url->page); - jft->headers = g_string_new(""); - jft->len = -1; - - jd->file_transfers = g_slist_append(jd->file_transfers, jft); - - jft->xfer = transfer_in_add(GJ_GC(gjc), jft->from, jft->name, jft->len, 1, msg); -#endif + xfer_data = g_new0(struct jabber_xfer_data, 1); + xfer_data->url = parse_url(xmlnode_get_data(urlnode)); + xfer_data->jd = jd; + xfer_data->headers = g_string_new(""); + xfer_data->iq_id = g_strdup(xmlnode_get_attrib(iqnode, "id")); + + xfer = gaim_xfer_new(GJ_GC(gjc)->account, GAIM_XFER_RECEIVE, + xmlnode_get_attrib(iqnode, "from")); + xfer->data = xfer_data; + + filename = g_strdup(g_strrstr(xfer_data->url->page, "/")); + if(!filename) + filename = g_strdup(xfer_data->url->page); + + gaim_xfer_set_filename(xfer, filename); + + g_free(filename); + + gaim_xfer_set_init_fnc(xfer, jabber_xfer_init); + gaim_xfer_set_end_fnc(xfer, jabber_xfer_end); + gaim_xfer_set_cancel_fnc(xfer, jabber_xfer_cancel); + gaim_xfer_set_read_fnc(xfer, jabber_xfer_read); + gaim_xfer_set_start_fnc(xfer, jabber_xfer_start); + + jd->file_transfers = g_slist_append(jd->file_transfers, xfer); + + gaim_xfer_request(xfer); } static void jabber_handlelast(gjconn gjc, xmlnode iqnode) { @@ -4240,14 +4190,6 @@ ret->convo_closed = jabber_convo_closed; ret->rename_group = jabber_rename_group; -#if 0 - ret->file_transfer_out = NULL; /* TODO */ - ret->file_transfer_in = jabber_file_transfer_in; - ret->file_transfer_data_chunk = NULL; /* TODO */ - ret->file_transfer_done = jabber_file_transfer_done; - ret->file_transfer_cancel = jabber_file_transfer_cancel; -#endif - puo = g_new0(struct proto_user_opt, 1); puo->label = g_strdup(_("Port:")); puo->def = g_strdup("5222");