home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / bin / xdg-settings < prev    next >
Encoding:
Text File  |  2010-09-15  |  24.5 KB  |  871 lines

  1. #!/bin/sh
  2. #---------------------------------------------
  3. #   xdg-settings
  4. #
  5. #   Utility script to get various settings from the desktop environment.
  6. #
  7. #   Refer to the usage() function below for usage.
  8. #
  9. #   Copyright 2009, Google Inc.
  10. #
  11. #   LICENSE:
  12. #
  13. #   Permission is hereby granted, free of charge, to any person obtaining a
  14. #   copy of this software and associated documentation files (the "Software"),
  15. #   to deal in the Software without restriction, including without limitation
  16. #   the rights to use, copy, modify, merge, publish, distribute, sublicense,
  17. #   and/or sell copies of the Software, and to permit persons to whom the
  18. #   Software is furnished to do so, subject to the following conditions:
  19. #
  20. #   The above copyright notice and this permission notice shall be included
  21. #   in all copies or substantial portions of the Software.
  22. #
  23. #   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  24. #   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  25. #   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  26. #   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  27. #   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  28. #   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  29. #   OTHER DEALINGS IN THE SOFTWARE.
  30. #
  31. #---------------------------------------------
  32.  
  33. manualpage()
  34. {
  35. cat << _MANUALPAGE
  36. Name
  37.  
  38. xdg-settings - get various settings from the desktop environment
  39.  
  40. Synopsis
  41.  
  42. xdg-settings { get | check | set } {property} [value]
  43.  
  44. xdg-settings { --help | --list | --manual | --version }
  45.  
  46. Description
  47.  
  48. xdg-settings gets various settings from the desktop environment. For instance,
  49. desktop environments often provide proxy configuration and default web browser
  50. settings. Using xdg-settings these parameters can be extracted for use by
  51. applications that do not use the desktop environment's libraries (which would
  52. use the settings natively).
  53.  
  54. xdg-settings is for use inside a desktop session only. It is not recommended to
  55. use xdg-settings as root.
  56.  
  57. Options
  58.  
  59. --help
  60.     Show command synopsis.
  61. --list
  62.     List all properties xdg-settings knows about.
  63. --manual
  64.     Show this manualpage.
  65. --version
  66.     Show the xdg-utils version information.
  67.  
  68. Exit Codes
  69.  
  70. An exit code of 0 indicates success while a non-zero exit code indicates
  71. failure. The following failure codes can be returned:
  72.  
  73. 1
  74.     Error in command line syntax.
  75. 2
  76.     One of the files passed on the command line did not exist.
  77. 3
  78.     A required tool could not be found.
  79. 4
  80.     The action failed.
  81.  
  82. Examples
  83.  
  84. Get the desktop file name of the current default web browser
  85.  
  86.         xdg-settings get default-web-browser
  87.  
  88.  
  89. Check whether the default web browser is firefox.desktop, which can be false
  90. even if "get default-web-browser" says that is the current value (if only some
  91. of the underlying settings actually reflect that value)
  92.  
  93.         xdg-settings check default-web-browser firefox.desktop
  94.  
  95.  
  96. Set the default web browser to google-chrome.desktop
  97.  
  98.         xdg-settings set default-web-browser google-chrome.desktop
  99.  
  100.  
  101. _MANUALPAGE
  102. }
  103.  
  104. usage()
  105. {
  106. cat << _USAGE
  107. xdg-settings - get various settings from the desktop environment
  108.  
  109. Synopsis
  110.  
  111. xdg-settings { get | check | set } {property} [value]
  112.  
  113. xdg-settings { --help | --list | --manual | --version }
  114.  
  115. _USAGE
  116. }
  117.  
  118. #@xdg-utils-common@
  119.  
  120. #----------------------------------------------------------------------------
  121. #   Common utility functions included in all XDG wrapper scripts
  122. #----------------------------------------------------------------------------
  123.  
  124. DEBUG()
  125. {
  126.   [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && return 0;
  127.   [ ${XDG_UTILS_DEBUG_LEVEL} -lt $1 ] && return 0;
  128.   shift
  129.   echo "$@" >&2
  130. }
  131.  
  132. #-------------------------------------------------------------
  133. # Exit script on successfully completing the desired operation
  134.  
  135. exit_success()
  136. {
  137.     if [ $# -gt 0 ]; then
  138.         echo "$@"
  139.         echo
  140.     fi
  141.  
  142.     exit 0
  143. }
  144.  
  145.  
  146. #-----------------------------------------
  147. # Exit script on malformed arguments, not enough arguments
  148. # or missing required option.
  149. # prints usage information
  150.  
  151. exit_failure_syntax()
  152. {
  153.     if [ $# -gt 0 ]; then
  154.         echo "xdg-settings: $@" >&2
  155.         echo "Try 'xdg-settings --help' for more information." >&2
  156.     else
  157.         usage
  158.         echo "Use 'man xdg-settings' or 'xdg-settings --manual' for additional info."
  159.     fi
  160.  
  161.     exit 1
  162. }
  163.  
  164. #-------------------------------------------------------------
  165. # Exit script on missing file specified on command line
  166.  
  167. exit_failure_file_missing()
  168. {
  169.     if [ $# -gt 0 ]; then
  170.         echo "xdg-settings: $@" >&2
  171.     fi
  172.  
  173.     exit 2
  174. }
  175.  
  176. #-------------------------------------------------------------
  177. # Exit script on failure to locate necessary tool applications
  178.  
  179. exit_failure_operation_impossible()
  180. {
  181.     if [ $# -gt 0 ]; then
  182.         echo "xdg-settings: $@" >&2
  183.     fi
  184.  
  185.     exit 3
  186. }
  187.  
  188. #-------------------------------------------------------------
  189. # Exit script on failure returned by a tool application
  190.  
  191. exit_failure_operation_failed()
  192. {
  193.     if [ $# -gt 0 ]; then
  194.         echo "xdg-settings: $@" >&2
  195.     fi
  196.  
  197.     exit 4
  198. }
  199.  
  200. #------------------------------------------------------------
  201. # Exit script on insufficient permission to read a specified file
  202.  
  203. exit_failure_file_permission_read()
  204. {
  205.     if [ $# -gt 0 ]; then
  206.         echo "xdg-settings: $@" >&2
  207.     fi
  208.  
  209.     exit 5
  210. }
  211.  
  212. #------------------------------------------------------------
  213. # Exit script on insufficient permission to write a specified file
  214.  
  215. exit_failure_file_permission_write()
  216. {
  217.     if [ $# -gt 0 ]; then
  218.         echo "xdg-settings: $@" >&2
  219.     fi
  220.  
  221.     exit 6
  222. }
  223.  
  224. check_input_file()
  225. {
  226.     if [ ! -e "$1" ]; then
  227.         exit_failure_file_missing "file '$1' does not exist"
  228.     fi
  229.     if [ ! -r "$1" ]; then
  230.         exit_failure_file_permission_read "no permission to read file '$1'"
  231.     fi
  232. }
  233.  
  234. check_vendor_prefix()
  235. {
  236.     file_label="$2"
  237.     [ -n "$file_label" ] || file_label="filename"
  238.     file=`basename "$1"`
  239.     case "$file" in
  240.        [a-zA-Z]*-*)
  241.          return
  242.          ;;
  243.     esac
  244.  
  245.     echo "xdg-settings: $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-settings --manual' for additional info." >&2
  249.     exit 1
  250. }
  251.  
  252. check_output_file()
  253. {
  254.     # if the file exists, check if it is writeable
  255.     # if it does not exists, check if we are allowed to write on the directory
  256.     if [ -e "$1" ]; then
  257.         if [ ! -w "$1" ]; then
  258.             exit_failure_file_permission_write "no permission to write to file '$1'"
  259.         fi
  260.     else
  261.         DIR=`dirname "$1"`
  262.         if [ ! -w "$DIR" -o ! -x "$DIR" ]; then
  263.             exit_failure_file_permission_write "no permission to create file '$1'"
  264.         fi
  265.     fi
  266. }
  267.  
  268. #----------------------------------------
  269. # Checks for shared commands, e.g. --help
  270.  
  271. check_common_commands()
  272. {
  273.     while [ $# -gt 0 ] ; do
  274.         parm="$1"
  275.         shift
  276.  
  277.         case "$parm" in
  278.             --help)
  279.             usage
  280.             echo "Use 'man xdg-settings' or 'xdg-settings --manual' for additional info."
  281.             exit_success
  282.             ;;
  283.  
  284.             --manual)
  285.             manualpage
  286.             exit_success
  287.             ;;
  288.  
  289.             --version)
  290.             echo "xdg-settings 1.0.2"
  291.             exit_success
  292.             ;;
  293.         esac
  294.     done
  295. }
  296.  
  297. check_common_commands "$@"
  298.  
  299. [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && unset XDG_UTILS_DEBUG_LEVEL;
  300. if [ ${XDG_UTILS_DEBUG_LEVEL-0} -lt 1 ]; then
  301.     # Be silent
  302.     xdg_redirect_output=" > /dev/null 2> /dev/null"
  303. else
  304.     # All output to stderr
  305.     xdg_redirect_output=" >&2"
  306. fi
  307.  
  308. #--------------------------------------
  309. # Checks for known desktop environments
  310. # set variable DE to the desktop environments name, lowercase
  311.  
  312. detectDE()
  313. {
  314.     if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde;
  315.     elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome;
  316.     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;
  317.     elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce;
  318.     fi
  319. }
  320.  
  321. #----------------------------------------------------------------------------
  322. # kfmclient exec/openURL can give bogus exit value in KDE <= 3.5.4
  323. # It also always returns 1 in KDE 3.4 and earlier
  324. # Simply return 0 in such case
  325.  
  326. kfmclient_fix_exit_code()
  327. {
  328.     version=`kde${KDE_SESSION_VERSION}-config --version 2>/dev/null | grep KDE`
  329.     major=`echo $version | sed 's/KDE: \([0-9]\).*/\1/'`
  330.     minor=`echo $version | sed 's/KDE: [0-9]*\.\([0-9]\).*/\1/'`
  331.     release=`echo $version | sed 's/KDE: [0-9]*\.[0-9]*\.\([0-9]\).*/\1/'`
  332.     test "$major" -gt 3 && return $1
  333.     test "$minor" -gt 5 && return $1
  334.     test "$release" -gt 4 && return $1
  335.     return 0
  336. }
  337.  
  338. check_desktop_filename()
  339. {
  340.     case "$1" in
  341.       */*)
  342.         exit_failure_syntax "invalid application name"
  343.         ;;
  344.       *.desktop)
  345.         return
  346.         ;;
  347.       *)
  348.         exit_failure_syntax "invalid application name"
  349.         ;;
  350.     esac
  351. }
  352.  
  353. # {{{ default browser
  354. # {{{ utility functions
  355.  
  356. # This handles backslashes but not quote marks.
  357. first_word()
  358. {
  359.     read first rest
  360.     echo "$first"
  361. }
  362.  
  363. binary_to_desktop_file()
  364. {
  365.     search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
  366.     binary="`which "$1"`"
  367.     binary="`readlink -f "$binary"`"
  368.     base="`basename "$binary"`"
  369.     IFS=:
  370.     for dir in $search; do
  371.         unset IFS
  372.         [ "$dir" ] || continue
  373.         [ -d "$dir/applications" -o -d "$dir/applnk" ] || continue
  374.         for file in "$dir"/applications/*.desktop "$dir"/applnk/*.desktop; do
  375.             [ -r "$file" ] || continue
  376.             # Check to make sure it's worth the processing.
  377.             grep -q "^Exec.*$base" "$file" || continue
  378.             # Make sure it's a visible desktop file (e.g. not "preferred-web-browser.desktop").
  379.             grep -Eq "^(NoDisplay|Hidden)=true" "$file" && continue
  380.             command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`"
  381.             command="`which "$command"`"
  382.             if [ x"`readlink -f "$command"`" = x"$binary" ]; then
  383.                 # Fix any double slashes that got added path composition
  384.                 echo "$file" | sed -e 's,//*,/,g'
  385.                 return
  386.             fi
  387.         done
  388.     done
  389. }
  390.  
  391. desktop_file_to_binary()
  392. {
  393.     search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
  394.     desktop="`basename "$1"`"
  395.     IFS=:
  396.     for dir in $search; do
  397.         unset IFS
  398.         [ "$dir" -a -d "$dir/applications" ] || continue
  399.         file="$dir/applications/$desktop"
  400.         [ -r "$file" ] || continue
  401.         # Remove any arguments (%F, %f, %U, %u, etc.).
  402.         command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`"
  403.         command="`which "$command"`"
  404.         readlink -f "$command"
  405.         return
  406.     done
  407. }
  408.  
  409. # In order to remove an application from the automatically-generated list of
  410. # applications for handling a given MIME type, the desktop environment may copy
  411. # the global .desktop file into the user's .local directory, and remove that
  412. # MIME type from its list. In that case, we must restore the MIME type to the
  413. # application's list of MIME types before we can set it as the default for that
  414. # MIME type. (We can't just delete the local version, since the user may have
  415. # made other changes to it as well. So, tweak the existing file.)
  416. # This function is hard-coded for text/html but it could be adapted if needed.
  417. fix_local_desktop_file()
  418. {
  419.     apps="${XDG_DATA_HOME:-$HOME/.local/share}/applications"
  420.     # No local desktop file?
  421.     [ ! -f "$apps/$1" ] && return
  422.     MIME="`grep "^MimeType=" "$apps/$1" | cut -d= -f 2-`"
  423.     case "$MIME" in
  424.       text/html\;*|*\;text/html\;*|*\;text/html\;|*\;text/html)
  425.         # Already has text/html? Great!
  426.         return 0
  427.         ;;
  428.     esac
  429.  
  430.     # Add text/html to the list
  431.     temp="`mktemp "$apps/$1.XXXXXX"`" || return
  432.     grep -v "^MimeType=" "$apps/$1" >> "$temp"
  433.     echo "MimeType=text/html;$MIME" >> "$temp"
  434.  
  435.     oldlines="`wc -l < "$apps/$1"`"
  436.     newlines="`wc -l < "$temp"`"
  437.     # The new file should have at least as many lines as the old.
  438.     if [ $oldlines -le $newlines ]; then
  439.         mv "$temp" "$apps/$1"
  440.         # This can take a little bit to get noticed.
  441.         sleep 4
  442.     else
  443.         rm -f "$temp"
  444.         return 1
  445.     fi
  446. }
  447.  
  448. # }}} utility functions
  449. # {{{ MIME utilities
  450.  
  451. xdg_mime_fixup()
  452. {
  453.     # xdg-mime may use ktradertest, which will fork off a copy of kdeinit if
  454.     # one does not already exist. It will exit after about 15 seconds if no
  455.     # further processes need it around. But since it does not close its stdout,
  456.     # the shell (via grep) will wait around for kdeinit to exit. If we start a
  457.     # copy here, that copy will be used in xdg-mime and we will avoid waiting.
  458.     if [ "$DE" = kde -a -z "$XDG_MIME_FIXED" ]; then
  459.         ktradertest text/html Application > /dev/null 2>&1
  460.         # Only do this once, as we only need it once.
  461.         XDG_MIME_FIXED=yes
  462.     fi
  463. }
  464.  
  465. get_browser_mime()
  466. {
  467.     xdg_mime_fixup
  468.     xdg-mime query default text/html
  469. }
  470.  
  471. set_browser_mime()
  472. {
  473.     xdg_mime_fixup
  474.     orig="`get_browser_mime`"
  475.     # Fixing the local desktop file can actually change the default browser all
  476.     # by itself, so we fix it only after querying to find the current default.
  477.     fix_local_desktop_file "$1" || return
  478.     mkdir -p "${XDG_DATA_HOME:-$HOME/.local/share}/applications"
  479.     xdg-mime default "$1" text/html || return
  480.     if [ x"`get_browser_mime`" != x"$1" ]; then
  481.         # Put back the original value
  482.         xdg-mime default "$orig" text/html
  483.         exit_failure_operation_failed
  484.     fi
  485. }
  486.  
  487. # }}} MIME utilities
  488. # {{{ KDE
  489.  
  490. # Resolves the KDE browser setting to a binary: if prefixed with !, simply removes it;
  491. # otherwise, uses desktop_file_to_binary to get the binary out of the desktop file.
  492. resolve_kde_browser()
  493. {
  494.     [ -z "$browser" ] && return
  495.     case "$browser" in
  496.       !*)
  497.         echo "${browser#!}"
  498.         ;;
  499.       *)
  500.         desktop_file_to_binary "$browser"
  501.         ;;
  502.     esac
  503. }
  504.  
  505. # Does the opposite of resolve_kde_browser: if prefixed with !, tries to find a desktop
  506. # file corresponding to the binary, otherwise just returns the desktop file name.
  507. resolve_kde_browser_desktop()
  508. {
  509.     [ -z "$browser" ] && return
  510.     case "$browser" in
  511.       !*)
  512.         desktop="`binary_to_desktop_file "${browser#!}"`"
  513.         basename "$desktop"
  514.         ;;
  515.       *)
  516.         echo "$browser"
  517.         ;;
  518.     esac
  519. }
  520.  
  521. # Reads the KDE browser setting, compensating for a bug in some versions of kreadconfig.
  522. read_kde_browser()
  523. {
  524.     browser="`kreadconfig --file kdeglobals --group General --key BrowserApplication`"
  525.     if [ "$browser" ]; then
  526.         echo "$browser"
  527.     fi
  528.     # kreadconfig in KDE 4 may not notice Key[$*]=... localized settings, so check
  529.     # by hand if it didn't find anything (oddly kwriteconfig works fine though).
  530.     kdeglobals_dir=`kde${KDE_SESSION_VERSION}-config --path config  | cut -d ':' -f 1`
  531.     kdeglobals="$kdeglobals_dir/kdeglobals"
  532.     [ ! -f "$kdeglobals" ] && return
  533.     # This will only take the first value if there is more than one.
  534.     grep '^BrowserApplication\[$[^]=]*\]=' "$kdeglobals" | head -n 1 | cut -d= -f 2-
  535. }
  536.  
  537. get_browser_kde()
  538. {
  539.     browser="`read_kde_browser`"
  540.     if [ x"$browser" = x ]; then
  541.         # No explicit default browser; KDE will use the MIME type text/html.
  542.         get_browser_mime
  543.     else
  544.         resolve_kde_browser_desktop
  545.     fi
  546. }
  547.  
  548. check_browser_kde()
  549. {
  550.     check="`desktop_file_to_binary "$1"`"
  551.     if [ -z "$check" ]; then
  552.         echo no
  553.         exit_success
  554.     fi
  555.     browser="`read_kde_browser`"
  556.     binary="`resolve_kde_browser`"
  557.     # Because KDE will use the handler for MIME type text/html if this value
  558.     # is empty, we allow either the empty string or a match to $check here.
  559.     if [ x"$binary" != x -a x"$binary" != x"$check" ]; then
  560.         echo no
  561.         exit_success
  562.     fi
  563.     browser="`get_browser_mime`"
  564.     binary="`desktop_file_to_binary "$browser"`"
  565.     if [ x"$binary" != x"$check" ]; then
  566.         echo no
  567.         exit_success
  568.     fi
  569.     echo yes
  570.     exit_success
  571. }
  572.  
  573. set_browser_kde()
  574. {
  575.     set_browser_mime "$1" || return
  576.     kwriteconfig --file kdeglobals --group General --key BrowserApplication "$1"
  577. }
  578.  
  579. # }}} KDE
  580. # {{{ GNOME
  581.  
  582. get_browser_gnome()
  583. {
  584.     binary="`gconftool-2 --get /desktop/gnome/applications/browser/exec | first_word`"
  585.     if [ x"$binary" = x ]; then
  586.         # No default browser; GNOME might use the MIME type text/html.
  587.         get_browser_mime
  588.     else
  589.         # gconftool gives the binary (maybe with %s etc. afterward),
  590.         # but we want the desktop file name, not the binary. So, we
  591.         # have to find the desktop file to which it corresponds.
  592.         desktop="`binary_to_desktop_file "$binary"`"
  593.         basename "$desktop"
  594.     fi
  595. }
  596.  
  597. check_browser_gnome()
  598. {
  599.     check="`desktop_file_to_binary "$1"`"
  600.     if [ -z "$check" ]; then
  601.         echo no
  602.         exit_success
  603.     fi
  604.     binary="`gconftool-2 --get /desktop/gnome/applications/browser/exec | first_word`"
  605.     if [ x"$binary" != x"$check" ]; then
  606.         echo no
  607.         exit_success
  608.     fi
  609.     # Check HTTP and HTTPS, but not about: and unknown:.
  610.     for protocol in http https; do
  611.         binary="`gconftool-2 --get /desktop/gnome/url-handlers/$protocol/command | first_word`"
  612.         if [ x"$binary" != x"$check" ]; then
  613.             echo no
  614.             exit_success
  615.         fi
  616.     done
  617.     browser="`get_browser_mime`"
  618.     binary="`desktop_file_to_binary "$browser"`"
  619.     if [ x"$binary" != x"$check" ]; then
  620.         echo no
  621.         exit_success
  622.     fi
  623.     echo yes
  624.     exit_success
  625. }
  626.  
  627. set_browser_gnome()
  628. {
  629.     binary="`desktop_file_to_binary "$1"`"
  630.     [ "$binary" ] || exit_failure_file_missing
  631.     set_browser_mime "$1" || return
  632.  
  633.     # Set the default browser.
  634.     gconftool-2 --type string --set /desktop/gnome/applications/browser/exec "$binary"
  635.     gconftool-2 --type bool --set /desktop/gnome/applications/browser/needs_term false
  636.     gconftool-2 --type bool --set /desktop/gnome/applications/browser/nremote true
  637.     # Set the handler for HTTP and HTTPS.
  638.     for protocol in http https; do
  639.         gconftool-2 --type string --set /desktop/gnome/url-handlers/$protocol/command "$binary %s"
  640.         gconftool-2 --type bool --set /desktop/gnome/url-handlers/$protocol/needs_terminal false
  641.         gconftool-2 --type bool --set /desktop/gnome/url-handlers/$protocol/enabled true
  642.     done
  643.     # Set the handler for about: and unknown URL types.
  644.     for protocol in about unknown; do
  645.         gconftool-2 --type string --set /desktop/gnome/url-handlers/$protocol/command "$binary %s"
  646.     done
  647. }
  648.  
  649. # }}} GNOME
  650. # {{{ xfce
  651.  
  652. get_browser_xfce()
  653. {
  654.     search="${XDG_CONFIG_HOME:-$HOME/.config}:${XDG_CONFIG_DIRS:-/etc/xdg}"
  655.     IFS=:
  656.     for dir in $search; do
  657.         unset IFS
  658.         [ "$dir" -a -d "$dir/xfce4" ] || continue
  659.         file="$dir/xfce4/helpers.rc"
  660.         [ -r "$file" ] || continue
  661.         grep -q "^WebBrowser=" "$file" || continue
  662.         desktop="`grep "^WebBrowser=" "$file" | cut -d= -f 2-`"
  663.         echo "$desktop.desktop"
  664.         return
  665.     done
  666.     exit_failure_operation_failed
  667. }
  668.  
  669. check_browser_xfce()
  670. {
  671.     browser="`get_browser_xfce`"
  672.     if [ x"$browser" != x"$1" ]; then
  673.         echo no
  674.         exit_success
  675.     fi
  676.     echo yes
  677.     exit_success
  678. }
  679.  
  680. check_xfce_desktop_file()
  681. {
  682.     # Annoyingly, xfce wants its .desktop files in a separate directory instead
  683.     # of the standard locations, and requires a few custom tweaks to them:
  684.     # "Type" must be "X-XFCE-Helper"
  685.     # "X-XFCE-Category" must be "WebBrowser" (for web browsers, anyway)
  686.     # "X-XFCE-Commands" and "X-XFCE-CommandsWithParameter" must be set
  687.     search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
  688.     IFS=:
  689.     for dir in $search; do
  690.         unset IFS
  691.         [ "$dir" -a -d "$dir/xfce4/helpers" ] || continue
  692.         file="$dir/xfce4/helpers/$1"
  693.         # We have the file, no need to create it.
  694.         [ -r "$file" ] && return
  695.     done
  696.     IFS=:
  697.     for dir in $search; do
  698.         unset IFS
  699.         [ "$dir" -a -d "$dir/applications" ] || continue
  700.         file="$dir/applications/$1"
  701.         if [ -r "$file" ]; then
  702.             # Found a file to convert.
  703.             target="${XDG_DATA_HOME:-$HOME/.local/share}/xfce4/helpers"
  704.             mkdir -p "$target"
  705.             grep -v "^Type=" "$file" > "$target/$1"
  706.             echo "Type=X-XFCE-Helper" >> "$target/$1"
  707.             echo "X-XFCE-Category=WebBrowser" >> "$target/$1"
  708.             # Change %F, %f, %U, and %u to "%s".
  709.             command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | sed -e 's/%[FfUu]/"%s"/g'`"
  710.             echo "X-XFCE-Commands=`echo "$command" | first_word`" >> "$target/$1"
  711.             echo "X-XFCE-CommandsWithParameter=$command" >> "$target/$1"
  712.             return
  713.         fi
  714.     done
  715.     return 1
  716. }
  717.  
  718. set_browser_xfce()
  719. {
  720.     check_xfce_desktop_file "$1" || exit_failure_operation_failed
  721.  
  722.     helper_dir="${XDG_CONFIG_HOME:-$HOME/.config}/xfce4"
  723.     if [ ! -d "$helper_dir" ]; then
  724.         mkdir -p "$helper_dir" || exit_failure_operation_failed
  725.     fi
  726.  
  727.     helpers_rc="$helper_dir/helpers.rc"
  728.     # Create the file if it does not exist to avoid special cases below.
  729.     if [ ! -r "$helpers_rc" ]; then
  730.         touch "$helpers_rc" || exit_failure_operation_failed
  731.     fi
  732.  
  733.     temp="`mktemp "$helpers_rc.XXXXXX"`" || return
  734.     grep -v "^WebBrowser=" "$helpers_rc" >> "$temp"
  735.     echo "WebBrowser=${1%.desktop}" >> "$temp"
  736.  
  737.     oldlines="`wc -l < "$helpers_rc"`"
  738.     newlines="`wc -l < "$temp"`"
  739.     # The new file should have at least as many lines as the old.
  740.     if [ $oldlines -le $newlines ]; then
  741.         mv "$temp" "$helpers_rc"
  742.     else
  743.         rm -f "$temp"
  744.         return 1
  745.     fi
  746. }
  747.  
  748. # }}} xfce
  749. # }}} default browser
  750.  
  751. dispatch_specific()
  752. {
  753.     # The PROP comments in this function are used to generate the output of
  754.     # the --list option. The formatting is important. Make sure to line up the
  755.     # property descriptions with spaces so that it will look nice.
  756.     if [ x"$op" = x"get" ]; then
  757.         case "$parm" in
  758.           default-web-browser) # PROP:           Default web browser
  759.             get_browser_$DE
  760.             ;;
  761.  
  762.           *)
  763.             exit_failure_syntax
  764.             ;;
  765.         esac
  766.     elif [ x"$op" = x"check" ]; then
  767.         case "$parm" in
  768.           default-web-browser)
  769.             check_desktop_filename "$1"
  770.             check_browser_$DE "$1"
  771.             ;;
  772.  
  773.           *)
  774.             exit_failure_syntax
  775.             ;;
  776.         esac
  777.     else # set
  778.         [ $# -eq 1 ] || exit_failure_syntax "unexpected/missing argument"
  779.         case "$parm" in
  780.           default-web-browser)
  781.             check_desktop_filename "$1"
  782.             set_browser_$DE "$1"
  783.             ;;
  784.  
  785.           *)
  786.             exit_failure_syntax
  787.             ;;
  788.         esac
  789.     fi
  790.  
  791.     if [ $? -eq 0 ]; then
  792.         exit_success
  793.     else
  794.         exit_failure_operation_failed
  795.     fi
  796. }
  797.  
  798. dispatch_generic()
  799. {
  800.     # We only know how to get or check the default web browser.
  801.     [ x"$op" != x"get" -a x"$op" != x"check" ] && exit_failure_operation_impossible
  802.     [ x"$parm" != x"default-web-browser" ] && exit_failure_operation_impossible
  803.  
  804.     # First look in $BROWSER
  805.     if [ x"$BROWSER" != x ]; then
  806.         binary="`which "${BROWSER%%:*}"`"
  807.     else
  808.         # Debian and Ubuntu (and others?) have x-www-browser.
  809.         binary="`which x-www-browser`"
  810.     fi
  811.  
  812.     [ "$binary" ] || exit_failure_operation_failed
  813.  
  814.     binary="`readlink -f "$binary"`"
  815.  
  816.     [ "$binary" ] || exit_failure_operation_failed
  817.  
  818.     if [ x"$op" = x"get" ]; then
  819.         desktop="`binary_to_desktop_file "$binary"`"
  820.         basename "$desktop"
  821.     else
  822.         # $op = "check"
  823.         check="`desktop_file_to_binary "$1"`"
  824.         if [ -z "$check" ]; then
  825.             echo no
  826.             exit_success
  827.         fi
  828.         if [ x"$binary" != x"$check" ]; then
  829.             echo no
  830.             exit_success
  831.         fi
  832.         echo yes
  833.     fi
  834.     exit_success
  835. }
  836.  
  837. if [ x"$1" = x"--list" ]; then
  838.     echo "Known properties:"
  839.     # Extract the property names from dispatch_specific() above.
  840.     grep "^[     ]*[^)]*) # PROP:" "$0" | sed -e 's/^[     ]*\([^)]*\)) # PROP: \(.*\)$/  \1 \2/' | sort
  841.     exit_success
  842. fi
  843.  
  844. [ x"$1" != x ] || exit_failure_syntax "no operation given"
  845. [ x"$2" != x ] || exit_failure_syntax "no parameter name given"
  846. [ x"$1" = x"get" -o x"$3" != x ] || exit_failure_syntax "no parameter value given"
  847.  
  848. op="$1"
  849. parm="$2"
  850. shift 2
  851.  
  852. if [ x"$op" != x"get" -a x"$op" != x"check" -a x"$op" != x"set" ]; then
  853.   exit_failure_syntax "invalid operation"
  854. fi
  855.  
  856. detectDE
  857.  
  858. case "$DE" in
  859.     kde|gnome|xfce)
  860.     dispatch_specific "$@"
  861.     ;;
  862.  
  863.     generic)
  864.     dispatch_generic "$@"
  865.     ;;
  866.  
  867.     *)
  868.     exit_failure_operation_impossible "unknown desktop environment"
  869.     ;;
  870. esac
  871.