| |
| #---------------------------------------------------------------------------- |
| # Common utility functions included in all XDG wrapper scripts |
| #---------------------------------------------------------------------------- |
| |
| DEBUG() |
| { |
| [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && return 0; |
| [ ${XDG_UTILS_DEBUG_LEVEL} -lt $1 ] && return 0; |
| shift |
| echo "$@" >&2 |
| } |
| |
| # This handles backslashes but not quote marks. |
| first_word() |
| { |
| read first rest |
| echo "$first" |
| } |
| |
| #------------------------------------------------------------- |
| # map a binary to a .desktop file |
| binary_to_desktop_file() |
| { |
| search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" |
| binary="`which "$1"`" |
| binary="`readlink -f "$binary"`" |
| base="`basename "$binary"`" |
| IFS=: |
| for dir in $search; do |
| unset IFS |
| [ "$dir" ] || continue |
| [ -d "$dir/applications" -o -d "$dir/applnk" ] || continue |
| for file in "$dir"/applications/*.desktop "$dir"/applications/*/*.desktop "$dir"/applnk/*.desktop "$dir"/applnk/*/*.desktop; do |
| [ -r "$file" ] || continue |
| # Check to make sure it's worth the processing. |
| grep -q "^Exec.*$base" "$file" || continue |
| # Make sure it's a visible desktop file (e.g. not "preferred-web-browser.desktop"). |
| grep -Eq "^(NoDisplay|Hidden)=true" "$file" && continue |
| command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" |
| command="`which "$command"`" |
| if [ x"`readlink -f "$command"`" = x"$binary" ]; then |
| # Fix any double slashes that got added path composition |
| echo "$file" | sed -e 's,//*,/,g' |
| return |
| fi |
| done |
| done |
| } |
| |
| #------------------------------------------------------------- |
| # map a .desktop file to a binary |
| ## FIXME: handle vendor dir case |
| desktop_file_to_binary() |
| { |
| search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" |
| desktop="`basename "$1"`" |
| IFS=: |
| for dir in $search; do |
| unset IFS |
| [ "$dir" -a -d "$dir/applications" ] || continue |
| file="$dir/applications/$desktop" |
| [ -r "$file" ] || continue |
| # Remove any arguments (%F, %f, %U, %u, etc.). |
| command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" |
| command="`which "$command"`" |
| readlink -f "$command" |
| return |
| done |
| } |
| |
| #------------------------------------------------------------- |
| # Exit script on successfully completing the desired operation |
| |
| exit_success() |
| { |
| if [ $# -gt 0 ]; then |
| echo "$@" |
| echo |
| fi |
| |
| exit 0 |
| } |
| |
| |
| #----------------------------------------- |
| # Exit script on malformed arguments, not enough arguments |
| # or missing required option. |
| # prints usage information |
| |
| exit_failure_syntax() |
| { |
| if [ $# -gt 0 ]; then |
| echo "@NAME@: $@" >&2 |
| echo "Try '@NAME@ --help' for more information." >&2 |
| else |
| usage |
| echo "Use 'man @NAME@' or '@NAME@ --manual' for additional info." |
| fi |
| |
| exit 1 |
| } |
| |
| #------------------------------------------------------------- |
| # Exit script on missing file specified on command line |
| |
| exit_failure_file_missing() |
| { |
| if [ $# -gt 0 ]; then |
| echo "@NAME@: $@" >&2 |
| fi |
| |
| exit 2 |
| } |
| |
| #------------------------------------------------------------- |
| # Exit script on failure to locate necessary tool applications |
| |
| exit_failure_operation_impossible() |
| { |
| if [ $# -gt 0 ]; then |
| echo "@NAME@: $@" >&2 |
| fi |
| |
| exit 3 |
| } |
| |
| #------------------------------------------------------------- |
| # Exit script on failure returned by a tool application |
| |
| exit_failure_operation_failed() |
| { |
| if [ $# -gt 0 ]; then |
| echo "@NAME@: $@" >&2 |
| fi |
| |
| exit 4 |
| } |
| |
| #------------------------------------------------------------ |
| # Exit script on insufficient permission to read a specified file |
| |
| exit_failure_file_permission_read() |
| { |
| if [ $# -gt 0 ]; then |
| echo "@NAME@: $@" >&2 |
| fi |
| |
| exit 5 |
| } |
| |
| #------------------------------------------------------------ |
| # Exit script on insufficient permission to write a specified file |
| |
| exit_failure_file_permission_write() |
| { |
| if [ $# -gt 0 ]; then |
| echo "@NAME@: $@" >&2 |
| fi |
| |
| exit 6 |
| } |
| |
| check_input_file() |
| { |
| if [ ! -e "$1" ]; then |
| exit_failure_file_missing "file '$1' does not exist" |
| fi |
| if [ ! -r "$1" ]; then |
| exit_failure_file_permission_read "no permission to read file '$1'" |
| fi |
| } |
| |
| check_vendor_prefix() |
| { |
| file_label="$2" |
| [ -n "$file_label" ] || file_label="filename" |
| file=`basename "$1"` |
| case "$file" in |
| [a-zA-Z]*-*) |
| return |
| ;; |
| esac |
| |
| echo "@NAME@: $file_label '$file' does not have a proper vendor prefix" >&2 |
| echo 'A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated' >&2 |
| echo 'with a dash ("-"). An example '"$file_label"' is '"'example-$file'" >&2 |
| echo "Use --novendor to override or '@NAME@ --manual' for additional info." >&2 |
| exit 1 |
| } |
| |
| check_output_file() |
| { |
| # if the file exists, check if it is writeable |
| # if it does not exists, check if we are allowed to write on the directory |
| if [ -e "$1" ]; then |
| if [ ! -w "$1" ]; then |
| exit_failure_file_permission_write "no permission to write to file '$1'" |
| fi |
| else |
| DIR=`dirname "$1"` |
| if [ ! -w "$DIR" -o ! -x "$DIR" ]; then |
| exit_failure_file_permission_write "no permission to create file '$1'" |
| fi |
| fi |
| } |
| |
| #---------------------------------------- |
| # Checks for shared commands, e.g. --help |
| |
| check_common_commands() |
| { |
| while [ $# -gt 0 ] ; do |
| parm="$1" |
| shift |
| |
| case "$parm" in |
| --help) |
| usage |
| echo "Use 'man @NAME@' or '@NAME@ --manual' for additional info." |
| exit_success |
| ;; |
| |
| --manual) |
| manualpage |
| exit_success |
| ;; |
| |
| --version) |
| echo "@NAME@ 1.1.0 rc1" |
| exit_success |
| ;; |
| esac |
| done |
| } |
| |
| check_common_commands "$@" |
| |
| [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && unset XDG_UTILS_DEBUG_LEVEL; |
| if [ ${XDG_UTILS_DEBUG_LEVEL-0} -lt 1 ]; then |
| # Be silent |
| xdg_redirect_output=" > /dev/null 2> /dev/null" |
| else |
| # All output to stderr |
| xdg_redirect_output=" >&2" |
| fi |
| |
| #-------------------------------------- |
| # Checks for known desktop environments |
| # set variable DE to the desktop environments name, lowercase |
| |
| detectDE() |
| { |
| # see https://bugs.freedesktop.org/show_bug.cgi?id=34164 |
| unset GREP_OPTIONS |
| |
| if [ -n "${XDG_CURRENT_DESKTOP}" ]; then |
| case "${XDG_CURRENT_DESKTOP}" in |
| GNOME) |
| DE=gnome; |
| ;; |
| KDE) |
| DE=kde; |
| ;; |
| LXDE) |
| DE=lxde; |
| ;; |
| XFCE) |
| DE=xfce |
| esac |
| fi |
| |
| if [ x"$DE" = x"" ]; then |
| # classic fallbacks |
| if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; |
| elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; |
| 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; |
| elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; |
| elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then DE=xfce |
| fi |
| fi |
| |
| if [ x"$DE" = x"" ]; then |
| # fallback to checking $DESKTOP_SESSION |
| case "$DESKTOP_SESSION" in |
| gnome) |
| DE=gnome; |
| ;; |
| LXDE) |
| DE=lxde; |
| ;; |
| xfce|xfce4) |
| DE=xfce; |
| ;; |
| esac |
| fi |
| |
| if [ x"$DE" = x"" ]; then |
| # fallback to uname output for other platforms |
| case "$(uname 2>/dev/null)" in |
| Darwin) |
| DE=darwin; |
| ;; |
| esac |
| fi |
| |
| if [ x"$DE" = x"gnome" ]; then |
| # gnome-default-applications-properties is only available in GNOME 2.x |
| # but not in GNOME 3.x |
| which gnome-default-applications-properties > /dev/null 2>&1 || DE="gnome3" |
| fi |
| } |
| |
| #---------------------------------------------------------------------------- |
| # kfmclient exec/openURL can give bogus exit value in KDE <= 3.5.4 |
| # It also always returns 1 in KDE 3.4 and earlier |
| # Simply return 0 in such case |
| |
| kfmclient_fix_exit_code() |
| { |
| version=`LC_ALL=C.UTF-8 kde-config --version 2>/dev/null | grep '^KDE'` |
| major=`echo $version | sed 's/KDE.*: \([0-9]\).*/\1/'` |
| minor=`echo $version | sed 's/KDE.*: [0-9]*\.\([0-9]\).*/\1/'` |
| release=`echo $version | sed 's/KDE.*: [0-9]*\.[0-9]*\.\([0-9]\).*/\1/'` |
| test "$major" -gt 3 && return $1 |
| test "$minor" -gt 5 && return $1 |
| test "$release" -gt 4 && return $1 |
| return 0 |
| } |