Mini Shell
Direktori : /bin/ |
|
Current File : //bin/xdg-mime |
#!/bin/sh
#---------------------------------------------
# xdg-mime
#
# Utility script to manipulate MIME related information
# on XDG compliant systems.
#
# Refer to the usage() function below for usage.
#
# Copyright 2009-2010, Fathi Boudra <fabo@freedesktop.org>
# Copyright 2009-2010, Rex Dieter <rdieter@fedoraproject.org>
# Copyright 2006, Kevin Krammer <kevin.krammer@gmx.at>
# Copyright 2006, Jeremy White <jwhite@codeweavers.com>
#
# LICENSE:
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
#---------------------------------------------
manualpage()
{
cat << _MANUALPAGE
Name
xdg-mime - command line tool for querying information about
file type handling and adding descriptions for new file types
Synopsis
xdg-mime query { filetype | default } ...
xdg-mime default application mimetype(s)
xdg-mime install [--mode mode] [--novendor] mimetypes-file
xdg-mime uninstall [--mode mode] mimetypes-file
xdg-mime { --help | --manual | --version }
Description
The xdg-mime program can be used to query information about
file types and to add descriptions for new file types.
Commands
query
Returns information related to file types.
The query option is for use inside a desktop session
only. It is not recommended to use xdg-mime query as
root.
The following queries are supported:
query filetype FILE: Returns the file type of FILE in
the form of a MIME type.
query default mimetype: Returns the default application
that the desktop environment uses for opening files of
type mimetype. The default application is identified by
its *.desktop file.
default
Ask the desktop environment to make application the
default application for opening files of type mimetype.
An application can be made the default for several file
types by specifying multiple mimetypes.
application is the desktop file id of the application
and has the form vendor-name.desktop. application must
already be installed in the desktop menu before it can
be made the default handler. The application's desktop
file must list support for all the MIME types that it
wishes to be the default handler for.
Requests to make an application a default handler may be
subject to system policy or approval by the end-user.
xdg-mime query can be used to verify whether an
application is the actual default handler for a specific
file type.
The default option is for use inside a desktop session
only. It is not recommended to use xdg-mime default as
root.
install
Adds the file type descriptions provided in
mimetypes-file to the desktop environment.
mimetypes-file must be a XML file that follows the
freedesktop.org Shared MIME-info Database specification
and that has a mime-info element as its document root.
For each new file type one or more icons with name
type-subtype must be installed with the
xdg-icon-resource command in the mimetypes context. For
example the filetype
application/vnd.oasis.opendocument.text requires an icon
named application-vnd.oasis.opendocument.text to be
installed (unless the file type recommends another icon
name).
uninstall
Removes the file type descriptions provided in
mimetypes-file and previously added with xdg-mime
install from the desktop environment. mimetypes-file
must be a XML file that follows the freedesktop.org
Shared MIME-info Database specification and that has a
mime-info element as its document root.
Options
--mode mode
mode can be user or system. In user mode the file is
(un)installed for the current user only. In system mode
the file is (un)installed for all users on the system.
Usually only root is allowed to install in system mode.
The default is to use system mode when called by root
and to use user mode when called by a non-root user.
--novendor
Normally, xdg-mime checks to ensure that the
mimetypes-file to be installed has a proper vendor
prefix. This option can be used to disable that check.
A vendor prefix consists of alpha characters ([a-zA-Z])
and is terminated with a dash ("-"). Companies and
organizations are encouraged to use a word or phrase,
preferably the organizations name, for which they hold a
trademark as their vendor prefix. The purpose of the
vendor prefix is to prevent name conflicts.
--help
Show command synopsis.
--manual
Show this manual page.
--version
Show the xdg-utils version information.
Environment Variables
xdg-mime honours the following environment variables:
XDG_UTILS_DEBUG_LEVEL
Setting this environment variable to a non-zero
numerical value makes xdg-mime do more verbose reporting
on stderr. Setting a higher value increases the
verbosity.
XDG_UTILS_INSTALL_MODE
This environment variable can be used by the user or
administrator to override the installation mode. Valid
values are user and system.
Exit Codes
An exit code of 0 indicates success while a non-zero exit code
indicates failure. The following failure codes can be returned:
1
Error in command line syntax.
2
One of the files passed on the command line did not
exist.
3
A required tool could not be found.
4
The action failed.
5
No permission to read one of the files passed on the
command line.
See Also
xdg-icon-resource(1), xdg-desktop-menu(1), Shared MIME database
specification, MIME applications associations specification
Examples
xdg-mime query filetype /tmp/foobar.png
Prints the MIME type of the file /tmp/foobar.png, in this case
image/png
xdg-mime query default image/png
Prints the .desktop filename of the application which is
registered to open PNG files.
xdg-mime install shinythings-shiny.xml
Adds a file type description for "shiny"-files. "shinythings-"
is used as the vendor prefix. The file type description could
look as follows.
shinythings-shiny.xml:
<?xml version="1.0"?>
<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'
>
<mime-type type="text/x-shiny">
<comment>Shiny new file type</comment>
<glob pattern="*.shiny"/>
<glob pattern="*.shi"/>
</mime-type>
</mime-info>
An icon for this new file type must also be installed, for
example with:
xdg-icon-resource install --context mimetypes --size 64 shiny-file-icon.
png text-x-shiny
_MANUALPAGE
}
usage()
{
cat << _USAGE
xdg-mime - command line tool for querying information about
file type handling and adding descriptions for new file types
Synopsis
xdg-mime query { filetype | default } ...
xdg-mime default application mimetype(s)
xdg-mime install [--mode mode] [--novendor] mimetypes-file
xdg-mime uninstall [--mode mode] mimetypes-file
xdg-mime { --help | --manual | --version }
_USAGE
}
#@xdg-utils-common@
#----------------------------------------------------------------------------
# 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" ] || [ -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
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" ] && [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue
# Check if desktop file contains -
if [ "${desktop#*-}" != "$desktop" ]; then
vendor=${desktop%-*}
app=${desktop#*-}
if [ -r $dir/applications/$vendor/$app ]; then
file_path=$dir/applications/$vendor/$app
elif [ -r $dir/applnk/$vendor/$app ]; then
file_path=$dir/applnk/$vendor/$app
fi
fi
if test -z "$file_path" ; then
for indir in "$dir"/applications/ "$dir"/applications/*/ "$dir"/applnk/ "$dir"/applnk/*/; do
file="$indir/$desktop"
if [ -r "$file" ]; then
file_path=$file
break
fi
done
fi
if [ -r "$file_path" ]; then
# Remove any arguments (%F, %f, %U, %u, etc.).
command="`grep -E "^Exec(\[[^]=]*])?=" "$file_path" | cut -d= -f 2- | first_word`"
command="`which "$command"`"
readlink -f "$command"
return
fi
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 "xdg-mime: $@" >&2
echo "Try 'xdg-mime --help' for more information." >&2
else
usage
echo "Use 'man xdg-mime' or 'xdg-mime --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 "xdg-mime: $@" >&2
fi
exit 2
}
#-------------------------------------------------------------
# Exit script on failure to locate necessary tool applications
exit_failure_operation_impossible()
{
if [ $# -gt 0 ]; then
echo "xdg-mime: $@" >&2
fi
exit 3
}
#-------------------------------------------------------------
# Exit script on failure returned by a tool application
exit_failure_operation_failed()
{
if [ $# -gt 0 ]; then
echo "xdg-mime: $@" >&2
fi
exit 4
}
#------------------------------------------------------------
# Exit script on insufficient permission to read a specified file
exit_failure_file_permission_read()
{
if [ $# -gt 0 ]; then
echo "xdg-mime: $@" >&2
fi
exit 5
}
#------------------------------------------------------------
# Exit script on insufficient permission to write a specified file
exit_failure_file_permission_write()
{
if [ $# -gt 0 ]; then
echo "xdg-mime: $@" >&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
[[:alpha:]]*-*)
return
;;
esac
echo "xdg-mime: $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 'xdg-mime --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" ] || [ ! -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 xdg-mime' or 'xdg-mime --manual' for additional info."
exit_success
;;
--manual)
manualpage
exit_success
;;
--version)
echo "xdg-mime 1.1.2+"
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
# only recently added to menu-spec, pre-spec X- still in use
Cinnamon|X-Cinnamon)
DE=cinnamon;
;;
ENLIGHTENMENT)
DE=enlightenment;
;;
# GNOME, GNOME-Classic:GNOME, or GNOME-Flashback:GNOME
GNOME*)
DE=gnome;
;;
KDE)
DE=kde;
;;
LXDE)
DE=lxde;
;;
LXQt)
DE=lxqt;
;;
MATE)
DE=mate;
;;
XFCE)
DE=xfce
;;
X-Generic)
DE=generic
;;
esac
fi
if [ x"$DE" = x"" ]; then
# classic fallbacks
if [ x"$KDE_FULL_SESSION" != x"" ]; then DE=kde;
elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome;
elif [ x"$MATE_DESKTOP_SESSION_ID" != x"" ]; then DE=mate;
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
elif echo $DESKTOP | grep -q '^Enlightenment'; then DE=enlightenment;
elif [ x"$LXQT_SESSION_CONFIG" != x"" ]; then DE=lxqt;
fi
fi
if [ x"$DE" = x"" ]; then
# fallback to checking $DESKTOP_SESSION
case "$DESKTOP_SESSION" in
gnome)
DE=gnome;
;;
LXDE|Lubuntu)
DE=lxde;
;;
MATE)
DE=mate;
;;
xfce|xfce4|'Xfce Session')
DE=xfce;
;;
esac
fi
if [ x"$DE" = x"" ]; then
# fallback to uname output for other platforms
case "$(uname 2>/dev/null)" in
CYGWIN*)
DE=cygwin;
;;
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
if [ -f "$XDG_RUNTIME_DIR/flatpak-info" ]; then
DE="flatpak"
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
}
#----------------------------------------------------------------------------
# Returns true if there is a graphical display attached.
has_display()
{
if [ -n "$DISPLAY" ] || [ -n "$WAYLAND_DISPLAY" ]; then
return 0
else
return 1
fi
}
update_mime_database()
{
if [ "$mode" = user ] && has_display; then
detectDE
if [ x"$DE" = x"kde" ] ; then
DEBUG 1 "Running kbuildsycoca"
eval 'kbuildsycoca${KDE_SESSION_VERSION}'$xdg_redirect_output
fi
fi
for x in `echo "$PATH:/opt/gnome/bin" | sed 's/:/ /g'`; do
if [ -x $x/update-mime-database ] ; then
DEBUG 1 "Running $x/update-mime-database $1"
eval '$x/update-mime-database $1'$xdg_redirect_output
return
fi
done
}
info_kde()
{
if [ -n "${KDE_SESSION_VERSION}" ]; then
case "${KDE_SESSION_VERSION}" in
4)
DEBUG 1 "Running kmimetypefinder \"$1\""
kmimetypefinder "$1" 2>/dev/null | head -n 1
;;
5)
DEBUG 1 "Running kmimetypefinder${KDE_SESSION_VERSION} \"$1\""
kmimetypefinder${KDE_SESSION_VERSION} "$1" 2>/dev/null | head -n 1
;;
esac
else
DEBUG 1 "Running kfile \"$1\""
kfile "$1" 2> /dev/null | head -n 1 | cut -d "(" -f 2 | cut -d ")" -f 1
fi
if [ $? -eq 0 ]; then
exit_success
else
exit_failure_operation_failed
fi
}
info_gnome()
{
if gio help info 2>/dev/null 1>&2; then
DEBUG 1 "Running gio info \"$1\""
gio info "$1" 2> /dev/null | grep standard::content-type | cut -d' ' -f4
elif gvfs-info --help 2>/dev/null 1>&2; then
DEBUG 1 "Running gvfs-info \"$1\""
gvfs-info "$1" 2> /dev/null | grep standard::content-type | cut -d' ' -f4
elif gnomevfs-info --help 2>/dev/null 1>&2; then
DEBUG 1 "Running gnomevfs-info \"$1\""
gnomevfs-info --slow-mime "$1" 2> /dev/null | grep "^MIME" | cut -d ":" -f 2 | sed s/"^ "//
fi
if [ $? -eq 0 ]; then
exit_success
else
exit_failure_operation_failed
fi
}
info_generic()
{
if mimetype --version >/dev/null 2>&1; then
DEBUG 1 "Running mimetype --brief --dereference \"$1\""
mimetype --brief --dereference "$1"
else
DEBUG 1 "Running file --brief --dereference --mime-type \"$1\""
/usr/bin/file --brief --dereference --mime-type "$1" 2> /dev/null
fi
if [ $? -eq 0 ]; then
exit_success
else
exit_failure_operation_failed
fi
}
make_default_kde()
{
# $1 is vendor-name.desktop
# $2 is mime/type
#
# On KDE 3, add to $KDE_CONFIG_PATH/profilerc:
# [$2 - 1]
# Application=$1
#
# Remove all [$2 - *] sections, or even better,
# renumber [$2 - *] sections and remove duplicate
#
# On KDE 4, add $2=$1 to $XDG_DATA_APPS/mimeapps.list
#
# Example file:
#
# [Added Associations]
# text/plain=kde4-kate.desktop;kde4-kwrite.desktop;
#
# [Removed Associations]
# text/plain=gnome-gedit.desktop;gnu-emacs.desktop;
vendor="$1"
mimetype="$2"
if [ x"$KDE_SESSION_VERSION" = x"4" ]; then
default_dir=`kde4-config --path xdgdata-apps 2> /dev/null | cut -d ':' -f 1`
default_file="$default_dir/mimeapps.list"
else
default_dir=`kde-config --path config 2> /dev/null | cut -d ':' -f 1`
default_file="$default_dir/profilerc"
fi
if [ -z "$default_dir" ]; then
DEBUG 2 "make_default_kde: No kde runtime detected"
return
fi
DEBUG 2 "make_default_kde $vendor $mimetype"
DEBUG 1 "Updating $default_file"
mkdir -p "$default_dir"
[ -f "$default_file" ] || touch "$default_file"
if [ x"$KDE_SESSION_VERSION" = x"4" ]; then
[ -f "$default_file" ] || touch "$default_file"
awk -v application="$vendor" -v mimetype="$mimetype" '
BEGIN {
prefix=mimetype "="
associations=0
found=0
blanks=0
}
{
suppress=0
if (index($0, "[Added Associations]") == 1) {
associations=1
} else if (index($0, "[") == 1) {
if (associations && !found) {
print prefix application
found=1
}
associations=0
} else if ($0 == "") {
blanks++
suppress=1
} else if (associations && index($0, prefix) == 1) {
value=substr($0, length(prefix) + 1, length())
split(value, apps, ";")
value=application ";"
count=0
for (i in apps) {
count++
}
for (i=0; i < count; i++) {
if (apps[i] != application && apps[i] != "") {
value=value apps[i] ";"
}
}
$0=prefix value
found=1
}
if (!suppress) {
while (blanks > 0) {
print ""
blanks--
}
print $0
}
}
END {
if (!found) {
if (!associations) {
print "[Added Associations]"
}
print prefix application
}
while (blanks > 0) {
print ""
blanks--
}
}
' "$default_file" > "${default_file}.new" && mv "${default_file}.new" "$default_file"
eval 'kbuildsycoca4'$xdg_redirect_output
else
awk -v application="$vendor" -v mimetype="$mimetype" '
BEGIN {
header_start="[" mimetype " - "
suppress=0
}
{
if (index($0, header_start) == 1 )
suppress=1
else
if (/^\[/) { suppress=0 }
if (!suppress) {
print $0
}
}
END {
print ""
print "[" mimetype " - 1]"
print "Application=" application
print "AllowAsDefault=true"
print "GenericServiceType=Application"
print "Preference=1"
print "ServiceType=" mimetype
}
' "$default_file" > "${default_file}.new" && mv "${default_file}.new" "$default_file"
fi
}
make_default_generic()
{
# $1 is vendor-name.desktop
# $2 is mime/type
# Add $2=$1 to XDG_CONFIG_HOME/mimeapps.list
xdg_config_home="$XDG_CONFIG_HOME"
[ -n "$xdg_config_home" ] || xdg_config_home="$HOME/.config"
default_file="$xdg_config_home/mimeapps.list"
DEBUG 2 "make_default_generic $1 $2"
DEBUG 1 "Updating $default_file"
[ -f "$default_file" ] || touch "$default_file"
awk -v mimetype="$2" -v application="$1" '
BEGIN {
prefix=mimetype "="
indefault=0
added=0
blanks=0
found=0
}
{
suppress=0
if (index($0, "[Default Applications]") == 1) {
indefault=1
found=1
} else if (index($0, "[") == 1) {
if (!added && indefault) {
print prefix application
added=1
}
indefault=0
} else if ($0 == "") {
suppress=1
blanks++
} else if (indefault && !added && index($0, prefix) == 1) {
$0=prefix application
added=1
}
if (!suppress) {
while (blanks > 0) {
print ""
blanks--
}
print $0
}
}
END {
if (!added) {
if (!found) {
print ""
print "[Default Applications]"
}
print prefix application
}
while (blanks > 0) {
print ""
blanks--
}
}
' "$default_file" > "${default_file}.new" && mv "${default_file}.new" "$default_file"
}
search_desktop_file()
{
local MIME="$1"
local dir="$2"
grep -l "$MIME;" "$dir/"*.desktop 2>/dev/null
for f in $dir/*/; do
[ -d "$f" ] && search_desktop_file "$MIME" "$f"
done
}
defapp_fallback()
{
MIME="$1"
xdg_user_dir="$XDG_DATA_HOME"
[ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share"
xdg_system_dirs="$XDG_DATA_DIRS"
[ -n "$xdg_system_dirs" ] || xdg_system_dirs=/usr/local/share/:/usr/share/
preference=-1
desktop_file=""
for d in `echo "$xdg_user_dir:$xdg_system_dirs" | sed 's/:/ /g'`; do
for x in `search_desktop_file "$MIME" "$d/applications"`; do
pref=0`awk -F"=" '/InitialPreference=/ {print($2)}' "$x"`
DEBUG 2 " Checking $x"
if [ $pref -gt $preference ]; then
DEBUG 2 " Select $x [ $preference => $pref ]"
preference=$pref
desktop_file=$x
fi
done
done
if [ -n "$desktop_file" ] ; then
echo `basename $desktop_file`
exit_success
fi
}
check_mimeapps_list()
{
local mimetype="$1" dir="$2"
local desktop oldifs="$IFS"
IFS=:
for desktop in $XDG_CURRENT_DESKTOP ''; do
IFS="$oldifs"
if [ -n "$desktop" ]; then
local prefix=$(echo "$desktop-" | tr '[:upper:]' '[:lower:]')
else
local prefix=
fi
local mimeapps_list="$dir/${prefix}mimeapps.list"
if [ -f "$mimeapps_list" ] ; then
DEBUG 2 "Checking $mimeapps_list"
local result=$(awk -v mimetype="$mimetype" '
BEGIN {
prefix=mimetype "="
indefault=0
found=0
}
{
if (index($0, "[Default Applications]") == 1) {
indefault=1
} else if (index($0, "[") == 1) {
indefault=0
} else if (!found && indefault && index($0, prefix) == 1) {
print substr($0, length(prefix) +1, length())
found=1
}
}
' "$mimeapps_list" | cut -d ';' -f 1)
if [ -n "$result" ]; then
# $result could be a ; separated list of .desktop files
# use the first on the system
IFS=\;
for app in $result; do
IFS="$oldifs"
exists=$(desktop_file_to_binary "$app")
if [ -n "$exists" ]; then
echo "$app"
exit_success
fi
done
fi
fi
done
}
defapp_generic()
{
MIME="$1"
xdg_config_home="$XDG_CONFIG_HOME"
[ -n "$xdg_config_home" ] || xdg_config_home="$HOME/.config"
xdg_config_dirs="$XDG_CONFIG_DIRS"
[ -n "$xdg_config_dirs" ] || xdg_config_dirs="/etc/xdg"
xdg_user_dir="$XDG_DATA_HOME"
[ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share"
xdg_system_dirs="$XDG_DATA_DIRS"
[ -n "$xdg_system_dirs" ] || xdg_system_dirs=/usr/local/share/:/usr/share/
local oldifs="$IFS" dir
IFS=:
for dir in $xdg_config_home $xdg_config_dirs; do
IFS="$oldifs"
check_mimeapps_list "$MIME" "$dir"
done
IFS=:
for dir in $xdg_user_dir $xdg_system_dirs; do
IFS="$oldifs"
check_mimeapps_list "$MIME" "$dir/applications"
done
for x in `echo "$xdg_user_dir:$xdg_system_dirs" | sed 's/:/ /g'`; do
for prefix in "$XDG_MENU_PREFIX" ""; do
DEBUG 2 "Checking $x/applications/${prefix}defaults.list and $x/applications/${prefix}mimeinfo.cache"
trader_result=`grep "$MIME=" $x/applications/${prefix}defaults.list $x/applications/${prefix}mimeinfo.cache 2> /dev/null | head -n 1 | cut -d '=' -f 2 | cut -d ';' -f 1`
if [ -n "$trader_result" ] ; then
echo $trader_result
exit_success
fi
done
done
defapp_fallback $MIME
exit_success
}
defapp_kde()
{
MIME="$1"
if [ -n "${KDE_SESSION_VERSION}" ]; then
case "${KDE_SESSION_VERSION}" in
4)
KTRADER=`which ktraderclient 2> /dev/null`
;;
5)
KTRADER=`which ktraderclient${KDE_SESSION_VERSION} 2> /dev/null`
;;
esac
else
KTRADER=`which ktradertest 2> /dev/null`
fi
if [ -n "$KTRADER" ] ; then
DEBUG 1 "Running KDE trader query \"$MIME\" mimetype and \"Application\" servicetype"
trader_result=`$KTRADER --mimetype "$MIME" --servicetype Application 2>/dev/null \
| grep -E "^DesktopEntryPath : |\.desktop$" | head -n1 | sed "s/^DesktopEntryPath : '\(.*\.desktop\)'\$/\1/"`
if [ -n "$trader_result" ] ; then
basename "$trader_result"
exit_success
else
exit_failure_operation_failed
fi
else
defapp_generic "$1"
fi
}
[ x"$1" != x"" ] || exit_failure_syntax
mode=
action=
filename=
mimetype=
case $1 in
install)
action=install
;;
uninstall)
action=uninstall
;;
query)
shift
if [ -z "$1" ] ; then
exit_failure_syntax "query type argument missing"
fi
case $1 in
filetype)
action=info
filename="$2"
if [ -z "$filename" ] ; then
exit_failure_syntax "FILE argument missing"
fi
case $filename in
-*)
exit_failure_syntax "unexpected option '$filename'"
;;
esac
check_input_file "$filename"
filename=`readlink -f -- "$filename"`
;;
default)
action=defapp
mimetype="$2"
if [ -z "$mimetype" ] ; then
exit_failure_syntax "mimetype argument missing"
fi
case $mimetype in
-*)
exit_failure_syntax "unexpected option '$mimetype'"
;;
*/*)
# Ok
;;
*)
exit_failure_syntax "mimetype '$mimetype' is not in the form 'minor/major'"
;;
esac
;;
*)
exit_failure_syntax "unknown query type '$1'"
;;
esac
;;
default)
action=makedefault
shift
if [ -z "$1" ] ; then
exit_failure_syntax "application argument missing"
fi
case $1 in
-*)
exit_failure_syntax "unexpected option '$1'"
;;
*.desktop)
filename="$1"
;;
*)
exit_failure_syntax "malformed argument '$1', expected *.desktop"
;;
esac
;;
*)
exit_failure_syntax "unknown command '$1'"
;;
esac
shift
if [ "$action" = "makedefault" ]; then
if [ -z "$1" ] ; then
exit_failure_syntax "mimetype argument missing"
fi
while [ $# -gt 0 ] ; do
case $1 in
-*)
exit_failure_syntax "unexpected option '$1'"
;;
esac
mimetype="$1"
shift
make_default_kde "$filename" "$mimetype"
make_default_generic "$filename" "$mimetype"
done
exit_success
fi
if [ "$action" = "info" ]; then
detectDE
if [ x"$DE" = x"" ]; then
if [ -x /usr/bin/file ]; then
DE=generic
fi
fi
case "$DE" in
kde)
info_kde "$filename"
;;
gnome*|cinnamon|lxde|mate|xfce)
info_gnome "$filename"
;;
*)
info_generic "$filename"
;;
esac
exit_failure_operation_impossible "no method available for quering MIME type of '$filename'"
fi
if [ "$action" = "defapp" ]; then
detectDE
case "$DE" in
kde)
defapp_kde "$mimetype"
;;
*)
defapp_generic "$mimetype"
;;
esac
exit_failure_operation_impossible "no method available for quering default application for '$mimetype'"
fi
vendor=true
while [ $# -gt 0 ] ; do
parm="$1"
shift
case $parm in
--mode)
if [ -z "$1" ] ; then
exit_failure_syntax "mode argument missing for --mode"
fi
case "$1" in
user)
mode="user"
;;
system)
mode="system"
;;
*)
exit_failure_syntax "unknown mode '$1'"
;;
esac
shift
;;
--novendor)
vendor=false
;;
-*)
exit_failure_syntax "unexpected option '$parm'"
;;
*)
if [ -n "$filename" ] ; then
exit_failure_syntax "unexpected argument '$parm'"
fi
filename="$parm"
check_input_file "$filename"
;;
esac
done
if [ -z "$action" ] ; then
exit_failure_syntax "command argument missing"
fi
if [ -n "$XDG_UTILS_INSTALL_MODE" ] ; then
if [ "$XDG_UTILS_INSTALL_MODE" = "system" ] ; then
mode="system"
elif [ "$XDG_UTILS_INSTALL_MODE" = "user" ] ; then
mode="user"
fi
fi
if [ -z "$mode" ] ; then
if [ `whoami` = "root" ] ; then
mode="system"
else
mode="user"
fi
fi
if [ -z "$filename" ] ; then
exit_failure_syntax "mimetypes-file argument missing"
fi
if [ "$vendor" = "true" -a "$action" = "install" ] ; then
check_vendor_prefix "$filename"
fi
xdg_base_dir=
xdg_dir_name=mime/packages/
xdg_user_dir="$XDG_DATA_HOME"
[ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share"
[ x"$mode" = x"user" ] && xdg_base_dir="$xdg_user_dir/mime"
xdg_user_dir="$xdg_user_dir/$xdg_dir_name"
xdg_system_dirs="$XDG_DATA_DIRS"
[ -n "$xdg_system_dirs" ] || xdg_system_dirs=/usr/local/share/:/usr/share/
for x in `echo $xdg_system_dirs | sed 's/:/ /g'`; do
if [ -w $x/$xdg_dir_name ] ; then
[ x"$mode" = x"system" ] && xdg_base_dir="$x/mime"
xdg_global_dir="$x/$xdg_dir_name"
break
fi
done
[ -w $xdg_global_dir ] || xdg_global_dir=
DEBUG 3 "xdg_user_dir: $xdg_user_dir"
DEBUG 3 "xdg_global_dir: $xdg_global_dir"
# Find KDE3 mimelnk directory
kde_user_dir=
kde_global_dir=
kde_global_dirs=`kde${KDE_SESSION_VERSION}-config --path mime 2> /dev/null`
DEBUG 3 "kde_global_dirs: $kde_global_dirs"
first=
for x in `echo $kde_global_dirs | sed 's/:/ /g'` ; do
if [ -z "$first" ] ; then
first=false
kde_user_dir="$x"
elif [ -w $x ] ; then
kde_global_dir="$x"
fi
done
DEBUG 3 "kde_user_dir: $kde_user_dir"
DEBUG 3 "kde_global_dir: $kde_global_dir"
# TODO: Gnome legacy support
# See http://forums.fedoraforum.org/showthread.php?t=26875
gnome_user_dir="$HOME/.gnome/apps"
gnome_global_dir=/usr/share/gnome/apps
[ -w $gnome_global_dir ] || gnome_global_dir=
DEBUG 3 "gnome_user_dir: $gnome_user_dir"
DEBUG 3 "gnome_global_dir: $gnome_global_dir"
if [ x"$mode" = x"user" ] ; then
xdg_dir="$xdg_user_dir"
kde_dir="$kde_user_dir"
gnome_dir="$gnome_user_dir"
my_umask=077
else
xdg_dir="$xdg_global_dir"
kde_dir="$kde_global_dir"
gnome_dir="$gnome_global_dir"
my_umask=022
if [ -z "${xdg_dir}${kde_dir}${gnome_dir}" ] ; then
exit_failure_operation_impossible "No writable system mimetype directory found."
fi
fi
# echo "[xdg|$xdg_user_dir|$xdg_global_dir]"
# echo "[kde|$kde_user_dir|$kde_global_dir]"
# echo "[gnome|$gnome_user_dir|$gnome_global_dir]"
# echo "[using|$xdg_dir|$kde_dir|$gnome_dir]"
basefile=`basename "$filename"`
#[ -z $vendor ] || basefile="$vendor-$basefile"
mimetypes=
if [ -n "$kde_dir" ] ; then
DEBUG 2 "KDE3 mimelnk directory found, extracting mimetypes from XML file"
mimetypes=`awk < "$filename" '
# Strip XML comments
BEGIN {
suppress=0
}
{
do
if (suppress) {
if (match($0,/-->/)) {
$0=substr($0,RSTART+RLENGTH)
suppress=0
}
else {
break
}
}
else {
if (match($0,/<!--/)) {
if (RSTART>1) print substr($0,0,RSTART)
$0=substr($0,RSTART+RLENGTH)
suppress=1
}
else {
if ($0) print $0
break
}
}
while(1)
}
' | awk '
# List MIME types listed in <mime-type> tags
BEGIN {
RS="<"
}
/^mime-info/, /^\/mime-info/ {
if (match($0,/^mime-type/)) {
if (match($0,/type="[^"]*/) || match($0,/type='"'"'[^'"'"']*/)) {
print substr($0,RSTART+6,RLENGTH-6)
}
}
}'`
fi
DEBUG 1 "$action mimetype in $xdg_dir"
case $action in
install)
save_umask=`umask`
umask $my_umask
for x in $xdg_dir ; do
mkdir -p $x
eval 'cp $filename $x/$basefile'$xdg_redirect_output
done
if [ -n "$mimetypes" ] ; then
# No quotes around $mimetypes
for x in $mimetypes ; do
DEBUG 1 "Installing $kde_dir/$x.desktop (KDE 3.x support)"
mkdir -p `dirname $kde_dir/$x.desktop`
awk < "$filename" '
# Strip XML comments
BEGIN {
suppress=0
}
{
do
if (suppress) {
if (match($0,/-->/)) {
$0=substr($0,RSTART+RLENGTH)
suppress=0
}
else {
break
}
}
else {
if (match($0,/<!--/)) {
if (RSTART>1) print substr($0,0,RSTART)
$0=substr($0,RSTART+RLENGTH)
suppress=1
}
else {
if ($0) print $0
break
}
}
while(1)
}
' | awk > $kde_dir/$x.desktop '
# Extract mimetype $x from the XML file $filename
# Note that bash requires us to escape a single quote as '"'"'
BEGIN {
the_type=ARGV[1]
the_source=ARGV[2]
ARGC=1
RS="<"
found=0
glob_patterns=""
}
/^mime-info/, /^\/mime-info/ {
if (match($0,/^mime-type/)) {
if (match($0,/type="[^"]*/) || match($0,/type='"'"'[^'"'"']*/)) {
if (substr($0,RSTART+6,RLENGTH-6) == the_type) {
found=1
print "[Desktop Entry]"
print "# Installed by xdg-mime from " the_source
print "Type=MimeType"
print "MimeType=" the_type
the_icon=the_type
sub("/", "-", the_icon)
print "Icon=" the_icon
}
}
}
else if (found) {
if (match($0,/^\/mime-type/)) {
if (glob_patterns)
print "Patterns=" glob_patterns
exit 0
}
if (match($0,/^sub-class-of/)) {
if (match($0,/type="[^"]*/) || match($0,/type='"'"'[^'"'"']*/)) {
print "X-KDE-IsAlso=" substr($0,RSTART+6,RLENGTH-6)
}
else {
print "Error: '"'"'type'"'"' argument missing in " RS $0
exit 1
}
}
if (match($0,/^glob/)) {
if (match($0,/pattern="[^"]*/) || match($0,/pattern='"'"'[^'"'"']*/)) {
glob_patterns = glob_patterns substr($0,RSTART+9,RLENGTH-9) ";"
}
else {
print "Error: '"'"'pattern'"'"' argument missing in " RS $0
exit 1
}
}
if (match($0,/^comment/)) {
if (match($0,/xml:lang="[^"]*/) || match($0,/xml:lang='"'"'[^'"'"']*/)) {
lang=substr($0,RSTART+10,RLENGTH-10)
}
else {
lang=""
}
if (match($0,/>/)) {
comment=substr($0,RSTART+1)
sub("<", "<", comment)
sub(">", ">", comment)
sub("&", "\\&", comment)
if (lang)
print "Comment[" lang "]=" comment
else
print "Comment=" comment
}
}
}
}
END {
if (!found) {
print "Error: Mimetype '"'"'" the_type "'"'"' not found"
exit 1
}
}
' $x $basefile
if [ "$?" = "1" ] ; then
grep -A 10 "^Error:" $kde_dir/$x.desktop >&2
rm $kde_dir/$x.desktop
exit 1
fi
done
fi
umask $save_umask
;;
uninstall)
for x in $xdg_dir ; do
rm -f $x/$basefile
done
# No quotes around $mimetypes
for x in $mimetypes ; do
if grep '^# Installed by xdg-mime' $kde_dir/$x.desktop >/dev/null 2>&1; then
DEBUG 1 "Removing $kde_dir/$x.desktop (KDE 3.x support)"
rm -f $kde_dir/$x.desktop
fi
done
;;
esac
update_mime_database $xdg_base_dir
exit_success
Zerion Mini Shell 1.0