/* just in case you were wondering, this is why DCC is gay */ static void irc_dccsend_send_read(gpointer data, int source, GaimInputCondition cond) { GaimXfer *xfer = data; struct irc_xfer_send_data *xd = xfer->data; char *buffer[16]; int len; len = read(source, buffer, sizeof(buffer)); if (len < 0 && errno == EAGAIN) return; else if (len <= 0) { /* XXX: Shouldn't this be canceling the transfer? */ gaim_input_remove(xd->inpa); xd->inpa = 0; return; } xd->rxqueue = g_realloc(xd->rxqueue, len + xd->rxlen); memcpy(xd->rxqueue + xd->rxlen, buffer, len); xd->rxlen += len; while (1) { size_t acked; if (xd->rxlen < 4) break; acked = ntohl(*((gint32 *)xd->rxqueue)); xd->rxlen -= 4; if (xd->rxlen) { unsigned char *tmp = g_memdup(xd->rxqueue + 4, xd->rxlen); g_free(xd->rxqueue); xd->rxqueue = tmp; } else { g_free(xd->rxqueue); xd->rxqueue = NULL; } if (acked >= gaim_xfer_get_size(xfer)) { gaim_input_remove(xd->inpa); xd->inpa = 0; gaim_xfer_set_completed(xfer, TRUE); gaim_xfer_end(xfer); return; } } }
static void transfer_cb(gpointer data, gint source, GaimInputCondition condition) { GaimXferUiOps *ui_ops; GaimXfer *xfer = (GaimXfer *)data; char *buffer = NULL; size_t r; if (condition & GAIM_INPUT_READ) { r = gaim_xfer_read(xfer, &buffer); if (r > 0) fwrite(buffer, 1, r, xfer->dest_fp); } else { size_t s = MIN(gaim_xfer_get_bytes_remaining(xfer), 4096); buffer = g_malloc0(s); fread(buffer, 1, s, xfer->dest_fp); /* Write as much as we're allowed to. */ r = gaim_xfer_write(xfer, buffer, s); if (r < s) { /* We have to seek back in the file now. */ fseek(xfer->dest_fp, r - s, SEEK_CUR); } } if (gaim_xfer_get_size(xfer) > 0) xfer->bytes_remaining -= r; xfer->bytes_sent += r; if (xfer->ops.ack != NULL) xfer->ops.ack(xfer, buffer, r); g_free(buffer); ui_ops = gaim_xfer_get_ui_ops(xfer); if (ui_ops != NULL && ui_ops->update_progress != NULL) ui_ops->update_progress(xfer, gaim_xfer_get_progress(xfer)); if (gaim_xfer_is_completed(xfer)) gaim_xfer_end(xfer); }
/* just in case you were wondering, this is why DCC is gay */ static void gaym_dccsend_send_read(gpointer data, int source, GaimInputCondition cond) { GaimXfer *xfer = data; struct gaym_xfer_send_data *xd = xfer->data; char *buffer[16]; int len; if ((len = read(source, buffer, sizeof(buffer))) <= 0) { gaim_input_remove(xd->inpa); xd->inpa = 0; return; } xd->rxqueue = g_realloc(xd->rxqueue, len + xd->rxlen); memcpy(xd->rxqueue + xd->rxlen, buffer, len); xd->rxlen += len; while (1) { int acked; if (xd->rxlen < 4) break; acked = ntohl(*((gint32 *)xd->rxqueue)); xd->rxlen -= 4; if (xd->rxlen) { char *tmp = g_memdup(xd->rxqueue + 4, xd->rxlen); g_free(xd->rxqueue); xd->rxqueue = tmp; } else { g_free(xd->rxqueue); xd->rxqueue = NULL; } if (acked >= gaim_xfer_get_size(xfer)) { gaim_input_remove(xd->inpa); xd->inpa = 0; gaim_xfer_set_completed(xfer, TRUE); gaim_xfer_end(xfer); return; } } }