diff --git a/AUTHORS b/AUTHORS index e086a333a..b8d4a4ab5 100644 --- a/AUTHORS +++ b/AUTHORS @@ -15,3 +15,6 @@ OKUJI Yoshinori contributed many bugfixes and new features, such as working LBA support, and /sbin/grub support for configuration files. Peter Astrand added support for a color menu. + +Pavel Roskin contributed many bugfixes and new features, such as FreeBSD +support in the grub shell, and configure process cleanups. diff --git a/ChangeLog b/ChangeLog index 153a04fb7..c50b6274c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,81 @@ +1999-09-29 OKUJI Yoshinori + + * stage2/builtins.c (install_func): If the Stage 2 id in FILE is + not STAGE2_ID_STAGE2, set IS_STAGE1_5 to 1, otherwise to 0. + Use CONFIG_FILE_LOCATION to point to the location of the name of + a configuration file in Stage 2. + If the option `p' is present and IS_STAGE1_5 is non-zero, reset + the device information in CONFIG_FILE_LOCATION. + (cat_func): New function. + (builtin_cat): New variable. + (builtin_table): Added a pointer to BUILTIN_CAT. + (geometry_func): Call real_open_partition with the argument 1 + after printing out the drive information. + * stage2/disk_io.c (real_open_partition): Made global. + [!STAGE1_5] (print_completions): In the command completion and + the filename completion, print a newline at the last if + IS_COMPLETION is zero. + * stage2/shared.h (real_open_partition): Declared. + * stage2/fsys_ext2fs.c (ext2fs_dir): Do not print a newline even + if PRINT_POSSIBILITIES is less than zero. + * stage2/fsys_ffs.c (ffs_dir): Likewise. + * stage2/fsys_fat.c (fat_dir): Likewise. + * stage2/fsys_minix.c (minix_dir): Likewise. + +1999-09-29 OKUJI Yoshinori + + * stage1/stage1.S [!FFS_STAGE1_5] (blocklist_default_len): Do + not divide the size by 512, but shift the size to the right by + 9 instead, because of a binutils-2.9.1.0.x bug. + * stage1/stage1_lba.S [!FFS_STAGE1_5] (blocklist_default_len): + Likewise. + * stage2/builtins.c (install_func): When installing Stage 1.5, + if set_device returns NULL, then set CURRENT_DRIVE to 0xFF and + CONFIG_FILE to PTR. + +1999-09-26 OKUJI Yoshinori + + * stage2/char_io.c [!STAGE1_5] (get_cmdline): In cl_insert, call + cl_setcpos before printing BUF, even if LPOS is equal to LLEN. + In the completion, if RET is zero, do not call cl_init. + * stage2/disk_io.c [!STAGE1_5] (print_completions): In the + filename completion, if UNIQUE is 1, check if UNIQUE_STRING is a + directory or not. If so, append '/' to BUF. + In the partition completion, if IS_COMPLETION is non-zero and + *UNIQUE_STRING is not NUL, copy UNIQUE_STRING to PTR. Do not + append '/'. + (real_open_partition) [!STAGE1_5]: If DO_COMPRESSION is non-zero, + call print_a_completion. + (check_BSD_parts) [!STAGE1_5]: Likewise. + [!STAGE1_5] (print_a_completion): Ignore NAME if it is "." or + "..". + +1999-09-25 OKUJI Yoshinori + + * acinclude.m4 (grub_CHECK_USCORE_END_SYMBOL): Do not call + AC_DEFINE within AC_CACHE_VAL. Call it after AC_CACHE_VAL. + * stage2/Makefile.am (STAGE1_5_COMPILE): Do not define + CONFIG_FILE_ASM. + * stage2/asm.S (config_file) [STAGE1_5]: Set the first 4 bytes + to 0xffffffff and the following to "/boot/grub/stage2". + (config_file) [!STAGE1_5]: Set to "/boot/grub/menu.lst". + * stage2/builtins.c (install_func): Read a Stage 2 before + handling the `p' option. + If the `configfile' option is present and FILE is a Stage 2, + translate the device name to the internal device representation + and copy the result to STR. + * stage2/disk_io.c [STAGE1_5] (sane_partition): Eliminated. + [STAGE1_5] (incomplete): Likewise. + [STAGE1_5] (disk_choice): Likewise. + [STAGE1_5] (part_choice): Likewise. + (set_device) [STAGE1_5]: Assume that the first 4 bytes of DEVICE + is a device number. Set DRIVE to the forth byte of DEV and + PARTITION to the first 3 bytes of DEV. If DRIVE is 0xFF, set + CURRENT_DRIVE and CURRENT_PARTITION to SAVED_DRIVE and + SAVED_PARTITION, respectively. Otherwise set to DRIVE and + PARTITION, respectively. + (setup_part) [STAGE1_5]: Always call set_device. + 1999-09-24 OKUJI Yoshinori * acinclude.m4 (grub_CHECK_END_SYMBOL): Add a missing diff --git a/NEWS b/NEWS index fa16e3b0e..62603f3d2 100644 --- a/NEWS +++ b/NEWS @@ -27,6 +27,8 @@ New in 0.5.93: * Killing (C-u and C-k), yanking (C-y) and manipulating the history (C-p and C-n) are supported. * The address argument for the command "install" is now optional. +* Better completion support. +* The command "cat" displays the contents of a file. New in 0.5.92 - 1999-07-26: * Bug fixes (i.e. Stage 1.5 can work fine again). diff --git a/README b/README index 7ec6e5125..7c6baedbf 100644 --- a/README +++ b/README @@ -18,8 +18,23 @@ you use the following utilities: * binutils 2.9.1.0.23 and later (Do not use early 2.9.1.0.x!) Binutils has changed the behavior of 16bit assembler between 2.9.1 -and 2.9.1.0.x, and we support only 2.9.1.0.x. It is available from -ftp.XX.kernel.org (XX is the country code, such as `jp'). +and 2.9.1.0.x, and we support only 2.9.1.0.x and higher. It is available +from ftp.varesearch.com:/pub/support/hjl/binutils. + +NOTE: you should check for the version of your binutils by the following +command: + +$ gcc -Wl,-v 2>&1 | grep "GNU ld" + +This will show two versions, like this: + +GNU ld version 2.9.5 (with BFD 2.9.5.0.13) + +The latter is what you should see. If you have installed a recent +version of binutils but this version number is not identical with it, +GCC uses a fixed path rather than the environment variable PATH to find +binutils. In this case, you need to install your binutils into the path +which GCC sees (typically, /usr/bin), or reinstall GCC. These below are required when you develop GRUB or when you get it from diff --git a/acinclude.m4 b/acinclude.m4 index 563633023..0c42e1224 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -270,11 +270,11 @@ else grub_cv_check_uscore_end_symbol=no fi +rm -f conftest*]) + if test "x$grub_cv_check_uscore_end_symbol" = xyes; then AC_DEFINE([HAVE_USCORE_END_SYMBOL]) fi -rm -f conftest*]) - AC_MSG_RESULT([$grub_cv_check_uscore_end_symbol]) ]) diff --git a/aclocal.m4 b/aclocal.m4 index 810a7c5e1..b2dd414b8 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -282,12 +282,12 @@ else grub_cv_check_uscore_end_symbol=no fi +rm -f conftest*]) + if test "x$grub_cv_check_uscore_end_symbol" = xyes; then AC_DEFINE([HAVE_USCORE_END_SYMBOL]) fi -rm -f conftest*]) - AC_MSG_RESULT([$grub_cv_check_uscore_end_symbol]) ]) diff --git a/configure b/configure index fcb8377be..c2e61ac3c 100644 --- a/configure +++ b/configure @@ -1765,6 +1765,10 @@ else grub_cv_check_uscore_end_symbol=no fi +rm -f conftest* +fi + + if test "x$grub_cv_check_uscore_end_symbol" = xyes; then cat >> confdefs.h <<\EOF #define HAVE_USCORE_END_SYMBOL 1 @@ -1772,10 +1776,6 @@ EOF fi -rm -f conftest* -fi - - echo "$ac_t""$grub_cv_check_uscore_end_symbol" 1>&6 if test "x$grub_cv_check_end_symbol" != "xyes" \ diff --git a/stage1/stage1.S b/stage1/stage1.S index 099d5e54a..612869b07 100644 --- a/stage1/stage1.S +++ b/stage1/stage1.S @@ -405,7 +405,7 @@ blocklist_default_start: sectors from the start of the disk, sector 0 */ blocklist_default_len: /* this is the number of sectors to read */ - .word (STAGE2_SIZE + 511) / 512 + .word (STAGE2_SIZE + 511) >> 9 blocklist_default_seg: .word 0x0800 /* this is the segment of the starting address to load the data into */ diff --git a/stage1/stage1_lba.S b/stage1/stage1_lba.S index 407d58dac..6400b17d7 100644 --- a/stage1/stage1_lba.S +++ b/stage1/stage1_lba.S @@ -352,7 +352,7 @@ blocklist_default_start: sectors from the start of the disk, sector 0 */ blocklist_default_len: /* this is the number of sectors to read */ - .word (STAGE2_SIZE + 511) / 512 + .word (STAGE2_SIZE + 511) >> 9 blocklist_default_seg: .word 0x0800 /* this is the segment of the starting address to load the data into */ diff --git a/stage2/Makefile.am b/stage2/Makefile.am index e76ba908b..4dbc164de 100644 --- a/stage2/Makefile.am +++ b/stage2/Makefile.am @@ -32,8 +32,7 @@ STAGE2_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,8000 STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000 -STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1 \ - -DCONFIG_FILE_ASM='.string "/boot/grub/stage2"' +STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1 # asm.S absolutely needs to come first! # For stage2 target. diff --git a/stage2/asm.S b/stage2/asm.S index d03e5b6fb..0b58a29a9 100644 --- a/stage2/asm.S +++ b/stage2/asm.S @@ -66,11 +66,12 @@ VARIABLE(stage2_id) VARIABLE(version_string) .string VERSION VARIABLE(config_file) -#ifndef CONFIG_FILE_ASM +#ifndef STAGE1_5 .string "/boot/grub/menu.lst" -#else /* CONFIG_FILE_ASM */ - CONFIG_FILE_ASM -#endif /* CONFIG_FILE_ASM */ +#else /* STAGE1_5 */ + .long 0xffffffff + .string "/boot/grub/stage2" +#endif /* STAGE1_5 */ /* * Leave some breathing room for the config file name. diff --git a/stage2/builtins.c b/stage2/builtins.c index 39498b7ba..bd2ed583e 100644 --- a/stage2/builtins.c +++ b/stage2/builtins.c @@ -127,6 +127,37 @@ static struct builtin builtin_boot = "Boot the OS/chain-loader which has been loaded." }; + +static int +cat_func (char *arg, int flags) +{ + int len; + char *ptr; + + if (! grub_open (arg)) + return 1; + + len = grub_read ((char *) RAW_ADDR (0x100000), -1); + if (errnum) + return 1; + + ptr = (char *) RAW_ADDR (0x100000); + + while (len--) + grub_putchar (*ptr++); + + return 0; +} + +static struct builtin builtin_cat = +{ + "cat", + cat_func, + BUILTIN_CMDLINE, + "cat FILE", + "Print the contents of the file FILE." +}; + /* chainloader */ static int @@ -502,6 +533,7 @@ geometry_func (char *arg, int flags) current_drive, geom.cylinders, geom.heads, geom.sectors, geom.total_sectors, msg); + real_open_partition (1); return 0; } @@ -728,7 +760,11 @@ install_func (char *arg, int flags) int stage2_sect; char *ptr; int installaddr, installlist; - + /* Point to the location of the name of a configuration file in Stage 2. */ + char *config_file_location; + /* If FILE is a Stage 1.5? */ + int is_stage1_5 = 0; + /* Save the first sector of Stage2 in STAGE2_SECT. */ static void disk_read_savesect_func (int sector) { @@ -926,33 +962,16 @@ install_func (char *arg, int flags) /* Stage 2. */ installaddr = 0x8000; else - /* Stage 1.5. */ - installaddr = 0x2000; + { + /* Stage 1.5. */ + installaddr = 0x2000; + is_stage1_5 = 1; + } } *((unsigned short *) (BOOTSEC_LOCATION + STAGE1_INSTALLADDR)) = installaddr; - if (*ptr == 'p') - { - write_stage2_sect = 1; - *((long *) (SCRATCHADDR + STAGE2_INSTALLPART)) = current_partition; - ptr = skip_to (0, ptr); - } - - if (*ptr) - { - char *str = ((char *) (SCRATCHADDR + STAGE2_VER_STR_OFFS)); - - write_stage2_sect = 1; - /* Find a string for the configuration filename. */ - while (*(str++)) - ; - /* Copy the filename to Stage 2. */ - while ((*(str++) = *(ptr++)) != 0) - ; - } - /* Read the whole of Stage 2. */ filepos = 0; disk_read_hook = disk_read_blocklist_func; @@ -962,6 +981,55 @@ install_func (char *arg, int flags) return 1; } + /* Find a string for the configuration filename. */ + config_file_location = ((char *) (SCRATCHADDR + STAGE2_VER_STR_OFFS)); + while (*(config_file_location++)) + ; + + if (*ptr == 'p') + { + write_stage2_sect = 1; + *((long *) (SCRATCHADDR + STAGE2_INSTALLPART)) = current_partition; + if (is_stage1_5) + { + /* Reset the device information in FILE if it is a Stage 1.5. */ + int device = 0xFFFFFFFF; + + grub_memmove (config_file_location, (char *) &device, sizeof (int)); + } + + ptr = skip_to (0, ptr); + } + + if (*ptr) + { + write_stage2_sect = 1; + + if (! is_stage1_5) + /* If it is a Stage 2, just copy PTR to CONFIG_FILE_LOCATION. */ + grub_strcpy (config_file_location, ptr); + else + { + char *config_file; + int device; + int tmp = current_drive; + + /* Translate the external device syntax to the internal device + syntax. */ + if (! (config_file = set_device (ptr))) + { + errnum = 0; + current_drive = 0xFF; + config_file = ptr; + } + + device = current_drive << 24 | current_partition; + current_drive = tmp; + grub_memmove (config_file_location, (char *) &device, sizeof (int)); + grub_strcpy (config_file_location + sizeof (int), config_file); + } + } + /* Clear the cache. */ buf_track = -1; @@ -1507,6 +1575,7 @@ static struct builtin builtin_uppermem = struct builtin *builtin_table[] = { &builtin_boot, + &builtin_cat, &builtin_chainloader, &builtin_color, &builtin_configfile, diff --git a/stage2/char_io.c b/stage2/char_io.c index 9423addba..dc4c35655 100644 --- a/stage2/char_io.c +++ b/stage2/char_io.c @@ -300,6 +300,7 @@ get_cmdline (char *prompt, char *cmdline, int maxlen, if (lpos == llen) { grub_memmove (buf + lpos, str, l + 1); + cl_setcpos (); cl_print (buf + lpos, echo_char); lpos += l; cl_setcpos (); @@ -414,7 +415,7 @@ get_cmdline (char *prompt, char *cmdline, int maxlen, { /* Found, so insert COMPLETION_BUFFER. */ cl_insert (completion_buffer + lpos - i); - + if (ret > 0) { /* There is more than one candidates, so print @@ -432,7 +433,9 @@ get_cmdline (char *prompt, char *cmdline, int maxlen, /* Restore the command-line. */ if (equal_pos >= 0) buf[equal_pos] = '='; - cl_init (); + + if (ret) + cl_init (); } break; case 1: /* C-a go to beginning of line */ diff --git a/stage2/disk_io.c b/stage2/disk_io.c index 09d15a2f0..e809b00f1 100644 --- a/stage2/disk_io.c +++ b/stage2/disk_io.c @@ -242,14 +242,13 @@ devread (int sector, int byte_offset, int byte_len, char *buf) byte_len, buf); } +#ifndef STAGE1_5 static int sane_partition (void) { -#ifndef STAGE1_5 /* network drive */ if (current_drive == 0x20) return 1; -#endif if (!(current_partition & 0xFF000000uL) && (current_drive & 0xFFFFFF7F) < 8 @@ -263,6 +262,7 @@ sane_partition (void) errnum = ERR_DEV_VALUES; return 0; } +#endif /* ! STAGE1_5 */ static void attempt_mount (void) @@ -415,6 +415,16 @@ check_BSD_parts (int flags) if (! do_completion) printf (" BSD Partition num: \'%c\', ", part_no + 'a'); + else + { + char str[16]; + + grub_sprintf (str, "%d,%c)", + (current_partition >> 16) & 0xFF, + part_no + 'a'); + print_a_completion (str); + } + check_and_print_mount (); } else @@ -446,7 +456,7 @@ check_BSD_parts (int flags) static char cur_part_desc[16]; #endif -static int +int real_open_partition (int flags) { char mbr_buf[SECTOR_SIZE]; @@ -543,14 +553,30 @@ real_open_partition (int flags) { current_partition |= 0xFFFF; if (! do_completion) - printf (" Partition num: %d, ", slice_no); - if (! IS_PC_SLICE_TYPE_BSD (current_slice)) - check_and_print_mount (); + { + printf (" Partition num: %d, ", slice_no); + + if (! IS_PC_SLICE_TYPE_BSD (current_slice)) + check_and_print_mount (); + else + check_BSD_parts (1); + } else - check_BSD_parts (1); + { + if (! IS_PC_SLICE_TYPE_BSD (current_slice)) + { + char str[8]; + + grub_sprintf (str, "%d)", slice_no); + print_a_completion (str); + } + else + check_BSD_parts (1); + } + errnum = ERR_NONE; } -# endif /* STAGE1_5 */ +# endif /* ! STAGE1_5 */ /* * If we've found the right partition, we're done */ @@ -636,20 +662,42 @@ open_partition (void) } +#ifndef STAGE1_5 /* XX used for device completion in 'set_device' and 'print_completions' */ static int incomplete, disk_choice; static enum - { - PART_UNSPECIFIED = 0, - PART_DISK, - PART_CHOSEN, - } +{ + PART_UNSPECIFIED = 0, + PART_DISK, + PART_CHOSEN, +} part_choice; - +#endif /* ! STAGE1_5 */ char * set_device (char *device) { +#ifdef STAGE1_5 + /* In Stage 1.5, the first 4 bytes of FILENAME has a device number. */ + int dev = *((int *) device); + int drive = dev >> 24; + int partition = dev & 0xFFFFFF; + + if (drive == 0xFF) + { + current_drive = saved_drive; + current_partition = saved_partition; + } + else + { + current_drive = drive; + current_partition = partition; + } + + return device + sizeof (int); + +#else /* ! STAGE1_5 */ + /* The use of retval in this function is not really clean, but it works */ char *retval = 0; @@ -659,11 +707,9 @@ set_device (char *device) current_drive = saved_drive; current_partition = 0xFFFFFF; -#ifndef STAGE1_5 if (*device == '(' && !*(device + 1)) /* user has given '(' only, let disk_choice handle what disks we have */ return device + 1; -#endif if (*device == '(' && *(++device)) { @@ -671,7 +717,6 @@ set_device (char *device) { char ch = *device; -#ifndef STAGE1_5 if (*device == 'f' || *device == 'h') { /* user has given '([fh]', check for resp. add 'd' and @@ -686,7 +731,6 @@ set_device (char *device) else if (*(device + 1) == 'd' && !*(device + 2)) return device + 2; } -#endif if ((*device == 'f' || *device == 'h' || *device == 'n') && (device += 2, (*(device - 1) != 'd'))) @@ -846,6 +890,8 @@ set_device (char *device) } return retval; + +#endif /* ! STAGE1_5 */ } /* @@ -901,6 +947,23 @@ set_bootdev (int hdbias) static char * setup_part (char *filename) { +#ifdef STAGE1_5 + + if (! (filename = set_device (filename))) + { + current_drive = 0xFF; + return 0; + } + +# ifndef NO_BLOCK_FILES + if (*filename != '/') + open_partition (); + else +# endif /* ! NO_BLOCK_FILES */ + open_device (); + +#else /* ! STAGE1_5 */ + /* FIXME: decide on syntax for blocklist vs. old-style vs. /dev/hd0s1 */ /* Strip any leading /dev. */ if (substring ("/dev/", filename) < 1) @@ -913,11 +976,11 @@ setup_part (char *filename) current_drive = 0xFF; return 0; } -#ifndef NO_BLOCK_FILES +# ifndef NO_BLOCK_FILES if (*filename != '/') open_partition (); else -#endif /* NO_BLOCK_FILES */ +# endif /* ! NO_BLOCK_FILES */ open_device (); } else if (saved_drive != current_drive @@ -929,14 +992,16 @@ setup_part (char *filename) current_partition = saved_partition; /* allow for the error case of "no filesystem" after the partition is found. This makes block files work fine on no filesystem */ -#ifndef NO_BLOCK_FILES +# ifndef NO_BLOCK_FILES if (*filename != '/') open_partition (); else -#endif /* NO_BLOCK_FILES */ +# endif /* ! NO_BLOCK_FILES */ open_device (); } - + +#endif /* ! STAGE1_5 */ + if (errnum && (*filename == '/' || errnum != ERR_FSYS_MOUNT)) return 0; else @@ -982,6 +1047,10 @@ print_fsys_type (void) void print_a_completion (char *name) { + /* If NAME is "." or "..", do not count it. */ + if (grub_strcmp (name, ".") == 0 || grub_strcmp (name, "..") == 0) + return; + if (do_completion) { char *buf = unique_string; @@ -1053,6 +1122,9 @@ print_completions (int is_filename, int is_completion) grub_strcpy (buf, unique_string); } + if (! is_completion) + grub_putchar ('\n'); + do_completion = 0; return unique - 1; } @@ -1082,12 +1154,9 @@ print_completions (int is_filename, int is_completion) if ((disk_choice || disk_no == current_drive) && ! get_diskinfo (disk_no, &geom)) { - char dev_name[4]; + char dev_name[8]; - dev_name[0] = (i ? 'h' : 'f'); - dev_name[1] = 'd'; - dev_name[2] = '0' + j; - dev_name[3] = '\0'; + grub_sprintf (dev_name, "%cd%d", i ? 'h' : 'f', j); print_a_completion (dev_name); } } @@ -1099,22 +1168,25 @@ print_completions (int is_filename, int is_completion) while (*ptr != '(') ptr--; ptr++; - { - char *u = unique_string; - while ((*ptr++ = *u++)) - ; - ptr--; - } - ptr--; - if ((*(ptr - 2) == 'h') && (*(ptr - 1) == 'd') - && ('0' <= *ptr && *ptr <= '8')) - *(ptr + 1) = ',', *(ptr + 2) = '\0'; - if ((*(ptr - 2) == 'f') && (*(ptr - 1) == 'd') - && ('0' <= *ptr && *ptr <= '8')) - *(ptr + 1) = ')', *(ptr + 2) = '\0'; - - grub_putchar ('\n'); + grub_strcpy (ptr, unique_string); + if (unique == 1) + { + ptr += grub_strlen (ptr); + if (*unique_string == 'h') + { + *ptr++ = ','; + *ptr = 0; + } + else + { + *ptr++ = ')'; + *ptr = 0; + } + } } + + if (! is_completion) + grub_putchar ('\n'); } else { @@ -1124,21 +1196,26 @@ print_completions (int is_filename, int is_completion) if (! is_completion) grub_printf (" Possible partitions are:\n"); real_open_partition (1); + + if (is_completion && *unique_string) + { + ptr = buf; + while (*ptr++ != ',') + ; + grub_strcpy (ptr, unique_string); + } } else { if (open_partition ()) { - check_and_print_mount (); - /* FIXME: Can talk about linux only, do we need - to know about syntax here? */ - ptr = buf; - while (*ptr) - ptr++; + unique = 1; + ptr = buf + grub_strlen (buf); if (*(ptr - 1) != ')') - *ptr++ = ')'; - *ptr++ = '/'; - *ptr = '\0'; + { + *ptr++ = ')'; + *ptr = 0; + } } } } @@ -1158,16 +1235,33 @@ print_completions (int is_filename, int is_completion) ptr--; ptr++; + grub_strcpy (ptr, unique_string); + if (unique == 1) { - char *u = unique_string + grub_strlen (unique_string); - - *u++ = ' '; - *u = 0; - } + ptr += grub_strlen (unique_string); - grub_strcpy (ptr, unique_string); + /* Check if the file UNIQUE_STRING is a directory. */ + *ptr = '/'; + *(ptr + 1) = 0; + + dir (buf); + + /* Restore the original unique value. */ + unique = 1; + + if (errnum) + { + /* Regular file */ + errnum = 0; + *ptr = ' '; + *(ptr + 1) = 0; + } + } } + + if (! is_completion) + grub_putchar ('\n'); } else errnum = ERR_BAD_FILENAME; diff --git a/stage2/fsys_ext2fs.c b/stage2/fsys_ext2fs.c index 35a3caa6b..64ffd9df4 100644 --- a/stage2/fsys_ext2fs.c +++ b/stage2/fsys_ext2fs.c @@ -705,7 +705,9 @@ ext2fs_dir (char *dirname) { if (print_possibilities < 0) { +# if 0 putchar ('\n'); +# endif } else { diff --git a/stage2/fsys_fat.c b/stage2/fsys_fat.c index 6f504576c..d3cfb3a7e 100644 --- a/stage2/fsys_fat.c +++ b/stage2/fsys_fat.c @@ -211,7 +211,9 @@ loop: { if (print_possibilities < 0) { +#if 0 putchar ('\n'); +#endif return 1; } diff --git a/stage2/fsys_ffs.c b/stage2/fsys_ffs.c index 93b581945..29408bb51 100644 --- a/stage2/fsys_ffs.c +++ b/stage2/fsys_ffs.c @@ -240,7 +240,9 @@ loop: { if (loc >= INODE->i_size) { +#if 0 putchar ('\n'); +#endif if (print_possibilities < 0) return 1; diff --git a/stage2/fsys_minix.c b/stage2/fsys_minix.c index aca47c769..f84c828ed 100644 --- a/stage2/fsys_minix.c +++ b/stage2/fsys_minix.c @@ -463,7 +463,9 @@ minix_dir (char *dirname) { if (print_possibilities < 0) { +#if 0 putchar ('\n'); +#endif } else { diff --git a/stage2/shared.h b/stage2/shared.h index d9609b8db..3c2d7f52f 100644 --- a/stage2/shared.h +++ b/stage2/shared.h @@ -640,6 +640,7 @@ int devread (int sector, int byte_offset, int byte_len, char *buf); /* Parse a device string and initialize the global parameters. */ char *set_device (char *device); int open_device (void); +int real_open_partition (int flags); int open_partition (void); /* Sets device to the one represented by the SAVED_* parameters. */