From: Kruti Pendharkar Date: Fri, 11 Jul 2025 12:48:15 +0000 (-0700) Subject: Change to common source files not applicable to open-vm-tools at this time. X-Git-Tag: stable-13.1.0~141 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bf1c86c08be4b6994209d82dcf6fb0424343228a;p=thirdparty%2Fopen-vm-tools.git Change to common source files not applicable to open-vm-tools at this time. --- diff --git a/open-vm-tools/services/plugins/dndcp/Makefile.am b/open-vm-tools/services/plugins/dndcp/Makefile.am index 10390bf3e..5a864e7c0 100644 --- a/open-vm-tools/services/plugins/dndcp/Makefile.am +++ b/open-vm-tools/services/plugins/dndcp/Makefile.am @@ -93,6 +93,7 @@ libdndcp_la_SOURCES += pointer.cpp libdndcp_la_SOURCES += copyPasteCompat.c libdndcp_la_SOURCES += vmCopyPasteDnDWrapper.cpp libdndcp_la_SOURCES += copyPasteDnDX11.cpp +libdndcp_la_SOURCES += copyPasteDnDUtil.cpp libdndcp_la_SOURCES += copyPasteCompatX11.c libdndcp_la_SOURCES += copyPasteUIX11.cpp libdndcp_la_SOURCES += dndUIX11.cpp diff --git a/open-vm-tools/services/plugins/dndcp/copyPasteDnDUtil.cpp b/open-vm-tools/services/plugins/dndcp/copyPasteDnDUtil.cpp new file mode 100644 index 000000000..6d2fbf227 --- /dev/null +++ b/open-vm-tools/services/plugins/dndcp/copyPasteDnDUtil.cpp @@ -0,0 +1,230 @@ +/********************************************************* + * Copyright (c) 2025 Broadcom. All Rights Reserved. + * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation version 2.1 and no later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + *********************************************************/ + +/* + * copyPasteDnDUtil.cpp -- + * + * This is the utility file to keep the common API's + * for Copy/Paste and Drag/Drop functionality. + * + */ + + +#include "copyPasteDnDUtil.h" +#include "file.h" +#include "dndFileContentsUtil.h" +#include "dndFileList.hh" +#include "copyPasteUIX11.h" +#include "cpNameUtil.h" + + +/* + *---------------------------------------------------------------------------- + * + * LocalPrepareFileContents -- + * + * Try to extract file contents from Clipboard. Write all files to a + * temporary staging directory. Construct uri list. + * + * Results: + * true if success, false otherwise. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------------- + */ + +bool +LocalPrepareFileContents(const CPClipboard *clip, // IN + std::vector& fileContentsList) // OUT +{ + void *buf = NULL; + size_t sz = 0; + XDR xdrs; + CPFileContents fileContents; + CPFileContentsList *contentsList = NULL; + size_t nFiles = 0; + CPFileItem *fileItem = NULL; + char *tempDir = NULL; + size_t i = 0; + bool ret = false; + + if (!CPClipboard_GetItem(clip, CPFORMAT_FILECONTENTS, &buf, &sz)) { + Warning("%s: CPClipboard_GetItem failed\n", __FUNCTION__); + return false; + } + + /* Extract file contents from buf. */ + xdrmem_create(&xdrs, (char *)buf, sz, XDR_DECODE); + memset(&fileContents, 0, sizeof fileContents); + + if (!xdr_CPFileContents(&xdrs, &fileContents)) { + Warning("%s: xdr_CPFileContents failed.\n", __FUNCTION__); + xdr_destroy(&xdrs); + return false; + } + xdr_destroy(&xdrs); + + contentsList = fileContents.CPFileContents_u.fileContentsV1; + if (!contentsList) { + Warning("%s: invalid contentsList.\n", __FUNCTION__); + goto exit; + } + + nFiles = contentsList->fileItem.fileItem_len; + if (0 == nFiles) { + Warning("%s: invalid nFiles.\n", __FUNCTION__); + goto exit; + } + + fileItem = contentsList->fileItem.fileItem_val; + if (!fileItem) { + Warning("%s: invalid fileItem.\n", __FUNCTION__); + goto exit; + } + + /* + * Write files into a temporary staging directory. These files will be moved + * to final destination, or deleted on next reboot. + */ + tempDir = DnD_CreateStagingDirectory(); + if (!tempDir) { + Warning("%s: DnD_CreateStagingDirectory failed.\n", __FUNCTION__); + goto exit; + } + + fileContentsList.clear(); + + for (i = 0; i < nFiles; i++) { + utf::string fileName; + utf::string filePathName; + VmTimeType createTime = -1; + VmTimeType accessTime = -1; + VmTimeType writeTime = -1; + VmTimeType attrChangeTime = -1; + + if (!fileItem[i].cpName.cpName_val || + 0 == fileItem[i].cpName.cpName_len) { + Warning("%s: invalid fileItem[%" FMTSZ "u].cpName.\n", __FUNCTION__, i); + goto exit; + } + + /* + * '\0' is used as directory separator in cross-platform name. Now turn + * '\0' in data into DIRSEPC. + * + * Note that we don't convert the final '\0' into DIRSEPC so the string + * is NUL terminated. + */ + CPNameUtil_CharReplace(fileItem[i].cpName.cpName_val, + fileItem[i].cpName.cpName_len - 1, + '\0', + DIRSEPC); + fileName = fileItem[i].cpName.cpName_val; + filePathName = tempDir; + filePathName += DIRSEPS + fileName; + + if ((fileItem[i].validFlags & CP_FILE_VALID_TYPE) && + CP_FILE_TYPE_DIRECTORY == fileItem[i].type) { + if (!File_CreateDirectory(filePathName.c_str())) { + goto exit; + } + g_debug("%s: created directory [%s].\n", + __FUNCTION__, filePathName.c_str()); + } else if ((fileItem[i].validFlags & CP_FILE_VALID_TYPE) && + CP_FILE_TYPE_REGULAR == fileItem[i].type) { + FileIODescriptor file; + FileIOResult fileErr; + + FileIO_Invalidate(&file); + + fileErr = FileIO_Open(&file, + filePathName.c_str(), + FILEIO_ACCESS_WRITE, + FILEIO_OPEN_CREATE_EMPTY); + if (!FileIO_IsSuccess(fileErr)) { + goto exit; + } + + fileErr = FileIO_Write(&file, + fileItem[i].content.content_val, + fileItem[i].content.content_len, + NULL); + + FileIO_Close(&file); + g_debug("%s: created file [%s].\n", __FUNCTION__, filePathName.c_str()); + } else { + /* + * Right now only Windows can provide CPFORMAT_FILECONTENTS data. + * Symlink file is not expected. Continue with next file if the + * type is not valid. + */ + continue; + } + + /* Update file time attributes. */ + createTime = (fileItem->validFlags & CP_FILE_VALID_CREATE_TIME) ? + fileItem->createTime: -1; + accessTime = (fileItem->validFlags & CP_FILE_VALID_ACCESS_TIME) ? + fileItem->accessTime: -1; + writeTime = (fileItem->validFlags & CP_FILE_VALID_WRITE_TIME) ? + fileItem->writeTime: -1; + attrChangeTime = (fileItem->validFlags & CP_FILE_VALID_CHANGE_TIME) ? + fileItem->attrChangeTime: -1; + + if (!File_SetTimes(filePathName.c_str(), + createTime, + accessTime, + writeTime, + attrChangeTime)) { + /* Not a critical error, only log it. */ + g_debug("%s: File_SetTimes failed with file [%s].\n", + __FUNCTION__, filePathName.c_str()); + } + + /* Update file permission attributes. */ + if (fileItem->validFlags & CP_FILE_VALID_PERMS) { + if (Posix_Chmod(filePathName.c_str(), + fileItem->permissions) < 0) { + /* Not a critical error, only log it. */ + g_debug("%s: Posix_Chmod failed with file [%s].\n", + __FUNCTION__, filePathName.c_str()); + } + } + + /* + * If there is no DIRSEPC inside the fileName, this file/directory is a + * top level one. We only put top level name into uri list. + */ + if (fileName.find(DIRSEPS, 0) == utf::string::npos) { + fileContentsList.push_back(filePathName); + } + } + g_debug("%s: created uri list\n", __FUNCTION__); + ret = true; + +exit: + xdr_free((xdrproc_t)xdr_CPFileContents, (char *)&fileContents); + if (tempDir && !ret) { + DnD_DeleteStagingFiles(tempDir, FALSE); + } + free(tempDir); + return ret; +} diff --git a/open-vm-tools/services/plugins/dndcp/copyPasteUIX11.cpp b/open-vm-tools/services/plugins/dndcp/copyPasteUIX11.cpp index 517ebe810..9f3491369 100644 --- a/open-vm-tools/services/plugins/dndcp/copyPasteUIX11.cpp +++ b/open-vm-tools/services/plugins/dndcp/copyPasteUIX11.cpp @@ -79,6 +79,7 @@ #include "file.h" #include "dnd.h" #include "dndMsg.h" +#include "copyPasteDnDUtil.h" extern "C" { #include "dndClipboard.h" @@ -1309,7 +1310,7 @@ CopyPasteUIX11::GetRemoteClipboardCB(const CPClipboard *clip) // IN if (CPClipboard_ItemExists(clip, CPFORMAT_FILECONTENTS)) { g_debug("%s: File contents data\n", __FUNCTION__); - if (LocalPrepareFileContents(clip)) { + if (LocalPrepareFileContents(clip, mHGFileContentsList)) { refClipboard->set(mListTargets, sigc::mem_fun(this, &CopyPasteUIX11::LocalGetFileContentsRequestCB), sigc::mem_fun(this, &CopyPasteUIX11::LocalClearClipboardCB)); @@ -1322,201 +1323,6 @@ CopyPasteUIX11::GetRemoteClipboardCB(const CPClipboard *clip) // IN } -/* - *---------------------------------------------------------------------------- - * - * CopyPasteUIX11::LocalPrepareFileContents -- - * - * Try to extract file contents from mClipboard. Write all files to a - * temporary staging directory. Construct uri list. - * - * Results: - * true if success, false otherwise. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------------- - */ - -bool -CopyPasteUIX11::LocalPrepareFileContents(const CPClipboard *clip) // IN -{ - void *buf = NULL; - size_t sz = 0; - XDR xdrs; - CPFileContents fileContents; - CPFileContentsList *contentsList = NULL; - size_t nFiles = 0; - CPFileItem *fileItem = NULL; - char *tempDir = NULL; - size_t i = 0; - bool ret = false; - - if (!CPClipboard_GetItem(clip, CPFORMAT_FILECONTENTS, &buf, &sz)) { - g_debug("%s: CPClipboard_GetItem failed\n", __FUNCTION__); - return false; - } - - /* Extract file contents from buf. */ - xdrmem_create(&xdrs, (char *)buf, sz, XDR_DECODE); - memset(&fileContents, 0, sizeof fileContents); - - if (!xdr_CPFileContents(&xdrs, &fileContents)) { - g_debug("%s: xdr_CPFileContents failed.\n", __FUNCTION__); - xdr_destroy(&xdrs); - return false; - } - xdr_destroy(&xdrs); - - contentsList = fileContents.CPFileContents_u.fileContentsV1; - if (!contentsList) { - g_debug("%s: invalid contentsList.\n", __FUNCTION__); - goto exit; - } - - nFiles = contentsList->fileItem.fileItem_len; - if (0 == nFiles) { - g_debug("%s: invalid nFiles.\n", __FUNCTION__); - goto exit; - } - - fileItem = contentsList->fileItem.fileItem_val; - if (!fileItem) { - g_debug("%s: invalid fileItem.\n", __FUNCTION__); - goto exit; - } - - /* - * Write files into a temporary staging directory. These files will be moved - * to final destination, or deleted on next reboot. - */ - tempDir = DnD_CreateStagingDirectory(); - if (!tempDir) { - g_debug("%s: DnD_CreateStagingDirectory failed.\n", __FUNCTION__); - goto exit; - } - - mHGFileContentsList.clear(); - - for (i = 0; i < nFiles; i++) { - utf::string fileName; - utf::string filePathName; - VmTimeType createTime = -1; - VmTimeType accessTime = -1; - VmTimeType writeTime = -1; - VmTimeType attrChangeTime = -1; - - if (!fileItem[i].cpName.cpName_val || - 0 == fileItem[i].cpName.cpName_len) { - g_debug("%s: invalid fileItem[%" FMTSZ "u].cpName.\n", __FUNCTION__, i); - goto exit; - } - - /* - * '\0' is used as directory separator in cross-platform name. Now turn - * '\0' in data into DIRSEPC. - * - * Note that we don't convert the final '\0' into DIRSEPC so the string - * is NUL terminated. - */ - CPNameUtil_CharReplace(fileItem[i].cpName.cpName_val, - fileItem[i].cpName.cpName_len - 1, - '\0', - DIRSEPC); - fileName = fileItem[i].cpName.cpName_val; - filePathName = tempDir; - filePathName += DIRSEPS + fileName; - - if (fileItem[i].validFlags & CP_FILE_VALID_TYPE && - CP_FILE_TYPE_DIRECTORY == fileItem[i].type) { - if (!File_CreateDirectory(filePathName.c_str())) { - goto exit; - } - g_debug("%s: created directory [%s].\n", - __FUNCTION__, filePathName.c_str()); - } else if (fileItem[i].validFlags & CP_FILE_VALID_TYPE && - CP_FILE_TYPE_REGULAR == fileItem[i].type) { - FileIODescriptor file; - FileIOResult fileErr; - - FileIO_Invalidate(&file); - - fileErr = FileIO_Open(&file, - filePathName.c_str(), - FILEIO_ACCESS_WRITE, - FILEIO_OPEN_CREATE_EMPTY); - if (!FileIO_IsSuccess(fileErr)) { - goto exit; - } - - fileErr = FileIO_Write(&file, - fileItem[i].content.content_val, - fileItem[i].content.content_len, - NULL); - - FileIO_Close(&file); - g_debug("%s: created file [%s].\n", __FUNCTION__, filePathName.c_str()); - } else { - /* - * Right now only Windows can provide CPFORMAT_FILECONTENTS data. - * Symlink file is not expected. Continue with next file if the - * type is not valid. - */ - continue; - } - - /* Update file time attributes. */ - createTime = fileItem->validFlags & CP_FILE_VALID_CREATE_TIME ? - fileItem->createTime: -1; - accessTime = fileItem->validFlags & CP_FILE_VALID_ACCESS_TIME ? - fileItem->accessTime: -1; - writeTime = fileItem->validFlags & CP_FILE_VALID_WRITE_TIME ? - fileItem->writeTime: -1; - attrChangeTime = fileItem->validFlags & CP_FILE_VALID_CHANGE_TIME ? - fileItem->attrChangeTime: -1; - - if (!File_SetTimes(filePathName.c_str(), - createTime, - accessTime, - writeTime, - attrChangeTime)) { - /* Not a critical error, only log it. */ - g_debug("%s: File_SetTimes failed with file [%s].\n", - __FUNCTION__, filePathName.c_str()); - } - - /* Update file permission attributes. */ - if (fileItem->validFlags & CP_FILE_VALID_PERMS) { - if (Posix_Chmod(filePathName.c_str(), - fileItem->permissions) < 0) { - /* Not a critical error, only log it. */ - g_debug("%s: Posix_Chmod failed with file [%s].\n", - __FUNCTION__, filePathName.c_str()); - } - } - - /* - * If there is no DIRSEPC inside the fileName, this file/directory is a - * top level one. We only put top level name into uri list. - */ - if (fileName.find(DIRSEPS, 0) == utf::string::npos) { - mHGFileContentsList.push_back(filePathName); - } - } - g_debug("%s: created uri list\n", __FUNCTION__); - ret = true; - -exit: - xdr_free((xdrproc_t)xdr_CPFileContents, (char *)&fileContents); - if (tempDir && !ret) { - DnD_DeleteStagingFiles(tempDir, FALSE); - } - free(tempDir); - return ret; -} - - /* *----------------------------------------------------------------------------- * diff --git a/open-vm-tools/services/plugins/dndcp/copyPasteUIX11.h b/open-vm-tools/services/plugins/dndcp/copyPasteUIX11.h index 28c3d8bf7..ebee86322 100644 --- a/open-vm-tools/services/plugins/dndcp/copyPasteUIX11.h +++ b/open-vm-tools/services/plugins/dndcp/copyPasteUIX11.h @@ -120,7 +120,6 @@ private: void LocalClipboardTimestampCB(const Gtk::SelectionData& sd); void LocalPrimTimestampCB(const Gtk::SelectionData& sd); void LocalReceivedFileListCB(const Gtk::SelectionData& selection_data); - bool LocalPrepareFileContents(const CPClipboard *clip); #endif void GetLocalFilesDone(bool success); void SendClipNotChanged(void); @@ -159,8 +158,8 @@ private: utf::string mHGTextData; std::string mHGRTFData; bool mGetTimestampOnly; - std::vector mHGFileContentsList; #endif + std::vector mHGFileContentsList; DND_FILE_TRANSFER_STATUS mHGGetFileStatus; bool mBlockAdded; diff --git a/open-vm-tools/services/plugins/dndcp/dndGuestBase/copyPasteDnDUtil.h b/open-vm-tools/services/plugins/dndcp/dndGuestBase/copyPasteDnDUtil.h new file mode 100644 index 000000000..8a1a34a03 --- /dev/null +++ b/open-vm-tools/services/plugins/dndcp/dndGuestBase/copyPasteDnDUtil.h @@ -0,0 +1,37 @@ +/********************************************************* + * Copyright (c) 2025 Broadcom. All Rights Reserved. + * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation version 2.1 and no later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + *********************************************************/ + +/** + * @file copyPasteDnDUtil.h + * + * Utility functions for Drag and Drop and Copy and Paste. + * + */ + +#ifndef COPYPASTE_DND_UTIL_H +#define COPYPASTE_DND_UTIL_H + +#include "dndClipboard.h" +#include +#include "stringxx/string.hh" + +bool LocalPrepareFileContents(const CPClipboard *clip, + std::vector& fileContentsList); + +#endif