1 2#---------------------------------------------------------------------------- 3# Common utility functions included in all XDG wrapper scripts 4#---------------------------------------------------------------------------- 5 6DEBUG() 7{ 8 [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && return 0; 9 [ ${XDG_UTILS_DEBUG_LEVEL} -lt $1 ] && return 0; 10 shift 11 echo "$@" >&2 12} 13 14# This handles backslashes but not quote marks. 15first_word() 16{ 17 read first rest 18 echo "$first" 19} 20 21#------------------------------------------------------------- 22# map a binary to a .desktop file 23binary_to_desktop_file() 24{ 25 search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" 26 binary="`which "$1"`" 27 binary="`readlink -f "$binary"`" 28 base="`basename "$binary"`" 29 IFS=: 30 for dir in $search; do 31 unset IFS 32 [ "$dir" ] || continue 33 [ -d "$dir/applications" -o -d "$dir/applnk" ] || continue 34 for file in "$dir"/applications/*.desktop "$dir"/applications/*/*.desktop "$dir"/applnk/*.desktop "$dir"/applnk/*/*.desktop; do 35 [ -r "$file" ] || continue 36 # Check to make sure it's worth the processing. 37 grep -q "^Exec.*$base" "$file" || continue 38 # Make sure it's a visible desktop file (e.g. not "preferred-web-browser.desktop"). 39 grep -Eq "^(NoDisplay|Hidden)=true" "$file" && continue 40 command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" 41 command="`which "$command"`" 42 if [ x"`readlink -f "$command"`" = x"$binary" ]; then 43 # Fix any double slashes that got added path composition 44 echo "$file" | sed -e 's,//*,/,g' 45 return 46 fi 47 done 48 done 49} 50 51#------------------------------------------------------------- 52# map a .desktop file to a binary 53## FIXME: handle vendor dir case 54desktop_file_to_binary() 55{ 56 search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" 57 desktop="`basename "$1"`" 58 IFS=: 59 for dir in $search; do 60 unset IFS 61 [ "$dir" -a -d "$dir/applications" ] || continue 62 file="$dir/applications/$desktop" 63 [ -r "$file" ] || continue 64 # Remove any arguments (%F, %f, %U, %u, etc.). 65 command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" 66 command="`which "$command"`" 67 readlink -f "$command" 68 return 69 done 70} 71 72#------------------------------------------------------------- 73# Exit script on successfully completing the desired operation 74 75exit_success() 76{ 77 if [ $# -gt 0 ]; then 78 echo "$@" 79 echo 80 fi 81 82 exit 0 83} 84 85 86#----------------------------------------- 87# Exit script on malformed arguments, not enough arguments 88# or missing required option. 89# prints usage information 90 91exit_failure_syntax() 92{ 93 if [ $# -gt 0 ]; then 94 echo "@NAME@: $@" >&2 95 echo "Try '@NAME@ --help' for more information." >&2 96 else 97 usage 98 echo "Use 'man @NAME@' or '@NAME@ --manual' for additional info." 99 fi 100 101 exit 1 102} 103 104#------------------------------------------------------------- 105# Exit script on missing file specified on command line 106 107exit_failure_file_missing() 108{ 109 if [ $# -gt 0 ]; then 110 echo "@NAME@: $@" >&2 111 fi 112 113 exit 2 114} 115 116#------------------------------------------------------------- 117# Exit script on failure to locate necessary tool applications 118 119exit_failure_operation_impossible() 120{ 121 if [ $# -gt 0 ]; then 122 echo "@NAME@: $@" >&2 123 fi 124 125 exit 3 126} 127 128#------------------------------------------------------------- 129# Exit script on failure returned by a tool application 130 131exit_failure_operation_failed() 132{ 133 if [ $# -gt 0 ]; then 134 echo "@NAME@: $@" >&2 135 fi 136 137 exit 4 138} 139 140#------------------------------------------------------------ 141# Exit script on insufficient permission to read a specified file 142 143exit_failure_file_permission_read() 144{ 145 if [ $# -gt 0 ]; then 146 echo "@NAME@: $@" >&2 147 fi 148 149 exit 5 150} 151 152#------------------------------------------------------------ 153# Exit script on insufficient permission to write a specified file 154 155exit_failure_file_permission_write() 156{ 157 if [ $# -gt 0 ]; then 158 echo "@NAME@: $@" >&2 159 fi 160 161 exit 6 162} 163 164check_input_file() 165{ 166 if [ ! -e "$1" ]; then 167 exit_failure_file_missing "file '$1' does not exist" 168 fi 169 if [ ! -r "$1" ]; then 170 exit_failure_file_permission_read "no permission to read file '$1'" 171 fi 172} 173 174check_vendor_prefix() 175{ 176 file_label="$2" 177 [ -n "$file_label" ] || file_label="filename" 178 file=`basename "$1"` 179 case "$file" in 180 [a-zA-Z]*-*) 181 return 182 ;; 183 esac 184 185 echo "@NAME@: $file_label '$file' does not have a proper vendor prefix" >&2 186 echo 'A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated' >&2 187 echo 'with a dash ("-"). An example '"$file_label"' is '"'example-$file'" >&2 188 echo "Use --novendor to override or '@NAME@ --manual' for additional info." >&2 189 exit 1 190} 191 192check_output_file() 193{ 194 # if the file exists, check if it is writeable 195 # if it does not exists, check if we are allowed to write on the directory 196 if [ -e "$1" ]; then 197 if [ ! -w "$1" ]; then 198 exit_failure_file_permission_write "no permission to write to file '$1'" 199 fi 200 else 201 DIR=`dirname "$1"` 202 if [ ! -w "$DIR" -o ! -x "$DIR" ]; then 203 exit_failure_file_permission_write "no permission to create file '$1'" 204 fi 205 fi 206} 207 208#---------------------------------------- 209# Checks for shared commands, e.g. --help 210 211check_common_commands() 212{ 213 while [ $# -gt 0 ] ; do 214 parm="$1" 215 shift 216 217 case "$parm" in 218 --help) 219 usage 220 echo "Use 'man @NAME@' or '@NAME@ --manual' for additional info." 221 exit_success 222 ;; 223 224 --manual) 225 manualpage 226 exit_success 227 ;; 228 229 --version) 230 echo "@NAME@ 1.1.0 rc1" 231 exit_success 232 ;; 233 esac 234 done 235} 236 237check_common_commands "$@" 238 239[ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && unset XDG_UTILS_DEBUG_LEVEL; 240if [ ${XDG_UTILS_DEBUG_LEVEL-0} -lt 1 ]; then 241 # Be silent 242 xdg_redirect_output=" > /dev/null 2> /dev/null" 243else 244 # All output to stderr 245 xdg_redirect_output=" >&2" 246fi 247 248#-------------------------------------- 249# Checks for known desktop environments 250# set variable DE to the desktop environments name, lowercase 251 252detectDE() 253{ 254 # see https://bugs.freedesktop.org/show_bug.cgi?id=34164 255 unset GREP_OPTIONS 256 257 if [ -n "${XDG_CURRENT_DESKTOP}" ]; then 258 case "${XDG_CURRENT_DESKTOP}" in 259 GNOME) 260 DE=gnome; 261 ;; 262 KDE) 263 DE=kde; 264 ;; 265 LXDE) 266 DE=lxde; 267 ;; 268 XFCE) 269 DE=xfce 270 esac 271 fi 272 273 if [ x"$DE" = x"" ]; then 274 # classic fallbacks 275 if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; 276 elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; 277 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; 278 elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; 279 elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then DE=xfce 280 fi 281 fi 282 283 if [ x"$DE" = x"" ]; then 284 # fallback to checking $DESKTOP_SESSION 285 case "$DESKTOP_SESSION" in 286 gnome) 287 DE=gnome; 288 ;; 289 LXDE) 290 DE=lxde; 291 ;; 292 xfce|xfce4) 293 DE=xfce; 294 ;; 295 esac 296 fi 297 298 if [ x"$DE" = x"" ]; then 299 # fallback to uname output for other platforms 300 case "$(uname 2>/dev/null)" in 301 Darwin) 302 DE=darwin; 303 ;; 304 esac 305 fi 306 307 if [ x"$DE" = x"gnome" ]; then 308 # gnome-default-applications-properties is only available in GNOME 2.x 309 # but not in GNOME 3.x 310 which gnome-default-applications-properties > /dev/null 2>&1 || DE="gnome3" 311 fi 312} 313 314#---------------------------------------------------------------------------- 315# kfmclient exec/openURL can give bogus exit value in KDE <= 3.5.4 316# It also always returns 1 in KDE 3.4 and earlier 317# Simply return 0 in such case 318 319kfmclient_fix_exit_code() 320{ 321 version=`LC_ALL=C.UTF-8 kde-config --version 2>/dev/null | grep '^KDE'` 322 major=`echo $version | sed 's/KDE.*: \([0-9]\).*/\1/'` 323 minor=`echo $version | sed 's/KDE.*: [0-9]*\.\([0-9]\).*/\1/'` 324 release=`echo $version | sed 's/KDE.*: [0-9]*\.[0-9]*\.\([0-9]\).*/\1/'` 325 test "$major" -gt 3 && return $1 326 test "$minor" -gt 5 && return $1 327 test "$release" -gt 4 && return $1 328 return 0 329} 330