UNPKG

21.4 kBPlain TextView Raw
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
36manualpage()
37{
38cat << _MANUALPAGE
39Name
40
41 xdg-open - opens a file or URL in the user's preferred
42 application
43
44Synopsis
45
46 xdg-open { file | URL }
47
48 xdg-open { --help | --manual | --version }
49
50Description
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
61Options
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
72Exit 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
90Examples
91
92xdg-open 'http://www.freedesktop.org/'
93
94 Opens the freedesktop.org website in the user's default
95 browser.
96
97xdg-open /tmp/foobar.png
98
99 Opens the PNG image file /tmp/foobar.png in the user's default
100 image viewing application.
101_MANUALPAGE
102}
103
104usage()
105{
106cat << _USAGE
107 xdg-open - opens a file or URL in the user's preferred
108 application
109
110Synopsis
111
112 xdg-open { file | URL }
113
114 xdg-open { --help | --manual | --version }
115
116_USAGE
117}
118
119#@xdg-utils-common@
120
121#----------------------------------------------------------------------------
122# Common utility functions included in all XDG wrapper scripts
123#----------------------------------------------------------------------------
124
125DEBUG()
126{
127 [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && return 0;
128 [ ${XDG_UTILS_DEBUG_LEVEL} -lt $1 ] && return 0;
129 shift
130 echo "$@" >&2
131}
132
133# This handles backslashes but not quote marks.
134first_word()
135{
136 read first rest
137 echo "$first"
138}
139
140#-------------------------------------------------------------
141# map a binary to a .desktop file
142binary_to_desktop_file()
143{
144 search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
145 binary="`which "$1"`"
146 binary="`readlink -f "$binary"`"
147 base="`basename "$binary"`"
148 IFS=:
149 for dir in $search; do
150 unset IFS
151 [ "$dir" ] || continue
152 [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue
153 for file in "$dir"/applications/*.desktop "$dir"/applications/*/*.desktop "$dir"/applnk/*.desktop "$dir"/applnk/*/*.desktop; do
154 [ -r "$file" ] || continue
155 # Check to make sure it's worth the processing.
156 grep -q "^Exec.*$base" "$file" || continue
157 # Make sure it's a visible desktop file (e.g. not "preferred-web-browser.desktop").
158 grep -Eq "^(NoDisplay|Hidden)=true" "$file" && continue
159 command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`"
160 command="`which "$command"`"
161 if [ x"`readlink -f "$command"`" = x"$binary" ]; then
162 # Fix any double slashes that got added path composition
163 echo "$file" | sed -e 's,//*,/,g'
164 return
165 fi
166 done
167 done
168}
169
170#-------------------------------------------------------------
171# map a .desktop file to a binary
172## FIXME: handle vendor dir case
173desktop_file_to_binary()
174{
175 search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
176 desktop="`basename "$1"`"
177 IFS=:
178 for dir in $search; do
179 unset IFS
180 [ "$dir" ] && [ -d "$dir/applications" ] || continue
181 file="$dir/applications/$desktop"
182 [ -r "$file" ] || continue
183 # Remove any arguments (%F, %f, %U, %u, etc.).
184 command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`"
185 command="`which "$command"`"
186 readlink -f "$command"
187 return
188 done
189}
190
191#-------------------------------------------------------------
192# Exit script on successfully completing the desired operation
193
194exit_success()
195{
196 if [ $# -gt 0 ]; then
197 echo "$@"
198 echo
199 fi
200
201 exit 0
202}
203
204
205#-----------------------------------------
206# Exit script on malformed arguments, not enough arguments
207# or missing required option.
208# prints usage information
209
210exit_failure_syntax()
211{
212 if [ $# -gt 0 ]; then
213 echo "xdg-open: $@" >&2
214 echo "Try 'xdg-open --help' for more information." >&2
215 else
216 usage
217 echo "Use 'man xdg-open' or 'xdg-open --manual' for additional info."
218 fi
219
220 exit 1
221}
222
223#-------------------------------------------------------------
224# Exit script on missing file specified on command line
225
226exit_failure_file_missing()
227{
228 if [ $# -gt 0 ]; then
229 echo "xdg-open: $@" >&2
230 fi
231
232 exit 2
233}
234
235#-------------------------------------------------------------
236# Exit script on failure to locate necessary tool applications
237
238exit_failure_operation_impossible()
239{
240 if [ $# -gt 0 ]; then
241 echo "xdg-open: $@" >&2
242 fi
243
244 exit 3
245}
246
247#-------------------------------------------------------------
248# Exit script on failure returned by a tool application
249
250exit_failure_operation_failed()
251{
252 if [ $# -gt 0 ]; then
253 echo "xdg-open: $@" >&2
254 fi
255
256 exit 4
257}
258
259#------------------------------------------------------------
260# Exit script on insufficient permission to read a specified file
261
262exit_failure_file_permission_read()
263{
264 if [ $# -gt 0 ]; then
265 echo "xdg-open: $@" >&2
266 fi
267
268 exit 5
269}
270
271#------------------------------------------------------------
272# Exit script on insufficient permission to write a specified file
273
274exit_failure_file_permission_write()
275{
276 if [ $# -gt 0 ]; then
277 echo "xdg-open: $@" >&2
278 fi
279
280 exit 6
281}
282
283check_input_file()
284{
285 if [ ! -e "$1" ]; then
286 exit_failure_file_missing "file '$1' does not exist"
287 fi
288 if [ ! -r "$1" ]; then
289 exit_failure_file_permission_read "no permission to read file '$1'"
290 fi
291}
292
293check_vendor_prefix()
294{
295 file_label="$2"
296 [ -n "$file_label" ] || file_label="filename"
297 file=`basename "$1"`
298 case "$file" in
299 [[:alpha:]]*-*)
300 return
301 ;;
302 esac
303
304 echo "xdg-open: $file_label '$file' does not have a proper vendor prefix" >&2
305 echo 'A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated' >&2
306 echo 'with a dash ("-"). An example '"$file_label"' is '"'example-$file'" >&2
307 echo "Use --novendor to override or 'xdg-open --manual' for additional info." >&2
308 exit 1
309}
310
311check_output_file()
312{
313 # if the file exists, check if it is writeable
314 # if it does not exist, check if we are allowed to write on the directory
315 if [ -e "$1" ]; then
316 if [ ! -w "$1" ]; then
317 exit_failure_file_permission_write "no permission to write to file '$1'"
318 fi
319 else
320 DIR=`dirname "$1"`
321 if [ ! -w "$DIR" ] || [ ! -x "$DIR" ]; then
322 exit_failure_file_permission_write "no permission to create file '$1'"
323 fi
324 fi
325}
326
327#----------------------------------------
328# Checks for shared commands, e.g. --help
329
330check_common_commands()
331{
332 while [ $# -gt 0 ] ; do
333 parm="$1"
334 shift
335
336 case "$parm" in
337 --help)
338 usage
339 echo "Use 'man xdg-open' or 'xdg-open --manual' for additional info."
340 exit_success
341 ;;
342
343 --manual)
344 manualpage
345 exit_success
346 ;;
347
348 --version)
349 echo "xdg-open 1.1.0 rc3"
350 exit_success
351 ;;
352 esac
353 done
354}
355
356check_common_commands "$@"
357
358[ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && unset XDG_UTILS_DEBUG_LEVEL;
359if [ ${XDG_UTILS_DEBUG_LEVEL-0} -lt 1 ]; then
360 # Be silent
361 xdg_redirect_output=" > /dev/null 2> /dev/null"
362else
363 # All output to stderr
364 xdg_redirect_output=" >&2"
365fi
366
367#--------------------------------------
368# Checks for known desktop environments
369# set variable DE to the desktop environments name, lowercase
370
371detectDE()
372{
373 # see https://bugs.freedesktop.org/show_bug.cgi?id=34164
374 unset GREP_OPTIONS
375
376 if [ -n "${XDG_CURRENT_DESKTOP}" ]; then
377 case "${XDG_CURRENT_DESKTOP}" in
378 ENLIGHTENMENT)
379 DE=enlightenment;
380 ;;
381 GNOME)
382 DE=gnome;
383 ;;
384 KDE)
385 DE=kde;
386 ;;
387 LXDE)
388 DE=lxde;
389 ;;
390 MATE)
391 DE=mate;
392 ;;
393 XFCE)
394 DE=xfce
395 ;;
396 esac
397 fi
398
399 if [ x"$DE" = x"" ]; then
400 # classic fallbacks
401 if [ x"$KDE_FULL_SESSION" != x"" ]; then DE=kde;
402 elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome;
403 elif [ x"$MATE_DESKTOP_SESSION_ID" != x"" ]; then DE=mate;
404 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;
405 elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce;
406 elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then DE=xfce
407 elif echo $DESKTOP | grep -q '^Enlightenment'; then DE=enlightenment;
408 fi
409 fi
410
411 if [ x"$DE" = x"" ]; then
412 # fallback to checking $DESKTOP_SESSION
413 case "$DESKTOP_SESSION" in
414 gnome)
415 DE=gnome;
416 ;;
417 LXDE|Lubuntu)
418 DE=lxde;
419 ;;
420 MATE)
421 DE=mate;
422 ;;
423 xfce|xfce4|'Xfce Session')
424 DE=xfce;
425 ;;
426 esac
427 fi
428
429 if [ x"$DE" = x"" ]; then
430 # fallback to uname output for other platforms
431 case "$(uname 2>/dev/null)" in
432 Darwin)
433 DE=darwin;
434 ;;
435 esac
436 fi
437
438 if [ x"$DE" = x"gnome" ]; then
439 # gnome-default-applications-properties is only available in GNOME 2.x
440 # but not in GNOME 3.x
441 which gnome-default-applications-properties > /dev/null 2>&1 || DE="gnome3"
442 fi
443}
444
445#----------------------------------------------------------------------------
446# kfmclient exec/openURL can give bogus exit value in KDE <= 3.5.4
447# It also always returns 1 in KDE 3.4 and earlier
448# Simply return 0 in such case
449
450kfmclient_fix_exit_code()
451{
452 version=`LC_ALL=C.UTF-8 kde-config --version 2>/dev/null | grep '^KDE'`
453 major=`echo $version | sed 's/KDE.*: \([0-9]\).*/\1/'`
454 minor=`echo $version | sed 's/KDE.*: [0-9]*\.\([0-9]\).*/\1/'`
455 release=`echo $version | sed 's/KDE.*: [0-9]*\.[0-9]*\.\([0-9]\).*/\1/'`
456 test "$major" -gt 3 && return $1
457 test "$minor" -gt 5 && return $1
458 test "$release" -gt 4 && return $1
459 return 0
460}
461
462# This handles backslashes but not quote marks.
463last_word()
464{
465 read first rest
466 echo "$rest"
467}
468
469# Get the value of a key in a desktop file's Desktop Entry group.
470# Example: Use get_key foo.desktop Exec
471# to get the values of the Exec= key for the Desktop Entry group.
472get_key()
473{
474 local file="${1}"
475 local key="${2}"
476 local desktop_entry=""
477
478 IFS_="${IFS}"
479 IFS=""
480 while read line
481 do
482 case "$line" in
483 "[Desktop Entry]")
484 desktop_entry="y"
485 ;;
486 # Reset match flag for other groups
487 "["*)
488 desktop_entry=""
489 ;;
490 "${key}="*)
491 # Only match Desktop Entry group
492 if [ -n "${desktop_entry}" ]
493 then
494 echo "${line}" | cut -d= -f 2-
495 fi
496 esac
497 done < "${file}"
498 IFS="${IFS_}"
499}
500
501open_darwin()
502{
503 open "$1"
504
505 if [ $? -eq 0 ]; then
506 exit_success
507 else
508 exit_failure_operation_failed
509 fi
510}
511
512open_kde()
513{
514 if [ -n "${KDE_SESSION_VERSION}" ]; then
515 case "${KDE_SESSION_VERSION}" in
516 4)
517 kde-open "$1"
518 ;;
519 5)
520 kde-open${KDE_SESSION_VERSION} "$1"
521 ;;
522 esac
523 else
524 kfmclient exec "$1"
525 kfmclient_fix_exit_code $?
526 fi
527
528 if [ $? -eq 0 ]; then
529 exit_success
530 else
531 exit_failure_operation_failed
532 fi
533}
534
535open_gnome()
536{
537 if gvfs-open --help 2>/dev/null 1>&2; then
538 gvfs-open "$1"
539 else
540 gnome-open "$1"
541 fi
542
543 if [ $? -eq 0 ]; then
544 exit_success
545 else
546 exit_failure_operation_failed
547 fi
548}
549
550open_mate()
551{
552 if gvfs-open --help 2>/dev/null 1>&2; then
553 gvfs-open "$1"
554 else
555 mate-open "$1"
556 fi
557
558 if [ $? -eq 0 ]; then
559 exit_success
560 else
561 exit_failure_operation_failed
562 fi
563}
564
565open_xfce()
566{
567 exo-open "$1"
568
569 if [ $? -eq 0 ]; then
570 exit_success
571 else
572 exit_failure_operation_failed
573 fi
574}
575
576open_enlightenment()
577{
578 enlightenment_open "$1"
579
580 if [ $? -eq 0 ]; then
581 exit_success
582 else
583 exit_failure_operation_failed
584 fi
585}
586
587#-----------------------------------------
588# Recursively search .desktop file
589
590search_desktop_file()
591{
592 local default="$1"
593 local dir="$2"
594 local target="$3"
595
596 local file=""
597 # look for both vendor-app.desktop, vendor/app.desktop
598 if [ -r "$dir/$default" ]; then
599 file="$dir/$default"
600 elif [ -r "$dir/`echo $default | sed -e 's|-|/|'`" ]; then
601 file="$dir/`echo $default | sed -e 's|-|/|'`"
602 fi
603
604 if [ -r "$file" ] ; then
605 command="$(get_key "${file}" "Exec" | first_word)"
606 command_exec=`which $command 2>/dev/null`
607 icon="$(get_key "${file}" "Icon")"
608 # FIXME: Actually LC_MESSAGES should be used as described in
609 # http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s04.html
610 localised_name="$(get_key "${file}" "Name")"
611 set -- $(get_key "${file}" "Exec" | last_word)
612 # We need to replace any occurrence of "%f", "%F" and
613 # the like by the target file. We examine each
614 # argument and append the modified argument to the
615 # end then shift.
616 local args=$#
617 local replaced=0
618 while [ $args -gt 0 ]; do
619 case $1 in
620 %[c])
621 replaced=1
622 arg="${localised_name}"
623 shift
624 set -- "$@" "$arg"
625 ;;
626 %[fFuU])
627 replaced=1
628 arg="$target"
629 shift
630 set -- "$@" "$arg"
631 ;;
632 %[i])
633 replaced=1
634 shift
635 set -- "$@" "--icon" "$icon"
636 ;;
637 *)
638 arg="$1"
639 shift
640 set -- "$@" "$arg"
641 ;;
642 esac
643 args=$(( $args - 1 ))
644 done
645 [ $replaced -eq 1 ] || set -- "$@" "$target"
646 "$command_exec" "$@"
647
648 if [ $? -eq 0 ]; then
649 exit_success
650 fi
651 fi
652
653 for d in $dir/*/; do
654 [ -d "$d" ] && search_desktop_file "$default" "$d" "$target"
655 done
656}
657
658
659open_generic_xdg_mime()
660{
661 filetype="$2"
662 default=`xdg-mime query default "$filetype"`
663 if [ -n "$default" ] ; then
664 xdg_user_dir="$XDG_DATA_HOME"
665 [ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share"
666
667 xdg_system_dirs="$XDG_DATA_DIRS"
668 [ -n "$xdg_system_dirs" ] || xdg_system_dirs=/usr/local/share/:/usr/share/
669
670DEBUG 3 "$xdg_user_dir:$xdg_system_dirs"
671 for x in `echo "$xdg_user_dir:$xdg_system_dirs" | sed 's/:/ /g'`; do
672 search_desktop_file "$default" "$x/applications/" "$1"
673 done
674 fi
675}
676
677open_generic_xdg_file_mime()
678{
679 filetype=`xdg-mime query filetype "$1" | sed "s/;.*//"`
680 open_generic_xdg_mime "$1" "$filetype"
681}
682
683open_generic_xdg_x_scheme_handler()
684{
685 scheme="`echo $1 | sed -n 's/\(^[[:alnum:]+\.-]*\):.*$/\1/p'`"
686 if [ -n $scheme ]; then
687 filetype="x-scheme-handler/$scheme"
688 open_generic_xdg_mime "$1" "$filetype"
689 fi
690}
691
692open_generic()
693{
694 # Paths or file:// URLs
695 if (echo "$1" | grep -q '^file://' ||
696 ! echo "$1" | egrep -q '^[[:alpha:]+\.\-]+:'); then
697
698 local file="$1"
699
700 # Decode URLs
701 if echo "$file" | grep -q '^file:///'; then
702 file=${file#file://}
703 file="$(printf "$(echo "$file" | sed -e 's@%\([a-f0-9A-F]\{2\}\)@\\x\1@g')")"
704 fi
705 file_check=${file%%#*}
706 file_check=${file_check%%\?*}
707 check_input_file "$file_check"
708
709 filetype=`xdg-mime query filetype "$file_check" | sed "s/;.*//"`
710 open_generic_xdg_mime "$file" "$filetype"
711
712 if which run-mailcap 2>/dev/null 1>&2; then
713 run-mailcap --action=view "$file"
714 if [ $? -eq 0 ]; then
715 exit_success
716 fi
717 fi
718
719 if mimeopen -v 2>/dev/null 1>&2; then
720 mimeopen -L -n "$file"
721 if [ $? -eq 0 ]; then
722 exit_success
723 fi
724 fi
725 fi
726
727 open_generic_xdg_x_scheme_handler "$1"
728
729 IFS=":"
730 for browser in $BROWSER; do
731 if [ x"$browser" != x"" ]; then
732
733 browser_with_arg=`printf "$browser" "$1" 2>/dev/null`
734 if [ $? -ne 0 ]; then
735 browser_with_arg=$browser;
736 fi
737
738 if [ x"$browser_with_arg" = x"$browser" ]; then
739 eval '$browser "$1"'$xdg_redirect_output;
740 else eval '$browser_with_arg'$xdg_redirect_output;
741 fi
742
743 if [ $? -eq 0 ]; then
744 exit_success;
745 fi
746 fi
747 done
748
749 exit_failure_operation_impossible "no method available for opening '$1'"
750}
751
752open_lxde()
753{
754 # pcmanfm only knows how to handle file:// urls and filepaths, it seems.
755 if (echo "$1" | grep -q '^file://' ||
756 ! echo "$1" | egrep -q '^[[:alpha:]+\.\-]+:')
757 then
758 local file="$1"
759
760 # handle relative paths
761 if ! echo "$file" | egrep -q '^(file://)?/'; then
762 file="$(pwd)/$file"
763 fi
764
765 pcmanfm "$file"
766
767 else
768 open_generic "$1"
769 fi
770
771 if [ $? -eq 0 ]; then
772 exit_success
773 else
774 exit_failure_operation_failed
775 fi
776}
777
778[ x"$1" != x"" ] || exit_failure_syntax
779
780url=
781while [ $# -gt 0 ] ; do
782 parm="$1"
783 shift
784
785 case "$parm" in
786 -*)
787 exit_failure_syntax "unexpected option '$parm'"
788 ;;
789
790 *)
791 if [ -n "$url" ] ; then
792 exit_failure_syntax "unexpected argument '$parm'"
793 fi
794 url="$parm"
795 ;;
796 esac
797done
798
799if [ -z "${url}" ] ; then
800 exit_failure_syntax "file or URL argument missing"
801fi
802
803detectDE
804
805if [ x"$DE" = x"" ]; then
806 DE=generic
807fi
808
809DEBUG 2 "Selected DE $DE"
810
811# sanitize BROWSER (avoid caling ourselves in particular)
812case "${BROWSER}" in
813 *:"xdg-open"|"xdg-open":*)
814 BROWSER=$(echo $BROWSER | sed -e 's|:xdg-open||g' -e 's|xdg-open:||g')
815 ;;
816 "xdg-open")
817 BROWSER=
818 ;;
819esac
820
821# if BROWSER variable is not set, check some well known browsers instead
822if [ x"$BROWSER" = x"" ]; then
823 BROWSER=links2:elinks:links:lynx:w3m
824 if [ -n "$DISPLAY" ]; then
825 BROWSER=x-www-browser:firefox:seamonkey:mozilla:epiphany:konqueror:chromium-browser:google-chrome:$BROWSER
826 fi
827fi
828
829case "$DE" in
830 kde)
831 open_kde "$url"
832 ;;
833
834 gnome*)
835 open_gnome "$url"
836 ;;
837
838 mate)
839 open_mate "$url"
840 ;;
841
842 xfce)
843 open_xfce "$url"
844 ;;
845
846 lxde)
847 open_lxde "$url"
848 ;;
849
850 enlightenment)
851 open_enlightenment "$url"
852 ;;
853
854 generic)
855 open_generic "$url"
856 ;;
857
858 *)
859 exit_failure_operation_impossible "no method available for opening '$url'"
860 ;;
861esac