Hi,
Back from my holidays I hacked some code into GRUB and finally merged
the stuff which todays (1999-07-16) CVS rep.
What the stuff does:
1) Bug fix: `gzip' is working on /sbin/grub (HACK yet but its in the
/sbin/grub tradition).
2) Completed the completion (Commands & filenames work, directories are
completed like bash does - See ChangeLog & NEWS).
3) Minix V1 - 14 char filenames is working.
To create such a thing on Linux use:
mkfs.minix -c -n14 DEVICE
Keep on hacking folks,
KR
BTW: OKUJI, tell us what `diff SWITCHES PREFIX' is preferred.
--
Klaus Reichl @ HOME email: [EMAIL PROTECTED]
Here's the patch:
diff -ruN -X grub.ignore grub-1999-07-16/src/grub/ChangeLog grub/src/grub/ChangeLog
--- grub-1999-07-16/src/grub/ChangeLog Fri Jul 16 21:28:10 1999
+++ grub/src/grub/ChangeLog Fri Jul 16 22:58:10 1999
@@ -1,3 +1,55 @@
+1999-07-09 Klaus Reichl <[EMAIL PROTECTED]>
+
+ * stage2/cmdline.c (commands): Change layout to make
+ COMPLETE_COMMANDS prettier.
+
+ * stage2/char_io.c (complete_commands): New function doing command
+ completion.
+ stage2/char_io.c (get_cmdline): Use it.
+
+ * stage2/disk_io.c (print_a_completion): add LEADING parameter to
+ give the caller the chance to specifiy what LEADING char has to be
+ printed (this is for command completion vs. file completion).
+ stage2/shared.h: update prototype
+ (print_completions): use it passing ' '
+ stage2/fsys_minix.c (minix_dir): ditto
+ stage2/fsys_ffs.c (ffs_dir): ditto
+ stage2/fsys_fat.c (fat_dir): ditto
+ stage2/fsys_ext2fs.c (ext2fs_dir): ditto
+
+1999-07-08 Klaus Reichl <[EMAIL PROTECTED]>
+
+ * stage2/gunzip.c (reset_linalloc): Add missing RAW_ADDR.
+ (gunzip_slide): make public to check in `memcheck'.
+ (gunzip_inbuf): ditto.
+
+ * stage2/char_io.c (memcheck): check for globals GUNZIP_INBUF and
+ GUNZIP_SLIDE being memcpy'd to.
+
+ * stage2/fsys_minix.c: new file.
+
+ * stage2/disk_io.c (fsys_table): minix stuff added
+ * stage2/filesys.h: ditto
+ * stage2/pc_slice.h: ditto
+ * stage2/shared.h: ditto
+ * stage2/Makefile.am: ditto
+
+1999-07-03 Klaus Reichl <[EMAIL PROTECTED]>
+
+ * Finish completion stuff to work almost like bash: ' 's in
+ filenames don't work yet, however.
+ stage2/disk_io.c (print_completions): If the completion is
+ unique, add '/' for directories and ' ' for files.
+ (print_a_completion): leave out "." and "..", this makes
+ completion much nicer.
+ stage2/char_io.c (get_cmdline): Save rest of CMDLINE if we're
+ completing. This enables completing in the middle of the line.
+
+ * grub/main.c (main): Use printf instead of grub_printf when
+ announcing gdb string (grub_printf doesn't print at this point in
+ time). If HOLD is given, print in any case, the person debugging
+ the stuff needs to find out the pid in any case.
+
1999-07-15 OKUJI Yoshinori <[EMAIL PROTECTED]>
* stage2/cmdline.c (skip_to): Don't increase CMDLINE if the
diff -ruN -X grub.ignore grub-1999-07-16/src/grub/NEWS grub/src/grub/NEWS
--- grub-1999-07-16/src/grub/NEWS Fri Jul 16 21:28:10 1999
+++ grub/src/grub/NEWS Fri Jul 16 21:29:26 1999
@@ -1,11 +1,13 @@
NEWS - list of user-visible changes between releases of GRUB
New:
+* Minix filesystems (V1 - 14 char filenames yet) added.
* Bug fixes (i.e. Stage 1.5 can work fine again).
* The /sbin/grub stage2 simulator now works at least on GNU/Linux, and
uses the Linux HDIO_GETGEO ioctl to determine hard disk geometry.
-* TAB not only lists filenames, but also completes a filename when the
- filename is unique.
+* TAB not only lists filenames and commands, but also completes the
+ unique part of them.
+ If a filename is unique, a '/' is added for directories, a ' ' otherwise.
* Password is not echoed back, put an asterisk for each of input
characters.
* stage2_debug is removed, and the debugging features are added into
diff -ruN -X grub.ignore grub-1999-07-16/src/grub/grub/main.c grub/src/grub/grub/main.c
--- grub-1999-07-16/src/grub/grub/main.c Sat Jul 3 08:20:27 1999
+++ grub/src/grub/grub/main.c Sat Jul 3 23:03:52 1999
@@ -195,10 +195,14 @@
}
while (c != EOF);
- /* Wait until the HOLD variable is cleared by an attached debugger. */
- if (hold && verbose)
- grub_printf ("Run \"gdb %s %d\", and set HOLD to zero.\n",
- program_name, (int) getpid ());
+ /* Wait until the HOLD variable is cleared by an attached debugger.
+ Don't depend on VERBOSE here - only people using the debugger need
+ that and they have to find out the pid */
+ if (hold)
+ /* Use printf (not grub_printf which is not working at this point in
+ time */
+ printf ("Run \"gdb %s %d\", and set HOLD to zero.\n",
+ program_name, (int) getpid ());
while (hold)
sleep (1);
diff -ruN -X grub.ignore grub-1999-07-16/src/grub/stage2/Makefile.am
grub/src/grub/stage2/Makefile.am
--- grub-1999-07-16/src/grub/stage2/Makefile.am Fri Jul 16 21:28:11 1999
+++ grub/src/grub/stage2/Makefile.am Fri Jul 16 21:32:30 1999
@@ -14,15 +14,16 @@
# The library for /sbin/grub.
noinst_LIBRARIES = libgrub.a
libgrub_a_SOURCES = boot.c common.c char_io.c cmdline.c disk_io.c \
- gunzip.c fsys_ffs.c fsys_ext2fs.c fsys_fat.c stage2.c
+ gunzip.c fsys_ffs.c fsys_ext2fs.c fsys_fat.c fsys_minix.c stage2.c
libgrub_a_CFLAGS = @GRUB_CFLAGS@ -DGRUB_UTIL=1 -fwritable-strings
# Stage 2 and Stage 1.5's.
pkgdatadir = $(datadir)/$(PACKAGE)/$(host_cpu)-$(host_vendor)
-nodist_pkgdata_DATA = stage2 e2fs_stage1_5 fat_stage1_5 ffs_stage1_5
+nodist_pkgdata_DATA = stage2 e2fs_stage1_5 fat_stage1_5 \
+ ffs_stage1_5 minix_stage1_5
CLEANFILES = $(pkgdata_DATA)
noinst_PROGRAMS = stage2.exec e2fs_stage1_5.exec fat_stage1_5.exec \
- ffs_stage1_5.exec
+ ffs_stage1_5.exec minix_stage1_5.exec
MOSTLYCLEANFILES = $(noinst_PROGRAMS)
STAGE2_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,8000
@@ -35,8 +36,8 @@
# asm.S absolutely needs to come first!
# For stage2 target.
stage2_exec_SOURCES = asm.S boot.c common.c char_io.c cmdline.c \
- disk_io.c gunzip.c fsys_ffs.c fsys_ext2fs.c fsys_fat.c stage2.c \
- bios.c smp-imps.c
+ disk_io.c gunzip.c fsys_ffs.c fsys_ext2fs.c fsys_fat.c fsys_minix.c \
+ stage2.c bios.c smp-imps.c
stage2_exec_CFLAGS = $(STAGE2_COMPILE)
stage2_exec_LDFLAGS = $(STAGE2_LINK)
@@ -60,6 +61,14 @@
ffs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_FFS=1 \
-DNO_BLOCK_FILES=1
ffs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
+
+# For minix_stage1_5 target.
+minix_stage1_5_exec_SOURCES = asm.S common.c char_io.c disk_io.c \
+ stage1_5.c fsys_minix.c bios.c
+
+minix_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_MINIX=1 \
+ -DNO_BLOCK_FILES=1
+minix_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
# General rule for making a raw binary.
%: %.exec
diff -ruN -X grub.ignore grub-1999-07-16/src/grub/stage2/char_io.c
grub/src/grub/stage2/char_io.c
--- grub-1999-07-16/src/grub/stage2/char_io.c Fri Jul 16 21:28:11 1999
+++ grub/src/grub/stage2/char_io.c Fri Jul 16 21:29:27 1999
@@ -137,6 +137,94 @@
version_string, mbi.mem_lower, mbi.mem_upper);
}
+/* COMMANDS is expected to start of with something like:
+ "Possible commands are:"
+ The a list of "\"COMMAND= parm\"" strings which we try to complete */
+
+static void
+complete_commands (char * cmdline, char * commands)
+{
+ char * p = commands;
+ char save;
+ int have_a_completion = 0;
+
+ reset_completion ();
+
+ while (*cmdline == ' ' || *cmdline == '\t')
+ cmdline++;
+
+ while (*p && *p != '"')
+ p++;
+
+ save = *p, *p = '\0';
+ printf (commands);
+ *p = save;
+
+ /* p on '\0' or '"' */
+ while (*p)
+ {
+ char * q;
+ int completed = 0;
+
+ /* advance p over '"' */
+ p++;
+
+ /* prepare command field */
+ q = p;
+ while (*q && *q != '"' && *q != ' ' && *q != '\t')
+ q++;
+ if (*q == ' ' || *q == '\t')
+ q++;
+
+ /* check if its a candidate and complete if so */
+ if (substring (cmdline, p) <= 0)
+ {
+ completed++;
+ have_a_completion++;
+ save = *q, *q = '\0';
+ print_a_completion (p, '"');
+ *q = save;
+ }
+
+ /* finish up command field */
+ p = q;
+ while (*q && *q != '"')
+ q++;
+ if (*q)
+ q++;
+ while (*q && *q != '"')
+ q++;
+
+ /* if something was completed, print parameters for help text */
+ if (completed)
+ {
+ save = *q, *q = '\0';
+ printf (p);
+ *q = save;
+ }
+
+ p = q;
+ }
+
+ if (! have_a_completion)
+ {
+ printf ("Invalid command\n\n");
+ printf (commands);
+ }
+ else
+ {
+ char *u = unique_string;
+
+ if (*u)
+ {
+ p = cmdline;
+ while ((*p++ = *u++))
+ ;
+ }
+ }
+
+ printf ("\n");
+}
/* Don't use this with a MAXLEN greater than 1600 or so! The problem
is that GET_CMDLINE depends on the everything fitting on the screen
@@ -261,41 +349,50 @@
case 9: /* TAB lists completions */
{
int i, j = 0, llen_old = llen;
-
- while (cmdline[j] && cmdline[j] != '=')
- j++;
-
- /* since the command line cannot have a '\n', we're OK to use c */
- c = cmdline[lpos];
-
- cl_kill_to_end ();
-
- /* goto part after line here */
- yend = ((llen + plen) / 79) + ystart;
- putchar ('\n');
- gotoxy (0, getxy () & 0xff);
-
- if (lpos > j)
+ /* rest of cmdline to be saved
+ XXX is 512 apropriate for the stack? XXX */
+ char cmdline_save [512];
+ int rest_of_line = llen - lpos + 1;
+
+ /* only to completion, if saving the rest of the line
+ is possible */
+ if (rest_of_line < sizeof (cmdline_save))
{
- for (i = lpos; i > 0 && cmdline[i - 1] != ' '; i--);
- if (i <= j)
- i = j + 1;
- /* print possible completions */
- print_completions (cmdline + i);
- /* if somebody in print_completions has added something,
- account for that */
+ while (cmdline[j] && cmdline[j] != '=')
+ j++;
+
+ memcpy (cmdline_save, &(cmdline[lpos]), rest_of_line);
+
+ cl_kill_to_end ();
+
+ /* goto part after line here */
+ yend = ((llen + plen) / 79) + ystart;
+ putchar ('\n');
+ gotoxy (0, getxy () & 0xff);
+
+ if (lpos > j)
+ {
+ for (i = lpos; i > 0 && cmdline[i - 1] != ' '; i--);
+ if (i <= j)
+ i = j + 1;
+ /* print possible completions */
+ print_completions (cmdline + i);
+ }
+ else if (commands)
+ complete_commands (cmdline, commands);
+ else
+ break;
+
+ /* if somebody in PRINT_COMPLETIONS or COMPLETE_COMMANDS has
+ added something, account for that */
while (cmdline[lpos])
lpos++, llen_old++;
- }
- else if (commands)
- printf (commands);
- else
- break;
- /* restore command-line */
- cmdline[lpos] = c;
- llen = llen_old;
- cl_init ();
+ /* restore command-line */
+ memcpy (&(cmdline[lpos]), cmdline_save, rest_of_line);
+ llen = llen_old;
+ cl_init ();
+ }
}
break;
case 1: /* C-a go to beginning of line */
@@ -606,6 +703,17 @@
extern char cur_part_desc[];
if (start >= (int) cur_part_desc && start + len <= (int) cur_part_desc + 16)
return ! errnum;
+ /* FIXME: same applies to GUNZIP_INBUF and GUNZIP_SLIDE from gunzip.c */
+ {
+ extern char gunzip_inbuf[];
+ extern char gunzip_slide[];
+
+ if ((start >= (int) gunzip_inbuf
+ && start + len <= (int) gunzip_inbuf + 0x2000)
+ || (start >= (int) gunzip_slide
+ && start + len <= (int) gunzip_slide + 0x8000))
+ return !errnum;
+ }
#endif /* GRUB_UTIL */
if ((start < RAW_ADDR (0x1000)) ||
diff -ruN -X grub.ignore grub-1999-07-16/src/grub/stage2/cmdline.c
grub/src/grub/stage2/cmdline.c
--- grub-1999-07-16/src/grub/stage2/cmdline.c Fri Jul 16 21:28:12 1999
+++ grub/src/grub/stage2/cmdline.c Fri Jul 16 21:36:44 1999
@@ -65,12 +65,13 @@
}
char commands[] =
-" Possible commands are: \"pause= ...\", \"uppermem= <kbytes>\", \"root= <device>\",
+ " Possible commands are:
+ \"pause= ...\", \"uppermem= <kbytes>\", \"root= <device>\",
\"rootnoverify= <device>\", \"chainloader= <file>\", \"kernel= <file> ...\",
\"testload= <file>\", \"read= <addr>\", \"displaymem\", \"impsprobe\",
\"fstest\", \"debug\", \"module= <file> ...\", \"modulenounzip= <file> ...\",
\"color= <normal> [<highlight>]\", \"makeactive\", \"boot\", \"quit\" and
- \"install= <stage1_file> [d] <dest_dev> <file> <addr> [p] [<config_file>]\"\n";
+ \"install= <stage1_file> [d] <dest_dev> <file> <addr> [p] [<config_file>]\"";
static void
debug_fs_print_func (int sector)
diff -ruN -X grub.ignore grub-1999-07-16/src/grub/stage2/disk_io.c
grub/src/grub/stage2/disk_io.c
--- grub-1999-07-16/src/grub/stage2/disk_io.c Sun Jun 27 13:35:37 1999
+++ grub/src/grub/stage2/disk_io.c Fri Jul 16 23:12:20 1999
@@ -46,6 +46,9 @@
# ifdef FSYS_FFS
{"ffs", ffs_mount, ffs_read, ffs_dir},
# endif
+# ifdef FSYS_MINIX
+ {"minix", minix_mount, minix_read, minix_dir},
+# endif
{0, 0, 0, 0}
};
@@ -584,7 +587,8 @@
static int incomplete, disk_choice;
#ifndef STAGE1_5
static int unique;
-static char unique_string[128]; /* XXX Don't know yet */
+char unique_string[128]; /* XXX Don't know yet about size*/
+static int complete_silently;
#endif
static enum
{
@@ -915,16 +919,34 @@
#ifndef STAGE1_5
/*
- * print_a_completion saves what has been printed to unique_string
- * printf's with a leading ' '.
+ * call RESET_COMPLETION to start new PRINT_A_COMPLETION series
*/
void
-print_a_completion (char *filename)
+reset_completion (void)
+{
+ *unique_string = '\0';
+ unique = 0;
+}
+
+/*
+ * PRINT_A_COMPLETION saves the unique part of what has been printed
+ * to UNIQUE_STRING.
+ * printf's with a leading char LEADING, unless COMPLETE_SILENTLY is set.
+ * UNIQUE is incremented on every file considered.
+ */
+
+void
+print_a_completion (char *filename, char leading)
{
char *f = filename;
char *u = unique_string;
-
+
+ /* leave "." and ".." out of completions */
+ if ((f[0] == '.' && f[1] == '\0')
+ || (f[0] == '.' && f[1] == '.' && f[2] =='\0'))
+ return;
+
if (! *u && unique == 0)
{
/* copy first string, this is unique. */
@@ -939,8 +961,9 @@
*u = '\0';
}
unique++;
-
- printf (" %s", filename);
+
+ if (!complete_silently)
+ printf ("%c%s", leading, filename);
}
/*
@@ -953,9 +976,8 @@
{
char *ptr = filename;
- *unique_string = '\0';
- unique = 0;
-
+ reset_completion ();
+
if (*filename == '/' || (ptr = set_device (filename)) || incomplete)
{
errnum = 0;
@@ -986,7 +1008,7 @@
dev_name[1] = 'd';
dev_name[2] = '0' + j;
dev_name[3] = '\0';
- print_a_completion (dev_name);
+ print_a_completion (dev_name, ' ');
}
}
}
@@ -1042,18 +1064,40 @@
/* filename completions */
printf (" Possible files are:");
dir (filename);
+
+ if (!errnum)
{
char *u = unique_string;
if (*u)
{
- while (*ptr++)
- ;
- while (*ptr != '/')
+ while (*ptr)
+ ptr++;
+ while (ptr[-1] != '/')
ptr--;
- ptr++;
while ((*ptr++ = *u++))
;
+ ptr--;
+
+ if (unique == 1)
+ {
+ printf (" Unique expansion");
+ /* try to add '/' to find out if its a directory */
+ ptr[0] = '/';
+ ptr[1] = '\0';
+ complete_silently = 1;
+ dir (filename);
+ complete_silently = 0;
+ if (errnum)
+ {
+ /* Not a directory, ... */
+ errnum = 0;
+ /* ... however, its unique so add a ' ' */
+ ptr[0] = ' ';
+ /* this \n makes the picture consistend */
+ putchar ('\n');
+ }
+ }
}
}
}
diff -ruN -X grub.ignore grub-1999-07-16/src/grub/stage2/filesys.h
grub/src/grub/stage2/filesys.h
--- grub-1999-07-16/src/grub/stage2/filesys.h Sun Jun 27 13:35:37 1999
+++ grub/src/grub/stage2/filesys.h Sun Jul 4 00:14:00 1999
@@ -25,10 +25,12 @@
* Default to all functioning filesystems enabled
*/
-#if !( defined(FSYS_FFS) || defined(FSYS_FAT) || defined(FSYS_EXT2FS) )
+#if !( defined(FSYS_FFS) || defined(FSYS_FAT) \
+ || defined(FSYS_EXT2FS) || defined(FSYS_MINIX) )
#define FSYS_FFS
#define FSYS_FAT
#define FSYS_EXT2FS
+#define FSYS_MINIX
#endif
#ifdef FSYS_FFS
@@ -61,8 +63,18 @@
#define FSYS_EXT2FS_NUM 0
#endif
+#ifdef FSYS_MINIX
+#define FSYS_MINIX_NUM 1
+int minix_mount (void);
+int minix_read (char *buf, int len);
+int minix_dir (char *dirname);
+#else
+#define FSYS_MINIX_NUM 0
+#endif
+
#ifndef NUM_FSYS
-#define NUM_FSYS ( FSYS_FFS_NUM + FSYS_FAT_NUM + FSYS_EXT2FS_NUM )
+#define NUM_FSYS ( FSYS_FFS_NUM + FSYS_FAT_NUM \
+ + FSYS_EXT2FS_NUM + FSYS_MINIX_NUM )
#endif
/* defines for the block filesystem info area */
diff -ruN -X grub.ignore grub-1999-07-16/src/grub/stage2/fsys_ext2fs.c
grub/src/grub/stage2/fsys_ext2fs.c
--- grub-1999-07-16/src/grub/stage2/fsys_ext2fs.c Sun Jun 27 13:35:37 1999
+++ grub/src/grub/stage2/fsys_ext2fs.c Thu Jul 8 23:54:54 1999
@@ -757,7 +757,7 @@
{
if (print_possibilities > 0)
print_possibilities = -print_possibilities;
- print_a_completion (dp->name);
+ print_a_completion (dp->name, ' ');
}
# endif
diff -ruN -X grub.ignore grub-1999-07-16/src/grub/stage2/fsys_fat.c
grub/src/grub/stage2/fsys_fat.c
--- grub-1999-07-16/src/grub/stage2/fsys_fat.c Sun Jun 27 13:35:37 1999
+++ grub/src/grub/stage2/fsys_fat.c Thu Jul 8 23:54:54 1999
@@ -240,7 +240,7 @@
{
if (print_possibilities > 0)
print_possibilities = -print_possibilities;
- print_a_completion (filename);
+ print_a_completion (filename, ' ');
}
# endif /* STAGE1_5 */
}
diff -ruN -X grub.ignore grub-1999-07-16/src/grub/stage2/fsys_ffs.c
grub/src/grub/stage2/fsys_ffs.c
--- grub-1999-07-16/src/grub/stage2/fsys_ffs.c Sun Jun 27 13:35:37 1999
+++ grub/src/grub/stage2/fsys_ffs.c Thu Jul 8 23:54:53 1999
@@ -252,7 +252,7 @@
if (print_possibilities > 0)
print_possibilities = -print_possibilities;
- print_a_completion (dp->d_name);
+ print_a_completion (dp->d_name, ' ');
}
#endif /* STAGE1_5 */
}
diff -ruN -X grub.ignore grub-1999-07-16/src/grub/stage2/fsys_minix.c
grub/src/grub/stage2/fsys_minix.c
--- grub-1999-07-16/src/grub/stage2/fsys_minix.c Thu Jan 1 01:00:00 1970
+++ grub/src/grub/stage2/fsys_minix.c Fri Jul 16 22:56:50 1999
@@ -0,0 +1,523 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 1999 Klaus Reichl <[EMAIL PROTECTED]>
+ * Copyright (C) 1999 Free Software Foundation, Inc.
+ *
+ * This program 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Restrictions:
+ This is MINIX V1 only (yet)
+ Disk creation is like:
+ mkfs.minix -c -n14 DEVICE
+*/
+
+#include "shared.h"
+#include "filesys.h"
+
+/* #define DEBUG_MINIX */
+
+/* indirect blocks */
+static int mapblock1, mapblock2;
+
+/* sizes are always in bytes, BLOCK values are always in DEV_BSIZE (sectors) */
+#define DEV_BSIZE 512
+
+/* include/linux/fs.h */
+#define BLOCK_SIZE_BITS 10
+#define BLOCK_SIZE (1<<BLOCK_SIZE_BITS)
+
+/* made up, defaults to 1 but can be passed via mount_opts */
+#define WHICH_SUPER 1
+/* kind of from fs/ext2/super.c (is OK for minix) */
+#define SBLOCK (WHICH_SUPER * BLOCK_SIZE / DEV_BSIZE) /* = 2 */
+
+/* include/asm-i386/type.h */
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+/* include/linux/minix_fs.h */
+#define MINIX_ROOT_INO 1
+
+/* Not the same as the bogus LINK_MAX in <linux/limits.h>. Oh well. */
+#define MINIX_LINK_MAX 250
+#define MINIX2_LINK_MAX 65530
+
+#define MINIX_I_MAP_SLOTS 8
+#define MINIX_Z_MAP_SLOTS 64
+#define MINIX_SUPER_MAGIC 0x137F /* original minix fs */
+#define MINIX_SUPER_MAGIC2 0x138F /* minix fs, 30 char names */
+#define MINIX2_SUPER_MAGIC 0x2468 /* minix V2 fs */
+#define MINIX2_SUPER_MAGIC2 0x2478 /* minix V2 fs, 30 char names */
+#define MINIX_VALID_FS 0x0001 /* Clean fs. */
+#define MINIX_ERROR_FS 0x0002 /* fs has errors. */
+
+#define MINIX_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix_inode)))
+#define MINIX2_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix2_inode)))
+
+#define MINIX_V1 0x0001 /* original minix fs */
+#define MINIX_V2 0x0002 /* minix V2 fs */
+
+/* originally this is :
+#define INODE_VERSION(inode) inode->i_sb->u.minix_sb.s_version
+ here we have */
+#define INODE_VERSION(inode) (SUPERBLOCK->s_version)
+
+#define MINIX_NAME_LEN 14 /* XXX depend on version */
+
+/*
+ * This is the original minix inode layout on disk.
+ * Note the 8-bit gid and atime and ctime.
+ */
+struct minix_inode {
+ __u16 i_mode;
+ __u16 i_uid;
+ __u32 i_size;
+ __u32 i_time;
+ __u8 i_gid;
+ __u8 i_nlinks;
+ __u16 i_zone[9];
+};
+
+/*
+ * The new minix inode has all the time entries, as well as
+ * long block numbers and a third indirect block (7+1+1+1
+ * instead of 7+1+1). Also, some previously 8-bit values are
+ * now 16-bit. The inode is now 64 bytes instead of 32.
+ */
+struct minix2_inode {
+ __u16 i_mode;
+ __u16 i_nlinks;
+ __u16 i_uid;
+ __u16 i_gid;
+ __u32 i_size;
+ __u32 i_atime;
+ __u32 i_mtime;
+ __u32 i_ctime;
+ __u32 i_zone[10];
+};
+
+/*
+ * minix super-block data on disk
+ */
+struct minix_super_block {
+ __u16 s_ninodes;
+ __u16 s_nzones;
+ __u16 s_imap_blocks;
+ __u16 s_zmap_blocks;
+ __u16 s_firstdatazone;
+ __u16 s_log_zone_size;
+ __u32 s_max_size;
+ __u16 s_magic;
+ __u16 s_state;
+ __u32 s_zones;
+};
+
+struct minix_dir_entry {
+ __u16 inode;
+ char name[0];
+};
+
+/* made up, these are pointers into FSYS_BUF */
+/* read once, always stays there: */
+#define SUPERBLOCK \
+ ((struct minix_super_block *)(FSYS_BUF))
+#define INODE \
+ ((struct minix_inode *)((int) SUPERBLOCK + BLOCK_SIZE))
+#define DATABLOCK1 \
+ ((int)((int)INODE + sizeof(struct minix_inode)))
+#define DATABLOCK2 \
+ ((int)((int)DATABLOCK1 + BLOCK_SIZE))
+
+/* linux/stat.h */
+#define S_IFMT 00170000
+#define S_IFLNK 0120000
+#define S_IFREG 0100000
+#define S_IFDIR 0040000
+#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+
+#define PATH_MAX 1024 /* include/linux/limits.h */
+#define MAX_LINK_COUNT 5 /* number of symbolic links to follow */
+
+/* check filesystem types and read superblock into memory buffer */
+int
+minix_mount (void)
+{
+ int retval = 1;
+
+ if ((((current_drive & 0x80 || current_slice != 0))
+ && (current_slice != PC_SLICE_TYPE_MINIX)
+ && (current_slice != (PC_SLICE_TYPE_BSD | (FS_OTHER << 8))))
+ || part_length < (SBLOCK +
+ (sizeof (struct minix_super_block) / DEV_BSIZE))
+ || !devread (SBLOCK, 0, sizeof (struct minix_super_block),
+ (char *) SUPERBLOCK)
+ || SUPERBLOCK->s_magic != MINIX_SUPER_MAGIC)
+ retval = 0;
+
+ return retval;
+}
+
+/* Takes a file system block number and reads it into BUFFER. */
+static int
+minix_rdfsb (int fsblock, int buffer)
+{
+ return devread (fsblock * (BLOCK_SIZE / DEV_BSIZE), 0,
+ BLOCK_SIZE, (char *) buffer);
+}
+
+/* Maps LOGICAL_BLOCK (the file offset divided by the blocksize) into
+ a physical block (the location in the file system) via an inode. */
+static int
+minix_block_map (int logical_block)
+{
+ int i;
+
+ if (logical_block < 7)
+ return INODE->i_zone[logical_block];
+
+ logical_block -= 7;
+ if (logical_block < 512)
+ {
+ i = INODE->i_zone[7];
+
+ if (!i || ((mapblock1 != 1)
+ && !minix_rdfsb (i, DATABLOCK1)))
+ {
+ errnum = ERR_FSYS_CORRUPT;
+ return -1;
+ }
+ mapblock1 = 1;
+ return ((__u16 *) DATABLOCK1) [logical_block];
+ }
+
+ logical_block -= 512;
+ i = INODE->i_zone[8];
+ if (!i || ((mapblock1 != 2)
+ && !minix_rdfsb (i, DATABLOCK1)))
+ {
+ errnum = ERR_FSYS_CORRUPT;
+ return -1;
+ }
+ mapblock1 = 2;
+ i = ((__u16 *) DATABLOCK1)[logical_block >> 9];
+ if (!i || ((mapblock2 != i)
+ && !minix_rdfsb (i, DATABLOCK2)))
+ {
+ errnum = ERR_FSYS_CORRUPT;
+ return -1;
+ }
+ mapblock2 = i;
+ return ((__u16 *) DATABLOCK2)[logical_block & 511];
+}
+
+/* read from INODE into BUF */
+int
+minix_read (char *buf, int len)
+{
+ int logical_block;
+ int offset;
+ int map;
+ int ret = 0;
+ int size = 0;
+
+ while (len > 0)
+ {
+ /* find the (logical) block component of our location */
+ logical_block = filepos >> BLOCK_SIZE_BITS;
+ offset = filepos & (BLOCK_SIZE - 1);
+ map = minix_block_map (logical_block);
+#ifdef DEBUG_MINIX
+ printf ("map=%d\n", map);
+#endif
+ if (map < 0)
+ break;
+
+ size = BLOCK_SIZE;
+ size -= offset;
+ if (size > len)
+ size = len;
+
+#ifndef STAGE1_5
+ debug_fs_func = debug_fs;
+#endif /* STAGE1_5 */
+
+ devread (map * (BLOCK_SIZE / DEV_BSIZE),
+ offset, size, buf);
+
+#ifndef STAGE1_5
+ debug_fs_func = NULL;
+#endif /* STAGE1_5 */
+
+ buf += size;
+ len -= size;
+ filepos += size;
+ ret += size;
+ }
+
+ if (errnum)
+ ret = 0;
+
+ return ret;
+}
+
+/* preconditions: minix_mount already executed, therefore supblk in buffer
+ known as SUPERBLOCK
+ returns: 0 if error, nonzero iff we were able to find the file successfully
+ postconditions: on a nonzero return, buffer known as INODE contains the
+ inode of the file we were trying to look up
+ side effects: none yet */
+int
+minix_dir (char *dirname)
+{
+ int current_ino = MINIX_ROOT_INO; /* start at the root */
+ int updir_ino = current_ino; /* the parent of the current directory */
+ int ino_blk; /* fs pointer of the inode's info */
+
+ int str_chk; /* used ot hold the results of a string
+ compare */
+
+ struct minix_inode * raw_inode; /* inode info for current_ino */
+
+ char linkbuf[PATH_MAX]; /* buffer for following sym-links */
+ int link_count = 0;
+
+ char * rest;
+ char ch;
+
+ int off; /* offset within block of directory
+ entry */
+ int loc; /* location within a directory */
+ int blk; /* which data blk within dir entry */
+ long map; /* fs pointer of a particular block from
+ dir entry */
+ struct minix_dir_entry * dp; /* pointer to directory entry */
+
+ /* loop invariants:
+ current_ino = inode to lookup
+ dirname = pointer to filename component we are cur looking up within
+ the directory known pointed to by current_ino (if any) */
+
+#ifdef DEBUG_MINIX
+ printf ("\n");
+#endif
+
+ while (1)
+ {
+#ifdef DEBUG_MINIX
+ printf ("inode %d, dirname %s\n", current_ino, dirname);
+#endif
+
+ ino_blk = (2 + SUPERBLOCK->s_imap_blocks + SUPERBLOCK->s_zmap_blocks
+ + (current_ino - 1) / MINIX_INODES_PER_BLOCK);
+ if (! minix_rdfsb (ino_blk, (int) INODE))
+ return 0;
+
+ /* reset indirect blocks! */
+ mapblock2 = mapblock1 = -1;
+
+ raw_inode = INODE + ((current_ino - 1) % MINIX_INODES_PER_BLOCK);
+
+ /* copy inode to fixed location */
+ memmove ((void *) INODE, (void *) raw_inode,
+ sizeof (struct minix_inode));
+
+ /* If we've got a symbolic link, then chase it. */
+ if (S_ISLNK (INODE->i_mode))
+ {
+ int len;
+
+ if (++link_count > MAX_LINK_COUNT)
+ {
+ errnum = ERR_SYMLINK_LOOP;
+ return 0;
+ }
+#ifdef DEBUG_MINIX
+ printf ("S_ISLNK (%s)\n", dirname);
+#endif
+
+ /* Find out how long our remaining name is. */
+ len = 0;
+ while (dirname[len] && !isspace (dirname[len]))
+ len++;
+
+ /* Get the symlink size. */
+ filemax = (INODE->i_size);
+ if (filemax + len > sizeof (linkbuf) - 2)
+ {
+ errnum = ERR_FILELENGTH;
+ return 0;
+ }
+
+ if (len)
+ {
+ /* Copy the remaining name to the end of the symlink data.
+ Note that DIRNAME and LINKBUF may overlap! */
+ memmove (linkbuf + filemax, dirname, len);
+ }
+ linkbuf[filemax + len] = '\0';
+
+ /* Read the necessary blocks, and reset the file pointer. */
+ len = grub_read (linkbuf, filemax);
+ filepos = 0;
+ if (!len)
+ return 0;
+
+#ifdef DEBUG_MINIX
+ printf ("symlink=%s\n", linkbuf);
+#endif
+
+ dirname = linkbuf;
+ if (*dirname == '/')
+ {
+ /* It's an absolute link, so look it up in root. */
+ current_ino = MINIX_ROOT_INO;
+ updir_ino = current_ino;
+ }
+ else
+ {
+ /* Relative, so look it up in our parent directory. */
+ current_ino = updir_ino;
+ }
+
+ /* Try again using the new name. */
+ continue;
+ }
+
+ /* If end of filename, INODE points to the file's inode */
+ if (!*dirname || isspace (*dirname))
+ {
+ if (!S_ISREG (INODE->i_mode))
+ {
+ errnum = ERR_BAD_FILETYPE;
+ return 0;
+ }
+
+ filemax = (INODE->i_size);
+ return 1;
+ }
+
+ /* else we have to traverse a directory */
+ updir_ino = current_ino;
+
+ /* skip over slashes */
+ while (*dirname == '/')
+ dirname++;
+
+ /* if this isn't a directory of sufficient size to hold our file,
+ abort */
+ if (!(INODE->i_size) || !S_ISDIR (INODE->i_mode))
+ {
+ errnum = ERR_BAD_FILETYPE;
+ return 0;
+ }
+
+ /* skip to next slash or end of filename (space) */
+ for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/';
+ rest++);
+
+ /* look through this directory and find the next filename component */
+ /* invariant: rest points to slash after the next filename component */
+ *rest = 0;
+ loc = 0;
+
+ do
+ {
+#ifdef DEBUG_MINIX
+ printf ("dirname=`%s', rest=`%s', loc=%d\n", dirname, rest, loc);
+#endif
+
+ /* if our location/byte offset into the directory exceeds the size,
+ give up */
+ if (loc >= INODE->i_size)
+ {
+ if (print_possibilities < 0)
+ {
+ putchar ('\n');
+ }
+ else
+ {
+ errnum = ERR_FILE_NOT_FOUND;
+ *rest = ch;
+ }
+ return (print_possibilities < 0);
+ }
+
+ /* else, find the (logical) block component of our location */
+ blk = loc >> BLOCK_SIZE_BITS;
+
+ /* we know which logical block of the directory entry we are looking
+ for, now we have to translate that to the physical (fs) block on
+ the disk */
+ map = minix_block_map (blk);
+#ifdef DEBUG_MINIX
+ printf ("fs block=%d\n", map);
+#endif
+ mapblock2 = -1;
+ if ((map < 0) || !minix_rdfsb (map, DATABLOCK2))
+ {
+ errnum = ERR_FSYS_CORRUPT;
+ *rest = ch;
+ return 0;
+ }
+ off = loc & (BLOCK_SIZE - 1);
+ dp = (struct minix_dir_entry *) (DATABLOCK2 + off);
+ /* advance loc prematurely to next on-disk directory entry */
+ loc += sizeof (dp->inode) + 14; /* XXX */
+
+ /* NOTE: minix filenames are NULL terminated if < 14 else exact */
+
+#ifdef DEBUG_MINIX
+ printf ("directory entry ino=%d\n", dp->inode);
+ if (dp->inode)
+ printf ("entry=%s\n", dp->name);
+#endif
+
+ if (dp->inode)
+ {
+ int saved_c = dp->name[MINIX_NAME_LEN+1];
+
+ dp->name[MINIX_NAME_LEN+1] = 0;
+ str_chk = substring (dirname, dp->name);
+
+# ifndef STAGE1_5
+ if (print_possibilities && ch != '/'
+ && (!*dirname || str_chk <= 0))
+ {
+ if (print_possibilities > 0)
+ print_possibilities = -print_possibilities;
+ print_a_completion (dp->name, ' ');
+ }
+# endif
+
+ dp->name[MINIX_NAME_LEN+1] = saved_c;
+ }
+
+ }
+ while (!dp->inode || (str_chk || (print_possibilities && ch != '/')));
+
+ current_ino = dp->inode;
+ *(dirname = rest) = ch;
+ }
+ /* never get here */
+}
+
+/* End of fsys_minix.c */
diff -ruN -X grub.ignore grub-1999-07-16/src/grub/stage2/gunzip.c
grub/src/grub/stage2/gunzip.c
--- grub-1999-07-16/src/grub/stage2/gunzip.c Sun Jun 27 13:35:37 1999
+++ grub/src/grub/stage2/gunzip.c Thu Jul 8 22:32:07 1999
@@ -169,7 +169,7 @@
static void
reset_linalloc (void)
{
- linalloc_topaddr = (mbi.mem_upper << 10) + 0x100000;
+ linalloc_topaddr = RAW_ADDR ((mbi.mem_upper << 10) + 0x100000);
}
@@ -352,7 +352,8 @@
/* sliding window in uncompressed data */
-static uch slide[WSIZE];
+uch gunzip_slide[WSIZE];
+#define slide gunzip_slide
/* current position in slide */
static unsigned wp;
@@ -473,7 +474,8 @@
#define INBUFSIZ 0x2000
-static uch inbuf[INBUFSIZ];
+uch gunzip_inbuf[INBUFSIZ];
+#define inbuf gunzip_inbuf
static int bufloc;
static int
diff -ruN -X grub.ignore grub-1999-07-16/src/grub/stage2/pc_slice.h
grub/src/grub/stage2/pc_slice.h
--- grub-1999-07-16/src/grub/stage2/pc_slice.h Sun Jun 27 13:35:37 1999
+++ grub/src/grub/stage2/pc_slice.h Sun Jul 4 00:47:52 1999
@@ -104,6 +104,7 @@
#define PC_SLICE_TYPE_FAT16_GT32M 6
#define PC_SLICE_TYPE_WIN95_EXTENDED 0xf
#define PC_SLICE_TYPE_EXT2FS 0x83
+#define PC_SLICE_TYPE_MINIX 0x80
/* this next one is special, as it uses it's own partitioning scheme
to subdivide the PC partition from there */
diff -ruN -X grub.ignore grub-1999-07-16/src/grub/stage2/shared.h
grub/src/grub/stage2/shared.h
--- grub-1999-07-16/src/grub/stage2/shared.h Fri Jul 16 21:28:12 1999
+++ grub/src/grub/stage2/shared.h Fri Jul 16 21:29:27 1999
@@ -134,6 +134,7 @@
#define STAGE2_ID_FFS_STAGE1_5 1
#define STAGE2_ID_E2FS_STAGE1_5 2
#define STAGE2_ID_FAT_STAGE1_5 3
+#define STAGE2_ID_MINIX_STAGE1_5 4
#ifndef STAGE1_5
#define STAGE2_ID STAGE2_ID_STAGE2
@@ -144,7 +145,9 @@
#define STAGE2_ID STAGE2_ID_E2FS_STAGE1_5
#elif defined(FSYS_FAT)
#define STAGE2_ID STAGE2_ID_FAT_STAGE1_5
-#else
+#elif defined(FSYS_MINIX)
+#define STAGE2_ID STAGE2_ID_MINIX_STAGE1_5
+#else
#error "unknown Stage 2"
#endif
#endif
@@ -558,8 +561,11 @@
/* Display statistics on the current active device. */
void print_fsys_type (void);
-/* Display device and filename completions. */
-void print_a_completion (char *filename);
+/* Display command, device, and filename completions. */
+
+extern char unique_string [];
+void reset_completion (void);
+void print_a_completion (char *filename, char leading);
void print_completions (char *filename);
/* Copies the current partition data to the desired address. */