| OLD | NEW |
| (Empty) | |
| 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 | 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 xdg-settings get default-web-browser |
| 85 |
| 86 |
| 87 Gets the desktop file name of the current default web browser |
| 88 |
| 89 xdg-settings set default-web-browser google-chrome.desktop |
| 90 |
| 91 |
| 92 Sets the default web browser to google-chrome.desktop |
| 93 |
| 94 _MANUALPAGE |
| 95 } |
| 96 |
| 97 usage() |
| 98 { |
| 99 cat << _USAGE |
| 100 xdg-settings - get various settings from the desktop environment |
| 101 |
| 102 Synopsis |
| 103 |
| 104 xdg-settings { get | set } {property} [value] |
| 105 |
| 106 xdg-settings { --help | --list | --manual | --version } |
| 107 |
| 108 _USAGE |
| 109 } |
| 110 |
| 111 #@xdg-utils-common@ |
| 112 |
| 113 #---------------------------------------------------------------------------- |
| 114 # Common utility functions included in all XDG wrapper scripts |
| 115 #---------------------------------------------------------------------------- |
| 116 |
| 117 DEBUG() |
| 118 { |
| 119 [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && return 0; |
| 120 [ ${XDG_UTILS_DEBUG_LEVEL} -lt $1 ] && return 0; |
| 121 shift |
| 122 echo "$@" >&2 |
| 123 } |
| 124 |
| 125 #------------------------------------------------------------- |
| 126 # Exit script on successfully completing the desired operation |
| 127 |
| 128 exit_success() |
| 129 { |
| 130 if [ $# -gt 0 ]; then |
| 131 echo "$@" |
| 132 echo |
| 133 fi |
| 134 |
| 135 exit 0 |
| 136 } |
| 137 |
| 138 |
| 139 #----------------------------------------- |
| 140 # Exit script on malformed arguments, not enough arguments |
| 141 # or missing required option. |
| 142 # prints usage information |
| 143 |
| 144 exit_failure_syntax() |
| 145 { |
| 146 if [ $# -gt 0 ]; then |
| 147 echo "xdg-settings: $@" >&2 |
| 148 echo "Try 'xdg-settings --help' for more information." >&2 |
| 149 else |
| 150 usage |
| 151 echo "Use 'man xdg-settings' or 'xdg-settings --manual' for additional i
nfo." |
| 152 fi |
| 153 |
| 154 exit 1 |
| 155 } |
| 156 |
| 157 #------------------------------------------------------------- |
| 158 # Exit script on missing file specified on command line |
| 159 |
| 160 exit_failure_file_missing() |
| 161 { |
| 162 if [ $# -gt 0 ]; then |
| 163 echo "xdg-settings: $@" >&2 |
| 164 fi |
| 165 |
| 166 exit 2 |
| 167 } |
| 168 |
| 169 #------------------------------------------------------------- |
| 170 # Exit script on failure to locate necessary tool applications |
| 171 |
| 172 exit_failure_operation_impossible() |
| 173 { |
| 174 if [ $# -gt 0 ]; then |
| 175 echo "xdg-settings: $@" >&2 |
| 176 fi |
| 177 |
| 178 exit 3 |
| 179 } |
| 180 |
| 181 #------------------------------------------------------------- |
| 182 # Exit script on failure returned by a tool application |
| 183 |
| 184 exit_failure_operation_failed() |
| 185 { |
| 186 if [ $# -gt 0 ]; then |
| 187 echo "xdg-settings: $@" >&2 |
| 188 fi |
| 189 |
| 190 exit 4 |
| 191 } |
| 192 |
| 193 #------------------------------------------------------------ |
| 194 # Exit script on insufficient permission to read a specified file |
| 195 |
| 196 exit_failure_file_permission_read() |
| 197 { |
| 198 if [ $# -gt 0 ]; then |
| 199 echo "xdg-settings: $@" >&2 |
| 200 fi |
| 201 |
| 202 exit 5 |
| 203 } |
| 204 |
| 205 #------------------------------------------------------------ |
| 206 # Exit script on insufficient permission to read a specified file |
| 207 |
| 208 exit_failure_file_permission_write() |
| 209 { |
| 210 if [ $# -gt 0 ]; then |
| 211 echo "xdg-settings: $@" >&2 |
| 212 fi |
| 213 |
| 214 exit 6 |
| 215 } |
| 216 |
| 217 check_input_file() |
| 218 { |
| 219 if [ ! -e "$1" ]; then |
| 220 exit_failure_file_missing "file '$1' does not exist" |
| 221 fi |
| 222 if [ ! -r "$1" ]; then |
| 223 exit_failure_file_permission_read "no permission to read file '$1'" |
| 224 fi |
| 225 } |
| 226 |
| 227 check_vendor_prefix() |
| 228 { |
| 229 file_label="$2" |
| 230 [ -n "$file_label" ] || file_label="filename" |
| 231 file=`basename "$1"` |
| 232 case "$file" in |
| 233 [a-zA-Z]*-*) |
| 234 return |
| 235 ;; |
| 236 esac |
| 237 |
| 238 echo "xdg-settings: $file_label '$file' does not have a proper vendor prefix
" >&2 |
| 239 echo 'A vendor prefix consists of alpha characters ([a-zA-Z]) and is termina
ted' >&2 |
| 240 echo 'with a dash ("-"). An example '"$file_label"' is '"'example-$file'" >&
2 |
| 241 echo "Use --novendor to override or 'xdg-settings --manual' for additional i
nfo." >&2 |
| 242 exit 1 |
| 243 } |
| 244 |
| 245 check_output_file() |
| 246 { |
| 247 # if the file exists, check if it is writeable |
| 248 # if it does not exists, check if we are allowed to write on the directory |
| 249 if [ -e "$1" ]; then |
| 250 if [ ! -w "$1" ]; then |
| 251 exit_failure_file_permission_write "no permission to write to file '
$1'" |
| 252 fi |
| 253 else |
| 254 DIR=`dirname "$1"` |
| 255 if [ ! -w "$DIR" -o ! -x "$DIR" ]; then |
| 256 exit_failure_file_permission_write "no permission to create file '$1
'" |
| 257 fi |
| 258 fi |
| 259 } |
| 260 |
| 261 #---------------------------------------- |
| 262 # Checks for shared commands, e.g. --help |
| 263 |
| 264 check_common_commands() |
| 265 { |
| 266 while [ $# -gt 0 ] ; do |
| 267 parm="$1" |
| 268 shift |
| 269 |
| 270 case "$parm" in |
| 271 --help) |
| 272 usage |
| 273 echo "Use 'man xdg-settings' or 'xdg-settings --manual' for addition
al info." |
| 274 exit_success |
| 275 ;; |
| 276 |
| 277 --manual) |
| 278 manualpage |
| 279 exit_success |
| 280 ;; |
| 281 |
| 282 --version) |
| 283 echo "xdg-settings 1.0.2" |
| 284 exit_success |
| 285 ;; |
| 286 esac |
| 287 done |
| 288 } |
| 289 |
| 290 check_common_commands "$@" |
| 291 |
| 292 [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && unset XDG_UTILS_DEBUG_LEVEL; |
| 293 if [ ${XDG_UTILS_DEBUG_LEVEL-0} -lt 1 ]; then |
| 294 # Be silent |
| 295 xdg_redirect_output=" > /dev/null 2> /dev/null" |
| 296 else |
| 297 # All output to stderr |
| 298 xdg_redirect_output=" >&2" |
| 299 fi |
| 300 |
| 301 #-------------------------------------- |
| 302 # Checks for known desktop environments |
| 303 # set variable DE to the desktop environments name, lowercase |
| 304 |
| 305 detectDE() |
| 306 { |
| 307 if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; |
| 308 elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; |
| 309 elif xprop -root _DT_SAVE_MODE | grep ' = \"xfce4\"$' >/dev/null 2>&1; then
DE=xfce; |
| 310 fi |
| 311 } |
| 312 |
| 313 #---------------------------------------------------------------------------- |
| 314 # kfmclient exec/openURL can give bogus exit value in KDE <= 3.5.4 |
| 315 # It also always returns 1 in KDE 3.4 and earlier |
| 316 # Simply return 0 in such case |
| 317 |
| 318 kfmclient_fix_exit_code() |
| 319 { |
| 320 version=`kde${KDE_SESSION_VERSION}-config --version 2>/dev/null | grep KDE` |
| 321 major=`echo $version | sed 's/KDE: \([0-9]\).*/\1/'` |
| 322 minor=`echo $version | sed 's/KDE: [0-9]*\.\([0-9]\).*/\1/'` |
| 323 release=`echo $version | sed 's/KDE: [0-9]*\.[0-9]*\.\([0-9]\).*/\1/'` |
| 324 test "$major" -gt 3 && return $1 |
| 325 test "$minor" -gt 5 && return $1 |
| 326 test "$release" -gt 4 && return $1 |
| 327 return 0 |
| 328 } |
| 329 |
| 330 check_desktop_filename() |
| 331 { |
| 332 case "$1" in |
| 333 */*) |
| 334 exit_failure_syntax "invalid application name" |
| 335 ;; |
| 336 *.desktop) |
| 337 return |
| 338 ;; |
| 339 *) |
| 340 exit_failure_syntax "invalid application name" |
| 341 ;; |
| 342 esac |
| 343 } |
| 344 |
| 345 # {{{ default browser |
| 346 |
| 347 # In order to remove an application from the automatically-generated list of |
| 348 # applications for handling a given MIME type, the desktop environment may copy |
| 349 # the global .desktop file into the user's .local directory, and remove that |
| 350 # MIME type from its list. In that case, we must restore the MIME type to the |
| 351 # application's list of MIME types before we can set it as the default for that |
| 352 # MIME type. (We can't just delete the local version, since the user may have |
| 353 # made other changes to it as well. So, tweak the existing file.) |
| 354 # This function is hard-coded for text/html but it could be adapted if needed. |
| 355 fix_local_desktop_file() |
| 356 { |
| 357 apps="${XDG_DATA_HOME:-$HOME/.local/share}/applications" |
| 358 # No local desktop file? |
| 359 [ ! -f "$apps/$1" ] && return |
| 360 MIME="`grep ^MimeType= "$apps/$1" | cut -d= -f 2-`" |
| 361 case "$MIME" in |
| 362 text/html\;*|*\;text/html\;*|*\;text/html\;|*\;text/html) |
| 363 # Already has text/html? Great! |
| 364 return 0 |
| 365 ;; |
| 366 esac |
| 367 |
| 368 # Add text/html to the list |
| 369 temp="`mktemp $apps/$1.XXXXXX`" || return |
| 370 grep -v ^MimeType= "$apps/$1" >> "$temp" |
| 371 echo "MimeType=text/html;$MIME" >> "$temp" |
| 372 |
| 373 oldlines="`wc -l < "$apps/$1"`" |
| 374 newlines="`wc -l < "$temp"`" |
| 375 # The new file should have at least as many lines as the old |
| 376 if [ $oldlines -le $newlines ]; then |
| 377 mv "$temp" "$apps/$1" |
| 378 # This can take a little bit to get noticed |
| 379 sleep 4 |
| 380 else |
| 381 rm -f "$temp" |
| 382 return 1 |
| 383 fi |
| 384 } |
| 385 |
| 386 get_browser_mime() |
| 387 { |
| 388 xdg-mime query default text/html |
| 389 } |
| 390 |
| 391 set_browser_mime() |
| 392 { |
| 393 orig="`get_browser_mime`" |
| 394 # Fixing the local desktop file can actually change the default browser all |
| 395 # by itself, so we fix it only after querying to find the current default |
| 396 fix_local_desktop_file "$1" || return |
| 397 mkdir -p "${XDG_DATA_HOME:-$HOME/.local/share/applications}" |
| 398 xdg-mime default "$1" text/html || return |
| 399 if [ x"`get_browser_mime`" != x"$1" ]; then |
| 400 # Put back the original value |
| 401 xdg-mime default "$orig" text/html |
| 402 exit_failure_operation_failed |
| 403 fi |
| 404 } |
| 405 |
| 406 get_browser_kde() |
| 407 { |
| 408 browser="`kreadconfig --file kdeglobals --group General --key BrowserApplica
tion`" |
| 409 if [ x"$browser" = x ]; then |
| 410 # No default browser; KDE will probably use the MIME type text/html |
| 411 get_browser_mime |
| 412 else |
| 413 echo "$browser" |
| 414 fi |
| 415 } |
| 416 |
| 417 set_browser_kde() |
| 418 { |
| 419 set_browser_mime "$1" || return |
| 420 kwriteconfig --file kdeglobals --group General --key BrowserApplication "$1" |
| 421 } |
| 422 |
| 423 # This handles backslashes but not quote marks |
| 424 first_word() |
| 425 { |
| 426 read first rest |
| 427 echo "$first" |
| 428 } |
| 429 |
| 430 binary_to_desktop_file() |
| 431 { |
| 432 search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/sha
re:/usr/share}" |
| 433 binary="`which "$1"`" |
| 434 base="`basename "$1"`" |
| 435 IFS=: |
| 436 for dir in $search; do |
| 437 unset IFS |
| 438 [ "$dir" -a -d "$dir/applications" ] || continue |
| 439 for file in "$dir"/applications/*.desktop; do |
| 440 [ -r "$file" ] || continue |
| 441 # Check to make sure it's worth the processing |
| 442 grep -q "^Exec.*$base" "$file" || continue |
| 443 exec="`grep "^Exec\(\[[^]=]*]\)\?=" "$file" | cut -d= -f 2- | first_
word`" |
| 444 full="`which "$exec"`" |
| 445 if [ x"$full" = x"$binary" ]; then |
| 446 # Fix any double slashes that got added path composition |
| 447 echo "$file" | sed -e 's,//*,/,g' |
| 448 return |
| 449 fi |
| 450 done |
| 451 done |
| 452 } |
| 453 |
| 454 desktop_file_to_command() |
| 455 { |
| 456 search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/sha
re:/usr/share}" |
| 457 desktop="`basename "$1"`" |
| 458 IFS=: |
| 459 for dir in $search; do |
| 460 [ "$dir" -a -d "$dir/applications" ] || continue |
| 461 file="$dir/applications/$desktop" |
| 462 [ -r "$file" ] || continue |
| 463 # Change %F, %f, %U, and %u to %s |
| 464 grep "^Exec\(\[[^]=]*]\)\?=" "$file" | cut -d= -f 2- | sed -e 's/%[FfUu]
/%s/g' |
| 465 return |
| 466 done |
| 467 } |
| 468 |
| 469 get_browser_gnome() |
| 470 { |
| 471 binary="`gconftool-2 --get /desktop/gnome/applications/browser/exec`" |
| 472 if [ x"$binary" = x ]; then |
| 473 # No default browser; GNOME might use the MIME type text/html |
| 474 get_browser_mime |
| 475 else |
| 476 # gconftool gives the binary (maybe with %s etc. afterward), |
| 477 # but we want the desktop file name, not the binary. So, we |
| 478 # have to find the desktop file to which it corresponds. |
| 479 binary="`echo "$binary" | first_word`" |
| 480 desktop="`binary_to_desktop_file "$binary"`" |
| 481 if [ "$desktop" ]; then |
| 482 basename "$desktop" |
| 483 exit_success |
| 484 fi |
| 485 binary="`which "$binary"`" |
| 486 if [ "$binary" ]; then |
| 487 echo "$binary" |
| 488 exit_success |
| 489 fi |
| 490 exit_failure_operation_failed |
| 491 fi |
| 492 } |
| 493 |
| 494 set_browser_gnome() |
| 495 { |
| 496 command="`desktop_file_to_command "$1"`" |
| 497 [ "$command" ] || exit_failure_file_missing |
| 498 binary="`echo "$command" | first_word`" |
| 499 set_browser_mime "$1" || return |
| 500 |
| 501 # Set the default browser |
| 502 gconftool-2 --type string --set /desktop/gnome/applications/browser/exec "$b
inary" |
| 503 gconftool-2 --type bool --set /desktop/gnome/applications/browser/needs_term
false |
| 504 gconftool-2 --type bool --set /desktop/gnome/applications/browser/nremote tr
ue |
| 505 # Set the handler for HTTP and HTTPS |
| 506 for protocol in http https; do |
| 507 gconftool-2 --type string --set /desktop/gnome/url-handlers/$protocol/co
mmand "$command" |
| 508 gconftool-2 --type bool --set /desktop/gnome/url-handlers/$protocol/need
s_terminal false |
| 509 gconftool-2 --type bool --set /desktop/gnome/url-handlers/$protocol/enab
led true |
| 510 done |
| 511 # Set the handler for about: and unknown URL types |
| 512 for protocol in about unknown; do |
| 513 gconftool-2 --type string --set /desktop/gnome/url-handlers/$protocol/co
mmand "$command" |
| 514 done |
| 515 } |
| 516 |
| 517 get_browser_xfce() |
| 518 { |
| 519 # Not supported yet |
| 520 exit_failure_operation_impossible |
| 521 } |
| 522 |
| 523 set_browser_xfce() |
| 524 { |
| 525 # Not supported yet |
| 526 exit_failure_operation_impossible |
| 527 } |
| 528 |
| 529 # }}} default browser |
| 530 |
| 531 dispatch_specific() |
| 532 { |
| 533 # The PARM comments in this function are used to generate the output of |
| 534 # the --list option. The formatting is important. Make sure to line up the |
| 535 # property descriptions with spaces so that it will look nice. |
| 536 if [ x"$op" = x"get" ]; then |
| 537 case "$parm" in |
| 538 default-web-browser) # PROP: Default web browser |
| 539 get_browser_$DE |
| 540 ;; |
| 541 |
| 542 *) |
| 543 exit_failure_syntax |
| 544 ;; |
| 545 esac |
| 546 else # set |
| 547 [ $# -eq 1 ] || exit_failure_syntax "unexpected/missing argument" |
| 548 case "$parm" in |
| 549 default-web-browser) |
| 550 check_desktop_filename "$1" |
| 551 set_browser_$DE "$1" |
| 552 ;; |
| 553 |
| 554 *) |
| 555 exit_failure_syntax |
| 556 ;; |
| 557 esac |
| 558 fi |
| 559 |
| 560 if [ $? -eq 0 ]; then |
| 561 exit_success |
| 562 else |
| 563 exit_failure_operation_failed |
| 564 fi |
| 565 } |
| 566 |
| 567 dispatch_generic() |
| 568 { |
| 569 # We only know how to get the default web browser |
| 570 [ x"$op" != x"get" ] && exit_failure_operation_impossible |
| 571 [ x"$parm" != x"default-web-browser" ] && exit_failure_operation_impossible |
| 572 |
| 573 # FIXME: look up the desktop file name |
| 574 |
| 575 # First look in $BROWSER |
| 576 if [ x"$BROWSER" != x ]; then |
| 577 echo "${BROWSER%%:*}" |
| 578 exit_success |
| 579 fi |
| 580 |
| 581 # Debian and Ubuntu (and others?) have x-www-browser |
| 582 browser="`which x-www-browser`" |
| 583 [ "$browser" ] || exit_failure_operation_failed |
| 584 browser="`readlink -f "$browser"`" |
| 585 |
| 586 echo "$browser" |
| 587 exit_success |
| 588 } |
| 589 |
| 590 if [ x"$1" = x"--list" ]; then |
| 591 echo "Known properties:" |
| 592 # Extract the property names from dispatch_specific() above |
| 593 grep "^[ ]*[^)]*) # PROP:" "$0" | sed -e 's/^[ ]*\([^)]*\)) # PROP: \(.
*\)$/ \1 \2/' | sort |
| 594 exit_success |
| 595 fi |
| 596 |
| 597 [ x"$1" != x ] || exit_failure_syntax "no operation given" |
| 598 [ x"$2" != x ] || exit_failure_syntax "no parameter name given" |
| 599 |
| 600 op="$1" |
| 601 parm="$2" |
| 602 shift 2 |
| 603 |
| 604 [ x"$op" = x"get" -o x"$op" = x"set" ] || exit_failure_syntax "invalid operation
" |
| 605 |
| 606 detectDE |
| 607 |
| 608 case "$DE" in |
| 609 kde|gnome|xfce) |
| 610 dispatch_specific "$@" |
| 611 ;; |
| 612 |
| 613 generic) |
| 614 dispatch_generic "$@" |
| 615 ;; |
| 616 |
| 617 *) |
| 618 exit_failure_operation_impossible "unknown desktop environment" |
| 619 ;; |
| 620 esac |
| OLD | NEW |