bool isSharedPath(const std::string& projectPath,
                  const core::FilePath& userHomePath)
{
#ifndef _WIN32
   // ensure this is a real path
   FilePath projectDir = FilePath::resolveAliasedPath(projectPath,
                                                      userHomePath);
   if (!projectDir.exists())
      return false;

   struct stat st;
   if (::stat(projectDir.absolutePath().c_str(), &st) == 0)
   {
      // consider this project to be shared if we aren't the owner
      if (st.st_uid != ::geteuid())
      {
         return true;
      }
   }
   else
   {
      Error error = systemError(errno, ERROR_LOCATION);
      error.addProperty("path", projectDir.absolutePath());
      LOG_ERROR(error);
   }

#endif
   return false;
}
Beispiel #2
0
void addToSystemPath(const FilePath& path, bool prepend)
{
   std::string systemPath = system::getenv("PATH");
   if (prepend)
      systemPath = path.absolutePath() + ":" + systemPath;
   else
      systemPath = systemPath + ":" + path.absolutePath();
   system::setenv("PATH", systemPath);
}
Beispiel #3
0
Error readStringFromFile(const FilePath& filePath,
                         std::string* pStr,
                         string_utils::LineEnding lineEnding)
{
   using namespace boost::system::errc ;
   
   // open file
   boost::shared_ptr<std::istream> pIfs;
   Error error = filePath.open_r(&pIfs);
   if (error)
      return error;

   try
   {
      // set exception mask (required for proper reporting of errors)
      pIfs->exceptions(std::istream::failbit | std::istream::badbit);
      
      // copy file to string stream
      std::ostringstream ostr;
      boost::iostreams::copy(*pIfs, ostr);
      *pStr = ostr.str();
      string_utils::convertLineEndings(pStr, lineEnding);

      // return success
      return Success();
   }
   catch(const std::exception& e)
   {
      Error error = systemError(boost::system::errc::io_error, 
                                ERROR_LOCATION);
      error.addProperty("what", e.what());
      error.addProperty("path", filePath.absolutePath());
      return error;
   }
}
Beispiel #4
0
Error writeStringToFile(const FilePath& filePath,
                        const std::string& str,
                        string_utils::LineEnding lineEnding)
{
   using namespace boost::system::errc ;
   
   // open file
   boost::shared_ptr<std::ostream> pOfs;
   Error error = filePath.open_w(&pOfs);
   if (error)
      return error;
   
   try
   {
      // set exception mask (required for proper reporting of errors)
      pOfs->exceptions(std::ostream::failbit | std::ostream::badbit);
      
      // copy string to file
      std::string normalized = str;
      string_utils::convertLineEndings(&normalized, lineEnding);
      std::istringstream istr(normalized);
      boost::iostreams::copy(istr, *pOfs);
      
      // return success
      return Success();
   }
   catch(const std::exception& e)
   {
      Error error = systemError(boost::system::errc::io_error, 
                                ERROR_LOCATION);
      error.addProperty("what", e.what());
      error.addProperty("path", filePath.absolutePath());
      return error;
   }
}
Beispiel #5
0
FilePath texFilePath(const std::string& logPath, const FilePath& compileDir)
{
   // some tex compilers report file names with absolute paths and some
   // report them relative to the compilation directory -- on Posix use
   // realPath to get a clean full path back -- note the fact that we
   // don't do this on Windows is a tacit assumption that Windows TeX logs
   // are either absolute or don't require interpretation of .., etc.

   FilePath path = compileDir.complete(logPath);

#ifdef _WIN32
   return path;
#else
   FilePath realPath;
   Error error = core::system::realPath(path.absolutePath(), &realPath);
   if (error)
   {
      LOG_ERROR(error);
      return path;
   }
   else
   {
      return realPath;
   }
#endif
}
Beispiel #6
0
   bool validate(const FilePath& userHomePath,
                 bool projectSharingEnabled) const
   {
      // ensure the scratch path and properties paths exist
      if (!scratchPath_.exists() || !propertiesPath_.exists())
         return false;

      // ensure the properties are there
      if (project().empty() || workingDir().empty() || (lastUsed() == 0))
          return false;

      // for projects validate that the base directory still exists
      std::string theProject = project();
      if (theProject != kProjectNone)
      {
         FilePath projectDir = FilePath::resolveAliasedPath(theProject,
                                                            userHomePath);
         if (!projectDir.exists())
            return false;

        // check for project file
        FilePath projectPath = r_util::projectFromDirectory(projectDir);
        if (!projectPath.exists())
           return false;

        // if we got this far the scope is valid, do one final check for
        // trying to open a shared project if sharing is disabled
        if (!projectSharingEnabled &&
            r_util::isSharedPath(projectPath.absolutePath(), userHomePath))
           return false;
      }

      // validated!
      return true;
   }
