Beispiel #1
0
bool SessionImpl::ConvertToBitmapFile(const PathName& sourceFileName, PathName& destFileName, IRunProcessCallback* callback)
{
  string ext = sourceFileName.GetExtension();

  if (ext.empty())
  {
    MIKTEX_FATAL_ERROR_2(T_("No file name extension in graphics rule."), "path", ext);
  }

  string rule;

  if (!FindGraphicsRule(ext, ".bmp", rule))
  {
    MIKTEX_FATAL_ERROR_2(T_("No conversion rule found."), "path", sourceFileName.ToString());
  }

  destFileName.SetToTempFile();
#if defined(MIKTEX_WINDOWS)
  Utils::RemoveBlanksFromPathName(destFileName);
#endif

  string commandLine;

  for (const char* lpsz = rule.c_str(); *lpsz != 0; ++lpsz)
  {
    if (*lpsz == '%')
    {
      ++lpsz;
      switch (*lpsz)
      {
      case 'i':
        commandLine += sourceFileName.GetData();
	break;
      case 'o':
        commandLine += destFileName.GetData();
	break;
      }
    }
    else
    {
      commandLine += *lpsz;
    }
  }

  bool done = Process::ExecuteSystemCommand(commandLine, nullptr, callback, nullptr);

  if (!done)
  {
    File::Delete(destFileName, { FileDeleteOption::TryHard });
  }

  return done;
}
Beispiel #2
0
template<typename CharType> static PathName UnmangleNameOfFile_(const CharType* lpszFrom)
{
  PathName ret;
  char* lpszTo = ret.GetData();
  MIKTEX_ASSERT_STRING(lpszFrom);
  size_t len = StrLen(lpszFrom);
  if (len >= ret.GetCapacity())
  {
    MIKTEX_UNEXPECTED();
  }
  size_t idx;
  for (idx = 0; idx < len; ++idx)
  {
    if (lpszFrom[idx] == '*')
    {
      lpszTo[idx] = ' ';
    }
    else if (lpszFrom[idx] == '?')
    {
      lpszTo[idx] = '~';
    }
    else
    {
      lpszTo[idx] = lpszFrom[idx];
    }
  }
  lpszTo[idx] = 0;
  return ret;
}
Beispiel #3
0
PathName WebAppInputLine::MangleNameOfFile(const char* lpszFrom)
{
  PathName ret;
  char* lpszTo = ret.GetData();
  MIKTEX_ASSERT_STRING(lpszFrom);
  size_t len = StrLen(lpszFrom);
  if (len >= ret.GetCapacity())
  {
    MIKTEX_UNEXPECTED();
  }
  size_t idx;
  for (idx = 0; idx < len; ++idx)
  {
    if (lpszFrom[idx] == ' ')
    {
      lpszTo[idx] = '*';
    }
    else if (lpszFrom[idx] == '~')
    {
      lpszTo[idx] = '?';
    }
    else if (lpszFrom[idx] == '\\')
    {
      lpszTo[idx] = '/';
    }
    else
    {
      lpszTo[idx] = lpszFrom[idx];
    }
  }
  lpszTo[idx] = 0;
  return ret;
}
Beispiel #4
0
void Fndb::Add(const vector<Fndb::Record>& records)
{
  if (records.empty())
  {
    MIKTEX_UNEXPECTED();
  }
  shared_ptr<SessionImpl> session = SessionImpl::GetSession();
  // TODO: parse/split records
  unsigned root = session->DeriveTEXMFRoot(records[0].path);
  PathName pathFqFndbFileName;
  if (session->FindFilenameDatabase(root, pathFqFndbFileName))
  {
    shared_ptr<FileNameDatabase> fndb = session->GetFileNameDatabase(root);
    if (fndb == nullptr)
    {
      MIKTEX_UNEXPECTED();
    }
    fndb->Add(records);
  }
  else
  {
    // create the fndb file
    // FIXME: the file name info hasn't been added, if the file exists
    PathName pathFndbFile = session->GetFilenameDatabasePathName(root);
    if (!Fndb::Create(pathFndbFile.GetData(), session->GetRootDirectoryPath(root).GetData(), nullptr))
    {
      MIKTEX_UNEXPECTED();
    }
    // RECURSION
    Add(records);
  }
}
Beispiel #5
0
bool SessionImpl::TryCreateFromTemplate(const PathName& path)
{
  unsigned r = TryDeriveTEXMFRoot(path);
  if (r == INVALID_ROOT_INDEX)
  {
    return false;
  }
  const char* lpszRelPath = Utils::GetRelativizedPath(path.GetData(), GetRootDirectoryPath(r).GetData());
  if (lpszRelPath == nullptr)
  {
    MIKTEX_UNEXPECTED();
  }
  string templ = lpszRelPath;
  templ += ".template";
  PathName configTemplatePath;
  if (FindFile(templ, MIKTEX_PATH_TEXMF_PLACEHOLDER, configTemplatePath))
  {
    Directory::Create(PathName(path).RemoveFileSpec());
    File::Copy(configTemplatePath, path);
    FileAttributeSet attr = File::GetAttributes(path);
    attr -= FileAttribute::ReadOnly;
    File::SetAttributes(path, attr);
    if (!Fndb::FileExists(path))
    {
      Fndb::Add({ {path} });
    }
    return true;
  }
  else
  {
    return false;
  }
}
Beispiel #6
0
const char* miktex_get_aux_directory()
{
  if (auxDirectory.Empty())
  {
    return nullptr;
  }
  else
  {
    return auxDirectory.GetData();
  }
}
Beispiel #7
0
bool WebAppInputLine::OpenInputFile(FILE** ppFile, const PathName& fileName)
{
  const char* lpszFileName = fileName.GetData();

#if defined(MIKTEX_WINDOWS)
  string utf8FileName;
  if (!Utils::IsUTF8(lpszFileName))
  {
    LogWarn("converting ANSI file name");
    utf8FileName = StringUtil::AnsiToUTF8(lpszFileName);
    LogWarn("conversion succeeded: " + utf8FileName);
    lpszFileName = utf8FileName.c_str();
  }
#endif

  shared_ptr<Session> session = GetSession();

  if (pimpl->enablePipes && lpszFileName[0] == '|')
  {
    string command = lpszFileName + 1;
    Session::ExamineCommandLineResult examineResult;
    string examinedCommand;
    string toBeExecuted;
    tie(examineResult, examinedCommand, toBeExecuted) = session->ExamineCommandLine(command);
    if (examineResult == Session::ExamineCommandLineResult::SyntaxError)
    {
      LogError("command line syntax error: " + command);
      return false;
    }
    if (examineResult != Session::ExamineCommandLineResult::ProbablySafe && examineResult != Session::ExamineCommandLineResult::MaybeSafe)
    {
      LogError("command is unsafe: " + command);
      return false;
    }
    switch (pimpl->shellCommandMode)
    {
    case ShellCommandMode::Unrestricted:
      toBeExecuted = command;
      break;
    case ShellCommandMode::Forbidden:
      LogError("command not executed: " + command);
      return false;
    case ShellCommandMode::Query:
      // TODO
    case ShellCommandMode::Restricted:
      if (examineResult != Session::ExamineCommandLineResult::ProbablySafe)
      {
        LogError("command not allowed: " + command);
        return false;
      }
      break;
    default:
      MIKTEX_UNEXPECTED();
    }
    LogInfo("executing input pipe: " + toBeExecuted);
    *ppFile = session->OpenFile(toBeExecuted, FileMode::Command, FileAccess::Read, false);
    pimpl->foundFile.Clear();
    pimpl->foundFileFq.Clear();
  }
  else
  {
#if defined(WITH_OMEGA)
    PathName unmangled;
    if (AmI("omega"))
    {
      unmangled = UnmangleNameOfFile(lpszFileName);
      lpszFileName = unmangled.GetData();
    }
#endif

    if (!session->FindFile(lpszFileName, GetInputFileType(), pimpl->foundFile))
    {
      return false;
    }

    pimpl->foundFileFq = pimpl->foundFile;
    pimpl->foundFileFq.MakeAbsolute();

#if 1 // 2015-01-15
    if (pimpl->foundFile[0] == '.' && PathName::IsDirectoryDelimiter(pimpl->foundFile[1]))
    {
      PathName temp(pimpl->foundFile.GetData() + 2);
      pimpl->foundFile = temp;
    }
#endif

    try
    {
      if (pimpl->foundFile.HasExtension(".gz"))
      {
        CommandLineBuilder cmd("zcat");
        cmd.AppendArgument(pimpl->foundFile);
        *ppFile = session->OpenFile(cmd.ToString(), FileMode::Command, FileAccess::Read, false);
      }
      else if (pimpl->foundFile.HasExtension(".bz2"))
      {
        CommandLineBuilder cmd("bzcat");
        cmd.AppendArgument(pimpl->foundFile);
        *ppFile = session->OpenFile(cmd.ToString(), FileMode::Command, FileAccess::Read, false);
      }
      else if (pimpl->foundFile.HasExtension(".xz") || pimpl->foundFile.HasExtension(".lzma"))
      {
        CommandLineBuilder cmd("xzcat");
        cmd.AppendArgument(pimpl->foundFile);
        *ppFile = session->OpenFile(cmd.ToString(), FileMode::Command, FileAccess::Read, false);
      }
      else
      {
        *ppFile = session->OpenFile(pimpl->foundFile.GetData(), FileMode::Open, FileAccess::Read, false);
      }
    }
#if defined(MIKTEX_WINDOWS)
    catch (const SharingViolationException &)
    {
    }
#endif
    catch (const UnauthorizedAccessException &)
    {
    }
    catch (const FileNotFoundException &)
    {
    }
  }

  if (*ppFile == nullptr)
  {
    return false;
  }

  if (!AmI("xetex"))
  {
    auto openFileInfo = session->TryGetOpenFileInfo(*ppFile);
    if (openFileInfo.first && openFileInfo.second.mode != FileMode::Command)
    {
      int bom = CheckBom(*ppFile);
      switch (bom)
      {
      case Bom::UTF8:
        LogInfo("UTF8 BOM detected: " + openFileInfo.second.fileName);
        break;
      case Bom::UTF16be:
        LogInfo("UTF16be BOM detected: " + openFileInfo.second.fileName);
        break;
      case Bom::UTF16le:
        LogInfo("UTF16le BOM detected: " + openFileInfo.second.fileName);
        break;
      }
    }
  }

  pimpl->lastInputFileName = lpszFileName;

  return true;
}
Beispiel #8
0
bool WebAppInputLine::OpenOutputFile(C4P::FileRoot& f, const PathName& fileName, bool text, PathName& outPath)
{
  const char* lpszPath = fileName.GetData();
#if defined(MIKTEX_WINDOWS)
  string utf8Path;
  if (!Utils::IsUTF8(lpszPath))
  {
    utf8Path = StringUtil::AnsiToUTF8(lpszPath);
    lpszPath = utf8Path.c_str();
  }
#endif
  shared_ptr<Session> session = GetSession();
  FILE* file = nullptr;
  if (pimpl->enablePipes && lpszPath[0] == '|')
  {
    string command = lpszPath + 1;
    Session::ExamineCommandLineResult examineResult;
    string examinedCommand;
    string toBeExecuted;
    tie(examineResult, examinedCommand, toBeExecuted) = session->ExamineCommandLine(command);
    if (examineResult == Session::ExamineCommandLineResult::SyntaxError)
    {
      LogError("command line syntax error: " + command);
      return false;
    }
    if (examineResult != Session::ExamineCommandLineResult::ProbablySafe && examineResult != Session::ExamineCommandLineResult::MaybeSafe)
    {
      LogError("command is unsafe: " + command);
      return false;
    }
    switch (pimpl->shellCommandMode)
    {
    case ShellCommandMode::Unrestricted:
      toBeExecuted = command;
      break;
    case ShellCommandMode::Forbidden:
      LogError("command not executed: " + command);
      return false;
    case ShellCommandMode::Query:
      // TODO
    case ShellCommandMode::Restricted:
      if (examineResult != Session::ExamineCommandLineResult::ProbablySafe)
      {
        LogError("command not allowed: " + command);
        return false;
      }
      break;
    default:
      MIKTEX_UNEXPECTED();
    }
    LogInfo("executing output pipe: " + toBeExecuted);
    file = session->OpenFile(toBeExecuted, FileMode::Command, FileAccess::Write, false);
  }
  else
  {
#if defined(WITH_OMEGA)
    PathName unmangled;
    if (AmI("omega"))
    {
      unmangled = UnmangleNameOfFile(lpszPath);
      lpszPath = unmangled.GetData();
    }
#endif
    bool isAuxFile = !IsOutputFile(lpszPath);
    PathName path;
    if (isAuxFile && !pimpl->auxDirectory.Empty())
    {
      path = pimpl->auxDirectory / lpszPath;
      lpszPath = path.GetData();
    }
    else if (!pimpl->outputDirectory.Empty())
    {
      path = pimpl->outputDirectory / lpszPath;
      lpszPath = path.GetData();
    }
    file = session->TryOpenFile(lpszPath, FileMode::Create, FileAccess::Write, text);
    if (file != nullptr)
    {
      outPath = lpszPath;
    }
  }
  if (file == nullptr)
  {
    return false;
  }
  f.Attach(file, true);
  return true;
}
Beispiel #9
0
int MAIN(int argc, MAINCHAR** argv)
{
  try
  {
    // build new argv
    vector<string> utf8args;
    for (int idx = 0; idx < argc; ++idx)
    {
      utf8args.push_back(TU_(argv[idx]));
    }
    vector<char*> newargv;
    newargv.reserve(utf8args.size() + 1);
    for (const string& arg : utf8args)
    {
      newargv.push_back((char*)arg.c_str());
    }
    newargv.push_back(nullptr);

    app.Init(newargv);

    // determine script name
    PathName programName = PathName(newargv[0]).GetFileNameWithoutExtension();

    std::string scriptName;

#if defined(MTXRUN)
    bool isLuatools = (PathName::Compare(programName, "luatools") == 0);
    bool isMtxrun = (PathName::Compare(programName, "mtxrun") == 0);
    bool isTexmfstart = (PathName::Compare(programName, "texmfstart") == 0);
    if (isLuatools)
    {
      scriptName = "luatools";
    }
    else
    {
      scriptName = "mtxrun";
    }
#else
    scriptName = programName.ToString();
#endif

    // get relative script path
    PathName scriptsIni;
    if (!app.GetSession()->FindFile(MIKTEX_PATH_SCRIPTS_INI, MIKTEX_PATH_TEXMF_PLACEHOLDER, scriptsIni))
    {
      MIKTEX_FATAL_ERROR(MIKTEXTEXT("The script configuration file cannot be found."));
    }
    unique_ptr<Cfg> scriptConfig(Cfg::Create());
    scriptConfig->Read(scriptsIni, true);
    std::string relScriptPath;
    if (!scriptConfig->TryGetValueAsString(CFGKEY, scriptName, relScriptPath))
    {
      MIKTEX_FATAL_ERROR_2(MIKTEXTEXT("The Lua script is not registered."), "programName", programName.ToString());
    }
    scriptConfig = nullptr;

    // find script
    PathName scriptPath;
    if (!app.GetSession()->FindFile(relScriptPath, MIKTEX_PATH_TEXMF_PLACEHOLDER, scriptPath))
    {
      MIKTEX_FATAL_ERROR_2(MIKTEXTEXT("The Lua script could not be found."), "path", relScriptPath);
    }

    // inject arguments
    vector<char*> extraArgs;
    extraArgs.push_back("--luaonly");
    extraArgs.push_back(scriptPath.GetData());
#if defined(MTXRUN)
    if (!(isLuatools || isMtxrun || isTexmfstart))
    {
      extraArgs.push_back("--script");
      extraArgs.push_back(programName);
    }
#endif
    newargv.insert(newargv.begin() + 1, extraArgs.begin(), extraArgs.end());

    // run texlua
    int exitCode = Main(newargv.size() - 1, &newargv[0]);

    app.Finalize2(exitCode);

    return exitCode;
  }
  catch (const MiKTeXException& e)
  {
    Utils::PrintException(e);
    app.Finalize2(1);
    return 1;
  }
  catch (const std::exception& e)
  {
    Utils::PrintException(e);
    app.Finalize2(1);
    return 1;
  }
  catch (int exitCode)
  {
    app.Finalize2(exitCode);
    return exitCode;
  }
}
Beispiel #10
0
/*
 * UserConfig:    $HOME/.miktex/texmfs/config
 * UserData:      $HOME/.miktex/texmfs/data
 * UserInstall:   $HOME/.miktex/texmfs/install
 * CommonConfig:  /var/lib/miktex-texmf           (DEB,RPM)
 *             or /var/local/lib/miktex-texmf     (TGZ)
 *             or /opt/miktex/texmfs/config       (self-contained)
 * CommonData:    /var/cache/miktex-texmf         (DEB,RPM,TGZ)
 *             or /opt/miktex/texmfs/data         (self-contained)
 * CommonInstall: /usr/local/share/miktex-texmf   (DEB,RPM,TGZ)
 *             or /opt/miktex/texmfs/install      (self-contained)
 */
