Esempio n. 1
0
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;
	}
    }
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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
}
Esempio n. 4
0
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();
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
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);
}
Esempio n. 7
0
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;
    }
}