Beispiel #7
0
inline Error changeFileMode(const FilePath& filePath, FileMode fileMode)
{
   mode_t mode ;
   switch(fileMode)
   {
      case UserReadWriteMode:
         mode = S_IRUSR | S_IWUSR;
         break;

      case UserReadWriteGroupReadMode:
         mode = S_IRUSR | S_IWUSR | S_IRGRP ;
         break;

      case EveryoneReadWriteMode:
         mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
         break;

      case EveryoneReadWriteExecuteMode:
         mode = S_IRWXU | S_IRWXG | S_IRWXO;
         break;

      default:
         return systemError(ENOTSUP, ERROR_LOCATION);
   }

   // change the mode
   errno = 0;
   if (::chmod(filePath.absolutePath().c_str(), mode) < 0)
      return systemError(errno, ERROR_LOCATION);
   else
      return Success();
}
Error SourceManager::source(const FilePath& filePath, bool local)
{
   std::string localPrefix = local ? "local(" : "";
   std::string localParam = local ? "TRUE" : "FALSE" ;
   std::string localSuffix = local ? ")" : "";
      
   // do \ escaping (for windows)
   std::string path = filePath.absolutePath();
   boost::algorithm::replace_all(path, "\\", "\\\\");

   // Build the code. If this build is targeted for debugging, keep the source
   // code around; otherwise, turn it off to conserve memory and expose fewer
   // internals to the user.
   std::string rCode = localPrefix + "source(\"" 
                           + path + "\", " +
                           "local=" + localParam + ", " + 
                           "echo=FALSE, " +
                           "verbose=FALSE, " + 
#ifdef NDEBUG
                           "keep.source=FALSE, " +
#else
                           "keep.source=TRUE, " +
#endif
                           "encoding='UTF-8')" + localSuffix;
      
   // record that we sourced the file. 
   recordSourcedFile(filePath, local);

   // source the file
   return r::exec::executeString(rCode); 
}
Beispiel #9
0
void GwtCallback::showKeyboardShortcutHelp()
{
   FilePath keyboardHelpPath = options().wwwDocsPath().complete("keyboard.htm");
   QString file = QString::fromUtf8(keyboardHelpPath.absolutePath().c_str());
   QUrl url = QUrl::fromLocalFile(file);
   desktop::openUrl(url);
}
Beispiel #10
0
Error saveDefaultGlobalEnvironment()
{
   // path to save to
   FilePath globalEnvPath = rSaveGlobalEnvironmentFilePath();

   // notify client of serialization status
   SerializationCallbackScope cb(kSerializationActionSaveDefaultWorkspace,
                                 globalEnvPath);

   // suppress interrupts which occur during saving
   r::exec::IgnoreInterruptsScope ignoreInterrupts;
         
   // save global environment
   std::string path = string_utils::utf8ToSystem(globalEnvPath.absolutePath());
   Error error = r::exec::executeSafely(
                    boost::bind(R_SaveGlobalEnvToFile, path.c_str()));
   
   if (error)
   {
      return error;
   }
   else
   {
      return Success();
   }
}
Beispiel #11
0
Error restoreDefaultGlobalEnvironment()
{
    // restore the default global environment if there is one
    FilePath globalEnvPath = s_options.startupEnvironmentFilePath;
    if (globalEnvPath.exists())
    {
        // notify client of serialization status
        SerializationCallbackScope cb(kSerializationActionLoadDefaultWorkspace,
                                      globalEnvPath);

        // ignore interrupts which occur during restoring of the global env
        // the restoration will run to completion in any case and then the
        // next thing the user does will be "interrupted" -- clearly not
        // what they intended
        r::exec::IgnoreInterruptsScope ignoreInterrupts;


        Error error = r::exec::executeSafely(boost::bind(
                R_RestoreGlobalEnvFromFile,
                globalEnvPath.absolutePath().c_str(),
                TRUE));
        if (error)
            return error;

        // print path to console
        std::string aliasedPath = createAliasedPath(globalEnvPath);
        Rprintf(("[Workspace loaded from " + aliasedPath + "]\n\n").c_str());
    }

    // mark image clean (we need to do this due to our delayed handling
    // of workspace restoration)
    markImageClean();

    return Success();
}
Beispiel #12
0
Error detectZipFileOverwrites(const FilePath& uploadedZipFile,
                              const FilePath& destDir,
                              json::Array* pOverwritesJson)
{
   // query for all of the paths in the zip file
   std::vector<std::string> zipFileListing;
   r::exec::RFunction listZipFile(".rs.listZipFile",
                                  uploadedZipFile.absolutePath());
   Error unzipError = listZipFile.call(&zipFileListing);
   if (unzipError)
      return unzipError;
   
   // check for overwrites
   for (std::vector<std::string>::const_iterator 
        it = zipFileListing.begin();
        it != zipFileListing.end();
        ++it)
   {
      FilePath filePath = destDir.complete(*it);
      if (filePath.exists())
         pOverwritesJson->push_back(module_context::createFileSystemItem(filePath));
   }
   
   return Success();
}
Beispiel #13
0
SEXP rs_pathInfo(SEXP pathSEXP)
{
   try
   {
      // validate
      if (r::sexp::length(pathSEXP) != 1)
      {
         throw r::exec::RErrorException(
                        "must pass a single file to get path info for");
      }

      std::string path;
      Error error = r::sexp::extract(pathSEXP, &path);
      if (error)
         throw r::exec::RErrorException(r::endUserErrorMessage(error));

      // resolve aliased path
      FilePath filePath = module_context::resolveAliasedPath(path);
      if (filePath.empty())
         throw r::exec::RErrorException("invalid path: " + path);

      // create path info vector (use json repsesentation to force convertion
      // to VECSXP rather than STRSXP)
      json::Object pathInfo;
      pathInfo["path"] = filePath.absolutePath();
      std::string parent = filePath.absolutePath();
      FilePath parentPath = filePath.parent();
      if (!parentPath.empty())
         parent = parentPath.absolutePath();
      pathInfo["directory"] = parent;
      pathInfo["name"] = filePath.filename();
      pathInfo["stem"] = filePath.stem();
      pathInfo["extension"] = filePath.extension();

      // return it
      r::sexp::Protect rProtect;
      return r::sexp::create(pathInfo, &rProtect);
   }
   catch(r::exec::RErrorException e)
   {
      r::exec::error(e.message());
   }
   CATCH_UNEXPECTED_EXCEPTION

   return R_NilValue;
}
Error PlotManipulator::save(const FilePath& filePath) const
{
   // call manipulator save
   r::exec::RFunction manipSave("manipulate:::manipulatorSave");
   manipSave.addParam(sexp_.get());
   manipSave.addParam(filePath.absolutePath());
   return manipSave.call();
}
void UserSettings::setWorkingDirectoryValue(const std::string& key,
                                            const FilePath& filePath)
{
   if (module_context::createAliasedPath(filePath) == "~")
      settings_.set(key, std::string("~"));
   else
      settings_.set(key, filePath.absolutePath());
}
bool readPresentation(SlideDeck* pSlideDeck,
                      std::string* pSlides,
                      std::string* pInitActions,
                      std::string* pSlideActions,
                      std::map<std::string,std::string>* pVars,
                      std::string* pErrMsg)
{
   // look for slides and knit if we need to
   FilePath rmdFile = presentation::state::filePath();
   std::string ext = rmdFile.extensionLowerCase();
   if (rmdFile.exists() && (ext != ".md"))
   {
      if (!performKnit(rmdFile, pErrMsg))
         return false;
   }

   // look for slides markdown
   FilePath slidesFile = rmdFile.parent().childPath(rmdFile.stem() + ".md");
   if (!slidesFile.exists())
   {
      *pErrMsg = slidesFile.absolutePath() + " not found";
      return false;
   }

   // parse the slides
   Error error = pSlideDeck->readSlides(slidesFile);
   if (error)
   {
      LOG_ERROR(error);
      *pErrMsg = error.summary();
      return false;
   }

   // render the slides
   std::string revealConfig;
   error = presentation::renderSlides(*pSlideDeck,
                                      pSlides,
                                      &revealConfig,
                                      pInitActions,
                                      pSlideActions);
   if (error)
   {
      LOG_ERROR(error);
      *pErrMsg = error.summary();
      return false;
   }

   // build template variables
   std::map<std::string,std::string>& vars = *pVars;
   vars["title"] = pSlideDeck->title();
   vars["slides"] = *pSlides;
   vars["slides_css"] =  resourceFiles().get("presentation/slides.css");
   vars["r_highlight"] = resourceFiles().get("r_highlight.html");
   vars["reveal_config"] = revealConfig;
   vars["preamble"] = pSlideDeck->preamble();

   return true;
}
Beispiel #17
0
VCSStatus StatusResult::getStatus(const FilePath& fileOrDirectory) const
{
   std::map<std::string, VCSStatus>::const_iterator found =
         this->filesByPath_.find(fileOrDirectory.absolutePath());
   if (found != this->filesByPath_.end())
      return found->second;

   return VCSStatus();
}
Beispiel #18
0
Error getScriptRunCommand(const json::JsonRpcRequest& request,
                          json::JsonRpcResponse* pResponse)
{
   // params
   std::string interpreter, path;
   Error error = json::readParams(request.params, &interpreter, &path);
   if (error)
      return error ;
   FilePath filePath = module_context::resolveAliasedPath(path);

   // use as minimal a path as possible
   FilePath currentPath = module_context::safeCurrentPath();
   if (filePath.isWithin(currentPath))
   {
      path = filePath.relativePath(currentPath);
      if (interpreter.empty())
      {
#ifndef _WINDOWS
         if (path.find_first_of('/') == std::string::npos)
            path = "./" + path;
      }
#endif
   }
   else
   {
      path = filePath.absolutePath();
   }

   // quote if necessary
   if (path.find_first_of(' ') != std::string::npos)
      path = "\\\"" + path + "\\\"";

   // if there's no interpreter then we may need to do a chmod
#ifndef _WINDOWS
   if (interpreter.empty())
   {
      error = r::exec::RFunction(
                 "system",
                  "chmod +x " +
                  string_utils::utf8ToSystem(path)).call();
      if (error)
         return error;
   }
#endif

   // now build and return the command
   std::string command;
   if (interpreter.empty())
      command = path;
   else
      command = interpreter + " " + path;
   command = "system(\"" + command + "\")";

   pResponse->setResult(command);

   return Success();
}
Beispiel #19
0
bool detectLineEndings(const FilePath& filePath, LineEnding* pType)
{
   if (!filePath.exists())
      return false;

   boost::shared_ptr<std::istream> pIfs;
   Error error = filePath.open_r(&pIfs);
   if (error)
   {
      LOG_ERROR(error);
      return false;
   }

   // read file character-by-character using a streambuf
   try
   {
      std::istream::sentry se(*pIfs, true);
      std::streambuf* sb = pIfs->rdbuf();

      while(true)
      {
         int ch = sb->sbumpc();

         if (ch == '\n')
         {
            // using posix line endings
            *pType = string_utils::LineEndingPosix;
            return true;
         }
         else if (ch == '\r' && sb->sgetc() == '\n')
         {
            // using windows line endings
            *pType = string_utils::LineEndingWindows;
            return true;
         }
         else if (ch == EOF)
         {
            break;
         }
         else if (pIfs->fail())
         {
            LOG_WARNING_MESSAGE("I/O Error reading file " +
                                filePath.absolutePath());
            break;
         }
      }
   }
   CATCH_UNEXPECTED_EXCEPTION

   // no detection possible (perhaps the file is empty or has only one line)
   return false;
}
void Options::resolvePandocPath(const FilePath& resourcePath,
                                std::string* pPath)
{
   if (*pPath == kDefaultPandocPath)
   {
      FilePath path = resourcePath.parent().complete("MacOS/pandoc");
      *pPath = path.absolutePath();
   }
   else
   {
      resolvePath(resourcePath, pPath);
   }
}
Beispiel #21
0
// installation path
Error installPath(const std::string& relativeToExecutable,
                  const char * argv0,
                  FilePath* pInstallPath)
{
   // get executable path
   FilePath executablePath;
   Error error = system::executablePath(argv0, &executablePath);
   if (error)
      return error;

   // fully resolve installation path relative to executable
   FilePath installPath = executablePath.parent().complete(relativeToExecutable);
   return realPath(installPath.absolutePath(), pInstallPath);
}
Error PlotManipulator::load(const FilePath& filePath)
{
   // call manipulator load
   r::exec::RFunction manipLoad("manipulate:::manipulatorLoad");
   manipLoad.addParam(filePath.absolutePath());
   r::sexp::Protect rProtect;
   SEXP manipSEXP;
   Error error = manipLoad.call(&manipSEXP, &rProtect);
   if (error)
      return error;

   // set it
   sexp_.set(manipSEXP);
   return Success();
}
Beispiel #23
0
Error FilePath::copy(const FilePath& targetPath) const
{
   try
   {
      boost::filesystem::copy_file(pImpl_->path, targetPath.pImpl_->path) ;
      return Success() ;
   }
   catch(const boost::filesystem::filesystem_error& e)
   {
      Error error(e.code(), ERROR_LOCATION) ;
      addErrorProperties(pImpl_->path, &error) ;   
      error.addProperty("target-path", targetPath.absolutePath()) ;
      return error ;
   }   
}
void Options::resolvePostbackPath(const FilePath& resourcePath,
                                  std::string* pPath)
{
   // On OSX we keep the postback scripts over in the MacOS directory
   // rather than in the Resources directory -- make this adjustment
   // when the default postback path has been passed
   if (*pPath == kDefaultPostbackPath)
   {
      FilePath path = resourcePath.parent().complete("MacOS/postback/rpostback");
      *pPath = path.absolutePath();
   }
   else
   {
      resolvePath(resourcePath, pPath);
   }
}
Beispiel #25
0
void onResume(const Settings& settings)
{
   // get the monitored path
   std::string monitoredPath = settings.get(kMonitoredPath);
   if (!monitoredPath.empty())
   {
      // resolve aliases
      FilePath resolvedPath = FilePath::resolveAliasedPath(
                                            monitoredPath,
                                            module_context::userHomePath());

      // start monitoriing
      startMonitoring(resolvedPath.absolutePath());
   }

   quotas::checkQuotaStatus();
}
Beispiel #26
0
   static boost::shared_ptr<AutoSnapshot> create(
         const FilePath& projectDir, 
         const std::string& targetHash)
   {
      boost::shared_ptr<AutoSnapshot> pSnapshot(new AutoSnapshot());
      std::string snapshotCmd;
      Error error = r::exec::RFunction(
            ".rs.getAutoSnapshotCmd",
            projectDir.absolutePath()).call(&snapshotCmd);
      if (error)
         LOG_ERROR(error); // will also be reported in the console

      PACKRAT_TRACE("starting auto snapshot, R command: " << snapshotCmd);
      pSnapshot->setTargetHash(targetHash);
      pSnapshot->start(snapshotCmd.c_str(), projectDir, 
                       async_r::R_PROCESS_VANILLA);
      return pSnapshot;
   }