StartupConfig SessionImpl::DefaultConfig(MiKTeXConfiguration config, const PathName& commonPrefixArg, const PathName& userPrefixArg)
{
  StartupConfig ret;
  if (config == MiKTeXConfiguration::None)
  {
    config = MiKTeXConfiguration::Regular;
  }
  ret.config = config;
  string home;
  if (!Utils::GetEnvironmentString("HOME", home))
  {
    MIKTEX_FATAL_ERROR(T_("Environment variable HOME is not set."));
  }
  PathName home_miktex(home);
#if defined(MIKTEX_MACOS_BUNDLE)
  home_miktex /= MIKTEX_MACOS_MIKTEX_LIBRARY_FOLDER;
#else
  home_miktex /= ".miktex";
#endif
  PathName home_miktex_texmfs(home_miktex);
  home_miktex_texmfs /= "texmfs";
  ret.userConfigRoot = home_miktex_texmfs;
  ret.userConfigRoot /= "config";
  ret.userDataRoot = home_miktex_texmfs;
  ret.userDataRoot /= "data";
  ret.userInstallRoot = home_miktex_texmfs;
  ret.userInstallRoot /= "install";
#if !defined(MIKTEX_MACOS_BUNDLE)
  PathName prefix = GetMyPrefix(false);
  vector<string> splittedPrefix = PathName::Split(prefix);
  size_t n = splittedPrefix.size();
  MIKTEX_ASSERT(n > 0 && splittedPrefix[0] == "/");
  size_t pos = n;
  if (n > 1 && splittedPrefix[n - 1] == "usr")
  {
    pos = n - 1;
  }
  else if (n > 2 && splittedPrefix[n - 2] == "usr" && splittedPrefix[n - 1] == "local")
  {
    pos = n - 2;
  }
  if (pos < n)
  {
    PathName destdir;
    for (size_t i = 0; i < pos; ++i)
    {
      destdir /= splittedPrefix[i];
    }
    MIKTEX_ASSERT(MIKTEX_SYSTEM_VAR_LIB_DIR[0] == '/');
    ret.commonConfigRoot = destdir / PathName(MIKTEX_SYSTEM_VAR_LIB_DIR + 1) / MIKTEX_PREFIX "texmf";
    MIKTEX_ASSERT(MIKTEX_SYSTEM_VAR_CACHE_DIR[0] == '/');
    ret.commonDataRoot = destdir / PathName(MIKTEX_SYSTEM_VAR_CACHE_DIR + 1) / MIKTEX_PREFIX "texmf";
    ret.commonInstallRoot = destdir / "usr/local" / MIKTEX_INSTALL_DIR;
  }
#endif
  if (ret.commonConfigRoot.Empty())
  {
#if defined(MIKTEX_MACOS_BUNDLE)
    PathName system_miktex_texmfs("/");
    system_miktex_texmfs /= MIKTEX_MACOS_MIKTEX_LIBRARY_FOLDER;
#else
    if (!PathName::Match("*miktex*", prefix.GetData()))
    {
      // TODO: log funny installation prefix
    }
    PathName system_miktex_texmfs(prefix);
#endif
    system_miktex_texmfs /= "texmfs";
    ret.commonConfigRoot = system_miktex_texmfs / "config";
    ret.commonDataRoot = system_miktex_texmfs / "data";
    ret.commonInstallRoot = system_miktex_texmfs / "install";
  }
  return ret;
}