Exemplo n.º 1
0
char *
StrUtil_AppendListItem(char const *list,  // IN:
                       char delim,        // IN:
                       char const *item)  // IN:
{
   if (list == NULL) {
      return Str_Asprintf(NULL, "%s", item);
   } else {
      return Str_Asprintf(NULL, "%s%c%s", list, delim, item);
   }
}
Exemplo n.º 2
0
char *
URL_Get(UrlId id,    // IN
        Bool append) // IN: Allow things to be appended
{
   unsigned int index;
   char *result;
   
   if (id == 0) {
      /* Invalid ID --hpreg */
      return NULL;
   }
   /* Lookup the URLs array for a URL ID --hpreg */
   for (index = 0; index < sizeof(URLs) / sizeof(URLs[0]); index++) {
      if (URLs[index].id == id) {
         break;
      }
   }
   if (index == sizeof(URLs) / sizeof(URLs[0])) {
      /* Invalid ID --hpreg */
      return NULL;
   }

   result = Str_Asprintf(NULL, "http://%s.com/info?id=%u",
                         PRODUCT_GENERIC_NAME_LOWER,
                         URLs[index].id);
   if (result == NULL) {
      return NULL;
   }

   if (append) {
      unsigned int i;

      for (i = 0; i < sizeof(appends) / sizeof(appends[0]); i++) {
         if ((URLs[index].appends & (1 << i)) && appends[i].value) {
            char *tmpResult;
            char encName[1024];
            char encValue[1024];

            URL_EncodeURL(appends[i].name, encName, sizeof(encName));
            URL_EncodeURL(appends[i].value, encValue, sizeof(encValue));
            tmpResult = Str_Asprintf(NULL, "%1$s&%2$s=%3$s", result, encName,
                                     encValue);
            free(result);
            if (tmpResult == NULL) {
               return NULL;
            }
            result = tmpResult;
         }
      }
   }

   return result;
}
Exemplo n.º 3
0
char *
TimeUtil_GetTimeFormat(int64 utcTime,  // IN
                       Bool showDate,  // IN
                       Bool showTime)  // IN
{
#ifdef _WIN32
   SYSTEMTIME systemTime = { 0 };
   char dateStr[100] = "";
   char timeStr[100] = "";

   if (!showDate && !showTime) {
      return NULL;
   }

   if (!TimeUtil_UTCTimeToSystemTime((const __time64_t) utcTime,
                                      &systemTime)) {
      return NULL;
   }

   Win32U_GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE,
                        &systemTime, NULL, dateStr, ARRAYSIZE(dateStr));

   Win32U_GetTimeFormat(LOCALE_USER_DEFAULT, 0, &systemTime, NULL,
                        timeStr, ARRAYSIZE(timeStr));

   if (showDate && showTime) {
      return Str_Asprintf(NULL, "%s %s", dateStr, timeStr);
   } else {
      return Str_Asprintf(NULL, "%s", showDate ? dateStr : timeStr);
   }

#else
   /*
    * On 32-bit systems the assignment of utcTime to time_t below will truncate
    * in the year 2038.  Ignore it; there's nothing we can do.
    */

   char *str;
   char buf[26];
   const time_t t = (time_t) utcTime;  // Implicit narrowing on 32-bit

#if defined sun
   str = Util_SafeStrdup(ctime_r(&t, buf, sizeof buf));
#else
   str = Util_SafeStrdup(ctime_r(&t, buf));
#endif
   str[strlen(str) - 1] = '\0';  // Remove the trailing '\n'.

   return str;
