| Server IP : 104.21.84.107 / Your IP : 104.23.197.209 Web Server : Apache/2.4.63 (Ubuntu) System : Linux adminpruebas-Virtual-Machine 6.14.0-37-generic #37-Ubuntu SMP PREEMPT_DYNAMIC Fri Nov 14 22:10:32 UTC 2025 x86_64 User : www-data ( 33) PHP Version : 8.4.5 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /usr/bin/ |
Upload File : |
#!/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 <[email protected]>
# Copyright 2009-2010, Rex Dieter <[email protected]>
# Copyright 2006, Kevin Krammer <[email protected]>
# Copyright 2006, Jeremy White <[email protected]>
#
# 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 FILE | default mimetype }
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 file
Returns the file type of FILE in the form of a MIME type.
Please note that FILE names starting with a - will be rejected, this can be
mitigated:
☆ Pass absolute paths, i.e. by using realpath as a preprocessor.
☆ Prefix known relative filepaths with a “./”. For example using sed -E
's|^[^/]|./\0|' as a preprocessor.
The query file option is for use inside a desktop session only. It is not
recommended to use xdg-mime query file as root.
query default
Returns the default application that the desktop environment uses for
opening files of type mimetype. The default application is identified by
its *.desktop file.
The value returned by this command may or may not match the application
launched by xdg-open as xdg-open hands over to desktop specific openers
most of the time which may implement their own logic.
The query default option is for use inside a desktop session only. It is
not recommended to use xdg-mime query default as root.
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.
Security Note: Never set a handler that will blindly execute code or
commands from the file being handled. Such behaviour will sooner than later
lead to unintended code execution i.e. through a curious user trying to
inspect a freshly downloaded file but running it by accident.
Keeping opening and executing separate actions helps with people protecting
themselves from malware, the default handler is an opener, not a runner.
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 FILE | default mimetype }
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
#----------------------------------------------------------------------------
#shellcheck shell=sh
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()
{
# shellcheck disable=SC2162 # No -r is intended here
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="$(command -v "$1")"
binary="$(xdg_realpath "$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="$(command -v "$command")"
if [ x"$(xdg_realpath "$command")" = x"$binary" ]; then
# Fix any double slashes that got added path composition
echo "$file" | tr -s /
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="$(command -v "$command")"
xdg_realpath "$command"
return
fi
done
}
#-------------------------------------------------------------
# Exit script on successfully completing the desired operation
# shellcheck disable=SC2120 # It is okay to call this without arguments
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.2.1"
exit_success
;;
--)
[ -z "$XDG_UTILS_ENABLE_DOUBLE_HYPEN" ] || break
;;
esac
done
}
check_common_commands "$@"
[ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && unset XDG_UTILS_DEBUG_LEVEL;
# shellcheck disable=SC2034
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;
;;
DEEPIN|Deepin|deepin)
DE=deepin;
;;
LXDE)
DE=lxde;
;;
LXQt)
DE=lxqt;
;;
MATE)
DE=mate;
;;
XFCE)
DE=xfce
;;
X-Generic)
DE=generic
;;
esac
fi
# shellcheck disable=SC2153
if [ -z "$DE" ]; then
# classic fallbacks
if [ -n "$KDE_FULL_SESSION" ]; then DE=kde;
elif [ -n "$GNOME_DESKTOP_SESSION_ID" ]; then DE=gnome;
elif [ -n "$MATE_DESKTOP_SESSION_ID" ]; 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 [ -n "$LXQT_SESSION_CONFIG" ]; then DE=lxqt;
fi
fi
if [ -z "$DE" ]; 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 [ -z "$DE" ]; then
# fallback to uname output for other platforms
case "$(uname 2>/dev/null)" in
CYGWIN*)
DE=cygwin;
;;
Darwin)
DE=darwin;
;;
Linux)
grep -q microsoft /proc/version > /dev/null 2>&1 && \
command -v explorer.exe > /dev/null 2>&1 && \
DE=wsl;
;;
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
command -v gnome-default-applications-properties > /dev/null || 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
}
#----------------------------------------------------------------------------
# Prefixes a path with a "./" if it starts with a "-".
# This is useful for programs to not confuse paths with options.
unoption_path()
{
case "$1" in
-*)
printf "./%s" "$1" ;;
*)
printf "%s" "$1" ;;
esac
}
#----------------------------------------------------------------------------
# Performs a symlink and relative path resolving for a single argument.
# This will always fail if the given file does not exist!
xdg_realpath()
{
# allow caching and external configuration
if [ -z "$XDG_UTILS_REALPATH_BACKEND" ] ; then
if command -v realpath >/dev/null 2>/dev/null ; then
lines="$(realpath -- / 2>&1)"
if [ $? = 0 ] && [ "$lines" = "/" ] ; then
XDG_UTILS_REALPATH_BACKEND="realpath"
else
# The realpath took the -- literally, probably the busybox implementation
XDG_UTILS_REALPATH_BACKEND="busybox-realpath"
fi
unset lines
elif command -v readlink >/dev/null 2>/dev/null ; then
XDG_UTILS_REALPATH_BACKEND="readlink"
else
exit_failure_operation_failed "No usable realpath backend found. Have a realpath binary or a readlink -f that canonicalizes paths."
fi
fi
# Always fail if the file doesn't exist (busybox realpath does that for example)
[ -e "$1" ] || return 1
case "$XDG_UTILS_REALPATH_BACKEND" in
realpath)
realpath -- "$1"
;;
busybox-realpath)
# busybox style realpath implementations have options too
realpath "$(unoption_path "$1")"
;;
readlink)
readlink -f "$(unoption_path "$1")"
;;
*)
exit_failure_operation_impossible "Realpath backend '$XDG_UTILS_REALPATH_BACKEND' not recognized."
;;
esac
}
update_kde_cache()
{
DEBUG 1 "Running kbuildsycoca"
if [ "${KDE_SESSION_VERSION:-0}" -gt 3 ] ; then
eval 'kbuildsycoca${KDE_SESSION_VERSION}'$xdg_redirect_output
else
eval 'kbuildsycoca'$xdg_redirect_output
fi
}
update_mime_database()
{
if [ "$mode" = user ] && has_display; then
detectDE
if [ x"$DE" = x"kde" ] ; then
update_kde_cache
fi
fi
old_ifs="$IFS"
IFS=:
for x in $PATH /opt/gnome/bin ; do
IFS="$old_ifs"
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 kmimetypefinder5 \"$1\""
kmimetypefinder5 "$1" 2>/dev/null | head -n 1
;;
6)
DEBUG 1 "Running kmimetypefinder \"$1\""
kmimetypefinder "$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/"^ "//
else
exit_failure_operation_impossible "no method available for querying MIME type of '$filename'"
fi
if [ $? -eq 0 ]; then
exit_success
else
exit_failure_operation_failed
fi
}
info_lxqt()
{
if qtxdg-mat mimetype --help 2>/dev/null 1>&2; then
qtxdg-mat mimetype "$1" 2>/dev/null
else
exit_failure_operation_impossible "no method available for querying MIME type of '$filename'"
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 [ "${KDE_SESSION_VERSION:-0}" -gt 4 ] ; then
default_dir="$(qtpaths --writable-path ConfigLocation)"
default_file="$default_dir/mimeapps.list"
elif [ 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 [ "${KDE_SESSION_VERSION:-0}" -gt 3 ]; 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"
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_lxqt()
{
# $1 is vendor-name.desktop
# $2 is mime/type
if qtxdg-mat defapp --help 2>/dev/null 1>&2; then
qtxdg-mat defapp --set "$1" "$2" 1>/dev/null
else
exit_failure_operation_impossible "no method available for setting the default application for MIME type(s) of '$mimetype'"
fi
if [ $? -eq 0 ]; then
exit_success
else
exit_failure_operation_failed
fi
}
make_default_generic()
{
# $1 is vendor-name.desktop
# $2 is mime/type
# Add $2=$1 to XDG_CONFIG_HOME/mimeapps.list
#shellcheck disable=SC2153 # not misspelled
xdg_config_home="$XDG_CONFIG_HOME"
[ -n "$xdg_config_home" ] || xdg_config_home="$HOME/.config"
default_file="$xdg_config_home/mimeapps.list"
if [ -L "$default_file" ]; then
out_file="$(xdg_realpath "$default_file")"
else
out_file="$default_file"
fi
DEBUG 2 "make_default_generic $1 $2"
DEBUG 1 "Updating $out_file"
[ -f "$out_file" ] || touch "$out_file"
[ -d "$xdg_config_home" ] || mkdir -p "$xdg_config_home"
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--
}
}
' "$out_file" > "$out_file.new" && mv "$out_file.new" "$out_file"
}
search_desktop_file()
{
local MIME dir
MIME="$1"
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=""
old_ifs="$IFS"
IFS=:
for d in $xdg_user_dir $xdg_system_dirs ; do
IFS="$old_ifs"
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
basename "$desktop_file"
exit_success
fi
}
check_mimeapps_list()
{
local mimetype dir desktop oldifs
mimetype="$1"
dir="$2"
oldifs="$IFS"
IFS=:
for desktop in $XDG_CURRENT_DESKTOP ''; do
IFS="$oldifs"
local prefix mimeapps_list result
if [ -n "$desktop" ]; then
prefix="$(echo "$desktop-" | tr '[:upper:]' '[:lower:]')"
else
prefix=""
fi
mimeapps_list="$dir/${prefix}mimeapps.list"
if [ -f "$mimeapps_list" ] ; then
DEBUG 2 "Checking $mimeapps_list"
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")"
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"
#shellcheck disable=SC2153 # not misspelled
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 dir
oldifs="$IFS"
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
IFS=:
for x in $xdg_user_dir $xdg_system_dirs ; do
IFS="$oldifs"
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="$(command -v ktraderclient)" # FIXME: Plasma 6?
;;
5)
KTRADER="$(command -v ktraderclient${KDE_SESSION_VERSION})"
;;
esac
else
KTRADER="$(command -v ktradertest)"
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
}
defapp_lxqt()
{
if qtxdg-mat defapp --help 2>/dev/null 1>&2; then
qtxdg-mat defapp "$1"
else
exit_failure_operation_impossible "no method available for querying the default application for MIME type of '$mimetype'"
fi
if [ $? -eq 0 ]; then
exit_success
else
exit_failure_operation_failed
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="$(xdg_realpath "$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
detectDE
while [ $# -gt 0 ] ; do
case $1 in
-*)
exit_failure_syntax "unexpected option '$1'"
;;
esac
mimetype="$1"
shift
case "$DE" in
lxqt)
make_default_lxqt "$filename" "$mimetype"
;;
*)
make_default_kde "$filename" "$mimetype"
make_default_generic "$filename" "$mimetype"
;;
esac
done
if [ "$DE" = "kde" ] ; then
update_kde_cache
fi
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"
;;
lxqt)
info_lxqt "$filename"
;;
*)
info_generic "$filename"
;;
esac
exit_failure_operation_impossible "no method available for querying MIME type of '$filename'"
fi
if [ "$action" = "defapp" ]; then
detectDE
if [ "$DE" = "kde" ] && [ "$KDE_SESSION_VERSION" -lt "6" ]; then
defapp_kde "$mimetype"
fi
case "$DE" in
lxqt)
defapp_lxqt "$mimetype"
;;
*)
defapp_generic "$mimetype"
;;
esac
exit_failure_operation_impossible "no method available for querying 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 [ "$(id -u)" -eq 0 ] ; then
mode="system"
else
mode="user"
fi
fi
if [ -z "$filename" ] ; then
exit_failure_syntax "mimetypes-file argument missing"
fi
if [ "$vendor" = "true" ] && [ "$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/
old_ifs="$IFS"
IFS=:
for x in $xdg_system_dirs ; do
IFS="$old_ifs"
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=
old_ifs="$IFS"
IFS=:
for x in $kde_global_dirs ; do
IFS="$old_ifs"
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