Hello,

Attached patch adds new flag to file structure.
It should be set by fs on files which cannot be easly seekable.

Also makes gzio respect this flag.

01_fileseek_indent.diff contains indentation fixes only not to blackout 
02_fileseek.diff.

TODO:
should be also set by other fs when necessary (pxe?)

-- 
Szymon K. Janc
szy...@janc.net.pl // GG: 1383435
=== modified file 'include/grub/file.h'
--- include/grub/file.h	2009-11-22 12:50:46 +0000
+++ include/grub/file.h	2010-04-06 19:27:00 +0000
@@ -44,18 +44,18 @@
 
   /* This is called when a sector is read. Used only for a disk device.  */
   void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-		     unsigned offset, unsigned length);
+				      unsigned offset, unsigned length);
 };
 typedef struct grub_file *grub_file_t;
 
 /* Get a device name from NAME.  */
-char *EXPORT_FUNC(grub_file_get_device_name) (const char *name);
+char *EXPORT_FUNC (grub_file_get_device_name) (const char *name);
 
-grub_file_t EXPORT_FUNC(grub_file_open) (const char *name);
-grub_ssize_t EXPORT_FUNC(grub_file_read) (grub_file_t file, void *buf,
-					  grub_size_t len);
-grub_off_t EXPORT_FUNC(grub_file_seek) (grub_file_t file, grub_off_t offset);
-grub_err_t EXPORT_FUNC(grub_file_close) (grub_file_t file);
+grub_file_t EXPORT_FUNC (grub_file_open) (const char *name);
+grub_ssize_t EXPORT_FUNC (grub_file_read) (grub_file_t file, void *buf,
+					   grub_size_t len);
+grub_off_t EXPORT_FUNC (grub_file_seek) (grub_file_t file, grub_off_t offset);
+grub_err_t EXPORT_FUNC (grub_file_close) (grub_file_t file);
 
 static inline grub_off_t
 grub_file_size (const grub_file_t file)

=== modified file 'io/gzio.c'
--- io/gzio.c	2010-02-14 01:10:46 +0000
+++ io/gzio.c	2010-04-06 19:27:12 +0000
@@ -113,18 +113,18 @@
     {
       if (len >= 0)
 	{
-	  if (! (len--))
+	  if (!(len--))
 	    break;
 	}
       else
 	{
-	  if (! ch)
+	  if (!ch)
 	    break;
 	}
     }
   while ((not_retval = grub_file_read (file, &ch, 1)) == 1);
 
-  return ! not_retval;
+  return !not_retval;
 }
 
 