#endif // _WIN32
}
Exemplo n.º 4
0
void
AppUtil_SendGuestCaps(const GuestCapabilities *caps, // IN: array of capabilities
                      size_t numCaps,                // IN: number of capabilities
                      Bool enabled)                  // IN: capabilities status
{
   char *capsStr = NULL;
   char *capsTemp = NULL;
   size_t capIdx;

   ASSERT(caps);
   ASSERT(numCaps > 0);

   capsStr = strdup(GUEST_CAP_FEATURES);
   for (capIdx = 0; capIdx < numCaps; capIdx++) {
      if (!capsStr) {
         Debug("%s: Not enough memory to create capabilities string\n", __FUNCTION__);
         return;
      }
      capsTemp = Str_Asprintf(NULL,
                              "%s %d=%d",
                              capsStr,
                              caps[capIdx],
                              (int)enabled);
      free(capsStr);
      capsStr = capsTemp;
   }

   if (!RpcOut_sendOne(NULL, NULL, capsStr)) {
      Debug("%s: could not set capabilities: older vmx?\n", __FUNCTION__);
   }

   free(capsStr);
}
Exemplo n.º 5
0
char *
GuestApp_GetInstallPath(void)
{
   char *pathUtf8 = NULL;

#if defined(_WIN32)
   size_t pathLen = 0;

   if (WinReg_GetSZ(HKEY_LOCAL_MACHINE,
                    CONF_VMWARE_TOOLS_REGKEY,
                    "InstallPath",
                    &pathUtf8) != ERROR_SUCCESS) {
      Warning("%s: Unable to retrieve install path: %s\n",
               __FUNCTION__, Msg_ErrString());
      return NULL;
   }

   /* Strip off the trailing backslash, if present */

   pathLen = strlen(pathUtf8);
   if (pathLen > 0) {
      if (pathUtf8[pathLen - 1] == '\\') {
         pathUtf8[pathLen - 1] = '\0';
      }
   }

#else
   pathUtf8 = Str_Asprintf(NULL, "%s", GUESTAPP_TOOLS_INSTALL_PATH);
#endif

   return pathUtf8;
}
Exemplo n.º 6
0
static char *
VmBackupGetScriptPath(void)
{
   char *scriptPath = NULL;
   char *installPath = GuestApp_GetInstallPath();

   if (installPath == NULL) {
      return NULL;
   }

   scriptPath = Str_Asprintf(NULL, "%s%s%s", installPath, DIRSEPS, "backupScripts.d");
   free(installPath);

   return scriptPath;
}
Exemplo n.º 7
0
char *
HgfsUri_ConvertFromPathToHgfsUri(const char *pathName,  // IN: path to convert
                                 Bool hgfsOnly)         // IN
{
   char *shareUri = NULL;
   Bool isHgfsName = FALSE;
   char *sharesDefaultRootPath = NULL;

   /* We can only operate on full paths. */
   if (pathName[0] != DIRSEPC) {
      return shareUri;
   }

   /* Retrieve the servername & share name in use. */
   if (!HgfsHlpr_QuerySharesDefaultRootPath(&sharesDefaultRootPath)) {
      Debug("%s: Unable to query shares default root path\n", __FUNCTION__);
      goto exit;
   }

   if (Unicode_StartsWith(pathName, sharesDefaultRootPath)) {
      char *relativeSharePath = NULL;
      char *escapedSharePath = NULL;
      UnicodeIndex relativePathStart = strlen(sharesDefaultRootPath);
      if (   strlen(pathName) > relativePathStart
          && pathName[relativePathStart] == DIRSEPC) {
         relativePathStart++;
      }
      relativeSharePath = Unicode_RemoveRange(pathName, 0, relativePathStart);
      HgfsEscape_Undo(relativeSharePath, strlen(relativeSharePath) + 1);
      escapedSharePath = g_uri_escape_string(relativeSharePath, "/", FALSE);
      shareUri = Unicode_Append(GHI_HGFS_SHARE_URL_UTF8, escapedSharePath);
      g_free(escapedSharePath);
      free(relativeSharePath);
      isHgfsName = TRUE;
   }

exit:
   if (!isHgfsName && !hgfsOnly) {
      /* Only convert non-hgfs file name if hgfsOnly is not set. */
      char *escapedPath = g_uri_escape_string(pathName, "/", FALSE);
      shareUri = Str_Asprintf(NULL,
                              "file://%s",
                               escapedPath);
      g_free(escapedPath);
   }
   HgfsHlpr_FreeSharesRootPath(sharesDefaultRootPath);
   return shareUri;
}
Exemplo n.º 8
0
static gboolean
RpcChannelReset(RpcInData *data)
{
   gchar *msg;
   RpcChannelInt *chan = data->clientData;

   if (chan->resetCheck == NULL) {
      chan->resetCheck = g_idle_source_new();
      g_source_set_priority(chan->resetCheck, G_PRIORITY_HIGH);
      g_source_set_callback(chan->resetCheck, RpcChannelCheckReset, chan, NULL);
      g_source_attach(chan->resetCheck, chan->mainCtx);
   }

   msg = Str_Asprintf(NULL, "ATR %s", chan->appName);
   ASSERT_MEM_ALLOC(msg);
   return RPCIN_SETRETVALSF(data, msg, TRUE);
}
Exemplo n.º 9
0
const char *
Xdg_GetCacheHome(void)
{
   static char *result = NULL;
   struct passwd *pw;

   if (result == NULL) {
      do {
         if (!Id_IsSetUGid()) {
            const char *base = NULL;

            /*
             * Paranoia:  Avoid environment variables if running in a sensitive
             *            context.  sudo or other loader should've sanitized the
             *            environment, but, well, we're paranoid, remember?
             */

            // 1. $XDG_CACHE_HOME
            base = Posix_Getenv("XDG_CACHE_HOME");
            if (Util_IsAbsolutePath(base)) {
               result = Util_SafeStrdup(base);
               break;
            }

            // 2. $HOME/.cache
            base = Posix_Getenv("HOME");
            if (Util_IsAbsolutePath(base)) {
               result = Util_SafeStrdup(base);
               StrUtil_SafeStrcat(&result, "/.cache");
               break;
            }
         }

         // 3. <pw_dir>/.cache
         pw = Posix_Getpwuid(geteuid());

         if (pw != NULL && Util_IsAbsolutePath(pw->pw_dir)) {
            result = Str_Asprintf(NULL, "%s/.cache", pw->pw_dir);
         }
      } while(0);
   }

   VERIFY(result == NULL || result[0] == '/');
   return result;
}
Exemplo n.º 10
0
static char *
FileCreateSafeTmpDir(uid_t userId,            // IN:
                     const char *userName,    // IN:
                     const char *baseTmpDir)  // IN:
{
   static const int MAX_DIR_ITERS = 250;
   int curDirIter = 0;
   char *tmpDir = NULL;

   while (TRUE) {
      /*
       * We use a random number that makes it more likely that we will create
       * an unused name than if we had simply tried suffixes in numeric order.
       */

      tmpDir = Str_Asprintf(NULL, "%s%s%s-%s-%u", baseTmpDir, DIRSEPS,
                            PRODUCT_GENERIC_NAME_LOWER, userName,
                            FileSimpleRandom());

      if (!tmpDir) {
         Warning("%s: Out of memory error.\n", __FUNCTION__);
         break;
      }

      if (FileAcceptableSafeTmpDir(tmpDir, userId)) {
         break;
      }

      if (++curDirIter > MAX_DIR_ITERS) {
         Warning("%s: Failed to create a safe temporary directory, path "
                 "\"%s\". The maximum number of attempts was exceeded.\n",
                 __FUNCTION__, tmpDir);
         free(tmpDir);
         tmpDir = NULL;
         break;
      }

      free(tmpDir);
      tmpDir = NULL;
   }

   return tmpDir;
}
Exemplo n.º 11
0
static void
UpdateMtab(HgfsMountInfo *mountInfo,  // IN: Info to write into mtab
           int flags)                 // IN: Flags (read-only, etc.)
{
   struct mntent mountEnt;
   FILE *mountFile;
   struct passwd *password;
   char *userName = NULL;

   ASSERT(mountInfo);

   mountFile = setmntent(MOUNTED, "a+");
   if (mountFile == NULL) {
      printf("Could not open mtab for appending, continuing sans mtab\n");
      return;
   }

   /* We only care about the mounting user if it isn't root. */
   if (getuid() != 0) {
      password = getpwuid(getuid());
      if (password == NULL) {
         printf("Could not get user for mounting uid, skipping user entry\n");
      } else {
         userName = password->pw_name;
      }
   }

   /*
    * Create the mtab entry to be written. We'll go ahead and try to write
    * even if we fail to allocate the mount options.
    */
   mountEnt.mnt_fsname = shareName;
   mountEnt.mnt_dir = mountPoint;
   mountEnt.mnt_type = HGFS_NAME;
   mountEnt.mnt_freq = 0;
   mountEnt.mnt_passno = 0;
   mountEnt.mnt_opts = malloc(MOUNT_OPTS_BUFFER_SIZE);
   if (mountEnt.mnt_opts) {
      char *ttlString;

      memset(mountEnt.mnt_opts, 0, MOUNT_OPTS_BUFFER_SIZE);

      /*
       * These are typically the displayed options in /etc/mtab (note that not
       * all options are typically displayed, just those the user may find
       * interesting).
       */
      if (flags & MS_RDONLY) {
         Str_Strcat(mountEnt.mnt_opts, "ro", MOUNT_OPTS_BUFFER_SIZE);
      } else {
         Str_Strcat(mountEnt.mnt_opts, "rw", MOUNT_OPTS_BUFFER_SIZE);
      }
      if (flags & MS_NOSUID) {
         Str_Strcat(mountEnt.mnt_opts, ",nosuid", MOUNT_OPTS_BUFFER_SIZE);
      }
#ifdef MS_NODEV
      if (flags & MS_NODEV) {
         Str_Strcat(mountEnt.mnt_opts, ",nodev", MOUNT_OPTS_BUFFER_SIZE);
      }
#endif
      if (flags & MS_NOEXEC) {
         Str_Strcat(mountEnt.mnt_opts, ",noexec", MOUNT_OPTS_BUFFER_SIZE);
      }
      if (flags & MS_SYNCHRONOUS) {
         Str_Strcat(mountEnt.mnt_opts, ",sync", MOUNT_OPTS_BUFFER_SIZE);
      }
      if (flags & MS_MANDLOCK) {
         Str_Strcat(mountEnt.mnt_opts, ",mand", MOUNT_OPTS_BUFFER_SIZE);
      }
      if (flags & MS_NOATIME) {
         Str_Strcat(mountEnt.mnt_opts, ",noatime", MOUNT_OPTS_BUFFER_SIZE);
      }
      if (flags & MS_NODIRATIME) {
         Str_Strcat(mountEnt.mnt_opts, ",nodiratime", MOUNT_OPTS_BUFFER_SIZE);
      }

      if (userName != NULL) {
         Str_Strcat(mountEnt.mnt_opts, ",user="******"%u", mountInfo->ttl);
      if (ttlString != NULL) {
         Str_Strcat(mountEnt.mnt_opts, ",ttl=", MOUNT_OPTS_BUFFER_SIZE);
         Str_Strcat(mountEnt.mnt_opts, ttlString, MOUNT_OPTS_BUFFER_SIZE);
         free(ttlString);
      } else {
         printf("Could not allocate memory for ttl entry in mtab, "
                "continuing\n");
      }
   }

   /* Add the entry and close. */
   if (addmntent(mountFile, &mountEnt)) {
      printf("Could not add entry to mtab, continuing\n");
   }
   endmntent(mountFile);
   if (mountEnt.mnt_opts) {
      free(mountEnt.mnt_opts);
   }
}
Exemplo n.º 12
0
char *
StrUtil_FormatSizeInBytesUnlocalized(uint64 size) // IN
{
   /*
    * XXX TODO, BUG 199661:
    * This is a direct copy of Msg_FormatSizeInBytes without localization.
    * These two functions should ideally share the basic functionality, and
    * just differ in the string localization
    */

   char const *fmt;
   double sizeInSelectedUnit;
   unsigned int precision;
   char *sizeFormat;
   char *sizeString;
   char *result;
   static const double epsilon = 0.01;
   double delta;

   if (size >= CONST64U(1) << 40 /* 1 TB */) {
      fmt = "%s TB";
      sizeInSelectedUnit = (double)size / (CONST64U(1) << 40);
      precision = 1;
   } else if (size >= CONST64U(1) << 30 /* 1 GB */) {
      fmt = "%s GB";
      sizeInSelectedUnit = (double)size / (CONST64U(1) << 30);
      precision = 1;
   } else if (size >= CONST64U(1) << 20 /* 1 MB */) {
      fmt = "%s MB";
      sizeInSelectedUnit = (double)size / (CONST64U(1) << 20);
      precision = 1;
   } else if (size >= CONST64U(1) << 10 /* 1 KB */) {
      fmt = "%s KB";
      sizeInSelectedUnit = (double)size / (CONST64U(1) << 10);
      precision = 1;
   } else if (size >= CONST64U(2) /* 2 bytes */) {
      fmt = "%s bytes";
      sizeInSelectedUnit = (double)size;
      precision = 0; // No fractional byte.
   } else if (size >= CONST64U(1) /* 1 byte */) {
      fmt = "%s byte";
      sizeInSelectedUnit = (double)size;
      precision = 0; // No fractional byte.
   } else {
      ASSERT(size == CONST64U(0) /* 0 bytes */);
      fmt = "%s bytes";
      sizeInSelectedUnit = (double)size;
      precision = 0; // No fractional byte.
   }

   /*
    * We cast to uint32 instead of uint64 here because of a problem with the
    * NetWare Tools build. However, it's safe to cast to uint32 since we have
    * already reduced the range of sizeInSelectedUnit above.
    */
   // If it would display with .0, round it off and display the integer value.
   delta = (uint32)(sizeInSelectedUnit + 0.5) - sizeInSelectedUnit;
   if (delta < 0) {
      delta = -delta;
   }
   if (delta <= epsilon) {
      precision = 0;
      sizeInSelectedUnit = (double)(uint32)(sizeInSelectedUnit + 0.5);
   }

   sizeFormat = Str_Asprintf(NULL, "%%.%uf", precision);
   sizeString = Str_Asprintf(NULL, sizeFormat, sizeInSelectedUnit);
   result = Str_Asprintf(NULL, fmt, sizeString);
   free(sizeFormat);
   free(sizeString);

   return result;
}
Exemplo n.º 13
0
static int
VmBackupRunNextScript(VmBackupScriptOp *op)  // IN/OUT
{
   const char *scriptOp;
   int ret = 0;
   ssize_t index;
   VmBackupScript *scripts = op->state->scripts;

   switch (op->type) {
   case VMBACKUP_SCRIPT_FREEZE:
      index = ++op->state->currentScript;
      scriptOp = "freeze";
      break;

   case VMBACKUP_SCRIPT_FREEZE_FAIL:
      index = --op->state->currentScript;
      scriptOp = "freezeFail";
      break;

   case VMBACKUP_SCRIPT_THAW:
      index = --op->state->currentScript;
      scriptOp = "thaw";
      break;

   default:
      NOT_REACHED();
   }

   while (index >= 0 && scripts[index].path != NULL) {
      char *cmd;

      if (File_IsFile(scripts[index].path)) {
         if (op->state->scriptArg != NULL) {
            cmd = Str_Asprintf(NULL, "\"%s\" %s \"%s\"", scripts[index].path,
                               scriptOp, op->state->scriptArg);
         } else {
            cmd = Str_Asprintf(NULL, "\"%s\" %s", scripts[index].path,
                               scriptOp);
         }
         if (cmd != NULL) {
            g_debug("Running script: %s\n", cmd);
            scripts[index].proc = ProcMgr_ExecAsync(cmd, NULL);
         } else {
            g_debug("Failed to allocate memory to run script: %s\n",
                    scripts[index].path);
            scripts[index].proc = NULL;
         }
         vm_free(cmd);

         if (scripts[index].proc == NULL) {
            if (op->type == VMBACKUP_SCRIPT_FREEZE) {
               ret = -1;
               break;
            } else {
               op->thawFailed = TRUE;
            }
         } else {
            ret = 1;
            break;
         }
      }

      if (op->type == VMBACKUP_SCRIPT_FREEZE) {
         index = ++op->state->currentScript;
      } else {
         index = --op->state->currentScript;
      }

      /*
       * This happens if all thaw/fail scripts failed to start. Since the first
       * entry may be a legacy script (which may not exist), need to check
       * whether the interesting failure is the first or the second entry in
       * the script list.
       */
      if (index == -1) {
         size_t failIdx = 0;
         if (!File_IsFile(scripts[0].path)) {
            failIdx = 1;
         }
         if (scripts[failIdx].proc == NULL && scripts[failIdx].path != NULL) {
            ret = -1;
         }
      }
   }

   return ret;
}
Exemplo n.º 14
0
VmBackupOp *
VmBackup_NewScriptOp(VmBackupScriptType type, // IN
                     VmBackupState *state)    // IN
{
   Bool fail = FALSE;
   char **fileList = NULL;
   char *scriptDir = NULL;
   int numFiles = 0;
   size_t i;
   VmBackupScriptOp *op = NULL;

   scriptDir = VmBackupGetScriptPath();
   if (scriptDir == NULL) {
      goto exit;
   }

   op = calloc(1, sizeof *op);
   if (op == NULL) {
      goto exit;
   }

   op->state = state;
   op->type = type;
   op->callbacks.queryFn = VmBackupScriptOpQuery;
   op->callbacks.cancelFn = VmBackupScriptOpCancel;
   op->callbacks.releaseFn = VmBackupScriptOpRelease;

   g_debug("Trying to run scripts from %s\n", scriptDir);

   /*
    * Load the list of scripts to run when freezing. The same list will be
    * used later in case of failure, or when thawing, in reverse order.
    *
    * This logic won't recurse into directories, so only files directly under
    * the script dir will be considered.
    *
    * Legacy scripts will be the first ones to run (or last ones in the
    * case of thawing). If either the legacy freeze or thaw script
    * exist, the first entry in the script list will be reserved for
    * them, and their path might not exist (in case, for example, the
    * freeze script exists but the thaw script doesn't).
    */
   if (type == VMBACKUP_SCRIPT_FREEZE) {
      VmBackupScript *scripts = NULL;
      int legacy = 0;
      size_t idx = 0;

      state->scripts = NULL;
      state->currentScript = 0;

      if (File_IsFile(LEGACY_FREEZE_SCRIPT) ||
          File_IsFile(LEGACY_THAW_SCRIPT)) {
         legacy = 1;
      }

      if (File_IsDirectory(scriptDir)) {
         numFiles = File_ListDirectory(scriptDir, &fileList);
      }

      if (numFiles + legacy > 0) {
         scripts = calloc(numFiles + legacy + 1, sizeof *scripts);
         if (scripts == NULL) {
            fail = TRUE;
            goto exit;
         }

         /*
          * VmBackupRunNextScript increments the index, so need to make it point
          * to "before the first script".
          */
         state->currentScript = -1;
         state->scripts = scripts;
      }

      if (legacy > 0) {
         scripts[idx++].path = Util_SafeStrdup(LEGACY_FREEZE_SCRIPT);
      }

      if (numFiles > 0) {
         size_t i;

         if (numFiles > 1) {
            qsort(fileList, (size_t) numFiles, sizeof *fileList, VmBackupStringCompare);
         }

         for (i = 0; i < numFiles; i++) {
            char *script;

            script = Str_Asprintf(NULL, "%s%c%s", scriptDir, DIRSEPC, fileList[i]);
            if (script == NULL) {
               fail = TRUE;
               goto exit;
            } else if (File_IsFile(script)) {
               scripts[idx++].path = script;
            } else {
               free(script);
            }
         }
      }
   } else if (state->scripts != NULL) {
      VmBackupScript *scripts = state->scripts;
      if (strcmp(scripts[0].path, LEGACY_FREEZE_SCRIPT) == 0) {
         vm_free(scripts[0].path);
         scripts[0].path = Util_SafeStrdup(LEGACY_THAW_SCRIPT);
      }
   }

   /*
    * If there are any scripts to be executed, start the first one. If we get to
    * this point, we won't free the scripts array until VmBackupScriptOpRelease
    * is called after thawing (or after the sync provider failed and the "fail"
    * scripts are run).
    */
   fail = (state->scripts != NULL && VmBackupRunNextScript(op) == -1);

exit:
   /* Free the file list. */
   for (i = 0; i < numFiles; i++) {
      free(fileList[i]);
   }
   free(fileList);

   if (fail && op != NULL) {
      VmBackup_Release((VmBackupOp *) op);
      op = NULL;
   }
   free(scriptDir);
   return (VmBackupOp *) op;
}
Exemplo n.º 15
0
/*
 *----------------------------------------------------------------------
 *
 * SysCompatIsInstalledFuse
 *
 *    Test if the FUSE file system is installed but not yet loaded.
 *
 * Results:
 *    FALSE the HGFS FUSE client is not installed, TRUE if it is installed.
 *
 * Side effects:
 *    None
 *
 *----------------------------------------------------------------------
 */
static Bool
SysCompatIsInstalledFuse(char *utsRelease)  // IN: kernel release
{
   char *fuseFilesystem;
   char *modulesDep;
   char *modulesDepData = NULL;
   struct stat modulesDepStat;
   size_t modulesDepLen;
   size_t modulesDepDataSize;
   size_t modulesDepFileSize;
   int modulesDepFd = -1;
   Bool installedFuse = FALSE;
   int statResult;

   modulesDep = Str_Asprintf(&modulesDepLen, "%s/%s/%s",
                             LIB_MODULEPATH, utsRelease, MODULES_DEP);

   if (modulesDep == NULL) {
      fprintf(stderr, "failed to create path str for %s\n", MODULES_DEP);
      goto exit;
   }

   modulesDepFd = open(modulesDep, O_RDONLY);
   if (modulesDepFd == -1) {
      fprintf(stderr, "failed to open %s %d\n", modulesDep, errno);
      goto exit;
   }

   statResult = fstat(modulesDepFd, &modulesDepStat);
   if (statResult == -1) {
      fprintf(stderr, "failed to stat %s %d\n", modulesDep, errno);
      goto exit;
   }
   modulesDepFileSize = (size_t)modulesDepStat.st_size;
   modulesDepData = malloc(modulesDepFileSize + 1);
   if (modulesDepData == NULL) {
      fprintf(stderr, "failed to alloc data buf for %s\n", modulesDep);
      goto exit;
   }

   modulesDepDataSize = read(modulesDepFd,
                             modulesDepData,
                             modulesDepFileSize);

   if (modulesDepDataSize != modulesDepFileSize) {
      fprintf(stderr, "failed to read %s %d\n", modulesDep, errno);
      goto exit;
   }

   modulesDepData[modulesDepDataSize] = '\0';
   fuseFilesystem = strstr(modulesDepData,
                           FUSER_KERNEL_FS);

   installedFuse = (fuseFilesystem != NULL);

exit:
   if (modulesDepFd != -1) {
      close(modulesDepFd);
   }
   free(modulesDepData);
   free(modulesDep);
   return installedFuse;
}
Exemplo n.º 16
0
char *
File_GetSafeTmpDir(Bool useConf)  // IN:
{
   char *tmpDir;

#if defined(__FreeBSD__) || defined(sun)
   tmpDir = FileGetTmpDir(useConf);
#else
   static Atomic_Ptr lckStorage;
   static char *safeDir;
   char *baseTmpDir = NULL;
   char *userName = NULL;
   uid_t userId;
   MXUserExclLock *lck;

   userId = geteuid();

   /* Get and take lock for our safe dir. */
   lck = MXUser_CreateSingletonExclLock(&lckStorage, "getSafeTmpDirLock",
                                        RANK_getSafeTmpDirLock);
   VERIFY(lck != NULL);

   MXUser_AcquireExclLock(lck);

   /*
    * Check if we've created a temporary dir already and if it is still usable.
    */

   tmpDir = NULL;

   if (safeDir && FileAcceptableSafeTmpDir(safeDir, userId)) {
      tmpDir = Util_SafeStrdup(safeDir);
      goto exit;
   }

   /* We don't have a useable temporary dir, create one. */
   baseTmpDir = FileGetTmpDir(useConf);

   if (!baseTmpDir) {
      Warning("%s: FileGetTmpDir failed.\n", __FUNCTION__);
      goto exit;
   }

   userName = FileGetUserName(userId);

   if (!userName) {
      Warning("%s: FileGetUserName failed, using numeric ID "
              "as username instead.\n", __FUNCTION__);

      /* Fallback on just using the userId as the username. */
      userName = Str_Asprintf(NULL, "uid-%d", userId);

      if (!userName) {
         Warning("%s: Str_Asprintf error.\n", __FUNCTION__);
         goto exit;
      }
   }

   tmpDir = Str_Asprintf(NULL, "%s%s%s-%s", baseTmpDir, DIRSEPS,
                         PRODUCT_GENERIC_NAME_LOWER, userName);

   if (!tmpDir) {
      Warning("%s: Out of memory error.\n", __FUNCTION__);
      goto exit;
   }

   if (!FileAcceptableSafeTmpDir(tmpDir, userId)) {
      /*
       * We didn't get our first choice for the safe temp directory.
       * Search through the unsafe tmp directory to see if there is
       * an acceptable one to use.
       */

      free(tmpDir);

      tmpDir = FileFindExistingSafeTmpDir(userId, userName, baseTmpDir);

      if (!tmpDir) {
         /*
          * We didn't find any usable directories, so try to create one now.
          */

         tmpDir = FileCreateSafeTmpDir(userId, userName, baseTmpDir);
      }
   }

   if (tmpDir) {
      /*
       * We have successfully created a temporary directory, remember it for
       * future calls.
       */

      free(safeDir);
      safeDir = Util_SafeStrdup(tmpDir);
   }

  exit:
   MXUser_ReleaseExclLock(lck);
   free(baseTmpDir);
   free(userName);
#endif

   return tmpDir;
}
Exemplo n.º 17
0
gboolean
RpcChannel_SendOne(char **reply,
                   size_t *repLen,
                   char const *reqFmt,
                   ...)
{
   va_list args;
   gboolean status;
   char *request;
   size_t reqLen = 0;

   status = FALSE;

   /* Format the request string */
   va_start(args, reqFmt);
   request = Str_Vasprintf(&reqLen, reqFmt, args);
   va_end(args);

   /*
    * If Str_Vasprintf failed, write NULL into the reply if the caller wanted
    * a reply back.
    */
   if (request == NULL) {
      goto error;
   }

   /*
    * If the command doesn't contain a space, add one to the end to maintain
    * compatibility with old VMXs.
    *
    * For a long time, the GuestRpc logic in the VMX was wired to expect a
    * trailing space in every command, even commands without arguments. That is
    * no longer true, but we must continue to add a trailing space because we
    * don't know whether we're talking to an old or new VMX.
    */
   if (request[reqLen - 1] != ' ') {
      char *tmp;

      tmp = Str_Asprintf(NULL, "%s ", request);
      free(request);
      request = tmp;

      /*
       * If Str_Asprintf failed, write NULL into reply if the caller wanted
       * a reply back.
       */
      if (request == NULL) {
         goto error;
      }
   }

   status = RpcChannel_SendOneRaw(request, reqLen, reply, repLen);

   free(request);

   return status;

error:
   if (reply) {
      *reply = NULL;
   }

   if (repLen) {
      *repLen = 0;
   }
   return FALSE;
}
Exemplo n.º 18
0
static MsgCatalog *
MsgLoadCatalog(const char *path)
{
   gchar *localPath;
   GError *err = NULL;
   GIOChannel *stream;
   gboolean error = FALSE;
   MsgCatalog *catalog = NULL;
   HashTable *dict;

   ASSERT(path != NULL);
   localPath = VMTOOLS_GET_FILENAME_LOCAL(path, NULL);
   ASSERT(localPath != NULL);

   stream = g_io_channel_new_file(localPath, "r", &err);
   VMTOOLS_RELEASE_FILENAME_LOCAL(localPath);

   if (err != NULL) {
      g_debug("Unable to open '%s': %s\n", path, err->message);
      g_clear_error(&err);
      return NULL;
   }

   dict = HashTable_Alloc(8, HASH_STRING_KEY | HASH_FLAG_COPYKEY, g_free);
   ASSERT_MEM_ALLOC(dict);

   for (;;) {
      gboolean eof = FALSE;
      char *name = NULL;
      char *value = NULL;
      gchar *line;

      /* Read the next key / value pair. */
      for (;;) {
         gsize i;
         gsize len;
         gsize term;
         char *unused = NULL;
         gboolean cont = FALSE;

         g_io_channel_read_line(stream, &line, &len, &term, &err);

         if (err != NULL) {
            g_warning("Unable to read a line from '%s': %s\n",
                      path, err->message);
            g_clear_error(&err);
            error = TRUE;
            g_free(line);
            break;
         }

         if (line == NULL) {
            eof = TRUE;
            break;
         }

         /*
          * Fix the line break to always be Unix-style, to make lib/dict
          * happy.
          */
         if (line[term] == '\r') {
            line[term] = '\n';
            if (len > term) {
               line[term + 1] = '\0';
            }
         }

         /*
          * If currently name is not NULL, then check if this is a continuation
          * line and, if it is, just append the contents to the current value.
          */
         if (term > 0 && name != NULL && line[term - 1] == '"') {
            for (i = 0; i < len; i++) {
               if (line[i] == '"') {
                  /* OK, looks like a continuation line. */
                  char *tmp;
                  char *unescaped;

                  line[term - 1] = '\0';
                  unescaped = Escape_Undo('|', line + i + 1, len - i, NULL);
                  tmp = Str_Asprintf(NULL, "%s%s", value, unescaped);
                  free(unescaped);
                  free(value);
                  value = tmp;
                  cont = TRUE;
                  break;
               } else if (line[i] != ' ' && line[i] != '\t') {
                  break;
               }
            }
         }

         /*
          * If not a continuation line and we have a name, break out of the
          * inner loop to update the dictionaty.
          */
         if (!cont && name != NULL) {
            g_free(line);
            break;
         }

         /*
          * Finally, try to parse the string using the dictionary library.
          */
         if (!cont && DictLL_UnmarshalLine(line, len, &unused, &name, &value) == NULL) {
            g_warning("Couldn't parse line from catalog: %s", line);
            error = TRUE;
         }

         g_free(line);
         free(unused);
      }

      if (error) {
         break;
      }

      if (name != NULL) {
         ASSERT(value);

         if (!Unicode_IsBufferValid(name, strlen(name) + 1, STRING_ENCODING_UTF8) ||
             !Unicode_IsBufferValid(value, strlen(value) + 1, STRING_ENCODING_UTF8)) {
            g_warning("Invalid UTF-8 string in message catalog (key = %s)\n", name);
            error = TRUE;
            break;
         }

         MsgUnescape(value);
         HashTable_ReplaceOrInsert(dict, name, g_strdup(value));
         free(name);
         free(value);
         name = NULL;
         value = NULL;
      }

      if (eof) {
         break;
      }
   }

   g_io_channel_unref(stream);

   if (error) {
      HashTable_Free(dict);
      dict = NULL;
   } else {
      catalog = g_new0(MsgCatalog, 1);
      catalog->utf8 = dict;
   }

   return catalog;
}
Exemplo n.º 19
0
Bool
RpcOut_sendOne(char **reply,        // OUT: Result
               size_t *repLen,      // OUT: Length of the result
               char const *reqFmt,  // IN: RPCI command
               ...)                 // Unspecified
{
    va_list args;
    Bool status;
    char *request;
    size_t reqLen = 0;

    status = FALSE;

    /* Format the request string */
    va_start(args, reqFmt);
    request = Str_Vasprintf(&reqLen, reqFmt, args);
    va_end(args);

    /*
     * If Str_Vasprintf failed, write NULL into the reply if the caller wanted
     * a reply back.
     */
    if (request == NULL) {
        if (reply) {
            *reply = NULL;
        }
        return FALSE;
    }

    /*
     * If the command doesn't contain a space, add one to the end to maintain
     * compatibility with old VMXs.
     *
     * For a long time, the GuestRpc logic in the VMX was wired to expect a
     * trailing space in every command, even commands without arguments. That is
     * no longer true, but we must continue to add a trailing space because we
     * don't know whether we're talking to an old or new VMX.
     */
    if (strchr(request, ' ') == NULL) {
        char *tmp;

        tmp = Str_Asprintf(NULL, "%s ", request);
        free(request);
        request = tmp;

        /*
         * If Str_Asprintf failed, write NULL into reply if the caller wanted
         * a reply back.
         */
        if (request == NULL) {
            if (reply != NULL) {
                *reply = NULL;
            }
            return FALSE;
        }
    }

    status = RpcOut_SendOneRaw(request, reqLen, reply, repLen);

    free(request);

    return status;
}