]> pilppa.org Git - familiar-h63xx-build.git/blob - org.handhelds.familiar/packages/openslug-init/openslug-init-0.10/functions
OE tree imported from monotone branch org.openembedded.oz354fam083 at revision 8b12e3...
[familiar-h63xx-build.git] / org.handhelds.familiar / packages / openslug-init / openslug-init-0.10 / functions
1 # . this file to load the following utility functions
2 #
3 # mtdev "name"
4 #  return (output) the character device name for flash parition "name"
5 #  /proc/mtd has the general form:
6 #    dev:    size   erasesize  name
7 #    mtd5: 00020000 00020000 "FIS directory"
8 #  use this rather than hard-wiring the device because the partition
9 #  table can change - looking in /proc/mtd is more reliable.
10 mtdev(){
11         sed -n 's!^\(mtd[0-9][0-9]*\):[^"]*"'"$1"'"$!/dev/\1!p' /proc/mtd
12 }
13 #
14 # mtblockdev "name"
15 #  as mtdev but output the name of the block (not character) device
16 mtblockdev(){
17         sed -n 's!^mtd\([0-9][0-9]*\):[^"]*"'"$1"'"$!/dev/mtdblock\1!p' /proc/mtd
18 }
19 #
20 # mtsize "name"
21 #  the size of the partition as a hexadecimal value (with 0x at the front)
22 mtsize(){
23         sed -n 's!^mtd[0-9][0-9]*: \([^ ]*\)[^"]*"'"$1"'"$!0x\1!p' /proc/mtd
24 }
25 #
26 # sysvalmatch "section" "name" 'pattern' "configuration file"
27 # sysvalof "section" "name" "configuration file"
28 # sysval "section" "name"
29 #  outputs the value of the SysConf variable 'name' from section 'section',
30 #  this is a bit gross, when it gets a match it copies the value to the
31 #  hold space, if no match it jumps over the copy, at the end ($) it copies
32 #  the hold space to the pattern space and prints the result, thus it only
33 #  ever prints the last match
34 # BUG FIX: busybox sed doesn't initialise the hold space and crashes if it
35 #  is used before initialisation, so temporarily this script does it's own
36 #  tail by hand.
37 # NOTE: these functions should only be used internally, add entries to 'config'
38 #  below if necessary.  This is because 'config' does the defaulting and in the
39 #  recovering case (zero or absent SysConf) /etc/default/sysconf only contains
40 #  the hw_addr entry!
41 sysvalmatch(){
42         # sed -n '/^\['"$1"'\]$/,/^\[.*\]$/s/^'"$2"'=\('"$3"'\)$/\1/;tH;bE;:H;h;:E;$g;$p' "$4"
43         sed -n '/^\['"$1"'\]$/,/^\[.*\]$/s/^'"$2"'=\('"$3"'\)$/\1/p' "$4" | sed -n '$p'
44 }
45 sysvalof(){
46         sysvalmatch "$1" "$2" '.*' "$3"
47 }
48 sysval(){
49         sysvalof "$1" "$2" /etc/default/sysconf
50 }
51 #
52 # config "value"
53 #  convenience callers for specific values to avoid mis-typing in scripts
54 #  NOTE: this function does the defaulting, 'sysval' does not!  Validity
55 #  of the sysconf file is determined by the presence of the all important
56 #  hw_addr.
57 config(){
58         local mac
59         mac=
60         test -r /etc/default/sysconf &&
61                 mac="$(sysvalmatch network hw_addr '[0-9A-Za-z][0-9A-Za-z]:[0-9A-Za-z][0-9A-Za-z]:[0-9A-Za-z][0-9A-Za-z]:[0-9A-Za-z][0-9A-Za-z]:[0-9A-Za-z][0-9A-Za-z]:[0-9A-Za-z][0-9A-Za-z]' /etc/default/sysconf)"
62         if test -n "$mac"
63         then
64                 case "$1" in
65                 mac)    echo "$mac";;
66                 host)   if test -n "$(sysval network disk_server_name)"
67                         then
68                                 sysval network disk_server_name
69                         elif test -n "$(sysval network default_server_name)"
70                         then
71                                 sysval network default_server_name
72                         else
73                                 echo "$mac" | sed -n 's/^..:..:..:\(..\):\(..\):\(..\)$/LKG\1\2\3/p'
74                         fi;;
75                 domain) sysval network w_d_name;;
76                 iface)  if test -n "$(sysval network lan_interface)"
77                         then
78                                 sysval network lan_interface
79                         else
80                                 echo eth0
81                         fi;;
82                 ip)     if test -n "$(sysval network ip_addr)"
83                         then
84                                 sysval network ip_addr
85                         else
86                                 echo 192.168.1.77
87                         fi;;
88                 netmask)sysval network netmask;;
89                 gateway)sysval network gateway;;
90                 dns)    sysval network dns_server1;;
91                 dns2)   sysval network dns_server2;;
92                 dns3)   sysval network dns_server3;;
93                 boot)   if test -n "$(sysval network bootproto)"
94                         then
95                                 sysval network bootproto
96                         else
97                                 echo dhcp
98                         fi;;
99                 valid)  return 0;;
100                 *)      return 1;;
101                 esac
102         else
103                 # These are the defaults for an invalid mac address, use the compiled
104                 # in hardware address.
105                 case "$1" in
106                 mac)    echo "00:02:B3:02:02:01";;
107                 host)   echo "brokenslug";;
108                 iface)  echo eth0;;
109                 ip)     echo 192.168.1.77;;
110                 boot)   echo dhcp;;
111                 *)      return 1;;
112                 esac
113         fi
114 }
115 #
116 # checkif "iface"
117 #  Validate an interface name by making sure that it exists
118 #  in /proc/net/dev (and is not lo).  The listing outputs the
119 #  interface followed by a :, the check function looks for
120 #  something of the form '$1[a-zA-Z0-9]*:' and outputs the
121 #  part preceding the ':'
122 checkif(){
123         sed -n '/^[     ]*lo:/d;s/^[    ]*\('"$1"'[a-zA-Z0-9]*\):.*$/\1/p;tE;d;:E;q' /proc/net/dev
124 }
125 #
126 # checkmount "mountpoint"
127 #  tests an already mounted mountpoint to see whether to attempt to
128 #  boot with this as root.  Returns success if it appears ok.
129 checkmount(){
130         # basic test for init (the kernel will try to load this)
131         # but require a shell in bin/sh and no .recovery too
132         test    \( ! -f "$1/.recovery" \) -a \
133                 \( -d "$1/initrd" -o -d "$1/mnt" \) -a \
134                 \( -x "$1/bin/sh" -o -h "$1/bin/sh" \) -a \
135                 \( -x "$1/sbin/init" -o -h "$1/sbin/init" -o \
136                 -x "$1/etc/init" -o -h "$1/etc/init" -o \
137                 -x "$1/bin/init" -o -h "$1/bin/init" \)
138 }
139 #
140 # swivel "new root" "old root"
141 #  NOTE: the arguments must be paths relative to /, bad things
142 #  will happen if the arguments themselves start with /
143 #  Pivot to a new root.  This does all the fancy pivot_root stuff
144 #  including closing streams and does a umount /proc - it doesn't
145 #  matter if this fails (failure codes are ignored), but if /proc
146 #  was mounted it must be restored by the caller on return.
147 #  Normally this function never returns!
148 #  On return 0,1,2 are connected to /dev/console - this may not
149 #  have been true before!
150 swivel() {
151         cd "$1"
152         exec <&- >&- 2>&-
153         # This is just-in-case the called mounted /proc and was
154         # unable to close it because of the streams
155         umount /proc 2>/dev/null
156         if pivot_root . "$2"
157         then
158                 # everything must move out of the old root, this process
159                 # is $2/bin/sh so it must die, IO is redirected
160                 # just in case - typically it will be to a device so it
161                 # won't hold the old root open.
162                 # the exec here is the first point at which the old root
163                 # is unused - before the exec regardless of the close of
164                 # 0,1,2 above ash still has *this* shell script open!
165                 # (it's on fd 10).
166                 # init closes all file descriptors, there's no point
167                 # supplying it with fds.
168                 # NOTE: this used to use $2/usr/sbin/chroot, however on
169                 # linux / is already . when the command is executed
170                 # therefore it is essential to use the local (new root)
171                 # chroot to ensure it gets the correct shared libraries.
172                 exec usr/sbin/chroot . bin/sh -c "\
173                         test -x sbin/init && exec sbin/init
174                         test -x etc/init && exec etc/init
175                         test -x bin/init && exec bin/init
176                         leds -A +gr1 '!g1'
177                         sleep 10 >/.recovery
178                         sync;sync;sync
179                         exit 1"
180         fi
181         #
182         # recovery - must restore the old root
183         cd "$2"
184         sbin/pivot_root . "$1"
185         # cd is back to $1 - either pivot_root doesn't change it and the
186         # chroot above was not executed, or pivot_root does change it and
187         # has just changed it back!
188         exec <>/dev/console >&0 2>&0
189 }
190 #
191 # ifup "interface"
192 #  bring that interface up with the configured ip and other
193 #  information
194 ifup(){
195         local ip hostname router subnet iface HOSTNAME NETMASK BROADCAST
196
197         iface="$1"
198         ip="$(config ip)"
199         hostname="$(config host)"
200         router="$(config gateway)"
201         broadcast=
202
203         if test -n "$ip"
204         then
205                 # only if an ip was specified
206                 subnet="$(config netmask)"
207         else
208                 ip=192.168.1.77
209         fi
210
211         # First try udhcpc - note that the /boot/udhcpc.script
212         # simply records the values returned and the udhcpc
213         # is not left running so this will only work for
214         # the lease length time!
215         ifconfig "$iface" up
216         if test "$(config boot)" != static
217         then
218                 test -n "$hostname" && HOSTNAME="-H $hostname"
219                 # The script writes the required shell variable assignments
220                 # to file descriptor 9
221                 eval $(udhcpc -i "$iface" -n -q -r "$ip" $HOSTNAME -s /boot/udhcpc.script 9>&1 >/dev/null)
222         fi
223
224         test -n "$broadcast" && BROADCAST="broadcast $broadcast"
225         test -n "$subnet" && NETMASK="netmask $subnet"
226
227         if ifconfig "$iface" "$ip" $NETMASK $BROADCAST
228         then
229                 for route in $router
230                 do
231                         route add default gw "$route" dev "$iface"
232                 done
233                 return 0
234         else
235                 ifconfig "$iface" down
236                 return 1
237         fi
238 }
239 #
240 # ifdown "interface"
241 #  take the interface down
242 ifdown(){
243         ifconfig "$1" down
244 }
245 #
246 # mountflash "flash device" "flash root directory" {mount options}
247 #  Finds and mounts the flash file system on the given directory
248 mountflash() {
249         local ffsdev ffsdir
250
251         ffsdev="$1"
252         test -n "$ffsdev" -a -b "$ffsdev" || {
253                 echo "$0: unable to find flash file system to copy ($ffsdev)" >&2
254                 return 1
255         }
256         shift
257
258         ffsdir="$1"
259         test -n "$ffsdir" -a -d "$ffsdir" || {
260                 echo "$0: mountflash $ffsdir: not a directory (internal error)" >&2
261                 return 1
262         }
263         shift
264
265         mount -t jffs2 "$@" "$ffsdev" "$ffsdir" || {
266                 echo "$0: $ffsdev: unable to mount flash file system on $ffsdir" >&2
267                 return 1
268         }
269         return 0
270 }
271 #
272 # umountflash [-r] "flash device"
273 #  unmount any instance of the given flash device, if -r is specified a mount on
274 #  root is an error, otherwise a mount on root is ignored (and remains).
275 umountflash() {
276         local rootok ffsno ffsdev
277         rootok=1
278         case "$1" in
279         -r)     rootok=
280                 shift;;
281         esac
282         #
283         # The argument is ffsdev
284         ffsdev="$1"
285         ffsno="$(devio "<<$ffsdev" prd)"
286         test -n "$ffsno" -a "$ffsno" -ge 0 || {
287                 echo "$0: $ffsdev: device number $ffsno is not valid, cannot continue." >&2
288                 return 1
289         }
290         #
291         # Make sure that Flashdisk isn't mounted on /
292         if test -z "$rootok" -a "$(devio "<</etc/init.d/sysconfsetup" prd)" -eq "$ffsno"
293         then
294                 echo "$0: $ffsdev is mounted on /, use turnup ram" >&2
295                 return 1
296         fi
297         #
298         # The function is currently always used interactively, so output 
299         echo "$0: umounting any existing mount of $ffsdev" >&2
300         #
301         # check each mount point, do this last first because otherwise nested
302         # mounts of ffsdev cannot be umounted.
303         ffs_umount() {
304                 local device mp type options stuff
305
306                 read device mp type options stuff
307                 test -z "$device" && return 0
308
309                 # handle following entries first
310                 ffs_umount || return 1
311
312                 # handle this entry, since this is currently only used for unmounting
313                 # the flash root partition we know a file which must exist...
314                 case "$mp/$type" in
315                 //jffs2);; # skip /
316                 */jffs2)test "$(devio "<<$mp/etc/init.d/sysconfsetup" prd 2>/dev/null)" -ne "$ffsno" ||
317                         umount "$mp" || {
318                                 echo "$0: $mp: unable to umount $ffsdev" >&2
319                                 return 1
320                         };;
321                 esac
322
323                 return 0
324         }
325         #
326         ffs_umount </proc/mounts || {
327                 echo "$0: umount $ffsdev from all mount points then re-run reflash" >&2
328                 return 1
329         }
330
331         return 0
332 }