grub-mkconfig_lib.in 9.53 KB
Newer Older
1
# Helper library for grub-mkconfig
2
# Copyright (C) 2007,2008,2009,2010  Free Software Foundation, Inc.
3 4 5 6 7 8 9 10 11 12 13 14 15 16
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB.  If not, see <http://www.gnu.org/licenses/>.

17 18 19 20 21 22
prefix="@prefix@"
exec_prefix="@exec_prefix@"
datarootdir="@datarootdir@"
datadir="@datadir@"
bindir="@bindir@"
sbindir="@sbindir@"
23 24 25
if [ "x$pkgdatadir" = x ]; then
    pkgdatadir="${datadir}/@PACKAGE@"
fi
26

27
if test "x$grub_probe" = x; then
28
  grub_probe="${sbindir}/@grub_probe@"
29
fi
30 31 32
if test "x$grub_file" = x; then
  grub_file="${bindir}/@grub_file@"
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 44
fi

45 46
grub_warn ()
{
47
  echo "$(gettext "Warning:")" "$@" >&2
48 49
}

50 51
make_system_path_relative_to_its_root ()
{
52
  "${grub_mkrelpath}" "$1"
53 54 55 56
}

is_path_readable_by_grub ()
{
57
  path="$1"
58 59

  # abort if path doesn't exist
60
  if test -e "$path" ; then : ;else
61 62 63
    return 1
  fi

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 67 68
    return 1
  fi

69 70
  # ... or if we can't figure out the abstraction module, for example if
  # memberlist fails on an LVM volume group.
71
  if abstractions="`"${grub_probe}" -t abstraction "$path"`" 2> /dev/null ; then 
72 73
      :
  else
74 75 76
    return 1
  fi

77
  if [ x$GRUB_ENABLE_CRYPTODISK = xy ]; then
78 79 80 81
      return 0
  fi
  
  for abstraction in $abstractions; do
82
      if [ "x$abstraction" = xcryptodisk ]; then
83 84 85 86
	  return 1
      fi
  done

87 88 89 90 91
  return 0
}

convert_system_path_to_grub_path ()
{
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 99 100
    return 1
  fi

101
  if drive="`"${grub_probe}" -t drive "$path"`" ; then : ; else
102 103 104
    return 1
  fi

105
  if relative_path="`make_system_path_relative_to_its_root "$path"`" ; then : ; else
106 107 108
    return 1
  fi

109
  echo "${drive}${relative_path}"
110 111
}

112 113
save_default_entry ()
{
114
  if [ "x${GRUB_SAVEDEFAULT}" = "xtrue" ] ; then
115
    cat << EOF
116
savedefault
117
EOF
118 119 120
  fi
}

121 122
prepare_grub_to_access_device ()
{
123 124 125 126
  old_ifs="$IFS"
  IFS='
'
  partmap="`"${grub_probe}" --device $@ --target=partmap`"
127
  for module in ${partmap} ; do
128 129 130 131 132 133
    case "${module}" in
      netbsd | openbsd)
        echo "insmod part_bsd";;
      *)
        echo "insmod part_${module}";;
    esac
134 135
  done

