20#include <config_features.h>
22#if HAVE_FEATURE_MACOSX_SANDBOX
24#include <Foundation/Foundation.h>
29#include <osl/thread.hxx>
32#include <rtl/ustring.hxx>
33#include <rtl/process.h>
36#include <com/sun/star/uri/ExternalUriReferenceTranslator.hpp>
39#include <rtl/strbuf.hxx>
40#include <osl/file.hxx>
54OUString translateExternalUris(OUString
const & input) {
58 translateToInternal(input));
59 return t.isEmpty() ? input :
t;
62std::vector< OUString > translateExternalUris(
63 std::vector< OUString >
const & input)
65 std::vector< OUString >
t;
66 t.reserve(input.size());
67 for (
auto const& elem : input)
69 t.push_back(translateExternalUris(elem));
74class ExtCommandLineSupplier:
public CommandLineArgs::Supplier {
76 explicit ExtCommandLineSupplier():
79 ? 0 : rtl_getAppCommandArgCount()),
88 virtual std::optional< OUString > getCwdUrl()
override {
return m_cwdUrl; }
90 virtual bool next(OUString * argument)
override {
91 OSL_ASSERT(argument !=
nullptr);
106enum class CommandLineEvent {
108 ForceOpen, ForceNew, Conversion, BatchPrint
117CommandLineEvent CheckOfficeURI( OUString& arg, CommandLineEvent curEvt)
121 bool isOfficeURI = ( arg.startsWithIgnoreAsciiCase(
"vnd.libreoffice.command:", &rest1)
122 || arg.startsWithIgnoreAsciiCase(
"ms-word:", &rest1)
123 || arg.startsWithIgnoreAsciiCase(
"ms-powerpoint:", &rest1)
124 || arg.startsWithIgnoreAsciiCase(
"ms-excel:", &rest1)
125 || arg.startsWithIgnoreAsciiCase(
"ms-visio:", &rest1)
126 || arg.startsWithIgnoreAsciiCase(
"ms-access:", &rest1));
134 OUString decoded_rest = rest1.replaceAll(
"%7C",
"|").replaceAll(
"%7c",
"|");
138 if (decoded_rest.startsWith(
"ofv|u|", &rest2))
141 if (curEvt == CommandLineEvent::Open)
142 curEvt = CommandLineEvent::View;
143 nURIlen = rest2.indexOf(
"|");
145 else if (decoded_rest.startsWith(
"ofe|u|", &rest2))
148 if (curEvt == CommandLineEvent::Open)
149 curEvt = CommandLineEvent::ForceOpen;
150 nURIlen = rest2.indexOf(
"|");
152 else if (decoded_rest.startsWith(
"nft|u|", &rest2))
155 if (curEvt == CommandLineEvent::Open)
156 curEvt = CommandLineEvent::ForceNew;
157 nURIlen = rest2.indexOf(
"|");
166 if (curEvt == CommandLineEvent::Open)
167 curEvt = CommandLineEvent::View;
171 nURIlen = rest2.getLength();
172 auto const uri = rest2.subView(0, nURIlen);
176 curEvt = CommandLineEvent::Open;
185bool SkipNewline(
const char* & pStr)
187 if ((*pStr !=
'\r') && (*pStr !=
'\n'))
197CommandLineEvent CheckWebQuery( OUString& arg, CommandLineEvent curEvt)
200 if (!arg.endsWithIgnoreAsciiCase(
".iqy"))
204 std::lock_guard aGuard(aMutex);
210 if (osl::FileBase::getFileURLFromSystemPath(arg, sFileURL) != osl::FileBase::RC::E_None)
214 const sal_Int32 nBufLen = 32000;
215 char sBuffer[nBufLen];
216 size_t nRead =
stream.ReadBytes(sBuffer, nBufLen);
220 const char* pPos = sBuffer;
221 if (strncmp(pPos,
"WEB", 3) != 0)
224 if (!SkipNewline(pPos))
229 if (!SkipNewline(pPos))
232 OStringBuffer aResult(nRead);
235 const char* pPos1 = pPos;
236 const char* pEnd = sBuffer + nRead;
237 while ((pPos1 < pEnd) && (*pPos1 !=
'\r') && (*pPos1 !=
'\n'))
239 aResult.append(pPos, pPos1 - pPos);
243 }
while ((nRead =
stream.ReadBytes(sBuffer, nBufLen)) > 0);
247 arg = OStringToOUString(aResult, osl_getThreadTextEncoding());
248 return CommandLineEvent::ForceNew;
252 SAL_WARN(
"desktop.app",
"An error processing Web Query file: " << arg);
274 ExtCommandLineSupplier s;
287 CommandLineEvent eCurrentEvent = CommandLineEvent::Open;
292 if ( !supplier.
next( &aArg ) )
297 if ( !aArg.isEmpty() )
301 OUString oDeprecatedArg;
302 if (!aArg.startsWith(
"--", &oArg) && aArg.startsWith(
"-", &oArg)
303 && aArg.getLength() > 2)
305 oDeprecatedArg = aArg;
309 if ( oArg ==
"minimized" )
313 else if ( oArg ==
"invisible" )
317 else if ( oArg ==
"norestore" )
321 else if ( oArg ==
"nodefault" )
325 else if ( oArg ==
"headless" )
329 else if ( oArg ==
"eventtesting" )
333 else if ( oArg ==
"safe-mode" )
337 else if ( oArg ==
"cat" )
341 eCurrentEvent = CommandLineEvent::Conversion;
344 else if ( oArg ==
"script-cat" )
347 eCurrentEvent = CommandLineEvent::Conversion;
350 else if ( oArg ==
"quickstart" )
352#if defined(ENABLE_QUICKSTART_APPLET)
357 else if ( oArg ==
"quickstart=no" )
362 else if ( oArg ==
"terminate_after_init" )
366 else if ( oArg ==
"nofirststartwizard" )
370 else if ( oArg ==
"nologo" )
374#if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
375 else if ( oArg ==
"nolockcheck" )
380 else if ( oArg ==
"help" || aArg ==
"-h" || aArg ==
"-?" )
384 else if ( oArg ==
"helpwriter" )
388 else if ( oArg ==
"helpcalc" )
392 else if ( oArg ==
"helpdraw" )
396 else if ( oArg ==
"helpimpress" )
400 else if ( oArg ==
"helpbase" )
404 else if ( oArg ==
"helpbasic" )
408 else if ( oArg ==
"helpmath" )
412 else if ( oArg ==
"protector" )
422 m_unknown =
"--protector must be followed by two arguments";
424 else if ( oArg ==
"version" )
428 else if ( oArg.startsWith(
"splash-pipe=") )
438 else if ( aArg.startsWith(
"-psn") )
440 oDeprecatedArg.clear();
443#if HAVE_FEATURE_MACOSX_SANDBOX
444 else if ( oArg ==
"nstemporarydirectory" )
446 printf(
"%s\n", [NSTemporaryDirectory() UTF8String]);
454 else if ( oArg ==
"Embedding" )
456 oDeprecatedArg.clear();
459 else if ( oArg.startsWith(
"infilter=", &rest))
463 else if ( oArg.startsWith(
"accept=", &rest))
467 else if ( oArg.startsWith(
"unaccept=", &rest))
471 else if ( oArg.startsWith(
"language=", &rest))
475 else if ( oArg.startsWith(
"pidfile=", &rest))
479 else if ( oArg ==
"writer" )
484 else if ( oArg ==
"calc" )
489 else if ( oArg ==
"draw" )
494 else if ( oArg ==
"impress" )
499 else if ( oArg ==
"base" )
504 else if ( oArg ==
"global" )
509 else if ( oArg ==
"math" )
514 else if ( oArg ==
"web" )
519 else if ( aArg ==
"-n" )
522 eCurrentEvent = CommandLineEvent::ForceNew;
524 else if ( aArg ==
"-o" )
527 eCurrentEvent = CommandLineEvent::ForceOpen;
529 else if ( oArg ==
"pt" )
532 eCurrentEvent = CommandLineEvent::PrintTo;
534 if (supplier.
next(&aArg))
537 m_unknown =
"--pt must be followed by printername";
539 else if ( aArg ==
"-p" )
542 eCurrentEvent = CommandLineEvent::Print;
544 else if ( oArg ==
"view")
547 eCurrentEvent = CommandLineEvent::View;
549 else if ( oArg ==
"show" )
552 eCurrentEvent = CommandLineEvent::Start;
554 else if ( oArg ==
"display" )
561 (void)supplier.
next(&aArg);
563 else if ( oArg ==
"convert-to" )
565 eCurrentEvent = CommandLineEvent::Conversion;
567 if (supplier.
next(&aArg))
574 m_unknown =
"--convert-to must be followed by output_file_extension[:output_filter_name]";
576 else if ( oArg ==
"print-to-file" )
578 eCurrentEvent = CommandLineEvent::BatchPrint;
580 else if ( oArg ==
"printer-name" )
582 if (eCurrentEvent == CommandLineEvent::BatchPrint)
585 if (supplier.
next(&aArg))
588 m_unknown =
"--printer-name must be followed by printername";
592 m_unknown =
"--printer-name must directly follow --print-to-file";
595 else if ( oArg ==
"outdir" )
597 if (eCurrentEvent == CommandLineEvent::Conversion ||
598 eCurrentEvent == CommandLineEvent::BatchPrint)
600 if (supplier.
next(&aArg))
603 m_unknown =
"--outdir must be followed by output directory path";
607 m_unknown =
"--outdir must directly follow either output filter specification of --convert-to, or --print-to-file or its printer specification";
610 else if ( eCurrentEvent == CommandLineEvent::Conversion
611 && oArg ==
"convert-images-to" )
613 if (supplier.
next(&aArg))
616 m_unknown =
"--convert-images-to must be followed by an image type";
618 else if ( aArg.startsWith(
"-") )
626 oArg !=
"backtrace" &&
628 oArg !=
"valgrind" &&
631 oArg !=
"session=" &&
634 oArg !=
"nocrashreport" &&
639 oDeprecatedArg.clear();
648 CommandLineEvent eThisEvent = CheckOfficeURI(aArg, eCurrentEvent);
651 eThisEvent = CheckWebQuery(aArg, eThisEvent);
655 case CommandLineEvent::Open:
659 case CommandLineEvent::View:
663 case CommandLineEvent::Start:
667 case CommandLineEvent::Print:
671 case CommandLineEvent::PrintTo:
675 case CommandLineEvent::ForceNew:
679 case CommandLineEvent::ForceOpen:
683 case CommandLineEvent::Conversion:
684 case CommandLineEvent::BatchPrint:
690 if (!oDeprecatedArg.isEmpty())
693 fprintf(stderr,
"Warning: %s is deprecated. Use -%s instead.\n", sArg.getStr(), sArg.getStr());
::boost::spirit::classic::rule< ScannerT > argument
INetProtocol GetProtocol() const
Exception & operator=(Exception const &)
bool m_terminateafterinit
OUString m_conversionparams
std::vector< OUString > GetForceNewList() const
std::vector< OUString > m_unaccept
std::vector< OUString > m_openlist
std::vector< OUString > m_infilter
std::vector< OUString > GetConversionList() const
std::vector< OUString > m_printtolist
std::vector< OUString > m_forceopenlist
std::vector< OUString > m_accept
OUString GetConversionOut() const
std::vector< OUString > GetViewList() const
std::vector< OUString > GetStartList() const
std::vector< OUString > GetPrintList() const
std::vector< OUString > m_conversionlist
std::vector< OUString > m_startlist
std::vector< OUString > GetForceOpenList() const
bool HasModuleParam() const
std::vector< OUString > m_printlist
std::vector< OUString > m_viewlist
std::vector< OUString > GetPrintToList() const
std::vector< OUString > GetOpenList() const
std::optional< OUString > m_cwdUrl
void ParseCommandLine_Impl(Supplier &supplier)
std::vector< OUString > m_forcenewlist
static bool getProcessWorkingDir(OUString &rUrl)
std::optional< OUString > m_cwdUrl
Reference< XOutputStream > stream
#define SAL_WARN(area, stream)
Reference< XComponentContext > getProcessComponentContext()
css::uno::Reference< css::deployment::XPackageRegistry > create(css::uno::Reference< css::deployment::XPackageRegistry > const &xRootRegistry, OUString const &context, OUString const &cachePath, css::uno::Reference< css::uno::XComponentContext > const &xComponentContext)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
virtual bool next(OUString *argument)=0
virtual std::optional< OUString > getCwdUrl()=0