Generalize send_file_xfer_status() to send all file xfer statuses, not just errors. Change send_file_xfer_status() to support sending detailed file xfer status messages with additional error data. --- configure.ac | 2 +- src/vdagentd/vdagentd.c | 60 ++++++++++++++++++++++++++++++++----------------- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/configure.ac b/configure.ac index 0c2cfd8..f207240 100644 --- a/configure.ac +++ b/configure.ac @@ -79,7 +79,7 @@ AC_ARG_ENABLE([static-uinput], PKG_CHECK_MODULES([GLIB2], [glib-2.0 >= 2.28]) PKG_CHECK_MODULES(X, [xfixes xrandr >= 1.3 xinerama x11]) -PKG_CHECK_MODULES(SPICE, [spice-protocol >= 0.12.8]) +PKG_CHECK_MODULES(SPICE, [spice-protocol >= 0.12.13]) PKG_CHECK_MODULES(ALSA, [alsa >= 1.0.22]) PKG_CHECK_MODULES([DBUS], [dbus-1]) diff --git a/src/vdagentd/vdagentd.c b/src/vdagentd/vdagentd.c index f3ac606..64819d0 100644 --- a/src/vdagentd/vdagentd.c +++ b/src/vdagentd/vdagentd.c @@ -301,20 +301,38 @@ static void do_client_clipboard(struct vdagent_virtio_port *vport, data, size); } -/* To be used by vdagentd for failures in file-xfer such as when file-xfer was - * cancelled or an error happened */ +/* Send file-xfer status to the client. In the case status is an error, + * optional data for the client and log message may be specified. */ static void send_file_xfer_status(struct vdagent_virtio_port *vport, - const char *msg, uint32_t id, uint32_t xfer_status) + const char *msg, uint32_t id, uint32_t xfer_status, + const uint8_t *data, uint32_t data_size) { - VDAgentFileXferStatusMessage status = { - .id = GUINT32_TO_LE(id), - .result = GUINT32_TO_LE(xfer_status), - }; - syslog(LOG_WARNING, msg, id); + VDAgentFileXferStatusMessage *status; + + /* Replace new detailed errors with older generic VD_AGENT_FILE_XFER_STATUS_ERROR + * when not supported by client */ + if (xfer_status > VD_AGENT_FILE_XFER_STATUS_SUCCESS && + !VD_AGENT_HAS_CAPABILITY(capabilities, capabilities_size, + VD_AGENT_CAP_FILE_XFER_DETAILED_ERRORS)) { + xfer_status = VD_AGENT_FILE_XFER_STATUS_ERROR; + data_size = 0; + } + + status = malloc(sizeof(*status) + data_size); + status->id = GUINT32_TO_LE(id); + status->result = GUINT32_TO_LE(xfer_status); + if (data) + memcpy(status->data, data, data_size); + + if (msg) + syslog(LOG_WARNING, msg, id); + if (vport) vdagent_virtio_port_write(vport, VDP_CLIENT_PORT, VD_AGENT_FILE_XFER_STATUS, 0, - (uint8_t *)&status, sizeof(status)); + (uint8_t *)status, sizeof(*status) + data_size); + + free(status); } static void do_client_file_xfer(struct vdagent_virtio_port *vport, @@ -331,14 +349,14 @@ static void do_client_file_xfer(struct vdagent_virtio_port *vport, send_file_xfer_status(vport, "Could not find an agent connection belonging to the " "active session, cancelling client file-xfer request %u", - s->id, VD_AGENT_FILE_XFER_STATUS_CANCELLED); + s->id, VD_AGENT_FILE_XFER_STATUS_CANCELLED, NULL, 0); return; } else if (session_info_session_is_locked(session_info)) { syslog(LOG_DEBUG, "Session is locked, skipping file-xfer-start"); send_file_xfer_status(vport, "User's session is locked and cannot start file transfer. " "Cancelling client file-xfer request %u", - s->id, VD_AGENT_FILE_XFER_STATUS_ERROR); + s->id, VD_AGENT_FILE_XFER_STATUS_ERROR, NULL, 0); return; } udscs_write(active_session_conn, VDAGENTD_FILE_XFER_START, 0, 0, @@ -810,7 +828,7 @@ static gboolean remove_active_xfers(gpointer key, gpointer value, gpointer conn) send_file_xfer_status(virtio_port, "Agent disc; cancelling file-xfer %u", GPOINTER_TO_UINT(key), - VD_AGENT_FILE_XFER_STATUS_CANCELLED); + VD_AGENT_FILE_XFER_STATUS_CANCELLED, NULL, 0); return 1; } else return 0; @@ -903,17 +921,17 @@ static void agent_read_complete(struct udscs_connection **connp, } break; case VDAGENTD_FILE_XFER_STATUS:{ - VDAgentFileXferStatusMessage status; - status.id = GUINT32_TO_LE(header->arg1); - status.result = GUINT32_TO_LE(header->arg2); - vdagent_virtio_port_write(virtio_port, VDP_CLIENT_PORT, - VD_AGENT_FILE_XFER_STATUS, 0, - (uint8_t *)&status, sizeof(status)); - if (status.result == VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA) - g_hash_table_insert(active_xfers, GUINT_TO_POINTER(status.id), + /* header->arg1 = file xfer task id, header->arg2 = file xfer status */ + switch (header->arg2) { + default: + send_file_xfer_status(virtio_port, NULL, header->arg1, header->arg2, NULL, 0); + } + + if (header->arg2 == VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA) + g_hash_table_insert(active_xfers, GUINT_TO_POINTER(GUINT32_TO_LE(header->arg1)), *connp); else - g_hash_table_remove(active_xfers, GUINT_TO_POINTER(status.id)); + g_hash_table_remove(active_xfers, GUINT_TO_POINTER(GUINT32_TO_LE(header->arg1))); break; } -- 2.9.4 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel