void File::Move (/*[in]*/ const PathName & source, /*[in]*/ const PathName & dest) { struct stat sourceStat; if (stat(source.Get(), &sourceStat) != 0) { FATAL_CRT_ERROR ("stat", source.Get()); } PathName destDir (dest); destDir.MakeAbsolute (); destDir.RemoveFileSpec (); struct stat destStat; if (stat(destDir.Get(), &destStat) != 0) { FATAL_CRT_ERROR ("stat", destDir.Get()); } bool sameDevice = (sourceStat.st_dev == destStat.st_dev); if (sameDevice) { SessionImpl::theSession->trace_files->WriteFormattedLine ("core", T_("renaming %s to %s"), Q_(source), Q_(dest)); if (rename(source.Get(), dest.Get()) != 0) { FATAL_CRT_ERROR ("rename", source.Get()); } } else { Copy (source, dest); try { Delete (source); } catch (const MiKTeXException &) { try { if (Exists(source)) { Delete (dest); } } catch (const MiKTeXException &) { } throw; } } }
void miktex_set_aux_directory(const char* path) { auxDirectory = path; auxDirectory.MakeAbsolute(); shared_ptr<Session> session = Session::Get(); if (!Directory::Exists(auxDirectory)) { if (session->GetConfigValue(MIKTEX_CONFIG_SECTION_TEXANDFRIENDS, MIKTEX_CONFIG_VALUE_CREATEAUXDIRECTORY).GetString() == "t") { Directory::Create(auxDirectory); } else { MIKTEX_FATAL_ERROR_2(T_("The specified auxiliary directory does not exist."), "directory", auxDirectory.ToString()); } } session->AddInputDirectory(auxDirectory, true); }
void File::Delete (/*[in]*/ const PathName & path, /*[in]*/ bool tryHarder, /*[in]*/ bool updateFndb) { if (updateFndb && SessionImpl::GetSession()->IsTEXMFFile(path.Get(), 0, 0) && Fndb::FileExists(path)) { Fndb::Remove (path); } FileAttributes attributes = File::GetAttributes(path); bool done; try { if ((attributes & FileAttributes::ReadOnly) != 0) { attributes &= ~ FileAttributes(FileAttributes::ReadOnly); File::SetAttributes (path, attributes); } File::Delete (path); done = true; } catch (const UnauthorizedAccessException &) { #if defined(MIKTEX_WINDOWS) if (! tryHarder) { throw; } done = false; #else throw; #endif } #if defined(MIKTEX_WINDOWS) if (! done) { // move the file out of the way PathName absPath (path); if (! Utils::IsAbsolutePath(path.Get())) { absPath.MakeAbsolute (); } wchar_t szDir[BufferSizes::MaxPath]; if (IsWindowsNT()) { DllProc3<BOOL, LPCWSTR, LPWSTR, DWORD> getVolumePathNameW ("Kernel32.dll", "GetVolumePathNameW"); if (! getVolumePathNameW(absPath.ToWideCharString().c_str(), szDir, BufferSizes::MaxPath)) { FATAL_WINDOWS_ERROR ("GetVolumePathNameA", absPath.Get()); } } else { #if defined(MIKTEX_SUPPORT_LEGACY_WINDOWS) dir = absPath; dir.RemoveFileSpec (); #else UNSUPPORTED_PLATFORM (); #endif } wchar_t szTemp[BufferSizes::MaxPath]; if (GetTempFileNameW(szDir, L"mik", 0, szTemp) == 0) { FATAL_WINDOWS_ERROR ("GetTempFileNameW", WU_(szDir)); } File::Delete (szTemp); File::Move (absPath, szTemp); SessionImpl::GetSession()->ScheduleFileRemoval (PathName(szTemp).Get()); } #endif }
bool DviImpl::FindSource(const char* fileName, int line, DviPosition& position) { CheckCondition(); BEGIN_CRITICAL_SECTION(dviMutex) { trace_search->WriteFormattedLine("libdvi", T_("searching src special %d %s"), line, fileName); SourceSpecial* pSourceSpecial1Best = nullptr; SourceSpecial* pSourceSpecial2Best = nullptr; int pageIdx1 = -1; int pageIdx2 = -1; // get fully qualified path to the directory location of the // document PathName documentLocation(fqDviFileName); documentLocation.RemoveFileSpec(); // file name relative to the location of the DVI document const char* lpszRelFileName; // absolute file name PathName fqFileName; if (Utils::IsAbsolutePath(fileName)) { lpszRelFileName = Utils::GetRelativizedPath(fileName, documentLocation.GetData()); fqFileName = fileName; fqFileName.MakeAbsolute(); } else { lpszRelFileName = fileName; fqFileName = documentLocation; fqFileName /= fileName; fqFileName.MakeAbsolute(); } // // scan the document // for (int pageIdx = 0; pageIdx < GetNumberOfPages(); ++pageIdx) { DviPageImpl* dviPage; try { dviPage = reinterpret_cast<DviPageImpl*>(GetLoadedPage(pageIdx)); } catch (const OperationCancelledException&) { return false; } if (dviPage == nullptr) { throw DviPageNotFoundException("", T_("The DVI page could not be found."), MiKTeXException::KVMAP(), MIKTEX_SOURCE_LOCATION()); } AutoUnlockPage autoUnlockPage(dviPage); SourceSpecial* pSourceSpecial1 = nullptr; SourceSpecial* pSourceSpecial2 = nullptr; SourceSpecial* pSourceSpecial; for (int j = -1; (pSourceSpecial = dviPage->GetNextSpecial<SourceSpecial>(j)) != nullptr; ) { const char* name = pSourceSpecial->GetFileName(); // try exact match bool nameMatch = (MyPathNameCompare(name, fileName) == 0); // try fully qualified file names if (!nameMatch) { PathName fqName; if (Utils::IsAbsolutePath(name)) { fqName = name; fqName.MakeAbsolute(); } else { fqName = documentLocation; fqName /= name; fqName.MakeAbsolute(); } nameMatch = (MyPathNameCompare(fqName, fqFileName) == 0); } // try relative file names if (!nameMatch && lpszRelFileName != nullptr) { const char* lpszRelName; if (!Utils::IsAbsolutePath(name)) { lpszRelName = name; } else { lpszRelName = Utils::GetRelativizedPath(name, documentLocation.GetData()); } nameMatch = lpszRelName != nullptr && MyPathNameCompare(lpszRelName, lpszRelFileName) == 0; } if (!nameMatch) { continue; } if (line >= pSourceSpecial->GetLineNum()) { if (pSourceSpecial1 == nullptr || (pSourceSpecial->GetLineNum() > pSourceSpecial1->GetLineNum())) { pSourceSpecial1 = pSourceSpecial; } } if (line <= pSourceSpecial->GetLineNum()) { if (pSourceSpecial2 == nullptr || (pSourceSpecial->GetLineNum() < pSourceSpecial2->GetLineNum())) { pSourceSpecial2 = pSourceSpecial; } } } if (pSourceSpecial1 != nullptr && pSourceSpecial2 != nullptr) { pSourceSpecial1Best = pSourceSpecial1; pageIdx1 = pageIdx; pSourceSpecial2Best = pSourceSpecial2; pageIdx2 = pageIdx; break; } else if (pSourceSpecial1 != nullptr && (pSourceSpecial1Best == nullptr || (abs(pSourceSpecial1Best->GetLineNum() - line) > abs(pSourceSpecial1->GetLineNum() - line)))) { pSourceSpecial1Best = pSourceSpecial1; pageIdx1 = pageIdx; pSourceSpecial2Best = nullptr; pageIdx2 = -1; } else if (pSourceSpecial2 != nullptr && (pSourceSpecial2Best == nullptr || (abs(pSourceSpecial2Best->GetLineNum() - line) > abs(pSourceSpecial2->GetLineNum() - line)))) { pSourceSpecial2Best = pSourceSpecial2; pageIdx2 = pageIdx; pSourceSpecial1Best = nullptr; pageIdx1 = -1; } } // // evaluate the results // if (pSourceSpecial1Best == nullptr && pSourceSpecial2Best == nullptr) { trace_search->WriteLine("libdvi", T_("search failed")); return false; } if (pSourceSpecial1Best == nullptr) { trace_search->WriteFormattedLine("libdvi", T_("found src2 on page #%d"), pageIdx2); trace_search->WriteFormattedLine("libdvi", " src2 = [%d (%d,%d)]", pSourceSpecial2Best->GetLineNum(), pSourceSpecial2Best->GetX(), pSourceSpecial2Best->GetY()); position.pageIdx = pageIdx2; position.x = pSourceSpecial2Best->GetX(); position.y = pSourceSpecial2Best->GetY(); } else if (pSourceSpecial2Best == nullptr) { trace_search->WriteFormattedLine("libdvi", T_("found src1 on page #%d"), pageIdx1); trace_search->WriteFormattedLine("libdvi", " src1 = [%d (%d,%d)]", pSourceSpecial1Best->GetLineNum(), pSourceSpecial1Best->GetX(), pSourceSpecial1Best->GetY()); position.pageIdx = pageIdx1; position.x = pSourceSpecial1Best->GetX(); position.y = pSourceSpecial1Best->GetY(); } else { position.pageIdx = pageIdx1; trace_search->WriteFormattedLine("libdvi", T_("found src region on page #%d"), position.pageIdx); trace_search->WriteFormattedLine("libdvi", " src1 = [%d (%d,%d)]", pSourceSpecial1Best->GetLineNum(), pSourceSpecial1Best->GetX(), pSourceSpecial1Best->GetY()); trace_search->WriteFormattedLine("libdvi", " src2 = [%d (%d,%d)]", pSourceSpecial2Best->GetLineNum(), pSourceSpecial2Best->GetX(), pSourceSpecial2Best->GetY()); position.x = pSourceSpecial1Best->GetX(); if (pSourceSpecial2Best->GetLineNum() == pSourceSpecial1Best->GetLineNum()) { position.y = pSourceSpecial1Best->GetY(); } else { position.y = (pSourceSpecial1Best->GetY() + ((line - pSourceSpecial1Best->GetLineNum()) * (pSourceSpecial2Best->GetY() - pSourceSpecial1Best->GetY()) / (pSourceSpecial2Best->GetLineNum() - pSourceSpecial1Best->GetLineNum()))); } trace_search->WriteFormattedLine("libdvi", " interpolated (x,y) = (%d,%d)", position.x, position.y); } return true; } END_CRITICAL_SECTION(); }
bool SessionImpl::FindFileInternal (/*[in]*/ const char * lpszFileName, /*[in]*/ const PathNameArray & directoryPatterns, /*[in]*/ bool firstMatchOnly, /*[in]*/ bool useFndb, /*[in]*/ bool searchFileSystem, /*[out]*/ vector<PathName> & result) { AutoTraceTime att ("find file", lpszFileName); MIKTEX_ASSERT (useFndb || searchFileSystem); bool found = false; // if a fully qualified path name is given, then don't look out any // further if (Utils::IsAbsolutePath(lpszFileName)) { PathName path (lpszFileName); found = CheckCandidate(path, 0); if (found) { result.push_back (path); } return (found); } // if an explicitly relative path name is given, then don't look out // any further if (IsExplicitlyRelativePath(lpszFileName)) { PathName pathWD; for (unsigned idx = 0; ! (found && firstMatchOnly) && GetWorkingDirectory(idx, pathWD); ++ idx) { PathName path (pathWD); path += lpszFileName; path.MakeAbsolute (); if (CheckCandidate(path, 0)) { found = true; #if FIND_FILE_PREFER_RELATIVE_PATH_NAMES // 2015-01-15 if (idx == 0) { MIKTEX_ASSERT(PathName::Compare(pathWD, PathName().SetToCurrentDirectory()) == 0); path = lpszFileName; } #endif result.push_back (path); } } return (found); } // make use of the file name database if (useFndb) { for (PathNameArray::const_iterator it = directoryPatterns.begin(); ! (found && firstMatchOnly) && it != directoryPatterns.end(); ++ it) { if (found && ! firstMatchOnly && IsMpmFile(it->Get())) { // don't trigger the package installer continue; } FileNameDatabase * pFndb = GetFileNameDatabase(it->Get()); if (pFndb != 0) { // search fndb AutoFndbRelease autoRelease (pFndb); vector<PathName> paths; vector<string> fileNameInfo; bool foundInFndb = pFndb->Search(lpszFileName, it->Get(), firstMatchOnly, paths, fileNameInfo); // we must release the FNDB handle since CheckCandidate() might request an unload of the FNDB autoRelease.Reset (); if (foundInFndb) { for (int idx = 0; idx < paths.size(); ++ idx) { if (CheckCandidate(paths[idx], fileNameInfo[idx].c_str())) { found = true; result.push_back (paths[idx]); } } } } else { // search the file system because the file name database does not exist vector<PathName> paths; if (SearchFileSystem(lpszFileName, it->Get(), firstMatchOnly, paths)) { found = true; result.insert (result.end(), paths.begin(), paths.end()); } } } } if (found || ! searchFileSystem) { return (found); } // search the file system for (PathNameArray::const_iterator it = directoryPatterns.begin(); ! (found && firstMatchOnly) && it != directoryPatterns.end(); ++ it) { if (found && ! firstMatchOnly && IsMpmFile(it->Get())) { // don't search the virtual MPM directory tree continue; } FileNameDatabase * pFndb = GetFileNameDatabase(it->Get()); if (pFndb == 0) { // fndb does not exist => we already searched the file system (see above) continue; } pFndb->Release (); vector<PathName> paths; if (SearchFileSystem(lpszFileName, it->Get(), firstMatchOnly, paths)) { found = true; result.insert (result.end(), paths.begin(), paths.end()); } } return (found); }
FileNameDatabaseHeader::FndbOffset FndbManager::ProcessFolder (/*[in]*/ FileNameDatabaseHeader::FndbOffset foParent, /*[in]*/ const char * lpszParentPath, /*[in]*/ const char * lpszFolderName, /*[in]*/ FileNameDatabaseHeader::FndbOffset foFolderName) { const size_t cReservedEntries = 0; if (currentLevel > deepestLevel) { deepestLevel = currentLevel; } vector<string> subDirectoryNames; subDirectoryNames.reserve (40); vector<FILENAMEINFO> fileNames; fileNames.reserve (100); bool done = false; PathName path (lpszParentPath, lpszFolderName); path.MakeAbsolute (); if (pCallback != 0) { if (! pCallback->OnProgress(currentLevel, path.Get())) { throw OperationCancelledException (); } char * lpszSubDirNames = 0; char * lpszFileNames = 0; char * lpszFileNameInfos = 0; done = pCallback->ReadDirectory(path.Get(), &lpszSubDirNames, &lpszFileNames, &lpszFileNameInfos); if (done) { AutoMemoryPointer xxx (lpszSubDirNames); AutoMemoryPointer xxy (lpszFileNames); AutoMemoryPointer xxz (lpszFileNameInfos); const char * lpsz = lpszSubDirNames; while (*lpsz != 0) { subDirectoryNames.push_back (lpsz); lpsz += strlen(lpsz) + 1; } lpsz = lpszFileNames; const char * lpsz2 = lpszFileNameInfos; while (*lpsz != 0) { FILENAMEINFO filenameinfo; filenameinfo.FileName = lpsz; lpsz += strlen(lpsz) + 1; if (lpsz2 != 0) { filenameinfo.Info = lpsz2; lpsz2 += strlen(lpsz2) + 1; } fileNames.push_back (filenameinfo); } } } if (! done) { ReadDirectory (path.Get(), subDirectoryNames, fileNames); } numDirectories += static_cast<unsigned long>(subDirectoryNames.size()); numFiles += static_cast<unsigned long>(fileNames.size()); sort (subDirectoryNames.begin(), subDirectoryNames.end(), StringComparerIgnoringCase()); sort (fileNames.begin(), fileNames.end(), COMPAREFILENAMEINFO()); // store all names; build offset table vector<FileNameDatabaseHeader::FndbOffset> vecfndboff; vecfndboff.reserve ((storeFileNameInfo ? 2 : 1) * fileNames.size() + 2 * subDirectoryNames.size() + cReservedEntries); vector<FILENAMEINFO>::iterator it; vector<string>::iterator it2; for (it = fileNames.begin(); it != fileNames.end(); ++ it) { vecfndboff.push_back (PushBack((*it).FileName.c_str())); } for (it2 = subDirectoryNames.begin(); it2 != subDirectoryNames.end(); ++ it2) { vecfndboff.push_back (PushBack((*it2).c_str())); } for (it2 = subDirectoryNames.begin(); it2 != subDirectoryNames.end(); ++ it2) { vecfndboff.push_back (null_byte); } if (storeFileNameInfo) { for (it = fileNames.begin(); it != fileNames.end(); ++ it) { vecfndboff.push_back (PushBack((*it).Info.c_str())); } } vecfndboff.insert (vecfndboff.end(), cReservedEntries, 0); // store directory data (excluding offsets) FileNameDatabaseDirectory dirdata; dirdata.Init (); dirdata.foName = foFolderName; dirdata.foParent = foParent; dirdata.numSubDirs = static_cast<unsigned long>(subDirectoryNames.size()); dirdata.numFiles = static_cast<unsigned long>(fileNames.size()); dirdata.capacity = static_cast<unsigned long>(vecfndboff.size()); AlignMem (AlignmentDirectory); FileNameDatabaseHeader::FndbOffset foThis = PushBack(&dirdata, offsetof(FileNameDatabaseDirectory, table)); if (vecfndboff.size() == 0) { return (foThis); } // reserve memory for offset table FileNameDatabaseHeader::FndbOffset foOffsetTable = ReserveMem(vecfndboff.size() * sizeof(FileNameDatabaseHeader::FndbOffset)); // recurse into sub-directories and remember offsets PathName pathFolder (lpszParentPath, lpszFolderName, 0); size_t i = 0; ++ currentLevel; for (it2 = subDirectoryNames.begin(); it2 != subDirectoryNames.end(); ++ it2, ++ i) { vecfndboff[dirdata.numFiles + dirdata.numSubDirs + i] // <recursivecall> = ProcessFolder(foThis, pathFolder.Get(), it2->c_str(), vecfndboff[dirdata.numFiles + i]); // </recursivecall> } -- currentLevel; // store offset table SetMem (foOffsetTable, &vecfndboff[0], vecfndboff.size() * sizeof(FileNameDatabaseHeader::FndbOffset)); return (foThis); }
FILE * File::Open (/*[in]*/ const PathName & path, /*[in]*/ FileMode mode, /*[in]*/ FileAccess access, /*[in]*/ bool isTextFile, /*[in]*/ FileShare share) { UNUSED_ALWAYS (isTextFile); UNUSED_ALWAYS (share); SessionImpl::theSession->trace_files->WriteFormattedLine ("core", T_("opening file %s (%d 0x%x %d %d)"), Q_(path), static_cast<int>(mode.Get()), static_cast<int>(access.Get()), static_cast<int>(share.Get()), static_cast<int>(isTextFile)); int flags = 0; string strFlags; if (mode == FileMode::Create) { flags |= O_CREAT; } else if (mode == FileMode::Append) { flags |= O_APPEND; } if (access == FileAccess::ReadWrite) { flags |= O_RDWR; if (mode == FileMode::Append) { strFlags += "a+"; } else { strFlags += "r+"; } } else if (access == FileAccess::Read) { flags |= O_RDONLY; strFlags += "r"; } else if (access == FileAccess::Write) { flags |= O_WRONLY; if (mode == FileMode::Append) { strFlags += "a"; } else { flags |= O_TRUNC; strFlags += "w"; } } if (mode == FileMode::Create) { PathName dir (path); dir.MakeAbsolute (); dir.RemoveFileSpec(); if (! Directory::Exists(dir)) { Directory::Create (dir); } } int fd; fd = open(path.Get(), flags, (((flags & O_CREAT) == 0) ? 0 : (0 | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH | 0))); if (fd < 0) { FATAL_CRT_ERROR ("open", path.Get()); } try { return (FdOpen(fd, strFlags.c_str())); } catch (const exception &) { close (fd); throw; } }