@@ -164,7 +164,8 @@
 static int
 test_header (grub_file_t file)
 {
-  struct {
+  struct
+  {
     grub_uint16_t magic;
     grub_uint8_t method;
     grub_uint8_t flags;
@@ -185,8 +186,7 @@
    *  is a compressed file, and simply mark it as such.
    */
   if (grub_file_read (gzio->file, &hdr, 10) != 10
-      || ((hdr.magic != GZIP_MAGIC)
-	  && (hdr.magic != OLD_GZIP_MAGIC)))
+      || ((hdr.magic != GZIP_MAGIC) && (hdr.magic != OLD_GZIP_MAGIC)))
     {
       grub_error (GRUB_ERR_BAD_FILE_TYPE, "no gzip magic found");
       return 0;
@@ -242,10 +242,10 @@
   uch e;			/* number of extra bits or operation */
   uch b;			/* number of bits in this code or subcode */
   union
-    {
-      ush n;			/* literal, length base, or distance base */
-      struct huft *t;		/* pointer to next level of table */
-    }
+  {
+    ush n;			/* literal, length base, or distance base */
+    struct huft *t;		/* pointer to next level of table */
+  }
   v;
 };
 
@@ -261,28 +261,32 @@
 
 
 /* Tables for deflate from PKZIP's appnote.txt. */
-static unsigned bitorder[] =
-{				/* Order of the bit length code lengths */
-  16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-static ush cplens[] =
-{				/* Copy lengths for literal codes 257..285 */
+static unsigned bitorder[] = {	/* Order of the bit length code lengths */
+  16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
+};
+
+static ush cplens[] = {		/* Copy lengths for literal codes 257..285 */
   3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
-  35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+  35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0
+};
+
 	/* note: see note #13 above about the 258 in this list. */
-static ush cplext[] =
-{				/* Extra bits for literal codes 257..285 */
+static ush cplext[] = {		/* Extra bits for literal codes 257..285 */
   0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
-  3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99};	/* 99==invalid */
-static ush cpdist[] =
-{				/* Copy offsets for distance codes 0..29 */
+  3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99
+};				/* 99==invalid */
+
+static ush cpdist[] = {		/* Copy offsets for distance codes 0..29 */
   1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
   257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
-  8193, 12289, 16385, 24577};
-static ush cpdext[] =
-{				/* Extra bits for distance codes */
+  8193, 12289, 16385, 24577
+};
+
+static ush cpdext[] = {		/* Extra bits for distance codes */
   0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
   7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
-  12, 12, 13, 13};
+  12, 12, 13, 13
+};
 
 
 /*
@@ -357,8 +361,7 @@
    the stream.
  */
 
-static ush mask_bits[] =
-{
+static ush mask_bits[] = {
   0x0000,
   0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
   0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
@@ -522,8 +525,9 @@
 	      z = 1 << j;	/* table entries for j-bit table */
 
 	      /* allocate and link in new table */
-	      q = (struct huft *) grub_malloc ((z + 1) * sizeof (struct huft));
-	      if (! q)
+	      q =
+		(struct huft *) grub_malloc ((z + 1) * sizeof (struct huft));
+	      if (!q)
 		{
 		  if (h)
 		    huft_free (u[0]);
@@ -539,7 +543,7 @@
 		{
 		  x[h] = i;	/* save pattern for backing up */
 		  r.b = (uch) l;	/* bits to dump before this table */
-		  r.e = (uch) (16 + j);		/* bits in this table */
+		  r.e = (uch) (16 + j);	/* bits in this table */
 		  r.v.t = q;	/* pointer to this table */
 		  j = i >> (w - l);	/* (get around Turbo C bug) */
 		  u[h - 1][j] = r;	/* connect to last table */
@@ -552,7 +556,7 @@
 	    r.e = 99;		/* out of values--invalid code */
 	  else if (*p < s)
 	    {
-	      r.e = (uch) (*p < 256 ? 16 : 15);		/* 256 is end-of-block code */
+	      r.e = (uch) (*p < 256 ? 16 : 15);	/* 256 is end-of-block code */
 	      r.v.n = (ush) (*p);	/* simple code is just the value */
 	      p++;		/* one compiler does not like *p++ */
 	    }
@@ -632,11 +636,11 @@
   w = gzio->wp;			/* initialize window position */
 
   /* inflate the coded data */
-  ml = mask_bits[gzio->bl];		/* precompute masks for speed */
+  ml = mask_bits[gzio->bl];	/* precompute masks for speed */
   md = mask_bits[gzio->bd];
   for (;;)			/* do until end of block */
     {
-      if (! gzio->code_state)
+      if (!gzio->code_state)
 	{
 	  NEEDBITS ((unsigned) gzio->bl);
 	  if ((e = (t = gzio->tl + ((unsigned) b & ml))->e) > 16)
@@ -652,7 +656,8 @@
 		e -= 16;
 		NEEDBITS (e);
 	      }
-	    while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16);
+	    while ((e =
+		    (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16);
 	  DUMPBITS (t->b);
 
 	  if (e == 16)		/* then it's a literal */
@@ -727,7 +732,7 @@
 	    }
 	  while (n);
 
-	  if (! n)
+	  if (!n)
 	    gzio->code_state--;
 
 	  /* did we break from the loop too soon? */
@@ -743,7 +748,7 @@
   gzio->bb = b;			/* restore global bit buffer */
   gzio->bk = k;
 
-  return ! gzio->block_len;
+  return !gzio->block_len;
 }
 
 
@@ -1030,7 +1035,7 @@
 
   while (gzio->wp < WSIZE && grub_errno == GRUB_ERR_NONE)
     {
-      if (! gzio->block_len)
+      if (!gzio->block_len)
 	{
 	  if (gzio->last_block)
 	    break;
@@ -1118,11 +1123,11 @@
   grub_gzio_t gzio = 0;
 
   file = (grub_file_t) grub_malloc (sizeof (*file));
-  if (! file)
+  if (!file)
     return 0;
 
   gzio = grub_zalloc (sizeof (*gzio));
-  if (! gzio)
+  if (!gzio)
     {
       grub_free (file);
       return 0;
@@ -1136,7 +1141,7 @@
   file->read_hook = 0;
   file->fs = &grub_gzio_fs;
 
-  if (! test_header (file))
+  if (!test_header (file))
     {
       grub_free (gzio);
       grub_free (file);
@@ -1161,11 +1166,11 @@
   grub_file_t io, file;
 
   io = grub_file_open (name);
-  if (! io)
+  if (!io)
     return 0;
 
   file = grub_gzio_open (io, transparent);
-  if (! file)
+  if (!file)
     {
       grub_file_close (io);
       return 0;
@@ -1236,16 +1241,15 @@
 
   return grub_errno;
 }
-
 
 
-static struct grub_fs grub_gzio_fs =
-  {
-    .name = "gzio",
-    .dir = 0,
-    .open = 0,
-    .read = grub_gzio_read,
-    .close = grub_gzio_close,
-    .label = 0,
-    .next = 0
-  };
+
+static struct grub_fs grub_gzio_fs = {
+  .name = "gzio",
+  .dir = 0,
+  .open = 0,
+  .read = grub_gzio_read,
+  .close = grub_gzio_close,
+  .label = 0,
+  .next = 0
+};

=== modified file 'kern/file.c'
--- kern/file.c	2010-01-03 22:05:07 +0000
+++ kern/file.c	2010-04-06 19:27:19 +0000
@@ -33,14 +33,14 @@
       char *p = grub_strchr (name, ')');
       char *ret;
 
-      if (! p)
+      if (!p)
 	{
 	  grub_error (GRUB_ERR_BAD_FILENAME, "missing `)'");
 	  return 0;
 	}
 
       ret = (char *) grub_malloc (p - name);
-      if (! ret)
+      if (!ret)
 	return 0;
 
       grub_memcpy (ret, name + 1, p - name - 1);
@@ -72,11 +72,11 @@
 
   device = grub_device_open (device_name);
   grub_free (device_name);
-  if (! device)
+  if (!device)
     goto fail;
 
   file = (grub_file_t) grub_zalloc (sizeof (*file));
-  if (! file)
+  if (!file)
     goto fail;
 
   file->device = device;
@@ -87,7 +87,7 @@
   else
     {
       file->fs = grub_fs_probe (device);
-      if (! file->fs)
+      if (!file->fs)
 	goto fail;
     }
 
@@ -96,7 +96,7 @@
 
   return file;
 
- fail:
+fail:
   if (device)
     grub_device_close (device);
 

=== modified file 'include/grub/file.h'
--- include/grub/file.h	2010-04-06 19:28:26 +0000
+++ include/grub/file.h	2010-03-21 23:45:49 +0000
@@ -39,6 +39,9 @@
   /* The file size.  */
   grub_off_t size;
 
+  /* If file is not easly seekable. Should be set by underlying layer.  */
+  int not_easly_seekable;
+
   /* Filesystem-specific data.  */
   void *data;
 
@@ -69,4 +72,10 @@
   return file->offset;
 }
 
+static inline int
+grub_file_seekable (const grub_file_t file)
+{
+  return !file->not_easly_seekable;
+}
+
 #endif /* ! GRUB_FILE_HEADER */

=== modified file 'io/gzio.c'
--- io/gzio.c	2010-04-06 19:28:26 +0000
+++ io/gzio.c	2010-03-31 20:45:40 +0000
@@ -173,6 +173,7 @@
     grub_uint8_t extra_flags;
     grub_uint8_t os_type;
   } hdr;
+
   grub_uint16_t extra_len;
   grub_uint32_t orig_len;
   grub_gzio_t gzio = file->data;
@@ -214,12 +215,14 @@
 
   grub_file_seek (gzio->file, grub_file_size (gzio->file) - 4);
 
-  if (grub_file_read (gzio->file, &orig_len, 4) != 4)
+  if (grub_file_seekable (gzio->file))
     {
-      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?  */
   file->size = grub_le_to_cpu32 (orig_len);
@@ -1140,6 +1143,7 @@
   file->data = gzio;
   file->read_hook = 0;
   file->fs = &grub_gzio_fs;
+  file->not_easly_seekable = 1;
 
   if (!test_header (file))
     {
@@ -1241,7 +1245,6 @@
 
   return grub_errno;
 }
-
 
 
 static struct grub_fs grub_gzio_fs = {

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to