Handle the case when links like /dev/root are returned
[kboot-utils.git] / kboot-mkconfig_lib
1 # kboot-mkconfig helper script.
2 # Copyright (C) 2011  Antonio Ospite <ospite@studenti.unina.it>
3 #
4 # Inspired by the 10_linux script from kboot
5 #
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
10 #
11 # This progra, is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this software.  If not, see <http://www.gnu.org/licenses/>.
18
19 prefix=/usr
20 exec_prefix=${prefix}
21 bindir=${exec_prefix}/bin
22 libdir=${exec_prefix}/lib
23
24 LINUX_ROOT_DEVICE="$(readlink -f $(mount | grep ' / ' | cut -d ' ' -f 1))"
25
26 if $(which gettext >/dev/null 2>/dev/null) ; then
27   gettext="gettext"
28 else
29   gettext="echo"
30 fi
31
32 # One layer of quotation is eaten by "", the second by sed, and the third by
33 # printf; so this turns ' into \'.  Note that you must use the output of
34 # this function in a printf format string.
35 gettext_quoted () {
36   $gettext "$@" | sed "s/'/'\\\\\\\\''/g"
37 }
38
39 # Run the first argument through gettext_quoted, and then pass that and all
40 # remaining arguments to printf.  This is a useful abbreviation and tends to
41 # be easier to type.
42 gettext_printf () {
43   local format="$1"
44   shift
45   printf "$(gettext_quoted "$format")" "$@"
46 }
47
48 kboot_file_is_not_garbage ()
49 {
50   if test -f "$1" ; then
51     case "$1" in
52       *.dpkg-*) return 1 ;; # debian dpkg
53       README*)  return 1 ;; # documentation
54     esac
55   else
56     return 1
57   fi
58   return 0
59 }
60
61 version_test_gt ()
62 {
63   local sedexp="s/[^-]*-//;s/[._-]\(pre\|rc\|test\|git\|old\|trunk\)/~\1/g"
64   local a=`echo $1 | sed -e "$sedexp"`
65   local b=`echo $2 | sed -e "$sedexp"`
66   local cmp=gt
67   if [ "x$b" = "x" ] ; then
68     return 0
69   fi
70   case $a:$b in
71     *.old:*.old) ;;
72     *.old:*) a=`echo -n $a | sed -e s/\.old$//` ; cmp=gt ;;
73     *:*.old) b=`echo -n $b | sed -e s/\.old$//` ; cmp=ge ;;
74   esac
75   dpkg --compare-versions "$a" $cmp "$b"
76   return $?
77 }
78
79 version_find_latest ()
80 {
81   local a=""
82   for i in $@ ; do
83     if version_test_gt "$i" "$a" ; then
84       a="$i"
85     fi
86   done
87   echo "$a"
88 }
89
90 linux_entry ()
91 {
92   os="$1"
93   version="$2"
94   recovery="$3"
95   args="$4"
96   if ${recovery} ; then
97     title="$(gettext_quoted "%s, with Linux %s (recovery mode)")"
98   else
99     title="$(gettext_quoted "%s, with Linux %s")"
100   fi
101   label="$(printf "${title}" "${os}" "${version}")"
102   echo -n "'${label}'='${dirname}/${basename} "
103   if test -n "${initrd}" ; then
104         echo -n "initrd=${dirname}/${initrd}"
105   fi
106   echo " root=${linux_root_device_thisversion} ro ${args}'"
107 }
108
109 list_kernels ()
110 {
111   list=`for i in /boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* ; do
112           if kboot_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
113         done`
114   prepare_boot_cache=
115
116   while [ "x$list" != "x" ] ; do
117     linux=`version_find_latest $list`
118     echo "Found linux image: $linux" >&2
119     basename=`basename $linux`
120     dirname=`dirname $linux`
121     
122     # XXX: this relies on a binary shipped by GRUB, we just use ${dirname} for 
123     # now, check the ${dirname} entries if we need something like that later
124     #rel_dirname=`make_system_path_relative_to_its_root $dirname`
125     
126     version=`echo $basename | sed -e "s,^[^0-9]*-,,g"`
127     alt_version=`echo $version | sed -e "s,\.old$,,g"`
128     linux_root_device_thisversion="${LINUX_ROOT_DEVICE}"
129
130     initrd=
131     for i in "initrd.img-${version}" "initrd-${version}.img" \
132              "initrd-${version}" "initramfs-${version}.img" \
133              "initrd.img-${alt_version}" "initrd-${alt_version}.img" \
134              "initrd-${alt_version}" "initramfs-${alt_version}.img"; do
135       if test -e "${dirname}/${i}" ; then
136         initrd="$i"
137         break
138       fi
139     done
140
141     initramfs=
142     for i in "config-${version}" "config-${alt_version}"; do
143       if test -e "${dirname}/${i}" ; then
144         initramfs=`grep CONFIG_INITRAMFS_SOURCE= "${dirname}/${i}" | cut -f2 -d= | tr -d \"`
145         break
146       fi
147     done
148
149     if test -n "${initrd}" ; then
150       echo "Found initrd image: ${dirname}/${initrd}" >&2
151     elif test -z "${initramfs}" ; then
152       # "UUID=" magic is parsed by initrd or initramfs.  Since there's
153       # no initrd or builtin initramfs, it can't work here.
154       linux_root_device_thisversion=${KBOOT_DEVICE}
155     fi
156
157     linux_entry "${OS}" "${version}" false \
158         "${KBOOT_CMDLINE_LINUX} ${KBOOT_CMDLINE_LINUX_DEFAULT}"
159     if [ "x${KBOOT_DISABLE_RECOVERY}" != "xtrue" ]; then
160       linux_entry "${OS}" "${version}" true \
161           "single ${KBOOT_CMDLINE_LINUX}"
162     fi
163
164     list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '`
165   done
166 }