60b31caddeb42b5db338897dc18acdc156dd2c22
[grub.git] / util / grub-mkconfig_lib.in
1 # Helper library for grub-mkconfig
2 # Copyright (C) 2007,2008,2009,2010  Free Software Foundation, Inc.
3 #
4 # GRUB is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # GRUB is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
16
17 prefix="@prefix@"
18 exec_prefix="@exec_prefix@"
19 datarootdir="@datarootdir@"
20 datadir="@datadir@"
21 bindir="@bindir@"
22 sbindir="@sbindir@"
23 if [ "x$pkgdatadir" = x ]; then
24     pkgdatadir="${datadir}/@PACKAGE@"
25 fi
26
27 if test "x$grub_probe" = x; then
28   grub_probe="${sbindir}/@grub_probe@"
29 fi
30 if test "x$grub_file" = x; then
31   grub_file="${bindir}/@grub_file@"
32 fi
33 if test "x$grub_mkrelpath" = x; then
34   grub_mkrelpath="${bindir}/@grub_mkrelpath@"
35 fi
36
37 if which gettext >/dev/null 2>/dev/null; then
38   :
39 else
40   gettext () {
41      printf "%s" "$@"
42   }
43 fi
44
45 grub_warn ()
46 {
47   echo "$(gettext "Warning:")" "$@" >&2
48 }
49
50 make_system_path_relative_to_its_root ()
51 {
52   "${grub_mkrelpath}" "$1"
53 }
54
55 is_path_readable_by_grub ()
56 {
57   path="$1"
58
59   # abort if path doesn't exist
60   if test -e "$path" ; then : ;else
61     return 1
62   fi
63
64   # abort if file is in a filesystem we can't read
65   if "${grub_probe}" -t fs "$path" > /dev/null 2>&1 ; then : ; else
66     return 1
67   fi
68
69   # ... or if we can't figure out the abstraction module, for example if
70   # memberlist fails on an LVM volume group.
71   if abstractions="`"${grub_probe}" -t abstraction "$path"`" 2> /dev/null ; then 
72       :
73   else
74     return 1
75   fi
76
77   if [ x$GRUB_ENABLE_CRYPTODISK = xy ]; then
78       return 0
79   fi
80   
81   for abstraction in $abstractions; do
82       if [ "x$abstraction" = xcryptodisk ]; then
83           return 1
84       fi
85   done
86
87   return 0
88 }
89
90 convert_system_path_to_grub_path ()
91 {
92   path="$1"
93
94   grub_warn "convert_system_path_to_grub_path() is deprecated.  Use prepare_grub_to_access_device() instead."
95
96   # abort if GRUB can't access the path
97   if is_path_readable_by_grub "${path}" ; then : ; else
98     return 1
99   fi
100
101   if drive="`"${grub_probe}" -t drive "$path"`" ; then : ; else
102     return 1
103   fi
104
105   if relative_path="`make_system_path_relative_to_its_root "$path"`" ; then : ; else
106     return 1
107   fi
108
109   echo "${drive}${relative_path}"
110 }
111
112 save_default_entry ()
113 {
114   if [ "x${GRUB_SAVEDEFAULT}" = "xtrue" ] ; then
115     cat << EOF
116 savedefault
117 EOF
118   fi
119 }
120
121 prepare_grub_to_access_device ()
122 {
123   old_ifs="$IFS"
124   IFS='
125 '
126   partmap="`"${grub_probe}" --device $@ --target=partmap`"
127   for module in ${partmap} ; do
128     case "${module}" in
129       netbsd | openbsd)
130         echo "insmod part_bsd";;
131       *)
132         echo "insmod part_${module}";;
133     esac
134   done
135
136   # Abstraction modules aren't auto-loaded.
137   abstraction="`"${grub_probe}" --device $@ --target=abstraction`"
138   for module in ${abstraction} ; do
139     echo "insmod ${module}"
140   done
141
142   fs="`"${grub_probe}" --device $@ --target=fs`"
143   for module in ${fs} ; do
144     echo "insmod ${module}"
145   done
146
147   if [ x$GRUB_ENABLE_CRYPTODISK = xy ]; then
148       for uuid in `"${grub_probe}" --device $@ --target=cryptodisk_uuid`; do
149           echo "cryptomount -u $uuid"
150       done
151   fi
152
153   # If there's a filesystem UUID that GRUB is capable of identifying, use it;
154   # otherwise set root as per value in device.map.
155   fs_hint="`"${grub_probe}" --device $@ --target=compatibility_hint`"
156   if [ "x$fs_hint" != x ]; then
157     echo "set root='$fs_hint'"
158   fi
159   if fs_uuid="`"${grub_probe}" --device $@ --target=fs_uuid 2> /dev/null`" ; then
160     hints="`"${grub_probe}" --device $@ --target=hints_string 2> /dev/null`" || hints=
161     echo "if [ x\$feature_platform_search_hint = xy ]; then"
162     echo "  search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}"
163     echo "else"
164     echo "  search --no-floppy --fs-uuid --set=root ${fs_uuid}"
165     echo "fi"
166   fi
167   IFS="$old_ifs"
168 }
169
170 grub_get_device_id ()
171 {
172   old_ifs="$IFS"
173   IFS='
174 '
175   device="$1"
176   if fs_uuid="`"${grub_probe}" --device ${device} --target=fs_uuid 2> /dev/null`" ; then
177     echo "$fs_uuid";
178   else
179     echo $device |sed 's, ,_,g'
180   fi
181   IFS="$old_ifs"
182 }
183
184 grub_file_is_not_garbage ()
185 {
186   if test -f "$1" ; then
187     case "$1" in
188       *.dpkg-*) return 1 ;; # debian dpkg
189       *.rpmsave|*.rpmnew) return 1 ;;
190       README*|*/README*)  return 1 ;; # documentation
191     esac
192   else
193     return 1
194   fi
195   return 0
196 }
197
198 version_sort ()
199 {
200   case $version_sort_sort_has_v in
201     yes)
202       LC_ALL=C sort -V;;
203     no)
204       LC_ALL=C sort -n;;
205     *)
206       if sort -V </dev/null > /dev/null 2>&1; then
207         version_sort_sort_has_v=yes
208         LC_ALL=C sort -V
209       else
210         version_sort_sort_has_v=no
211         LC_ALL=C sort -n
212       fi;;
213    esac
214 }
215
216 version_test_numeric ()
217 {
218   version_test_numeric_a="$1"
219   version_test_numeric_cmp="$2"
220   version_test_numeric_b="$3"
221   if [ "$version_test_numeric_a" = "$version_test_numeric_b" ] ; then
222     case "$version_test_numeric_cmp" in
223       ge|eq|le) return 0 ;;
224       gt|lt) return 1 ;;
225     esac
226   fi
227   if [ "$version_test_numeric_cmp" = "lt" ] ; then
228     version_test_numeric_c="$version_test_numeric_a"
229     version_test_numeric_a="$version_test_numeric_b"
230     version_test_numeric_b="$version_test_numeric_c"
231   fi
232   if (echo "$version_test_numeric_a" ; echo "$version_test_numeric_b") | version_sort | head -n 1 | grep -qx "$version_test_numeric_b" ; then
233     return 0
234   else
235     return 1
236   fi
237 }
238
239 version_test_gt ()
240 {
241   version_test_gt_a="`echo "$1" | sed -e "s/[^-]*-//"`"
242   version_test_gt_b="`echo "$2" | sed -e "s/[^-]*-//"`"
243   version_test_gt_cmp=gt
244   if [ "x$version_test_gt_b" = "x" ] ; then
245     return 0
246   fi
247   case "$version_test_gt_a:$version_test_gt_b" in
248     *.old:*.old) ;;
249     *.old:*) version_test_gt_a="`echo "$version_test_gt_a" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=gt ;;
250     *:*.old) version_test_gt_b="`echo "$version_test_gt_b" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=ge ;;
251   esac
252   version_test_numeric "$version_test_gt_a" "$version_test_gt_cmp" "$version_test_gt_b"
253   return "$?"
254 }
255
256 version_find_latest ()
257 {
258   version_find_latest_a=""
259   for i in "$@" ; do
260     if version_test_gt "$i" "$version_find_latest_a" ; then
261       version_find_latest_a="$i"
262     fi
263   done
264   echo "$version_find_latest_a"
265 }
266
267 # One layer of quotation is eaten by "" and the second by sed; so this turns
268 # ' into \'.
269 grub_quote () {
270   sed "s/'/'\\\\''/g"
271 }
272
273 gettext_quoted () {
274   gettext "$@" | grub_quote
275 }
276
277 # Run the first argument through gettext, and then pass that and all
278 # remaining arguments to printf.  This is a useful abbreviation and tends to
279 # be easier to type.
280 gettext_printf () {
281   gettext_printf_format="$1"
282   shift
283   printf "$(gettext "$gettext_printf_format")" "$@"
284 }
285
286 uses_abstraction () {
287   device="$1"
288   old_ifs="$IFS"
289   IFS='
290 '
291
292   abstraction="`"${grub_probe}" --device ${device} --target=abstraction`"
293   for module in ${abstraction}; do
294     if test "x${module}" = "x$2"; then
295       IFS="$old_ifs"
296       return 0
297     fi
298   done
299   IFS="$old_ifs"
300   return 1
301 }
302
303 print_option_help () {
304   if test x$print_option_help_wc = x; then
305       if wc -L  </dev/null > /dev/null 2>&1; then
306           print_option_help_wc=-L
307       elif wc -m  </dev/null > /dev/null 2>&1; then
308           print_option_help_wc=-m
309       else
310           print_option_help_wc=-b
311       fi
312   fi
313   if test x$grub_have_fmt = x; then
314       if fmt -w 40  </dev/null > /dev/null 2>&1; then
315           grub_have_fmt=y;
316       else
317           grub_have_fmt=n;
318       fi
319   fi
320   print_option_help_lead="  $1"
321   print_option_help_lspace="$(echo "$print_option_help_lead" | wc $print_option_help_wc)"
322   print_option_help_fill="$((26 - print_option_help_lspace))"
323   printf "%s" "$print_option_help_lead"
324   if test $print_option_help_fill -le 0; then
325       print_option_help_nl=y
326       echo
327   else
328       print_option_help_i=0;
329       while test $print_option_help_i -lt $print_option_help_fill; do
330       printf " "
331           print_option_help_i=$((print_option_help_i+1))
332       done
333       print_option_help_nl=n
334   fi
335   if test x$grub_have_fmt = xy; then
336       print_option_help_split="$(echo "$2" | fmt -w 50)"
337   else
338       print_option_help_split="$2"
339   fi
340   if test x$print_option_help_nl = xy; then
341       echo "$print_option_help_split" | awk \
342           '{ print "                          " $0; }'
343   else
344       echo "$print_option_help_split" | awk 'BEGIN   { n = 0 }
345   { if (n == 1) print "                          " $0; else print $0; n = 1 ; }'
346   fi
347 }
348
349 grub_fmt () {
350   if test x$grub_have_fmt = x; then
351       if fmt -w 40 < /dev/null > /dev/null; then
352           grub_have_fmt=y;
353       else
354           grub_have_fmt=n;
355       fi
356   fi
357
358   if test x$grub_have_fmt = xy; then
359       fmt
360   else
361       cat
362   fi
363 }
364
365 grub_tab="      "
366
367 grub_add_tab () {
368   sed -e "s/^/$grub_tab/"
369 }
370