Exemple #1
0
    inline bool FindModule(std::string baseName, std::string *fileName, Module *hint)
    {
        // Try first in the current directory.
        if(ExistsFile(baseName))
        {
            *fileName = baseName;
            return true;
        }

        // Now, use the hint.
        if(hint)
        {
            // Check in the same directory as the module.
            std::string modDir = DirName(hint->GetName().filename);
            *fileName = JoinPath(modDir, baseName);
            if(ExistsFile(*fileName))
                return true;

            // Check in the library search path.
            for(size_t i = 0; i < hint->GetLibraryPathCount(); ++i)
            {
                *fileName = JoinPath(hint->GetLibraryPath(i), baseName);
                if(ExistsFile(*fileName))
                    return true;
            }
        }

        return false;
    }
Exemple #2
0
int CompressPath(char *dest, const char *src)
{
    char node[CF_BUFSIZE];
    int nodelen;
    int rootlen;

    memset(dest, 0, CF_BUFSIZE);

    rootlen = RootDirLength(src);
    strncpy(dest, src, rootlen);

    for (const char *sp = src + rootlen; *sp != '\0'; sp++)
    {
        if (IsFileSep(*sp))
        {
            continue;
        }

        for (nodelen = 0; (sp[nodelen] != '\0') && (!IsFileSep(sp[nodelen])); nodelen++)
        {
            if (nodelen > CF_MAXLINKSIZE)
            {
                Log(LOG_LEVEL_ERR, "Link in path suspiciously large");
                return false;
            }
        }

        strncpy(node, sp, nodelen);
        node[nodelen] = '\0';

        sp += nodelen - 1;

        if (strcmp(node, ".") == 0)
        {
            continue;
        }

        if (strcmp(node, "..") == 0)
        {
            if (!ChopLastNode(dest))
            {
                Log(LOG_LEVEL_DEBUG, "used .. beyond top of filesystem!");
                return false;
            }

            continue;
        }
        else
        {
            AddSlash(dest);
        }

        if (!JoinPath(dest, node))
        {
            return false;
        }
    }

    return true;
}
Exemple #3
0
HelpWindow::HelpWindow()
{
    resize( 600,500);
    QTextEdit* content = new QTextEdit();
    content->setReadOnly(true);
    {
        QFile file( JoinPath(g_App->DataPath(), "help.html").c_str() );
        if(file.open(QIODevice::ReadOnly | QIODevice::Text))
        {
            QString help_txt;
            help_txt = file.readAll();
            content->setHtml(help_txt);
        }
    }

    QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok);
    connect(buttonBox, SIGNAL(accepted()), this, SLOT(hide()));

    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(content);
    mainLayout->addWidget(buttonBox);
    setLayout(mainLayout);

    setWindowTitle(tr("Help"));
}
Exemple #4
0
bool CRConFiles::CheckParentFolders(LPCWSTR asParentDir, LPCWSTR asFilePath, CEStr& szFull)
{
	bool bFound = false;

	// Try to go to parent folder (useful while browsing git-diff-s or #include-s)
	CEStr lsParent = asParentDir;
	MBoxAssert(lsParent.ms_Val && !wcschr(lsParent.ms_Val, L'/')); // WinPath is expected
	for (int i = 6; i >= 0; --i)
	{
		wchar_t* pszDirSlash = wcsrchr(lsParent.ms_Val, L'\\');
		// Stop on the network server's root and drive letter
		if (!pszDirSlash || (pszDirSlash - lsParent.ms_Val) <= 2 || *(pszDirSlash-1) == L':')
			break;
		*pszDirSlash = 0;
		// Does it exist?
		if ((bFound = FileExistSubDir(lsParent, asFilePath, 1, szFull)))
			break;
		// Don't try to go upper, if current folder already contains ".git" (root of the repo)
		if (i > 0)
		{
			CEStr szGit(JoinPath(lsParent, L".git"));
			if (DirectoryExists(szGit))
				break;
		}
	}

	return bFound;
}
Exemple #5
0
bool CConEmuStart::FindBashLocation(CEStr& lsBash)
{
	wchar_t szRoot[MAX_PATH+32], *pszSlash;
	wcscpy_c(szRoot, gpConEmu->ms_ConEmuExeDir);

	LPCWSTR pszPlaces[] = {
		L"\\msys\\1.0\\bin\\bash.exe",  // Msys/MinGW
		L"\\bin\\bash.exe",             // Git-Bash
		L"\\usr\\bin\\bash.exe",        // Git-For-Windows
		NULL
	};

	// Before ConEmu.exe was intended to be in /bin/ folder
	// With Git-For-Windows it may be places in /opt/bin/ subfolder
	// So we do searching with two steps
	for (size_t i = 0; i <= 1; i++)
	{
		pszSlash = wcsrchr(szRoot, L'\\');
		if (pszSlash)
			*pszSlash = 0;

		for (size_t j = 0; pszPlaces[j]; j++)
		{
			lsBash = JoinPath(szRoot, pszPlaces[j]);
			if (FileExists(lsBash))
			{
				return true;
			}
		}
	}

	// Last chance, without path
	lsBash = L"bash.exe";
	return false;
}
Exemple #6
0
void ForceDir(const char* dir)
{
  if (dir != NULL)
  {
    const char* startDir = dir;
#if defined(CFG_OS_WINDOWS)
    // Skip "X:" (if dir is Windows file path)
    if (startDir[0] != '\0' && startDir[1] == ':')
      startDir += 2;
#endif
    // Skip \\ and // (if dir is network path)
    while (IsPathDelimiter(*startDir))
      ++startDir;
    // Split path into parts and add server name if dir is network path
    MultiString dirs(startDir, FILE_PATH_DELIMITERS, NULL);
    std::string path(dir, startDir - dir);
    int i = 0;
    if (startDir != dir && dirs.word_count() > 0) // if dir is network path
    {
      path.append(dirs.word(0));
      i = 1;
    }
    // Create directories
    while (i < dirs.word_count())
    {
      path = JoinPath(path.c_str(), dirs.word(i));
      if (!DirExists(path.c_str()))
        CreateDir(path.c_str());
      ++i;
    }
  }
  else
    throw CreateArgumentNullException();
}
Exemple #7
0
bool FileEnumerator::MoveNext()
{
  bool result = false;
  if (!m_StartupDir.empty())
  {
    if (m_CurrentNonRecursiveEnumerator == NULL)
      m_CurrentNonRecursiveEnumerator = new NonRecursiveFileEnumerator(NULL, m_StartupDir.c_str());
    // Enter directory if mode is recursive
    if ((m_Flags & DIRENUM_RECURSIVE_MODE) != 0 && 
      !m_CurrentNonRecursiveEnumerator->Bof() && 
      !m_CurrentNonRecursiveEnumerator->Eof() && 
      IsDir(CurrentPath()))
    {
      //std::string s = m_EntriesEnumerator->StartupDir();
      std::string s = JoinPath(CurrentDir(), m_CurrentNonRecursiveEnumerator->CurrentFileName());
      m_CurrentNonRecursiveEnumerator = new NonRecursiveFileEnumerator(m_CurrentNonRecursiveEnumerator, s.c_str());
    }
    // Find next entry
    result = m_CurrentNonRecursiveEnumerator->MoveNext();
    while (!result && m_CurrentNonRecursiveEnumerator->Parent() != NULL)
    {
      // Go to the parent directory
      NonRecursiveFileEnumerator* p = m_CurrentNonRecursiveEnumerator;
      m_CurrentNonRecursiveEnumerator = p->Parent();
      delete p;
      result = m_CurrentNonRecursiveEnumerator->MoveNext();
    }
    m_Flags &= ~DIRENUM_CURRENT_CACHED;
  }
  return result;
}
Exemple #8
0
bool GetRepositoryPath(const char *file, Attributes attr, char *destination)
{
    if ((attr.repository == NULL) && (VREPOSITORY == NULL))
    {
        return false;
    }

    size_t repopathlen;

    if (attr.repository != NULL)
    {
        repopathlen = strlcpy(destination, attr.repository, CF_BUFSIZE);
    }
    else
    {
        repopathlen = strlcpy(destination, VREPOSITORY, CF_BUFSIZE);
    }

    if (!JoinPath(destination, file))
    {
        Log(LOG_LEVEL_ERR, "Internal limit, buffer ran out of space for long filename");
        return false;
    }

    for (char *s = destination + repopathlen; *s; s++)
    {
        if (*s == FILE_SEPARATOR)
        {
            *s = REPOSCHAR;
        }
    }

    return true;
}
Exemple #9
0
void UnitFileNamesTest()
{
	_ASSERTE(IsDotsName(L"."));
	_ASSERTE(IsDotsName(L".."));
	_ASSERTE(!IsDotsName(L"..."));
	_ASSERTE(!IsDotsName(L""));

	struct {
		LPCWSTR asPath, asPart1, asPart2, asResult;
	} Tests[] = {
		{L"C:", L"Dir", L"File.txt", L"C:\\Dir\\File.txt"},
		{L"C:\\", L"\\Dir\\", L"\\File.txt", L"C:\\Dir\\File.txt"},
		{L"C:\\", L"\\File.txt", NULL, L"C:\\File.txt"},
		{L"C:", L"\\File.txt", NULL, L"C:\\File.txt"},
		{L"C:\\", L"File.txt", NULL, L"C:\\File.txt"},
		{NULL}
	};
	bool bCheck;
	wchar_t* pszJoin;
	for (size_t i = 0; Tests[i].asPath; i++)
	{
		pszJoin = JoinPath(Tests[i].asPath, Tests[i].asPart1, Tests[i].asPart2);
		bCheck = (pszJoin && (lstrcmp(pszJoin, Tests[i].asResult) == 0));
		_ASSERTE(bCheck);
		SafeFree(pszJoin);
	}
	bCheck = true;
}
Exemple #10
0
bool NonRecursiveFileEnumerator::DoMoveNext()
{
  bool result = false;
#ifdef CFG_WIN32
  if (m_Data != NULL)
  {
    if (m_Handle == NULL_HANDLE)
    {
      std::string t = JoinPath(m_StartupDir.c_str(), "*"); // Windows always expects wildcard
      m_Handle = FindFirstFile(t.c_str(), m_Data);
      result = m_Handle != NULL_HANDLE;
    }
    else
      result = FindNextFile(m_Handle, m_Data) == TRUE;
  }
#endif
#ifdef CFG_POSIX
  if (m_Handle != NULL_HANDLE)
  {
    m_Data = readdir(m_Handle);
    result = m_Data != NULL;
  }
#endif
  if (!result)
    Finalize();
  return result;
}
bool SBMLModelSimulation::SetModelFileName(const string& name)
{
    if(ExtractFilePath(name).size() > 0)
    {
        mModelFilePath = ExtractFilePath(name);
    }

    mModelFileName = ExtractFileName(name);

    if(!FileExists(JoinPath(mModelFilePath, mModelFileName)))
    {
        Log(lError)<<"The file: "<<JoinPath(mModelFilePath, mModelFileName)<<" don't exist.";
        return false;
    }

    return true;
}
int ArchiveToRepository(const char *file, Attributes attr, Promise *pp, const ReportContext *report_context)
 /* Returns true if the file was backup up and false if not */
{
    char destination[CF_BUFSIZE];
    struct stat sb, dsb;

    if (!GetRepositoryPath(file, attr, destination))
    {
        return false;
    }

    if (attr.copy.backup == cfa_nobackup)
    {
        return true;
    }

    if (IsItemIn(VREPOSLIST, file))
    {
        CfOut(OUTPUT_LEVEL_INFORM, "",
              "The file %s has already been moved to the repository once. Multiple update will cause loss of backup.",
              file);
        return true;
    }

    ThreadLock(cft_getaddr);
    PrependItemList(&VREPOSLIST, file);
    ThreadUnlock(cft_getaddr);

    CfDebug("Repository(%s)\n", file);
    
    JoinPath(destination, CanonifyName(file));

    if (!MakeParentDirectory(destination, attr.move_obstructions, report_context))
    {
    }

    if (cfstat(file, &sb) == -1)
    {
        CfDebug("File %s promised to archive to the repository but it disappeared!\n", file);
        return true;
    }

    cfstat(destination, &dsb);

    CheckForFileHoles(&sb, pp);

    if (pp && CopyRegularFileDisk(file, destination, pp->makeholes))
    {
        CfOut(OUTPUT_LEVEL_INFORM, "", "Moved %s to repository location %s\n", file, destination);
        return true;
    }
    else
    {
        CfOut(OUTPUT_LEVEL_INFORM, "", "Failed to move %s to repository location %s\n", file, destination);
        return false;
    }
}
Exemple #13
0
const char* FileEnumerator::CurrentPath()
{
  if ((m_Flags & DIRENUM_CURRENT_CACHED) == 0)
  {
    m_Current = JoinPath(CurrentDir(), CurrentFileName());
    m_Flags |= DIRENUM_CURRENT_CACHED;
  }
  return m_Current.c_str();
}
Exemple #14
0
int ArchiveToRepository(const char *file, Attributes attr)
 /* Returns true if the file was backup up and false if not */
{
    char destination[CF_BUFSIZE];
    struct stat sb, dsb;

    if (!GetRepositoryPath(file, attr, destination))
    {
        return false;
    }

    if (attr.copy.backup == BACKUP_OPTION_NO_BACKUP)
    {
        return true;
    }

    if (IsItemIn(VREPOSLIST, file))
    {
        Log(LOG_LEVEL_INFO,
            "The file '%s' has already been moved to the repository once. Multiple update will cause loss of backup.",
              file);
        return true;
    }

    ThreadLock(cft_getaddr);
    PrependItemList(&VREPOSLIST, file);
    ThreadUnlock(cft_getaddr);
    
    JoinPath(destination, CanonifyName(file));

    if (!MakeParentDirectory(destination, attr.move_obstructions))
    {
    }

    if (stat(file, &sb) == -1)
    {
        Log(LOG_LEVEL_DEBUG, "File '%s' promised to archive to the repository but it disappeared!", file);
        return true;
    }

    stat(destination, &dsb);

    if (CopyRegularFileDisk(file, destination))
    {
        Log(LOG_LEVEL_INFO, "Moved '%s' to repository location '%s'", file, destination);
        return true;
    }
    else
    {
        Log(LOG_LEVEL_INFO, "Failed to move '%s' to repository location '%s'", file, destination);
        return false;
    }
}
bool SBMLModelSimulation::SaveResult()
{
    string resultFileName(JoinPath(mDataOutputFolder, "rr_" + mModelFileName));
    resultFileName = ChangeFileExtensionTo(resultFileName, ".csv");
    Log(lInfo)<<"Saving result to file: "<<resultFileName;
    SimulationData resultData = mEngine->getSimulationResult();

    ofstream fs(resultFileName.c_str());
    fs << resultData;
    fs.close();
    return true;
}
void MakeOptDest(const std::string &src, std::string &dest)
{
    TSTLStrSize len = dest.length();
    
    // Strip trailing /'s
    while (len && (dest[len-1] == '/'))
    {
        dest.erase(len-1, 1);
        len--;
    }
    
    if (IsDir(dest))
        dest = JoinPath(dest, BaseName(src));
}
Exemple #17
0
	bool FileSourceFS::ReadDirectory(const std::string &dirpath, std::vector<FileInfo> &output)
	{
		const std::string fulldirpath = JoinPathBelow(GetRoot(), dirpath);
		DIR *dir = opendir(fulldirpath.c_str());
		if (!dir) { return false; }
		struct dirent *entry;

		const size_t output_head_size = output.size();

		while ((entry = readdir(dir))) {
			if (strcmp(entry->d_name, ".") == 0) continue;
			if (strcmp(entry->d_name, "..") == 0) continue;

			const std::string fullpath = JoinPath(fulldirpath, entry->d_name);

			FileInfo::FileType ty;
			switch (entry->d_type) {
				case DT_DIR: ty = FileInfo::FT_DIR; break;
				case DT_REG: ty = FileInfo::FT_FILE; break;
				case DT_LNK: case DT_UNKNOWN:
				{
					// if readdir() can't tell us whether we've got a file or directory then we need to stat
					// also stat for links to traverse them
					struct stat statinfo;
					if (stat(fullpath.c_str(), &statinfo) == 0) {
						if (S_ISREG(statinfo.st_mode)) {
							ty = FileInfo::FT_FILE;
						} else if (S_ISDIR(statinfo.st_mode)) {
							ty = FileInfo::FT_DIR;
						} else {
							ty = FileInfo::FT_SPECIAL;
						}
					} else {
						// XXX error out here?
						ty = FileInfo::FT_NON_EXISTENT;
					}
					break;
				}
				default: ty = FileInfo::FT_SPECIAL; break;
			}

			output.push_back(MakeFileInfo(fullpath.substr(GetRoot().size() + 1), ty));
		}

		closedir(dir);

		std::sort(output.begin() + output_head_size, output.end());
		return true;
	}
