blob: 55795a78e7e99c1eb2e142a2ebf712b669133016 [file] [log] [blame]
mdm@chromium.org00caad52009-07-01 22:16:05 +00001#!/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
33manualpage()
34{
35cat << _MANUALPAGE
36Name
37
38xdg-settings - get various settings from the desktop environment
39
40Synopsis
41
mdm@chromium.orgd609afa2009-07-22 00:11:19 +000042xdg-settings { get | check | set } {property} [value]
mdm@chromium.org00caad52009-07-01 22:16:05 +000043
44xdg-settings { --help | --list | --manual | --version }
45
46Description
47
48xdg-settings gets various settings from the desktop environment. For instance,
49desktop environments often provide proxy configuration and default web browser
50settings. Using xdg-settings these parameters can be extracted for use by
51applications that do not use the desktop environment's libraries (which would
52use the settings natively).
53
54xdg-settings is for use inside a desktop session only. It is not recommended to
55use xdg-settings as root.
56
57Options
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
68Exit Codes
69
70An exit code of 0 indicates success while a non-zero exit code indicates
71failure. The following failure codes can be returned:
72
731
74 Error in command line syntax.
752
76 One of the files passed on the command line did not exist.
773
78 A required tool could not be found.
794
80 The action failed.
81
82Examples
83
mdm@chromium.orgd609afa2009-07-22 00:11:19 +000084Get the desktop file name of the current default web browser
85
mdm@chromium.org00caad52009-07-01 22:16:05 +000086 xdg-settings get default-web-browser
87
88
mdm@chromium.orgd609afa2009-07-22 00:11:19 +000089Check whether the default web browser is firefox.desktop, which can be false
90even if "get default-web-browser" says that is the current value (if only some
91of the underlying settings actually reflect that value)
92
93 xdg-settings check default-web-browser firefox.desktop
94
95
96Set the default web browser to google-chrome.desktop
mdm@chromium.org00caad52009-07-01 22:16:05 +000097
98 xdg-settings set default-web-browser google-chrome.desktop
99
100
mdm@chromium.org00caad52009-07-01 22:16:05 +0000101_MANUALPAGE
102}
103
104usage()
105{
106cat << _USAGE
107xdg-settings - get various settings from the desktop environment
108
109Synopsis
110
mdm@chromium.orgd609afa2009-07-22 00:11:19 +0000111xdg-settings { get | check | set } {property} [value]
mdm@chromium.org00caad52009-07-01 22:16:05 +0000112
113xdg-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
124DEBUG()
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
135exit_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
151exit_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
167exit_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
179exit_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
191exit_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
203exit_failure_file_permission_read()
204{
205 if [ $# -gt 0 ]; then
206 echo "xdg-settings: $@" >&2
207 fi
208
209 exit 5
210}
211
212#------------------------------------------------------------
mdm@chromium.org56df6d32010-08-31 18:16:49 +0000213# Exit script on insufficient permission to write a specified file
mdm@chromium.org00caad52009-07-01 22:16:05 +0000214
215exit_failure_file_permission_write()
216{
217 if [ $# -gt 0 ]; then
218 echo "xdg-settings: $@" >&2
219 fi
220
221 exit 6
222}
223
224check_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
234check_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
252check_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
271check_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
297check_common_commands "$@"
298
299[ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && unset XDG_UTILS_DEBUG_LEVEL;
300if [ ${XDG_UTILS_DEBUG_LEVEL-0} -lt 1 ]; then
301 # Be silent
302 xdg_redirect_output=" > /dev/null 2> /dev/null"
303else
304 # All output to stderr
305 xdg_redirect_output=" >&2"
306fi
307
308#--------------------------------------
309# Checks for known desktop environments
310# set variable DE to the desktop environments name, lowercase
311
312detectDE()
313{
314 if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde;
315 elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome;
mdm@chromium.org56df6d32010-08-31 18:16:49 +0000316 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;
mdm@chromium.org00caad52009-07-01 22:16:05 +0000318 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
326kfmclient_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
338check_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
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000354# {{{ utility functions
355
356# This handles backslashes but not quote marks.
357first_word()
358{
359 read first rest
360 echo "$first"
361}
362
363binary_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
thestig@chromium.org13456fd2009-09-16 01:21:40 +0000372 [ "$dir" ] || continue
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000373 [ -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
thestig@chromium.org13456fd2009-09-16 01:21:40 +0000380 command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`"
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000381 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
391desktop_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}
mdm@chromium.org00caad52009-07-01 22:16:05 +0000408
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.
417fix_local_desktop_file()
418{
419 apps="${XDG_DATA_HOME:-$HOME/.local/share}/applications"
420 # No local desktop file?
421 [ ! -f "$apps/$1" ] && return
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000422 MIME="`grep "^MimeType=" "$apps/$1" | cut -d= -f 2-`"
mdm@chromium.org00caad52009-07-01 22:16:05 +0000423 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
mdm@chromium.org323a1a02009-07-07 20:43:24 +0000431 temp="`mktemp "$apps/$1.XXXXXX"`" || return
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000432 grep -v "^MimeType=" "$apps/$1" >> "$temp"
mdm@chromium.org00caad52009-07-01 22:16:05 +0000433 echo "MimeType=text/html;$MIME" >> "$temp"
434
435 oldlines="`wc -l < "$apps/$1"`"
436 newlines="`wc -l < "$temp"`"
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000437 # The new file should have at least as many lines as the old.
mdm@chromium.org00caad52009-07-01 22:16:05 +0000438 if [ $oldlines -le $newlines ]; then
439 mv "$temp" "$apps/$1"
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000440 # This can take a little bit to get noticed.
mdm@chromium.org00caad52009-07-01 22:16:05 +0000441 sleep 4
442 else
443 rm -f "$temp"
444 return 1
445 fi
446}
447
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000448# }}} utility functions
449# {{{ MIME utilities
450
mdm@chromium.orgea2ef9f2009-07-27 20:41:38 +0000451xdg_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
mdm@chromium.org00caad52009-07-01 22:16:05 +0000465get_browser_mime()
466{
mdm@chromium.orgea2ef9f2009-07-27 20:41:38 +0000467 xdg_mime_fixup
mdm@chromium.org00caad52009-07-01 22:16:05 +0000468 xdg-mime query default text/html
469}
470
mdm@chromium.orgd609afa2009-07-22 00:11:19 +0000471set_browser_mime()
472{
mdm@chromium.orgea2ef9f2009-07-27 20:41:38 +0000473 xdg_mime_fixup
mdm@chromium.orgd609afa2009-07-22 00:11:19 +0000474 orig="`get_browser_mime`"
475 # Fixing the local desktop file can actually change the default browser all
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000476 # by itself, so we fix it only after querying to find the current default.
mdm@chromium.orgd609afa2009-07-22 00:11:19 +0000477 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
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000487# }}} MIME utilities
488# {{{ KDE
thestig@chromium.orge5c2d602009-07-13 21:43:13 +0000489
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000490# 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.
mdm@chromium.orgd609afa2009-07-22 00:11:19 +0000492resolve_kde_browser()
mdm@chromium.org00caad52009-07-01 22:16:05 +0000493{
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000494 [ -z "$browser" ] && return
495 case "$browser" in
496 !*)
497 echo "${browser#!}"
498 ;;
499 *)
500 desktop_file_to_binary "$browser"
501 ;;
502 esac
mdm@chromium.org00caad52009-07-01 22:16:05 +0000503}
504
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000505# 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.
507resolve_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.
mdm@chromium.org1005b212009-07-30 19:01:55 +0000522read_kde_browser()
mdm@chromium.org00caad52009-07-01 22:16:05 +0000523{
524 browser="`kreadconfig --file kdeglobals --group General --key BrowserApplication`"
mdm@chromium.org1005b212009-07-30 19:01:55 +0000525 if [ "$browser" ]; then
526 echo "$browser"
527 fi
528 # kreadconfig in KDE 4 may not notice Key[$*]=... localized settings, so check
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000529 # by hand if it didn't find anything (oddly kwriteconfig works fine though).
mdm@chromium.org56df6d32010-08-31 18:16:49 +0000530 kdeglobals_dir=`kde${KDE_SESSION_VERSION}-config --path config | cut -d ':' -f 1`
531 kdeglobals="$kdeglobals_dir/kdeglobals"
mdm@chromium.org1005b212009-07-30 19:01:55 +0000532 [ ! -f "$kdeglobals" ] && return
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000533 # This will only take the first value if there is more than one.
mdm@chromium.org1005b212009-07-30 19:01:55 +0000534 grep '^BrowserApplication\[$[^]=]*\]=' "$kdeglobals" | head -n 1 | cut -d= -f 2-
535}
536
537get_browser_kde()
538{
539 browser="`read_kde_browser`"
mdm@chromium.org00caad52009-07-01 22:16:05 +0000540 if [ x"$browser" = x ]; then
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000541 # No explicit default browser; KDE will use the MIME type text/html.
mdm@chromium.org00caad52009-07-01 22:16:05 +0000542 get_browser_mime
543 else
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000544 resolve_kde_browser_desktop
mdm@chromium.org00caad52009-07-01 22:16:05 +0000545 fi
546}
547
mdm@chromium.orgd609afa2009-07-22 00:11:19 +0000548check_browser_kde()
549{
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000550 check="`desktop_file_to_binary "$1"`"
551 if [ -z "$check" ]; then
552 echo no
553 exit_success
554 fi
mdm@chromium.org1005b212009-07-30 19:01:55 +0000555 browser="`read_kde_browser`"
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000556 binary="`resolve_kde_browser`"
mdm@chromium.orgd609afa2009-07-22 00:11:19 +0000557 # Because KDE will use the handler for MIME type text/html if this value
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000558 # 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
mdm@chromium.orgd609afa2009-07-22 00:11:19 +0000560 echo no
561 exit_success
562 fi
563 browser="`get_browser_mime`"
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000564 binary="`desktop_file_to_binary "$browser"`"
565 if [ x"$binary" != x"$check" ]; then
mdm@chromium.orgd609afa2009-07-22 00:11:19 +0000566 echo no
567 exit_success
568 fi
569 echo yes
570 exit_success
571}
572
mdm@chromium.org00caad52009-07-01 22:16:05 +0000573set_browser_kde()
574{
575 set_browser_mime "$1" || return
576 kwriteconfig --file kdeglobals --group General --key BrowserApplication "$1"
577}
578
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000579# }}} KDE
580# {{{ GNOME
mdm@chromium.org00caad52009-07-01 22:16:05 +0000581
582get_browser_gnome()
583{
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000584 binary="`gconftool-2 --get /desktop/gnome/applications/browser/exec | first_word`"
mdm@chromium.org00caad52009-07-01 22:16:05 +0000585 if [ x"$binary" = x ]; then
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000586 # No default browser; GNOME might use the MIME type text/html.
mdm@chromium.org00caad52009-07-01 22:16:05 +0000587 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.
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000592 desktop="`binary_to_desktop_file "$binary"`"
593 basename "$desktop"
mdm@chromium.org00caad52009-07-01 22:16:05 +0000594 fi
595}
596
mdm@chromium.orgd609afa2009-07-22 00:11:19 +0000597check_browser_gnome()
598{
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000599 check="`desktop_file_to_binary "$1"`"
600 if [ -z "$check" ]; then
mdm@chromium.orgd609afa2009-07-22 00:11:19 +0000601 echo no
602 exit_success
603 fi
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000604 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:.
mdm@chromium.orgd609afa2009-07-22 00:11:19 +0000610 for protocol in http https; do
611 binary="`gconftool-2 --get /desktop/gnome/url-handlers/$protocol/command | first_word`"
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000612 if [ x"$binary" != x"$check" ]; then
mdm@chromium.orgd609afa2009-07-22 00:11:19 +0000613 echo no
614 exit_success
615 fi
616 done
617 browser="`get_browser_mime`"
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000618 binary="`desktop_file_to_binary "$browser"`"
619 if [ x"$binary" != x"$check" ]; then
mdm@chromium.orgd609afa2009-07-22 00:11:19 +0000620 echo no
621 exit_success
622 fi
623 echo yes
624 exit_success
625}
626
mdm@chromium.org00caad52009-07-01 22:16:05 +0000627set_browser_gnome()
628{
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000629 binary="`desktop_file_to_binary "$1"`"
630 [ "$binary" ] || exit_failure_file_missing
mdm@chromium.org00caad52009-07-01 22:16:05 +0000631 set_browser_mime "$1" || return
632
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000633 # Set the default browser.
mdm@chromium.org00caad52009-07-01 22:16:05 +0000634 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
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000637 # Set the handler for HTTP and HTTPS.
mdm@chromium.org00caad52009-07-01 22:16:05 +0000638 for protocol in http https; do
thestig@chromium.org7b453362009-10-15 08:33:22 +0000639 gconftool-2 --type string --set /desktop/gnome/url-handlers/$protocol/command "$binary %s"
mdm@chromium.org00caad52009-07-01 22:16:05 +0000640 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
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000643 # Set the handler for about: and unknown URL types.
mdm@chromium.org00caad52009-07-01 22:16:05 +0000644 for protocol in about unknown; do
thestig@chromium.org7b453362009-10-15 08:33:22 +0000645 gconftool-2 --type string --set /desktop/gnome/url-handlers/$protocol/command "$binary %s"
mdm@chromium.org00caad52009-07-01 22:16:05 +0000646 done
647}
648
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000649# }}} GNOME
650# {{{ xfce
651
mdm@chromium.org00caad52009-07-01 22:16:05 +0000652get_browser_xfce()
653{
mdm@chromium.org323a1a02009-07-07 20:43:24 +0000654 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
mdm@chromium.orgd609afa2009-07-22 00:11:19 +0000669check_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
mdm@chromium.org323a1a02009-07-07 20:43:24 +0000680check_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"
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000693 # We have the file, no need to create it.
mdm@chromium.org323a1a02009-07-07 20:43:24 +0000694 [ -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
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000702 # Found a file to convert.
mdm@chromium.org323a1a02009-07-07 20:43:24 +0000703 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"
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000708 # Change %F, %f, %U, and %u to "%s".
709 command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | sed -e 's/%[FfUu]/"%s"/g'`"
mdm@chromium.org323a1a02009-07-07 20:43:24 +0000710 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
mdm@chromium.org00caad52009-07-01 22:16:05 +0000716}
717
718set_browser_xfce()
719{
mdm@chromium.org323a1a02009-07-07 20:43:24 +0000720 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"
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000728 # Create the file if it does not exist to avoid special cases below.
mdm@chromium.org323a1a02009-07-07 20:43:24 +0000729 if [ ! -r "$helpers_rc" ]; then
730 touch "$helpers_rc" || exit_failure_operation_failed
731 fi
732
733 temp="`mktemp "$helpers_rc.XXXXXX"`" || return
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000734 grep -v "^WebBrowser=" "$helpers_rc" >> "$temp"
mdm@chromium.org323a1a02009-07-07 20:43:24 +0000735 echo "WebBrowser=${1%.desktop}" >> "$temp"
736
737 oldlines="`wc -l < "$helpers_rc"`"
738 newlines="`wc -l < "$temp"`"
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000739 # The new file should have at least as many lines as the old.
mdm@chromium.org323a1a02009-07-07 20:43:24 +0000740 if [ $oldlines -le $newlines ]; then
741 mv "$temp" "$helpers_rc"
742 else
743 rm -f "$temp"
744 return 1
745 fi
mdm@chromium.org00caad52009-07-01 22:16:05 +0000746}
747
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000748# }}} xfce
mdm@chromium.org00caad52009-07-01 22:16:05 +0000749# }}} default browser
750
751dispatch_specific()
752{
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000753 # The PROP comments in this function are used to generate the output of
mdm@chromium.org00caad52009-07-01 22:16:05 +0000754 # 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
mdm@chromium.orgd609afa2009-07-22 00:11:19 +0000766 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
mdm@chromium.org00caad52009-07-01 22:16:05 +0000777 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
798dispatch_generic()
799{
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000800 # 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
mdm@chromium.org00caad52009-07-01 22:16:05 +0000802 [ x"$parm" != x"default-web-browser" ] && exit_failure_operation_impossible
803
mdm@chromium.org00caad52009-07-01 22:16:05 +0000804 # First look in $BROWSER
805 if [ x"$BROWSER" != x ]; then
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000806 binary="`which "${BROWSER%%:*}"`"
807 else
808 # Debian and Ubuntu (and others?) have x-www-browser.
809 binary="`which x-www-browser`"
mdm@chromium.org00caad52009-07-01 22:16:05 +0000810 fi
811
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000812 [ "$binary" ] || exit_failure_operation_failed
mdm@chromium.org00caad52009-07-01 22:16:05 +0000813
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000814 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
mdm@chromium.org00caad52009-07-01 22:16:05 +0000834 exit_success
835}
836
837if [ x"$1" = x"--list" ]; then
838 echo "Known properties:"
mdm@chromium.org4bb19ec2009-09-08 22:34:24 +0000839 # Extract the property names from dispatch_specific() above.
mdm@chromium.org00caad52009-07-01 22:16:05 +0000840 grep "^[ ]*[^)]*) # PROP:" "$0" | sed -e 's/^[ ]*\([^)]*\)) # PROP: \(.*\)$/ \1 \2/' | sort
841 exit_success
842fi
843
844[ x"$1" != x ] || exit_failure_syntax "no operation given"
845[ x"$2" != x ] || exit_failure_syntax "no parameter name given"
mdm@chromium.orgd609afa2009-07-22 00:11:19 +0000846[ x"$1" = x"get" -o x"$3" != x ] || exit_failure_syntax "no parameter value given"
mdm@chromium.org00caad52009-07-01 22:16:05 +0000847
848op="$1"
849parm="$2"
850shift 2
851
mdm@chromium.orgd609afa2009-07-22 00:11:19 +0000852if [ x"$op" != x"get" -a x"$op" != x"check" -a x"$op" != x"set" ]; then
853 exit_failure_syntax "invalid operation"
854fi
mdm@chromium.org00caad52009-07-01 22:16:05 +0000855
856detectDE
857
858case "$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 ;;
870esac