136 137 138 139 140 141 142 143 144 145
  loop_file=
  case $1 in
    /dev/loop/*|/dev/loop[0-9])
      grub_loop_device="${1#/dev/}"
      loop_file=`losetup "$1" | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/"`
      case $loop_file in
        /dev/*) ;;
        *)
          loop_device="$1"
          shift
146
          set -- `"${grub_probe}" --target=device "${loop_file}"` "$@" || return 0
147 148 149 150 151
        ;;
      esac
    ;;
  esac

152
  # Abstraction modules aren't auto-loaded.
153
  abstraction="`"${grub_probe}" --device $@ --target=abstraction`"
154 155 156 157
  for module in ${abstraction} ; do
    echo "insmod ${module}"
  done

158
  fs="`"${grub_probe}" --device $@ --target=fs`"
159 160 161 162
  for module in ${fs} ; do
    echo "insmod ${module}"
  done

163
  if [ x$GRUB_ENABLE_CRYPTODISK = xy ]; then
164
      for uuid in `"${grub_probe}" --device $@ --target=cryptodisk_uuid`; do
165
	  echo "cryptomount -u $uuid"
166 167 168
      done
  fi

169 170
  # If there's a filesystem UUID that GRUB is capable of identifying, use it;
  # otherwise set root as per value in device.map.
171
  fs_hint="`"${grub_probe}" --device $@ --target=compatibility_hint`"
172 173 174
  if [ "x$fs_hint" != x ]; then
    echo "set root='$fs_hint'"
  fi
175 176
  if fs_uuid="`"${grub_probe}" --device $@ --target=fs_uuid 2> /dev/null`" ; then
    hints="`"${grub_probe}" --device $@ --target=hints_string 2> /dev/null`" || hints=
177
    echo "if [ x\$feature_platform_search_hint = xy ]; then"
178 179 180 181
    echo "  search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}"
    echo "else"
    echo "  search --no-floppy --fs-uuid --set=root ${fs_uuid}"
    echo "fi"
182
  fi
183
  IFS="$old_ifs"
184 185 186 187 188 189 190 191

  if [ "x${loop_file}" != x ]; then
    loop_mountpoint="$(awk '"'${loop_file}'" ~ "^"$2 && $2 != "/" { print $2 }' /proc/mounts | tail -n1)"
    if [ "x${loop_mountpoint}" != x ]; then
      echo "loopback ${grub_loop_device} ${loop_file#$loop_mountpoint}"
      echo "set root=(${grub_loop_device})"
    fi
  fi
192 193
}

194 195
grub_get_device_id ()
{
196 197 198
  old_ifs="$IFS"
  IFS='
'
199
  device="$1"
200
  if fs_uuid="`"${grub_probe}" --device ${device} --target=fs_uuid 2> /dev/null`" ; then
201 202
    echo "$fs_uuid";
  else
203
    echo $device |sed 's, ,_,g'
204
  fi
205
  IFS="$old_ifs"
206 207
}

208 209 210 211
grub_file_is_not_garbage ()
{
  if test -f "$1" ; then
    case "$1" in
212
      *.dpkg-*) return 1 ;; # debian dpkg
213
      *.rpmsave|*.rpmnew) return 1 ;;
214
      README*|*/README*)  return 1 ;; # documentation
215 216 217 218 219 220
    esac
  else
    return 1
  fi
  return 0
}
221

222 223 224 225 226 227 228 229
version_sort ()
{
  case $version_sort_sort_has_v in
    yes)
      LC_ALL=C sort -V;;
    no)
      LC_ALL=C sort -n;;
    *)
230
      if sort -V </dev/null > /dev/null 2>&1; then
231 232 233 234 235 236 237 238 239
        version_sort_sort_has_v=yes
	LC_ALL=C sort -V
      else
        version_sort_sort_has_v=no
        LC_ALL=C sort -n
      fi;;
   esac
}

240 241
version_test_numeric ()
{
242 243 244 245 246
  version_test_numeric_a="$1"
  version_test_numeric_cmp="$2"
  version_test_numeric_b="$3"
  if [ "$version_test_numeric_a" = "$version_test_numeric_b" ] ; then
    case "$version_test_numeric_cmp" in
247 248 249 250
      ge|eq|le) return 0 ;;
      gt|lt) return 1 ;;
    esac
  fi
251 252 253 254
  if [ "$version_test_numeric_cmp" = "lt" ] ; then
    version_test_numeric_c="$version_test_numeric_a"
    version_test_numeric_a="$version_test_numeric_b"
    version_test_numeric_b="$version_test_numeric_c"
255
  fi
256
  if (echo "$version_test_numeric_a" ; echo "$version_test_numeric_b") | version_sort | head -n 1 | grep -qx "$version_test_numeric_b" ; then
257 258 259 260 261 262 263 264
    return 0
  else
    return 1
  fi
}

version_test_gt ()
{
265 266 267
  version_test_gt_sedexp="s/[^-]*-//;s/[._-]\(pre\|rc\|test\|git\|old\|trunk\)/~\1/g"
  version_test_gt_a="`echo "$1" | sed -e "$version_test_gt_sedexp"`"
  version_test_gt_b="`echo "$2" | sed -e "$version_test_gt_sedexp"`"
268 269
  version_test_gt_cmp=gt
  if [ "x$version_test_gt_b" = "x" ] ; then
270 271
    return 0
  fi
272
  case "$version_test_gt_a:$version_test_gt_b" in
273
    *.old:*.old) ;;