Exemple #18
0
void Resources::Init()
{
    char buf[PATH_MAX];
    if( osx_get_resource_path(buf,PATH_MAX) )
    {
        s_ResourcePath = JoinPath(buf,"data");
        log_infof("data: %s\n", s_ResourcePath.c_str());
    }
    else
    {
        log_infof("couldn't get path for data\n");
        // uhoh...
        s_ResourcePath = "./data";
    }
}
Exemple #19
0
gcc_malloc gcc_nonnull_all
static char *
FindInSearchPaths(const char *suffix)
{
  const auto suffix_length = StringLength(suffix);

  for (const char *const* i = font_search_paths; *i != nullptr; ++i) {
    const char *path = *i;

    auto *full_path = JoinPath(path, suffix, suffix_length);
    if (File::Exists(full_path))
      return full_path;

    delete[] full_path;
  }

  return nullptr;
}
bool SBMLModelSimulation::SaveModelAsXML(const string& folder)
{
    if(!mEngine)
    {
        return false;
    }
    string fName = JoinPath(folder, mModelFileName);
    fName = ChangeFileExtensionTo(fName, "xml");

    fstream fs(fName.c_str(), fstream::out);

    if(!fs)
    {
        Log(lError)<<"Failed writing sbml to file "<< fName;
        return false;
    }
    fs<<mEngine->getSBML();
    fs.close();
    return true;
}
Exemple #21
0
void ZigConfig::Save() const
{
	std::string outname = JoinPath( ZigUserDir(), "options" );

	std::ofstream out( outname.c_str() );

	if( !out.good() )
		return;

	if( fullscreen )
		out << "fullscreen" << std::endl;
	else
		out << "window" << std::endl;

#if 0
	out << "width " << width << std::endl;
	out << "height " << height << std::endl;
	out << "depth " << depth << std::endl;
#endif
}
Exemple #22
0
// ac and av are commandline options passed along from main()
// Commandline options override config file options.
void ZigConfig::Init( int ac, char* av[] )
{
	// try to read in opts from file
	{
		std::string inname = JoinPath( ZigUserDir(), "options" );
		std::ifstream in( inname.c_str() );
		int linenum = 0;
		while( in.good() )
		{
			std::string line;
			std::getline( in, line );
			++linenum;

			std::vector< std::string > opts;
			SplitLine( line, opts );

			if( opts.empty() )		// ignore blank lines
				continue;

			ApplyOption( *this, opts );
		}
	}

	// now apply commandline opts on top.
	int i=1;
	while( i<ac )
	{
		std::vector< std::string > opt;
		if( av[i][0] != '-' )
			throw Wobbly( "Syntax error: '%s'", av[i] );
		opt.push_back( &av[i][1] );
		++i;
		// collect args for this option
		while( i<ac && av[i][0] != '-' )
		{
			opt.push_back( av[i] );
			++i;
		}
		ApplyOption( *this, opt );
	}
}
		CommandExecutionResults CatCommand::Execute(const ExecutionContext& context)
		{
			auto& currentDir = GetCurrentPath(this->context->UserData, context.Message->SourceProtocol, context.Message->Sender);
			std::string path = SanitizePath(context.ParseResults->GetParameter("file"));
			std::string newPath = JoinPath(currentDir, path);
			if (newPath.empty())
			{
				throw Exceptions::ExecutionException(InvalidPath);
			}
			if (PathIsDirectoryA(newPath.c_str()))
			{
				throw Exceptions::ExecutionException(PathIsNotFile);
			}
			if (!PathFileExistsA(newPath.c_str()))
			{
				throw Exceptions::ExecutionException(FileDoesNotExist);
			}

			std::ifstream file(newPath, std::ios_base::binary);
			file.seekg(0, std::ios_base::end);
			int64_t length = file.tellg();
			file.seekg(0, std::ios_base::beg);
			if (length == -1 || !file)
			{
				throw Exceptions::ExecutionException(CannotReadFile);
			}
			if (length > MaxFileLength)
			{
				length = MaxFileLength;
			}

			std::unique_ptr<char[]> buffer(new char[(unsigned)length + 1]);
			if (file.read(buffer.get(), length).bad())
			{
				throw Exceptions::ExecutionException(CannotReadFile);
			}
			buffer.get()[length] = 0;
			return CommandExecutionResults(std::string(buffer.get()));
		}
		CommandExecutionResults StoreTextCommand::Execute(const ExecutionContext& context)
		{
			auto& currentDir = GetCurrentPath(this->context->UserData, context.Message->SourceProtocol, context.Message->Sender);
			auto& content = context.ParseResults->GetParameter("content");
			auto path = SanitizePath(context.ParseResults->GetParameter("file"));
			auto newPath = JoinPath(currentDir, path);
			if (newPath.empty())
			{
				throw Exceptions::ExecutionException(InvalidPath);
			}
			if (PathIsDirectoryA(newPath.c_str()))
			{
				throw Exceptions::ExecutionException(PathIsNotFile);
			}

			std::ofstream file(newPath, std::ios_base::binary | std::ios_base::trunc);
			file.write(content.c_str(), content.size());
			if (!file)
			{
				throw Exceptions::ExecutionException(CannotWriteToFile);
			}
			return CommandExecutionResults(FileWritten);
		}
	bool FileSourceFS::ReadDirectory(const std::string &dirpath, std::vector<FileInfo> &output)
	{
		size_t output_head_size = output.size();
		const std::wstring wsearchglob = transcode_utf8_to_utf16(JoinPathBelow(GetRoot(), dirpath)) + L"/*";
		WIN32_FIND_DATAW findinfo;
		HANDLE dirhandle = FindFirstFileW(wsearchglob.c_str(), &findinfo);
		DWORD err;

		if (dirhandle == INVALID_HANDLE_VALUE) {
			err = GetLastError();
			// if the directory was empty we succeeded even though FindFirstFile failed
			return (err == ERROR_FILE_NOT_FOUND);
		}

		do {
			std::string fname = transcode_utf16_to_utf8(findinfo.cFileName, wcslen(findinfo.cFileName));
			if (fname != "." && fname != "..") {
				const FileInfo::FileType ty = file_type_for_attributes(findinfo.dwFileAttributes);
				const Time::DateTime modtime = datetime_for_filetime(findinfo.ftLastWriteTime);
				output.push_back(MakeFileInfo(JoinPath(dirpath, fname), ty, modtime));
			}

			if (! FindNextFileW(dirhandle, &findinfo)) {
				err = GetLastError();
			} else
				err = ERROR_SUCCESS;
		} while (err == ERROR_SUCCESS);
		FindClose(dirhandle);

		if (err != ERROR_NO_MORE_FILES) {
			output.resize(output_head_size);
			return false;
		}

		std::sort(output.begin() + output_head_size, output.end());
		return true;
	}
