base-files/functions.sh: remove useless cat
[oweals/openwrt.git] / package / base-files / files / lib / functions.sh
1 #!/bin/sh
2 # Copyright (C) 2006-2014 OpenWrt.org
3 # Copyright (C) 2006 Fokus Fraunhofer <carsten.tittel@fokus.fraunhofer.de>
4 # Copyright (C) 2010 Vertical Communications
5
6
7 debug () {
8         ${DEBUG:-:} "$@"
9 }
10
11 # newline
12 N="
13 "
14
15 _C=0
16 NO_EXPORT=1
17 LOAD_STATE=1
18 LIST_SEP=" "
19
20 # xor multiple hex values of the same length
21 xor() {
22         local val
23         local ret="0x$1"
24         local retlen=${#1}
25
26         shift
27         while [ -n "$1" ]; do
28                 val="0x$1"
29                 ret=$((ret ^ val))
30                 shift
31         done
32
33         printf "%0${retlen}x" "$ret"
34 }
35
36 append() {
37         local var="$1"
38         local value="$2"
39         local sep="${3:- }"
40
41         eval "export ${NO_EXPORT:+-n} -- \"$var=\${$var:+\${$var}\${value:+\$sep}}\$value\""
42 }
43
44 list_contains() {
45         local var="$1"
46         local str="$2"
47         local val
48
49         eval "val=\" \${$var} \""
50         [ "${val%% $str *}" != "$val" ]
51 }
52
53 config_load() {
54         [ -n "$IPKG_INSTROOT" ] && return 0
55         uci_load "$@"
56 }
57
58 reset_cb() {
59         config_cb() { return 0; }
60         option_cb() { return 0; }
61         list_cb() { return 0; }
62 }
63 reset_cb
64
65 package() {
66         return 0
67 }
68
69 config () {
70         local cfgtype="$1"
71         local name="$2"
72
73         export ${NO_EXPORT:+-n} CONFIG_NUM_SECTIONS=$((CONFIG_NUM_SECTIONS + 1))
74         name="${name:-cfg$CONFIG_NUM_SECTIONS}"
75         append CONFIG_SECTIONS "$name"
76         export ${NO_EXPORT:+-n} CONFIG_SECTION="$name"
77         config_set "$CONFIG_SECTION" "TYPE" "${cfgtype}"
78         [ -n "$NO_CALLBACK" ] || config_cb "$cfgtype" "$name"
79 }
80
81 option () {
82         local varname="$1"; shift
83         local value="$*"
84
85         config_set "$CONFIG_SECTION" "${varname}" "${value}"
86         [ -n "$NO_CALLBACK" ] || option_cb "$varname" "$*"
87 }
88
89 list() {
90         local varname="$1"; shift
91         local value="$*"
92         local len
93
94         config_get len "$CONFIG_SECTION" "${varname}_LENGTH" 0
95         [ $len = 0 ] && append CONFIG_LIST_STATE "${CONFIG_SECTION}_${varname}"
96         len=$((len + 1))
97         config_set "$CONFIG_SECTION" "${varname}_ITEM$len" "$value"
98         config_set "$CONFIG_SECTION" "${varname}_LENGTH" "$len"
99         append "CONFIG_${CONFIG_SECTION}_${varname}" "$value" "$LIST_SEP"
100         [ -n "$NO_CALLBACK" ] || list_cb "$varname" "$*"
101 }
102
103 config_unset() {
104         config_set "$1" "$2" ""
105 }
106
107 # config_get <variable> <section> <option> [<default>]
108 # config_get <section> <option>
109 config_get() {
110         case "$3" in
111                 "") eval echo "\"\${CONFIG_${1}_${2}:-\${4}}\"";;
112                 *)  eval export ${NO_EXPORT:+-n} -- "${1}=\${CONFIG_${2}_${3}:-\${4}}";;
113         esac
114 }
115
116 # config_get_bool <variable> <section> <option> [<default>]
117 config_get_bool() {
118         local _tmp
119         config_get _tmp "$2" "$3" "$4"
120         case "$_tmp" in
121                 1|on|true|yes|enabled) _tmp=1;;
122                 0|off|false|no|disabled) _tmp=0;;
123                 *) _tmp="$4";;
124         esac
125         export ${NO_EXPORT:+-n} "$1=$_tmp"
126 }
127
128 config_set() {
129         local section="$1"
130         local option="$2"
131         local value="$3"
132
133         export ${NO_EXPORT:+-n} "CONFIG_${section}_${option}=${value}"
134 }
135
136 config_foreach() {
137         local ___function="$1"
138         [ "$#" -ge 1 ] && shift
139         local ___type="$1"
140         [ "$#" -ge 1 ] && shift
141         local section cfgtype
142
143         [ -z "$CONFIG_SECTIONS" ] && return 0
144         for section in ${CONFIG_SECTIONS}; do
145                 config_get cfgtype "$section" TYPE
146                 [ -n "$___type" -a "x$cfgtype" != "x$___type" ] && continue
147                 eval "$___function \"\$section\" \"\$@\""
148         done
149 }
150
151 config_list_foreach() {
152         [ "$#" -ge 3 ] || return 0
153         local section="$1"; shift
154         local option="$1"; shift
155         local function="$1"; shift
156         local val
157         local len
158         local c=1
159
160         config_get len "${section}" "${option}_LENGTH"
161         [ -z "$len" ] && return 0
162         while [ $c -le "$len" ]; do
163                 config_get val "${section}" "${option}_ITEM$c"
164                 eval "$function \"\$val\" \"\$@\""
165                 c="$((c + 1))"
166         done
167 }
168
169 default_prerm() {
170         local root="${IPKG_INSTROOT}"
171         local pkgname="$(basename ${1%.*})"
172         local ret=0
173
174         if [ -f "$root/usr/lib/opkg/info/${pkgname}.prerm-pkg" ]; then
175                 ( . "$root/usr/lib/opkg/info/${pkgname}.prerm-pkg" )
176                 ret=$?
177         fi
178
179         local shell="$(which bash)"
180         for i in $(grep -s "^/etc/init.d/" "$root/usr/lib/opkg/info/${pkgname}.list"); do
181                 if [ -n "$root" ]; then
182                         ${shell:-/bin/sh} "$root/etc/rc.common" "$root$i" disable
183                 else
184                         if [ "$PKG_UPGRADE" != "1" ]; then
185                                 "$i" disable
186                         fi
187                         "$i" stop
188                 fi
189         done
190
191         return $ret
192 }
193
194 add_group_and_user() {
195         local pkgname="$1"
196         local rusers="$(sed -ne 's/^Require-User: *//p' $root/usr/lib/opkg/info/${pkgname}.control 2>/dev/null)"
197
198         if [ -n "$rusers" ]; then
199                 local tuple oIFS="$IFS"
200                 for tuple in $rusers; do
201                         local uid gid uname gname
202
203                         IFS=":"
204                         set -- $tuple; uname="$1"; gname="$2"
205                         IFS="="
206                         set -- $uname; uname="$1"; uid="$2"
207                         set -- $gname; gname="$1"; gid="$2"
208                         IFS="$oIFS"
209
210                         if [ -n "$gname" ] && [ -n "$gid" ]; then
211                                 group_exists "$gname" || group_add "$gname" "$gid"
212                         elif [ -n "$gname" ]; then
213                                 gid="$(group_add_next "$gname")"
214                         fi
215
216                         if [ -n "$uname" ]; then
217                                 user_exists "$uname" || user_add "$uname" "$uid" "$gid"
218                         fi
219
220                         if [ -n "$uname" ] && [ -n "$gname" ]; then
221                                 group_add_user "$gname" "$uname"
222                         fi
223
224                         unset uid gid uname gname
225                 done
226         fi
227 }
228
229 default_postinst() {
230         local root="${IPKG_INSTROOT}"
231         local pkgname="$(basename ${1%.*})"
232         local filelist="/usr/lib/opkg/info/${pkgname}.list"
233         local ret=0
234
235         add_group_and_user "${pkgname}"
236
237         if [ -f "$root/usr/lib/opkg/info/${pkgname}.postinst-pkg" ]; then
238                 ( . "$root/usr/lib/opkg/info/${pkgname}.postinst-pkg" )
239                 ret=$?
240         fi
241
242         if [ -d "$root/rootfs-overlay" ]; then
243                 cp -R $root/rootfs-overlay/. $root/
244                 rm -fR $root/rootfs-overlay/
245         fi
246
247         if [ -z "$root" ]; then
248                 if grep -m1 -q -s "^/etc/modules.d/" "$filelist"; then
249                         kmodloader
250                 fi
251
252                 if grep -m1 -q -s "^/etc/sysctl.d/" "$filelist"; then
253                         /etc/init.d/sysctl restart
254                 fi
255
256                 if grep -m1 -q -s "^/etc/uci-defaults/" "$filelist"; then
257                         . /lib/functions/system.sh
258                         [ -d /tmp/.uci ] || mkdir -p /tmp/.uci
259                         for i in $(grep -s "^/etc/uci-defaults/" "$filelist"); do
260                                 ( [ -f "$i" ] && cd "$(dirname $i)" && . "$i" ) && rm -f "$i"
261                         done
262                         uci commit
263                 fi
264
265                 rm -f /tmp/luci-indexcache
266         fi
267
268         local shell="$(which bash)"
269         for i in $(grep -s "^/etc/init.d/" "$root$filelist"); do
270                 if [ -n "$root" ]; then
271                         ${shell:-/bin/sh} "$root/etc/rc.common" "$root$i" enable
272                 else
273                         if [ "$PKG_UPGRADE" != "1" ]; then
274                                 "$i" enable
275                         fi
276                         "$i" start
277                 fi
278         done
279
280         return $ret
281 }
282
283 include() {
284         local file
285
286         for file in $(ls $1/*.sh 2>/dev/null); do
287                 . $file
288         done
289 }
290
291 find_mtd_index() {
292         local PART="$(grep "\"$1\"" /proc/mtd | awk -F: '{print $1}')"
293         local INDEX="${PART##mtd}"
294
295         echo ${INDEX}
296 }
297
298 find_mtd_part() {
299         local INDEX=$(find_mtd_index "$1")
300         local PREFIX=/dev/mtdblock
301
302         [ -d /dev/mtdblock ] && PREFIX=/dev/mtdblock/
303         echo "${INDEX:+$PREFIX$INDEX}"
304 }
305
306 group_add() {
307         local name="$1"
308         local gid="$2"
309         local rc
310         [ -f "${IPKG_INSTROOT}/etc/group" ] || return 1
311         [ -n "$IPKG_INSTROOT" ] || lock /var/lock/group
312         echo "${name}:x:${gid}:" >> ${IPKG_INSTROOT}/etc/group
313         [ -n "$IPKG_INSTROOT" ] || lock -u /var/lock/group
314 }
315
316 group_exists() {
317         grep -qs "^${1}:" ${IPKG_INSTROOT}/etc/group
318 }
319
320 group_add_next() {
321         local gid gids
322         gid=$(grep -s "^${1}:" ${IPKG_INSTROOT}/etc/group | cut -d: -f3)
323         if [ -n "$gid" ]; then
324                 echo $gid
325                 return
326         fi
327         gids=$(cut -d: -f3 ${IPKG_INSTROOT}/etc/group)
328         gid=65536
329         while [ -n "$(echo "$gids" | grep "^$gid$")" ] ; do
330                 gid=$((gid + 1))
331         done
332         group_add $1 $gid
333         echo $gid
334 }
335
336 group_add_user() {
337         local grp delim=","
338         grp=$(grep -s "^${1}:" ${IPKG_INSTROOT}/etc/group)
339         [ -z "$(echo $grp | cut -d: -f4 | grep $2)" ] || return
340         [ -n "$(echo $grp | grep ":$")" ] && delim=""
341         [ -n "$IPKG_INSTROOT" ] || lock /var/lock/passwd
342         sed -i "s/$grp/$grp$delim$2/g" ${IPKG_INSTROOT}/etc/group
343         [ -n "$IPKG_INSTROOT" ] || lock -u /var/lock/passwd
344 }
345
346 user_add() {
347         local name="${1}"
348         local uid="${2}"
349         local gid="${3}"
350         local desc="${4:-$1}"
351         local home="${5:-/var/run/$1}"
352         local shell="${6:-/bin/false}"
353         local rc
354         [ -z "$uid" ] && {
355                 uids=$(cut -d: -f3 ${IPKG_INSTROOT}/etc/passwd)
356                 uid=65536
357                 while [ -n "$(echo "$uids" | grep "^$uid$")" ] ; do
358                         uid=$((uid + 1))
359                 done
360         }
361         [ -z "$gid" ] && gid=$uid
362         [ -f "${IPKG_INSTROOT}/etc/passwd" ] || return 1
363         [ -n "$IPKG_INSTROOT" ] || lock /var/lock/passwd
364         echo "${name}:x:${uid}:${gid}:${desc}:${home}:${shell}" >> ${IPKG_INSTROOT}/etc/passwd
365         echo "${name}:x:0:0:99999:7:::" >> ${IPKG_INSTROOT}/etc/shadow
366         [ -n "$IPKG_INSTROOT" ] || lock -u /var/lock/passwd
367 }
368
369 user_exists() {
370         grep -qs "^${1}:" ${IPKG_INSTROOT}/etc/passwd
371 }
372
373 board_name() {
374         [ -e /tmp/sysinfo/board_name ] && cat /tmp/sysinfo/board_name || echo "generic"
375 }
376
377 [ -z "$IPKG_INSTROOT" -a -f /lib/config/uci.sh ] && . /lib/config/uci.sh