--- a/libpurple/ft.c Mon May 23 20:30:57 2022 -0500
+++ b/libpurple/ft.c Wed May 25 23:51:10 2022 -0500
@@ -1107,11 +1107,12 @@
r = write(xfer->fd, buffer, s);
if (r < 0 && errno == EAGAIN)
+ if ((purple_xfer_get_bytes_sent(xfer) + r) >= purple_xfer_get_size(xfer) && + !purple_xfer_is_completed(xfer)) { + purple_xfer_set_completed(xfer, TRUE); - if (r >= 0 && (purple_xfer_get_bytes_sent(xfer)+r) >= purple_xfer_get_size(xfer) &&
- !purple_xfer_is_completed(xfer))
- purple_xfer_set_completed(xfer, TRUE);
@@ -1222,6 +1223,7 @@
if (xfer->type == PURPLE_XFER_RECEIVE) {
r = purple_xfer_read(xfer, &buffer);
if (ui_ops && ui_ops->ui_write)
@@ -1236,9 +1238,13 @@
- if ((purple_xfer_get_size(xfer) > 0) &&
- ((purple_xfer_get_bytes_sent(xfer)+r) >= purple_xfer_get_size(xfer)))
- purple_xfer_set_completed(xfer, TRUE);
+ if(xfer->ops.read == NULL) { + if ((purple_xfer_get_size(xfer) > 0) && + ((purple_xfer_get_bytes_sent(xfer) + r) >= purple_xfer_get_size(xfer))) { + purple_xfer_set_completed(xfer, TRUE); purple_xfer_cancel_remote(xfer);
@@ -1545,19 +1551,6 @@
begin_transfer(xfer, cond);
-purple_xfer_drain_socket(int sock)
- ret = read(sock, buffer, sizeof(buffer));
- (errno == EAGAIN || errno == EWOULDBLOCK)));
purple_xfer_end(PurpleXfer *xfer)
@@ -1579,7 +1572,6 @@
- purple_xfer_drain_socket(xfer->fd);
--- a/libpurple/protocols/irc/dcc_send.c Mon May 23 20:30:57 2022 -0500
+++ b/libpurple/protocols/irc/dcc_send.c Wed May 25 23:51:10 2022 -0500
@@ -62,6 +62,38 @@
+static gssize irc_dccsend_recv_read(guchar **buffer, PurpleXfer *xfer) { + if (purple_xfer_get_size(xfer) == 0) { + s = xfer->current_buffer_size; + s = MIN(purple_xfer_get_bytes_remaining(xfer), xfer->current_buffer_size); + *buffer = g_malloc0(s); + r = read(xfer->fd, *buffer, s); + if (r < 0 && errno == EAGAIN) { + /* read() would block if the socket was nonblocking, so retry */ + /* read() has errored out for some other reason, so we fail the xfer */ + /* read() signals that there is no more data to get from the socket */ + if(purple_xfer_get_bytes_sent(xfer) >= purple_xfer_get_size(xfer)) { + /* We got all the data, xfer successful */ + purple_xfer_set_completed(xfer, TRUE); + /* We expect more data, fail the xfer */ static void irc_dccsend_recv_init(PurpleXfer *xfer) {
struct irc_xfer_rx_data *xd = xfer->data;
@@ -134,6 +166,7 @@
purple_xfer_set_init_fnc(xfer, irc_dccsend_recv_init);
purple_xfer_set_ack_fnc(xfer, irc_dccsend_recv_ack);
+ purple_xfer_set_read_fnc(xfer, irc_dccsend_recv_read); purple_xfer_set_end_fnc(xfer, irc_dccsend_recv_destroy);
purple_xfer_set_request_denied_fnc(xfer, irc_dccsend_recv_destroy);
purple_xfer_set_cancel_recv_fnc(xfer, irc_dccsend_recv_destroy);