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; }
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; }
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; }
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); } }
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; } }
const char* miktex_get_aux_directory() { if (auxDirectory.Empty()) { return nullptr; } else { return auxDirectory.GetData(); } }
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; }
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; }
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; } }
/* * 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; }