Example #1
0
static char *
FindSuitableExistingDirectory(
   const char *realRoot,       // IN: e.g. $HOME/.cache/vmware/drag_and_drop/
   const char *apparentRoot)   // IN: e.g. /tmp/VMwareDnD/
{
   char *result = NULL;

   char **stagingDirList;
   int numStagingDirs = File_ListDirectory(realRoot, &stagingDirList);
   int i;

   for (i = 0; i < numStagingDirs && result == NULL; i++) {
      char *stagingDir = Unicode_Append(realRoot, stagingDirList[i]);
      char *apparentStagingDir = Unicode_Append(apparentRoot, stagingDirList[i]);
      char *temp = NULL;
      struct stat sb;

      if (   File_IsEmptyDirectory(stagingDir)
          && (   Posix_Symlink(stagingDir, apparentStagingDir) == 0
              || (   Posix_Lstat(apparentStagingDir, &sb) == 0
                  && sb.st_uid == getuid()
                  && (temp = Posix_ReadLink(apparentStagingDir)) != NULL
                  && strcmp(stagingDir, temp) == 0))) {
         result = apparentStagingDir;
         apparentStagingDir = NULL;
      }

      free(stagingDir);
      free(apparentStagingDir);
      free(temp);
   }

   Util_FreeStringList(stagingDirList, numStagingDirs);
   return result;
}
Example #2
0
char *
DnD_CreateStagingDirectory(void)
{
   const char *root;
   char **stagingDirList;
   int numStagingDirs;
   int i;
   char *ret = NULL;
   Bool found = FALSE;

   /*
    * Make sure the root staging directory is created with the correct
    * permissions.
    */
   root = DnDCreateRootStagingDirectory();
   if (!root) {
      return NULL;
   }

   /* Look for an existing, empty staging directory */
   numStagingDirs = File_ListDirectory(root, &stagingDirList);
   if (numStagingDirs < 0) {
      goto exit;
   }

   for (i = 0; i < numStagingDirs; i++) {
      if (!found) {
         char *stagingDir;

         stagingDir = Unicode_Append(root, stagingDirList[i]);

         if (File_IsEmptyDirectory(stagingDir) &&
             DnDStagingDirectoryUsable(stagingDir)) {
               ret = Unicode_Append(stagingDir, DIRSEPS);
               /*
                * We can use this directory.  Make sure to continue to loop
                * so we don't leak the remaining stagindDirList[i]s.
                */
               found = TRUE;
         }

         free(stagingDir);
      }
   }

   Util_FreeStringList(stagingDirList, numStagingDirs);

   /* Only create a directory if we didn't find one above. */
   if (!found) {
      rqContext *context;

      context = Random_QuickSeed((unsigned)time(NULL));

      for (i = 0; i < 10; i++) {
         char *temp;

         /* Each staging directory is given a random name. */
         free(ret);
         temp = Unicode_Format("%08x%c", Random_Quick(context), DIRSEPC);
         VERIFY(temp);
         ret = Unicode_Append(root, temp);
         free(temp);

         if (File_CreateDirectory(ret) &&
             DnDSetPermissionsOnStagingDir(ret)) {
            found = TRUE;
            break;
         }
      }

      free(context);
   }

exit:
   if (!found && ret != NULL) {
      free(ret);
      ret = NULL;
   }

   return ret;
}