#!/bin/sh
#---------------------------------------------
#   xdg-mime
#
#   Utility script to manipulate MIME related information
#   on XDG compliant systems.
#
#   Refer to the usage() function below for usage.
#
#   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 aplication'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 major-minor must be installed with the xdg-icon-resource
    command in the mimetypes context. For example the application/
    vnd.oasis.opendocument.text filetype requires an icon by the name of
    application-vnd.oasis.opendocument.text to be installed.
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 manualpage.
--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)

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 folows.

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
}

#-------------------------------------------------------------
# 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 read a specified file

exit_failure_file_permission_write()
{
    if [ $# -gt 0 ]; then
        echo "xdg-mime: $@" >&2
    fi

    exit 6
}

check_input_file()
{
    if [ ! -f "$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 "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 [ -f "$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 xdg-mime' or 'xdg-mime --manual' for additional info."
            exit_success
            ;;

            --manual)
            manualpage
            exit_success
            ;;

            --version)
            echo "xdg-mime 1.0.1"
            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()
{
    if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde;
    elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome;
    elif xprop -root _DT_SAVE_MODE | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce;
    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=`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
}

if [ -x /usr/bin/test ]; then
	TestCmd=/usr/bin/test
else
	TestCmd=test
fi

if $TestCmd -e . 2>/dev/null; then
	TestCmdOption="-e"
else
	TestCmdOption="-f"
fi
readlink()
{
    OLDPWD="`pwd`"
    lfile="$1"

    while $TestCmd -h "$lfile" -a $TestCmdOption "$lfile" ; do
        CWD="`dirname "$lfile"`"
        lfile="`basename "$lfile"`"
        cd $CWD
        lfile="`ls -l "$lfile"|sed 's/^.*-> *\(.*\) *$/\1/'`"
    done

    if $TestCmd $TestCmdOption "$lfile" ; then
        CWD="`dirname "$lfile"`"
        lfile="`basename "$lfile"`"
        cd $CWD
        printf "%s\n" "`pwd`/$lfile"
        cd "$OLDPWD"
        return 0
    fi

    cd "$OLDPWD"
    return 1
}


update_mime_database()
{
   if [ x"$mode" = x"user" -a -n "$DISPLAY" ] ; then
      detectDE
      if [ x"$DE" = x"kde" ] ; then
         DEBUG 1 "Running kbuildsycoca"
         eval 'kbuildsycoca'$xdg_redirect_output
         eval 'kbuildsycoca4'$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()
{
    DE_save="$DE"
    DE=kde

    update_mime_database $xdg_base_dir

    if [ "${KDE_SESSION_VERSION+set}" = "set" -a "${KDE_SESSION_VERSION}" = "4" ]; then
        DEBUG 1 "Running kmimetypefinder \"$1\""
        kmimetypefinder "$1" 2>/dev/null | head -n 1
    else
        DEBUG 1 "Running kfile \"$1\""
        kfile "$1" 2> /dev/null | head -n 1 | cut -d "(" -f 2 | cut -d ")" -f 1
    fi

    DE="$DE_save"
    exit_success
}

info_gnome()
{
    file=`readlink "$1"` # Normalize path
    DEBUG 1 "Running gnomevfs-info \"$file\""
    gnomevfs-info "$file" 2> /dev/null | grep MIME | cut -d ":" -f 2 | sed s/"^ "//

    exit_success
}

info_generic()
{
    DEBUG 1 "Running /usr/bin/file -i \"$1\"" 
    /usr/bin/file -i "$1" 2> /dev/null | cut -d ":" -f 2 | sed s/"^ "//

    exit_success
}

get_generic_config_dirs()
{
    xdg_user_dir="$XDG_DATA_HOME"
    [ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share"
    
    if [ -z "$mode" ] ; then
        if [ `whoami` = "root" ] ; then
            mode="system"
        else
            mode="user"
        fi
    fi
    
    if [ "$mode" = "system" ] ; then
        if [ -n "$XDG_DATA_DIRS" ]; then
	    xdg_system_dirs="$XDG_DATA_DIRS"
	else
	    xdg_system_dirs=/usr/local/share/:/usr/share/
	fi
	
	echo "$xdg_system_dirs"
    else
	mkdir -p "$xdg_user_dir/applications"
	[ -f "$xdg_user_dir/applications/defaults.list" ] || touch "$xdg_user_dir/applications/defaults.list"
	echo "$xdg_user_dir"
    fi
}

get_kde_config_dirs()
{
      xdg_user_dir="`kde-config --path config 2>/dev/null | cut -d: -f1 -s`"

      if [ -z "$xdg_user_dir" ]; then
	  kde_user_dir="`kde-config --localprefix --expandvars 2>/dev/null`"
	  
	  if [ -z "$kde_user_dir" ]; then
              kde_user_dir="$HOME/.kde"
          fi
	  
          xdg_user_dir="${kde_user_dir}/share/config"
      fi
      
      if [ -z "$mode" ] ; then
          if [ `whoami` = "root" ] ; then
              mode="system"
          else
              mode="user"
          fi
      fi
      if [ "$mode" = "system" ] ; then
          xdg_dirs="`kde-config --install config --expandvars 2>/dev/null`"
	  
          if [ -n "$xdg_dirs" ]; then
              for i in $xdg_dirs; do
                  touch "$i/profilerc"
              done
          else
              xdg_dirs="`kde-config --path config --expandvars 2>/dev/null | cut -d: -f2- -s`"
	      
              if [ -z "$xdg_dirs" ]; then
                  if [ -n "$XDG_DATA_DIRS" ]; then
                      xdg_system_dirs="$XDG_DATA_DIRS"
                  else
                      xdg_system_dirs=/usr/local/share/:/usr/share/
                  fi
              fi
	      
              xdg_dirs="`echo $xdg_system_dirs | awk -F: '{ for (i=1;i<NF;i++) printf("%s/config:", $i); printf("%s/config", $NF); }'`"
          fi
	  
          echo "$xdg_dirs"
      else
          default_file="${xdg_user_dir}/profilerc"
          [ -f "$default_file" ] || touch "$default_file"
          mkdir -p "$xdg_user_dir"
         echo "$xdg_user_dir"
    fi
 }

make_default_kde()
{
    # $1 is vendor-name.desktop
    # $2 is mime/type 
    # Add to $KDE_HOME/share/config/profilerc:
    # [$2 - 1]
    # Application=$1
    #
    # Remove all [$2 - *] sections, or even better,
    # renumber [$2 - *] sections and remove duplicate
    
    default_file="$HOME/.kde/share/config/profilerc"
    DEBUG 2 "make_default_kde $1 $2"
    DEBUG 1 "Updating $default_file"

    xdg_dirs="`get_kde_config_dirs`"
    newfilename="$1"
    OLD_IFS="$IFS"
    IFS=":"
    found=false

    for x in $xdg_dirs; do
        pfile="$x/profilerc"

        if [ -f "$pfile" ]; then
            awk -v application="$newfilename" -v mimetype="$2" '  
                BEGIN {
                    header_start="[" mimetype " - " 
                    supress=0 
                } 
                { 
                    if (index($0, header_start) == 1 ) 
                        supress=1 
                    else 
                        if (/^\[/) { supress=0 }  

                    if (!supress) {
                        print $0
                    }
                }
                END { 
                    print "" 
                    print "[" mimetype " - 1]" 
                    print "Application=" application
                    print "AllowAsDefault=true"
                    print "GenericServiceType=Application"
                    print "Preference=1" 
                    print "ServiceType=" mimetype
                }
            ' "$pfile" > "${pfile}.new" && mv -f "${pfile}.new" "${pfile}"

            if [ $? -eq 0 ]; then
                found=true
            fi
        fi

        if [ "$found" = "true" -a -f "$1" ]; then
            if [ "$mode" = "system" ]; then
                kde_dir="`kde-config --install apps --expandvars 2>/dev/null | cut -d: -f1`"
            else
                kde_dir="`kde-config --path apps --expandvars 2>/dev/null | cut -d: -f1`"
            fi

            if [ -n "$kde_dir" ]; then
                rm -f "${kde_dir}/${newfilename}"
                ( grep -v "MimeType=" "$1" | grep -v "Categories=" ; printf "MimeType=$2;\nCategories=X-None;" ) > "${kde_dir}/${newfilename}"
            fi
        fi
    done

    IFS="$OLD_IFS"
}

unset_default_kde()
{
    # $1 is vendor-name.desktop
    # $2 is mime/type
    # [$2 - 1]
    # Application=$1
    #
    # Remove all [$2 - *] sections, or even better,
    # renumber [$2 - *] sections and remove duplicate
    
    desktopfilename="`basename "$1"`"
    newfilename="`echo "$desktopfilename"`"

    xdg_dirs="`get_kde_config_dirs`"
    OLD_IFS="$IFS"
    IFS=":"

    for x in $xdg_dirs; do
	pfile="$x/profilerc"
	if [ -f "$pfile" ]; then
	    awk -v application="$newfilename" -v mimetype="$2" '
                  BEGIN  {
                       found=0
                       header_start="[" mimetype " - "
                       l=length("Application=")
                       block=""
                   }
                   {
                       if ( index($0, header_start) == 1 ) {
                           found=1;
                           block=$0;
                           next;
                       }
                       else if ( /^\[/ ) {
                            found = 0;
                           block="";
                       }
  
                       if ( found == 1 ) {
                            if ( /^Application=/ && ! /AdobeReader\.desktop$/ ) {
                                    found=0;
                                    printf("%s\n%s\n", block, $0);
                           }
                            else
                                sprintf(block, "%s\n%s", block, $0);
                        }
                        else
                            print $0;
                    }
                ' "$pfile" > "${pfile}.new" && mv -f "${pfile}.new" "${pfile}"

            kde_dir="`kde-config --path apps --expandvars 2>/dev/null | cut -d: -f1`"
            if [ -n "$kde_dir" ]; then
                rm -f "${kde_dir}/${newfilename}" 2>/dev/null	    
            fi
        fi
    done
    
    IFS="$OLD_IFS"
}

unset_default_generic()
{
    if [  "`uname -s`" != "SunOS" -o `gnome-session-properties --version  2> /dev/null| grep -c '2\.6' ` -eq 0 ] ; then

# $1 is vendor-name.desktop
# $2 is mime/type
# Remove $2=$1 to XDG_DATA_HOME/applications/defaults.list

        desktopfilename="`basename $1`"
        newfilename="`echo $desktopfilename`"
        xdg_dirs="`get_generic_config_dirs`"
        OLD_IFS="$IFS"
        IFS=":"

        for x in $xdg_dirs; do
            y="$x/applications/defaults.list"
            if [ -f "$y" ]; then
                grep -v "$2=`basename "$newfilename"`" "${y}" > "${y}.new" 2>/dev/null && cat "${y}.new" >| "${y}" && rm -f "${y}.new"
            fi
        done

        IFS="$OLD_IFS"
    else
        if [ -z "$mode" ] ; then
            if [ "`whoami`" = "root" ] ; then
                mode="system"
            else
                mode="user"
            fi
        fi


        if [ "$mode" = "user" ] ; then
            xdg_app_dir="$HOME/.gnome/application-info"
            application_file="$xdg_app_dir/user.applications"
            xdg_key_dir="$HOME/.gnome/mime-info"
            key_file="$xdg_key_dir/user.keys"
        else
            xdg_app_dir="/usr/share/application-registry"
            application_file="$xdg_app_dir/gnome-vfs.applications"
            xdg_key_dir="/usr/share/mime-info"
            key_file="$xdg_key_dir/gnome-vfs.keys"
        fi

        appname="`basename $3`"
        # removing entry of acroread from user.applications
        if [ -f "$application_file" ]; then
            /usr/xpg4/bin/awk -v application="$appname" '
            BEGIN {
                header_start=application;
                supress=0;
            }
            {
                if (supress == 1) {
                    if (/^[A-Za-z0-9]/) {
                        supress=0 ;
                        print $0 ;
                    }
                }
                else {
                    if (index($0, header_start) == 1 ) {
                        supress=1 ;
                    }
                    else {
                        print $0 ;
                    }
                }
            }
            ' "${application_file}" > "${application_file}.new"  && mv -f "${application_file}.new" "${application_file}"
        fi

        # updating entry of mimetype in .keys file
        /usr/xpg4/bin/awk -v application="$appname" -v mimetype="${2}"  '
        BEGIN {
            header_start=mimetype;
            matched=0;
            non_ddi=0;
            block=""
            block_tmp=""
        }
        {
            if (matched == 1) {
                if (/^[^a-zA-Z_0-9]*default_application_id=.*$/) {
                }
                else if (/^[^a-zA-Z_0-9]*default_action_type=.*$/) {
                }
                else if (/^[^a-zA-Z_0-9]*icon_filename=.*$/) {
                }
                else {
                    if ( (/^ *$/) || (/^[a-zA-Z0-9_]/) ) {
                        matched=0;
                        if (non_ddi == 1) {
                            print block
                            print ""
                            non_ddi=0 ;
                        }
                    }
                    else {
                        block=block_tmp "\n" $0 ;
                        block_tmp=block
                    }
                    non_ddi=1 ;
                }
            }
            else {
                if (index($0, header_start) == 1 ) {
                    matched=1;
                    block_tmp=$0
                }
                else {
                    print $0 ;
                }
            }
        }
        ' "${key_file}" > "${key_file}.new" && mv -f "${key_file}.new" "${key_file}"
    fi
}

make_default_generic()
{
    if [  "`uname -s`" != "SunOS" -o `gnome-session-properties --version  2> /dev/null| grep -c '2\.6' ` -eq 0 ] ; then

        # $1 is vendor-name.desktop
        # $2 is mime/type
        # Add $2=$1 to XDG_DATA_HOME/applications/defaults.list

        xdg_user_dir="$XDG_DATA_HOME"
        [ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share"
        default_file="$xdg_user_dir/applications/defaults.list"
        DEBUG 2 "make_default_generic $1 $2"
        DEBUG 1 "Updating $default_file"

        xdg_dirs="`get_generic_config_dirs`"
        newfilename="$1"
        OLD_IFS="$IFS"
        IFS=":"

        for x in $xdg_dirs; do
            y="${x}/applications/defaults.list"
            if [ -f "$y" ]; then
                grep -v "$2=" "$y" > "${y}.new" 2>/dev/null
                if ! grep -q "[Default Applications]" "${y}.new" 2> /dev/null; then
                    echo "[Default Applications]" >> "${y}.new"
                fi

                echo "$2=$newfilename" >> "${y}.new" && cat "${y}.new" >| "${y}" && rm -f "${y}.new"
            fi
        done


        IFS="$OLD_IFS"
    else
        if [ -z "$mode" ] ; then
            if [ `whoami` = "root" ] ; then
                mode="system"
            else
                mode="user"
            fi
        fi

        if [ "$mode" = "user" ] ; then
            xdg_app_dir="$HOME/.gnome/application-info"
            application_file="$xdg_app_dir/user.applications"
            xdg_key_dir="$HOME/.gnome/mime-info"
            key_file="$xdg_key_dir/user.keys"
        else
            xdg_app_dir="/usr/share/application-registry"
            application_file="$xdg_app_dir/gnome-vfs.applications"
            xdg_key_dir="/usr/share/mime-info"
            key_file="$xdg_key_dir/gnome-vfs.keys"
        fi


        appname="`basename $3`"
        mime_types="application/pdf,application/vnd.adobe.xfdf,application/vnd.fdf,application/vnd.adobe.xdp+xml,application/vnd.adobe.pdx,application/fdf,application/xdp,application/xfdf,application/pdx"

        # handling of .applications file
        app_path="$3"
        found=`grep '^'"$appname" "$application_file" 2> /dev/null `
        if [ -z "$found" ] ; then
            echo "" > "$application_file.new"
            echo "$appname" >> "$application_file.new"
            echo "        command=$app_path"  >> "$application_file.new"
            echo "        name=Adobe Reader 9" >> "$application_file.new"
            echo "        can_open_multiple_files=true" >> "$application_file.new"
            echo "        expects_uris=false" >> "$application_file.new"
            echo "        requires_terminal=false" >> "$application_file.new"
            echo "        mime_types=$mime_types" >> "$application_file.new"
            cat "$application_file.new" >> "$application_file"
        else
            if [ -f "$application_file" ]; then
                /usr/xpg4/bin/awk -v application="$appname" -v mimetype="${mime_types}" -v apppath="${app_path}" '
                BEGIN {
                    header_start=application;
                    supress=0;
                }
                {
                    if (supress == 1) {
                        if (/^[A-Za-z0-9]/) {
                            supress=0 ;
                            print $0 ;
                        }
                    }
                    else {
                        if (index($0, header_start) == 1 ) {
                            supress=1;
                            print application
                            print "        command=" apppath
                            print "        name=Adobe Reader 9"
                            print "        can_open_multiple_files=true"
                            print "        expects_uris=false"
                            print "        requires_terminal=false"
                            print "        mime_types=" mimetype
                            print ""
                        }
                        else
                        {
                            print $0
                        }
                    }
                }
                ' "${application_file}" > "${application_file}.new"  && mv -f "${application_file}.new" "${application_file}"
            fi
        fi

        # handling of .keys file
        for i in `echo $mime_types | sed 's/,/ /g'` ; do
            found=`grep "$i" "$key_file" 2> /dev/null `
            if [ -z "$found" ] ; then
                echo "" > "$key_file.new"
                echo "$i" >> "$key_file.new"
                echo "        default_application_id=$appname" >> "$key_file.new"
                echo "        icon_filename=adobe.pdf.png" >> "$key_file.new"
                echo "        default_action_type=application" >> "$key_file.new"
                cat "$key_file.new" >> "$key_file"
            else
                # update the mime-info
                /usr/xpg4/bin/awk -v application="$appname" -v mimetype="${i}"  '
                BEGIN {
                    header_start=mimetype;
                    matched=0;
                    dai=0; dat=0; ifn=0;
                }
                {
                    if (matched == 1) {
                        if (/^[^a-zA-Z_0-9]*default_application_id=/) {
                            print "        default_application_id=" application
                            dai=1;
                        }
                        else if (/^[^a-zA-Z_0-9]*default_action_type=/) {
                            print "        default_action_type=application"
                            dat=1;
                        }
                        else if (/^[^a-zA-Z_0-9]*icon_filename=/) {
                            print "        icon_filename=adobe.pdf.png";
                            ifn=1;
                        }
                        else {
                            if (/^ *$/) {
                                matched=0;
                                if (dai == 0) {
                                    print "        default_application_id=" application ;
                                }
                                if (dat == 0) {
                                    print "        default_action_type=application" ;
                                }
                                if (ifn == 0) {
                                    print "        icon_filename=adobe.pdf.png" ;
                                }
                            }
                            print $0 ;
                        }
                    }
                    else {
                        if (index($0, header_start) == 1 ) {
                            matched=1;
                        }
                        print $0 ;
                    }
                }
                ' "${key_file}" > "${key_file}.new" && mv -f "${key_file}.new" "${key_file}"
            fi
        done
    fi
}

defapp_generic()
{
    MIME="$1"
    xdg_user_dir="$XDG_DATA_HOME"
    [ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share"
    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_user_dir:$xdg_system_dirs" | sed 's/:/ /g'`; do
       DEBUG 2 "Checking $x/applications/defaults.list"
       trader_result=`grep "$MIME=" $x/applications/defaults.list 2> /dev/null | cut -d '=' -f 2 | cut -d ';' -f 1`
       if [ -n "$trader_result" ] ; then
          echo $trader_result
          exit_success
       fi
    done
    exit_success
}

defapp_kde()
{
    MIME="$1"
    ktradertest=`which ktradertest 2> /dev/null`
    if [ -n "$ktradertest" ] ; then
        DEBUG 1 "Running ktradertest \"$MIME\" Application"
        trader_result=`ktradertest "$MIME" Application 2>/dev/null | grep DesktopEntryPath \
            | head -n 1 | cut -d ':' -f 2 | cut -d \' -f 2`
        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"
        ;;

      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
    ;;

  unset)                                                                                                                                                                    
    action=unsetdefault                                                                                                                                                     
    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"
        app_path="${APP_PATH}"
        shift
        
        make_default_kde "$filename" "$mimetype"
        make_default_generic "$filename" "$mimetype" "$app_path"
#    done
    exit_success
fi

if [ "$action" = "unsetdefault" ]; 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"                                                                                                                                                       
	app_path="${APP_PATH}"
	shift                                                                                                                                                               
	
	unset_default_kde "$filename" "$mimetype" 2> /dev/null
	unset_default_generic "$filename" "$mimetype" "${app_path}" 2> /dev/null
#   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)
        info_gnome "$filename"
        ;;

        generic)
        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-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 {
 supress=0
}
{
 do 
    if (supress) {
       if (match($0,/-->/)) {
           $0=substr($0,RSTART+RLENGTH)
           supress=0
       }
       else {
           break
       }
    }
    else {
       if (match($0,/<!--/)) {
           if (RSTART>1) print substr($0,0,RSTART)
           $0=substr($0,RSTART+RLENGTH)
           supress=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 {
 supress=0
}
{
 do 
    if (supress) {
       if (match($0,/-->/)) {
           $0=substr($0,RSTART+RLENGTH)
           supress=0
       }
       else {
           break
       }
    }
    else {
       if (match($0,/<!--/)) {
           if (RSTART>1) print substr($0,0,RSTART)
           $0=substr($0,RSTART+RLENGTH)
           supress=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("&lt;", "<", comment)
        sub("&gt;", ">", comment)
        sub("&amp;", "\\&", 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 ; 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

