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(static_cast<unsigned int>(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 &) {}
254 CommandLineArgs::Supplier::Exception::~Exception() {}
257 CommandLineArgs::Supplier::Exception::operator =(
Exception const &)
260 CommandLineArgs::Supplier::~Supplier() {}
263 CommandLineArgs::CommandLineArgs()
266 ExtCommandLineSupplier s;
267 ParseCommandLine_Impl( s );
270 CommandLineArgs::CommandLineArgs(
Supplier& supplier )
273 ParseCommandLine_Impl( supplier );
276 void CommandLineArgs::ParseCommandLine_Impl(
Supplier& supplier )
279 CommandLineEvent eCurrentEvent = CommandLineEvent::Open;
284 if ( !supplier.
next( &aArg ) )
289 if ( !aArg.isEmpty() )
293 OUString oDeprecatedArg;
294 if (!aArg.startsWith(
"--", &oArg) && aArg.startsWith(
"-", &oArg)
295 && aArg.getLength() > 2)
297 oDeprecatedArg = aArg;
301 if ( oArg ==
"minimized" )
305 else if ( oArg ==
"invisible" )
309 else if ( oArg ==
"norestore" )
313 else if ( oArg ==
"nodefault" )
317 else if ( oArg ==
"headless" )
321 else if ( oArg ==
"eventtesting" )
323 m_eventtesting =
true;
325 else if ( oArg ==
"safe-mode" )
329 else if ( oArg ==
"cat" )
332 m_conversionparams =
"txt:Text";
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)
347 m_noquickstart =
false;
349 else if ( oArg ==
"quickstart=no" )
351 m_noquickstart =
true;
352 m_quickstart =
false;
354 else if ( oArg ==
"terminate_after_init" )
356 m_terminateafterinit =
true;
358 else if ( oArg ==
"nofirststartwizard" )
362 else if ( oArg ==
"nologo" )
366 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
367 else if ( oArg ==
"nolockcheck" )
369 m_nolockcheck =
true;
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" )
390 m_helpimpress =
true;
392 else if ( oArg ==
"helpbase" )
396 else if ( oArg ==
"helpbasic" )
400 else if ( oArg ==
"helpmath" )
404 else if ( oArg ==
"protector" )
413 if ((!supplier.
next(&aArg) || !supplier.
next(&aArg)) && m_unknown.isEmpty())
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))
453 m_infilter.push_back(rest);
455 else if ( oArg.startsWith(
"accept=", &rest))
457 m_accept.push_back(rest);
459 else if ( oArg.startsWith(
"unaccept=", &rest))
461 m_unaccept.push_back(rest);
463 else if ( oArg.startsWith(
"language=", &rest))
467 else if ( oArg.startsWith(
"pidfile=", &rest))
471 else if ( oArg ==
"writer" )
474 m_bDocumentArgs =
true;
476 else if ( oArg ==
"calc" )
479 m_bDocumentArgs =
true;
481 else if ( oArg ==
"draw" )
484 m_bDocumentArgs =
true;
486 else if ( oArg ==
"impress" )
489 m_bDocumentArgs =
true;
491 else if ( oArg ==
"base" )
494 m_bDocumentArgs =
true;
496 else if ( oArg ==
"global" )
499 m_bDocumentArgs =
true;
501 else if ( oArg ==
"math" )
504 m_bDocumentArgs =
true;
506 else if ( oArg ==
"web" )
509 m_bDocumentArgs =
true;
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))
527 m_printername = aArg;
528 else if (m_unknown.isEmpty())
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" )
555 else if ( oArg ==
"convert-to" )
557 eCurrentEvent = CommandLineEvent::Conversion;
559 if (supplier.
next(&aArg))
561 m_conversionparams = aArg;
565 else if (m_unknown.isEmpty())
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))
578 m_printername = aArg;
579 else if (m_unknown.isEmpty())
580 m_unknown =
"--printer-name must be followed by printername";
582 else if (m_unknown.isEmpty())
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))
593 m_conversionout = aArg;
594 else if (m_unknown.isEmpty())
595 m_unknown =
"--outdir must be followed by output directory path";
597 else if (m_unknown.isEmpty())
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))
606 m_convertimages = aArg;
607 else if (m_unknown.isEmpty())
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:
648 m_openlist.push_back(aArg);
649 m_bDocumentArgs =
true;
651 case CommandLineEvent::View:
652 m_viewlist.push_back(aArg);
653 m_bDocumentArgs =
true;
655 case CommandLineEvent::Start:
656 m_startlist.push_back(aArg);
657 m_bDocumentArgs =
true;
659 case CommandLineEvent::Print:
660 m_printlist.push_back(aArg);
661 m_bDocumentArgs =
true;
663 case CommandLineEvent::PrintTo:
664 m_printtolist.push_back(aArg);
665 m_bDocumentArgs =
true;
667 case CommandLineEvent::ForceNew:
668 m_forcenewlist.push_back(aArg);
669 m_bDocumentArgs =
true;
671 case CommandLineEvent::ForceOpen:
672 m_forceopenlist.push_back(aArg);
673 m_bDocumentArgs =
true;
675 case CommandLineEvent::Conversion:
676 case CommandLineEvent::BatchPrint:
677 m_conversionlist.push_back(aArg);
682 if (!oDeprecatedArg.isEmpty())
685 fprintf(stderr,
"Warning: %s is deprecated. Use -%s instead.\n", sArg.getStr(), sArg.getStr());
691 void CommandLineArgs::InitParamValues()
702 m_eventtesting =
false;
703 m_quickstart =
false;
704 m_noquickstart =
false;
705 m_terminateafterinit =
false;
707 m_nolockcheck =
false;
718 m_helpwriter =
false;
723 m_helpimpress =
false;
726 m_splashpipe =
false;
728 m_bDocumentArgs =
false;
734 bool CommandLineArgs::HasModuleParam()
const
736 return m_writer || m_calc || m_draw || m_impress || m_global || m_math
740 std::vector< OUString > CommandLineArgs::GetOpenList()
const
742 return translateExternalUris(m_openlist);
745 std::vector< OUString > CommandLineArgs::GetViewList()
const
747 return translateExternalUris(m_viewlist);
750 std::vector< OUString > CommandLineArgs::GetStartList()
const
752 return translateExternalUris(m_startlist);
755 std::vector< OUString > CommandLineArgs::GetForceOpenList()
const
757 return translateExternalUris(m_forceopenlist);
760 std::vector< OUString > CommandLineArgs::GetForceNewList()
const
762 return translateExternalUris(m_forcenewlist);
765 std::vector< OUString > CommandLineArgs::GetPrintList()
const
767 return translateExternalUris(m_printlist);
770 std::vector< OUString > CommandLineArgs::GetPrintToList()
const
772 return translateExternalUris(m_printtolist);
775 std::vector< OUString > CommandLineArgs::GetConversionList()
const
777 return translateExternalUris(m_conversionlist);
780 OUString CommandLineArgs::GetConversionOut()
const
782 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