]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Change to common source files not applicable to open-vm-tools at this time.
authorKruti Pendharkar <kp025370@broadcom.com>
Fri, 11 Jul 2025 12:48:15 +0000 (05:48 -0700)
committerKruti Pendharkar <kp025370@broadcom.com>
Fri, 11 Jul 2025 12:48:15 +0000 (05:48 -0700)
open-vm-tools/services/plugins/dndcp/Makefile.am
open-vm-tools/services/plugins/dndcp/copyPasteDnDUtil.cpp [new file with mode: 0644]
open-vm-tools/services/plugins/dndcp/copyPasteUIX11.cpp
open-vm-tools/services/plugins/dndcp/copyPasteUIX11.h
open-vm-tools/services/plugins/dndcp/dndGuestBase/copyPasteDnDUtil.h [new file with mode: 0644]

index 10390bf3e20185c69f5e01002f4a5ff19a9fceaf..5a864e7c065b4460f064d902e1beab1ccc34ec30 100644 (file)
@@ -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 (file)
index 0000000..6d2fbf2
--- /dev/null
@@ -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<utf::string>& 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;
+}
index 517ebe810a1b4a16d1447ecf699dc90ae5c8bac4..9f3491369c2366f5bc6ec0eae35a413875a08ce1 100644 (file)
@@ -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;
-}
-
-
 /*
  *-----------------------------------------------------------------------------
  *
index 28c3d8bf7727e31cd678481e1b96efd21da81b86..ebee86322a7a7911366504767f43148697f0df7d 100644 (file)
@@ -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<utf::string> mHGFileContentsList;
 #endif
+   std::vector<utf::string> 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 (file)
index 0000000..8a1a34a
--- /dev/null
@@ -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 <vector>
+#include "stringxx/string.hh"
+
+bool LocalPrepareFileContents(const CPClipboard *clip,
+                              std::vector<utf::string>& fileContentsList);
+
+#endif