]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Internal branch sync. Included in this change:
authorVMware, Inc <>
Mon, 20 Dec 2010 21:53:12 +0000 (13:53 -0800)
committerMarcelo Vanzin <mvanzin@vmware.com>
Mon, 20 Dec 2010 21:53:12 +0000 (13:53 -0800)
. VIX: try to use bash for starting processes on Solaris.

. VIX: escaping strings in XML VMAutomation responses.

. vmxnet: allow changing MAC address in FreeBSD.

. changes in shared code that don't affect open-vm-tools functionality.

Signed-off-by: Marcelo Vanzin <mvanzin@vmware.com>
open-vm-tools/lib/foundryMsg/foundryMsg.c
open-vm-tools/lib/include/vixCommands.h
open-vm-tools/lib/include/vm_version.h
open-vm-tools/lib/procMgr/procMgrPosix.c
open-vm-tools/modules/freebsd/vmxnet/if_vxn.c
open-vm-tools/services/plugins/vix/vixTools.c
open-vm-tools/services/plugins/vix/vixToolsInt.h

index 56930a26cbbef875c9e264519fe9565c60dda73b..8965b45a67a4d30ee9f1a5e8244618f930807fbf 100644 (file)
@@ -133,10 +133,8 @@ static const VixCommandInfo vixCommandInfoTable[] = {
                            VIX_COMMAND_CATEGORY_PRIVILEGED),
    VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_DELETE_VM,
                            VIX_COMMAND_CATEGORY_PRIVILEGED),
-   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_SYNCDRIVER_FREEZE,
-                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
-   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_SYNCDRIVER_THAW,
-                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
+   VIX_DEFINE_UNUSED_COMMAND,
+   VIX_DEFINE_UNUSED_COMMAND,
    VIX_DEFINE_UNUSED_COMMAND,
    VIX_DEFINE_UNUSED_COMMAND,
    VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_SET_GUEST_PRINTER,
index cb40ffaa5c9814012c0ab46edb1323d6a582b969..c6551cfa3984d9dd8e4d0a1eb28c22e8c2f1187b 100644 (file)
@@ -98,6 +98,7 @@ enum {
    VIX_REQUESTMSG_REQUIRES_INTERACTIVE_ENVIRONMENT    = 0x08,
    VIX_REQUESTMSG_INCLUDES_AUTH_DATA_V1               = 0x10,
    VIX_REQUESTMSG_REQUIRES_VMDB_NOTIFICATION          = 0x20,
+   VIX_REQUESTMSG_ESCAPE_XML_DATA                     = 0x40,
 };
 
 
@@ -2133,8 +2134,8 @@ enum {
    /* DEPRECATED VIX_COMMAND_CREATE_FLOPPY                    = 30, */
    VIX_COMMAND_RELOAD_VM                        = 31,
    VIX_COMMAND_DELETE_VM                        = 32,
-   VIX_COMMAND_SYNCDRIVER_FREEZE                = 33,
-   VIX_COMMAND_SYNCDRIVER_THAW                  = 34,
+   /* DEPRECATED VIX_COMMAND_SYNCDRIVER_FREEZE                = 33, */
+   /* DEPRECATED VIX_COMMAND_SYNCDRIVER_THAW                  = 34, */
    /* DEPRECATED VIX_COMMAND_HOT_ADD_DISK                     = 35, */
    /* DEPRECATED VIX_COMMAND_HOT_REMOVE_DISK                  = 36, */
    VIX_COMMAND_SET_GUEST_PRINTER                = 37,
@@ -2423,6 +2424,35 @@ enum VixRunProgramResultValues {
 #endif
 
 
+/*
+ * This is used to denote that the contents of a VIX XML-like response
+ * string has been escaped. Old Tools did not escape the contents.
+ * This tag is only used for existing commands that did not originally perform
+ * escaping. Any new command must always escape any strings passed in XML.
+ * See ListProcessesInGuest as an example.
+ * The protocol works as follows:
+ * 1) A client library that internally knows how to handle escaped XML opts in
+ *    by including the VIX_REQUESTMSG_ESCAPE_XML_DATA in relevent requests.
+ * 2) Tools that understands the VIX_REQUESTMSG_ESCAPE_XML_DATA flag sees that
+ *    it is set in the request, and then escapes all string data within the
+ *    XML response. To indicate to the client that it has understood the
+ *    request, it include the VIX_XML_ESCAPED_TAG in the response (at the
+ *    begining of the response).
+ * 3) When the client library receives the response, it searches for the
+ *    VIX_XML_ESCAPED_TAG. If it is present, it then unescapes all string
+ *    data in the response. If the tag is not present, the client library
+ *    assumes that the Tools did not understand VIX_REQUESTMSG_ESCAPE_XML_DATA
+ *    and that the string data is not escaped.
+ * The following characters are escaped: '<', '>', and '%'.
+ * For new commands (starting with those released in M/N for the vSphere
+ * guest ops project), the escaping is exactly the same, but the
+ * VIX_REQUESTMSG_ESCAPE_XML_DATA flag and the VIX_XML_ESCAPED_TAG are not
+ * used, since both ends expect escaping.
+ */
+#define VIX_XML_ESCAPED_TAG   "<escaped/>"
+
+#define VIX_XML_ESCAPE_CHARACTER '%'
+
 
 /*
  *-----------------------------------------------------------------------------
index fdc35d340d41d12f02eb1864748a915821d3a8f5..59af0ecd1bd51e8c80031cb41bda1d7a22b83ce3 100644 (file)
 
 #define USB_ARBITRATOR_VERSION_MAJOR 8
 #define USB_ARBITRATOR_VERSION_MINOR 2
-#define USB_ARBITRATOR_VERSION_Z     0
+#define USB_ARBITRATOR_VERSION_Z     2
 #define USB_ARBITRATOR_VERSION_BASE  USB_ARBITRATOR_VERSION_MAJOR.\
                                      USB_ARBITRATOR_VERSION_MINOR
 
  * USB Arbitrator Component version. This version is used by the linux
  * installer. See USB_ARBITRATOR_COMPONENT_VERSION_NUMBER in mk/defs-onetime.mk
  */
-#define USB_ARBITRATOR_COMPONENT_VERSION_NUMBER "8.2.0"
+#define USB_ARBITRATOR_COMPONENT_VERSION_NUMBER "8.2.2"
 
 #ifdef VMX86_VPX
 #define VIM_API_TYPE "VirtualCenter"
@@ -519,22 +519,4 @@ typedef enum {
    VMX_PLATFORM_MACOS,
 } VMX_Platform;
 
-
-/*
- * UI versions
- *
- * Note that these only make sense in the context of the server type
- */
-
-#define  UI_VERSION_OLD            1  // pre-versioned UIs
-#define  UI_VERSION_ESX15          2
-#define  UI_VERSION_GSX20          2
-#define  UI_VERSION_ESX20          3
-#define  UI_VERSION_GSX25          3
-// Skip one just in case we want to insert ESX21 in between here for neatness
-#define  UI_VERSION_GSX30          5
-#define  UI_VERSION_VMSERVER10     6
-
-#define  UI_VERSION                6  // Current UI version
-
 #endif /* VM_VERSION_H */
index cfac558b71e411c046bed56aab6869c132bc57df..45f905c34bff3a18fa2e843ad39d403148b47eab 100644 (file)
@@ -110,6 +110,10 @@ static Bool ProcMgrKill(pid_t pid,
                         int sig,
                         int timeout);
 
+#ifdef sun
+#define  SOLARIS_BASH_PATH "/usr/bin/bash"
+#endif
+
 #if defined(linux) && !defined(GLIBC_VERSION_23)
 /*
  * Implements the system calls (they are not wrapped by glibc til 2.3.2).
@@ -652,8 +656,40 @@ ProcMgrStartProcess(char const *cmd,            // IN: UTF-8 encoded cmd
    if (pid == -1) {
       Warning("Unable to fork: %s.\n\n", strerror(errno));
    } else if (pid == 0) {
+#ifdef sun
+      /*
+       * On Solaris, /bin/sh is the Bourne shell, and it
+       * doesn't appear to have the optimization that bash does -- when
+       * called with -c, bash appears to just use exec() to replace itself.
+       * Bourne shell does a fork & exec, so 2 processes are started.
+       * This is bad for us because we then see the PID of the shell, not the
+       * app that it starts.  When this PID is returned to a user to
+       * watch, they'll watch the wrong process.
+       *
+       * So for Solaris, use bash instead if possible.  We support
+       * Solaris 10 and better; it contains bash, but not in its
+       * minimal 'core' package, so it may not exist.
+       */
+      static const char bashShellPath[] = SOLARIS_BASH_PATH;
+      char *bashArgs[] = { "bash", "-c", cmdCurrent, NULL };
+      static const char bourneShellPath[] = "/bin/sh";
+      char *bourneArgs[] = { "sh", "-c", cmdCurrent, NULL };
+      const char *shellPath;
+      char **args;
+#else
       static const char shellPath[] = "/bin/sh";
       char *args[] = { "sh", "-c", cmdCurrent, NULL };
+#endif
+
+#ifdef sun
+      if (File_Exists(SOLARIS_BASH_PATH)) {
+         shellPath = bashShellPath;
+         args = bashArgs;
+      } else {
+         shellPath = bourneShellPath;
+         args = bourneArgs;
+      }
+#endif
 
       /*
        * Child
index cd1f78f1657cddd8966ce79a11f209b65bb19af0..fe1f087aa286d3cce869a91bf37365880ffd9a12 100644 (file)
@@ -104,6 +104,7 @@ typedef struct vxn_softc {
    struct arpcom            arpcom;
 #else
    struct ifnet            *vxn_ifp;
+   struct ifmedia           media;
 #endif
 #ifdef VXN_MPSAFE
    struct mtx               vxn_mtx;
@@ -217,6 +218,93 @@ vxn_execute_4(const vxn_softc_t *sc,       /* IN: adapter */
                            VMXNET_COMMAND_ADDR);
 }
 