Beispiel #27
0
Error extractVariables(const FilePath& file, Variables* pVariables)
{
   // return path not found if necessary
   if (!file.exists())
      return core::pathNotFoundError(file.absolutePath(), ERROR_LOCATION);

   // read in the file
   std::string contents;
   Error error = readStringFromFile(file,
                                    &contents,
                                    string_utils::LineEndingPosix);
   if (error)
      return error;

   extractVariables(contents, pVariables);

   return Success();
}
Error PlotManager::savePlotAsSvg(const FilePath& targetPath,
                                 int width,
                                 int height)
{
   // calculate size in inches
   double widthInches = pixelsToInches(width);
   double heightInches = pixelsToInches(height);

   // generate code for creating svg device
   boost::format fmt("{ require(grDevices, quietly=TRUE); "
                     "  svg(filename=\"%1%\", width=%2%, height=%3%, "
                     "      antialias = \"subpixel\"); }");
   std::string deviceCreationCode = boost::str(fmt % string_utils::utf8ToSystem(targetPath.absolutePath()) %
                                                     widthInches %
                                                     heightInches);

   return savePlotAsFile(deviceCreationCode);
}
Beispiel #29
0
// IN: String path
// OUT: Array<FileEntry> files
core::Error listFiles(const json::JsonRpcRequest& request, 
                      json::JsonRpcResponse* pResponse)
{
   // get path
   std::string path;
   bool monitor;
   Error error = json::readParams(request.params, &path, &monitor);
   if (error)
      return error ;
   
   // retreive list of files
   FilePath targetPath = module_context::resolveAliasedPath(path) ;
   std::vector<FilePath> files ;
   Error listingError = targetPath.children(&files) ;
   if (listingError)
      return listingError ;

   // sort the files by name
   std::sort(files.begin(), files.end(), compareAbsolutePathNoCase);
   
   // produce json listing
   json::Array jsonFiles ;
   BOOST_FOREACH( FilePath& filePath, files )
   {
      // files which may have been deleted after the listing or which
      // are not end-user visible
      if (filePath.exists() && isVisible(filePath))
      {
         json::Object fileObject = module_context::createFileSystemItem(filePath);
         jsonFiles.push_back(fileObject) ;
      }
   }

   // return listing
   pResponse->setResult(jsonFiles) ;
   
   // setup monitoring if requested (merely log errors so if something
   // unexpected happens the user still gets the file listing)
   if (monitor)
      startMonitoring(targetPath.absolutePath());
   
   // success
   return Success();
}
Beispiel #30
0
std::string FilePath::createAliasedPath(const FilePath& path,
                              const FilePath& userHomePath)
{
   // Special case for "~"
   if (path == userHomePath)
      return kHomePathLeafAlias;

   // if the path is contained within the home path then alias it
   std::string homeRelativePath = path.relativePath(userHomePath);
   if (!homeRelativePath.empty())
   {
      std::string aliasedPath = kHomePathAlias + homeRelativePath;
      return aliasedPath;
   }
   else  // no aliasing
   {
      return path.absolutePath();
   }
}