xdg-open 21 KB

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