Proper sorting of linux images requires more sophisticated logic than the
sort command can provide.  For example, we need to assert that foo.old is
older than foo, but foo.bar is newer, etc.

This brought me to implementing an inefficient (but simple) sorting algorithm
for 10_linux.in.  Seems to work for our (Debian's) needs.  Do you have any
comments or suggestions?

-- 
Robert Millan

My spam trap is [EMAIL PROTECTED]  Note: this address is only intended
for spam harvesters.  Writing to it will get you added to my black list.
diff -ur grub2-1.95+20070507.old/util/grub.d/10_linux.in grub2-1.95+20070507/util/grub.d/10_linux.in
--- grub2-1.95+20070507.old/util/grub.d/10_linux.in	2007-05-05 12:34:05.000000000 +0200
+++ grub2-1.95+20070507/util/grub.d/10_linux.in	2007-05-09 17:22:36.000000000 +0200
@@ -23,12 +23,67 @@
   OS="${GRUB_DISTRIBUTOR} GNU/Linux"
 fi
 
+test_numeric ()
+{
+  a=$1
+  cmp=$2
+  b=$3
+  if [ "$a" = "$b" ] ; then
+    case $cmp in
+      ge|eq|le) return 0 ;;
+      gt|lt) return 1 ;;
+    esac
+  fi
+  if [ "$cmp" = "lt" ] ; then
+    c=$a
+    a=$b
+    b=$c
+  fi
+  if (echo $a ; echo $b) | sort -n | head -n 1 | grep -qx $b ; then
+    return 0
+  else
+    return 1
+  fi
+}
+
+test_gt ()
+{
+  a=$1
+  b=$2
+  cmp=gt
+  if [ "x$b" = "x" ] ; then
+    return 0
+  fi
+  case $a:$b in
+    *.old:*.old) ;;
+    *.old:*) a=`echo -n $a | sed -e s/\.old$//g` ; cmp=gt ;;
+    *:*.old) b=`echo -n $b | sed -e s/\.old$//g` ; cmp=ge ;;
+  esac
+  (set -e ; test_numeric $a $cmp $b)
+  return $?
+}
+
+find_latest ()
+{
+  a=""
+  for i in $@ ; do
+    if (set -e ; test_gt "$i" "$a") ; then
+      a="$i"
+    fi
+  done
+  echo "$a"
+}
+
+list=`for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* ; do
+        if test -e $i ; then echo -n "$i " ; fi
+      done`
 
-for linux in /boot/vmlinu[xz]-* /vmlinu[xz]-* ; do
+while [ "x$list" != "x" ] ; do
+  linux=`find_latest $list`
   if test -e ${linux} ; then : ; else
     continue
   fi
-  echo "Found linux image:  $linux" >&2
+  echo "Found linux image: $linux" >&2
   version=`echo $linux | sed -e "s,.*/[^0-9]*-,,g"`
   basedir=`echo $linux | sed -e "s,/[^/]*$,,g"`
   cat << EOF
@@ -56,4 +111,5 @@
   cat << EOF
 }
 EOF
+  list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '`
 done

Reply via email to