@zeppos/zeus-cli 1.6.0 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1069 @@
1
+ #!/bin/sh
2
+ #---------------------------------------------
3
+ # xdg-open
4
+ #
5
+ # Utility script to open a URL in the registered default application.
6
+ #
7
+ # Refer to the usage() function below for usage.
8
+ #
9
+ # Copyright 2009-2010, Fathi Boudra <fabo@freedesktop.org>
10
+ # Copyright 2009-2010, Rex Dieter <rdieter@fedoraproject.org>
11
+ # Copyright 2006, Kevin Krammer <kevin.krammer@gmx.at>
12
+ # Copyright 2006, Jeremy White <jwhite@codeweavers.com>
13
+ #
14
+ # LICENSE:
15
+ #
16
+ # Permission is hereby granted, free of charge, to any person obtaining a
17
+ # copy of this software and associated documentation files (the "Software"),
18
+ # to deal in the Software without restriction, including without limitation
19
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
20
+ # and/or sell copies of the Software, and to permit persons to whom the
21
+ # Software is furnished to do so, subject to the following conditions:
22
+ #
23
+ # The above copyright notice and this permission notice shall be included
24
+ # in all copies or substantial portions of the Software.
25
+ #
26
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
27
+ # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
29
+ # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
30
+ # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
31
+ # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
32
+ # OTHER DEALINGS IN THE SOFTWARE.
33
+ #
34
+ #---------------------------------------------
35
+
36
+ manualpage()
37
+ {
38
+ cat << _MANUALPAGE
39
+ Name
40
+
41
+ xdg-open -- opens a file or URL in the user's preferred
42
+ application
43
+
44
+ Synopsis
45
+
46
+ xdg-open { file | URL }
47
+
48
+ xdg-open { --help | --manual | --version }
49
+
50
+ Description
51
+
52
+ xdg-open opens a file or URL in the user's preferred
53
+ application. If a URL is provided the URL will be opened in the
54
+ user's preferred web browser. If a file is provided the file
55
+ will be opened in the preferred application for files of that
56
+ type. xdg-open supports file, ftp, http and https URLs.
57
+
58
+ xdg-open is for use inside a desktop session only. It is not
59
+ recommended to use xdg-open as root.
60
+
61
+ Options
62
+
63
+ --help
64
+ Show command synopsis.
65
+
66
+ --manual
67
+ Show this manual page.
68
+
69
+ --version
70
+ Show the xdg-utils version information.
71
+
72
+ Exit Codes
73
+
74
+ An exit code of 0 indicates success while a non-zero exit code
75
+ indicates failure. The following failure codes can be returned:
76
+
77
+ 1
78
+ Error in command line syntax.
79
+
80
+ 2
81
+ One of the files passed on the command line did not
82
+ exist.
83
+
84
+ 3
85
+ A required tool could not be found.
86
+
87
+ 4
88
+ The action failed.
89
+
90
+ See Also
91
+
92
+ xdg-mime(1), xdg-settings(1), MIME applications associations
93
+ specification
94
+
95
+ Examples
96
+
97
+ xdg-open 'http://www.freedesktop.org/'
98
+
99
+ Opens the freedesktop.org website in the user's default
100
+ browser.
101
+
102
+ xdg-open /tmp/foobar.png
103
+
104
+ Opens the PNG image file /tmp/foobar.png in the user's default
105
+ image viewing application.
106
+ _MANUALPAGE
107
+ }
108
+
109
+ usage()
110
+ {
111
+ cat << _USAGE
112
+ xdg-open -- opens a file or URL in the user's preferred
113
+ application
114
+
115
+ Synopsis
116
+
117
+ xdg-open { file | URL }
118
+
119
+ xdg-open { --help | --manual | --version }
120
+
121
+ _USAGE
122
+ }
123
+
124
+ #@xdg-utils-common@
125
+
126
+ #----------------------------------------------------------------------------
127
+ # Common utility functions included in all XDG wrapper scripts
128
+ #----------------------------------------------------------------------------
129
+
130
+ DEBUG()
131
+ {
132
+ [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && return 0;
133
+ [ ${XDG_UTILS_DEBUG_LEVEL} -lt $1 ] && return 0;
134
+ shift
135
+ echo "$@" >&2
136
+ }
137
+
138
+ # This handles backslashes but not quote marks.
139
+ first_word()
140
+ {
141
+ read first rest
142
+ echo "$first"
143
+ }
144
+
145
+ #-------------------------------------------------------------
146
+ # map a binary to a .desktop file
147
+ binary_to_desktop_file()
148
+ {
149
+ search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
150
+ binary="`which "$1"`"
151
+ binary="`readlink -f "$binary"`"
152
+ base="`basename "$binary"`"
153
+ IFS=:
154
+ for dir in $search; do
155
+ unset IFS
156
+ [ "$dir" ] || continue
157
+ [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue
158
+ for file in "$dir"/applications/*.desktop "$dir"/applications/*/*.desktop "$dir"/applnk/*.desktop "$dir"/applnk/*/*.desktop; do
159
+ [ -r "$file" ] || continue
160
+ # Check to make sure it's worth the processing.
161
+ grep -q "^Exec.*$base" "$file" || continue
162
+ # Make sure it's a visible desktop file (e.g. not "preferred-web-browser.desktop").
163
+ grep -Eq "^(NoDisplay|Hidden)=true" "$file" && continue
164
+ command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`"
165
+ command="`which "$command"`"
166
+ if [ x"`readlink -f "$command"`" = x"$binary" ]; then
167
+ # Fix any double slashes that got added path composition
168
+ echo "$file" | sed -e 's,//*,/,g'
169
+ return
170
+ fi
171
+ done
172
+ done
173
+ }
174
+
175
+ #-------------------------------------------------------------
176
+ # map a .desktop file to a binary
177
+ desktop_file_to_binary()
178
+ {
179
+ search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
180
+ desktop="`basename "$1"`"
181
+ IFS=:
182
+ for dir in $search; do
183
+ unset IFS
184
+ [ "$dir" ] && [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue
185
+ # Check if desktop file contains -
186
+ if [ "${desktop#*-}" != "$desktop" ]; then
187
+ vendor=${desktop%-*}
188
+ app=${desktop#*-}
189
+ if [ -r $dir/applications/$vendor/$app ]; then
190
+ file_path=$dir/applications/$vendor/$app
191
+ elif [ -r $dir/applnk/$vendor/$app ]; then
192
+ file_path=$dir/applnk/$vendor/$app
193
+ fi
194
+ fi
195
+ if test -z "$file_path" ; then
196
+ for indir in "$dir"/applications/ "$dir"/applications/*/ "$dir"/applnk/ "$dir"/applnk/*/; do
197
+ file="$indir/$desktop"
198
+ if [ -r "$file" ]; then
199
+ file_path=$file
200
+ break
201
+ fi
202
+ done
203
+ fi
204
+ if [ -r "$file_path" ]; then
205
+ # Remove any arguments (%F, %f, %U, %u, etc.).
206
+ command="`grep -E "^Exec(\[[^]=]*])?=" "$file_path" | cut -d= -f 2- | first_word`"
207
+ command="`which "$command"`"
208
+ readlink -f "$command"
209
+ return
210
+ fi
211
+ done
212
+ }
213
+
214
+ #-------------------------------------------------------------
215
+ # Exit script on successfully completing the desired operation
216
+
217
+ exit_success()
218
+ {
219
+ if [ $# -gt 0 ]; then
220
+ echo "$@"
221
+ echo
222
+ fi
223
+
224
+ exit 0
225
+ }
226
+
227
+
228
+ #-----------------------------------------
229
+ # Exit script on malformed arguments, not enough arguments
230
+ # or missing required option.
231
+ # prints usage information
232
+
233
+ exit_failure_syntax()
234
+ {
235
+ if [ $# -gt 0 ]; then
236
+ echo "xdg-open: $@" >&2
237
+ echo "Try 'xdg-open --help' for more information." >&2
238
+ else
239
+ usage
240
+ echo "Use 'man xdg-open' or 'xdg-open --manual' for additional info."
241
+ fi
242
+
243
+ exit 1
244
+ }
245
+
246
+ #-------------------------------------------------------------
247
+ # Exit script on missing file specified on command line
248
+
249
+ exit_failure_file_missing()
250
+ {
251
+ if [ $# -gt 0 ]; then
252
+ echo "xdg-open: $@" >&2
253
+ fi
254
+
255
+ exit 2
256
+ }
257
+
258
+ #-------------------------------------------------------------
259
+ # Exit script on failure to locate necessary tool applications
260
+
261
+ exit_failure_operation_impossible()
262
+ {
263
+ if [ $# -gt 0 ]; then
264
+ echo "xdg-open: $@" >&2
265
+ fi
266
+
267
+ exit 3
268
+ }
269
+
270
+ #-------------------------------------------------------------
271
+ # Exit script on failure returned by a tool application
272
+
273
+ exit_failure_operation_failed()
274
+ {
275
+ if [ $# -gt 0 ]; then
276
+ echo "xdg-open: $@" >&2
277
+ fi
278
+
279
+ exit 4
280
+ }
281
+
282
+ #------------------------------------------------------------
283
+ # Exit script on insufficient permission to read a specified file
284
+
285
+ exit_failure_file_permission_read()
286
+ {
287
+ if [ $# -gt 0 ]; then
288
+ echo "xdg-open: $@" >&2
289
+ fi
290
+
291
+ exit 5
292
+ }
293
+
294
+ #------------------------------------------------------------
295
+ # Exit script on insufficient permission to write a specified file
296
+
297
+ exit_failure_file_permission_write()
298
+ {
299
+ if [ $# -gt 0 ]; then
300
+ echo "xdg-open: $@" >&2
301
+ fi
302
+
303
+ exit 6
304
+ }
305
+
306
+ check_input_file()
307
+ {
308
+ if [ ! -e "$1" ]; then
309
+ exit_failure_file_missing "file '$1' does not exist"
310
+ fi
311
+ if [ ! -r "$1" ]; then
312
+ exit_failure_file_permission_read "no permission to read file '$1'"
313
+ fi
314
+ }
315
+
316
+ check_vendor_prefix()
317
+ {
318
+ file_label="$2"
319
+ [ -n "$file_label" ] || file_label="filename"
320
+ file=`basename "$1"`
321
+ case "$file" in
322
+ [[:alpha:]]*-*)
323
+ return
324
+ ;;
325
+ esac
326
+
327
+ echo "xdg-open: $file_label '$file' does not have a proper vendor prefix" >&2
328
+ echo 'A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated' >&2
329
+ echo 'with a dash ("-"). An example '"$file_label"' is '"'example-$file'" >&2
330
+ echo "Use --novendor to override or 'xdg-open --manual' for additional info." >&2
331
+ exit 1
332
+ }
333
+
334
+ check_output_file()
335
+ {
336
+ # if the file exists, check if it is writeable
337
+ # if it does not exists, check if we are allowed to write on the directory
338
+ if [ -e "$1" ]; then
339
+ if [ ! -w "$1" ]; then
340
+ exit_failure_file_permission_write "no permission to write to file '$1'"
341
+ fi
342
+ else
343
+ DIR=`dirname "$1"`
344
+ if [ ! -w "$DIR" ] || [ ! -x "$DIR" ]; then
345
+ exit_failure_file_permission_write "no permission to create file '$1'"
346
+ fi
347
+ fi
348
+ }
349
+
350
+ #----------------------------------------
351
+ # Checks for shared commands, e.g. --help
352
+
353
+ check_common_commands()
354
+ {
355
+ while [ $# -gt 0 ] ; do
356
+ parm="$1"
357
+ shift
358
+
359
+ case "$parm" in
360
+ --help)
361
+ usage
362
+ echo "Use 'man xdg-open' or 'xdg-open --manual' for additional info."
363
+ exit_success
364
+ ;;
365
+
366
+ --manual)
367
+ manualpage
368
+ exit_success
369
+ ;;
370
+
371
+ --version)
372
+ echo "xdg-open 1.1.3"
373
+ exit_success
374
+ ;;
375
+ esac
376
+ done
377
+ }
378
+
379
+ check_common_commands "$@"
380
+
381
+ [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && unset XDG_UTILS_DEBUG_LEVEL;
382
+ if [ ${XDG_UTILS_DEBUG_LEVEL-0} -lt 1 ]; then
383
+ # Be silent
384
+ xdg_redirect_output=" > /dev/null 2> /dev/null"
385
+ else
386
+ # All output to stderr
387
+ xdg_redirect_output=" >&2"
388
+ fi
389
+
390
+ #--------------------------------------
391
+ # Checks for known desktop environments
392
+ # set variable DE to the desktop environments name, lowercase
393
+
394
+ detectDE()
395
+ {
396
+ # see https://bugs.freedesktop.org/show_bug.cgi?id=34164
397
+ unset GREP_OPTIONS
398
+
399
+ if [ -n "${XDG_CURRENT_DESKTOP}" ]; then
400
+ case "${XDG_CURRENT_DESKTOP}" in
401
+ # only recently added to menu-spec, pre-spec X- still in use
402
+ Cinnamon|X-Cinnamon)
403
+ DE=cinnamon;
404
+ ;;
405
+ ENLIGHTENMENT)
406
+ DE=enlightenment;
407
+ ;;
408
+ # GNOME, GNOME-Classic:GNOME, or GNOME-Flashback:GNOME
409
+ GNOME*)
410
+ DE=gnome;
411
+ ;;
412
+ KDE)
413
+ DE=kde;
414
+ ;;
415
+ # Deepin Desktop Environments
416
+ DEEPIN|Deepin|deepin)
417
+ DE=dde;
418
+ ;;
419
+ LXDE)
420
+ DE=lxde;
421
+ ;;
422
+ LXQt)
423
+ DE=lxqt;
424
+ ;;
425
+ MATE)
426
+ DE=mate;
427
+ ;;
428
+ XFCE)
429
+ DE=xfce
430
+ ;;
431
+ X-Generic)
432
+ DE=generic
433
+ ;;
434
+ esac
435
+ fi
436
+
437
+ if [ x"$DE" = x"" ]; then
438
+ # classic fallbacks
439
+ if [ x"$KDE_FULL_SESSION" != x"" ]; then DE=kde;
440
+ elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome;
441
+ elif [ x"$MATE_DESKTOP_SESSION_ID" != x"" ]; then DE=mate;
442
+ elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome;
443
+ elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce;
444
+ elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then DE=xfce
445
+ elif echo $DESKTOP | grep -q '^Enlightenment'; then DE=enlightenment;
446
+ elif [ x"$LXQT_SESSION_CONFIG" != x"" ]; then DE=lxqt;
447
+ fi
448
+ fi
449
+
450
+ if [ x"$DE" = x"" ]; then
451
+ # fallback to checking $DESKTOP_SESSION
452
+ case "$DESKTOP_SESSION" in
453
+ gnome)
454
+ DE=gnome;
455
+ ;;
456
+ LXDE|Lubuntu)
457
+ DE=lxde;
458
+ ;;
459
+ MATE)
460
+ DE=mate;
461
+ ;;
462
+ xfce|xfce4|'Xfce Session')
463
+ DE=xfce;
464
+ ;;
465
+ esac
466
+ fi
467
+
468
+ if [ x"$DE" = x"" ]; then
469
+ # fallback to uname output for other platforms
470
+ case "$(uname 2>/dev/null)" in
471
+ CYGWIN*)
472
+ DE=cygwin;
473
+ ;;
474
+ Darwin)
475
+ DE=darwin;
476
+ ;;
477
+ esac
478
+ fi
479
+
480
+ if [ x"$DE" = x"gnome" ]; then
481
+ # gnome-default-applications-properties is only available in GNOME 2.x
482
+ # but not in GNOME 3.x
483
+ which gnome-default-applications-properties > /dev/null 2>&1 || DE="gnome3"
484
+ fi
485
+
486
+ if [ -f "$XDG_RUNTIME_DIR/flatpak-info" ]; then
487
+ DE="flatpak"
488
+ fi
489
+ }
490
+
491
+ #----------------------------------------------------------------------------
492
+ # kfmclient exec/openURL can give bogus exit value in KDE <= 3.5.4
493
+ # It also always returns 1 in KDE 3.4 and earlier
494
+ # Simply return 0 in such case
495
+
496
+ kfmclient_fix_exit_code()
497
+ {
498
+ version=`LC_ALL=C.UTF-8 kde-config --version 2>/dev/null | grep '^KDE'`
499
+ major=`echo $version | sed 's/KDE.*: \([0-9]\).*/\1/'`
500
+ minor=`echo $version | sed 's/KDE.*: [0-9]*\.\([0-9]\).*/\1/'`
501
+ release=`echo $version | sed 's/KDE.*: [0-9]*\.[0-9]*\.\([0-9]\).*/\1/'`
502
+ test "$major" -gt 3 && return $1
503
+ test "$minor" -gt 5 && return $1
504
+ test "$release" -gt 4 && return $1
505
+ return 0
506
+ }
507
+
508
+ #----------------------------------------------------------------------------
509
+ # Returns true if there is a graphical display attached.
510
+
511
+ has_display()
512
+ {
513
+ if [ -n "$DISPLAY" ] || [ -n "$WAYLAND_DISPLAY" ]; then
514
+ return 0
515
+ else
516
+ return 1
517
+ fi
518
+ }
519
+
520
+ # This handles backslashes but not quote marks.
521
+ last_word()
522
+ {
523
+ read first rest
524
+ echo "$rest"
525
+ }
526
+
527
+ # Get the value of a key in a desktop file's Desktop Entry group.
528
+ # Example: Use get_key foo.desktop Exec
529
+ # to get the values of the Exec= key for the Desktop Entry group.
530
+ get_key()
531
+ {
532
+ local file="${1}"
533
+ local key="${2}"
534
+ local desktop_entry=""
535
+
536
+ IFS_="${IFS}"
537
+ IFS=""
538
+ while read line
539
+ do
540
+ case "$line" in
541
+ "[Desktop Entry]")
542
+ desktop_entry="y"
543
+ ;;
544
+ # Reset match flag for other groups
545
+ "["*)
546
+ desktop_entry=""
547
+ ;;
548
+ "${key}="*)
549
+ # Only match Desktop Entry group
550
+ if [ -n "${desktop_entry}" ]
551
+ then
552
+ echo "${line}" | cut -d= -f 2-
553
+ fi
554
+ esac
555
+ done < "${file}"
556
+ IFS="${IFS_}"
557
+ }
558
+
559
+ # Returns true if argument is a file:// URL or path
560
+ is_file_url_or_path()
561
+ {
562
+ if echo "$1" | grep -q '^file://' \
563
+ || ! echo "$1" | egrep -q '^[[:alpha:]+\.\-]+:'; then
564
+ return 0
565
+ else
566
+ return 1
567
+ fi
568
+ }
569
+
570
+ # If argument is a file URL, convert it to a (percent-decoded) path.
571
+ # If not, leave it as it is.
572
+ file_url_to_path()
573
+ {
574
+ local file="$1"
575
+ if echo "$file" | grep -q '^file:///'; then
576
+ file=${file#file://}
577
+ file=${file%%#*}
578
+ file=$(echo "$file" | sed -r 's/\?.*$//')
579
+ local printf=printf
580
+ if [ -x /usr/bin/printf ]; then
581
+ printf=/usr/bin/printf
582
+ fi
583
+ file=$($printf "$(echo "$file" | sed -e 's@%\([a-f0-9A-F]\{2\}\)@\\x\1@g')")
584
+ fi
585
+ echo "$file"
586
+ }
587
+
588
+ open_cygwin()
589
+ {
590
+ cygstart "$1"
591
+
592
+ if [ $? -eq 0 ]; then
593
+ exit_success
594
+ else
595
+ exit_failure_operation_failed
596
+ fi
597
+ }
598
+
599
+ open_darwin()
600
+ {
601
+ open "$1"
602
+
603
+ if [ $? -eq 0 ]; then
604
+ exit_success
605
+ else
606
+ exit_failure_operation_failed
607
+ fi
608
+ }
609
+
610
+ open_kde()
611
+ {
612
+ if [ -n "${KDE_SESSION_VERSION}" ]; then
613
+ case "${KDE_SESSION_VERSION}" in
614
+ 4)
615
+ kde-open "$1"
616
+ ;;
617
+ 5)
618
+ kde-open${KDE_SESSION_VERSION} "$1"
619
+ ;;
620
+ *)
621
+ kde-open "$1"
622
+ ;;
623
+ esac
624
+ else
625
+ kfmclient exec "$1"
626
+ kfmclient_fix_exit_code $?
627
+ fi
628
+
629
+ if [ $? -eq 0 ]; then
630
+ exit_success
631
+ else
632
+ exit_failure_operation_failed
633
+ fi
634
+ }
635
+
636
+ open_dde()
637
+ {
638
+ if dde-open -version >/dev/null 2>&1; then
639
+ dde-open "$1"
640
+ else
641
+ open_generic "$1"
642
+ fi
643
+
644
+ if [ $? -eq 0 ]; then
645
+ exit_success
646
+ else
647
+ exit_failure_operation_failed
648
+ fi
649
+ }
650
+
651
+ open_gnome3()
652
+ {
653
+ if gio help open 2>/dev/null 1>&2; then
654
+ gio open "$1"
655
+ elif gvfs-open --help 2>/dev/null 1>&2; then
656
+ gvfs-open "$1"
657
+ else
658
+ open_generic "$1"
659
+ fi
660
+
661
+ if [ $? -eq 0 ]; then
662
+ exit_success
663
+ else
664
+ exit_failure_operation_failed
665
+ fi
666
+ }
667
+
668
+ open_gnome()
669
+ {
670
+ if gio help open 2>/dev/null 1>&2; then
671
+ gio open "$1"
672
+ elif gvfs-open --help 2>/dev/null 1>&2; then
673
+ gvfs-open "$1"
674
+ elif gnome-open --help 2>/dev/null 1>&2; then
675
+ gnome-open "$1"
676
+ else
677
+ open_generic "$1"
678
+ fi
679
+
680
+ if [ $? -eq 0 ]; then
681
+ exit_success
682
+ else
683
+ exit_failure_operation_failed
684
+ fi
685
+ }
686
+
687
+ open_mate()
688
+ {
689
+ if gio help open 2>/dev/null 1>&2; then
690
+ gio open "$1"
691
+ elif gvfs-open --help 2>/dev/null 1>&2; then
692
+ gvfs-open "$1"
693
+ elif mate-open --help 2>/dev/null 1>&2; then
694
+ mate-open "$1"
695
+ else
696
+ open_generic "$1"
697
+ fi
698
+
699
+ if [ $? -eq 0 ]; then
700
+ exit_success
701
+ else
702
+ exit_failure_operation_failed
703
+ fi
704
+ }
705
+
706
+ open_xfce()
707
+ {
708
+ if exo-open --help 2>/dev/null 1>&2; then
709
+ exo-open "$1"
710
+ elif gio help open 2>/dev/null 1>&2; then
711
+ gio open "$1"
712
+ elif gvfs-open --help 2>/dev/null 1>&2; then
713
+ gvfs-open "$1"
714
+ else
715
+ open_generic "$1"
716
+ fi
717
+
718
+ if [ $? -eq 0 ]; then
719
+ exit_success
720
+ else
721
+ exit_failure_operation_failed
722
+ fi
723
+ }
724
+
725
+ open_enlightenment()
726
+ {
727
+ if enlightenment_open --help 2>/dev/null 1>&2; then
728
+ enlightenment_open "$1"
729
+ else
730
+ open_generic "$1"
731
+ fi
732
+
733
+ if [ $? -eq 0 ]; then
734
+ exit_success
735
+ else
736
+ exit_failure_operation_failed
737
+ fi
738
+ }
739
+
740
+ open_flatpak()
741
+ {
742
+ gdbus call --session \
743
+ --dest org.freedesktop.portal.Desktop \
744
+ --object-path /org/freedesktop/portal/desktop \
745
+ --method org.freedesktop.portal.OpenURI.OpenURI \
746
+ "" "$1" {}
747
+
748
+ if [ $? -eq 0 ]; then
749
+ exit_success
750
+ else
751
+ exit_failure_operation_failed
752
+ fi
753
+ }
754
+
755
+ #-----------------------------------------
756
+ # Recursively search .desktop file
757
+
758
+ search_desktop_file()
759
+ {
760
+ local default="$1"
761
+ local dir="$2"
762
+ local target="$3"
763
+
764
+ local file=""
765
+ # look for both vendor-app.desktop, vendor/app.desktop
766
+ if [ -r "$dir/$default" ]; then
767
+ file="$dir/$default"
768
+ elif [ -r "$dir/`echo $default | sed -e 's|-|/|'`" ]; then
769
+ file="$dir/`echo $default | sed -e 's|-|/|'`"
770
+ fi
771
+
772
+ if [ -r "$file" ] ; then
773
+ command="$(get_key "${file}" "Exec" | first_word)"
774
+ command_exec=`which $command 2>/dev/null`
775
+ icon="$(get_key "${file}" "Icon")"
776
+ # FIXME: Actually LC_MESSAGES should be used as described in
777
+ # http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s04.html
778
+ localised_name="$(get_key "${file}" "Name")"
779
+ set -- $(get_key "${file}" "Exec" | last_word)
780
+ # We need to replace any occurrence of "%f", "%F" and
781
+ # the like by the target file. We examine each
782
+ # argument and append the modified argument to the
783
+ # end then shift.
784
+ local args=$#
785
+ local replaced=0
786
+ while [ $args -gt 0 ]; do
787
+ case $1 in
788
+ %[c])
789
+ replaced=1
790
+ arg="${localised_name}"
791
+ shift
792
+ set -- "$@" "$arg"
793
+ ;;
794
+ %[fFuU])
795
+ replaced=1
796
+ arg="$target"
797
+ shift
798
+ set -- "$@" "$arg"
799
+ ;;
800
+ %[i])
801
+ replaced=1
802
+ shift
803
+ set -- "$@" "--icon" "$icon"
804
+ ;;
805
+ *)
806
+ arg="$1"
807
+ shift
808
+ set -- "$@" "$arg"
809
+ ;;
810
+ esac
811
+ args=$(( $args - 1 ))
812
+ done
813
+ [ $replaced -eq 1 ] || set -- "$@" "$target"
814
+ "$command_exec" "$@"
815
+
816
+ if [ $? -eq 0 ]; then
817
+ exit_success
818
+ fi
819
+ fi
820
+
821
+ for d in $dir/*/; do
822
+ [ -d "$d" ] && search_desktop_file "$default" "$d" "$target"
823
+ done
824
+ }
825
+
826
+
827
+ open_generic_xdg_mime()
828
+ {
829
+ filetype="$2"
830
+ default=`xdg-mime query default "$filetype"`
831
+ if [ -n "$default" ] ; then
832
+ xdg_user_dir="$XDG_DATA_HOME"
833
+ [ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share"
834
+
835
+ xdg_system_dirs="$XDG_DATA_DIRS"
836
+ [ -n "$xdg_system_dirs" ] || xdg_system_dirs=/usr/local/share/:/usr/share/
837
+
838
+ DEBUG 3 "$xdg_user_dir:$xdg_system_dirs"
839
+ for x in `echo "$xdg_user_dir:$xdg_system_dirs" | sed 's/:/ /g'`; do
840
+ search_desktop_file "$default" "$x/applications/" "$1"
841
+ done
842
+ fi
843
+ }
844
+
845
+ open_generic_xdg_file_mime()
846
+ {
847
+ filetype=`xdg-mime query filetype "$1" | sed "s/;.*//"`
848
+ open_generic_xdg_mime "$1" "$filetype"
849
+ }
850
+
851
+ open_generic_xdg_x_scheme_handler()
852
+ {
853
+ scheme="`echo $1 | sed -n 's/\(^[[:alnum:]+\.-]*\):.*$/\1/p'`"
854
+ if [ -n $scheme ]; then
855
+ filetype="x-scheme-handler/$scheme"
856
+ open_generic_xdg_mime "$1" "$filetype"
857
+ fi
858
+ }
859
+
860
+ has_single_argument()
861
+ {
862
+ test $# = 1
863
+ }
864
+
865
+ open_envvar()
866
+ {
867
+ local oldifs="$IFS"
868
+ local browser browser_with_arg
869
+
870
+ IFS=":"
871
+ for browser in $BROWSER; do
872
+ IFS="$oldifs"
873
+
874
+ if [ -z "$browser" ]; then
875
+ continue
876
+ fi
877
+
878
+ if echo "$browser" | grep -q %s; then
879
+ # Avoid argument injection.
880
+ # See https://bugs.freedesktop.org/show_bug.cgi?id=103807
881
+ # URIs don't have IFS characters spaces anyway.
882
+ has_single_argument $1 && $(printf "$browser" "$1")
883
+ else
884
+ $browser "$1"
885
+ fi
886
+
887
+ if [ $? -eq 0 ]; then
888
+ exit_success
889
+ fi
890
+ done
891
+ }
892
+
893
+ open_generic()
894
+ {
895
+ if is_file_url_or_path "$1"; then
896
+ local file="$(file_url_to_path "$1")"
897
+
898
+ check_input_file "$file"
899
+
900
+ if has_display; then
901
+ filetype=`xdg-mime query filetype "$file" | sed "s/;.*//"`
902
+ open_generic_xdg_mime "$file" "$filetype"
903
+ fi
904
+
905
+ if which run-mailcap 2>/dev/null 1>&2; then
906
+ run-mailcap --action=view "$file"
907
+ if [ $? -eq 0 ]; then
908
+ exit_success
909
+ fi
910
+ fi
911
+
912
+ if has_display && mimeopen -v 2>/dev/null 1>&2; then
913
+ mimeopen -L -n "$file"
914
+ if [ $? -eq 0 ]; then
915
+ exit_success
916
+ fi
917
+ fi
918
+ fi
919
+
920
+ if has_display; then
921
+ open_generic_xdg_x_scheme_handler "$1"
922
+ fi
923
+
924
+ if [ -n "$BROWSER" ]; then
925
+ open_envvar "$1"
926
+ fi
927
+
928
+ # if BROWSER variable is not set, check some well known browsers instead
929
+ if [ x"$BROWSER" = x"" ]; then
930
+ BROWSER=www-browser:links2:elinks:links:lynx:w3m
931
+ if has_display; then
932
+ BROWSER=x-www-browser:firefox:iceweasel:seamonkey:mozilla:epiphany:konqueror:chromium:chromium-browser:google-chrome:microsoft-edge:$BROWSER
933
+ fi
934
+ fi
935
+
936
+ open_envvar "$1"
937
+
938
+ exit_failure_operation_impossible "no method available for opening '$1'"
939
+ }
940
+
941
+ open_lxde()
942
+ {
943
+
944
+ # pcmanfm only knows how to handle file:// urls and filepaths, it seems.
945
+ if pcmanfm --help >/dev/null 2>&1 && is_file_url_or_path "$1"; then
946
+ local file="$(file_url_to_path "$1")"
947
+
948
+ # handle relative paths
949
+ if ! echo "$file" | grep -q ^/; then
950
+ file="$(pwd)/$file"
951
+ fi
952
+
953
+ pcmanfm "$file"
954
+ else
955
+ open_generic "$1"
956
+ fi
957
+
958
+ if [ $? -eq 0 ]; then
959
+ exit_success
960
+ else
961
+ exit_failure_operation_failed
962
+ fi
963
+ }
964
+
965
+ open_lxqt()
966
+ {
967
+ open_generic "$1"
968
+ }
969
+
970
+ [ x"$1" != x"" ] || exit_failure_syntax
971
+
972
+ url=
973
+ while [ $# -gt 0 ] ; do
974
+ parm="$1"
975
+ shift
976
+
977
+ case "$parm" in
978
+ -*)
979
+ exit_failure_syntax "unexpected option '$parm'"
980
+ ;;
981
+
982
+ *)
983
+ if [ -n "$url" ] ; then
984
+ exit_failure_syntax "unexpected argument '$parm'"
985
+ fi
986
+ url="$parm"
987
+ ;;
988
+ esac
989
+ done
990
+
991
+ if [ -z "${url}" ] ; then
992
+ exit_failure_syntax "file or URL argument missing"
993
+ fi
994
+
995
+ detectDE
996
+
997
+ if [ x"$DE" = x"" ]; then
998
+ DE=generic
999
+ fi
1000
+
1001
+ DEBUG 2 "Selected DE $DE"
1002
+
1003
+ # sanitize BROWSER (avoid caling ourselves in particular)
1004
+ case "${BROWSER}" in
1005
+ *:"xdg-open"|"xdg-open":*)
1006
+ BROWSER=$(echo $BROWSER | sed -e 's|:xdg-open||g' -e 's|xdg-open:||g')
1007
+ ;;
1008
+ "xdg-open")
1009
+ BROWSER=
1010
+ ;;
1011
+ esac
1012
+
1013
+ case "$DE" in
1014
+ kde)
1015
+ open_kde "$url"
1016
+ ;;
1017
+
1018
+ dde)
1019
+ open_dde "$url"
1020
+ ;;
1021
+
1022
+ gnome3|cinnamon)
1023
+ open_gnome3 "$url"
1024
+ ;;
1025
+
1026
+ gnome)
1027
+ open_gnome "$url"
1028
+ ;;
1029
+
1030
+ mate)
1031
+ open_mate "$url"
1032
+ ;;
1033
+
1034
+ xfce)
1035
+ open_xfce "$url"
1036
+ ;;
1037
+
1038
+ lxde)
1039
+ open_lxde "$url"
1040
+ ;;
1041
+
1042
+ lxqt)
1043
+ open_lxqt "$url"
1044
+ ;;
1045
+
1046
+ enlightenment)
1047
+ open_enlightenment "$url"
1048
+ ;;
1049
+
1050
+ cygwin)
1051
+ open_cygwin "$url"
1052
+ ;;
1053
+
1054
+ darwin)
1055
+ open_darwin "$url"
1056
+ ;;
1057
+
1058
+ flatpak)
1059
+ open_flatpak "$url"
1060
+ ;;
1061
+
1062
+ generic)
1063
+ open_generic "$url"
1064
+ ;;
1065
+
1066
+ *)
1067
+ exit_failure_operation_impossible "no method available for opening '$url'"
1068
+ ;;
1069
+ esac