274 275
    *.old:*) version_test_gt_a="`echo "$version_test_gt_a" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=gt ;;
    *:*.old) version_test_gt_b="`echo "$version_test_gt_b" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=ge ;;
276
  esac
277
  dpkg --compare-versions "$version_test_gt_a" "$version_test_gt_cmp" "$version_test_gt_b"
278
  return "$?"
279 280 281 282
}

version_find_latest ()
{
283
  version_find_latest_a=""
284
  for i in "$@" ; do
285 286
    if version_test_gt "$i" "$version_find_latest_a" ; then
      version_find_latest_a="$i"
287 288
    fi
  done
289
  echo "$version_find_latest_a"
290
}
291

292 293
# One layer of quotation is eaten by "" and the second by sed; so this turns
# ' into \'.
294
grub_quote () {
295
  sed "s/'/'\\\\''/g"
296 297
}

298
gettext_quoted () {
299
  gettext "$@" | grub_quote
300 301
}

302
# Run the first argument through gettext, and then pass that and all
303 304 305
# remaining arguments to printf.  This is a useful abbreviation and tends to
# be easier to type.
gettext_printf () {
306
  gettext_printf_format="$1"
307
  shift
308
  printf "$(gettext "$gettext_printf_format")" "$@"
309
}
310 311

uses_abstraction () {
312
  device="$1"
313 314 315
  old_ifs="$IFS"
  IFS='
'
316

317
  abstraction="`"${grub_probe}" --device ${device} --target=abstraction`"
318 319
  for module in ${abstraction}; do
    if test "x${module}" = "x$2"; then
320
      IFS="$old_ifs"
321 322 323
      return 0
    fi
  done
324
  IFS="$old_ifs"
325 326
  return 1
}
327 328 329

print_option_help () {
  if test x$print_option_help_wc = x; then
330
      if wc -L  </dev/null > /dev/null 2>&1; then
331
	  print_option_help_wc=-L
332
      elif wc -m  </dev/null > /dev/null 2>&1; then
333 334 335 336 337 338
	  print_option_help_wc=-m
      else
	  print_option_help_wc=-b
      fi
  fi
  if test x$grub_have_fmt = x; then
339
      if fmt -w 40  </dev/null > /dev/null 2>&1; then
340 341 342 343 344 345 346 347
	  grub_have_fmt=y;
      else
	  grub_have_fmt=n;
      fi
  fi
  print_option_help_lead="  $1"
  print_option_help_lspace="$(echo "$print_option_help_lead" | wc $print_option_help_wc)"
  print_option_help_fill="$((26 - print_option_help_lspace))"
348
  printf "%s" "$print_option_help_lead"
349 350 351 352 353 354
  if test $print_option_help_fill -le 0; then
      print_option_help_nl=y
      echo
  else
      print_option_help_i=0;
      while test $print_option_help_i -lt $print_option_help_fill; do
355
      printf " "
356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388
	  print_option_help_i=$((print_option_help_i+1))
      done
      print_option_help_nl=n
  fi
  if test x$grub_have_fmt = xy; then
      print_option_help_split="$(echo "$2" | fmt -w 50)"
  else
      print_option_help_split="$2"
  fi
  if test x$print_option_help_nl = xy; then
      echo "$print_option_help_split" | awk \
	  '{ print "                          " $0; }'
  else
      echo "$print_option_help_split" | awk 'BEGIN   { n = 0 }
  { if (n == 1) print "                          " $0; else print $0; n = 1 ; }'
  fi
}

grub_fmt () {
  if test x$grub_have_fmt = x; then
      if fmt -w 40 < /dev/null > /dev/null; then
	  grub_have_fmt=y;
      else
	  grub_have_fmt=n;
      fi
  fi

  if test x$grub_have_fmt = xy; then
      fmt
  else
      cat
  fi
}
389 390 391 392 393 394 395

grub_tab="	"

grub_add_tab () {
  sed -e "s/^/$grub_tab/"
}