lib/file/file.c: - Add new function File_ContainSymLink().
lib/file/filePosix.c: - Add new function File_GetMountPath()
lib/include/file.h: - Add new function declarations.
lib/include/dynbuf.h:
- Clean up documentation.
- Rename DynBuf_ConcatString() to DynBuf_Strcat().
- New inline static function DynBuf_GetString().
lib/misc/dynbuf.c:
- Clean up documentation comments.
- New function DynBuf_DetachString().
lib/misc/hostinfoPosix.c:
- Utilize new DynBuf functions.
lib/misc/strutil.c:
- Clarify documentaion comments based on DynBuf changes.
lib/misc/utilMem.c:
- Adjustment to comments.
Common source file changeis; not applicable to open-vm-tools.
}
+/*
+ *----------------------------------------------------------------------
+ *
+ * File_ContainSymLink --
+ *
+ * Check if the specified file path contains symbolic link.
+ *
+ * Results:
+ * return TRUE if pathName contains a symlink,
+ * return FALSE if pathName is not a symlink or error.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+Bool
+File_ContainSymLink(const char *pathName) // IN:
+{
+ char *path = NULL;
+ char *base = NULL;
+ Bool retValue = FALSE;
+
+ if (File_IsSymLink(pathName)) {
+ return TRUE;
+ }
+
+ File_GetPathName(pathName, &path, &base);
+
+ if ( (path != NULL)
+ && (base != NULL)
+ && (strcmp(path, "") != 0)
+ && (strcmp(base, "") != 0)) {
+ if (File_ContainSymLink(path)) {
+ retValue = TRUE;
+ }
+ }
+
+ free(path);
+ free(base);
+
+ return retValue;
+}
return (FileAttributes(pathName, &fileData) == 0) &&
(fileData.fileType == FILE_TYPE_CHARDEVICE);
}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * File_GetMountPath --
+ *
+ * This function translates the path for a symlink to the physical path.
+ * If checkEntirePath is TRUE, this function will try to translate
+ * every parent directory to physical path.
+ * Caller must free the returned buffer if valid path is returned.
+ *
+ * Results:
+ * return valid physical path if successfully.
+ * return NULL if error.
+ *
+ * Side effects:
+ * The result is allocated.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+char *
+File_GetMountPath(const char *pathName, // IN:
+ Bool checkEntirePath) // IN:
+{
+ NOT_IMPLEMENTED();
+ return NULL;
+}
* Dynamic buffers
*/
-#ifndef __DYNBUF_H__
-# define __DYNBUF_H__
+#ifndef DYNBUF_H
+# define DYNBUF_H
#include <string.h>
#include "vm_basic_types.h"
void *
DynBuf_Detach(DynBuf *b); // IN/OUT
+char *
+DynBuf_DetachString(DynBuf *b); // IN/OUT
+
Bool
DynBuf_Enlarge(DynBuf *b, // IN/OUT
size_t min_size); // IN
}
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * DynBuf_GetString --
+ *
+ * Results:
+ * Returns a pointer to the dynamic buffer data as a NUL-terminated
+ * string.
+ *
+ * Side effects:
+ * DynBuf might allocate additional memory and will panic if it fails to.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+#if defined(SWIG)
+static char *
+#else
+static INLINE char *
+#endif
+DynBuf_GetString(DynBuf *b) // IN
+{
+ ASSERT(b);
+
+ if (b->size == b->allocated) {
+ ASSERT_MEM_ALLOC(DynBuf_Enlarge(b, b->size + 1));
+ }
+ b->data[b->size] = '\0';
+ return b->data;
+}
+
+
/*
*-----------------------------------------------------------------------------
*
*
* DynBuf_AppendString --
*
- * Append the string to the specified DynBuf object. Basically a
- * fancy strcat().
+ * Appends the string to the specified DynBuf object, including its NUL
+ * terminator. Note that this is NOT like strcat; repeated calls will
+ * leave embedded NULs in the middle of the buffer. (Compare to
+ * DynBuf_Strcat.)
*
* Results:
* TRUE on success
* FALSE on failure (not enough memory)
*
- *
* Side effects:
- * DynBuf may change its size or allocate additional memory.
+ * DynBuf may change its size or allocate additional memory.
*
*----------------------------------------------------------------------------
*/
DynBuf_AppendString(DynBuf *buf, // IN/OUT
const char *string) // IN
{
- /*
- * Make sure to copy the NUL.
- */
- return DynBuf_Append(buf, string, strlen(string) + 1);
+ return DynBuf_Append(buf, string, strlen(string) + 1 /* NUL */);
}
/*
*----------------------------------------------------------------------------
*
- * DynBuf_ConcatString --
+ * DynBuf_Strcat --
*
- * Append the string to the specified DynBuf object without adding a
- * trailing NUL. The caller is responsible for NUL-terminating if so
- * desired.
+ * A DynBuf version of strcat. Unlike DynBuf_AppendString, does NOT
+ * visibly NUL-terminate the DynBuf, thereby allowing future appends to
+ * do proper string concatenation without leaving embedded NULs in the
+ * middle.
*
* Results:
* TRUE on success
* FALSE on failure (not enough memory)
*
- *
* Side effects:
- * DynBuf may change its size or allocate additional memory.
+ * DynBuf may change its size or allocate additional memory.
*
*----------------------------------------------------------------------------
*/
#else
static INLINE Bool
#endif
-DynBuf_ConcatString(DynBuf *buf, // IN/OUT
- const char *string) // IN
+DynBuf_Strcat(DynBuf *buf, // IN/OUT
+ const char *string) // IN
{
- return DynBuf_Append(buf, string, strlen(string));
+ Bool success;
+
+ ASSERT(buf != NULL);
+ ASSERT(string != NULL);
+
+ /*
+ * We actually do NUL-terminate the buffer internally, but this is not
+ * visible to callers, and they should not rely on this.
+ */
+ success = DynBuf_AppendString(buf, string);
+ if (LIKELY(success)) {
+ ASSERT(buf->size > 0);
+ buf->size--;
+ }
+ return success;
}
} // extern "C"
#endif
-#endif /* __DYNBUF_H__ */
+#endif /* DYNBUF_H */
Bool File_IsSymLink(const char *pathName);
+Bool File_ContainSymLink(const char *pathName);
+
Bool File_IsCharDevice(const char *pathName);
Bool File_GetParent(char **canPath);
char *File_GetUniqueFileSystemID(const char *pathName);
+char *File_GetMountPath(const char *pathName, Bool checkEntirePath);
+
#ifdef _WIN32
char *File_GetVolumeGUID(const char *pathName);
#endif
PRODUCT_GANTRY = 1 << 9,
PRODUCT_VMACORETESTS = 1 << 10,
PRODUCT_SRM = 1 << 11,
+ PRODUCT_VIEWCRT = 1 << 12,
/* etc */
} Product;
typedef uint64 ProductMask;
* a copy of that data.
*
* Results:
- * The pointer to the data. NULL on out of memory failure.
+ * The pointer to the data. NULL on out of memory failure or if the
+ * input DynBuf is empty.
*
* Side effects:
* Allocates memory.
void *new_data;
ASSERT(b);
+ if (b->size == 0) {
+ return NULL;
+ }
+
new_data = malloc(b->size);
if (new_data) {
memcpy(new_data, b->data, b->size);
*
* DynBuf_Detach --
*
- * Releases ownership of the buffer stored in the DynBuf object,
- * and returns a pointer to it.
+ * Transfers ownership of the buffer stored in the DynBuf object to the
+ * caller.
*
* Results:
- * The pointer to the data.
+ * Returns a pointer to the data. The caller must free it with free().
*
* Side effects:
* None
}
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * DynBuf_DetachString --
+ *
+ * Transfers ownership of the buffer stored in the DynBuf object to the
+ * caller.
+ *
+ * Results:
+ * Returns a pointer to the data as a NUL-terminated string. The caller
+ * must free it with free().
+ *
+ * Side effects:
+ * None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+char *
+DynBuf_DetachString(DynBuf *b) // IN/OUT
+{
+ char *data = DynBuf_GetString(b);
+ DynBuf_Detach(b);
+ return data;
+}
+
+
/*
*-----------------------------------------------------------------------------
*
if (new_size > b->allocated) {
/* Not enough room */
- if (DynBuf_Enlarge(b, new_size) == FALSE) {
+ if (!DynBuf_Enlarge(b, new_size)) {
return FALSE;
}
}
break;
}
- /* size does -not- include the NUL terminator. */
- DynBuf_Append(&db, line, size + 1);
+ /* size does not include the NUL terminator. */
+ DynBuf_Append(&db, line, size);
free(line);
}
- if (DynBuf_Get(&db)) {
- out = (char *) DynBuf_AllocGet(&db);
- }
+ out = DynBuf_DetachString(&db);
closeIt:
pclose(stream);
* StrUtil_VDynBufPrintf --
*
* This is a vprintf() variant which appends directly into a
- * dynbuf. The dynbuf is not NUL-terminated: The printf() result
- * is written immediately after the last byte in the DynBuf.
+ * DynBuf. Does NOT visibly NUL-terminate the DynBuf.
*
* This function does not use any temporary buffer. The printf()
* result can be arbitrarily large. This function automatically
va_list tmpArgs;
va_copy(tmpArgs, args);
+
+ /*
+ * We actually do NUL-terminate the buffer internally, but this is not
+ * visible to callers, and they should not rely on this.
+ */
i = Str_Vsnprintf((char *) DynBuf_Get(b) + size, allocSize - size,
fmt, tmpArgs);
va_end(tmpArgs);
*
* UtilSafeMalloc0 --
* UtilSafeMalloc1 --
- * Helper function for malloc
+ *
+ * Helper functions for Util_SafeMalloc.
*
* Results:
* Pointer to the dynamically allocated memory.
*
* UtilSafeRealloc0 --
* UtilSafeRealloc1 --
- * Helper function for realloc
+ *
+ * Helper functions for Util_SafeRealloc.
*
* Results:
* Pointer to the dynamically allocated memory.
*
* UtilSafeCalloc0 --
* UtilSafeCalloc1 --
- * Helper function for calloc
+ *
+ * Helper functions for Util_SafeCalloc.
*
* Results:
* Pointer to the dynamically allocated memory.
/*
*-----------------------------------------------------------------------------
*
- * Util_SafeStrdup --
- * Helper function for strdup
+ * UtilSafeStrdup0 --
+ * UtilSafeStrdup1 --
+ *
+ * Helper functions for Util_SafeStrdup.
*
* Results:
* Pointer to the dynamically allocated, duplicate string
/*
*-----------------------------------------------------------------------------
*
- * Util_SafeStrndup --
+ * UtilSafeStrndup0 --
+ * UtilSafeStrndup1 --
+ *
+ * Helper functions for Util_SafeStrndup.
*
* Returns a string consisting of first n characters of 's' if 's' has
* length >= 'n', otherwise returns a string duplicate of 's'.
if (*user == '\0') {
#if defined(__APPLE__)
/*
- * The HOME environment variable is not always set on Mac OS.
- * (was bug 841728)
+ * This check mimics the checks and order of CFCopyHomeDirectoryURL(),
+ * which is unfortunately not callable directly since Apple has marked it
+ * as only in iOS despite the fact that they clearly ship it on macOS.
*/
+ str = issetugid() ? NULL
+ : Unicode_Duplicate(Posix_Getenv("CFFIXED_USER_HOME"));
+
if (str == NULL) {
pwd = Posix_Getpwuid(getuid());
if (pwd == NULL) {
Log("Could not get passwd for current user.\n");
}
}
-#else // !defined(__APPLE__)
- str = Unicode_Duplicate(Posix_Getenv("HOME"));
- if (str == NULL) {
- Log("Could not expand environment variable HOME.\n");
+#endif // defined(__APPLE__)
+ if (str == NULL && pwd == NULL) {
+ str = Unicode_Duplicate(Posix_Getenv("HOME"));
+ if (str == NULL) {
+ Log("Could not expand environment variable HOME.\n");
+ }
}
-#endif // !defined(__APPLE__)
} else {
pwd = Posix_Getpwnam(user);
if (pwd == NULL) {