Exemple #26
0
int ExpandLinks(char *dest, const char *from, int level)
{
    char buff[CF_BUFSIZE];
    char node[CF_MAXLINKSIZE];
    struct stat statbuf;
    int lastnode = false;

    memset(dest, 0, CF_BUFSIZE);

    if (level >= CF_MAXLINKLEVEL)
    {
        Log(LOG_LEVEL_ERR, "Too many levels of symbolic links to evaluate absolute path");
        return false;
    }

    const char *sp = from;

    while (*sp != '\0')
    {
        if (*sp == FILE_SEPARATOR)
        {
            sp++;
            continue;
        }

        sscanf(sp, "%[^/]", node);
        sp += strlen(node);

        if (*sp == '\0')
        {
            lastnode = true;
        }

        if (strcmp(node, ".") == 0)
        {
            continue;
        }

        if (strcmp(node, "..") == 0)
        {
            continue;
        }
        else
        {
            strcat(dest, "/");
        }

        strcat(dest, node);

        if (lstat(dest, &statbuf) == -1)        /* File doesn't exist so we can stop here */
        {
            Log(LOG_LEVEL_ERR, "Can't stat '%s' in ExpandLinks. (lstat: %s)", dest, GetErrorStr());
            return false;
        }

        if (S_ISLNK(statbuf.st_mode))
        {
            memset(buff, 0, CF_BUFSIZE);

            if (readlink(dest, buff, CF_BUFSIZE - 1) == -1)
            {
                Log(LOG_LEVEL_ERR, "Expand links can't stat '%s'. (readlink: %s)", dest, GetErrorStr());
                return false;
            }
            else
            {
                if (buff[0] == '.')
                {
                    ChopLastNode(dest);

                    AddSlash(dest);

                    if (!JoinPath(dest, buff))
                    {
                        return false;
                    }
                }
                else if (IsAbsoluteFileName(buff))
                {
                    strcpy(dest, buff);
                    DeleteSlash(dest);

                    if (strcmp(dest, from) == 0)
                    {
                        Log(LOG_LEVEL_DEBUG, "No links to be expanded");
                        return true;
                    }

                    if ((!lastnode) && (!ExpandLinks(buff, dest, level + 1)))
                    {
                        return false;
                    }
                }
                else
                {
                    ChopLastNode(dest);
                    AddSlash(dest);
                    strcat(dest, buff);
                    DeleteSlash(dest);

                    if (strcmp(dest, from) == 0)
                    {
                        Log(LOG_LEVEL_DEBUG, "No links to be expanded");
                        return true;
                    }

                    memset(buff, 0, CF_BUFSIZE);

                    if ((!lastnode) && (!ExpandLinks(buff, dest, level + 1)))
                    {
                        return false;
                    }
                }
            }
        }
    }

    return true;
}
Exemple #27
0
PromiseResult VerifyRelativeLink(EvalContext *ctx, char *destination, const char *source, Attributes attr, const Promise *pp)
{
    char *sp, *commonto, *commonfrom;
    char buff[CF_BUFSIZE], linkto[CF_BUFSIZE], add[CF_BUFSIZE];
    int levels = 0;

    if (*source == '.')
    {
        return VerifyLink(ctx, destination, source, attr, pp);
    }

    if (!CompressPath(linkto, source))
    {
        cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_INTERRUPTED, pp, attr, "Failed to link %s to %s\n", destination, source);
        return PROMISE_RESULT_FAIL;
    }

    commonto = linkto;
    commonfrom = destination;

    if (strcmp(commonto, commonfrom) == 0)
    {
        cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_INTERRUPTED, pp, attr, "Failed to link %s to %s - can't link file %s to itself\n",
             destination, source, commonto);
        return PROMISE_RESULT_FAIL;
    }

    while (*commonto == *commonfrom)
    {
        commonto++;
        commonfrom++;
    }

    while (!((IsAbsoluteFileName(commonto)) && (IsAbsoluteFileName(commonfrom))))
    {
        commonto--;
        commonfrom--;
    }

    commonto++;

    for (sp = commonfrom; *sp != '\0'; sp++)
    {
        if (IsFileSep(*sp))
        {
            levels++;
        }
    }

    memset(buff, 0, CF_BUFSIZE);

    strcat(buff, ".");
    strcat(buff, FILE_SEPARATOR_STR);

    while (--levels > 0)
    {
        snprintf(add, CF_BUFSIZE - 1, "..%c", FILE_SEPARATOR);

        if (!JoinPath(buff, add))
        {
            return PROMISE_RESULT_FAIL;
        }
    }

    if (!JoinPath(buff, commonto))
    {
        return PROMISE_RESULT_FAIL;
    }

    return VerifyLink(ctx, destination, buff, attr, pp);
}
Exemple #28
0
int DepthSearch(char *name, struct stat *sb, int rlevel, Attributes attr, Promise *pp)
{
    Dir *dirh;
    int goback;
    const struct dirent *dirp;
    char path[CF_BUFSIZE];
    struct stat lsb;

    if (!attr.havedepthsearch)  /* if the search is trivial, make sure that we are in the parent dir of the leaf */
    {
        char basedir[CF_BUFSIZE];

        CfDebug(" -> Direct file reference %s, no search implied\n", name);
        snprintf(basedir, sizeof(basedir), "%s", name);
        ChopLastNode(basedir);
        chdir(basedir);
        return VerifyFileLeaf(name, sb, attr, pp);
    }

    if (rlevel > CF_RECURSION_LIMIT)
    {
        CfOut(cf_error, "", "WARNING: Very deep nesting of directories (>%d deep): %s (Aborting files)", rlevel, name);
        return false;
    }

    if (rlevel > CF_RECURSION_LIMIT)
    {
        CfOut(cf_error, "", "WARNING: Very deep nesting of directories (>%d deep): %s (Aborting files)", rlevel, name);
        return false;
    }

    memset(path, 0, CF_BUFSIZE);

    CfDebug("To iterate is Human, to recurse is Divine...(%s)\n", name);

    if (!PushDirState(name, sb))
    {
        return false;
    }

    if ((dirh = OpenDirLocal(".")) == NULL)
    {
        CfOut(cf_inform, "opendir", "Could not open existing directory %s\n", name);
        return false;
    }

    for (dirp = ReadDir(dirh); dirp != NULL; dirp = ReadDir(dirh))
    {
        if (!ConsiderFile(dirp->d_name, name, attr, pp))
        {
            continue;
        }

        strcpy(path, name);
        AddSlash(path);

        if (!JoinPath(path, dirp->d_name))
        {
            CloseDir(dirh);
            return true;
        }

        if (lstat(dirp->d_name, &lsb) == -1)
        {
            CfOut(cf_verbose, "lstat", "Recurse was looking at %s when an error occurred:\n", path);
            continue;
        }

        if (S_ISLNK(lsb.st_mode))       /* should we ignore links? */
        {
            if (!KillGhostLink(path, attr, pp))
            {
                VerifyFileLeaf(path, &lsb, attr, pp);
            }
            else
            {
                continue;
            }
        }

        /* See if we are supposed to treat links to dirs as dirs and descend */

        if (attr.recursion.travlinks && S_ISLNK(lsb.st_mode))
        {
            if (lsb.st_uid != 0 && lsb.st_uid != getuid())
            {
                CfOut(cf_inform, "",
                      "File %s is an untrusted link: cfengine will not follow it with a destructive operation", path);
                continue;
            }

            /* if so, hide the difference by replacing with actual object */

            if (cfstat(dirp->d_name, &lsb) == -1)
            {
                CfOut(cf_error, "stat", "Recurse was working on %s when this failed:\n", path);
                continue;
            }
        }

        if (attr.recursion.xdev && DeviceBoundary(&lsb, pp))
        {
            CfOut(cf_verbose, "", "Skipping %s on different device - use xdev option to change this\n", path);
            continue;
        }

        if (S_ISDIR(lsb.st_mode))
        {
            if (SkipDirLinks(path, dirp->d_name, attr.recursion))
            {
                continue;
            }

            if (attr.recursion.depth > 1 && rlevel <= attr.recursion.depth)
            {
                CfOut(cf_verbose, "", " ->>  Entering %s (%d)\n", path, rlevel);
                goback = DepthSearch(path, &lsb, rlevel + 1, attr, pp);
                PopDirState(goback, name, sb, attr.recursion);
                VerifyFileLeaf(path, &lsb, attr, pp);
            }
            else
            {
                VerifyFileLeaf(path, &lsb, attr, pp);
            }
        }
        else
        {
            VerifyFileLeaf(path, &lsb, attr, pp);
        }
    }

    CloseDir(dirh);
    return true;
}
Exemple #29
0
namespace FileSystem {

static FileSourceFS dataFilesApp(GetDataDir());
static FileSourceFS dataFilesUser(JoinPath(GetUserDir(), "data"));
FileSourceUnion gameDataFiles;
FileSourceFS userFiles(GetUserDir());

// note: some functions (GetUserDir(), GetDataDir()) are in FileSystem{Posix,Win32}.cpp

std::string JoinPath(const std::string &a, const std::string &b)
{
    if (!b.empty()) {
        if (b[0] == '/' || a.empty())
            return b;
        else
            return a + "/" + b;
    } else
        return a;
}

static void normalise_path(std::string &result, const StringRange &path)
{
    StringRange part(path.begin, path.begin);
    const char *c = path.begin;
    if ((c != path.end) && (*c == '/')) {
        result += '/';
        ++c;
        ++part.begin;
    }
    const size_t initial_result_length = result.size();
    while (true) {
        if ((*c == '/') || (c == path.end)) {
            part.end = c;
            if (part.Empty() || (part == ".")) {
                // skip this part
            } else if (part == "..") {
                // pop the last component
                if (result.size() <= initial_result_length)
                    throw std::invalid_argument(path.ToString());
                size_t pos = result.rfind('/', result.size()-2);
                ++pos;
                assert(pos >= initial_result_length);
                result.erase(pos);
            } else {
                // push the new component
                if (part.end != path.end) {
                    assert(*part.end == '/');
                    ++part.end;
                }
                result.append(part.begin, part.Size());
            }
            part.begin = c+1;
        }
        if (c == path.end) {
            break;
        }
        ++c;
    }
}

std::string NormalisePath(const std::string &path)
{
    std::string result;
    result.reserve(path.size());
    normalise_path(result, StringRange(path.c_str(), path.size()));
    return result;
}

std::string JoinPathBelow(const std::string &base, const std::string &path)
{
    if (base.empty())
        return path;
    if (!path.empty()) {
        if ((path[0] == '/') && (base != "/"))
            throw std::invalid_argument(path);
        else {
            std::string result(base);
            result.reserve(result.size() + 1 + path.size());
            if (result[result.size()-1] != '/')
                result += '/';
            StringRange rhs(path.c_str(), path.size());
            if (path[0] == '/') {
                assert(base == "/");
                ++rhs.begin;
            }
            normalise_path(result, rhs);
            return result;
        }
    } else
        return base;
}

void Init()
{
    gameDataFiles.AppendSource(&dataFilesUser);
    gameDataFiles.AppendSource(&dataFilesApp);
}

void Uninit()
{
}

FileInfo::FileInfo(FileSource *source, const std::string &path, FileType type):
    m_source(source),
    m_path(path),
    m_dirLen(0),
    m_type(type)
{
    assert((m_path.size() <= 1) || (m_path[m_path.size()-1] != '/'));
    std::size_t slashpos = m_path.rfind('/');
    if (slashpos != std::string::npos) {
        m_dirLen = slashpos + 1;
    } else {
        m_dirLen = 0;
    }
}

FileInfo FileSource::MakeFileInfo(const std::string &path, FileInfo::FileType fileType)
{
    return FileInfo(this, path, fileType);
}

FileSourceUnion::FileSourceUnion(): FileSource(":union:") {}
FileSourceUnion::~FileSourceUnion() {}

void FileSourceUnion::PrependSource(FileSource *fs)
{
    assert(fs);
    RemoveSource(fs);
    m_sources.insert(m_sources.begin(), fs);
}

void FileSourceUnion::AppendSource(FileSource *fs)
{
    assert(fs);
    RemoveSource(fs);
    m_sources.push_back(fs);
}

void FileSourceUnion::RemoveSource(FileSource *fs)
{
    std::vector<FileSource*>::iterator nend = std::remove(m_sources.begin(), m_sources.end(), fs);
    m_sources.erase(nend, m_sources.end());
}

FileInfo FileSourceUnion::Lookup(const std::string &path)
{
    for (std::vector<FileSource*>::const_iterator
            it = m_sources.begin(); it != m_sources.end(); ++it)
    {
        FileInfo info = (*it)->Lookup(path);
        if (info.Exists()) {
            return info;
        }
    }
    return MakeFileInfo(path, FileInfo::FT_NON_EXISTENT);
}

RefCountedPtr<FileData> FileSourceUnion::ReadFile(const std::string &path)
{
    for (std::vector<FileSource*>::const_iterator
            it = m_sources.begin(); it != m_sources.end(); ++it)
    {
        RefCountedPtr<FileData> data = (*it)->ReadFile(path);
        if (data) {
            return data;
        }
    }
    return RefCountedPtr<FileData>();
}

// Merge two sets of FileInfo's, by path.
// Input vectors must be sorted. Output will be sorted.
// Where a path is present in both inputs, directories are selected
// in preference to non-directories; otherwise, the FileInfo from the
// first vector is selected in preference to the second vector.
static void file_union_merge(
    std::vector<FileInfo>::const_iterator a, std::vector<FileInfo>::const_iterator aend,
    std::vector<FileInfo>::const_iterator b, std::vector<FileInfo>::const_iterator bend,
    std::vector<FileInfo> &output)
{
    while ((a != aend) && (b != bend)) {
        int order = a->GetPath().compare(b->GetPath());
        int which = order;
        if (which == 0) {
            if (b->IsDir() && !a->IsDir()) {
                which = 1;
            }
            else {
                which = -1;
            }
        }
        if (which < 0) {
            output.push_back(*a++);
            if (order == 0) ++b;
        } else {
            output.push_back(*b++);
            if (order == 0) ++a;
        }
    }

    if (a != aend) {
        std::copy(a, aend, std::back_inserter(output));
    }
    if (b != bend) {
        std::copy(b, bend, std::back_inserter(output));
    }
}

bool FileSourceUnion::ReadDirectory(const std::string &path, std::vector<FileInfo> &output)
{
    if (m_sources.empty()) {
        return false;
    }
    if (m_sources.size() == 1) {
        return m_sources.front()->ReadDirectory(path, output);
    }

    bool founddir = false;

    std::vector<FileInfo> merged;
    for (std::vector<FileSource*>::const_iterator
            it = m_sources.begin(); it != m_sources.end(); ++it)
    {
        std::vector<FileInfo> nextfiles;
        if ((*it)->ReadDirectory(path, nextfiles)) {
            founddir = true;

            std::vector<FileInfo> prevfiles;
            prevfiles.swap(merged);
            // merge order is important
            // file_union_merge selects from its first input preferentially
            file_union_merge(
                prevfiles.begin(), prevfiles.end(),
                nextfiles.begin(), nextfiles.end(),
                merged);
        }
    }

    output.reserve(output.size() + merged.size());
    std::copy(merged.begin(), merged.end(), std::back_inserter(output));

    return founddir;
}

FileEnumerator::FileEnumerator(FileSource &fs, int flags):
    m_source(&fs), m_flags(flags) {}

FileEnumerator::FileEnumerator(FileSource &fs, const std::string &path, int flags):
    m_source(&fs), m_flags(flags)
{
    AddSearchRoot(path);
}

FileEnumerator::~FileEnumerator() {}

void FileEnumerator::AddSearchRoot(const std::string &path)
{
    const FileInfo fi = m_source->Lookup(path);
    if (fi.IsDir()) {
        QueueDirectoryContents(fi);
        ExpandDirQueue();
    }
}

void FileEnumerator::Next()
{
    m_queue.pop_front();
    ExpandDirQueue();
}

void FileEnumerator::ExpandDirQueue()
{
    while (m_queue.empty() && !m_dirQueue.empty()) {
        const FileInfo &nextDir = m_dirQueue.front();
        assert(nextDir.IsDir());
        QueueDirectoryContents(nextDir);
        m_dirQueue.pop_front();
    }
}

void FileEnumerator::QueueDirectoryContents(const FileInfo &info)
{
    assert(info.IsDir());

    std::vector<FileInfo> entries;
    m_source->ReadDirectory(info.GetPath(), entries);
    for (std::vector<FileInfo>::const_iterator
            it = entries.begin(); it != entries.end(); ++it) {

        switch (it->GetType()) {
        case FileInfo::FT_DIR:
            if (m_flags & IncludeDirs) {
                m_queue.push_back(*it);
            }
            if (m_flags & Recurse) {
                m_dirQueue.push_back(*it);
            }
            break;
        case FileInfo::FT_FILE:
            if (!(m_flags & ExcludeFiles)) {
                m_queue.push_back(*it);
            }
            break;
        case FileInfo::FT_SPECIAL:
            if (m_flags & IncludeSpecials) {
                m_queue.push_back(*it);
            }
            break;
        default:
            assert(0);
            break;
        }
    }
}

} // namespace FileSystem
Exemple #30
0
void CLngRc::Reload(bool bForce /*= false*/)
{
	bool bChanged = bForce;
	bool bExists = false;
	CEStr lsNewLng, lsNewFile;

	// TODO: There would be gpSet member in future
	lsNewLng.Set(gpConEmu->opt.Language.GetStr());

	// Language was requested?
	if (!lsNewLng.IsEmpty())
	{
		if (ms_Lng.IsEmpty() || (0 != wcscmp(lsNewLng, ms_Lng)))
		{
			bChanged = true;
		}

		// We need a file
		if (gpConEmu->opt.LanguageFile.Exists)
		{
			// It may contain environment variables
			lsNewFile = ExpandEnvStr(gpConEmu->opt.LanguageFile.GetStr());
			if (lsNewFile.IsEmpty())
				lsNewFile.Set(gpConEmu->opt.LanguageFile.GetStr());
			// Check if the file exists
			bExists = FileExists(lsNewFile);
		}
		else
		{
			lsNewFile = JoinPath(gpConEmu->ms_ConEmuExeDir, gsResourceFileName);
			if (!(bExists = FileExists(lsNewFile)))
			{
				lsNewFile = JoinPath(gpConEmu->ms_ConEmuBaseDir, gsResourceFileName);
				bExists = FileExists(lsNewFile);
			}
		}

		// File name was changed?
		if ((bExists == ms_l10n.IsEmpty())
			|| (bExists
				&& (ms_l10n.IsEmpty()
					|| (0 != wcscmp(lsNewFile, ms_l10n)))
				)
			)
		{
			bChanged = true;
		}
	}
	else if (!ms_Lng.IsEmpty())
	{
		bChanged = true;
	}

	// Check if we have to reload data
	if (bChanged)
	{
		if (!bExists
			|| !LoadResouces(lsNewLng, lsNewFile))
		{
			ms_Lng.Empty();
			ms_l10n.Empty();

			Clean(m_CmnHints);
			Clean(m_MnuHints);
			Clean(m_Controls);
		}
	}
}