Index: kdm/backend/bootman.c =================================================================== --- kdm/backend/bootman.c (revision 947666) +++ kdm/backend/bootman.c (working copy) @@ -69,6 +69,9 @@ } #define GRUB_MENU "/boot/grub/menu.lst" +#define GRUB_ONCE_PATCH_UNKNOWN 0 +#define GRUB_ONCE_PATCH_YES 1 +#define GRUB_ONCE_PATCH_NO 2 static char *grub; @@ -133,16 +136,54 @@ FILE *f; int pid; static const char *args[] = { 0, "--batch", "--no-floppy", 0 }; + static const char *env[] = { 0 }; + static int grubOncePatch = GRUB_ONCE_PATCH_UNKNOWN; + static char* grub_set_default = 0; + char rec[4]; if (sdRec.bmstamp != mTime( GRUB_MENU ) && setGrub( sdRec.osname, &sdRec ) != BO_OK) return; - args[0] = grub; - if ((f = pOpen( (char **)args, 'w', &pid ))) { - fprintf( f, "savedefault --default=%d --once\n", sdRec.osindex ); - pClose( f, &pid ); + /* + There are two ways to set the default entry for next boot. + + The grub shell can be used with `savedefault', however that + requires a (widely distributed) patch to grub, e.g. + grub-0.97-once.patch. This won't work with a vanilla grub. + + Alternatively the grub-set-default command can be used, which + is less good because there is no way of setting an entry for + the next boot only. + + The two methods are mutually exclusive; grub can only support + one. If the grub-set-default command exists then that is used, + otherwise the savedefault method is used. + */ + if (grubOncePatch == GRUB_ONCE_PATCH_UNKNOWN) { + if ((grub_set_default = locate( "grub-set-default" ))) { + grubOncePatch = GRUB_ONCE_PATCH_NO; + } + else { + grubOncePatch = GRUB_ONCE_PATCH_YES; + } } + + if (grubOncePatch == GRUB_ONCE_PATCH_YES) { + args[0] = grub; + if ((f = pOpen( (char **)args, 'w', &pid ))) { + fprintf( f, "savedefault --default=%d --once\n", + sdRec.osindex ); + pClose( f, &pid ); + } + } + else if (grubOncePatch == GRUB_ONCE_PATCH_NO) { + args[0] = grub_set_default; + snprintf( rec, sizeof(rec), "%d", sdRec.osindex ); + args[1] = rec; + args[2] = 0; + runAndWait( (char **)args, (char **)env ); + } } static char *lilo;