20 #include <config_features.h>
22 #if HAVE_FEATURE_MACOSX_SANDBOX
24 #include <Foundation/Foundation.h>
29 #include <osl/thread.hxx>
31 #include <rtl/ustring.hxx>
32 #include <rtl/process.h>
35 #include <com/sun/star/uri/ExternalUriReferenceTranslator.hpp>
38 #include <rtl/strbuf.hxx>
39 #include <osl/file.hxx>
51 OUString translateExternalUris(OUString
const & input) {
55 translateToInternal(input));
56 return t.isEmpty() ? input :
t;
59 std::vector< OUString > translateExternalUris(
60 std::vector< OUString >
const & input)
62 std::vector< OUString >
t;
63 t.reserve(input.size());
64 for (
auto const& elem : input)
66 t.push_back(translateExternalUris(elem));
71 class ExtCommandLineSupplier:
public CommandLineArgs::Supplier {
73 explicit ExtCommandLineSupplier():
76 ? 0 : rtl_getAppCommandArgCount()),
85 virtual std::optional< OUString > getCwdUrl()
override {
return m_cwdUrl; }
87 virtual bool next(OUString * argument)
override {
88 OSL_ASSERT(argument !=
nullptr);
90 rtl_getAppCommandArg(
m_index++, &argument->pData);
103 enum class CommandLineEvent {
105 ForceOpen, ForceNew, Conversion, BatchPrint
114 CommandLineEvent CheckOfficeURI( OUString& arg, CommandLineEvent curEvt)
118 bool isOfficeURI = ( arg.startsWithIgnoreAsciiCase(
"vnd.libreoffice.command:", &rest1)
119 || arg.startsWithIgnoreAsciiCase(
"ms-word:", &rest1)
120 || arg.startsWithIgnoreAsciiCase(
"ms-powerpoint:", &rest1)
121 || arg.startsWithIgnoreAsciiCase(
"ms-excel:", &rest1)
122 || arg.startsWithIgnoreAsciiCase(
"ms-visio:", &rest1)
123 || arg.startsWithIgnoreAsciiCase(
"ms-access:", &rest1));
131 OUString decoded_rest = rest1.replaceAll(
"%7C",
"|").replaceAll(
"%7c",
"|");
135 if (decoded_rest.startsWith(
"ofv|u|", &rest2))
138 if (curEvt == CommandLineEvent::Open)
139 curEvt = CommandLineEvent::View;
140 nURIlen = rest2.indexOf(
"|");
142 else if (decoded_rest.startsWith(
"ofe|u|", &rest2))
145 if (curEvt == CommandLineEvent::Open)
146 curEvt = CommandLineEvent::ForceOpen;
147 nURIlen = rest2.indexOf(
"|");
149 else if (decoded_rest.startsWith(
"nft|u|", &rest2))
152 if (curEvt == CommandLineEvent::Open)
153 curEvt = CommandLineEvent::ForceNew;
154 nURIlen = rest2.indexOf(
"|");
163 if (curEvt == CommandLineEvent::Open)
164 curEvt = CommandLineEvent::View;
168 nURIlen = rest2.getLength();
169 arg = rest2.copy(0, nURIlen);
175 bool SkipNewline(
const char* & pStr)
177 if ((*pStr !=
'\r') && (*pStr !=
'\n'))
187 CommandLineEvent CheckWebQuery( OUString& arg, CommandLineEvent curEvt)
190 if (!arg.endsWithIgnoreAsciiCase(
".iqy"))
194 osl::MutexGuard aGuard(aMutex);
200 if (osl::FileBase::getFileURLFromSystemPath(arg, sFileURL) != osl::FileBase::RC::E_None)
204 const sal_Int32 nBufLen = 32000;
205 char sBuffer[nBufLen];
206 size_t nRead =
stream.ReadBytes(sBuffer, nBufLen);
210 const char* pPos = sBuffer;
211 if (strncmp(pPos,
"WEB", 3) != 0)
214 if (!SkipNewline(pPos))
219 if (!SkipNewline(pPos))
222 OStringBuffer aResult(nRead);
225 const char* pPos1 = pPos;
226 const char* pEnd = sBuffer + nRead;
227 while ((pPos1 < pEnd) && (*pPos1 !=
'\r') && (*pPos1 !=
'\n'))
229 aResult.append(pPos, pPos1 - pPos);
233 }
while ((nRead =
stream.ReadBytes(sBuffer, nBufLen)) > 0);
237 arg = OStringToOUString(aResult.makeStringAndClear(), osl_getThreadTextEncoding());
238 return CommandLineEvent::ForceNew;
242 SAL_WARN(
"desktop.app",
"An error processing Web Query file: " << arg);
250 CommandLineArgs::Supplier::Exception::Exception() {}
252 CommandLineArgs::Supplier::Exception::Exception(
Exception const &) {}
255 CommandLineArgs::Supplier::Exception::operator =(
Exception const &)
258 CommandLineArgs::Supplier::~Supplier() {}
261 CommandLineArgs::CommandLineArgs()
264 ExtCommandLineSupplier s;
265 ParseCommandLine_Impl( s );
268 CommandLineArgs::CommandLineArgs(
Supplier& supplier )
271 ParseCommandLine_Impl( supplier );
274 void CommandLineArgs::ParseCommandLine_Impl(
Supplier& supplier )
277 CommandLineEvent eCurrentEvent = CommandLineEvent::Open;
282 if ( !supplier.
next( &aArg ) )
287 if ( !aArg.isEmpty() )
291 OUString oDeprecatedArg;
292 if (!aArg.startsWith(
"--", &oArg) && aArg.startsWith(
"-", &oArg)
293 && aArg.getLength() > 2)
295 oDeprecatedArg = aArg;
299 if ( oArg ==
"minimized" )
303 else if ( oArg ==
"invisible" )
307 else if ( oArg ==
"norestore" )
311 else if ( oArg ==
"nodefault" )
315 else if ( oArg ==
"headless" )
319 else if ( oArg ==
"eventtesting" )
321 m_eventtesting =
true;
323 else if ( oArg ==
"safe-mode" )
327 else if ( oArg ==
"cat" )
330 m_conversionparams =
"txt:Text";
331 eCurrentEvent = CommandLineEvent::Conversion;
334 else if ( oArg ==
"script-cat" )
337 eCurrentEvent = CommandLineEvent::Conversion;
340 else if ( oArg ==
"quickstart" )
342 #if defined(ENABLE_QUICKSTART_APPLET)
345 m_noquickstart =
false;
347 else if ( oArg ==
"quickstart=no" )
349 m_noquickstart =
true;
350 m_quickstart =
false;
352 else if ( oArg ==
"terminate_after_init" )
354 m_terminateafterinit =
true;
356 else if ( oArg ==
"nofirststartwizard" )
360 else if ( oArg ==
"nologo" )
364 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
365 else if ( oArg ==
"nolockcheck" )
367 m_nolockcheck =
true;
370 else if ( oArg ==
"help" || aArg ==
"-h" || aArg ==
"-?" )
374 else if ( oArg ==
"helpwriter" )
378 else if ( oArg ==
"helpcalc" )
382 else if ( oArg ==
"helpdraw" )
386 else if ( oArg ==
"helpimpress" )
388 m_helpimpress =
true;
390 else if ( oArg ==
"helpbase" )
394 else if ( oArg ==
"helpbasic" )
398 else if ( oArg ==
"helpmath" )
402 else if ( oArg ==
"protector" )
411 if ((!supplier.
next(&aArg) || !supplier.
next(&aArg)) && m_unknown.isEmpty())
412 m_unknown =
"--protector must be followed by two arguments";
414 else if ( oArg ==
"version" )
418 else if ( oArg.startsWith(
"splash-pipe=") )
428 else if ( aArg.startsWith(
"-psn") )
430 oDeprecatedArg.clear();
433 #if HAVE_FEATURE_MACOSX_SANDBOX
434 else if ( oArg ==
"nstemporarydirectory" )
436 printf(
"%s\n", [NSTemporaryDirectory() UTF8String]);
444 else if ( oArg ==
"Embedding" )
446 oDeprecatedArg.clear();
449 else if ( oArg.startsWith(
"infilter=", &rest))
451 m_infilter.push_back(rest);
453 else if ( oArg.startsWith(
"accept=", &rest))
455 m_accept.push_back(rest);
457 else if ( oArg.startsWith(
"unaccept=", &rest))
459 m_unaccept.push_back(rest);
461 else if ( oArg.startsWith(
"language=", &rest))
465 else if ( oArg.startsWith(
"pidfile=", &rest))
469 else if ( oArg ==
"writer" )
472 m_bDocumentArgs =
true;
474 else if ( oArg ==
"calc" )
477 m_bDocumentArgs =
true;
479 else if ( oArg ==
"draw" )
482 m_bDocumentArgs =
true;
484 else if ( oArg ==
"impress" )
487 m_bDocumentArgs =
true;
489 else if ( oArg ==
"base" )
492 m_bDocumentArgs =
true;
494 else if ( oArg ==
"global" )
497 m_bDocumentArgs =
true;
499 else if ( oArg ==
"math" )
502 m_bDocumentArgs =
true;
504 else if ( oArg ==
"web" )
507 m_bDocumentArgs =
true;
509 else if ( aArg ==
"-n" )
512 eCurrentEvent = CommandLineEvent::ForceNew;
514 else if ( aArg ==
"-o" )
517 eCurrentEvent = CommandLineEvent::ForceOpen;
519 else if ( oArg ==
"pt" )
522 eCurrentEvent = CommandLineEvent::PrintTo;
524 if (supplier.
next(&aArg))
525 m_printername = aArg;
526 else if (m_unknown.isEmpty())
527 m_unknown =
"--pt must be followed by printername";
529 else if ( aArg ==
"-p" )
532 eCurrentEvent = CommandLineEvent::Print;
534 else if ( oArg ==
"view")
537 eCurrentEvent = CommandLineEvent::View;
539 else if ( oArg ==
"show" )
542 eCurrentEvent = CommandLineEvent::Start;
544 else if ( oArg ==
"display" )
553 else if ( oArg ==
"convert-to" )
555 eCurrentEvent = CommandLineEvent::Conversion;
557 if (supplier.
next(&aArg))
559 m_conversionparams = aArg;
563 else if (m_unknown.isEmpty())
564 m_unknown =
"--convert-to must be followed by output_file_extension[:output_filter_name]";
566 else if ( oArg ==
"print-to-file" )
568 eCurrentEvent = CommandLineEvent::BatchPrint;
570 else if ( oArg ==
"printer-name" )
572 if (eCurrentEvent == CommandLineEvent::BatchPrint)
575 if (supplier.
next(&aArg))
576 m_printername = aArg;
577 else if (m_unknown.isEmpty())
578 m_unknown =
"--printer-name must be followed by printername";
580 else if (m_unknown.isEmpty())
582 m_unknown =
"--printer-name must directly follow --print-to-file";
585 else if ( oArg ==
"outdir" )
587 if (eCurrentEvent == CommandLineEvent::Conversion ||
588 eCurrentEvent == CommandLineEvent::BatchPrint)
590 if (supplier.
next(&aArg))
591 m_conversionout = aArg;
592 else if (m_unknown.isEmpty())
593 m_unknown =
"--outdir must be followed by output directory path";
595 else if (m_unknown.isEmpty())
597 m_unknown =
"--outdir must directly follow either output filter specification of --convert-to, or --print-to-file or its printer specification";
600 else if ( eCurrentEvent == CommandLineEvent::Conversion
601 && oArg ==
"convert-images-to" )
603 if (supplier.
next(&aArg))
604 m_convertimages = aArg;
605 else if (m_unknown.isEmpty())
606 m_unknown =
"--convert-images-to must be followed by an image type";
608 else if ( aArg.startsWith(
"-") )
616 oArg !=
"backtrace" &&
618 oArg !=
"valgrind" &&
621 oArg !=
"session=" &&
624 oArg !=
"nocrashreport" &&
629 oDeprecatedArg.clear();
638 CommandLineEvent eThisEvent = CheckOfficeURI(aArg, eCurrentEvent);
641 eThisEvent = CheckWebQuery(aArg, eThisEvent);
645 case CommandLineEvent::Open:
646 m_openlist.push_back(aArg);
647 m_bDocumentArgs =
true;
649 case CommandLineEvent::View:
650 m_viewlist.push_back(aArg);
651 m_bDocumentArgs =
true;
653 case CommandLineEvent::Start:
654 m_startlist.push_back(aArg);
655 m_bDocumentArgs =
true;
657 case CommandLineEvent::Print:
658 m_printlist.push_back(aArg);
659 m_bDocumentArgs =
true;
661 case CommandLineEvent::PrintTo:
662 m_printtolist.push_back(aArg);
663 m_bDocumentArgs =
true;
665 case CommandLineEvent::ForceNew:
666 m_forcenewlist.push_back(aArg);
667 m_bDocumentArgs =
true;
669 case CommandLineEvent::ForceOpen:
670 m_forceopenlist.push_back(aArg);
671 m_bDocumentArgs =
true;
673 case CommandLineEvent::Conversion:
674 case CommandLineEvent::BatchPrint:
675 m_conversionlist.push_back(aArg);
680 if (!oDeprecatedArg.isEmpty())
683 fprintf(stderr,
"Warning: %s is deprecated. Use -%s instead.\n", sArg.getStr(), sArg.getStr());
689 void CommandLineArgs::InitParamValues()
700 m_eventtesting =
false;
701 m_quickstart =
false;
702 m_noquickstart =
false;
703 m_terminateafterinit =
false;
705 m_nolockcheck =
false;
716 m_helpwriter =
false;
721 m_helpimpress =
false;
724 m_splashpipe =
false;
726 m_bDocumentArgs =
false;
732 bool CommandLineArgs::HasModuleParam()
const
734 return m_writer || m_calc || m_draw || m_impress || m_global || m_math
738 std::vector< OUString > CommandLineArgs::GetOpenList()
const
740 return translateExternalUris(m_openlist);
743 std::vector< OUString > CommandLineArgs::GetViewList()
const
745 return translateExternalUris(m_viewlist);
748 std::vector< OUString > CommandLineArgs::GetStartList()
const
750 return translateExternalUris(m_startlist);
753 std::vector< OUString > CommandLineArgs::GetForceOpenList()
const
755 return translateExternalUris(m_forceopenlist);
758 std::vector< OUString > CommandLineArgs::GetForceNewList()
const
760 return translateExternalUris(m_forcenewlist);
763 std::vector< OUString > CommandLineArgs::GetPrintList()
const
765 return translateExternalUris(m_printlist);
768 std::vector< OUString > CommandLineArgs::GetPrintToList()
const
770 return translateExternalUris(m_printtolist);
773 std::vector< OUString > CommandLineArgs::GetConversionList()
const
775 return translateExternalUris(m_conversionlist);
778 OUString CommandLineArgs::GetConversionOut()
const
780 return translateExternalUris(m_conversionout);
std::optional< OUString > m_cwdUrl
static bool getProcessWorkingDir(OUString &rUrl)
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)
virtual std::optional< OUString > getCwdUrl()=0
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
Reference< XOutputStream > stream
Reference< XComponentContext > getProcessComponentContext()
#define SAL_WARN(area, stream)
virtual bool next(OUString *argument)=0