Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <config_features.h>
21 :
22 : #if HAVE_FEATURE_MACOSX_SANDBOX
23 : #include <premac.h>
24 : #include <Foundation/Foundation.h>
25 : #include <postmac.h>
26 : #endif
27 :
28 : #include "cmdlineargs.hxx"
29 : #include <vcl/svapp.hxx>
30 : #include <rtl/uri.hxx>
31 : #include <rtl/ustring.hxx>
32 : #include <rtl/process.h>
33 : #include <comphelper/processfactory.hxx>
34 : #include <com/sun/star/uri/ExternalUriReferenceTranslator.hpp>
35 : #include <tools/getprocessworkingdir.hxx>
36 :
37 : #include <svl/documentlockfile.hxx>
38 :
39 : #include <cstdio>
40 :
41 : using namespace com::sun::star::lang;
42 : using namespace com::sun::star::uri;
43 : using namespace com::sun::star::uno;
44 :
45 : namespace desktop
46 : {
47 :
48 : namespace {
49 :
50 65 : OUString translateExternalUris(OUString const & input) {
51 : OUString t(
52 : com::sun::star::uri::ExternalUriReferenceTranslator::create(
53 195 : comphelper::getProcessComponentContext())->
54 130 : translateToInternal(input));
55 65 : return t.isEmpty() ? input : t;
56 : }
57 :
58 512 : std::vector< OUString > translateExternalUris(
59 : std::vector< OUString > const & input)
60 : {
61 512 : std::vector< OUString > t;
62 1539 : for (std::vector< OUString >::const_iterator i(input.begin());
63 1026 : i != input.end(); ++i)
64 : {
65 1 : t.push_back(translateExternalUris(*i));
66 : }
67 512 : return t;
68 : }
69 :
70 : class ExtCommandLineSupplier: public CommandLineArgs::Supplier {
71 : public:
72 116 : explicit ExtCommandLineSupplier():
73 116 : m_count(rtl_getAppCommandArgCount()),
74 232 : m_index(0)
75 : {
76 116 : OUString url;
77 116 : if (tools::getProcessWorkingDir(url)) {
78 116 : m_cwdUrl.reset(url);
79 116 : }
80 116 : }
81 :
82 116 : virtual ~ExtCommandLineSupplier() {}
83 :
84 116 : virtual boost::optional< OUString > getCwdUrl() SAL_OVERRIDE { return m_cwdUrl; }
85 :
86 693 : virtual bool next(OUString * argument) SAL_OVERRIDE {
87 : OSL_ASSERT(argument != NULL);
88 693 : if (m_index < m_count) {
89 577 : rtl_getAppCommandArg(m_index++, &argument->pData);
90 577 : return true;
91 : } else {
92 116 : return false;
93 : }
94 : }
95 :
96 : private:
97 : boost::optional< OUString > m_cwdUrl;
98 : sal_uInt32 m_count;
99 : sal_uInt32 m_index;
100 : };
101 :
102 : }
103 :
104 0 : CommandLineArgs::Supplier::Exception::Exception() {}
105 :
106 0 : CommandLineArgs::Supplier::Exception::Exception(Exception const &) {}
107 :
108 0 : CommandLineArgs::Supplier::Exception::~Exception() {}
109 :
110 : CommandLineArgs::Supplier::Exception &
111 0 : CommandLineArgs::Supplier::Exception::operator =(Exception const &)
112 0 : { return *this; }
113 :
114 116 : CommandLineArgs::Supplier::~Supplier() {}
115 :
116 : // intialize class with command line parameters from process environment
117 116 : CommandLineArgs::CommandLineArgs()
118 : {
119 116 : InitParamValues();
120 116 : ExtCommandLineSupplier s;
121 116 : ParseCommandLine_Impl( s );
122 116 : }
123 :
124 0 : CommandLineArgs::CommandLineArgs( Supplier& supplier )
125 : {
126 0 : InitParamValues();
127 0 : ParseCommandLine_Impl( supplier );
128 0 : }
129 :
130 116 : void CommandLineArgs::ParseCommandLine_Impl( Supplier& supplier )
131 : {
132 116 : m_cwdUrl = supplier.getCwdUrl();
133 :
134 : // parse command line arguments
135 116 : bool bOpenEvent(true);
136 116 : bool bPrintEvent(false);
137 116 : bool bViewEvent(false);
138 116 : bool bStartEvent(false);
139 116 : bool bPrintToEvent(false);
140 116 : bool bPrinterName(false);
141 116 : bool bForceOpenEvent(false);
142 116 : bool bForceNewEvent(false);
143 116 : bool bDisplaySpec(false);
144 116 : bool bOpenDoc(false);
145 116 : bool bConversionEvent(false);
146 116 : bool bConversionParamsEvent(false);
147 116 : bool bBatchPrintEvent(false);
148 116 : bool bBatchPrinterNameEvent(false);
149 116 : bool bConversionOutEvent(false);
150 :
151 : for (;;)
152 : {
153 693 : OUString aArg;
154 693 : if ( !supplier.next( &aArg ) )
155 : {
156 116 : break;
157 : }
158 :
159 577 : if ( !aArg.isEmpty() )
160 : {
161 577 : m_bEmpty = false;
162 577 : OUString oArg;
163 577 : bool bDeprecated = !aArg.startsWith("--", &oArg)
164 577 : && aArg.startsWith("-", &oArg) && aArg.getLength() > 2;
165 : // -h, -?, -n, -o, -p are still valid
166 :
167 1154 : OUString rest;
168 577 : if ( oArg == "minimized" )
169 : {
170 0 : m_minimized = true;
171 : }
172 577 : else if ( oArg == "invisible" )
173 : {
174 0 : m_invisible = true;
175 : }
176 577 : else if ( oArg == "norestore" )
177 : {
178 115 : m_norestore = true;
179 : }
180 462 : else if ( oArg == "nodefault" )
181 : {
182 0 : m_nodefault = true;
183 : }
184 462 : else if ( oArg == "headless" )
185 : {
186 116 : setHeadless();
187 : }
188 346 : else if ( oArg == "cat" )
189 : {
190 0 : m_textcat = true;
191 0 : m_conversionparams = "txt:Text";
192 0 : bOpenEvent = false;
193 0 : bConversionEvent = true;
194 : }
195 346 : else if ( oArg == "quickstart" )
196 : {
197 : #if defined(ENABLE_QUICKSTART_APPLET)
198 0 : m_quickstart = true;
199 : #endif
200 0 : m_noquickstart = false;
201 : }
202 346 : else if ( oArg == "quickstart=no" )
203 : {
204 115 : m_noquickstart = true;
205 115 : m_quickstart = false;
206 : }
207 231 : else if ( oArg == "terminate_after_init" )
208 : {
209 0 : m_terminateafterinit = true;
210 : }
211 231 : else if ( oArg == "nofirststartwizard" )
212 : {
213 : // Do nothing, accept only for backward compatibility
214 : }
215 231 : else if ( oArg == "nologo" )
216 : {
217 115 : m_nologo = true;
218 : }
219 : #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
220 116 : else if ( oArg == "nolockcheck" )
221 : {
222 0 : m_nolockcheck = true;
223 : }
224 : #endif
225 116 : else if ( oArg == "help" || aArg == "-h" || aArg == "-?" )
226 : {
227 0 : m_help = true;
228 : }
229 116 : else if ( oArg == "helpwriter" )
230 : {
231 0 : m_helpwriter = true;
232 : }
233 116 : else if ( oArg == "helpcalc" )
234 : {
235 0 : m_helpcalc = true;
236 : }
237 116 : else if ( oArg == "helpdraw" )
238 : {
239 0 : m_helpdraw = true;
240 : }
241 116 : else if ( oArg == "helpimpress" )
242 : {
243 0 : m_helpimpress = true;
244 : }
245 116 : else if ( oArg == "helpbase" )
246 : {
247 0 : m_helpbase = true;
248 : }
249 116 : else if ( oArg == "helpbasic" )
250 : {
251 0 : m_helpbasic = true;
252 : }
253 116 : else if ( oArg == "helpmath" )
254 : {
255 0 : m_helpmath = true;
256 : }
257 116 : else if ( oArg == "protector" )
258 : {
259 : // Not relevant for us here, but can be used in unit tests.
260 : // Usually unit tests would not end up here, but e.g. the
261 : // LOK Tiled Rendering tests end up running a full soffice
262 : // process, and we can't bail on the use of --protector.
263 :
264 : // We specifically need to consume the following 2 arguments
265 : // for --protector
266 : assert( supplier.next( &aArg ) );
267 : assert( supplier.next( &aArg ) );
268 : }
269 116 : else if ( oArg == "version" )
270 : {
271 0 : m_version = true;
272 : }
273 116 : else if ( oArg.startsWith("splash-pipe=") )
274 : {
275 0 : m_splashpipe = true;
276 : }
277 : #ifdef MACOSX
278 : /* #i84053# ignore -psn on Mac
279 : Platform dependent #ifdef here is ugly, however this is currently
280 : the only platform dependent parameter. Should more appear
281 : we should find a better solution
282 : */
283 : else if ( aArg.startsWith("-psn") )
284 : {
285 : bDeprecated = false;
286 : }
287 : #endif
288 : #if HAVE_FEATURE_MACOSX_SANDBOX
289 : else if ( oArg == "nstemporarydirectory" )
290 : {
291 : printf("%s\n", [NSTemporaryDirectory() UTF8String]);
292 : exit(0);
293 : }
294 : #endif
295 : #ifdef WIN32
296 : /* fdo#57203 ignore -Embedding on Windows
297 : when LibreOffice is launched by COM+
298 : */
299 : else if ( oArg == "Embedding" )
300 : {
301 : bDeprecated = false;
302 : }
303 : #endif
304 116 : else if ( oArg.startsWith("infilter=", &rest))
305 : {
306 0 : m_infilter.push_back(rest);
307 : }
308 116 : else if ( oArg.startsWith("accept=", &rest))
309 : {
310 115 : m_accept.push_back(rest);
311 : }
312 1 : else if ( oArg.startsWith("unaccept=", &rest))
313 : {
314 0 : m_unaccept.push_back(rest);
315 : }
316 1 : else if ( oArg.startsWith("language=", &rest))
317 : {
318 0 : m_language = rest;
319 : }
320 1 : else if ( oArg.startsWith("pidfile=", &rest))
321 : {
322 0 : m_pidfile = rest;
323 : }
324 1 : else if ( oArg == "writer" )
325 : {
326 0 : m_writer = true;
327 0 : m_bDocumentArgs = true;
328 : }
329 1 : else if ( oArg == "calc" )
330 : {
331 0 : m_calc = true;
332 0 : m_bDocumentArgs = true;
333 : }
334 1 : else if ( oArg == "draw" )
335 : {
336 0 : m_draw = true;
337 0 : m_bDocumentArgs = true;
338 : }
339 1 : else if ( oArg == "impress" )
340 : {
341 0 : m_impress = true;
342 0 : m_bDocumentArgs = true;
343 : }
344 1 : else if ( oArg == "base" )
345 : {
346 0 : m_base = true;
347 0 : m_bDocumentArgs = true;
348 : }
349 1 : else if ( oArg == "global" )
350 : {
351 0 : m_global = true;
352 0 : m_bDocumentArgs = true;
353 : }
354 1 : else if ( oArg == "math" )
355 : {
356 0 : m_math = true;
357 0 : m_bDocumentArgs = true;
358 : }
359 1 : else if ( oArg == "web" )
360 : {
361 0 : m_web = true;
362 0 : m_bDocumentArgs = true;
363 : }
364 1 : else if ( aArg == "-n" )
365 : {
366 : // force new documents based on the following documents
367 0 : bForceNewEvent = true;
368 0 : bOpenEvent = false;
369 0 : bForceOpenEvent = false;
370 0 : bPrintToEvent = false;
371 0 : bPrintEvent = false;
372 0 : bViewEvent = false;
373 0 : bStartEvent = false;
374 0 : bDisplaySpec = false;
375 : }
376 1 : else if ( aArg == "-o" )
377 : {
378 : // force open documents regardless if they are templates or not
379 0 : bForceOpenEvent = true;
380 0 : bOpenEvent = false;
381 0 : bForceNewEvent = false;
382 0 : bPrintToEvent = false;
383 0 : bPrintEvent = false;
384 0 : bViewEvent = false;
385 0 : bStartEvent = false;
386 0 : bDisplaySpec = false;
387 : }
388 1 : else if ( oArg == "pt" )
389 : {
390 : // Print to special printer
391 0 : bPrintToEvent = true;
392 0 : bPrinterName = true;
393 0 : bPrintEvent = false;
394 0 : bOpenEvent = false;
395 0 : bForceNewEvent = false;
396 0 : bViewEvent = false;
397 0 : bStartEvent = false;
398 0 : bDisplaySpec = false;
399 0 : bForceOpenEvent = false;
400 : }
401 1 : else if ( aArg == "-p" )
402 : {
403 : // Print to default printer
404 0 : bPrintEvent = true;
405 0 : bPrintToEvent = false;
406 0 : bOpenEvent = false;
407 0 : bForceNewEvent = false;
408 0 : bForceOpenEvent = false;
409 0 : bViewEvent = false;
410 0 : bStartEvent = false;
411 0 : bDisplaySpec = false;
412 : }
413 1 : else if ( oArg == "view")
414 : {
415 : // open in viewmode
416 0 : bOpenEvent = false;
417 0 : bPrintEvent = false;
418 0 : bPrintToEvent = false;
419 0 : bForceNewEvent = false;
420 0 : bForceOpenEvent = false;
421 0 : bViewEvent = true;
422 0 : bStartEvent = false;
423 0 : bDisplaySpec = false;
424 : }
425 1 : else if ( oArg == "show" )
426 : {
427 : // open in viewmode
428 0 : bOpenEvent = false;
429 0 : bViewEvent = false;
430 0 : bStartEvent = true;
431 0 : bPrintEvent = false;
432 0 : bPrintToEvent = false;
433 0 : bForceNewEvent = false;
434 0 : bForceOpenEvent = false;
435 0 : bDisplaySpec = false;
436 : }
437 1 : else if ( oArg == "display" )
438 : {
439 : // set display
440 0 : bOpenEvent = false;
441 0 : bPrintEvent = false;
442 0 : bForceOpenEvent = false;
443 0 : bPrintToEvent = false;
444 0 : bForceNewEvent = false;
445 0 : bViewEvent = false;
446 0 : bStartEvent = false;
447 0 : bDisplaySpec = true;
448 : }
449 1 : else if ( oArg == "language" )
450 : {
451 0 : bOpenEvent = false;
452 0 : bPrintEvent = false;
453 0 : bForceOpenEvent = false;
454 0 : bPrintToEvent = false;
455 0 : bForceNewEvent = false;
456 0 : bViewEvent = false;
457 0 : bStartEvent = false;
458 0 : bDisplaySpec = false;
459 : }
460 1 : else if ( oArg == "convert-to" )
461 : {
462 0 : bOpenEvent = false;
463 0 : bConversionEvent = true;
464 0 : bConversionParamsEvent = true;
465 : // It doesn't make sense to use convert-to without headless.
466 0 : setHeadless();
467 : }
468 1 : else if ( oArg == "print-to-file" )
469 : {
470 0 : bOpenEvent = false;
471 0 : bBatchPrintEvent = true;
472 : }
473 1 : else if ( oArg == "printer-name" && bBatchPrintEvent )
474 : {
475 0 : bBatchPrinterNameEvent = true;
476 : }
477 1 : else if ( oArg == "outdir" &&
478 0 : (bConversionEvent || bBatchPrintEvent) )
479 : {
480 0 : bConversionOutEvent = true;
481 : }
482 1 : else if ( aArg.startsWith("-") )
483 : {
484 : // because it's impossible to filter these options that
485 : // are handled in the soffice shell script with the
486 : // primitive tools that /bin/sh offers, ignore them here
487 0 : if (
488 : #if defined UNX
489 0 : oArg != "record" &&
490 0 : oArg != "backtrace" &&
491 0 : oArg != "strace" &&
492 0 : oArg != "valgrind" &&
493 : // for X Session Management, handled in
494 : // vcl/unx/generic/app/sm.cxx:
495 0 : oArg != "session=" &&
496 : #endif
497 : //ignore additional legacy options that don't do anything anymore
498 0 : oArg != "nocrashreport" &&
499 0 : m_unknown.isEmpty())
500 : {
501 0 : m_unknown = aArg;
502 : }
503 0 : bDeprecated = false;
504 : }
505 : else
506 : {
507 1 : if ( bPrinterName && bPrintToEvent )
508 : {
509 : // first argument after "-pt" this must be the printer name
510 0 : m_printername = aArg;
511 0 : bPrinterName = false;
512 : }
513 1 : else if ( bConversionParamsEvent && bConversionEvent )
514 : {
515 : // first argument must be the params
516 0 : m_conversionparams = aArg;
517 0 : bConversionParamsEvent = false;
518 : }
519 1 : else if ( bBatchPrinterNameEvent && bBatchPrintEvent )
520 : {
521 : // first argument is the printer name
522 0 : m_printername = aArg;
523 0 : bBatchPrinterNameEvent = false;
524 : }
525 1 : else if ( (bConversionEvent || bBatchPrintEvent) && bConversionOutEvent )
526 : {
527 0 : m_conversionout = aArg;
528 0 : bConversionOutEvent = false;
529 : }
530 : else
531 : {
532 : // handle this argument as a filename
533 1 : if ( bOpenEvent )
534 : {
535 1 : m_openlist.push_back(aArg);
536 1 : bOpenDoc = true;
537 : }
538 0 : else if ( bViewEvent )
539 : {
540 0 : m_viewlist.push_back(aArg);
541 0 : bOpenDoc = true;
542 : }
543 0 : else if ( bStartEvent )
544 : {
545 0 : m_startlist.push_back(aArg);
546 0 : bOpenDoc = true;
547 : }
548 0 : else if ( bPrintEvent )
549 : {
550 0 : m_printlist.push_back(aArg);
551 0 : bOpenDoc = true;
552 : }
553 0 : else if ( bPrintToEvent )
554 : {
555 0 : m_printtolist.push_back(aArg);
556 0 : bOpenDoc = true;
557 : }
558 0 : else if ( bForceNewEvent )
559 : {
560 0 : m_forcenewlist.push_back(aArg);
561 0 : bOpenDoc = true;
562 : }
563 0 : else if ( bForceOpenEvent )
564 : {
565 0 : m_forceopenlist.push_back(aArg);
566 0 : bOpenDoc = true;
567 : }
568 0 : else if ( bDisplaySpec )
569 : {
570 0 : bDisplaySpec = false; // only one display, not a lsit
571 0 : bOpenEvent = true; // set back to standard
572 : }
573 0 : else if ( bConversionEvent || bBatchPrintEvent )
574 0 : m_conversionlist.push_back(aArg);
575 : }
576 : }
577 :
578 577 : if (bDeprecated)
579 : {
580 0 : OString sArg(OUStringToOString(aArg, osl_getThreadTextEncoding()));
581 0 : fprintf(stderr, "Warning: %s is deprecated. Use -%s instead.\n", sArg.getStr(), sArg.getStr());
582 577 : }
583 : }
584 577 : }
585 :
586 116 : if ( bOpenDoc )
587 1 : m_bDocumentArgs = true;
588 116 : }
589 :
590 116 : void CommandLineArgs::InitParamValues()
591 : {
592 116 : m_minimized = false;
593 116 : m_norestore = false;
594 : #ifdef LIBO_HEADLESS
595 : m_invisible = true;
596 : m_headless = true;
597 : #else
598 116 : m_invisible = false;
599 116 : m_headless = false;
600 : #endif
601 116 : m_quickstart = false;
602 116 : m_noquickstart = false;
603 116 : m_terminateafterinit = false;
604 116 : m_nologo = false;
605 116 : m_nolockcheck = false;
606 116 : m_nodefault = false;
607 116 : m_help = false;
608 116 : m_writer = false;
609 116 : m_calc = false;
610 116 : m_draw = false;
611 116 : m_impress = false;
612 116 : m_global = false;
613 116 : m_math = false;
614 116 : m_web = false;
615 116 : m_base = false;
616 116 : m_helpwriter = false;
617 116 : m_helpcalc = false;
618 116 : m_helpdraw = false;
619 116 : m_helpbasic = false;
620 116 : m_helpmath = false;
621 116 : m_helpimpress = false;
622 116 : m_helpbase = false;
623 116 : m_version = false;
624 116 : m_splashpipe = false;
625 116 : m_bEmpty = true;
626 116 : m_bDocumentArgs = false;
627 116 : m_textcat = false;
628 116 : }
629 :
630 1 : bool CommandLineArgs::HasModuleParam() const
631 : {
632 1 : return m_writer || m_calc || m_draw || m_impress || m_global || m_math
633 2 : || m_web || m_base;
634 : }
635 :
636 64 : std::vector< OUString > CommandLineArgs::GetOpenList() const
637 : {
638 64 : return translateExternalUris(m_openlist);
639 : }
640 :
641 64 : std::vector< OUString > CommandLineArgs::GetViewList() const
642 : {
643 64 : return translateExternalUris(m_viewlist);
644 : }
645 :
646 64 : std::vector< OUString > CommandLineArgs::GetStartList() const
647 : {
648 64 : return translateExternalUris(m_startlist);
649 : }
650 :
651 64 : std::vector< OUString > CommandLineArgs::GetForceOpenList() const
652 : {
653 64 : return translateExternalUris(m_forceopenlist);
654 : }
655 :
656 64 : std::vector< OUString > CommandLineArgs::GetForceNewList() const
657 : {
658 64 : return translateExternalUris(m_forcenewlist);
659 : }
660 :
661 64 : std::vector< OUString > CommandLineArgs::GetPrintList() const
662 : {
663 64 : return translateExternalUris(m_printlist);
664 : }
665 :
666 64 : std::vector< OUString > CommandLineArgs::GetPrintToList() const
667 : {
668 64 : return translateExternalUris(m_printtolist);
669 : }
670 :
671 64 : std::vector< OUString > CommandLineArgs::GetConversionList() const
672 : {
673 64 : return translateExternalUris(m_conversionlist);
674 : }
675 :
676 64 : OUString CommandLineArgs::GetConversionOut() const
677 : {
678 64 : return translateExternalUris(m_conversionout);
679 : }
680 :
681 : } // namespace desktop
682 :
683 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|