/
update-user-apps.sh
executable file
·215 lines (183 loc) · 7.58 KB
/
update-user-apps.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#!/bin/bash
## Generates the applications.conf simple rules ##
## See scripts/cron.daily/99ulatencyd ##
# BUGS: doess not handle whitespaces in paths to .desktop files
DEPENDECIES_SATISFIED=1
which file >/dev/null || { echo "The 'file' command not found." >&2 && DEPENDECIES_SATISFIED=0; }
which debtags >/dev/null || { echo "The 'debtags' command not found." >&2 && DEPENDECIES_SATISFIED=0; }
if [ $DEPENDECIES_SATISFIED = 0 ]; then
echo "$0: Dependecies not satisfied, aborting." >&2
exit 1
fi
timeout=60 # flag timeout
flag_params="instant=1 inherit=1 timeout=$timeout"
output=${1:-/etc/ulatencyd/simple.d/applications.conf}
# XDG_DATA_DIRS to search for desktop files
_XDG_DATA_DIRS="/usr/local/share:/usr/share:/usr/share/gnome"
## additions to _XDG_DATA_DIRS
# add desktop files generated from Debian menu files
ADD_DEBIAN_MENUS="yes"
# add desktop files with xsessions
ADD_XSESSIONS="yes"
# add user desktop files
# SECURITY WARNING: generated rules may contain user's private executables!
ADD_USERS="yes"
[ "$ADD_DEBIAN_MENUS" = "yes" ] && _XDG_DATA_DIRS="$_XDG_DATA_DIRS:/var/lib/menu-xdg"
[ "$ADD_USERS" = "yes" ] && _XDG_DATA_DIRS="$_XDG_DATA_DIRS:$(egrep '^([^:]*:){2}[0-9]{4,}' /etc/passwd | cut -d: -f 6 | while read line; do echo -n "$line/.local/share:"; done)"
DESKTOP_DIRS="$(echo "$_XDG_DATA_DIRS" | sed 's/:/\/applications:/g;s/:$//;//d')"
[ "$ADD_XSESSIONS" = "yes" ] && DESKTOP_DIRS="$DESKTOP_DIRS:$(echo "$_XDG_DATA_DIRS" | sed 's/:/\/xsessions:/g;s/:$//;//d')"
EXEC_PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games"
FILE_CMD="file --brief -e apptype -e ascii -e encoding -e cdf -e compress -e tar -e elf --mime-type"
# include only executables of following types (extended regex without surrounding braces)
BINARY_TYPES_RE="application/x-executable|application/x-sharedlib"
SCRIPT_TYPES_RE="application/octet-stream"
flag_name="application.starting"
# trim usage: var=" sdf fd "; trim var
trim() {
read -rd '' $1 <<<"${!1}"
}
# get interpreters, desktop files that execute an interpreter will be ignored
INTERPRETERS=$(tempfile)
debtags search '(interface::shell || devel::interpreter) && !x11::application' | cut -d' ' -f1 |
xargs dpkg-query --listfiles 2>/dev/null | sort -u |
while read file; do
trim file
[ -z "$file" ] && continue
[ -x "$file" ] || continue;
real="$(readlink -e "$file")";
[ "$?" != 0 ] && continue;
[ -z "$real" ] && continue;
[ -x "$real" ] || continue;
if $FILE_CMD "$real" | egrep -xq "($BINARY_TYPES_RE|$SCRIPT_TYPES_RE)" 2>/dev/null; then
echo "$real"
fi
done | sort -u >$INTERPRETERS
COMMENTED=$(tempfile)
COMMENTED_APPLIED=$(tempfile)
sed -n "/#[^[:blank:]].*$flag_name\b/p" "$output" | sed "s/ $flag_name\b.*$/ $flag_name /" | sort -u >$COMMENTED
exec >"$output"
echo "# desktop applications boosted when starting"
echo "# Automatically generated by $0 on $(date --rfc-3339=seconds)"
echo "# "
echo "# To exclude some application comment the line with #. Such commented lines are preserved."
echo "# To include custom applications put them in own simple rules file(s)."
echo
# set DEBUG="yes" to log debug messages into DEBUG_LOG file
DEBUG="no"
DEBUG="yes"
DEBUG_LOG=/tmp/log
[ "$DEBUG" = "yes" ] && echo -e "GENERATING STARTED ($(date --rfc-2822))\n" >$DEBUG_LOG
SIMPLE_BINS=$(tempfile)
SIMPLE_SCRIPTS=$(tempfile)
PARAMETRIZED_BINS=$(tempfile)
PARAMETRIZED_SCRIPTS=$(tempfile)
echo -n "$DESKTOP_DIRS" | xargs -d: -n1 -I '{}' find "{}" -type f -name '*.desktop' 2>/dev/null |
xargs grep -ilF 'Type=Application' |
xargs grep -iLF 'Terminal=true' |
xargs grep -iLF 'NoDisplay=true' |
xargs grep -iLF 'OnlyShowIn=X-' |
xargs |
while read files; do
grep -h '^Exec=' $files | cut -b6-
grep -h '^StartupWMClass=' $files | cut -b16-
done |
#cut -f1 -d' ' |
sort -u |
while read exec; do
[ -z "$exec" ] && continue
trim exec
exec_prog="${exec%% *}"
exec_params=
if [ "$exec_prog" != "$exec" ]; then
# exec with parameters
exec_params="${exec#*[[:blank:]]}"
fi
real_exec="$(PATH=$EXEC_PATH which "$exec_prog" 2>/dev/null)"
if [ -z "$real_exec" ]; then
[ "$DEBUG" = "yes" ] && echo "IGNORED (exec file not found): exec: '$exec'" >>$DEBUG_LOG
continue
fi
chased_exec="$(readlink -e "$real_exec" 2>/dev/null)"
if [ -z "$chased_exec" ]; then
[ "$DEBUG" = "yes" ] && echo "IGNORED (exec is broken symbolic link?): real exec: '$real_exec' exec: '$exec'" >>$DEBUG_LOG
continue
fi
if grep -Fxq "$chased_exec" $INTERPRETERS; then
# interpreter
#cmd_match="cmd:$hashbang_value\ $real_exec"
[ "$DEBUG" = "yes" ] && echo "IGNORED (called with interpreter): '$chased_exec' exec: '$exec'" >>$DEBUG_LOG
continue
else
exec_type="$($FILE_CMD "$chased_exec" 2>/dev/null)"
if [ -z "$exec_type" ]; then
[ "$DEBUG" = "yes" ] && echo "IGNORED (cannot get filetype): '$chased_exec' exec: '$exec'" >>$DEBUG_LOG
continue
fi
if echo "$exec_type" | egrep -xq "($BINARY_TYPES_RE)"; then
match="$(printf "%-30s $flag_name" "\"$chased_exec\"")"
# disable if commented in old output version
if grep -qFx "#$match " $COMMENTED; then
echo "#$match " >>$COMMENTED_APPLIED
match="#$match"
fi
echo "$match $flag_params"
if [ -n "$exec_params" ]; then
echo "$chased_exec $exec" >>$PARAMETRIZED_BINS
else
echo "$chased_exec" >>$SIMPLE_BINS
fi
elif echo "$exec_type" | egrep -xq "($SCRIPT_TYPES_RE)"; then
hashbang_line="$(head -n1 "$chased_exec")"
hashbang_value="${hashbang_line#\#\!}"
trim hashbang_value
if [ -z "$hashbang_value" ]; then
[ "$DEBUG" = "yes" ] && echo "IGNORED (script: hashbang problem): '$chased_exec' exec: '$exec'" >>$DEBUG_LOG
continue
fi
hashbang_value="${hashbang_value// /\\ }" # escape spaces
## version without arguments
match="$(printf "%-30s $flag_name" "cmd:$hashbang_value\ $real_exec")"
# disable if commented in old output version
if grep -qFx "#$match " $COMMENTED; then
echo "#$match " >>$COMMENTED_APPLIED
match="#$match"
fi
echo "$match $flag_params"
## version with arbitrary argument count
match="$(printf "%-30s $flag_name" "cmd:$hashbang_value\ $real_exec\ *")"
# disable if commented in old output version
if grep -qFx "#$match " $COMMENTED; then
echo "#$match " >>$COMMENTED_APPLIED
match="#$match"
fi
echo "$match $flag_params"
if [ -n "$exec_params" ]; then
echo "$chased_exec $exec" >>$PARAMETRIZED_SCRIPTS
else
echo "$chased_exec" >>$SIMPLE_SCRIPTS
fi
else
echo "IGNORED (unsupported filetype): '$chased_exec' exec: '$exec', filetype: '$exec_type'" >>$DEBUG_LOG
continue
fi
fi
done |
sort -u
COMMENTED_NOT_APPLIED=$(tempfile)
(sort -u $COMMENTED_APPLIED; cat $COMMENTED) | sort | uniq -u > $COMMENTED_NOT_APPLIED
if [ -s $COMMENTED_NOT_APPLIED ]; then
echo
echo "# commented by user in the past:"
cat $COMMENTED_NOT_APPLIED
fi
rm -f $COMMENTED $COMMENTED_APPLIED $COMMENTED_NOT_APPLIED $INTERPRETERS
while read -r chased_exec exec; do
grep -Fxq "$chased_exec" $SIMPLE_BINS && continue || true
[ "$DEBUG" = "yes" ] && echo "WARNING (binary exec with params will be boosted with any params, double check this): '$chased_exec' exec: '$exec'" >>$DEBUG_LOG
done <$PARAMETRIZED_BINS
rm -f $SIMPLE_BINS $PARAMETRIZED_BINS
while read -r chased_exec exec; do
grep -Fxq "$chased_exec" $SIMPLE_SCRIPTS && continue || true
[ "$DEBUG" = "yes" ] && echo "WARNING (script exec with params will be boosted with any params, double check this): '$chased_exec' exec: '$exec'" >>$DEBUG_LOG
done <$PARAMETRIZED_SCRIPTS
rm -f $SIMPLE_SCRIPTS $PARAMETRIZED_SCRIPTS