Upstream version 9.37.195.0
[platform/framework/web/crosswalk.git] / src / chrome / tools / test / reference_build / chrome_linux / xdg-mime
1 #!/bin/sh
2 #---------------------------------------------
3 #   xdg-mime
4 #
5 #   Utility script to manipulate MIME related information
6 #   on XDG compliant systems.
7 #
8 #   Refer to the usage() function below for usage.
9 #
10 #   Copyright 2009-2010, Fathi Boudra <fabo@freedesktop.org>
11 #   Copyright 2009-2010, Rex Dieter <rdieter@fedoraproject.org>
12 #   Copyright 2006, Kevin Krammer <kevin.krammer@gmx.at>
13 #   Copyright 2006, Jeremy White <jwhite@codeweavers.com>
14 #
15 #   LICENSE:
16 #
17 #   Permission is hereby granted, free of charge, to any person obtaining a
18 #   copy of this software and associated documentation files (the "Software"),
19 #   to deal in the Software without restriction, including without limitation
20 #   the rights to use, copy, modify, merge, publish, distribute, sublicense,
21 #   and/or sell copies of the Software, and to permit persons to whom the
22 #   Software is furnished to do so, subject to the following conditions:
23 #
24 #   The above copyright notice and this permission notice shall be included
25 #   in all copies or substantial portions of the Software.
26 #
27 #   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
28 #   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 #   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30 #   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
31 #   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
32 #   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
33 #   OTHER DEALINGS IN THE SOFTWARE.
34 #
35 #---------------------------------------------
36
37 manualpage()
38 {
39 cat << _MANUALPAGE
40 Name
41
42 xdg-mime - command line tool for querying information about file type handling
43 and adding descriptions for new file types
44
45 Synopsis
46
47 xdg-mime query { filetype | default } ...
48
49 xdg-mime default application mimetype(s)
50
51 xdg-mime install [--mode mode] [--novendor] mimetypes-file
52
53 xdg-mime uninstall [--mode mode] mimetypes-file
54
55 xdg-mime { --help | --manual | --version }
56
57 Description
58
59 The xdg-mime program can be used to query information about file types and to
60 add descriptions for new file types.
61
62 Commands
63
64 query
65
66     Returns information related to file types.
67
68     The query option is for use inside a desktop session only. It is not
69     recommended to use xdg-mime query as root.
70
71     The following queries are supported:
72
73     query filetype FILE: Returns the file type of FILE in the form of a MIME
74     type.
75
76     query default mimetype: Returns the default application that the desktop
77     environment uses for opening files of type mimetype. The default
78     application is identified by its *.desktop file.
79
80 default
81
82     Ask the desktop environment to make application the default application for
83     opening files of type mimetype. An application can be made the default for
84     several file types by specifying multiple mimetypes.
85
86     application is the desktop file id of the application and has the form
87     vendor-name.desktop application must already be installed in the desktop
88     menu before it can be made the default handler. The aplication's desktop
89     file must list support for all the MIME types that it wishes to be the
90     default handler for.
91
92     Requests to make an application a default handler may be subject to system
93     policy or approval by the end-user. xdg-mime query can be used to verify
94     whether an application is the actual default handler for a specific file
95     type.
96
97     The default option is for use inside a desktop session only. It is not
98     recommended to use xdg-mime default as root.
99
100 install
101     Adds the file type descriptions provided in mimetypes-file to the desktop
102     environment. mimetypes-file must be a XML file that follows the
103     freedesktop.org Shared MIME-info Database specification and that has a
104     mime-info element as its document root. For each new file type one or more
105     icons with name type-subtype must be installed with the xdg-icon-resource
106     command in the mimetypes context. For example the filetype application/
107     vnd.oasis.opendocument.text requires an icon named
108     application-vnd.oasis.opendocument.text to be installed (unless the file
109     type recommends another icon name).
110 uninstall
111     Removes the file type descriptions provided in mimetypes-file and
112     previously added with xdg-mime install from the desktop environment.
113     mimetypes-file must be a XML file that follows the freedesktop.org Shared
114     MIME-info Database specification and that has a mime-info element as its
115     document root.
116
117 Options
118
119 --mode mode
120
121     mode can be user or system. In user mode the file is (un)installed for the
122     current user only. In system mode the file is (un)installed for all users
123     on the system. Usually only root is allowed to install in system mode.
124
125     The default is to use system mode when called by root and to use user mode
126     when called by a non-root user.
127
128 --novendor
129
130     Normally, xdg-mime checks to ensure that the mimetypes-file to be installed
131     has a proper vendor prefix. This option can be used to disable that check.
132
133     A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated
134     with a dash ("-"). Companies and organizations are encouraged to use a word
135     or phrase, preferably the organizations name, for which they hold a
136     trademark as their vendor prefix. The purpose of the vendor prefix is to
137     prevent name conflicts.
138
139 --help
140     Show command synopsis.
141 --manual
142     Show this manualpage.
143 --version
144     Show the xdg-utils version information.
145
146 Environment Variables
147
148 xdg-mime honours the following environment variables:
149
150 XDG_UTILS_DEBUG_LEVEL
151     Setting this environment variable to a non-zero numerical value makes
152     xdg-mime do more verbose reporting on stderr. Setting a higher value
153     increases the verbosity.
154 XDG_UTILS_INSTALL_MODE
155     This environment variable can be used by the user or administrator to
156     override the installation mode. Valid values are user and system.
157
158 Exit Codes
159
160 An exit code of 0 indicates success while a non-zero exit code indicates
161 failure. The following failure codes can be returned:
162
163 1
164     Error in command line syntax.
165 2
166     One of the files passed on the command line did not exist.
167 3
168     A required tool could not be found.
169 4
170     The action failed.
171 5
172     No permission to read one of the files passed on the command line.
173
174 See Also
175
176 xdg-icon-resource(1), xdg-desktop-menu(1)
177
178 Examples
179
180 xdg-mime query filetype /tmp/foobar.png
181
182 Prints the MIME type of the file /tmp/foobar.png, in this case image/png
183
184 xdg-mime query default image/png
185
186 Prints the .desktop filename of the application which is registered to open PNG
187 files.
188
189 xdg-mime install shinythings-shiny.xml
190
191 Adds a file type description for "shiny"-files. "shinythings-" is used as the
192 vendor prefix. The file type description could look as folows.
193
194 shinythings-shiny.xml:
195
196 <?xml version="1.0"?>
197 <mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
198   <mime-type type="text/x-shiny">
199     <comment>Shiny new file type</comment>
200     <glob pattern="*.shiny"/>
201     <glob pattern="*.shi"/>
202   </mime-type>
203 </mime-info>
204
205 An icon for this new file type must also be installed, for example with:
206
207 xdg-icon-resource install --context mimetypes --size 64 shiny-file-icon.png text-x-shiny
208
209 _MANUALPAGE
210 }
211
212 usage()
213 {
214 cat << _USAGE
215 xdg-mime - command line tool for querying information about file type handling
216 and adding descriptions for new file types
217
218 Synopsis
219
220 xdg-mime query { filetype | default } ...
221
222 xdg-mime default application mimetype(s)
223
224 xdg-mime install [--mode mode] [--novendor] mimetypes-file
225
226 xdg-mime uninstall [--mode mode] mimetypes-file
227
228 xdg-mime { --help | --manual | --version }
229
230 _USAGE
231 }
232
233 #@xdg-utils-common@
234
235 #----------------------------------------------------------------------------
236 #   Common utility functions included in all XDG wrapper scripts
237 #----------------------------------------------------------------------------
238
239 DEBUG()
240 {
241   [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && return 0;
242   [ ${XDG_UTILS_DEBUG_LEVEL} -lt $1 ] && return 0;
243   shift
244   echo "$@" >&2
245 }
246
247 # This handles backslashes but not quote marks.
248 first_word()
249 {
250     read first rest
251     echo "$first"
252 }
253
254 #-------------------------------------------------------------
255 # map a binary to a .desktop file
256 binary_to_desktop_file()
257 {
258     search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
259     binary="`which "$1"`"
260     binary="`readlink -f "$binary"`"
261     base="`basename "$binary"`"
262     IFS=:
263     for dir in $search; do
264         unset IFS
265         [ "$dir" ] || continue
266         [ -d "$dir/applications" -o -d "$dir/applnk" ] || continue
267         for file in "$dir"/applications/*.desktop "$dir"/applications/*/*.desktop "$dir"/applnk/*.desktop "$dir"/applnk/*/*.desktop; do
268             [ -r "$file" ] || continue
269             # Check to make sure it's worth the processing.
270             grep -q "^Exec.*$base" "$file" || continue
271             # Make sure it's a visible desktop file (e.g. not "preferred-web-browser.desktop").
272             grep -Eq "^(NoDisplay|Hidden)=true" "$file" && continue
273             command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`"
274             command="`which "$command"`"
275             if [ x"`readlink -f "$command"`" = x"$binary" ]; then
276                 # Fix any double slashes that got added path composition
277                 echo "$file" | sed -e 's,//*,/,g'
278                 return
279             fi
280         done
281     done
282 }
283
284 #-------------------------------------------------------------
285 # map a .desktop file to a binary
286 ## FIXME: handle vendor dir case
287 desktop_file_to_binary()
288 {
289     search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
290     desktop="`basename "$1"`"
291     IFS=:
292     for dir in $search; do
293         unset IFS
294         [ "$dir" -a -d "$dir/applications" ] || continue
295         file="$dir/applications/$desktop"
296         [ -r "$file" ] || continue
297         # Remove any arguments (%F, %f, %U, %u, etc.).
298         command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`"
299         command="`which "$command"`"
300         readlink -f "$command"
301         return
302     done
303 }
304
305 #-------------------------------------------------------------
306 # Exit script on successfully completing the desired operation
307
308 exit_success()
309 {
310     if [ $# -gt 0 ]; then
311         echo "$@"
312         echo
313     fi
314
315     exit 0
316 }
317
318
319 #-----------------------------------------
320 # Exit script on malformed arguments, not enough arguments
321 # or missing required option.
322 # prints usage information
323
324 exit_failure_syntax()
325 {
326     if [ $# -gt 0 ]; then
327         echo "xdg-mime: $@" >&2
328         echo "Try 'xdg-mime --help' for more information." >&2
329     else
330         usage
331         echo "Use 'man xdg-mime' or 'xdg-mime --manual' for additional info."
332     fi
333
334     exit 1
335 }
336
337 #-------------------------------------------------------------
338 # Exit script on missing file specified on command line
339
340 exit_failure_file_missing()
341 {
342     if [ $# -gt 0 ]; then
343         echo "xdg-mime: $@" >&2
344     fi
345
346     exit 2
347 }
348
349 #-------------------------------------------------------------
350 # Exit script on failure to locate necessary tool applications
351
352 exit_failure_operation_impossible()
353 {
354     if [ $# -gt 0 ]; then
355         echo "xdg-mime: $@" >&2
356     fi
357
358     exit 3
359 }
360
361 #-------------------------------------------------------------
362 # Exit script on failure returned by a tool application
363
364 exit_failure_operation_failed()
365 {
366     if [ $# -gt 0 ]; then
367         echo "xdg-mime: $@" >&2
368     fi
369
370     exit 4
371 }
372
373 #------------------------------------------------------------
374 # Exit script on insufficient permission to read a specified file
375
376 exit_failure_file_permission_read()
377 {
378     if [ $# -gt 0 ]; then
379         echo "xdg-mime: $@" >&2
380     fi
381
382     exit 5
383 }
384
385 #------------------------------------------------------------
386 # Exit script on insufficient permission to write a specified file
387
388 exit_failure_file_permission_write()
389 {
390     if [ $# -gt 0 ]; then
391         echo "xdg-mime: $@" >&2
392     fi
393
394     exit 6
395 }
396
397 check_input_file()
398 {
399     if [ ! -e "$1" ]; then
400         exit_failure_file_missing "file '$1' does not exist"
401     fi
402     if [ ! -r "$1" ]; then
403         exit_failure_file_permission_read "no permission to read file '$1'"
404     fi
405 }
406
407 check_vendor_prefix()
408 {
409     file_label="$2"
410     [ -n "$file_label" ] || file_label="filename"
411     file=`basename "$1"`
412     case "$file" in
413        [a-zA-Z]*-*)
414          return
415          ;;
416     esac
417
418     echo "xdg-mime: $file_label '$file' does not have a proper vendor prefix" >&2
419     echo 'A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated' >&2
420     echo 'with a dash ("-"). An example '"$file_label"' is '"'example-$file'" >&2
421     echo "Use --novendor to override or 'xdg-mime --manual' for additional info." >&2
422     exit 1
423 }
424
425 check_output_file()
426 {
427     # if the file exists, check if it is writeable
428     # if it does not exists, check if we are allowed to write on the directory
429     if [ -e "$1" ]; then
430         if [ ! -w "$1" ]; then
431             exit_failure_file_permission_write "no permission to write to file '$1'"
432         fi
433     else
434         DIR=`dirname "$1"`
435         if [ ! -w "$DIR" -o ! -x "$DIR" ]; then
436             exit_failure_file_permission_write "no permission to create file '$1'"
437         fi
438     fi
439 }
440
441 #----------------------------------------
442 # Checks for shared commands, e.g. --help
443
444 check_common_commands()
445 {
446     while [ $# -gt 0 ] ; do
447         parm="$1"
448         shift
449
450         case "$parm" in
451             --help)
452             usage
453             echo "Use 'man xdg-mime' or 'xdg-mime --manual' for additional info."
454             exit_success
455             ;;
456
457             --manual)
458             manualpage
459             exit_success
460             ;;
461
462             --version)
463             echo "xdg-mime 1.1.0 rc1"
464             exit_success
465             ;;
466         esac
467     done
468 }
469
470 check_common_commands "$@"
471
472 [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && unset XDG_UTILS_DEBUG_LEVEL;
473 if [ ${XDG_UTILS_DEBUG_LEVEL-0} -lt 1 ]; then
474     # Be silent
475     xdg_redirect_output=" > /dev/null 2> /dev/null"
476 else
477     # All output to stderr
478     xdg_redirect_output=" >&2"
479 fi
480
481 #--------------------------------------
482 # Checks for known desktop environments
483 # set variable DE to the desktop environments name, lowercase
484
485 detectDE()
486 {
487     # see https://bugs.freedesktop.org/show_bug.cgi?id=34164
488     unset GREP_OPTIONS
489
490     if [ -n "${XDG_CURRENT_DESKTOP}" ]; then
491       case "${XDG_CURRENT_DESKTOP}" in
492          GNOME)
493            DE=gnome;
494            ;;
495          KDE)
496            DE=kde;
497            ;;
498          LXDE)
499            DE=lxde;
500            ;;
501          XFCE)
502            DE=xfce
503       esac
504     fi
505
506     if [ x"$DE" = x"" ]; then
507       # classic fallbacks
508       if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde;
509       elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome;
510       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;
511       elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce;
512       elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then DE=xfce
513       fi
514     fi
515
516     if [ x"$DE" = x"" ]; then
517       # fallback to checking $DESKTOP_SESSION
518       case "$DESKTOP_SESSION" in
519          gnome)
520            DE=gnome;
521            ;;
522          LXDE)
523            DE=lxde; 
524            ;;
525          xfce|xfce4)
526            DE=xfce;
527            ;;
528       esac
529     fi
530
531     if [ x"$DE" = x"" ]; then
532       # fallback to uname output for other platforms
533       case "$(uname 2>/dev/null)" in 
534         Darwin)
535           DE=darwin;
536           ;;
537       esac
538     fi
539
540     if [ x"$DE" = x"gnome" ]; then
541       # gnome-default-applications-properties is only available in GNOME 2.x
542       # but not in GNOME 3.x
543       which gnome-default-applications-properties > /dev/null 2>&1  || DE="gnome3"
544     fi
545 }
546
547 #----------------------------------------------------------------------------
548 # kfmclient exec/openURL can give bogus exit value in KDE <= 3.5.4
549 # It also always returns 1 in KDE 3.4 and earlier
550 # Simply return 0 in such case
551
552 kfmclient_fix_exit_code()
553 {
554     version=`LC_ALL=C.UTF-8 kde-config --version 2>/dev/null | grep '^KDE'`
555     major=`echo $version | sed 's/KDE.*: \([0-9]\).*/\1/'`
556     minor=`echo $version | sed 's/KDE.*: [0-9]*\.\([0-9]\).*/\1/'`
557     release=`echo $version | sed 's/KDE.*: [0-9]*\.[0-9]*\.\([0-9]\).*/\1/'`
558     test "$major" -gt 3 && return $1
559     test "$minor" -gt 5 && return $1
560     test "$release" -gt 4 && return $1
561     return 0
562 }
563
564 update_mime_database()
565 {
566    if [ x"$mode" = x"user" -a -n "$DISPLAY" ] ; then
567       detectDE
568       if [ x"$DE" = x"kde" ] ; then
569          DEBUG 1 "Running kbuildsycoca"
570          if [ x"$KDE_SESSION_VERSION" = x"4" ]; then
571              eval 'kbuildsycoca4'$xdg_redirect_output
572          else
573              eval 'kbuildsycoca'$xdg_redirect_output
574          fi
575       fi
576    fi
577    for x in `echo "$PATH:/opt/gnome/bin" | sed 's/:/ /g'`; do
578       if [ -x $x/update-mime-database ] ; then
579          DEBUG 1 "Running $x/update-mime-database $1"
580          eval '$x/update-mime-database $1'$xdg_redirect_output
581          return
582       fi
583    done
584 }
585
586 info_kde()
587 {
588     if [ x"$KDE_SESSION_VERSION" = x"4" ]; then
589         DEBUG 1 "Running kmimetypefinder \"$1\""
590         kmimetypefinder "$1" 2>/dev/null | head -n 1
591     else
592         DEBUG 1 "Running kfile \"$1\""
593         kfile "$1" 2> /dev/null | head -n 1 | cut -d "(" -f 2 | cut -d ")" -f 1
594     fi
595
596     if [ $? -eq 0 ]; then
597         exit_success
598     else
599         exit_failure_operation_failed
600     fi
601 }
602
603 info_gnome()
604 {
605     if gvfs-info --help 2>/dev/null 1>&2; then
606         DEBUG 1 "Running gvfs-info \"$1\""
607         gvfs-info "$1" 2> /dev/null | grep standard::content-type | cut -d' ' -f4
608     elif gnomevfs-info --help 2>/dev/null 1>&2; then
609        DEBUG 1 "Running gnomevfs-info \"$1\""
610        gnomevfs-info --slow-mime "$1" 2> /dev/null | grep "^MIME" | cut -d ":" -f 2 | sed s/"^ "//
611     else
612        # according to https://bugs.freedesktop.org/show_bug.cgi?id=33094#c5
613        # neither gvfs-info or gnomevfs-info are present in a default Ubuntu Natty
614        # install, so fallback to info_generic
615        info_generic "$1"
616     fi
617
618     if [ $? -eq 0 ]; then
619         exit_success
620     else
621         exit_failure_operation_failed
622     fi
623 }
624
625 info_generic()
626 {
627     if mimetype --version >/dev/null 2>&1; then
628         DEBUG 1 "Running mimetype -b \"$1\""
629         mimetype -b "$1"
630     else
631         DEBUG 1 "Running file --mime-type \"$1\""
632         /usr/bin/file --mime-type "$1" 2> /dev/null | cut -d ":" -f 2 | sed s/"^ "//
633     fi
634
635     if [ $? -eq 0 ]; then
636         exit_success
637     else
638         exit_failure_operation_failed
639     fi
640 }
641
642 make_default_kde()
643 {
644     # $1 is vendor-name.desktop
645     # $2 is mime/type
646     #
647     # On KDE 3, add to $KDE_CONFIG_PATH/profilerc:
648     # [$2 - 1]
649     # Application=$1
650     #
651     # Remove all [$2 - *] sections, or even better,
652     # renumber [$2 - *] sections and remove duplicate
653     #
654     # On KDE 4, add $2=$1 to $XDG_DATA_APPS/mimeapps.list
655     #
656     # Example file:
657     #
658     # [Added Associations]
659     # text/plain=kde4-kate.desktop;kde4-kwrite.desktop;
660     #
661     # [Removed Associations]
662     # text/plain=gnome-gedit.desktop;gnu-emacs.desktop;
663     vendor="$1"
664     mimetype="$2"
665     if [ x"$KDE_SESSION_VERSION" = x"4" ]; then
666         default_dir=`kde4-config --path xdgdata-apps 2> /dev/null | cut -d ':' -f 1`
667         default_file="$default_dir/mimeapps.list"
668     else
669         default_dir=`kde-config --path config 2> /dev/null | cut -d ':' -f 1`
670         default_file="$default_dir/profilerc"
671     fi
672     if [ -z "$default_dir" ]; then
673         DEBUG 2 "make_default_kde: No kde runtime detected"
674         return
675     fi
676     DEBUG 2 "make_default_kde $vendor $mimetype"
677     DEBUG 1 "Updating $default_file"
678     mkdir -p "$default_dir"
679     [ -f "$default_file" ] || touch "$default_file"
680     if [ x"$KDE_SESSION_VERSION" = x"4" ]; then
681         [ -f "$default_file" ] || touch "$default_file"
682         awk -v application="$vendor" -v mimetype="$mimetype" '
683     BEGIN {
684         prefix=mimetype "="
685         associations=0
686         found=0
687         blanks=0
688     }
689     {
690         suppress=0
691         if (index($0, "[Added Associations]") == 1) {
692             associations=1
693         } else if (index($0, "[") == 1) {
694             if (associations && !found) {
695                 print prefix application
696                 found=1
697             }
698             associations=0
699         } else if ($0 == "") {
700             blanks++
701             suppress=1
702         } else if (associations && index($0, prefix) == 1) {
703             value=substr($0, length(prefix) + 1, length)
704             split(value, apps, ";")
705             value=application ";"
706             count=0
707             for (i in apps) {
708               count++
709             }
710             for (i=0; i < count; i++) {
711                 if (apps[i] != application && apps[i] != "") {
712                     value=value apps[i] ";"
713                 }
714             }
715             $0=prefix value
716             found=1
717         }
718         if (!suppress) {
719             while (blanks > 0) {
720                 print ""
721                 blanks--
722             }
723             print $0
724         }
725     }
726     END {
727         if (!found) {
728             if (!associations) {
729                 print "[Added Associations]"
730             }
731             print prefix application
732         }
733         while (blanks > 0) {
734             print ""
735             blanks--
736         }
737     }
738 ' "$default_file" > "${default_file}.new" && mv "${default_file}.new" "$default_file"
739         eval 'kbuildsycoca4'$xdg_redirect_output
740     else
741         awk -v application="$vendor" -v mimetype="$mimetype" '
742     BEGIN {
743         header_start="[" mimetype " - "
744         suppress=0
745     }
746     {
747         if (index($0, header_start) == 1 )
748             suppress=1
749         else
750             if (/^\[/) { suppress=0 }
751
752         if (!suppress) {
753             print $0
754         }
755     }
756     END {
757         print ""
758         print "[" mimetype " - 1]"
759         print "Application=" application
760         print "AllowAsDefault=true"
761         print "GenericServiceType=Application"
762         print "Preference=1"
763         print "ServiceType=" mimetype
764     }
765 ' "$default_file" > "${default_file}.new" && mv "${default_file}.new" "$default_file"
766     fi
767 }
768
769 make_default_generic()
770 {
771     # $1 is vendor-name.desktop
772     # $2 is mime/type
773     # Add $2=$1 to XDG_DATA_HOME/applications/mimeapps.list
774     xdg_user_dir="$XDG_DATA_HOME"
775     [ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share"
776     default_file="$xdg_user_dir/applications/mimeapps.list"
777     DEBUG 2 "make_default_generic $1 $2"
778     DEBUG 1 "Updating $default_file"
779     [ -f "$default_file" ] || touch "$default_file"
780     awk -v mimetype="$2" -v application="$1" '
781     BEGIN {
782         prefix=mimetype "="
783         indefault=0
784         added=0
785         blanks=0
786         found=0
787     }
788     {
789         suppress=0
790         if (index($0, "[Default Applications]") == 1) {
791             indefault=1
792             found=1
793         } else if (index($0, "[") == 1) {
794             if (!added && indefault) {
795                 print prefix application
796                 added=1
797             }
798             indefault=0
799         } else if ($0 == "") {
800             suppress=1
801             blanks++
802         } else if (indefault && !added && index($0, prefix) == 1) {
803                 $0=prefix application
804                 added=1
805         }
806         if (!suppress) {
807             while (blanks > 0) {
808                 print ""
809                 blanks--
810             }
811             print $0
812         }
813     }
814     END {
815         if (!added) {
816             if (!found) {
817                 print ""
818                 print "[Default Applications]"
819             }
820             print prefix application
821         }
822         while (blanks > 0) {
823             print ""
824             blanks--
825         }
826     }
827 ' "$default_file" > "${default_file}.new" && mv "${default_file}.new" "$default_file"
828 }
829
830 defapp_generic()
831 {
832     MIME="$1"
833     xdg_user_dir="$XDG_DATA_HOME"
834     [ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share"
835     xdg_user_dir="$xdg_user_dir/$xdg_dir_name"
836     xdg_system_dirs="$XDG_DATA_DIRS"
837     [ -n "$xdg_system_dirs" ] || xdg_system_dirs=/usr/local/share/:/usr/share/
838
839     for x in `echo "$xdg_user_dir" | sed 's/:/ /g'`; do
840         mimeapps_list="$x/applications/mimeapps.list"
841         if [ -f "$mimeapps_list" ] ; then
842             DEBUG 2 "Checking $mimeapps_list"
843             trader_result=`awk -v mimetype="$MIME" '
844     BEGIN {
845         prefix=mimetype "="
846         indefault=0
847         found=0
848     }
849     {
850         if (index($0, "[Default Applications]") == 1) {
851             indefault=1
852         } else if (index($0, "[") == 1) {
853             indefault=0
854         } else if (!found && indefault && index($0, prefix) == 1) {
855             print substr($0, length(prefix) +1, length)
856             found=1
857         }
858     }
859 ' $mimeapps_list`
860             if [ -n "$trader_result" ] ; then
861                 echo $trader_result
862                 exit_success
863             fi
864         fi
865     done
866
867     for x in `echo "$xdg_system_dirs" | sed 's/:/ /g'`; do
868        DEBUG 2 "Checking $x/applications/defaults.list"
869        trader_result=`grep "$MIME=" $x/applications/defaults.list 2> /dev/null | cut -d '=' -f 2 | cut -d ';' -f 1`
870        if [ -n "$trader_result" ] ; then
871           echo $trader_result
872           exit_success
873        fi
874     done
875     exit_success
876 }
877
878 defapp_kde()
879 {
880     MIME="$1"
881     if [ x"$KDE_SESSION_VERSION" = x"4" ]; then
882         KTRADER=`which ktraderclient 2> /dev/null`
883         MIMETYPE="--mimetype"
884         SERVICETYPE="--servicetype"
885     else
886         KTRADER=`which ktradertest 2> /dev/null`
887     fi
888     if [ -n "$KTRADER" ] ; then
889         DEBUG 1 "Running KDE trader query \"$MIME\" mimetype and \"Application\" servicetype"
890         trader_result=`$KTRADER $MIMETYPE "$MIME" $SERVICETYPE Application 2>/dev/null \
891             | grep DesktopEntryPath | head -n 1 | cut -d ':' -f 2 | cut -d \' -f 2`
892         if [ -n "$trader_result" ] ; then
893             basename "$trader_result"
894             exit_success
895         else
896             exit_failure_operation_failed
897         fi
898     else
899         defapp_generic "$1"
900     fi
901 }
902
903 [ x"$1" != x"" ] || exit_failure_syntax
904
905 mode=
906 action=
907 filename=
908 mimetype=
909
910 case $1 in
911   install)
912     action=install
913     ;;
914
915   uninstall)
916     action=uninstall
917     ;;
918
919   query)
920     shift
921
922     if [ -z "$1" ] ; then
923         exit_failure_syntax "query type argument missing"
924     fi
925
926     case $1 in
927       filetype)
928         action=info
929
930         filename="$2"
931         if [ -z "$filename" ] ; then
932             exit_failure_syntax "FILE argument missing"
933         fi
934         case $filename in
935           -*)
936             exit_failure_syntax "unexpected option '$filename'"
937             ;;
938         esac
939         check_input_file "$filename"
940         filename=`readlink -f -- "$filename"`
941         ;;
942
943       default)
944         action=defapp
945         mimetype="$2"
946         if [ -z "$mimetype" ] ; then
947             exit_failure_syntax "mimetype argument missing"
948         fi
949         case $mimetype in
950           -*)
951             exit_failure_syntax "unexpected option '$mimetype'"
952             ;;
953
954           */*)
955             # Ok
956             ;;
957
958           *)
959             exit_failure_syntax "mimetype '$mimetype' is not in the form 'minor/major'"
960             ;;
961         esac
962         ;;
963
964       *)
965       exit_failure_syntax "unknown query type '$1'"
966       ;;
967     esac
968     ;;
969
970   default)
971     action=makedefault
972     shift
973
974     if [ -z "$1" ] ; then
975         exit_failure_syntax "application argument missing"
976     fi
977     case $1 in
978       -*)
979         exit_failure_syntax "unexpected option '$1'"
980         ;;
981
982       *.desktop)
983         filename="$1"
984         ;;
985
986       *)
987         exit_failure_syntax "malformed argument '$1', expected *.desktop"
988         ;;
989     esac
990     ;;
991
992   *)
993   exit_failure_syntax "unknown command '$1'"
994   ;;
995 esac
996
997 shift
998
999
1000 if [ "$action" = "makedefault" ]; then
1001     if [ -z "$1" ] ; then
1002         exit_failure_syntax "mimetype argument missing"
1003     fi
1004
1005     while [ $# -gt 0 ] ; do
1006         case $1 in
1007           -*)
1008             exit_failure_syntax "unexpected option '$1'"
1009             ;;
1010         esac
1011         mimetype="$1"
1012         shift
1013
1014         make_default_kde "$filename" "$mimetype"
1015         make_default_generic "$filename" "$mimetype"
1016     done
1017     exit_success
1018 fi
1019
1020 if [ "$action" = "info" ]; then
1021     detectDE
1022
1023     if [ x"$DE" = x"" ]; then
1024         if [ -x /usr/bin/file ]; then
1025             DE=generic
1026         fi
1027     fi
1028
1029     case "$DE" in
1030         kde)
1031         info_kde "$filename"
1032         ;;
1033
1034         gnome*)
1035         info_gnome "$filename"
1036         ;;
1037
1038         *)
1039         info_generic "$filename"
1040         ;;
1041     esac
1042     exit_failure_operation_impossible "no method available for quering MIME type of '$filename'"
1043 fi
1044
1045 if [ "$action" = "defapp" ]; then
1046     detectDE
1047
1048     case "$DE" in
1049         kde)
1050         defapp_kde "$mimetype"
1051         ;;
1052
1053         *)
1054         defapp_generic "$mimetype"
1055         ;;
1056     esac
1057     exit_failure_operation_impossible "no method available for quering default application for '$mimetype'"
1058 fi
1059
1060 vendor=true
1061 while [ $# -gt 0 ] ; do
1062     parm="$1"
1063     shift
1064
1065     case $parm in
1066       --mode)
1067         if [ -z "$1" ] ; then
1068             exit_failure_syntax "mode argument missing for --mode"
1069         fi
1070         case "$1" in
1071           user)
1072             mode="user"
1073             ;;
1074
1075           system)
1076             mode="system"
1077             ;;
1078
1079           *)
1080             exit_failure_syntax "unknown mode '$1'"
1081             ;;
1082         esac
1083         shift
1084         ;;
1085
1086       --novendor)
1087         vendor=false
1088         ;;
1089
1090       -*)
1091         exit_failure_syntax "unexpected option '$parm'"
1092         ;;
1093
1094       *)
1095         if [ -n "$filename" ] ; then
1096             exit_failure_syntax "unexpected argument '$parm'"
1097         fi
1098
1099         filename="$parm"
1100         check_input_file "$filename"
1101         ;;
1102     esac
1103 done
1104
1105 if [ -z "$action" ] ; then
1106     exit_failure_syntax "command argument missing"
1107 fi
1108
1109 if [ -n "$XDG_UTILS_INSTALL_MODE" ] ; then
1110     if [ "$XDG_UTILS_INSTALL_MODE" = "system" ] ; then
1111         mode="system"
1112     elif [ "$XDG_UTILS_INSTALL_MODE" = "user" ] ; then
1113         mode="user"
1114     fi
1115 fi
1116
1117 if [ -z "$mode" ] ; then
1118     if [ `whoami` = "root" ] ; then
1119         mode="system"
1120     else
1121         mode="user"
1122     fi
1123 fi
1124
1125 if [ -z "$filename" ] ; then
1126     exit_failure_syntax "mimetypes-file argument missing"
1127 fi
1128
1129 if [ "$vendor" =  "true" -a "$action" = "install" ] ; then
1130     check_vendor_prefix "$filename"
1131 fi
1132
1133 xdg_base_dir=
1134 xdg_dir_name=mime/packages/
1135
1136 xdg_user_dir="$XDG_DATA_HOME"
1137 [ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share"
1138 [ x"$mode" = x"user" ] && xdg_base_dir="$xdg_user_dir/mime"
1139 xdg_user_dir="$xdg_user_dir/$xdg_dir_name"
1140
1141 xdg_system_dirs="$XDG_DATA_DIRS"
1142 [ -n "$xdg_system_dirs" ] || xdg_system_dirs=/usr/local/share/:/usr/share/
1143 for x in `echo $xdg_system_dirs | sed 's/:/ /g'`; do
1144     if [ -w $x/$xdg_dir_name ] ; then
1145         [ x"$mode" = x"system" ] && xdg_base_dir="$x/mime"
1146         xdg_global_dir="$x/$xdg_dir_name"
1147         break
1148     fi
1149 done
1150 [ -w $xdg_global_dir ] || xdg_global_dir=
1151 DEBUG 3 "xdg_user_dir: $xdg_user_dir"
1152 DEBUG 3 "xdg_global_dir: $xdg_global_dir"
1153
1154 # Find KDE3 mimelnk directory
1155 kde_user_dir=
1156 kde_global_dir=
1157 kde_global_dirs=`kde${KDE_SESSION_VERSION}-config --path mime 2> /dev/null`
1158 DEBUG 3 "kde_global_dirs: $kde_global_dirs"
1159 first=
1160 for x in `echo $kde_global_dirs | sed 's/:/ /g'` ; do
1161     if [ -z "$first" ] ; then
1162         first=false
1163         kde_user_dir="$x"
1164     elif [ -w $x ] ; then
1165         kde_global_dir="$x"
1166     fi
1167 done
1168 DEBUG 3 "kde_user_dir: $kde_user_dir"
1169 DEBUG 3 "kde_global_dir: $kde_global_dir"
1170
1171 # TODO: Gnome legacy support
1172 # See http://forums.fedoraforum.org/showthread.php?t=26875
1173 gnome_user_dir="$HOME/.gnome/apps"
1174 gnome_global_dir=/usr/share/gnome/apps
1175 [ -w $gnome_global_dir ] || gnome_global_dir=
1176 DEBUG 3 "gnome_user_dir: $gnome_user_dir"
1177 DEBUG 3 "gnome_global_dir: $gnome_global_dir"
1178
1179 if [ x"$mode" = x"user" ] ; then
1180     xdg_dir="$xdg_user_dir"
1181     kde_dir="$kde_user_dir"
1182     gnome_dir="$gnome_user_dir"
1183     my_umask=077
1184 else
1185     xdg_dir="$xdg_global_dir"
1186     kde_dir="$kde_global_dir"
1187     gnome_dir="$gnome_global_dir"
1188     my_umask=022
1189     if [ -z "${xdg_dir}${kde_dir}${gnome_dir}" ] ; then
1190         exit_failure_operation_impossible "No writable system mimetype directory found."
1191     fi
1192 fi
1193
1194 # echo "[xdg|$xdg_user_dir|$xdg_global_dir]"
1195 # echo "[kde|$kde_user_dir|$kde_global_dir]"
1196 # echo "[gnome|$gnome_user_dir|$gnome_global_dir]"
1197 # echo "[using|$xdg_dir|$kde_dir|$gnome_dir]"
1198
1199 basefile=`basename "$filename"`
1200 #[ -z $vendor ] || basefile="$vendor-$basefile"
1201
1202 mimetypes=
1203 if [ -n "$kde_dir" ] ; then
1204     DEBUG 2 "KDE3 mimelnk directory found, extracting mimetypes from XML file"
1205
1206     mimetypes=`awk < "$filename" '
1207 # Strip XML comments
1208 BEGIN {
1209  suppress=0
1210 }
1211 {
1212  do
1213     if (suppress) {
1214        if (match($0,/-->/)) {
1215            $0=substr($0,RSTART+RLENGTH)
1216            suppress=0
1217        }
1218        else {
1219            break
1220        }
1221     }
1222     else {
1223        if (match($0,/<!--/)) {
1224            if (RSTART>1) print substr($0,0,RSTART)
1225            $0=substr($0,RSTART+RLENGTH)
1226            suppress=1
1227        }
1228        else {
1229            if ($0) print $0
1230            break
1231        }
1232     }
1233  while(1)
1234 }
1235 ' | awk '
1236 # List MIME types listed in <mime-type> tags
1237 BEGIN {
1238   RS="<"
1239 }
1240 /^mime-info/, /^\/mime-info/ {
1241   if (match($0,/^mime-type/)) {
1242     if (match($0,/type="[^"]*/) || match($0,/type='"'"'[^'"'"']*/)) {
1243       print substr($0,RSTART+6,RLENGTH-6)
1244     }
1245   }
1246 }'`
1247 fi
1248
1249 DEBUG 1 "$action mimetype in $xdg_dir"
1250
1251 case $action in
1252     install)
1253         save_umask=`umask`
1254         umask $my_umask
1255
1256         for x in $xdg_dir ; do
1257             mkdir -p $x
1258             eval 'cp $filename $x/$basefile'$xdg_redirect_output
1259         done
1260
1261         if [ -n "$mimetypes" ] ; then
1262             # No quotes around $mimetypes
1263             for x in $mimetypes ; do
1264                 DEBUG 1 "Installing $kde_dir/$x.desktop (KDE 3.x support)"
1265                 mkdir -p `dirname $kde_dir/$x.desktop`
1266                 awk < "$filename" '
1267 # Strip XML comments
1268 BEGIN {
1269  suppress=0
1270 }
1271 {
1272  do
1273     if (suppress) {
1274        if (match($0,/-->/)) {
1275            $0=substr($0,RSTART+RLENGTH)
1276            suppress=0
1277        }
1278        else {
1279            break
1280        }
1281     }
1282     else {
1283        if (match($0,/<!--/)) {
1284            if (RSTART>1) print substr($0,0,RSTART)
1285            $0=substr($0,RSTART+RLENGTH)
1286            suppress=1
1287        }
1288        else {
1289            if ($0) print $0
1290            break
1291        }
1292     }
1293  while(1)
1294 }
1295 ' | awk > $kde_dir/$x.desktop '
1296 # Extract mimetype $x from the XML file $filename
1297 # Note that bash requires us to escape a single quote as '"'"'
1298 BEGIN {
1299   the_type=ARGV[1]
1300   the_source=ARGV[2]
1301   ARGC=1
1302   RS="<"
1303   found=0
1304   glob_patterns=""
1305 }
1306 /^mime-info/, /^\/mime-info/ {
1307   if (match($0,/^mime-type/)) {
1308     if (match($0,/type="[^"]*/) || match($0,/type='"'"'[^'"'"']*/)) {
1309       if (substr($0,RSTART+6,RLENGTH-6) == the_type) {
1310         found=1
1311         print "[Desktop Entry]"
1312         print "# Installed by xdg-mime from " the_source
1313         print "Type=MimeType"
1314         print "MimeType=" the_type
1315         the_icon=the_type
1316         sub("/", "-", the_icon)
1317         print "Icon=" the_icon
1318       }
1319     }
1320   }
1321   else if (found) {
1322     if (match($0,/^\/mime-type/)) {
1323       if (glob_patterns)
1324          print "Patterns=" glob_patterns
1325       exit 0
1326     }
1327
1328     if (match($0,/^sub-class-of/)) {
1329       if (match($0,/type="[^"]*/) || match($0,/type='"'"'[^'"'"']*/)) {
1330         print "X-KDE-IsAlso=" substr($0,RSTART+6,RLENGTH-6)
1331       }
1332       else {
1333         print "Error: '"'"'type'"'"' argument missing in " RS $0
1334         exit 1
1335       }
1336     }
1337     if (match($0,/^glob/)) {
1338       if (match($0,/pattern="[^"]*/) || match($0,/pattern='"'"'[^'"'"']*/)) {
1339         glob_patterns = glob_patterns substr($0,RSTART+9,RLENGTH-9) ";"
1340       }
1341       else {
1342         print "Error: '"'"'pattern'"'"' argument missing in " RS $0
1343         exit 1
1344       }
1345     }
1346     if (match($0,/^comment/)) {
1347       if (match($0,/xml:lang="[^"]*/) || match($0,/xml:lang='"'"'[^'"'"']*/)) {
1348         lang=substr($0,RSTART+10,RLENGTH-10)
1349       }
1350       else {
1351         lang=""
1352       }
1353       if (match($0,/>/)) {
1354         comment=substr($0,RSTART+1)
1355         sub("&lt;", "<", comment)
1356         sub("&gt;", ">", comment)
1357         sub("&amp;", "\\&", comment)
1358         if (lang)
1359            print "Comment[" lang "]=" comment
1360         else
1361            print "Comment=" comment
1362       }
1363     }
1364   }
1365 }
1366 END {
1367   if (!found) {
1368     print "Error: Mimetype '"'"'" the_type "'"'"' not found"
1369     exit 1
1370   }
1371 }
1372 ' $x $basefile
1373                 if [ "$?" = "1" ] ; then
1374                     grep -A 10 "^Error:" $kde_dir/$x.desktop >&2
1375                     rm $kde_dir/$x.desktop
1376                     exit 1
1377                 fi
1378             done
1379         fi
1380
1381         umask $save_umask
1382         ;;
1383
1384     uninstall)
1385         for x in $xdg_dir ; do
1386             rm -f $x/$basefile
1387         done
1388
1389         # No quotes around $mimetypes
1390         for x in $mimetypes ; do
1391             if grep '^# Installed by xdg-mime' $kde_dir/$x.desktop >/dev/null 2>&1; then
1392                 DEBUG 1 "Removing $kde_dir/$x.desktop (KDE 3.x support)"
1393                 rm -f $kde_dir/$x.desktop
1394             fi
1395         done
1396         ;;
1397 esac
1398
1399 update_mime_database $xdg_base_dir
1400
1401 exit_success
1402