* [PATCH] transparent file reader
@ 2010-02-16 18:06 Szymon Janc
2010-02-16 18:16 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-02-16 19:38 ` Seth Goldberg
0 siblings, 2 replies; 7+ messages in thread
From: Szymon Janc @ 2010-02-16 18:06 UTC (permalink / raw)
To: The development of GNU GRUB
[-- Attachment #1: Type: Text/Plain, Size: 394 bytes --]
Hello,
Attached patch makes file reader transparent. It should make adding new filters
to file reader easier.
- gzio.h is gone
- gzio is no more transparent, transparency is handled in grub_file_open()
- renamed GRUB_ERR_BAD_GZIP_DATA to GRUB_ERR_BAD_IOFILTER_DATA, it will be
used by other ios like xzio
What do You think about it?
--
Szymon K. Janc
szymon@janc.net.pl // GG: 1383435
[-- Attachment #2: transparentio.diff --]
[-- Type: text/x-patch, Size: 20331 bytes --]
diff -urBN orig//experimental/commands/acpi.c transparentio//experimental/commands/acpi.c
--- orig//experimental/commands/acpi.c 2010-02-16 01:43:03.711945824 +0100
+++ transparentio//experimental/commands/acpi.c 2010-02-16 18:29:04.037133199 +0100
@@ -23,7 +23,6 @@
#include <grub/disk.h>
#include <grub/term.h>
#include <grub/misc.h>
-#include <grub/gzio.h>
#include <grub/acpi.h>
#include <grub/mm.h>
#include <grub/machine/memory.h>
@@ -627,7 +626,7 @@
grub_size_t size;
char *buf;
- file = grub_gzfile_open (args[i], 1);
+ file = grub_file_open (args[i]);
if (! file)
{
free_tables ();
diff -urBN orig//experimental/commands/cat.c transparentio//experimental/commands/cat.c
--- orig//experimental/commands/cat.c 2010-02-16 01:43:03.755946959 +0100
+++ transparentio//experimental/commands/cat.c 2010-02-16 18:29:04.037133199 +0100
@@ -22,7 +22,6 @@
#include <grub/disk.h>
#include <grub/term.h>
#include <grub/misc.h>
-#include <grub/gzio.h>
#include <grub/command.h>
#include <grub/i18n.h>
@@ -39,7 +38,7 @@
if (argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
- file = grub_gzfile_open (args[0], 1);
+ file = grub_file_open (args[0]);
if (! file)
return 0;
diff -urBN orig//experimental/commands/cmp.c transparentio//experimental/commands/cmp.c
--- orig//experimental/commands/cmp.c 2010-02-16 01:43:03.783945497 +0100
+++ transparentio//experimental/commands/cmp.c 2010-02-16 18:29:04.037133199 +0100
@@ -21,7 +21,6 @@
#include <grub/misc.h>
#include <grub/file.h>
#include <grub/mm.h>
-#include <grub/gzio.h>
#include <grub/command.h>
#include <grub/i18n.h>
@@ -44,8 +43,8 @@
grub_printf ("Compare file `%s' with `%s':\n", args[0],
args[1]);
- file1 = grub_gzfile_open (args[0], 1);
- file2 = grub_gzfile_open (args[1], 1);
+ file1 = grub_file_open (args[0]);
+ file2 = grub_file_open (args[1]);
if (! file1 || ! file2)
goto cleanup;
diff -urBN orig//experimental/commands/hexdump.c transparentio//experimental/commands/hexdump.c
--- orig//experimental/commands/hexdump.c 2010-02-16 01:43:03.900945869 +0100
+++ transparentio//experimental/commands/hexdump.c 2010-02-16 18:29:04.037133199 +0100
@@ -21,7 +21,6 @@
#include <grub/file.h>
#include <grub/disk.h>
#include <grub/misc.h>
-#include <grub/gzio.h>
#include <grub/lib/hexdump.h>
#include <grub/extcmd.h>
#include <grub/i18n.h>
@@ -89,7 +88,7 @@
{
grub_file_t file;
- file = grub_gzfile_open (args[0], 1);
+ file = grub_file_open (args[0]);
if (! file)
return 0;
diff -urBN orig//experimental/gettext/gettext.c transparentio//experimental/gettext/gettext.c
--- orig//experimental/gettext/gettext.c 2010-02-16 01:43:03.859945957 +0100
+++ transparentio//experimental/gettext/gettext.c 2010-02-16 18:29:04.100132573 +0100
@@ -26,7 +26,6 @@
#include <grub/normal.h>
#include <grub/file.h>
#include <grub/kernel.h>
-#include <grub/gzio.h>
#include <grub/i18n.h>
/*
@@ -229,7 +228,7 @@
/* Using fd_mo and not another variable because
it's needed for grub_gettext_get_info. */
- fd_mo = grub_gzfile_open (filename, 1);
+ fd_mo = grub_file_open (filename);
grub_errno = GRUB_ERR_NONE;
if (!fd_mo)
diff -urBN orig//experimental/include/grub/err.h transparentio//experimental/include/grub/err.h
--- orig//experimental/include/grub/err.h 2010-02-16 01:43:03.835943739 +0100
+++ transparentio//experimental/include/grub/err.h 2010-02-16 18:29:04.116149419 +0100
@@ -50,7 +50,7 @@
GRUB_ERR_BAD_FONT,
GRUB_ERR_NOT_IMPLEMENTED_YET,
GRUB_ERR_SYMLINK_LOOP,
- GRUB_ERR_BAD_GZIP_DATA,
+ GRUB_ERR_BAD_IOFILTER_DATA,
GRUB_ERR_MENU,
GRUB_ERR_TIMEOUT,
GRUB_ERR_IO,
diff -urBN orig//experimental/include/grub/file.h transparentio//experimental/include/grub/file.h
--- orig//experimental/include/grub/file.h 2010-02-16 01:43:03.843945875 +0100
+++ transparentio//experimental/include/grub/file.h 2010-02-16 18:29:04.116149419 +0100
@@ -48,6 +48,20 @@
};
typedef struct grub_file *grub_file_t;
+/* The io filter structure. */
+struct grub_io_filter
+{
+ grub_file_t (*grub_io_open)(grub_file_t file);
+ struct grub_io_filter *next;
+};
+typedef struct grub_io_filter *grub_io_filter_t;
+
+/* Register io filter. */
+void EXPORT_FUNC(grub_io_register) (grub_io_filter_t filter);
+
+/* Unregister io filter. */
+void EXPORT_FUNC(grub_io_unregister) (grub_io_filter_t filter);
+
/* Get a device name from NAME. */
char *EXPORT_FUNC(grub_file_get_device_name) (const char *name);
diff -urBN orig//experimental/include/grub/gzio.h transparentio//experimental/include/grub/gzio.h
--- orig//experimental/include/grub/gzio.h 2010-02-16 01:43:03.896944801 +0100
+++ transparentio//experimental/include/grub/gzio.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,28 +0,0 @@
-/* gzio.h - prototypes for gzio */
-/*
- * GRUB -- GRand Unified Bootloader
- * Copyright (C) 2005,2007 Free Software Foundation, Inc.
- *
- * 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/>.
- */
-
-#ifndef GRUB_GZIO_H
-#define GRUB_GZIO_H 1
-
-#include <grub/file.h>
-
-grub_file_t grub_gzio_open (grub_file_t io, int transparent);
-grub_file_t grub_gzfile_open (const char *name, int transparent);
-
-#endif /* ! GRUB_GZIO_H */
diff -urBN orig//experimental/io/gzio.c transparentio//experimental/io/gzio.c
--- orig//experimental/io/gzio.c 2010-02-16 01:43:03.896944801 +0100
+++ transparentio//experimental/io/gzio.c 2010-02-16 18:29:04.164135704 +0100
@@ -40,7 +40,9 @@
#include <grub/misc.h>
#include <grub/fs.h>
#include <grub/file.h>
-#include <grub/gzio.h>
+#include <grub/dl.h>
+
+/*grub_file_t grub_gzio_open (grub_file_t io);*/
/*
* Window Size
@@ -206,7 +208,7 @@
|| ((hdr.flags & ORIG_NAME) && eat_field (gzio->file, -1))
|| ((hdr.flags & COMMENT) && eat_field (gzio->file, -1)))
{
- grub_error (GRUB_ERR_BAD_GZIP_DATA, "unsupported gzip format");
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA, "unsupported gzip format");
return 0;
}
@@ -644,7 +646,7 @@
{
if (e == 99)
{
- grub_error (GRUB_ERR_BAD_GZIP_DATA,
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA,
"an unused code found");
return 1;
}
@@ -683,7 +685,7 @@
{
if (e == 99)
{
- grub_error (GRUB_ERR_BAD_GZIP_DATA,
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA,
"an unused code found");
return 1;
}
@@ -769,7 +771,7 @@
DUMPBITS (16);
NEEDBITS (16);
if (gzio->block_len != (int) ((~b) & 0xffff))
- grub_error (GRUB_ERR_BAD_GZIP_DATA,
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA,
"the length of a stored block does not match");
DUMPBITS (16);
@@ -803,7 +805,7 @@
if (huft_build (l, 288, 257, cplens, cplext, &gzio->tl, &gzio->bl) != 0)
{
if (grub_errno == GRUB_ERR_NONE)
- grub_error (GRUB_ERR_BAD_GZIP_DATA,
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA,
"failed in building a Huffman code table");
return;
}
@@ -815,7 +817,7 @@
if (huft_build (l, 30, 0, cpdist, cpdext, &gzio->td, &gzio->bd) > 1)
{
if (grub_errno == GRUB_ERR_NONE)
- grub_error (GRUB_ERR_BAD_GZIP_DATA,
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA,
"failed in building a Huffman code table");
huft_free (gzio->tl);
gzio->tl = 0;
@@ -862,7 +864,7 @@
DUMPBITS (4);
if (nl > 286 || nd > 30)
{
- grub_error (GRUB_ERR_BAD_GZIP_DATA, "too much data");
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA, "too much data");
return;
}
@@ -880,7 +882,7 @@
gzio->bl = 7;
if (huft_build (ll, 19, 19, NULL, NULL, &gzio->tl, &gzio->bl) != 0)
{
- grub_error (GRUB_ERR_BAD_GZIP_DATA,
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA,
"failed in building a Huffman code table");
return;
}
@@ -904,7 +906,7 @@
DUMPBITS (2);
if ((unsigned) i + j > n)
{
- grub_error (GRUB_ERR_BAD_GZIP_DATA, "too many codes found");
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA, "too many codes found");
return;
}
while (j--)
@@ -917,7 +919,7 @@
DUMPBITS (3);
if ((unsigned) i + j > n)
{
- grub_error (GRUB_ERR_BAD_GZIP_DATA, "too many codes found");
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA, "too many codes found");
return;
}
while (j--)
@@ -932,7 +934,7 @@
DUMPBITS (7);
if ((unsigned) i + j > n)
{
- grub_error (GRUB_ERR_BAD_GZIP_DATA, "too many codes found");
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA, "too many codes found");
return;
}
while (j--)
@@ -954,7 +956,7 @@
gzio->bl = lbits;
if (huft_build (ll, nl, 257, cplens, cplext, &gzio->tl, &gzio->bl) != 0)
{
- grub_error (GRUB_ERR_BAD_GZIP_DATA,
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA,
"failed in building a Huffman code table");
return;
}
@@ -963,7 +965,7 @@
{
huft_free (gzio->tl);
gzio->tl = 0;
- grub_error (GRUB_ERR_BAD_GZIP_DATA,
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA,
"failed in building a Huffman code table");
return;
}
@@ -1039,7 +1041,7 @@
}
if (gzio->block_type > INFLATE_DYNAMIC)
- grub_error (GRUB_ERR_BAD_GZIP_DATA,
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA,
"unknown block type %d", gzio->block_type);
if (grub_errno != GRUB_ERR_NONE)
@@ -1111,8 +1113,8 @@
/* Open a new decompressing object on the top of IO. If TRANSPARENT is true,
even if IO does not contain data compressed by gzip, return a valid file
object. Note that this function won't close IO, even if an error occurs. */
-grub_file_t
-grub_gzio_open (grub_file_t io, int transparent)
+static grub_file_t
+grub_gzio_open (grub_file_t io)
{
grub_file_t file;
grub_gzio_t gzio = 0;
@@ -1142,32 +1144,12 @@
grub_free (file);
grub_file_seek (io, 0);
- if (grub_errno == GRUB_ERR_BAD_FILE_TYPE && transparent)
- {
- grub_errno = GRUB_ERR_NONE;
- return io;
- }
- else
- return 0;
- }
-
- return file;
-}
-
-/* This is similar to grub_gzio_open, but takes a file name as an argument. */
-grub_file_t
-grub_gzfile_open (const char *name, int transparent)
-{
- grub_file_t io, file;
-
- io = grub_file_open (name);
- if (! io)
- return 0;
+ /* Don't report bad file type as error. */
+ if (grub_errno == GRUB_ERR_BAD_FILE_TYPE)
+ {
+ grub_errno = GRUB_ERR_NONE;
+ }
- file = grub_gzio_open (io, transparent);
- if (! file)
- {
- grub_file_close (io);
return 0;
}
@@ -1237,8 +1219,6 @@
return grub_errno;
}
-\f
-
static struct grub_fs grub_gzio_fs =
{
.name = "gzio",
@@ -1249,3 +1229,19 @@
.label = 0,
.next = 0
};
+
+static struct grub_io_filter grub_gzio_filter = {
+ .grub_io_open = grub_gzio_open,
+ .next = 0
+};
+
+
+GRUB_MOD_INIT (gzio)
+{
+ grub_io_register (&grub_gzio_filter);
+}
+
+GRUB_MOD_FINI (gzio)
+{
+ grub_io_unregister (&grub_gzio_filter);
+}
diff -urBN orig//experimental/kern/elf.c transparentio//experimental/kern/elf.c
--- orig//experimental/kern/elf.c 2010-02-16 01:43:03.831946861 +0100
+++ transparentio//experimental/kern/elf.c 2010-02-16 18:29:04.164135704 +0100
@@ -21,7 +21,6 @@
#include <grub/elf.h>
#include <grub/elfload.h>
#include <grub/file.h>
-#include <grub/gzio.h>
#include <grub/misc.h>
#include <grub/mm.h>
@@ -95,7 +94,7 @@
grub_file_t file;
grub_elf_t elf;
- file = grub_gzfile_open (name, 1);
+ file = grub_file_open (name);
if (! file)
return 0;
diff -urBN orig//experimental/kern/file.c transparentio//experimental/kern/file.c
--- orig//experimental/kern/file.c 2010-02-16 01:43:03.843945875 +0100
+++ transparentio//experimental/kern/file.c 2010-02-16 18:29:04.164135704 +0100
@@ -24,6 +24,27 @@
#include <grub/fs.h>
#include <grub/device.h>
+/* Registered filters list. */
+static grub_io_filter_t grub_io_filter_list = NULL;
+
+void grub_io_register(grub_io_filter_t filter)
+{
+ filter->next = grub_io_filter_list;
+ grub_io_filter_list = filter;
+}
+
+void grub_io_unregister(grub_io_filter_t filter)
+{
+ grub_io_filter_t *p, q;
+
+ for (p = &grub_io_filter_list, q = *p; q; p = &(q->next), q = q->next)
+ if (q == filter)
+ {
+ *p = q->next;
+ break;
+ }
+}
+
/* Get the device part of the filename NAME. It is enclosed by parentheses. */
char *
grub_file_get_device_name (const char *name)
@@ -94,6 +115,20 @@
if ((file->fs->open) (file, file_name) != GRUB_ERR_NONE)
goto fail;
+ /* Check available filters. */
+ grub_file_t ffile;
+ grub_io_filter_t filter = grub_io_filter_list;
+ while (filter)
+ {
+ ffile = filter->grub_io_open(file);
+ if (ffile)
+ {
+ file = ffile;
+ break;
+ }
+ filter = filter->next;
+ }
+
return file;
fail:
diff -urBN orig//experimental/loader/i386/bsd.c transparentio//experimental/loader/i386/bsd.c
--- orig//experimental/loader/i386/bsd.c 2010-02-16 01:43:03.747944543 +0100
+++ transparentio//experimental/loader/i386/bsd.c 2010-02-16 18:29:04.192133406 +0100
@@ -30,7 +30,6 @@
#include <grub/elfload.h>
#include <grub/env.h>
#include <grub/misc.h>
-#include <grub/gzio.h>
#include <grub/aout.h>
#include <grub/command.h>
#include <grub/extcmd.h>
@@ -904,7 +903,7 @@
goto fail;
}
- file = grub_gzfile_open (argv[0], 1);
+ file = grub_file_open (argv[0]);
if (!file)
goto fail;
@@ -970,7 +969,7 @@
if (err)
return err;
- file = grub_gzfile_open (argv[0], 1);
+ file = grub_file_open (argv[0]);
if (! file)
return grub_errno;
@@ -1086,7 +1085,7 @@
goto fail;
}
- file = grub_gzfile_open (argv[0], 1);
+ file = grub_file_open (argv[0]);
if ((!file) || (!file->size))
goto fail;
@@ -1191,7 +1190,7 @@
return 0;
}
- file = grub_gzfile_open (argv[0], 1);
+ file = grub_file_open (argv[0]);
if ((!file) || (!file->size))
goto fail;
@@ -1257,7 +1256,7 @@
return 0;
}
- file = grub_gzfile_open (argv[0], 1);
+ file = grub_file_open (argv[0]);
if (!file)
return grub_errno;
if (!file->size)
diff -urBN orig//experimental/loader/i386/multiboot.c transparentio//experimental/loader/i386/multiboot.c
--- orig//experimental/loader/i386/multiboot.c 2010-02-16 01:43:03.996945519 +0100
+++ transparentio//experimental/loader/i386/multiboot.c 2010-02-16 18:29:04.192133406 +0100
@@ -39,7 +39,6 @@
#include <grub/dl.h>
#include <grub/mm.h>
#include <grub/misc.h>
-#include <grub/gzio.h>
#include <grub/env.h>
#include <grub/i386/relocator.h>
#include <grub/video.h>
@@ -154,7 +153,7 @@
goto fail;
}
- file = grub_gzfile_open (argv[0], 1);
+ file = grub_file_open (argv[0]);
if (! file)
{
grub_error (GRUB_ERR_BAD_ARGUMENT, "couldn't open file");
@@ -305,7 +304,7 @@
goto fail;
}
- file = grub_gzfile_open (argv[0], 1);
+ file = grub_file_open (argv[0]);
if (! file)
goto fail;
diff -urBN orig//experimental/loader/i386/xnu.c transparentio//experimental/loader/i386/xnu.c
--- orig//experimental/loader/i386/xnu.c 2010-02-16 01:43:04.123948020 +0100
+++ transparentio//experimental/loader/i386/xnu.c 2010-02-16 18:29:04.192133406 +0100
@@ -31,7 +31,6 @@
#include <grub/charset.h>
#include <grub/term.h>
#include <grub/command.h>
-#include <grub/gzio.h>
#include <grub/bitmap_scale.h>
#include <grub/i18n.h>
@@ -536,7 +535,7 @@
if (argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
- file = grub_gzfile_open (args[0], 1);
+ file = grub_file_open (args[0]);
if (! file)
return grub_error (GRUB_ERR_FILE_NOT_FOUND,
"couldn't load device-propertie dump");
diff -urBN orig//experimental/loader/macho.c transparentio//experimental/loader/macho.c
--- orig//experimental/loader/macho.c 2010-02-16 01:43:03.980946274 +0100
+++ transparentio//experimental/loader/macho.c 2010-02-16 18:29:04.192133406 +0100
@@ -26,7 +26,6 @@
#include <grub/cpu/macho.h>
#include <grub/machoload.h>
#include <grub/file.h>
-#include <grub/gzio.h>
#include <grub/misc.h>
#include <grub/mm.h>
@@ -149,7 +148,7 @@
grub_file_t file;
grub_macho_t macho;
- file = grub_gzfile_open (name, 1);
+ file = grub_file_open (name);
if (! file)
return 0;
diff -urBN orig//experimental/loader/multiboot_loader.c transparentio//experimental/loader/multiboot_loader.c
--- orig//experimental/loader/multiboot_loader.c 2010-02-16 01:43:04.000945470 +0100
+++ transparentio//experimental/loader/multiboot_loader.c 2010-02-16 18:29:04.192133406 +0100
@@ -24,7 +24,6 @@
#include <grub/dl.h>
#include <grub/mm.h>
#include <grub/misc.h>
-#include <grub/gzio.h>
#include <grub/command.h>
#include <grub/i18n.h>
@@ -74,7 +73,7 @@
goto fail;
}
- file = grub_gzfile_open (argv[0], 1);
+ file = grub_file_open (argv[0]);
if (! file)
{
grub_error (GRUB_ERR_BAD_ARGUMENT, "couldn't open file");
diff -urBN orig//experimental/loader/sparc64/ieee1275/linux.c transparentio//experimental/loader/sparc64/ieee1275/linux.c
--- orig//experimental/loader/sparc64/ieee1275/linux.c 2010-02-16 01:43:03.944945603 +0100
+++ transparentio//experimental/loader/sparc64/ieee1275/linux.c 2010-02-16 18:29:04.192133406 +0100
@@ -25,7 +25,6 @@
#include <grub/misc.h>
#include <grub/ieee1275/ieee1275.h>
#include <grub/machine/loader.h>
-#include <grub/gzio.h>
#include <grub/command.h>
#include <grub/i18n.h>
@@ -306,7 +305,7 @@
goto out;
}
- file = grub_gzfile_open (argv[0], 1);
+ file = grub_file_open (argv[0]);
if (!file)
goto out;
diff -urBN orig//experimental/loader/xnu.c transparentio//experimental/loader/xnu.c
--- orig//experimental/loader/xnu.c 2010-02-16 01:43:04.123948020 +0100
+++ transparentio//experimental/loader/xnu.c 2010-02-16 18:29:04.192133406 +0100
@@ -28,7 +28,6 @@
#include <grub/machoload.h>
#include <grub/macho.h>
#include <grub/cpu/macho.h>
-#include <grub/gzio.h>
#include <grub/command.h>
#include <grub/misc.h>
#include <grub/env.h>
@@ -667,7 +666,7 @@
macho = 0;
if (infoplistname)
- infoplist = grub_gzfile_open (infoplistname, 1);
+ infoplist = grub_file_open (infoplistname);
else
infoplist = 0;
grub_errno = GRUB_ERR_NONE;
@@ -761,7 +760,7 @@
if (! grub_xnu_heap_size)
return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");
- file = grub_gzfile_open (args[0], 1);
+ file = grub_file_open (args[0]);
if (! file)
return grub_error (GRUB_ERR_FILE_NOT_FOUND,
"couldn't load driver package");
@@ -873,7 +872,7 @@
if (! grub_xnu_heap_size)
return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");
- file = grub_gzfile_open (args[0], 1);
+ file = grub_file_open (args[0]);
if (! file)
return grub_error (GRUB_ERR_FILE_NOT_FOUND,
"couldn't load ramdisk");
@@ -913,7 +912,7 @@
if (binname)
*binname = 0;
- file = grub_gzfile_open (plistname, 1);
+ file = grub_file_open (plistname);
if (! file)
{
grub_file_close (file);
@@ -1170,7 +1169,7 @@
grub_strcpy (binname + grub_strlen (binname), "/");
grub_strcpy (binname + grub_strlen (binname), binsuffix);
grub_dprintf ("xnu", "%s:%s\n", plistname, binname);
- binfile = grub_gzfile_open (binname, 1);
+ binfile = grub_file_open (binname);
if (! binfile)
grub_errno = GRUB_ERR_NONE;
@@ -1208,7 +1207,7 @@
/* User explicitly specified plist and binary. */
if (grub_strcmp (args[1], "-") != 0)
{
- binfile = grub_gzfile_open (args[1], 1);
+ binfile = grub_file_open (args[1]);
if (! binfile)
{
grub_error (GRUB_ERR_BAD_OS, "can't open file");
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] transparent file reader
2010-02-16 18:06 [PATCH] transparent file reader Szymon Janc
@ 2010-02-16 18:16 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-02-16 19:12 ` Szymon Janc
2010-02-28 21:38 ` Szymon Janc
2010-02-16 19:38 ` Seth Goldberg
1 sibling, 2 replies; 7+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2010-02-16 18:16 UTC (permalink / raw)
To: The development of GNU GRUB
[-- Attachment #1: Type: text/plain, Size: 1136 bytes --]
Szymon Janc wrote:
> Hello,
>
> Attached patch makes file reader transparent. It should make adding new filters
> to file reader easier.
>
> - gzio.h is gone
> - gzio is no more transparent, transparency is handled in grub_file_open()
> - renamed GRUB_ERR_BAD_GZIP_DATA to GRUB_ERR_BAD_IOFILTER_DATA, it will be
> used by other ios like xzio
>
>
I like the patch however few comments:
1) How are filters ordered?
2) How would I selectively disable a filter. E.g. for hexdump or when
payload expects compressed data?
+/* Registered filters list. */
+static grub_io_filter_t grub_io_filter_list = NULL;
+
+void grub_io_register(grub_io_filter_t filter)
+{
+ filter->next = grub_io_filter_list;
+ grub_io_filter_list = filter;
+}
+
list.h can be used for this.
> What do You think about it?
>
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
--
Regards
Vladimir 'φ-coder/phcoder' Serbinenko
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 293 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] transparent file reader
2010-02-16 18:16 ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2010-02-16 19:12 ` Szymon Janc
2010-02-28 21:38 ` Szymon Janc
1 sibling, 0 replies; 7+ messages in thread
From: Szymon Janc @ 2010-02-16 19:12 UTC (permalink / raw)
To: grub-devel
Dnia wtorek 16 luty 2010 o 19:16:19 Vladimir 'φ-coder/phcoder' Serbinenko
napisał(a):
> I like the patch however few comments:
> 1) How are filters ordered?
Filters are tested in order that last registered filter is tested first. First
match stop further tests.
> 2) How would I selectively disable a filter. E.g. for hexdump or when
> payload expects compressed data?
Currently one would have to unregister filters before calling grub_file_open()
and reregister them afterwards. However this can mix up filters order. Not
a best option.
I was thinking about something like:
grub_file_open("name", NO_XFILTER|NO_YFILTER);
grub_file_open("name",NO_ALL);
to allow selectable filters or fopen() style maybe.
And a priority based filter registration if there is a need for that.
--
Szymon K. Janc
szymon@janc.net.pl // GG: 1383435
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] transparent file reader
2010-02-16 18:06 [PATCH] transparent file reader Szymon Janc
2010-02-16 18:16 ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2010-02-16 19:38 ` Seth Goldberg
2010-02-16 20:00 ` Szymon Janc
1 sibling, 1 reply; 7+ messages in thread
From: Seth Goldberg @ 2010-02-16 19:38 UTC (permalink / raw)
To: The development of GNU GRUB
How do consumers of this interface determine the underlying cause of the
problem? Sometimes, more layering creates more problems than it solves.
Think about how you determine the message to display when getting a return
value from a function.
--S
Quoting Szymon Janc, who wrote the following on Tue, 16 Feb 2010:
> Hello,
>
> Attached patch makes file reader transparent. It should make adding new filters
> to file reader easier.
>
> - gzio.h is gone
> - gzio is no more transparent, transparency is handled in grub_file_open()
> - renamed GRUB_ERR_BAD_GZIP_DATA to GRUB_ERR_BAD_IOFILTER_DATA, it will be
> used by other ios like xzio
>
>
> What do You think about it?
>
>
> --
> Szymon K. Janc
> szymon@janc.net.pl // GG: 1383435
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] transparent file reader
2010-02-16 19:38 ` Seth Goldberg
@ 2010-02-16 20:00 ` Szymon Janc
0 siblings, 0 replies; 7+ messages in thread
From: Szymon Janc @ 2010-02-16 20:00 UTC (permalink / raw)
To: grub-devel
Dnia wtorek 16 luty 2010 o 20:38:28 Seth Goldberg napisał(a):
> How do consumers of this interface determine the underlying cause of the
> problem? Sometimes, more layering creates more problems than it solves.
> Think about how you determine the message to display when getting a return
> value from a function.
Right, should check grub_errno when filter returns null file handler.
I'll add that in next version of patch.
--
Szymon K. Janc
szymon@janc.net.pl // GG: 1383435
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] transparent file reader
2010-02-16 18:16 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-02-16 19:12 ` Szymon Janc
@ 2010-02-28 21:38 ` Szymon Janc
2010-03-14 13:44 ` Vladimir 'φ-coder/phcoder' Serbinenko
1 sibling, 1 reply; 7+ messages in thread
From: Szymon Janc @ 2010-02-28 21:38 UTC (permalink / raw)
To: grub-devel
[-- Attachment #1: Type: Text/Plain, Size: 935 bytes --]
Dnia wtorek 16 luty 2010 o 19:16:19 Vladimir 'φ-coder/phcoder' Serbinenko
napisał(a):
> I like the patch however few comments:
> 1) How are filters ordered?
> 2) How would I selectively disable a filter. E.g. for hexdump or when
> payload expects compressed data?
>
> +/* Registered filters list. */
> +static grub_io_filter_t grub_io_filter_list = NULL;
> +
> +void grub_io_register(grub_io_filter_t filter)
> +{
> + filter->next = grub_io_filter_list;
> + grub_io_filter_list = filter;
> +}
> +
>
> list.h can be used for this.
Attached is new version, changes since previous one:
- use list.h
- filter registration is priority based
- filter can be disabled for next open by grub_io_filter_disable()
Interface could be simpler if make it only transparent/non-transparent but
this is somewhat less flexible. Yet, is it really needed?
--
Szymon K. Janc
szymon@janc.net.pl // GG: 1383435
[-- Attachment #2: transparentio2.diff --]
[-- Type: text/x-patch, Size: 23001 bytes --]
diff -urBN orig//experimental/commands/acpi.c transparentio//experimental/commands/acpi.c
--- orig//experimental/commands/acpi.c 2010-02-16 01:43:03.711945824 +0100
+++ transparentio//experimental/commands/acpi.c 2010-02-28 20:54:17.251005185 +0100
@@ -23,7 +23,6 @@
#include <grub/disk.h>
#include <grub/term.h>
#include <grub/misc.h>
-#include <grub/gzio.h>
#include <grub/acpi.h>
#include <grub/mm.h>
#include <grub/machine/memory.h>
@@ -627,7 +626,7 @@
grub_size_t size;
char *buf;
- file = grub_gzfile_open (args[i], 1);
+ file = grub_file_open (args[i]);
if (! file)
{
free_tables ();
diff -urBN orig//experimental/commands/cat.c transparentio//experimental/commands/cat.c
--- orig//experimental/commands/cat.c 2010-02-16 01:43:03.755946959 +0100
+++ transparentio//experimental/commands/cat.c 2010-02-28 20:54:17.251005185 +0100
@@ -22,7 +22,6 @@
#include <grub/disk.h>
#include <grub/term.h>
#include <grub/misc.h>
-#include <grub/gzio.h>
#include <grub/command.h>
#include <grub/i18n.h>
@@ -39,7 +38,7 @@
if (argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
- file = grub_gzfile_open (args[0], 1);
+ file = grub_file_open (args[0]);
if (! file)
return 0;
diff -urBN orig//experimental/commands/cmp.c transparentio//experimental/commands/cmp.c
--- orig//experimental/commands/cmp.c 2010-02-16 01:43:03.783945497 +0100
+++ transparentio//experimental/commands/cmp.c 2010-02-28 20:54:17.251005185 +0100
@@ -21,7 +21,6 @@
#include <grub/misc.h>
#include <grub/file.h>
#include <grub/mm.h>
-#include <grub/gzio.h>
#include <grub/command.h>
#include <grub/i18n.h>
@@ -44,8 +43,8 @@
grub_printf ("Compare file `%s' with `%s':\n", args[0],
args[1]);
- file1 = grub_gzfile_open (args[0], 1);
- file2 = grub_gzfile_open (args[1], 1);
+ file1 = grub_file_open (args[0]);
+ file2 = grub_file_open (args[1]);
if (! file1 || ! file2)
goto cleanup;
diff -urBN orig//experimental/commands/hexdump.c transparentio//experimental/commands/hexdump.c
--- orig//experimental/commands/hexdump.c 2010-02-16 01:43:03.900945869 +0100
+++ transparentio//experimental/commands/hexdump.c 2010-02-28 20:54:17.251005185 +0100
@@ -21,7 +21,6 @@
#include <grub/file.h>
#include <grub/disk.h>
#include <grub/misc.h>
-#include <grub/gzio.h>
#include <grub/lib/hexdump.h>
#include <grub/extcmd.h>
#include <grub/i18n.h>
@@ -89,7 +88,7 @@
{
grub_file_t file;
- file = grub_gzfile_open (args[0], 1);
+ file = grub_file_open (args[0]);
if (! file)
return 0;
diff -urBN orig//experimental/gettext/gettext.c transparentio//experimental/gettext/gettext.c
--- orig//experimental/gettext/gettext.c 2010-02-16 01:43:03.859945957 +0100
+++ transparentio//experimental/gettext/gettext.c 2010-02-28 20:54:17.251005185 +0100
@@ -26,7 +26,6 @@
#include <grub/normal.h>
#include <grub/file.h>
#include <grub/kernel.h>
-#include <grub/gzio.h>
#include <grub/i18n.h>
/*
@@ -229,7 +228,7 @@
/* Using fd_mo and not another variable because
it's needed for grub_gettext_get_info. */
- fd_mo = grub_gzfile_open (filename, 1);
+ fd_mo = grub_file_open (filename);
grub_errno = GRUB_ERR_NONE;
if (!fd_mo)
diff -urBN orig//experimental/include/grub/err.h transparentio//experimental/include/grub/err.h
--- orig//experimental/include/grub/err.h 2010-02-16 01:43:03.835943739 +0100
+++ transparentio//experimental/include/grub/err.h 2010-02-28 20:54:17.251005185 +0100
@@ -50,7 +50,7 @@
GRUB_ERR_BAD_FONT,
GRUB_ERR_NOT_IMPLEMENTED_YET,
GRUB_ERR_SYMLINK_LOOP,
- GRUB_ERR_BAD_GZIP_DATA,
+ GRUB_ERR_BAD_IOFILTER_DATA,
GRUB_ERR_MENU,
GRUB_ERR_TIMEOUT,
GRUB_ERR_IO,
diff -urBN orig//experimental/include/grub/file.h transparentio//experimental/include/grub/file.h
--- orig//experimental/include/grub/file.h 2010-02-16 01:43:03.843945875 +0100
+++ transparentio//experimental/include/grub/file.h 2010-02-28 21:12:26.000000000 +0100
@@ -39,6 +39,9 @@
/* The file size. */
grub_off_t size;
+ /* If underlying filesystem is not easly seekable. */
+ int not_easly_seekable;
+
/* Filesystem-specific data. */
void *data;
@@ -48,6 +51,26 @@
};
typedef struct grub_file *grub_file_t;
+/* The io filter structure. */
+struct grub_io_filter
+{
+ struct grub_io_filter *next;
+ char *name;
+ int prio;
+ grub_file_t (*grub_io_open) (grub_file_t file);
+};
+typedef struct grub_io_filter *grub_io_filter_t;
+
+/* Register io filter. */
+void EXPORT_FUNC(grub_io_register) (grub_io_filter_t filter);
+
+/* Unregister io filter. */
+void EXPORT_FUNC(grub_io_unregister) (grub_io_filter_t filter);
+
+/* Disable selected filter for next opened file. Last parameter must be "".
+ * Disable all for only "". */
+void EXPORT_FUNC(grub_io_filter_disable) (char *filter_name, ...);
+
/* Get a device name from NAME. */
char *EXPORT_FUNC(grub_file_get_device_name) (const char *name);
diff -urBN orig//experimental/include/grub/gzio.h transparentio//experimental/include/grub/gzio.h
--- orig//experimental/include/grub/gzio.h 2010-02-16 01:43:03.896944801 +0100
+++ transparentio//experimental/include/grub/gzio.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,28 +0,0 @@
-/* gzio.h - prototypes for gzio */
-/*
- * GRUB -- GRand Unified Bootloader
- * Copyright (C) 2005,2007 Free Software Foundation, Inc.
- *
- * 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/>.
- */
-
-#ifndef GRUB_GZIO_H
-#define GRUB_GZIO_H 1
-
-#include <grub/file.h>
-
-grub_file_t grub_gzio_open (grub_file_t io, int transparent);
-grub_file_t grub_gzfile_open (const char *name, int transparent);
-
-#endif /* ! GRUB_GZIO_H */
diff -urBN orig//experimental/io/gzio.c transparentio//experimental/io/gzio.c
--- orig//experimental/io/gzio.c 2010-02-16 01:43:03.896944801 +0100
+++ transparentio//experimental/io/gzio.c 2010-02-25 21:33:11.000000000 +0100
@@ -40,7 +40,9 @@
#include <grub/misc.h>
#include <grub/fs.h>
#include <grub/file.h>
-#include <grub/gzio.h>
+#include <grub/dl.h>
+
+/*grub_file_t grub_gzio_open (grub_file_t io);*/
/*
* Window Size
@@ -173,7 +175,7 @@
grub_uint8_t os_type;
} hdr;
grub_uint16_t extra_len;
- grub_uint32_t orig_len;
+ grub_uint32_t orig_len = (grub_uint32_t)(-1);
grub_gzio_t gzio = file->data;
if (grub_file_tell (gzio->file) != 0)
@@ -206,19 +208,22 @@
|| ((hdr.flags & ORIG_NAME) && eat_field (gzio->file, -1))
|| ((hdr.flags & COMMENT) && eat_field (gzio->file, -1)))
{
- grub_error (GRUB_ERR_BAD_GZIP_DATA, "unsupported gzip format");
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA, "unsupported gzip format");
return 0;
}
gzio->data_offset = grub_file_tell (gzio->file);
- grub_file_seek (gzio->file, grub_file_size (gzio->file) - 4);
+ if (!gzio->file->not_easly_seekable)
+ {
+ grub_file_seek (gzio->file, grub_file_size (gzio->file) - 4);
- if (grub_file_read (gzio->file, &orig_len, 4) != 4)
- {
- grub_error (GRUB_ERR_BAD_FILE_TYPE, "unsupported gzip format");
- return 0;
- }
+ if (grub_file_read (gzio->file, &orig_len, 4) != 4)
+ {
+ grub_error (GRUB_ERR_BAD_FILE_TYPE, "unsupported gzip format");
+ return 0;
+ }
+ }
/* FIXME: this does not handle files whose original size is over 4GB.
But how can we know the real original size? */
@@ -644,7 +649,7 @@
{
if (e == 99)
{
- grub_error (GRUB_ERR_BAD_GZIP_DATA,
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA,
"an unused code found");
return 1;
}
@@ -683,7 +688,7 @@
{
if (e == 99)
{
- grub_error (GRUB_ERR_BAD_GZIP_DATA,
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA,
"an unused code found");
return 1;
}
@@ -769,7 +774,7 @@
DUMPBITS (16);
NEEDBITS (16);
if (gzio->block_len != (int) ((~b) & 0xffff))
- grub_error (GRUB_ERR_BAD_GZIP_DATA,
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA,
"the length of a stored block does not match");
DUMPBITS (16);
@@ -803,7 +808,7 @@
if (huft_build (l, 288, 257, cplens, cplext, &gzio->tl, &gzio->bl) != 0)
{
if (grub_errno == GRUB_ERR_NONE)
- grub_error (GRUB_ERR_BAD_GZIP_DATA,
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA,
"failed in building a Huffman code table");
return;
}
@@ -815,7 +820,7 @@
if (huft_build (l, 30, 0, cpdist, cpdext, &gzio->td, &gzio->bd) > 1)
{
if (grub_errno == GRUB_ERR_NONE)
- grub_error (GRUB_ERR_BAD_GZIP_DATA,
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA,
"failed in building a Huffman code table");
huft_free (gzio->tl);
gzio->tl = 0;
@@ -862,7 +867,7 @@
DUMPBITS (4);
if (nl > 286 || nd > 30)
{
- grub_error (GRUB_ERR_BAD_GZIP_DATA, "too much data");
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA, "too much data");
return;
}
@@ -880,7 +885,7 @@
gzio->bl = 7;
if (huft_build (ll, 19, 19, NULL, NULL, &gzio->tl, &gzio->bl) != 0)
{
- grub_error (GRUB_ERR_BAD_GZIP_DATA,
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA,
"failed in building a Huffman code table");
return;
}
@@ -904,7 +909,7 @@
DUMPBITS (2);
if ((unsigned) i + j > n)
{
- grub_error (GRUB_ERR_BAD_GZIP_DATA, "too many codes found");
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA, "too many codes found");
return;
}
while (j--)
@@ -917,7 +922,7 @@
DUMPBITS (3);
if ((unsigned) i + j > n)
{
- grub_error (GRUB_ERR_BAD_GZIP_DATA, "too many codes found");
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA, "too many codes found");
return;
}
while (j--)
@@ -932,7 +937,7 @@
DUMPBITS (7);
if ((unsigned) i + j > n)
{
- grub_error (GRUB_ERR_BAD_GZIP_DATA, "too many codes found");
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA, "too many codes found");
return;
}
while (j--)
@@ -954,7 +959,7 @@
gzio->bl = lbits;
if (huft_build (ll, nl, 257, cplens, cplext, &gzio->tl, &gzio->bl) != 0)
{
- grub_error (GRUB_ERR_BAD_GZIP_DATA,
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA,
"failed in building a Huffman code table");
return;
}
@@ -963,7 +968,7 @@
{
huft_free (gzio->tl);
gzio->tl = 0;
- grub_error (GRUB_ERR_BAD_GZIP_DATA,
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA,
"failed in building a Huffman code table");
return;
}
@@ -1039,7 +1044,7 @@
}
if (gzio->block_type > INFLATE_DYNAMIC)
- grub_error (GRUB_ERR_BAD_GZIP_DATA,
+ grub_error (GRUB_ERR_BAD_IOFILTER_DATA,
"unknown block type %d", gzio->block_type);
if (grub_errno != GRUB_ERR_NONE)
@@ -1111,8 +1116,8 @@
/* Open a new decompressing object on the top of IO. If TRANSPARENT is true,
even if IO does not contain data compressed by gzip, return a valid file
object. Note that this function won't close IO, even if an error occurs. */
-grub_file_t
-grub_gzio_open (grub_file_t io, int transparent)
+static grub_file_t
+grub_gzio_open (grub_file_t io)
{
grub_file_t file;
grub_gzio_t gzio = 0;
@@ -1135,6 +1140,7 @@
file->data = gzio;
file->read_hook = 0;
file->fs = &grub_gzio_fs;
+ file->not_easly_seekable = 1;
if (! test_header (file))
{
@@ -1142,32 +1148,6 @@
grub_free (file);
grub_file_seek (io, 0);
- if (grub_errno == GRUB_ERR_BAD_FILE_TYPE && transparent)
- {
- grub_errno = GRUB_ERR_NONE;
- return io;
- }
- else
- return 0;
- }
-
- return file;
-}
-
-/* This is similar to grub_gzio_open, but takes a file name as an argument. */
-grub_file_t
-grub_gzfile_open (const char *name, int transparent)
-{
- grub_file_t io, file;
-
- io = grub_file_open (name);
- if (! io)
- return 0;
-
- file = grub_gzio_open (io, transparent);
- if (! file)
- {
- grub_file_close (io);
return 0;
}
@@ -1237,8 +1217,6 @@
return grub_errno;
}
-\f
-
static struct grub_fs grub_gzio_fs =
{
.name = "gzio",
@@ -1249,3 +1227,21 @@
.label = 0,
.next = 0
};
+
+static struct grub_io_filter grub_gzio_filter = {
+ .next = 0,
+ .name = "gzio",
+ .prio = 1,
+ .grub_io_open = grub_gzio_open
+};
+
+
+GRUB_MOD_INIT (gzio)
+{
+ grub_io_register (&grub_gzio_filter);
+}
+
+GRUB_MOD_FINI (gzio)
+{
+ grub_io_unregister (&grub_gzio_filter);
+}
diff -urBN orig//experimental/kern/elf.c transparentio//experimental/kern/elf.c
--- orig//experimental/kern/elf.c 2010-02-16 01:43:03.831946861 +0100
+++ transparentio//experimental/kern/elf.c 2010-02-28 20:54:17.259003968 +0100
@@ -21,7 +21,6 @@
#include <grub/elf.h>
#include <grub/elfload.h>
#include <grub/file.h>
-#include <grub/gzio.h>
#include <grub/misc.h>
#include <grub/mm.h>
@@ -95,7 +94,7 @@
grub_file_t file;
grub_elf_t elf;
- file = grub_gzfile_open (name, 1);
+ file = grub_file_open (name);
if (! file)
return 0;
diff -urBN orig//experimental/kern/file.c transparentio//experimental/kern/file.c
--- orig//experimental/kern/file.c 2010-02-16 01:43:03.843945875 +0100
+++ transparentio//experimental/kern/file.c 2010-02-28 20:25:23.000000000 +0100
@@ -23,6 +23,77 @@
#include <grub/mm.h>
#include <grub/fs.h>
#include <grub/device.h>
+#include <grub/list.h>
+#include <stdarg.h>
+
+/* Registered filters list. */
+static grub_io_filter_t grub_io_filter_list = NULL;
+
+void
+grub_io_register(grub_io_filter_t filter)
+{
+ grub_prio_list_insert (GRUB_AS_PRIO_LIST_P (&grub_io_filter_list),
+ GRUB_AS_PRIO_LIST (filter));
+}
+
+void
+grub_io_unregister(grub_io_filter_t filter)
+{
+ grub_prio_list_remove (GRUB_AS_PRIO_LIST_P (&grub_io_filter_list),
+ GRUB_AS_PRIO_LIST (filter));
+}
+
+static int
+disable_filter (grub_list_t item)
+{
+ grub_io_filter_t filter = (grub_io_filter_t)item;
+ filter->prio &= ~GRUB_PRIO_LIST_FLAG_ACTIVE;
+ return 0;
+}
+
+static int
+enable_filter (grub_list_t item)
+{
+ grub_io_filter_t filter = (grub_io_filter_t)item;
+ filter->prio |= GRUB_PRIO_LIST_FLAG_ACTIVE;
+ return 0;
+}
+
+static int
+is_filter_enabled (grub_list_t item)
+{
+ grub_io_filter_t filter = (grub_io_filter_t)item;
+ return (filter->prio & GRUB_PRIO_LIST_FLAG_ACTIVE);
+}
+
+void
+grub_io_filter_disable (char *filter_name, ...)
+{
+ if (grub_strcmp (filter_name, "") == 0)
+ {
+ grub_list_iterate (GRUB_AS_NAMED_LIST (grub_io_filter_list),
+ disable_filter);
+ return;
+ }
+
+ grub_io_filter_t filter;
+ char *fname = filter_name;
+
+ va_list ap;
+ va_start (ap, filter_name);
+
+ while (grub_strcmp (fname, "") != 0)
+ {
+ filter = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_io_filter_list),
+ fname);
+ if (! filter)
+ disable_filter (GRUB_AS_PRIO_LIST (filter));
+
+ fname = va_arg (ap, char*);
+ }
+
+ va_end (ap);
+}
/* Get the device part of the filename NAME. It is enclosed by parentheses. */
char *
@@ -94,6 +165,32 @@
if ((file->fs->open) (file, file_name) != GRUB_ERR_NONE)
goto fail;
+ /* Check available filters. */
+ grub_file_t ffile;
+ grub_io_filter_t filter = grub_io_filter_list;
+ while (filter)
+ {
+ if (is_filter_enabled (GRUB_AS_PRIO_LIST (filter)))
+ {
+ ffile = filter->grub_io_open (file);
+ if (ffile)
+ {
+ file = ffile;
+ break;
+ }
+
+ if (grub_errno != GRUB_ERR_BAD_FILE_TYPE)
+ goto fail;
+ }
+ else
+ {
+ enable_filter (GRUB_AS_PRIO_LIST (filter));
+ }
+
+ filter = filter->next;
+ }
+
+ grub_errno = GRUB_ERR_NONE;
return file;
fail:
diff -urBN orig//experimental/loader/i386/bsd.c transparentio//experimental/loader/i386/bsd.c
--- orig//experimental/loader/i386/bsd.c 2010-02-16 01:43:03.747944543 +0100
+++ transparentio//experimental/loader/i386/bsd.c 2010-02-28 20:54:17.259003968 +0100
@@ -30,7 +30,6 @@
#include <grub/elfload.h>
#include <grub/env.h>
#include <grub/misc.h>
-#include <grub/gzio.h>
#include <grub/aout.h>
#include <grub/command.h>
#include <grub/extcmd.h>
@@ -904,7 +903,7 @@
goto fail;
}
- file = grub_gzfile_open (argv[0], 1);
+ file = grub_file_open (argv[0]);
if (!file)
goto fail;
@@ -970,7 +969,7 @@
if (err)
return err;
- file = grub_gzfile_open (argv[0], 1);
+ file = grub_file_open (argv[0]);
if (! file)
return grub_errno;
@@ -1086,7 +1085,7 @@
goto fail;
}
- file = grub_gzfile_open (argv[0], 1);
+ file = grub_file_open (argv[0]);
if ((!file) || (!file->size))
goto fail;
@@ -1191,7 +1190,7 @@
return 0;
}
- file = grub_gzfile_open (argv[0], 1);
+ file = grub_file_open (argv[0]);
if ((!file) || (!file->size))
goto fail;
@@ -1257,7 +1256,7 @@
return 0;
}
- file = grub_gzfile_open (argv[0], 1);
+ file = grub_file_open (argv[0]);
if (!file)
return grub_errno;
if (!file->size)
diff -urBN orig//experimental/loader/i386/multiboot.c transparentio//experimental/loader/i386/multiboot.c
--- orig//experimental/loader/i386/multiboot.c 2010-02-16 01:43:03.996945519 +0100
+++ transparentio//experimental/loader/i386/multiboot.c 2010-02-28 20:54:17.263005316 +0100
@@ -39,7 +39,6 @@
#include <grub/dl.h>
#include <grub/mm.h>
#include <grub/misc.h>
-#include <grub/gzio.h>
#include <grub/env.h>
#include <grub/i386/relocator.h>
#include <grub/video.h>
@@ -154,7 +153,7 @@
goto fail;
}
- file = grub_gzfile_open (argv[0], 1);
+ file = grub_file_open (argv[0]);
if (! file)
{
grub_error (GRUB_ERR_BAD_ARGUMENT, "couldn't open file");
@@ -305,7 +304,7 @@
goto fail;
}
- file = grub_gzfile_open (argv[0], 1);
+ file = grub_file_open (argv[0]);
if (! file)
goto fail;
diff -urBN orig//experimental/loader/i386/xnu.c transparentio//experimental/loader/i386/xnu.c
--- orig//experimental/loader/i386/xnu.c 2010-02-16 01:43:04.123948020 +0100
+++ transparentio//experimental/loader/i386/xnu.c 2010-02-28 20:54:17.263005316 +0100
@@ -31,7 +31,6 @@
#include <grub/charset.h>
#include <grub/term.h>
#include <grub/command.h>
-#include <grub/gzio.h>
#include <grub/bitmap_scale.h>
#include <grub/i18n.h>
@@ -536,7 +535,7 @@
if (argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
- file = grub_gzfile_open (args[0], 1);
+ file = grub_file_open (args[0]);
if (! file)
return grub_error (GRUB_ERR_FILE_NOT_FOUND,
"couldn't load device-propertie dump");
diff -urBN orig//experimental/loader/macho.c transparentio//experimental/loader/macho.c
--- orig//experimental/loader/macho.c 2010-02-16 01:43:03.980946274 +0100
+++ transparentio//experimental/loader/macho.c 2010-02-28 20:54:17.263005316 +0100
@@ -26,7 +26,6 @@
#include <grub/cpu/macho.h>
#include <grub/machoload.h>
#include <grub/file.h>
-#include <grub/gzio.h>
#include <grub/misc.h>
#include <grub/mm.h>
@@ -149,7 +148,7 @@
grub_file_t file;
grub_macho_t macho;
- file = grub_gzfile_open (name, 1);
+ file = grub_file_open (name);
if (! file)
return 0;
diff -urBN orig//experimental/loader/multiboot_loader.c transparentio//experimental/loader/multiboot_loader.c
--- orig//experimental/loader/multiboot_loader.c 2010-02-16 01:43:04.000945470 +0100
+++ transparentio//experimental/loader/multiboot_loader.c 2010-02-28 20:54:17.263005316 +0100
@@ -24,7 +24,6 @@
#include <grub/dl.h>
#include <grub/mm.h>
#include <grub/misc.h>
-#include <grub/gzio.h>
#include <grub/command.h>
#include <grub/i18n.h>
@@ -74,7 +73,7 @@
goto fail;
}
- file = grub_gzfile_open (argv[0], 1);
+ file = grub_file_open (argv[0]);
if (! file)
{
grub_error (GRUB_ERR_BAD_ARGUMENT, "couldn't open file");
diff -urBN orig//experimental/loader/sparc64/ieee1275/linux.c transparentio//experimental/loader/sparc64/ieee1275/linux.c
--- orig//experimental/loader/sparc64/ieee1275/linux.c 2010-02-16 01:43:03.944945603 +0100
+++ transparentio//experimental/loader/sparc64/ieee1275/linux.c 2010-02-28 20:54:17.263005316 +0100
@@ -25,7 +25,6 @@
#include <grub/misc.h>
#include <grub/ieee1275/ieee1275.h>
#include <grub/machine/loader.h>
-#include <grub/gzio.h>
#include <grub/command.h>
#include <grub/i18n.h>
@@ -306,7 +305,7 @@
goto out;
}
- file = grub_gzfile_open (argv[0], 1);
+ file = grub_file_open (argv[0]);
if (!file)
goto out;
diff -urBN orig//experimental/loader/xnu.c transparentio//experimental/loader/xnu.c
--- orig//experimental/loader/xnu.c 2010-02-16 01:43:04.123948020 +0100
+++ transparentio//experimental/loader/xnu.c 2010-02-28 20:54:17.267002751 +0100
@@ -28,7 +28,6 @@
#include <grub/machoload.h>
#include <grub/macho.h>
#include <grub/cpu/macho.h>
-#include <grub/gzio.h>
#include <grub/command.h>
#include <grub/misc.h>
#include <grub/env.h>
@@ -667,7 +666,7 @@
macho = 0;
if (infoplistname)
- infoplist = grub_gzfile_open (infoplistname, 1);
+ infoplist = grub_file_open (infoplistname);
else
infoplist = 0;
grub_errno = GRUB_ERR_NONE;
@@ -761,7 +760,7 @@
if (! grub_xnu_heap_size)
return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");
- file = grub_gzfile_open (args[0], 1);
+ file = grub_file_open (args[0]);
if (! file)
return grub_error (GRUB_ERR_FILE_NOT_FOUND,
"couldn't load driver package");
@@ -873,7 +872,7 @@
if (! grub_xnu_heap_size)
return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");
- file = grub_gzfile_open (args[0], 1);
+ file = grub_file_open (args[0]);
if (! file)
return grub_error (GRUB_ERR_FILE_NOT_FOUND,
"couldn't load ramdisk");
@@ -913,7 +912,7 @@
if (binname)
*binname = 0;
- file = grub_gzfile_open (plistname, 1);
+ file = grub_file_open (plistname);
if (! file)
{
grub_file_close (file);
@@ -1170,7 +1169,7 @@
grub_strcpy (binname + grub_strlen (binname), "/");
grub_strcpy (binname + grub_strlen (binname), binsuffix);
grub_dprintf ("xnu", "%s:%s\n", plistname, binname);
- binfile = grub_gzfile_open (binname, 1);
+ binfile = grub_file_open (binname);
if (! binfile)
grub_errno = GRUB_ERR_NONE;
@@ -1208,7 +1207,7 @@
/* User explicitly specified plist and binary. */
if (grub_strcmp (args[1], "-") != 0)
{
- binfile = grub_gzfile_open (args[1], 1);
+ binfile = grub_file_open (args[1]);
if (! binfile)
{
grub_error (GRUB_ERR_BAD_OS, "can't open file");
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] transparent file reader
2010-02-28 21:38 ` Szymon Janc
@ 2010-03-14 13:44 ` Vladimir 'φ-coder/phcoder' Serbinenko
0 siblings, 0 replies; 7+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2010-03-14 13:44 UTC (permalink / raw)
To: The development of GNU GRUB
[-- Attachment #1: Type: text/plain, Size: 1792 bytes --]
Szymon Janc wrote:
> Dnia wtorek 16 luty 2010 o 19:16:19 Vladimir 'φ-coder/phcoder' Serbinenko
> napisał(a):
>
>
>> I like the patch however few comments:
>> 1) How are filters ordered?
>> 2) How would I selectively disable a filter. E.g. for hexdump or when
>> payload expects compressed data?
>>
>> +/* Registered filters list. */
>> +static grub_io_filter_t grub_io_filter_list = NULL;
>> +
>> +void grub_io_register(grub_io_filter_t filter)
>> +{
>> + filter->next = grub_io_filter_list;
>> + grub_io_filter_list = filter;
>> +}
>> +
>>
>> list.h can be used for this.
>>
>
> Attached is new version, changes since previous one:
> - use list.h
> - filter registration is priority based
> - filter can be disabled for next open by grub_io_filter_disable()
>
> Interface could be simpler if make it only transparent/non-transparent but
> this is somewhat less flexible. Yet, is it really needed?
>
>
First of all I would prefer not_easily_seekable part to be a separate
patches so it would be easier to pinpoint bugs by bisecting.
+ .prio = 1,
This should be macroifyed e.g
GRUB_IOFILTER_PRIO_COMPRESSOR
grub_io_register, grub_io_unregister and grub_io_filter_disable must be inlined. Last one has to be splitted into grub_io_filter_disable and grub_io_filter_disable_all to avoid special case with "". va_arg in grub_io_filter_disable doesn't justify itself (one can always make 2 calls, especially if function would be inlined
> ------------------------------------------------------------------------
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
--
Regards
Vladimir 'φ-coder/phcoder' Serbinenko
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 293 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2010-03-14 13:44 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-02-16 18:06 [PATCH] transparent file reader Szymon Janc
2010-02-16 18:16 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-02-16 19:12 ` Szymon Janc
2010-02-28 21:38 ` Szymon Janc
2010-03-14 13:44 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-02-16 19:38 ` Seth Goldberg
2010-02-16 20:00 ` Szymon Janc
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.