@wix/create-headless-site 0.0.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.
package/build/xdg-open ADDED
@@ -0,0 +1,1267 @@
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-2016, 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
+ As xdg-open can not handle arguments that begin with a "-" it
62
+ is recommended to pass filepaths in one of the following ways:
63
+ * Pass absolute paths, i.e. by using realpath as a
64
+ preprocessor.
65
+ * Prefix known relative filepaths with a "./". For example
66
+ using sed -E 's|^[^/]|./\0|'.
67
+ * Pass a file URL.
68
+
69
+ Options
70
+
71
+ --help
72
+ Show command synopsis.
73
+
74
+ --manual
75
+ Show this manual page.
76
+
77
+ --version
78
+ Show the xdg-utils version information.
79
+
80
+ Exit Codes
81
+
82
+ An exit code of 0 indicates success while a non-zero exit code
83
+ indicates failure. The following failure codes can be returned:
84
+
85
+ 1
86
+ Error in command line syntax.
87
+
88
+ 2
89
+ One of the files passed on the command line did not
90
+ exist.
91
+
92
+ 3
93
+ A required tool could not be found.
94
+
95
+ 4
96
+ The action failed.
97
+
98
+ In case of success the process launched from the .desktop file
99
+ will not be forked off and therefore may result in xdg-open
100
+ running for a very long time. This behaviour intentionally
101
+ differs from most desktop specific openers to allow terminal
102
+ based applications to run using the same terminal xdg-open was
103
+ called from.
104
+
105
+ Reporting Issues
106
+
107
+ Please keep in mind xdg-open inherits most of the flaws of its
108
+ configuration and the underlying opener.
109
+
110
+ In case the command xdg-mime query default "$(xdg-mime query
111
+ filetype path/to/troublesome_file)" names the program
112
+ responsible for any unexpected behaviour you can fix that by
113
+ setting a different handler. (If the program is broken let the
114
+ developers know)
115
+
116
+ Also see the security note on xdg-mime(1) for the default
117
+ subcommand.
118
+
119
+ If a flaw is reproducible using the desktop specific opener
120
+ (and isn't a configuration issue): Please report to whoever is
121
+ responsible for that first (reporting to xdg-utils is better
122
+ than not reporting at all, but since the xdg-utils are
123
+ maintained in very little spare time a fix will take much
124
+ longer)
125
+
126
+ In case an issue specific to xdg-open please report it to
127
+ https://gitlab.freedesktop.org/xdg/xdg-utils/-/issues .
128
+
129
+ See Also
130
+
131
+ xdg-mime(1), xdg-settings(1), MIME applications associations
132
+ specification
133
+
134
+ Examples
135
+
136
+ xdg-open 'http://www.freedesktop.org/'
137
+
138
+ Opens the freedesktop.org website in the user's default
139
+ browser.
140
+
141
+ xdg-open /tmp/foobar.png
142
+
143
+ Opens the PNG image file /tmp/foobar.png in the user's default
144
+ image viewing application.
145
+ _MANUALPAGE
146
+ }
147
+
148
+ usage()
149
+ {
150
+ cat << '_USAGE'
151
+ xdg-open -- opens a file or URL in the user's preferred
152
+ application
153
+
154
+ Synopsis
155
+
156
+ xdg-open { file | URL }
157
+
158
+ xdg-open { --help | --manual | --version }
159
+
160
+ _USAGE
161
+ }
162
+
163
+ #@xdg-utils-common@
164
+ #----------------------------------------------------------------------------
165
+ # Common utility functions included in all XDG wrapper scripts
166
+ #----------------------------------------------------------------------------
167
+
168
+ #shellcheck shell=sh
169
+
170
+ DEBUG()
171
+ {
172
+ [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && return 0;
173
+ [ "${XDG_UTILS_DEBUG_LEVEL}" -lt "$1" ] && return 0;
174
+ shift
175
+ echo "$@" >&2
176
+ }
177
+
178
+ # This handles backslashes but not quote marks.
179
+ first_word()
180
+ {
181
+ # shellcheck disable=SC2162 # No -r is intended here
182
+ read first rest
183
+ echo "$first"
184
+ }
185
+
186
+ #-------------------------------------------------------------
187
+ # map a binary to a .desktop file
188
+ binary_to_desktop_file()
189
+ {
190
+ search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
191
+ binary="$(command -v "$1")"
192
+ binary="$(xdg_realpath "$binary")"
193
+ base="$(basename "$binary")"
194
+ IFS=:
195
+ for dir in $search; do
196
+ unset IFS
197
+ [ "$dir" ] || continue
198
+ [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue
199
+ for file in "$dir"/applications/*.desktop "$dir"/applications/*/*.desktop "$dir"/applnk/*.desktop "$dir"/applnk/*/*.desktop; do
200
+ [ -r "$file" ] || continue
201
+ # Check to make sure it's worth the processing.
202
+ grep -q "^Exec.*$base" "$file" || continue
203
+ # Make sure it's a visible desktop file (e.g. not "preferred-web-browser.desktop").
204
+ grep -Eq "^(NoDisplay|Hidden)=true" "$file" && continue
205
+ command="$(grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word)"
206
+ command="$(command -v "$command")"
207
+ if [ x"$(xdg_realpath "$command")" = x"$binary" ]; then
208
+ # Fix any double slashes that got added path composition
209
+ echo "$file" | tr -s /
210
+ return
211
+ fi
212
+ done
213
+ done
214
+ }
215
+
216
+ #-------------------------------------------------------------
217
+ # map a .desktop file to a binary
218
+ desktop_file_to_binary()
219
+ {
220
+ search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
221
+ desktop="$(basename "$1")"
222
+ IFS=:
223
+ for dir in $search; do
224
+ unset IFS
225
+ [ "$dir" ] && [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue
226
+ # Check if desktop file contains -
227
+ if [ "${desktop#*-}" != "$desktop" ]; then
228
+ vendor=${desktop%-*}
229
+ app=${desktop#*-}
230
+ if [ -r "$dir/applications/$vendor/$app" ]; then
231
+ file_path="$dir/applications/$vendor/$app"
232
+ elif [ -r "$dir/applnk/$vendor/$app" ]; then
233
+ file_path="$dir/applnk/$vendor/$app"
234
+ fi
235
+ fi
236
+ if test -z "$file_path" ; then
237
+ for indir in "$dir"/applications/ "$dir"/applications/*/ "$dir"/applnk/ "$dir"/applnk/*/; do
238
+ file="$indir/$desktop"
239
+ if [ -r "$file" ]; then
240
+ file_path=$file
241
+ break
242
+ fi
243
+ done
244
+ fi
245
+ if [ -r "$file_path" ]; then
246
+ # Remove any arguments (%F, %f, %U, %u, etc.).
247
+ command="$(grep -E "^Exec(\[[^]=]*])?=" "$file_path" | cut -d= -f 2- | first_word)"
248
+ command="$(command -v "$command")"
249
+ xdg_realpath "$command"
250
+ return
251
+ fi
252
+ done
253
+ }
254
+
255
+ #-------------------------------------------------------------
256
+ # Exit script on successfully completing the desired operation
257
+
258
+ # shellcheck disable=SC2120 # It is okay to call this without arguments
259
+ exit_success()
260
+ {
261
+ if [ $# -gt 0 ]; then
262
+ echo "$*"
263
+ echo
264
+ fi
265
+
266
+ exit 0
267
+ }
268
+
269
+
270
+ #-----------------------------------------
271
+ # Exit script on malformed arguments, not enough arguments
272
+ # or missing required option.
273
+ # prints usage information
274
+
275
+ exit_failure_syntax()
276
+ {
277
+ if [ $# -gt 0 ]; then
278
+ echo "xdg-open: $*" >&2
279
+ echo "Try 'xdg-open --help' for more information." >&2
280
+ else
281
+ usage
282
+ echo "Use 'man xdg-open' or 'xdg-open --manual' for additional info."
283
+ fi
284
+
285
+ exit 1
286
+ }
287
+
288
+ #-------------------------------------------------------------
289
+ # Exit script on missing file specified on command line
290
+
291
+ exit_failure_file_missing()
292
+ {
293
+ if [ $# -gt 0 ]; then
294
+ echo "xdg-open: $*" >&2
295
+ fi
296
+
297
+ exit 2
298
+ }
299
+
300
+ #-------------------------------------------------------------
301
+ # Exit script on failure to locate necessary tool applications
302
+
303
+ exit_failure_operation_impossible()
304
+ {
305
+ if [ $# -gt 0 ]; then
306
+ echo "xdg-open: $*" >&2
307
+ fi
308
+
309
+ exit 3
310
+ }
311
+
312
+ #-------------------------------------------------------------
313
+ # Exit script on failure returned by a tool application
314
+
315
+ exit_failure_operation_failed()
316
+ {
317
+ if [ $# -gt 0 ]; then
318
+ echo "xdg-open: $*" >&2
319
+ fi
320
+
321
+ exit 4
322
+ }
323
+
324
+ #------------------------------------------------------------
325
+ # Exit script on insufficient permission to read a specified file
326
+
327
+ exit_failure_file_permission_read()
328
+ {
329
+ if [ $# -gt 0 ]; then
330
+ echo "xdg-open: $*" >&2
331
+ fi
332
+
333
+ exit 5
334
+ }
335
+
336
+ #------------------------------------------------------------
337
+ # Exit script on insufficient permission to write a specified file
338
+
339
+ exit_failure_file_permission_write()
340
+ {
341
+ if [ $# -gt 0 ]; then
342
+ echo "xdg-open: $*" >&2
343
+ fi
344
+
345
+ exit 6
346
+ }
347
+
348
+ check_input_file()
349
+ {
350
+ if [ ! -e "$1" ]; then
351
+ exit_failure_file_missing "file '$1' does not exist"
352
+ fi
353
+ if [ ! -r "$1" ]; then
354
+ exit_failure_file_permission_read "no permission to read file '$1'"
355
+ fi
356
+ }
357
+
358
+ check_vendor_prefix()
359
+ {
360
+ file_label="$2"
361
+ [ -n "$file_label" ] || file_label="filename"
362
+ file="$(basename "$1")"
363
+ case "$file" in
364
+ [[:alpha:]]*-*)
365
+ return
366
+ ;;
367
+ esac
368
+
369
+ echo "xdg-open: $file_label '$file' does not have a proper vendor prefix" >&2
370
+ echo 'A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated' >&2
371
+ echo 'with a dash ("-"). An example '"$file_label"' is '"'example-$file'" >&2
372
+ echo "Use --novendor to override or 'xdg-open --manual' for additional info." >&2
373
+ exit 1
374
+ }
375
+
376
+ check_output_file()
377
+ {
378
+ # if the file exists, check if it is writeable
379
+ # if it does not exists, check if we are allowed to write on the directory
380
+ if [ -e "$1" ]; then
381
+ if [ ! -w "$1" ]; then
382
+ exit_failure_file_permission_write "no permission to write to file '$1'"
383
+ fi
384
+ else
385
+ DIR="$(dirname "$1")"
386
+ if [ ! -w "$DIR" ] || [ ! -x "$DIR" ]; then
387
+ exit_failure_file_permission_write "no permission to create file '$1'"
388
+ fi
389
+ fi
390
+ }
391
+
392
+ #----------------------------------------
393
+ # Checks for shared commands, e.g. --help
394
+
395
+ check_common_commands()
396
+ {
397
+ while [ $# -gt 0 ] ; do
398
+ parm="$1"
399
+ shift
400
+
401
+ case "$parm" in
402
+ --help)
403
+ usage
404
+ echo "Use 'man xdg-open' or 'xdg-open --manual' for additional info."
405
+ exit_success
406
+ ;;
407
+
408
+ --manual)
409
+ manualpage
410
+ exit_success
411
+ ;;
412
+
413
+ --version)
414
+ echo "xdg-open 1.2.1"
415
+ exit_success
416
+ ;;
417
+
418
+ --)
419
+ [ -z "$XDG_UTILS_ENABLE_DOUBLE_HYPEN" ] || break
420
+ ;;
421
+ esac
422
+ done
423
+ }
424
+
425
+ check_common_commands "$@"
426
+
427
+ [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && unset XDG_UTILS_DEBUG_LEVEL;
428
+ # shellcheck disable=SC2034
429
+ if [ "${XDG_UTILS_DEBUG_LEVEL-0}" -lt 1 ]; then
430
+ # Be silent
431
+ xdg_redirect_output=" > /dev/null 2> /dev/null"
432
+ else
433
+ # All output to stderr
434
+ xdg_redirect_output=" >&2"
435
+ fi
436
+
437
+ #--------------------------------------
438
+ # Checks for known desktop environments
439
+ # set variable DE to the desktop environments name, lowercase
440
+
441
+ detectDE()
442
+ {
443
+ # see https://bugs.freedesktop.org/show_bug.cgi?id=34164
444
+ unset GREP_OPTIONS
445
+
446
+ if [ -n "${XDG_CURRENT_DESKTOP}" ]; then
447
+ case "${XDG_CURRENT_DESKTOP}" in
448
+ # only recently added to menu-spec, pre-spec X- still in use
449
+ Cinnamon|X-Cinnamon)
450
+ DE=cinnamon;
451
+ ;;
452
+ ENLIGHTENMENT)
453
+ DE=enlightenment;
454
+ ;;
455
+ # GNOME, GNOME-Classic:GNOME, or GNOME-Flashback:GNOME
456
+ GNOME*)
457
+ DE=gnome;
458
+ ;;
459
+ KDE)
460
+ DE=kde;
461
+ ;;
462
+ DEEPIN|Deepin|deepin)
463
+ DE=deepin;
464
+ ;;
465
+ LXDE)
466
+ DE=lxde;
467
+ ;;
468
+ LXQt)
469
+ DE=lxqt;
470
+ ;;
471
+ MATE)
472
+ DE=mate;
473
+ ;;
474
+ XFCE)
475
+ DE=xfce
476
+ ;;
477
+ X-Generic)
478
+ DE=generic
479
+ ;;
480
+ esac
481
+ fi
482
+
483
+ # shellcheck disable=SC2153
484
+ if [ -z "$DE" ]; then
485
+ # classic fallbacks
486
+ if [ -n "$KDE_FULL_SESSION" ]; then DE=kde;
487
+ elif [ -n "$GNOME_DESKTOP_SESSION_ID" ]; then DE=gnome;
488
+ elif [ -n "$MATE_DESKTOP_SESSION_ID" ]; then DE=mate;
489
+ 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;
490
+ elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce;
491
+ elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then DE=xfce
492
+ elif echo "$DESKTOP" | grep -q '^Enlightenment'; then DE=enlightenment;
493
+ elif [ -n "$LXQT_SESSION_CONFIG" ]; then DE=lxqt;
494
+ fi
495
+ fi
496
+
497
+ if [ -z "$DE" ]; then
498
+ # fallback to checking $DESKTOP_SESSION
499
+ case "$DESKTOP_SESSION" in
500
+ gnome)
501
+ DE=gnome;
502
+ ;;
503
+ LXDE|Lubuntu)
504
+ DE=lxde;
505
+ ;;
506
+ MATE)
507
+ DE=mate;
508
+ ;;
509
+ xfce|xfce4|'Xfce Session')
510
+ DE=xfce;
511
+ ;;
512
+ esac
513
+ fi
514
+
515
+ if [ -z "$DE" ]; then
516
+ # fallback to uname output for other platforms
517
+ case "$(uname 2>/dev/null)" in
518
+ CYGWIN*)
519
+ DE=cygwin;
520
+ ;;
521
+ Darwin)
522
+ DE=darwin;
523
+ ;;
524
+ Linux)
525
+ grep -q microsoft /proc/version > /dev/null 2>&1 && \
526
+ command -v explorer.exe > /dev/null 2>&1 && \
527
+ DE=wsl;
528
+ ;;
529
+ esac
530
+ fi
531
+
532
+ if [ x"$DE" = x"gnome" ]; then
533
+ # gnome-default-applications-properties is only available in GNOME 2.x
534
+ # but not in GNOME 3.x
535
+ command -v gnome-default-applications-properties > /dev/null || DE="gnome3"
536
+ fi
537
+
538
+ if [ -f "$XDG_RUNTIME_DIR/flatpak-info" ]; then
539
+ DE="flatpak"
540
+ fi
541
+ }
542
+
543
+ #----------------------------------------------------------------------------
544
+ # kfmclient exec/openURL can give bogus exit value in KDE <= 3.5.4
545
+ # It also always returns 1 in KDE 3.4 and earlier
546
+ # Simply return 0 in such case
547
+
548
+ kfmclient_fix_exit_code()
549
+ {
550
+ version="$(LC_ALL=C.UTF-8 kde-config --version 2>/dev/null | grep '^KDE')"
551
+ major="$(echo "$version" | sed 's/KDE.*: \([0-9]\).*/\1/')"
552
+ minor="$(echo "$version" | sed 's/KDE.*: [0-9]*\.\([0-9]\).*/\1/')"
553
+ release="$(echo "$version" | sed 's/KDE.*: [0-9]*\.[0-9]*\.\([0-9]\).*/\1/')"
554
+ test "$major" -gt 3 && return "$1"
555
+ test "$minor" -gt 5 && return "$1"
556
+ test "$release" -gt 4 && return "$1"
557
+ return 0
558
+ }
559
+
560
+ #----------------------------------------------------------------------------
561
+ # Returns true if there is a graphical display attached.
562
+
563
+ has_display()
564
+ {
565
+ if [ -n "$DISPLAY" ] || [ -n "$WAYLAND_DISPLAY" ]; then
566
+ return 0
567
+ else
568
+ return 1
569
+ fi
570
+ }
571
+
572
+ #----------------------------------------------------------------------------
573
+ # Prefixes a path with a "./" if it starts with a "-".
574
+ # This is useful for programs to not confuse paths with options.
575
+
576
+ unoption_path()
577
+ {
578
+ case "$1" in
579
+ -*)
580
+ printf "./%s" "$1" ;;
581
+ *)
582
+ printf "%s" "$1" ;;
583
+ esac
584
+ }
585
+
586
+ #----------------------------------------------------------------------------
587
+ # Performs a symlink and relative path resolving for a single argument.
588
+ # This will always fail if the given file does not exist!
589
+
590
+ xdg_realpath()
591
+ {
592
+ # allow caching and external configuration
593
+ if [ -z "$XDG_UTILS_REALPATH_BACKEND" ] ; then
594
+ if command -v realpath >/dev/null 2>/dev/null ; then
595
+ lines="$(realpath -- / 2>&1)"
596
+ if [ $? = 0 ] && [ "$lines" = "/" ] ; then
597
+ XDG_UTILS_REALPATH_BACKEND="realpath"
598
+ else
599
+ # The realpath took the -- literally, probably the busybox implementation
600
+ XDG_UTILS_REALPATH_BACKEND="busybox-realpath"
601
+ fi
602
+ unset lines
603
+ elif command -v readlink >/dev/null 2>/dev/null ; then
604
+ XDG_UTILS_REALPATH_BACKEND="readlink"
605
+ else
606
+ exit_failure_operation_failed "No usable realpath backend found. Have a realpath binary or a readlink -f that canonicalizes paths."
607
+ fi
608
+ fi
609
+ # Always fail if the file doesn't exist (busybox realpath does that for example)
610
+ [ -e "$1" ] || return 1
611
+ case "$XDG_UTILS_REALPATH_BACKEND" in
612
+ realpath)
613
+ realpath -- "$1"
614
+ ;;
615
+ busybox-realpath)
616
+ # busybox style realpath implementations have options too
617
+ realpath "$(unoption_path "$1")"
618
+ ;;
619
+ readlink)
620
+ readlink -f "$(unoption_path "$1")"
621
+ ;;
622
+ *)
623
+ exit_failure_operation_impossible "Realpath backend '$XDG_UTILS_REALPATH_BACKEND' not recognized."
624
+ ;;
625
+ esac
626
+ }
627
+
628
+ # This handles backslashes but not quote marks.
629
+ last_word()
630
+ {
631
+ # Backslash handling is intended, not using `first` too
632
+ # shellcheck disable=SC2162,SC2034
633
+ read first rest
634
+ echo "$rest"
635
+ }
636
+
637
+ # Get the value of a key in a desktop file's Desktop Entry group.
638
+ # Example: Use get_key foo.desktop Exec
639
+ # to get the values of the Exec= key for the Desktop Entry group.
640
+ get_key()
641
+ {
642
+ local file="${1}"
643
+ local key="${2}"
644
+ local desktop_entry=""
645
+
646
+ IFS_="${IFS}"
647
+ IFS=""
648
+ # No backslash handling here, first_word and last_word do that
649
+ while read -r line
650
+ do
651
+ case "$line" in
652
+ "[Desktop Entry]")
653
+ desktop_entry="y"
654
+ ;;
655
+ # Reset match flag for other groups
656
+ "["*)
657
+ desktop_entry=""
658
+ ;;
659
+ "${key}="*)
660
+ # Only match Desktop Entry group
661
+ if [ -n "${desktop_entry}" ]
662
+ then
663
+ echo "${line}" | cut -d= -f 2-
664
+ fi
665
+ esac
666
+ done < "${file}"
667
+ IFS="${IFS_}"
668
+ }
669
+
670
+ has_url_scheme()
671
+ {
672
+ echo "$1" | LC_ALL=C grep -Eq '^[[:alpha:]][[:alpha:][:digit:]+\.\-]*:'
673
+ }
674
+
675
+ # Returns true if argument is a file:// URL or path
676
+ is_file_url_or_path()
677
+ {
678
+ if echo "$1" | grep -q '^file://' || ! has_url_scheme "$1" ; then
679
+ return 0
680
+ else
681
+ return 1
682
+ fi
683
+ }
684
+
685
+ get_hostname() {
686
+ if [ -z "$HOSTNAME" ]; then
687
+ if command -v hostname > /dev/null; then
688
+ HOSTNAME=$(hostname)
689
+ else
690
+ HOSTNAME=$(uname -n)
691
+ fi
692
+ fi
693
+ }
694
+
695
+ # If argument is a file URL, convert it to a (percent-decoded) path.
696
+ # If not, leave it as it is.
697
+ file_url_to_path()
698
+ {
699
+ local file="$1"
700
+ get_hostname
701
+ if echo "$file" | grep -q '^file://'; then
702
+ file=${file#file://localhost}
703
+ file=${file#file://"$HOSTNAME"}
704
+ file=${file#file://}
705
+ if ! echo "$file" | grep -q '^/'; then
706
+ echo "$file"
707
+ return
708
+ fi
709
+ file=${file%%#*}
710
+ file=${file%%\?*}
711
+ local printf=printf
712
+ if [ -x /usr/bin/printf ]; then
713
+ printf=/usr/bin/printf
714
+ fi
715
+ file=$($printf "$(echo "$file" | sed -e 's@%\([a-f0-9A-F]\{2\}\)@\\x\1@g')")
716
+ fi
717
+ echo "$file"
718
+ }
719
+
720
+ open_cygwin()
721
+ {
722
+ cygstart "$1"
723
+
724
+ if [ $? -eq 0 ]; then
725
+ exit_success
726
+ else
727
+ exit_failure_operation_failed
728
+ fi
729
+ }
730
+
731
+ open_darwin()
732
+ {
733
+ open "$1"
734
+
735
+ if [ $? -eq 0 ]; then
736
+ exit_success
737
+ else
738
+ exit_failure_operation_failed
739
+ fi
740
+ }
741
+
742
+ open_kde()
743
+ {
744
+ if [ -n "${KDE_SESSION_VERSION}" ]; then
745
+ case "${KDE_SESSION_VERSION}" in
746
+ 4)
747
+ kde-open "$1"
748
+ ;;
749
+ 5)
750
+ "kde-open${KDE_SESSION_VERSION}" "$1"
751
+ ;;
752
+ 6)
753
+ kde-open "$1"
754
+ ;;
755
+ esac
756
+ else
757
+ kfmclient exec "$1"
758
+ kfmclient_fix_exit_code $?
759
+ fi
760
+
761
+ if [ $? -eq 0 ]; then
762
+ exit_success
763
+ else
764
+ exit_failure_operation_failed
765
+ fi
766
+ }
767
+
768
+ open_deepin()
769
+ {
770
+ if dde-open -version >/dev/null 2>&1; then
771
+ dde-open "$1"
772
+ else
773
+ open_generic "$1"
774
+ fi
775
+
776
+ if [ $? -eq 0 ]; then
777
+ exit_success
778
+ else
779
+ exit_failure_operation_failed
780
+ fi
781
+ }
782
+
783
+ open_gnome3()
784
+ {
785
+ if gio help open 2>/dev/null 1>&2; then
786
+ gio open "$1"
787
+ elif gvfs-open --help 2>/dev/null 1>&2; then
788
+ gvfs-open "$1"
789
+ else
790
+ open_generic "$1"
791
+ fi
792
+
793
+ if [ $? -eq 0 ]; then
794
+ exit_success
795
+ else
796
+ exit_failure_operation_failed
797
+ fi
798
+ }
799
+
800
+ open_gnome()
801
+ {
802
+ if gio help open 2>/dev/null 1>&2; then
803
+ gio open "$1"
804
+ elif gvfs-open --help 2>/dev/null 1>&2; then
805
+ gvfs-open "$1"
806
+ elif gnome-open --help 2>/dev/null 1>&2; then
807
+ gnome-open "$1"
808
+ else
809
+ open_generic "$1"
810
+ fi
811
+
812
+ if [ $? -eq 0 ]; then
813
+ exit_success
814
+ else
815
+ exit_failure_operation_failed
816
+ fi
817
+ }
818
+
819
+ open_mate()
820
+ {
821
+ if gio help open 2>/dev/null 1>&2; then
822
+ gio open "$1"
823
+ elif gvfs-open --help 2>/dev/null 1>&2; then
824
+ gvfs-open "$1"
825
+ elif mate-open --help 2>/dev/null 1>&2; then
826
+ mate-open "$1"
827
+ else
828
+ open_generic "$1"
829
+ fi
830
+
831
+ if [ $? -eq 0 ]; then
832
+ exit_success
833
+ else
834
+ exit_failure_operation_failed
835
+ fi
836
+ }
837
+
838
+ open_xfce()
839
+ {
840
+ if exo-open --help 2>/dev/null 1>&2; then
841
+ exo-open "$1"
842
+ elif gio help open 2>/dev/null 1>&2; then
843
+ gio open "$1"
844
+ elif gvfs-open --help 2>/dev/null 1>&2; then
845
+ gvfs-open "$1"
846
+ else
847
+ open_generic "$1"
848
+ fi
849
+
850
+ if [ $? -eq 0 ]; then
851
+ exit_success
852
+ else
853
+ exit_failure_operation_failed
854
+ fi
855
+ }
856
+
857
+ open_enlightenment()
858
+ {
859
+ if enlightenment_open --help 2>/dev/null 1>&2; then
860
+ enlightenment_open "$1"
861
+ else
862
+ open_generic "$1"
863
+ fi
864
+
865
+ if [ $? -eq 0 ]; then
866
+ exit_success
867
+ else
868
+ exit_failure_operation_failed
869
+ fi
870
+ }
871
+
872
+ open_flatpak()
873
+ {
874
+ if is_file_url_or_path "$1"; then
875
+ local file
876
+ file="$(file_url_to_path "$1")"
877
+
878
+ check_input_file "$file"
879
+
880
+ gdbus call --session \
881
+ --dest org.freedesktop.portal.Desktop \
882
+ --object-path /org/freedesktop/portal/desktop \
883
+ --method org.freedesktop.portal.OpenURI.OpenFile \
884
+ --timeout 5 \
885
+ "" "3" {} 3< "$file"
886
+ else
887
+ # $1 contains an URI
888
+
889
+ gdbus call --session \
890
+ --dest org.freedesktop.portal.Desktop \
891
+ --object-path /org/freedesktop/portal/desktop \
892
+ --method org.freedesktop.portal.OpenURI.OpenURI \
893
+ --timeout 5 \
894
+ "" "$1" {}
895
+ fi
896
+
897
+ if [ $? -eq 0 ]; then
898
+ exit_success
899
+ else
900
+ exit_failure_operation_failed
901
+ fi
902
+ }
903
+
904
+ #-----------------------------------------
905
+ # Recursively search .desktop file
906
+
907
+ #(application, directory, target file, target_url)
908
+ search_desktop_file()
909
+ {
910
+ local default="$1"
911
+ local dir="$2"
912
+ local target="$3"
913
+ local target_uri="$4"
914
+
915
+ local file=""
916
+ # look for both vendor-app.desktop, vendor/app.desktop
917
+ if [ -r "$dir/$default" ]; then
918
+ file="$dir/$default"
919
+ elif [ -r "$dir/$(echo "$default" | sed -e 's|-|/|')" ]; then
920
+ file="$dir/$(echo "$default" | sed -e 's|-|/|')"
921
+ fi
922
+
923
+ if [ -r "$file" ] ; then
924
+ command="$(get_key "${file}" "Exec" | first_word)"
925
+ if command -v "$command" >/dev/null; then
926
+ icon="$(get_key "${file}" "Icon")"
927
+ # FIXME: Actually LC_MESSAGES should be used as described in
928
+ # http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s04.html
929
+ localised_name="$(get_key "${file}" "Name")"
930
+ #shellcheck disable=SC2046 # Splitting is intentional here
931
+ set -- $(get_key "${file}" "Exec" | last_word)
932
+ # We need to replace any occurrence of "%f", "%F" and
933
+ # the like by the target file. We examine each
934
+ # argument and append the modified argument to the
935
+ # end then shift.
936
+ local args=$#
937
+ local replaced=0
938
+ while [ $args -gt 0 ]; do
939
+ case $1 in
940
+ %[c])
941
+ replaced=1
942
+ arg="${localised_name}"
943
+ shift
944
+ set -- "$@" "$arg"
945
+ ;;
946
+ %[fF])
947
+ # if there is only a target_url return,
948
+ # this application can't handle it.
949
+ [ -n "$target" ] || return
950
+ replaced=1
951
+ arg="$target"
952
+ shift
953
+ set -- "$@" "$arg"
954
+ ;;
955
+ %[uU])
956
+ replaced=1
957
+ # When an URI is requested use it,
958
+ # otherwise fall back to the filepath.
959
+ arg="${target_uri:-$target}"
960
+ shift
961
+ set -- "$@" "$arg"
962
+ ;;
963
+ %[i])
964
+ replaced=1
965
+ shift
966
+ set -- "$@" "--icon" "$icon"
967
+ ;;
968
+ *)
969
+ arg="$1"
970
+ shift
971
+ set -- "$@" "$arg"
972
+ ;;
973
+ esac
974
+ args=$(( args - 1 ))
975
+ done
976
+ [ $replaced -eq 1 ] || set -- "$@" "${target:-$target_uri}"
977
+ env "$command" "$@"
978
+ exit_success
979
+ fi
980
+ fi
981
+
982
+ for d in "$dir/"*/; do
983
+ [ -d "$d" ] && search_desktop_file "$default" "$d" "$target" "$target_uri"
984
+ done
985
+ }
986
+
987
+ # (file (or empty), mimetype, optional url)
988
+ open_generic_xdg_mime()
989
+ {
990
+ filetype="$2"
991
+ default="$(xdg-mime query default "$filetype")"
992
+ if [ -n "$default" ] ; then
993
+ xdg_user_dir="$XDG_DATA_HOME"
994
+ [ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share"
995
+
996
+ xdg_system_dirs="$XDG_DATA_DIRS"
997
+ [ -n "$xdg_system_dirs" ] || xdg_system_dirs=/usr/local/share/:/usr/share/
998
+
999
+ search_dirs="$xdg_user_dir:$xdg_system_dirs"
1000
+ DEBUG 3 "$search_dirs"
1001
+ old_ifs="$IFS"
1002
+ IFS=:
1003
+ for x in $search_dirs ; do
1004
+ IFS="$old_ifs"
1005
+ search_desktop_file "$default" "$x/applications/" "$1" "$3"
1006
+ done
1007
+ fi
1008
+ }
1009
+
1010
+ open_generic_xdg_x_scheme_handler()
1011
+ {
1012
+ scheme="$(echo "$1" | LC_ALL=C sed -n 's/\(^[[:alpha:]][[:alnum:]+\.-]*\):.*$/\1/p')"
1013
+ if [ -n "$scheme" ]; then
1014
+ filetype="x-scheme-handler/$scheme"
1015
+ open_generic_xdg_mime "" "$filetype" "$1"
1016
+ fi
1017
+ }
1018
+
1019
+ has_single_argument()
1020
+ {
1021
+ test $# = 1
1022
+ }
1023
+
1024
+ open_envvar()
1025
+ {
1026
+ local oldifs="$IFS"
1027
+ local browser
1028
+
1029
+ IFS=":"
1030
+ for browser in $BROWSER; do
1031
+ IFS="$oldifs"
1032
+
1033
+ if [ -z "$browser" ]; then
1034
+ continue
1035
+ fi
1036
+
1037
+ if echo "$browser" | grep -q %s; then
1038
+ # Avoid argument injection.
1039
+ # See https://bugs.freedesktop.org/show_bug.cgi?id=103807
1040
+ # URIs don't have IFS characters spaces anyway.
1041
+ # shellcheck disable=SC2086,SC2091,SC2059
1042
+ # All the scary things here are intentional
1043
+ has_single_argument $1 && $(printf "$browser" "$1")
1044
+ else
1045
+ $browser "$1"
1046
+ fi
1047
+
1048
+ if [ $? -eq 0 ]; then
1049
+ exit_success
1050
+ fi
1051
+ done
1052
+ }
1053
+
1054
+ open_wsl()
1055
+ {
1056
+ local win_path
1057
+ if is_file_url_or_path "$1" ; then
1058
+ win_path="$(file_url_to_path "$1")"
1059
+ win_path="$(wslpath -aw "$win_path")"
1060
+ [ $? -eq 0 ] || exit_failure_operation_failed
1061
+ explorer.exe "${win_path}"
1062
+ else
1063
+ rundll32.exe url.dll,FileProtocolHandler "$1"
1064
+ fi
1065
+
1066
+ if [ $? -eq 0 ]; then
1067
+ exit_success
1068
+ else
1069
+ exit_failure_operation_failed
1070
+ fi
1071
+ }
1072
+
1073
+ open_generic()
1074
+ {
1075
+ if is_file_url_or_path "$1"; then
1076
+ local file
1077
+ file="$(file_url_to_path "$1")"
1078
+
1079
+ check_input_file "$file"
1080
+
1081
+ if has_display; then
1082
+ filetype="$(xdg-mime query filetype "$file" | sed "s/;.*//")"
1083
+ # passing a path a url is okay too,
1084
+ # see desktop file specification for '%u'
1085
+ open_generic_xdg_mime "$file" "$filetype" "$1"
1086
+ fi
1087
+
1088
+ if command -v run-mailcap >/dev/null; then
1089
+ run-mailcap --action=view "$file"
1090
+ if [ $? -eq 0 ]; then
1091
+ exit_success
1092
+ fi
1093
+ fi
1094
+
1095
+ if has_display && mimeopen -v 2>/dev/null 1>&2; then
1096
+ mimeopen -L -n "$file"
1097
+ if [ $? -eq 0 ]; then
1098
+ exit_success
1099
+ fi
1100
+ fi
1101
+ fi
1102
+
1103
+ if has_display; then
1104
+ open_generic_xdg_x_scheme_handler "$1"
1105
+ fi
1106
+
1107
+ if [ -n "$BROWSER" ]; then
1108
+ open_envvar "$1"
1109
+ fi
1110
+
1111
+ # if BROWSER variable is not set, check some well known browsers instead
1112
+ if [ x"$BROWSER" = x"" ]; then
1113
+ BROWSER=www-browser:links2:elinks:links:lynx:w3m
1114
+ if has_display; then
1115
+ BROWSER=x-www-browser:firefox:iceweasel:seamonkey:mozilla:epiphany:konqueror:chromium:chromium-browser:google-chrome:$BROWSER
1116
+ fi
1117
+ fi
1118
+
1119
+ open_envvar "$1"
1120
+
1121
+ exit_failure_operation_impossible "no method available for opening '$1'"
1122
+ }
1123
+
1124
+ open_lxde()
1125
+ {
1126
+
1127
+ # pcmanfm only knows how to handle file:// urls and filepaths, it seems.
1128
+ if pcmanfm --help >/dev/null 2>&1 && is_file_url_or_path "$1"; then
1129
+ local file
1130
+ file="$(file_url_to_path "$1")"
1131
+
1132
+ # handle relative paths
1133
+ if ! echo "$file" | grep -q ^/; then
1134
+ file="$(pwd)/$file"
1135
+ fi
1136
+
1137
+ pcmanfm "$file"
1138
+ else
1139
+ open_generic "$1"
1140
+ fi
1141
+
1142
+ if [ $? -eq 0 ]; then
1143
+ exit_success
1144
+ else
1145
+ exit_failure_operation_failed
1146
+ fi
1147
+ }
1148
+
1149
+ open_lxqt()
1150
+ {
1151
+ if qtxdg-mat open --help 2>/dev/null 1>&2; then
1152
+ qtxdg-mat open "$1"
1153
+ else
1154
+ exit_failure_operation_impossible "no method available for opening '$1'"
1155
+ fi
1156
+
1157
+ if [ $? -eq 0 ]; then
1158
+ exit_success
1159
+ else
1160
+ exit_failure_operation_failed
1161
+ fi
1162
+ }
1163
+
1164
+ [ x"$1" != x"" ] || exit_failure_syntax
1165
+
1166
+ url=
1167
+ while [ $# -gt 0 ] ; do
1168
+ parm="$1"
1169
+ shift
1170
+
1171
+ case "$parm" in
1172
+ -*)
1173
+ exit_failure_syntax "unexpected option '$parm'"
1174
+ ;;
1175
+
1176
+ *)
1177
+ if [ -n "$url" ] ; then
1178
+ exit_failure_syntax "unexpected argument '$parm'"
1179
+ fi
1180
+ url="$parm"
1181
+ ;;
1182
+ esac
1183
+ done
1184
+
1185
+ if [ -z "${url}" ] ; then
1186
+ exit_failure_syntax "file or URL argument missing"
1187
+ fi
1188
+
1189
+ detectDE
1190
+
1191
+ if [ x"$DE" = x"" ]; then
1192
+ DE=generic
1193
+ fi
1194
+
1195
+ DEBUG 2 "Selected DE $DE"
1196
+
1197
+ # sanitize BROWSER (avoid calling ourselves in particular)
1198
+ case "${BROWSER}" in
1199
+ *:"xdg-open"|"xdg-open":*)
1200
+ BROWSER="$(echo "$BROWSER" | sed -e 's|:xdg-open||g' -e 's|xdg-open:||g')"
1201
+ ;;
1202
+ "xdg-open")
1203
+ BROWSER=
1204
+ ;;
1205
+ esac
1206
+
1207
+ case "$DE" in
1208
+ kde)
1209
+ open_kde "$url"
1210
+ ;;
1211
+
1212
+ deepin)
1213
+ open_deepin "$url"
1214
+ ;;
1215
+
1216
+ gnome3|cinnamon)
1217
+ open_gnome3 "$url"
1218
+ ;;
1219
+
1220
+ gnome)
1221
+ open_gnome "$url"
1222
+ ;;
1223
+
1224
+ mate)
1225
+ open_mate "$url"
1226
+ ;;
1227
+
1228
+ xfce)
1229
+ open_xfce "$url"
1230
+ ;;
1231
+
1232
+ lxde)
1233
+ open_lxde "$url"
1234
+ ;;
1235
+
1236
+ lxqt)
1237
+ open_lxqt "$url"
1238
+ ;;
1239
+
1240
+ enlightenment)
1241
+ open_enlightenment "$url"
1242
+ ;;
1243
+
1244
+ cygwin)
1245
+ open_cygwin "$url"
1246
+ ;;
1247
+
1248
+ darwin)
1249
+ open_darwin "$url"
1250
+ ;;
1251
+
1252
+ flatpak)
1253
+ open_flatpak "$url"
1254
+ ;;
1255
+
1256
+ wsl)
1257
+ open_wsl "$url"
1258
+ ;;
1259
+
1260
+ generic)
1261
+ open_generic "$url"
1262
+ ;;
1263
+
1264
+ *)
1265
+ exit_failure_operation_impossible "no method available for opening '$url'"
1266
+ ;;
1267
+ esac