+static int
+vxn_check_link(vxn_softc_t *sc)
+{
+   uint32 status;
+   int ok;
+
+   status = bus_space_read_4(sc->vxn_iobtag, sc->vxn_iobhandle, VMXNET_STATUS_ADDR);
+   ok = (status & VMXNET_STATUS_CONNECTED) != 0;
+   return ok;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vxn_media_status --
+ *
+ *      This routine is called when the user quries the status of interface
+ *      using ifconfig. Checks link state and updates media state accorgingly.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+vxn_media_status(struct ifnet * ifp, struct ifmediareq * ifmr)
+{
+   vxn_softc_t *sc = ifp->if_softc;
+   int connected = 0;
+
+   VXN_LOCK((vxn_softc_t *)ifp->if_softc);
+   connected = vxn_check_link(sc);
+
+   ifmr->ifm_status = IFM_AVALID;
+   ifmr->ifm_active = IFM_ETHER;
+
+   if (!connected) {
+      ifmr->ifm_status &= ~IFM_ACTIVE;
+      VXN_UNLOCK((vxn_softc_t *)ifp->if_softc);
+      return;
+   }
+
+   ifmr->ifm_status |= IFM_ACTIVE;
+
+   VXN_UNLOCK((vxn_softc_t *)ifp->if_softc);
+   return;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vxn_media_change --
+ *
+ *      This routine is called when the user changes speed/duplex using
+ *      media/mediopt option with ifconfig.
+ *
+ * Results:
+ *      Returns 0 for success, error code otherwise.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+vxn_media_change(struct ifnet * ifp)
+{
+   vxn_softc_t *sc = ifp->if_softc;
+   struct ifmedia *ifm = &sc->media;
+
+   if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
+      return (EINVAL);
+
+   if (IFM_SUBTYPE(ifm->ifm_media) != IFM_AUTO)
+      printf("Media subtype is not AUTO, it is : %d.\n",
+             IFM_SUBTYPE(ifm->ifm_media));
+
+   return (0);
+}
+
+
 /*
  *-----------------------------------------------------------------------------
  * vxn_attach --
@@ -393,7 +481,8 @@ vxn_attach(device_t dev)
     * read the MAC address from the device
     */
    for (i = 0; i < 6; i++) {
-      mac[i] = bus_space_read_1(sc->vxn_iobtag, sc->vxn_iobhandle, VMXNET_MAC_ADDR + i);
+      mac[i] = bus_space_read_1(sc->vxn_iobtag, sc->vxn_iobhandle, VMXNET_MAC_ADDR
+                                + i);
    }
 
 #ifdef VXN_NEEDARPCOM
@@ -414,9 +503,22 @@ vxn_attach(device_t dev)
           sc->vxn_num_tx_bufs, (int)sizeof(Vmxnet2_TxRingEntry),
           driverDataSize);
 
+   /*
+    * Specify the media types supported by this adapter and register
+    * callbacks to update media and link information
+    */
+   ifmedia_init(&sc->media, IFM_IMASK, vxn_media_change,
+                vxn_media_status);
+   ifmedia_add(&sc->media, IFM_ETHER | IFM_FDX, 0, NULL);
+   ifmedia_add(&sc->media, IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL);
+   ifmedia_add(&sc->media, IFM_ETHER | IFM_1000_T, 0, NULL);
+   ifmedia_add(&sc->media, IFM_ETHER | IFM_AUTO, 0, NULL);
+   ifmedia_set(&sc->media, IFM_ETHER | IFM_AUTO);
+
+
    goto done;
 
-  fail:
+fail:
 
    if (sc->vxn_intrhand != NULL) {
       bus_teardown_intr(dev, sc->vxn_irq, sc->vxn_intrhand);
@@ -468,8 +570,7 @@ vxn_detach(device_t dev)
    sc = device_get_softc(dev);
 
    ifp = VXN_SC2IFP(sc);
-
-   if (device_get_state(dev) >= DS_ATTACHED) {
+   if (device_is_attached(dev)) {
       vxn_stop(sc);
       /*
        * detach from stack
@@ -689,7 +790,8 @@ vxn_initl(vxn_softc_t *sc)
 {
    Vmxnet2_DriverData *dd = sc->vxn_dd;
    struct ifnet *ifp = VXN_SC2IFP(sc);
-   uint32 r;
+   uint32 r, i;
+   u_char mac_addr[6];
 
    VXN_LOCK_ASSERT(sc);
 
@@ -702,6 +804,28 @@ vxn_initl(vxn_softc_t *sc)
          return;
       }
 
+      /* Get MAC address from interface and set it in hardware */
+#if __FreeBSD_version >= 700000
+      printf("addrlen : %d. \n", ifp->if_addrlen);
+      bcopy(LLADDR((struct sockaddr_dl *)ifp->if_addr->ifa_addr), mac_addr,
+            ifp->if_addrlen > 6 ? 6 : ifp->if_addrlen);
+#else
+      if (!ifaddr_byindex(ifp->if_index)) {
+         printf("vxn:%d Invalid link address, interface index :%d.\n",
+                VXN_IF_UNIT(ifp), ifp->if_index);
+      } else {
+         bcopy(LLADDR((struct sockaddr_dl *)ifaddr_byindex(ifp->if_index)->ifa_addr),
+               mac_addr, ifp->if_addrlen);
+      }
+#endif
+      printf("vxn%d: MAC Address : %02x:%02x:%02x:%02x:%02x:%02x \n",
+             VXN_IF_UNIT(ifp), mac_addr[0], mac_addr[1], mac_addr[2],
+             mac_addr[3], mac_addr[4], mac_addr[5]);
+      for (i = 0; i < 6; i++) {
+         bus_space_write_1(sc->vxn_iobtag, sc->vxn_iobhandle, VMXNET_MAC_ADDR +
+                           i, mac_addr[i]);
+      }
+
       /*
        * Start hardware
        */
@@ -1008,6 +1132,10 @@ vxn_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
       error = 0;
       break;
 
+   case SIOCSIFMEDIA:
+   case SIOCGIFMEDIA:
+      ifmedia_ioctl(ifp, (struct ifreq *)data, &sc->media, command);
+
    default:
       error = EINVAL;
       break;
index bcbadd946fe0ff2dfa3c5c2bddca01760aa3d620..37c9be14580655248cc6836358dd8c337ad53c31 100644 (file)
@@ -92,6 +92,7 @@
 #include "unicode.h"
 #include "hashTable.h"
 #include "su.h"
+#include "escape.h"
 
 #if defined(linux) || defined(_WIN32)
 #include "netutil.h"
@@ -292,6 +293,7 @@ static gboolean VixToolsMonitorStartProgram(void *clientData);
 
 static void VixToolsPrintFileInfo(const char *filePathName,
                                   char *fileName,
+                                  Bool escapeStrs,
                                   char **destPtr,
                                   char *endDestPtr);
 
@@ -395,6 +397,14 @@ static VixError VixToolsListProcesses(VixCommandRequestHeader *requestMsg,
                                       size_t maxBufferSize,
                                       char **result);
 
+static VixError VixToolsPrintProcInfoEx(DynBuf *dstBuffer,
+                                        const char *name,
+                                        uint64 pid,
+                                        const char *user,
+                                        int start,
+                                        int exitCode,
+                                        int exitTime);
+
 static VixError VixToolsListDirectory(VixCommandRequestHeader *requestMsg,
                                       size_t maxBufferSize,
                                       char **result);
@@ -428,6 +438,17 @@ static VixError VixToolsProcessHgfsPacket(VixCommandHgfsSendPacket *requestMsg,
 static VixError VixToolsListFileSystems(VixCommandRequestHeader *requestMsg,
                                         char **result);
 
+#if defined(_WIN32) || defined(linux)
+static VixError VixToolsPrintFileSystemInfo(char **destPtr,
+                                            const char *endDestPtr,
+                                            const char *name,
+                                            uint64 size,
+                                            uint64 freeSpace,
+                                            const char *type,
+                                            Bool escapeStrs,
+                                            Bool *truncated);
+#endif
+
 static VixError VixToolsValidateCredentials(VixCommandRequestHeader *requestMsg);
 
 static VixError VixToolsAcquireCredentials(VixCommandRequestHeader *requestMsg,
@@ -486,6 +507,8 @@ static void VixToolsFreeEnvp(char **envp);
 static VixError VixToolsRewriteError(uint32 opCode,
                                      VixError origError);
 
+static size_t VixToolsXMLStringEscapedLen(const char *str, Bool escapeStr);
+
 
 /*
  *-----------------------------------------------------------------------------
@@ -3447,12 +3470,34 @@ VixToolsGetMultipleEnvVarsForUser(void *userToken,       // IN
       value = VixToolsGetEnvFromUserEnvironment(env, names);
       if (NULL != value) {
          char *tmp = resultLocal;
+         char *tmpVal;
+         char *escapedName;
+
+         escapedName = VixToolsEscapeXMLString(names);
+         if (NULL == escapedName) {
+            err = VIX_E_OUT_OF_MEMORY;
+            goto loopCleanup;
+         }
+
+         tmpVal = VixToolsEscapeXMLString(value);
+         if (NULL == tmpVal) {
+            err = VIX_E_OUT_OF_MEMORY;
+            goto loopCleanup;
+         }
+         free(value);
+         value = tmpVal;
+
          resultLocal = Str_Asprintf(NULL, "%s<ev>%s=%s</ev>",
-                                    tmp, names, value);
+                                    tmp, escapedName, value);
          free(tmp);
-         free(value);
          if (NULL == resultLocal) {
             err = VIX_E_OUT_OF_MEMORY;
+         }
+
+      loopCleanup:
+         free(value);
+         free(escapedName);
+         if (VIX_OK != err) {
             goto abort;
          }
       }
@@ -3461,9 +3506,11 @@ VixToolsGetMultipleEnvVarsForUser(void *userToken,       // IN
    }
 
    *result = resultLocal;
+   resultLocal = NULL;
    err = VIX_OK;
 
 abort:
+   free(resultLocal);
    VixToolsDestroyUserEnvironment(env);
 
    return err;
@@ -3512,6 +3559,16 @@ VixToolsGetAllEnvVarsForUser(void *userToken,     // IN
 
    while ((envVar = VixToolsGetNextEnvVar(itr)) != NULL) {
       char *tmp = resultLocal;
+      char *tmpVal;
+
+      tmpVal = VixToolsEscapeXMLString(envVar);
+      free(envVar);
+      if (NULL == tmpVal) {
+         err = VIX_E_OUT_OF_MEMORY;
+         goto abort;
+      }
+      envVar = tmpVal;
+
       resultLocal = Str_Asprintf(NULL, "%s<ev>%s</ev>", tmp, envVar);
       free(tmp);
       free(envVar);
@@ -4153,7 +4210,7 @@ VixToolsListProcesses(VixCommandRequestHeader *requestMsg, // IN
                       char **result)                       // OUT
 {
    VixError err = VIX_OK;
-   int index;
+   int i;
    static char resultBuffer[GUESTMSG_MAX_IN_SIZE];
    ProcMgr_ProcList *procList = NULL;
    char *destPtr;
@@ -4162,6 +4219,9 @@ VixToolsListProcesses(VixCommandRequestHeader *requestMsg, // IN
    size_t procBufSize;
    Bool impersonatingVMWareUser = FALSE;
    void *userToken = NULL;
+   Bool escapeStrs;
+   char *escapedName = NULL;
+   char *escapedUser = NULL;
 
    ASSERT(maxBufferSize <= GUESTMSG_MAX_IN_SIZE);
 
@@ -4174,6 +4234,9 @@ VixToolsListProcesses(VixCommandRequestHeader *requestMsg, // IN
    }
    impersonatingVMWareUser = TRUE;
 
+   escapeStrs = (requestMsg->requestFlags &
+                 VIX_REQUESTMSG_ESCAPE_XML_DATA) != 0;
+
    procList = ProcMgr_ListProcesses();
    if (NULL == procList) {
       err = FoundryToolsDaemon_TranslateSystemErr();
@@ -4181,26 +4244,62 @@ VixToolsListProcesses(VixCommandRequestHeader *requestMsg, // IN
    }
 
    endDestPtr = resultBuffer + maxBufferSize;
-   for (index = 0; index < procList->procCount; index++) {
+
+   if (escapeStrs) {
+      destPtr += Str_Sprintf(destPtr, endDestPtr - destPtr, "%s",
+                             VIX_XML_ESCAPED_TAG);
+   }
+
+   for (i = 0; i < procList->procCount; i++) {
+      const char *name;
+      const char *user;
+
+      if (escapeStrs) {
+         name = escapedName =
+            VixToolsEscapeXMLString(procList->procCmdList[i]);
+         if (NULL == escapedName) {
+            err = VIX_E_OUT_OF_MEMORY;
+            goto abort;
+         }
+      } else {
+         name = procList->procCmdList[i];
+      }
+
+      if ((NULL != procList->procOwnerList) &&
+          (NULL != procList->procOwnerList[i])) {
+         if (escapeStrs) {
+            user = escapedUser =
+               VixToolsEscapeXMLString(procList->procOwnerList[i]);
+            if (NULL == escapedUser) {
+               err = VIX_E_OUT_OF_MEMORY;
+               goto abort;
+            }
+         } else {
+            user = procList->procOwnerList[i];
+         }
+      } else {
+         user = "";
+      }
+
       procBufPtr = Str_Asprintf(&procBufSize,
                              "<proc><name>%s</name><pid>%d</pid>"
 #if defined(_WIN32)
                              "<debugged>%d</debugged>"
 #endif
                              "<user>%s</user><start>%d</start></proc>",
-                             procList->procCmdList[index],
-                             (int) procList->procIdList[index],
+                             name,
+                             (int) procList->procIdList[i],
 #if defined(_WIN32)
-                             (int) procList->procDebugged[index],
+                             (int) procList->procDebugged[i],
 #endif
-                             (NULL == procList->procOwnerList
-                               || NULL == procList->procOwnerList[index])
-                                 ? ""
-                                 : procList->procOwnerList[index],
+                             user,
                              (NULL == procList->startTime)
                                  ? 0
-                                 : (int) procList->startTime[index]);
-
+                                 : (int) procList->startTime[i]);
+      if (NULL == procBufPtr) {
+         err = VIX_E_OUT_OF_MEMORY;
+         goto abort;
+      }
       if ((destPtr + procBufSize) < endDestPtr) {
          destPtr += Str_Sprintf(destPtr, endDestPtr - destPtr,
                                 "%s", procBufPtr);
@@ -4210,6 +4309,10 @@ VixToolsListProcesses(VixCommandRequestHeader *requestMsg, // IN
          goto abort;
       }
       free(procBufPtr);
+      free(escapedName);
+      escapedName = NULL;
+      free(escapedUser);
+      escapedUser = NULL;
    }
 
 abort:
@@ -4218,6 +4321,8 @@ abort:
    }
    VixToolsLogoutUser(userToken);
    ProcMgr_FreeProcList(procList);
+   free(escapedName);
+   free(escapedUser);
 
    *result = resultBuffer;
 
@@ -4308,20 +4413,13 @@ VixToolsListProcessesExGenerateData(uint32 numPids,          // IN
                                     size_t *resultSize,      // OUT
                                     char **resultBuffer)     // OUT
 {
-   int i;
-   int j;
    VixError err = VIX_OK;
-   char *procBufPtr = NULL;
-   size_t procBufSize;
    ProcMgr_ProcList *procList = NULL;
    DynBuf dynBuffer;
    VixToolsExitedProgramState *epList;
+   int i;
+   int j;
    Bool bRet;
-   static const char *procInfoFormatString =
-                                 "<proc><name>%s</name><pid>%"FMT64"d</pid>"
-                                 "<user>%s</user><start>%d</start>"
-                                 "<eCode>%d</eCode><eTime>%d</eTime>"
-                                 "</proc>";
 
    DynBuf_Init(&dynBuffer);
 
@@ -4342,18 +4440,14 @@ VixToolsListProcessesExGenerateData(uint32 numPids,          // IN
          epList = exitedProcessList;
          while (epList) {
             if (pids[i] == epList->pid) {
-               procBufPtr = Str_Asprintf(&procBufSize,
-                                         procInfoFormatString,
-                                         epList->fullCommandLine,
-                                         epList->pid,
-                                         epList->user,
-                                         (int) epList->startTime,
-                                         epList->exitCode,
-                                         (int) epList->endTime);
-               bRet = DynBuf_Append(&dynBuffer, procBufPtr, procBufSize);
-               free(procBufPtr);
-               if (!bRet) {
-                  err = VIX_E_OUT_OF_MEMORY;
+               err = VixToolsPrintProcInfoEx(&dynBuffer,
+                                             epList->fullCommandLine,
+                                             epList->pid,
+                                             epList->user,
+                                             (int) epList->startTime,
+                                             epList->exitCode,
+                                             (int) epList->endTime);
+               if (VIX_OK != err) {
                   goto abort;
                }
             }
@@ -4363,18 +4457,14 @@ VixToolsListProcessesExGenerateData(uint32 numPids,          // IN
    } else {
       epList = exitedProcessList;
       while (epList) {
-         procBufPtr = Str_Asprintf(&procBufSize,
-                                   procInfoFormatString,
-                                   epList->fullCommandLine,
-                                   epList->pid,
-                                   epList->user,
-                                   (int) epList->startTime,
-                                   epList->exitCode,
-                                   (int) epList->endTime);
-         bRet = DynBuf_Append(&dynBuffer, procBufPtr, procBufSize);
-         free(procBufPtr);
-         if (!bRet) {
-            err = VIX_E_OUT_OF_MEMORY;
+         err = VixToolsPrintProcInfoEx(&dynBuffer,
+                                       epList->fullCommandLine,
+                                       epList->pid,
+                                       epList->user,
+                                       (int) epList->startTime,
+                                       epList->exitCode,
+                                       (int) epList->endTime);
+         if (VIX_OK != err) {
             goto abort;
          }
          epList = epList->next;
@@ -4396,22 +4486,16 @@ VixToolsListProcessesExGenerateData(uint32 numPids,          // IN
                continue;
             }
             if (pids[i] == procList->procIdList[j]) {
-               procBufPtr = Str_Asprintf(&procBufSize,
-                                         procInfoFormatString,
-                                         procList->procCmdList[j],
-                                         (uint64) procList->procIdList[j],
-                                         (NULL == procList->procOwnerList
-                                           || NULL == procList->procOwnerList[j])
-                                             ? ""
-                                             : procList->procOwnerList[j],
-                                         (NULL == procList->startTime)
-                                             ? 0
-                                             : (int) procList->startTime[j],
-                                             0, 0);      // eCode, eTime
-               bRet = DynBuf_Append(&dynBuffer, procBufPtr, procBufSize);
-               free(procBufPtr);
-               if (!bRet) {
-                  err = VIX_E_OUT_OF_MEMORY;
+               err = VixToolsPrintProcInfoEx(&dynBuffer,
+                                             procList->procCmdList[i],
+                                             procList->procIdList[i],
+                                             (NULL == procList->procOwnerList
+                                              || NULL == procList->procOwnerList[i])
+                                             ? "" : procList->procOwnerList[i],
+                                             (NULL == procList->startTime)
+                                             ? 0 : (int) procList->startTime[i],
+                                             0, 0);
+               if (VIX_OK != err) {
                   goto abort;
                }
             }
@@ -4423,22 +4507,16 @@ VixToolsListProcessesExGenerateData(uint32 numPids,          // IN
          if (VixToolsFindExitedProgramState(procList->procIdList[i])) {
             continue;
          }
-         procBufPtr = Str_Asprintf(&procBufSize,
-                                   procInfoFormatString,
-                                   procList->procCmdList[i],
-                                   (uint64) procList->procIdList[i],
-                                   (NULL == procList->procOwnerList
-                                     || NULL == procList->procOwnerList[i])
-                                       ? ""
-                                       : procList->procOwnerList[i],
-                                   (NULL == procList->startTime)
-                                       ? 0
-                                       : (int) procList->startTime[i],
-                                    0, 0);      // eCode, eTime
-         bRet = DynBuf_Append(&dynBuffer, procBufPtr, procBufSize);
-         free(procBufPtr);
-         if (!bRet) {
-            err = VIX_E_OUT_OF_MEMORY;
+         err = VixToolsPrintProcInfoEx(&dynBuffer,
+                                       procList->procCmdList[i],
+                                       procList->procIdList[i],
+                                       (NULL == procList->procOwnerList
+                                        || NULL == procList->procOwnerList[i])
+                                       ? "" : procList->procOwnerList[i],
+                                       (NULL == procList->startTime)
+                                       ? 0 : (int) procList->startTime[i],
+                                       0, 0);
+         if (VIX_OK != err) {
             goto abort;
          }
       }
@@ -4481,6 +4559,7 @@ abort:
  *
  *-----------------------------------------------------------------------------
  */
+
 static Bool
 VixToolsGetUserName(wchar_t **userName)                     // OUT
 {
@@ -4755,6 +4834,80 @@ abort:
 } // VixToolsListProcessesEx
 
 
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VixToolsPrintProcInfoEx --
+ *
+ *      Appends a single process entry to the XML-like string starting at
+ *      *destPtr.
+ *
+ * Results:
+ *      VixError
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static VixError
+VixToolsPrintProcInfoEx(DynBuf *dstBuffer,             // IN/OUT
+                        const char *name,              // IN
+                        uint64 pid,                    // IN
+                        const char *user,              // IN
+                        int start,                     // IN
+                        int exitCode,                  // IN
+                        int exitTime)                  // IN
+{
+   VixError err;
+   char *escapedName;
+   char *escapedUser = NULL;
+   size_t bytesPrinted;
+   char *procInfoEntry;
+   Bool success;
+
+   escapedName = VixToolsEscapeXMLString(name);
+   if (NULL == escapedName) {
+      err = VIX_E_OUT_OF_MEMORY;
+      goto abort;
+   }
+
+   escapedUser = VixToolsEscapeXMLString(user);
+   if (NULL == escapedUser) {
+      err = VIX_E_OUT_OF_MEMORY;
+      goto abort;
+   }
+
+   procInfoEntry = Str_Asprintf(&bytesPrinted,
+                                "<proc><name>%s</name><pid>%"FMT64"d</pid>"
+                                "<user>%s</user><start>%d</start>"
+                                "<eCode>%d</eCode><eTime>%d</eTime>"
+                                "</proc>",
+                                escapedName, pid, escapedUser, start, exitCode,
+                                exitTime);
+   if (NULL == procInfoEntry) {
+      err = VIX_E_OUT_OF_MEMORY;
+      goto abort;
+   }
+
+   success = DynBuf_Append(dstBuffer, procInfoEntry, bytesPrinted);
+   free(procInfoEntry);
+   if (!success) {
+      err = VIX_E_OUT_OF_MEMORY;
+      goto abort;
+   }
+
+   err = VIX_OK;
+
+abort:
+   free(escapedName);
+   free(escapedUser);
+
+   return err;
+}
+
+
 /*
  *-----------------------------------------------------------------------------
  *
@@ -4991,6 +5144,7 @@ VixToolsListDirectory(VixCommandRequestHeader *requestMsg,    // IN
    Bool isLegacyFormat;
    VMAutomationRequestParser parser;
    int dirPathLen;
+   Bool escapeStrs;
 
    legacyListRequest = (VixMsgSimpleFileRequest *) requestMsg;
    if (legacyListRequest->fileOptions & VIX_LIST_DIRECTORY_USE_OFFSET) {
@@ -5039,6 +5193,9 @@ VixToolsListDirectory(VixCommandRequestHeader *requestMsg,    // IN
    }
    impersonatingVMWareUser = TRUE;
 
+   escapeStrs = (requestMsg->requestFlags &
+                 VIX_REQUESTMSG_ESCAPE_XML_DATA) != 0;
+
    if (!(File_IsDirectory(dirPathName))) {
       err = VIX_E_NOT_A_DIRECTORY;
       goto abort;
@@ -5055,6 +5212,9 @@ VixToolsListDirectory(VixCommandRequestHeader *requestMsg,    // IN
     * max number of entries we can store.
     */
    resultBufferSize = 3; // truncation bool + space + '\0'
+   if (escapeStrs) {
+      resultBufferSize += strlen(VIX_XML_ESCAPED_TAG);
+   }
    lastGoodResultBufferSize = resultBufferSize;
    ASSERT_NOT_IMPLEMENTED(lastGoodResultBufferSize < maxBufferSize);
    formatStringLength = strlen(fileInfoFormatString);
@@ -5063,7 +5223,8 @@ VixToolsListDirectory(VixCommandRequestHeader *requestMsg,    // IN
       currentFileName = fileNameList[fileNum];
 
       resultBufferSize += formatStringLength;
-      resultBufferSize += strlen(currentFileName);
+      resultBufferSize += VixToolsXMLStringEscapedLen(currentFileName,
+                                                      escapeStrs);
       resultBufferSize += 2; // DIRSEPC chars
       resultBufferSize += 10 + 20 + 20; // properties + size + modTime
 
@@ -5104,6 +5265,11 @@ VixToolsListDirectory(VixCommandRequestHeader *requestMsg,    // IN
       }
    }
 
+   if (escapeStrs) {
+      destPtr += Str_Sprintf(destPtr, endDestPtr - destPtr, "%s",
+                             VIX_XML_ESCAPED_TAG);
+   }
+
    for (fileNum = offset; fileNum < lastGoodNumFiles; fileNum++) {
       /* File_ListDirectory never returns "." or ".." */
       char *pathName;
@@ -5113,7 +5279,8 @@ VixToolsListDirectory(VixCommandRequestHeader *requestMsg,    // IN
       pathName = Str_SafeAsprintf(NULL, "%s%s%s", dirPathName, DIRSEPS,
                                   currentFileName);
 
-      VixToolsPrintFileInfo(pathName, currentFileName, &destPtr, endDestPtr);
+      VixToolsPrintFileInfo(pathName, currentFileName, escapeStrs, &destPtr,
+                            endDestPtr);
 
       free(pathName);
    } // for (fileNum = 0; fileNum < lastGoodNumFiles; fileNum++)
@@ -5465,13 +5632,14 @@ VixToolsGetFileExtendedInfoLength(const char *filePathName,   // IN
       char *symlinkTarget;
       symlinkTarget = Posix_ReadLink(filePathName);
       if (NULL != symlinkTarget) {
-         fileExtendedInfoBufferSize += strlen(symlinkTarget);
+         fileExtendedInfoBufferSize +=
+            VixToolsXMLStringEscapedLen(symlinkTarget, TRUE);
       }
       free(symlinkTarget);
    }
 #endif
 
-   fileExtendedInfoBufferSize += strlen(fileName);
+   fileExtendedInfoBufferSize += VixToolsXMLStringEscapedLen(fileName, TRUE);
 
    return fileExtendedInfoBufferSize;
 }
@@ -5549,7 +5717,7 @@ VixToolsGetFileInfo(VixCommandRequestHeader *requestMsg,    // IN
     * Print the result buffer
     */
    destPtr = resultBuffer;
-   VixToolsPrintFileInfo(filePathName, "", &destPtr, resultBuffer + resultBufferSize);
+   VixToolsPrintFileInfo(filePathName, "", FALSE, &destPtr, resultBuffer + resultBufferSize);
 
 abort:
    if (impersonatingVMWareUser) {
@@ -5833,12 +6001,14 @@ abort:
 static void
 VixToolsPrintFileInfo(const char *filePathName,     // IN
                       char *fileName,               // IN
-                      char **destPtr,               // IN
-                      char *endDestPtr)             // OUT
+                      Bool escapeStrs,              // IN
+                      char **destPtr,               // IN/OUT
+                      char *endDestPtr)             // IN
 {
    int64 fileSize = 0;
    int64 modTime;
    int32 fileProperties = 0;
+   char *escapedFileName = NULL;
 
    modTime = File_GetModTime(filePathName);
    if (File_IsDirectory(filePathName)) {
@@ -5852,6 +6022,11 @@ VixToolsPrintFileInfo(const char *filePathName,     // IN
       }
    }
 
+   if (escapeStrs) {
+      fileName = escapedFileName = VixToolsEscapeXMLString(fileName);
+      ASSERT_MEM_ALLOC(NULL != escapedFileName);
+   }
+
    *destPtr += Str_Sprintf(*destPtr, 
                            endDestPtr - *destPtr, 
                            fileInfoFormatString,
@@ -5859,6 +6034,7 @@ VixToolsPrintFileInfo(const char *filePathName,     // IN
                            fileProperties,
                            fileSize,
                            modTime);
+   free(escapedFileName);
 } // VixToolsPrintFileInfo
 
 
@@ -5879,8 +6055,8 @@ VixToolsPrintFileInfo(const char *filePathName,     // IN
 static void
 VixToolsPrintFileExtendedInfo(const char *filePathName,     // IN
                               const char *fileName,         // IN
-                              char **destPtr,               // IN
-                              char *endDestPtr)             // OUT
+                              char **destPtr,               // IN/OUT
+                              char *endDestPtr)             // IN
 {
 #if defined(_WIN32) || defined(linux)
    int64 fileSize = 0;
@@ -5897,8 +6073,10 @@ VixToolsPrintFileExtendedInfo(const char *filePathName,     // IN
    int ownerId = 0;
    int groupId = 0;
    char *symlinkTarget = NULL;
+   char *tmp;
 #endif
    struct stat statbuf;
+   char *escapedFileName = NULL;
 
    /*
     * First check for symlink -- File_IsDirectory() will lie
@@ -5927,6 +6105,11 @@ VixToolsPrintFileExtendedInfo(const char *filePathName,     // IN
    if (NULL == symlinkTarget) {
       symlinkTarget = Util_SafeStrdup("");
    }
+
+   tmp = VixToolsEscapeXMLString(symlinkTarget);
+   ASSERT_MEM_ALLOC(NULL != tmp);
+   free(symlinkTarget);
+   symlinkTarget = tmp;
 #endif
 
 #ifdef _WIN32
@@ -5961,11 +6144,14 @@ VixToolsPrintFileExtendedInfo(const char *filePathName,     // IN
             __FUNCTION__, filePathName, errno);
    }
 
+   escapedFileName = VixToolsEscapeXMLString(fileName);
+   ASSERT_MEM_ALLOC(NULL != escapedFileName);
+
 #ifdef _WIN32
    *destPtr += Str_Sprintf(*destPtr,
                            endDestPtr - *destPtr,
                            fileExtendedInfoWindowsFormatString,
-                           fileName,
+                           escapedFileName,
                            fileProperties,
                            fileSize,
                            modTime,
@@ -5977,7 +6163,7 @@ VixToolsPrintFileExtendedInfo(const char *filePathName,     // IN
    *destPtr += Str_Sprintf(*destPtr,
                            endDestPtr - *destPtr,
                            fileExtendedInfoLinuxFormatString,
-                           fileName,
+                           escapedFileName,
                            fileProperties,
                            fileSize,
                            modTime,
@@ -5988,6 +6174,7 @@ VixToolsPrintFileExtendedInfo(const char *filePathName,     // IN
                            symlinkTarget);
    free(symlinkTarget);
 #endif
+   free(escapedFileName);
 #endif   // defined(_WIN32) || defined(linux)
 } // VixToolsPrintFileExtendedInfo
 
@@ -6026,8 +6213,8 @@ VixToolsPrintFileExtendedInfoEx(const char *filePathName,          // IN
    destPtr = resultBuffer;
    endDestPtr = resultBuffer + resultBufferSize;
 
-   VixToolsPrintFileExtendedInfo(filePathName, filePathName,
-                                 &destPtr, endDestPtr);
+   VixToolsPrintFileExtendedInfo(filePathName, filePathName, &destPtr,
+                                 endDestPtr);
 
    *destPtr = '\0';
    return resultBuffer;
@@ -7304,13 +7491,9 @@ VixToolsListFileSystems(VixCommandRequestHeader *requestMsg, // IN
    void *userToken = NULL;
    char *destPtr;
    char *endDestPtr;
+   Bool escapeStrs;
 #if defined(_WIN32) || defined(linux)
-   const char *listFileSystemsFormatString = "<filesystem>"
-                                             "<name>%s</name>"
-                                             "<size>%"FMT64"u</size>"
-                                             "<freeSpace>%"FMT64"u</freeSpace>"
-                                             "<type>%s</type>"
-                                             "</filesystem>";
+   Bool truncated;
 #endif
 #if defined(_WIN32)
    Unicode *driveList = NULL;
@@ -7339,6 +7522,9 @@ VixToolsListFileSystems(VixCommandRequestHeader *requestMsg, // IN
    }
    impersonatingVMWareUser = TRUE;
 
+   escapeStrs = (requestMsg->requestFlags &
+                 VIX_REQUESTMSG_ESCAPE_XML_DATA) != 0;
+
 #if defined(_WIN32)
    numDrives = Win32U_GetLogicalDriveStrings(&driveList);
    if (-1 == numDrives) {
@@ -7348,6 +7534,11 @@ VixToolsListFileSystems(VixCommandRequestHeader *requestMsg, // IN
       goto abort;
    }
 
+   if (escapeStrs) {
+      destPtr += Str_Sprintf(destPtr, endDestPtr - destPtr, "%s",
+                             VIX_XML_ESCAPED_TAG);
+   }
+
    for (i = 0; i < numDrives; i++) {
       if (!Win32U_GetDiskFreeSpaceEx(driveList[i],
                                      (PULARGE_INTEGER) &freeBytesToUser,
@@ -7371,14 +7562,14 @@ VixToolsListFileSystems(VixCommandRequestHeader *requestMsg, // IN
                                   NULL,
                                   NULL,
                                   &fileSystemType);
-
-      destPtr += Str_Sprintf(destPtr, endDestPtr - destPtr,
-                             listFileSystemsFormatString,
-                             driveList[i],
-                             totalBytesToUser,
-                             freeBytesToUser,
-                             fileSystemType);
-
+      err = VixToolsPrintFileSystemInfo(&destPtr, endDestPtr,
+                                        driveList[i], totalBytesToUser,
+                                        freeBytesToUser,
+                                        fileSystemType ? fileSystemType : "",
+                                        escapeStrs, &truncated);
+      if ((VIX_OK != err) || truncated) {
+         goto abort;
+      }
       Unicode_Free(fileSystemType);
    }
 
@@ -7404,13 +7595,13 @@ VixToolsListFileSystems(VixCommandRequestHeader *requestMsg, // IN
       }
       size = (uint64) statfsbuf.f_blocks * (uint64) statfsbuf.f_bsize;
       freeSpace = (uint64) statfsbuf.f_bfree * (uint64) statfsbuf.f_bsize;
-      destPtr += Str_Sprintf(destPtr, endDestPtr - destPtr,
-                             listFileSystemsFormatString,
-                             MNTINFO_NAME(mnt),
-                             size,
-                             freeSpace,
-                             MNTINFO_FSTYPE(mnt));
-
+      err = VixToolsPrintFileSystemInfo(&destPtr, endDestPtr,
+                                        MNTINFO_NAME(mnt), size, freeSpace,
+                                        MNTINFO_FSTYPE(mnt), escapeStrs,
+                                        &truncated);
+      if ((VIX_OK != err) || truncated) {
+         goto abort;
+      }
    }
    CLOSE_MNTFILE(fp);
 #else
@@ -7438,6 +7629,88 @@ abort:
    return(err);
 } // VixToolsListFileSystems
 
+
+#if defined(_WIN32) || defined(linux)
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VixToolsPrintFileSystemInfo --
+ *
+ *      Appends a single file system entry to the XML-like string starting at
+ *      *destPtr.
+ *
+ * Results:
+ *      VixError
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static VixError
+VixToolsPrintFileSystemInfo(char **destPtr,                // IN/OUT
+                            const char *endDestPtr,        // IN
+                            const char *name,              // IN
+                            uint64 size,                   // IN
+                            uint64 freeSpace,              // IN
+                            const char *type,              // IN
+                            Bool escapeStrs,               // IN
+                            Bool *truncated)               // OUT
+{
+   VixError err;
+   char *escapedName = NULL;
+   char *escapedType = NULL;
+   int bytesPrinted;
+
+   ASSERT(endDestPtr > *destPtr);
+
+   *truncated = FALSE;
+
+   if (escapeStrs) {
+      name = escapedName = VixToolsEscapeXMLString(name);
+      if (NULL == escapedName) {
+         err = VIX_E_OUT_OF_MEMORY;
+         goto abort;
+      }
+
+      type = escapedType = VixToolsEscapeXMLString(type);
+      if (NULL == escapedType) {
+         err = VIX_E_OUT_OF_MEMORY;
+         goto abort;
+      }
+   }
+
+   bytesPrinted = Str_Snprintf(*destPtr, endDestPtr - *destPtr,
+                                "<filesystem>"
+                               "<name>%s</name>"
+                               "<size>%"FMT64"u</size>"
+                               "<freeSpace>%"FMT64"u</freeSpace>"
+                               "<type>%s</type>"
+                               "</filesystem>",
+                               name, size, freeSpace, type);
+   if (bytesPrinted != -1) {
+      *destPtr += bytesPrinted;
+   } else { // out of space
+      **destPtr = '\0';
+      Debug("%s: file system list results too large, truncating",
+            __FUNCTION__);
+      *truncated = TRUE;
+      err = VIX_OK;
+      goto abort;
+   }
+
+   err = VIX_OK;
+
+abort:
+   free(escapedName);
+   free(escapedType);
+
+   return err;
+}
+#endif // #if defined(_WIN32) || defined(linux)
+
+
 /*
  *-----------------------------------------------------------------------------
  *
@@ -8480,7 +8753,7 @@ VixTools_ProcessVixCommand(VixCommandRequestHeader *requestMsg,   // IN
       ////////////////////////////////////
       case VIX_COMMAND_INITIATE_FILE_TRANSFER_TO_GUEST:
          err = VixToolsInitiateFileTransferToGuest(requestMsg);
-                       break;
+         break;
 
       ////////////////////////////////////
       case VIX_COMMAND_VALIDATE_CREDENTIALS:
@@ -8810,3 +9083,95 @@ VixToolsEnableStaticOnPrimary(const char *ipAddr,       // IN
    return ret;
 }
 #endif
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VixToolsEscapeXMLString --
+ *
+ *      Escapes a string to be included in VMAutomation XML.
+ *
+ * Results:
+ *      Pointer to a heap-allocated escaped string.
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+char *
+VixToolsEscapeXMLString(const char *str)    // IN
+{
+   static const int bytesToEscape[] = {
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   // '%'
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,   // '<' and '>'
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+   };
+
+   return Escape_Do(VIX_XML_ESCAPE_CHARACTER, bytesToEscape, str, strlen(str),
+                    NULL);
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VixToolsXMLStringEscapedLen --
+ *
+ *      Computes the length of the supplied string if it were escaped
+ *      (if escapeStr is TRUE), or the length of the string as is.
+ *
+ * Results:
+ *      The length.
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static size_t
+VixToolsXMLStringEscapedLen(const char *str,    // IN
+                            Bool escapeStr)     // IN
+{
+   if (escapeStr) {
+      size_t totalLen = 0;
+
+      while (TRUE) {
+         size_t nextLen = strcspn(str, "<>%");
+
+         totalLen += nextLen;
+         if ('\0' == str[nextLen]) {
+            break;
+         }
+
+         /*
+          * str[nextLen] is a character that needs to be escaped. Each
+          * escapeStr that is escaped will take up 3 bytes (an escape
+          * character and two hex digits) in the escaped string.
+          */
+
+         totalLen += 3;
+         str += nextLen + 1;
+      }
+
+      return totalLen;
+   } else {
+      return strlen(str);
+   }
+}
index 32e453fc73a81e70479ff81d78682b842ab98079..12249863c47cddc549cd0d27f1538e3e74770067 100644 (file)
@@ -65,6 +65,8 @@ VixError VixToolsValidateEnviron(char const * const *environ);
 char *VixToolsGetEnvVarFromEnvBlock(const wchar_t *envBlock,
                                     const char *envVarName);
 
+char *VixToolsEscapeXMLString(const char *str);
+
 #ifdef _WIN32
 VixError VixToolsGetEnvBlock(void *userToken,
                              wchar_t **envBlock);