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>
50OUString translateExternalUris(OUString
const & input) {
54 translateToInternal(input));
55 return t.isEmpty() ? input :
t;
58std::vector< OUString > translateExternalUris(
59 std::vector< OUString >
const & input)
61 std::vector< OUString >
t;
62 t.reserve(input.size());
63 for (
auto const& elem : input)
65 t.push_back(translateExternalUris(elem));
70class ExtCommandLineSupplier:
public CommandLineArgs::Supplier {
72 explicit ExtCommandLineSupplier():
75 ? 0 : rtl_getAppCommandArgCount()),
84 virtual std::optional< OUString > getCwdUrl()
override {
return m_cwdUrl; }
86 virtual bool next(OUString * argument)
override {
87 OSL_ASSERT(argument !=
nullptr);
102enum class CommandLineEvent {
104 ForceOpen, ForceNew, Conversion, BatchPrint
113CommandLineEvent CheckOfficeURI( OUString& arg, CommandLineEvent curEvt)
117 bool isOfficeURI = ( arg.startsWithIgnoreAsciiCase(
"vnd.libreoffice.command:", &rest1)
118 || arg.startsWithIgnoreAsciiCase(
"ms-word:", &rest1)
119 || arg.startsWithIgnoreAsciiCase(
"ms-powerpoint:", &rest1)
120 || arg.startsWithIgnoreAsciiCase(
"ms-excel:", &rest1)
121 || arg.startsWithIgnoreAsciiCase(
"ms-visio:", &rest1)
122 || arg.startsWithIgnoreAsciiCase(
"ms-access:", &rest1));
130 OUString decoded_rest = rest1.replaceAll(
"%7C",
"|").replaceAll(
"%7c",
"|");
134 if (decoded_rest.startsWith(
"ofv|u|", &rest2))
137 if (curEvt == CommandLineEvent::Open)
138 curEvt = CommandLineEvent::View;
139 nURIlen = rest2.indexOf(
"|");
141 else if (decoded_rest.startsWith(
"ofe|u|", &rest2))
144 if (curEvt == CommandLineEvent::Open)
145 curEvt = CommandLineEvent::ForceOpen;
146 nURIlen = rest2.indexOf(
"|");
148 else if (decoded_rest.startsWith(
"nft|u|", &rest2))
151 if (curEvt == CommandLineEvent::Open)
152 curEvt = CommandLineEvent::ForceNew;
153 nURIlen = rest2.indexOf(
"|");
162 if (curEvt == CommandLineEvent::Open)
163 curEvt = CommandLineEvent::View;
167 nURIlen = rest2.getLength();
168 auto const uri = rest2.subView(0, nURIlen);
172 curEvt = CommandLineEvent::Open;
181bool SkipNewline(
const char* & pStr)
183 if ((*pStr !=
'\r') && (*pStr !=
'\n'))
193CommandLineEvent CheckWebQuery( OUString& arg, CommandLineEvent curEvt)
196 if (!arg.endsWithIgnoreAsciiCase(
".iqy"))
200 std::lock_guard aGuard(aMutex);
206 if (osl::FileBase::getFileURLFromSystemPath(arg, sFileURL) != osl::FileBase::RC::E_None)
210 const sal_Int32 nBufLen = 32000;
211 char sBuffer[nBufLen];
212 size_t nRead =
stream.ReadBytes(sBuffer, nBufLen);
216 const char* pPos = sBuffer;
217 if (strncmp(pPos,
"WEB", 3) != 0)
220 if (!SkipNewline(pPos))
225 if (!SkipNewline(pPos))
228 OStringBuffer aResult(nRead);
231 const char* pPos1 = pPos;
232 const char* pEnd = sBuffer + nRead;
233 while ((pPos1 < pEnd) && (*pPos1 !=
'\r') && (*pPos1 !=
'\n'))
235 aResult.append(pPos, pPos1 - pPos);
239 }
while ((nRead =
stream.ReadBytes(sBuffer, nBufLen)) > 0);
243 arg = OStringToOUString(aResult, osl_getThreadTextEncoding());
244 return CommandLineEvent::ForceNew;
248 SAL_WARN(
"desktop.app",
"An error processing Web Query file: " << arg);
270 ExtCommandLineSupplier s;
283 CommandLineEvent eCurrentEvent = CommandLineEvent::Open;
288 if ( !supplier.
next( &aArg ) )
293 if ( !aArg.isEmpty() )
297 OUString oDeprecatedArg;
298 if (!aArg.startsWith(
"--", &oArg) && aArg.startsWith(
"-", &oArg)
299 && aArg.getLength() > 2)
301 oDeprecatedArg = aArg;
305 if ( oArg ==
"minimized" )
309 else if ( oArg ==
"invisible" )
313 else if ( oArg ==
"norestore" )
317 else if ( oArg ==
"nodefault" )
321 else if ( oArg ==
"headless" )
325 else if ( oArg ==
"safe-mode" )
329 else if ( oArg ==
"cat" )
333 eCurrentEvent = CommandLineEvent::Conversion;
336 else if ( oArg ==
"script-cat" )
339 eCurrentEvent = CommandLineEvent::Conversion;
342 else if ( oArg ==
"quickstart" )
344#if defined(ENABLE_QUICKSTART_APPLET)
349 else if ( oArg ==
"quickstart=no" )
354 else if ( oArg ==
"terminate_after_init" )
358 else if ( oArg ==
"nofirststartwizard" )
362 else if ( oArg ==
"nologo" )
366#if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
367 else if ( oArg ==
"nolockcheck" )
372 else if ( oArg ==
"help" || aArg ==
"-h" || aArg ==
"-?" )
376 else if ( oArg ==
"helpwriter" )
380 else if ( oArg ==
"helpcalc" )
384 else if ( oArg ==
"helpdraw" )
388 else if ( oArg ==
"helpimpress" )
392 else if ( oArg ==
"helpbase" )
396 else if ( oArg ==
"helpbasic" )
400 else if ( oArg ==
"helpmath" )
404 else if ( oArg ==
"protector" )
414 m_unknown =
"--protector must be followed by two arguments";
416 else if ( oArg ==
"version" )
420 else if ( oArg.startsWith(
"splash-pipe=") )
430 else if ( aArg.startsWith(
"-psn") )
432 oDeprecatedArg.clear();
435#if HAVE_FEATURE_MACOSX_SANDBOX
436 else if ( oArg ==
"nstemporarydirectory" )
438 printf(
"%s\n", [NSTemporaryDirectory() UTF8String]);
446 else if ( oArg ==
"Embedding" )
448 oDeprecatedArg.clear();
451 else if ( oArg.startsWith(
"infilter=", &rest))
455 else if ( oArg.startsWith(
"accept=", &rest))
459 else if ( oArg.startsWith(
"unaccept=", &rest))
463 else if ( oArg.startsWith(
"language=", &rest))
467 else if ( oArg.startsWith(
"pidfile=", &rest))
471 else if ( oArg ==
"writer" )
476 else if ( oArg ==
"calc" )
481 else if ( oArg ==
"draw" )
486 else if ( oArg ==
"impress" )
491 else if ( oArg ==
"base" )
496 else if ( oArg ==
"global" )
501 else if ( oArg ==
"math" )
506 else if ( oArg ==
"web" )
511 else if ( aArg ==
"-n" )
514 eCurrentEvent = CommandLineEvent::ForceNew;
516 else if ( aArg ==
"-o" )
519 eCurrentEvent = CommandLineEvent::ForceOpen;
521 else if ( oArg ==
"pt" )
524 eCurrentEvent = CommandLineEvent::PrintTo;
526 if (supplier.
next(&aArg))
529 m_unknown =
"--pt must be followed by printername";
531 else if ( aArg ==
"-p" )
534 eCurrentEvent = CommandLineEvent::Print;
536 else if ( oArg ==
"view")
539 eCurrentEvent = CommandLineEvent::View;
541 else if ( oArg ==
"show" )
544 eCurrentEvent = CommandLineEvent::Start;
546 else if ( oArg ==
"display" )
553 (void)supplier.
next(&aArg);
555 else if ( oArg ==
"convert-to" )
557 eCurrentEvent = CommandLineEvent::Conversion;
559 if (supplier.
next(&aArg))
566 m_unknown =
"--convert-to must be followed by output_file_extension[:output_filter_name]";
568 else if ( oArg ==
"print-to-file" )
570 eCurrentEvent = CommandLineEvent::BatchPrint;
572 else if ( oArg ==
"printer-name" )
574 if (eCurrentEvent == CommandLineEvent::BatchPrint)
577 if (supplier.
next(&aArg))
580 m_unknown =
"--printer-name must be followed by printername";
584 m_unknown =
"--printer-name must directly follow --print-to-file";
587 else if ( oArg ==
"outdir" )
589 if (eCurrentEvent == CommandLineEvent::Conversion ||
590 eCurrentEvent == CommandLineEvent::BatchPrint)
592 if (supplier.
next(&aArg))
595 m_unknown =
"--outdir must be followed by output directory path";
599 m_unknown =
"--outdir must directly follow either output filter specification of --convert-to, or --print-to-file or its printer specification";
602 else if ( eCurrentEvent == CommandLineEvent::Conversion
603 && oArg ==
"convert-images-to" )
605 if (supplier.
next(&aArg))
608 m_unknown =
"--convert-images-to must be followed by an image type";
610 else if ( aArg.startsWith(
"-") )
618 oArg !=
"backtrace" &&
620 oArg !=
"valgrind" &&
623 oArg !=
"session=" &&
626 oArg !=
"nocrashreport" &&
631 oDeprecatedArg.clear();
640 CommandLineEvent eThisEvent = CheckOfficeURI(aArg, eCurrentEvent);
643 eThisEvent = CheckWebQuery(aArg, eThisEvent);
647 case CommandLineEvent::Open:
651 case CommandLineEvent::View:
655 case CommandLineEvent::Start:
659 case CommandLineEvent::Print:
663 case CommandLineEvent::PrintTo:
667 case CommandLineEvent::ForceNew:
671 case CommandLineEvent::ForceOpen:
675 case CommandLineEvent::Conversion:
676 case CommandLineEvent::BatchPrint:
682 if (!oDeprecatedArg.isEmpty())
685 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