File suse-update-mime-defaults of Package desktop-file-utils
257
1
#!/bin/sh
2
#
3
# suse-update-mime-defaults - create default application ordering for MIME associations
4
#
5
# Copyright (C) 2012 Guido Berhoerster <gber@opensuse.org>
6
#
7
# Permission to use, copy, modify, and distribute this software for any
8
# purpose with or without fee is hereby granted, provided that the above
9
# copyright notice and this permission notice appear in all copies.
10
#
11
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
# TORTIOUS ACTION, ARISING OUT OF PERFORMANCE OF THIS SOFTWARE.
17
#
18
19
export LC_ALL=C
20
21
r=
22
case $1 in
23
DESTDIR=* )
24
r=`echo "$1" | sed s/^DESTDIR=//`
25
shift
26
;;
27
esac
28
29
# reset XDG_DATA_DIRS so it can be trusted
30
unset XDG_DATA_DIRS
31
if [ "${PROFILEREAD}" != "true" ]; then
32
. $r/etc/profile
33
fi
34
35
# ensue the cache directory structure is in order
36
if [ ! -d $r/var/cache/gio-2.0 ]; then
37
mkdir -m 755 -p $r/var/cache/gio-2.0
38
fi
39
40
for desktop in gnome xfce lxde; do
41
awk -vdesktop=${desktop} '
42
# print a warning to stderr
43
function warn(msg, cmd) {
44
cmd = "cat >&2"
45
print msg | cmd
46
close(cmd)
47
}
48
49
# print an error message and exit with the given exit status
50
function err(status, msg)
51
{
52
warn(msg)
53
exit_status = status
54
exit exit_status
55
}
56
57
# delete all elements of an array
58
function delete_array(arr, i) {
59
for (i in arr) {
60
delete arr[i]
61
}
62
}
63
64
# find preferred combination of mimetype and category
65
function find_preferred_category(mimetypes_categories, categories, mimetype,
66
i) {
67
for (i = 1; i in categories; i++) {
68
if (mimetype SUBSEP categories[i] in mimetypes_categories) {
69
return mimetypes_categories[mimetype,categories[i]]
70
}
71
}
72
}
73
74
# sort keys of an array by index (using the awk default comparison)
75
function asorti2(src, dest, key, len) {
76
len = 0
77
delete_array(dest)
78
for (key in src) {
79
dest[len++] = key
80
}
81
82
_qsorti(dest, 0, len - 1);
83
}
84
85
function array_swap(arr, i, j, tmp) {
86
tmp = arr[i]
87
arr[i] = arr[j]
88
arr[j] = tmp
89
}
90
91
# Based on Bentley, J. L., 2000. Programming Pearls. 2nd ed. Reading, MA:
92
# Addison-Wesley Professional.
93
function _qsorti(dest, l, u, val, i, j) {
94
if (l >= u) {
95
return
96
}
97
98
array_swap(dest, l, l + int(rand() * (u - l)))
99
val = dest[l]
100
i = l
101
j = u + 1
102
while (1) {
103
do { i++ } while (i <= u && dest[i] < val)
104
do { j-- } while (dest[j] > val)
105
if (i > j) {
106
break
107
}
108
array_swap(dest, i, j)
109
}
110
array_swap(dest, l, j)
111
112
_qsorti(dest, l, j - 1)
113
_qsorti(dest, j + 1, u)
114
}
115
116
BEGIN {
117
desktop = desktop != "" ? desktop : "gnome"
118
if (desktop == "gnome") {
119
categories_list = "GNOME,GTK"
120
} else if (desktop == "xfce") {
121
categories_list = "XFCE,GTK"
122
} else if (desktop == "lxde") {
123
categories_list = "GTK"
124
}
125
split(categories_list, categories, /,/)
126
root = ENVIRON["r"]
127
defaults_conf = root "/etc/" desktop "_defaults.conf"
128
129
# parse desktop defaults preferences
130
lineno = 0
131
while ((getline < defaults_conf) > 0) {
132
lineno++
133
if (NF == 0 || $1 ~ /^#/) {
134
# skip comments and empty lines
135
continue
136
} else if (NF != 1) {
137
err(1, "syntax error in " defaults_conf " line " lineno)
138
} else if (split($1, arr, /=/) == 2) {
139
# handle MIME type defaults
140
mimetype_default_apps[arr[1]] = arr[2]
141
} else if ($1 ~ /^!.+\.desktop$/) {
142
# handle preferred default applications
143
preferred_default_apps[substr($1, 2)] = substr($1, 2)
144
} else if ($1 ~ /^.+\.desktop$/) {
145
# handle regular default applications
146
default_apps[$1] = $1
147
} else {
148
err(1, "syntax error in " defaults_conf ", line " lineno)
149
}
150
}
151
close(defaults_conf)
152
153
# find all desktop files
154
for (i = split("XDG_DATA_DIRS" in ENVIRON ? ENVIRON["XDG_DATA_DIRS"] : \
155
"/usr/local/share:/usr/share", xdg_data_dirs, /:/); i > 0; i--) {
156
# XDG_DATA_DIRS is trusted here because it has been reset
157
cmd = "find \"" root xdg_data_dirs[i] "/applications/\" -name \"*.desktop\" " \
158
"2>/dev/null"
159
while ((cmd | getline desktopfile) > 0) {
160
l = split(desktopfile, arr, "/")
161
desktopfiles[arr[l]] = desktopfile
162
}
163
close(cmd)
164
}
165
166
# process all desktop files in alphabetical order
167
asorti2(desktopfiles, desktopfiles_keys)
168
for (i = 0; i in desktopfiles_keys; i++) {
169
# parse a desktop file
170
desktopfile = desktopfiles_keys[i]
171
delete_array(desktopfile_mimetypes)
172
delete_array(desktopfile_categories)
173
lineno = 0
174
in_desktop_entry = 0
175
while ((getline < desktopfiles[desktopfile]) > 0) {
176
lineno++
177
if (NF == 0 || $1 ~ /^#/) {
178
# skip comments and empty lines
179
continue
180
} else if (in_desktop_entry == 0 && \
181
$0 ~ /^\[Desktop Entry\][\t ]*$/) {
182
# desktop entry group
183
in_desktop_entry = 1
184
} else if (in_desktop_entry == 1) {
185
if (in_desktop_entry == 1 && $1 ~ /^\[/) {
186
# quit when a different group starts, "Desktop Entry" must
187
# come first
188
break
189
} else if ($0 ~ /^MimeType *=/ && split($0, arr, /=/) == 2) {
190
# handle MimeTypes
191
gsub(/(^ *|; *$)/, "", arr[2])
192
split(arr[2], desktopfile_mimetypes, /;/)
193
} else if ($0 ~ /^Categories *=/ && split($0, arr, /=/) == 2) {
194
# handle Categories
195
gsub(/(^ *|; *$)/, "", arr[2])
196
split(arr[2], desktopfile_categories, /;/)
197
} else if ($0 ~ /^[A-Za-z0-9\[\]@_-]+ *=/) {
198
# skip other keys
199
continue
200
}
201
} else {
202
warn("syntax error in " desktopfiles[desktopfile] ", line " \
203
lineno)
204
break
205
}
206
}
207
close(desktopfiles[desktopfile])
208
209
# store the results
210
for (j = 1; j in desktopfile_mimetypes; j++) {
211
if (desktopfile_mimetypes[j] in mimetype_default_apps && \
212
mimetype_default_apps[desktopfile_mimetypes[j]] == \
213
desktopfile) {
214
mimetype_defaults[desktopfile_mimetypes[j]] = desktopfile
215
}
216
if (desktopfile in preferred_default_apps) {
217
preferred_defaults[desktopfile_mimetypes[j]] = desktopfile
218
}
219
if (desktopfile in default_apps) {
220
defaults[desktopfile_mimetypes[j]] = desktopfile
221
}
222
for (k = 1; k in desktopfile_categories; k++) {
223
mimetypes_categories[desktopfile_mimetypes[j], \
224
desktopfile_categories[k]] = desktopfile
225
}
226
generic_mimetypes[desktopfile_mimetypes[j]] = desktopfile
227
}
228
}
229
230
# determine default mimetype handlers
231
for (mimetype in generic_mimetypes) {
232
if (mimetype in mimetype_defaults) {
233
defaults_list[mimetype] = mimetype_defaults[mimetype]
234
} else if (mimetype in preferred_defaults) {
235
defaults_list[mimetype] = preferred_defaults[mimetype]
236
} else if (mimetype in defaults) {
237
defaults_list[mimetype] = defaults[mimetype]
238
} else if ((desktopfile = \
239
find_preferred_category(mimetypes_categories, categories, \
240
mimetype)) != "") {
241
defaults_list[mimetype] = desktopfile
242
} else if (mimetype in generic_mimetypes) {
243
defaults_list[mimetype] = generic_mimetypes[mimetype]
244
}
245
}
246
247
print "# generated by suse-update-mime-defaults from " defaults_conf
248
print "[Default Applications]"
249
asorti2(defaults_list, defaults_list_keys)
250
for (i = 0; i in defaults_list_keys; i++) {
251
mimetype = defaults_list_keys[i]
252
printf("%s=%s\n", mimetype, defaults_list[mimetype])
253
}
254
}
255
' >$r/var/cache/gio-2.0/${desktop}-mimeapps.list
256
done
257