On Thu, 2017-04-27 at 15:20 -0500, Jonathon Jongsma wrote: > Previously, if the user attempted to transfer a file that had the > same > name as a file that already exists on the guest, we would just fail > the > transfer. This patch tries to match the behavior of the linux > vdagent > where we try to append an integer onto the name of the new file to > make > it unique. For example, if you tried to transfer 'file.doc' to the > guest > and that file already existed, it would try to create 'file (1).doc' > instead. If that also failed, it would attempt 'file (2).doc', etc, > up > to 63. > > Resolves: rhbz#1410181 > Signed-off-by: Jonathon Jongsma <jjongsma@xxxxxxxxxx> > --- > Changes since v1: > - change from "file.doc (1)" to "file (1).doc" > - retain debug output for other CreateFile errors > > vdagent/file_xfer.cpp | 50 > ++++++++++++++++++++++++++++++++++++++++++++------ > 1 file changed, 44 insertions(+), 6 deletions(-) > > diff --git a/vdagent/file_xfer.cpp b/vdagent/file_xfer.cpp > index f763ed3..24eb00a 100644 > --- a/vdagent/file_xfer.cpp > +++ b/vdagent/file_xfer.cpp > @@ -61,6 +61,7 @@ void > FileXfer::handle_start(VDAgentFileXferStartMessage* start, > HANDLE handle; > AsUser as_user; > int wlen; > + int attempt = 0; > > status->id = start->id; > status->result = VD_AGENT_FILE_XFER_STATUS_ERROR; > @@ -99,15 +100,52 @@ void > FileXfer::handle_start(VDAgentFileXferStartMessage* start, > > file_path[wlen++] = TEXT('\\'); > file_path[wlen] = TEXT('\0'); > - if((wlen = MultiByteToWideChar(CP_UTF8, 0, file_name, -1, > file_path + wlen, MAX_PATH - wlen)) == 0){ > - vd_printf("failed converting file_name:%s to WideChar", > file_name); > - return; > + > + const int MAX_ATTEMPTS = 64; // matches behavior of linux > vdagent > + const size_t POSTFIX_LEN = 6; // up to 2 digits in parentheses > and final NULL: " (xx)" > + size_t name_len = strlen(file_name); > + char *extension = strrchr(file_name, '.'); > + > + for (attempt = 0; attempt < MAX_ATTEMPTS; attempt++) { > + char dest_filename[MAX_PATH]; > + if (attempt == 0) { > + strcpy(dest_filename, file_name); > + } else { > + if (name_len + POSTFIX_LEN > MAX_PATH) { > + vd_printf("failed creating %ls. Postfix makes name > too long for the buffer.", file_path); > + return; > + } > + > + int basename_len = (extension != NULL) ? (extension - > file_name) : name_len; > + memcpy(dest_filename, file_name, basename_len); > + // append postfix > + int postfix_len = snprintf(dest_filename + > basename_len, POSTFIX_LEN, " (%d)", attempt); > + if (extension != NULL) { > + strcpy(dest_filename + basename_len + postfix_len, > extension); > + } > + } > + if((MultiByteToWideChar(CP_UTF8, 0, dest_filename, -1, missing space^ > file_path + wlen, MAX_PATH - wlen)) == 0){ and here ^ > + vd_printf("failed converting file_name:%s to WideChar", > dest_filename); > + return; > + } > + handle = CreateFile(file_path, GENERIC_WRITE, 0, NULL, > CREATE_NEW, 0, NULL); > + if (handle != INVALID_HANDLE_VALUE) { > + break; > + } > + > + // If the file already exists, we can re-try with a new > filename. If > + // it's a different error, there's not much we can do. > + if (GetLastError() != ERROR_FILE_EXISTS) { > + vd_printf("Failed creating %ls %lu", file_path, > GetLastError()); > + return; > + } > } > - handle = CreateFile(file_path, GENERIC_WRITE, 0, NULL, > CREATE_NEW, 0, NULL); > - if (handle == INVALID_HANDLE_VALUE) { > - vd_printf("failed creating %ls %lu", file_path, > GetLastError()); > + > + if (attempt == MAX_ATTEMPTS) { > + vd_printf("Failed creating %ls. More than 63 copies > exist?", file_path); > return; > } > + > task = new FileXferTask(handle, file_size, file_path); > _tasks[start->id] = task; > status->result = VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA; looks good, ack Pavel _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel