libcdio-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Libcdio-devel] [RFC/PATCH] add multi extent ISO9660 file support to lib


From: Pete Batard
Subject: [Libcdio-devel] [RFC/PATCH] add multi extent ISO9660 file support to libcdio
Date: Wed, 6 Jun 2018 16:45:09 +0100
User-agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.8.0

Hi,

As per a discussion from last August regarding the current lack of support for multi extent in our ISO9660 implementation (See http://lists.gnu.org/archive/html/libcdio-devel/2017-08/threads.html#00001), I would like to propose the following patch, a version of which I have been using in Rufus' version of libcdio for some time, as a starting point for adding support for this feature.

Unfortunately, I wasn't able to submit this proposal in the timeframe for the 2.0 release, which would probably have been the best place to do it, as this introduces breaking changes that are better suited for a "dot" release. However, I suspect that this proposed modification might be something that is better introduced early in the next release cycle (3.0?), so that it should give ample time to sort out issues and get feedback about it from libcdio users.

Technically, the patch boils down to changing the following section from struct iso9660_stat_s:

  lsn_t              lsn;     /**< start logical sector number */
  uint32_t           size;    /**< total size in bytes */
  uint32_t           secsize; /**< number of sectors allocated */

to this:

  uint64_t           size;    /**< total size in bytes */
  uint8_t            extents; /**< number of multiextents */
                     /**v start logical sector number for each extent */
  lsn_t              lsn[ISO_MAX_MULTIEXTENT];
                     /**v size of each extent */
  uint32_t           extsize[ISO_MAX_MULTIEXTENT];
                     /**v number of sectors allocated for each extent */
  uint32_t           secsize[ISO_MAX_MULTIEXTENT];

In other words, because we need to handle entries occupying multiple extents, we must grow the size attribute to a 64-bit value, and then we use static arrays for the attributes that are specific to each extent.

At this stage, to keep things simple, I suggest that a hardcoded limit of ISO_MAX_MULTIEXTENT, currently set to 8, for the maximum number of extents libcdio can deal with should be good enough. This is because I see it unlikely that we'll see people publishing ISO9660 images containing at least one file that is larger than 32 GB for some time.

From there, libcdio based applications processing a statbuf returned by _cdio_list_node_data() will need to either:
- update their code to loop through all the extents
- replace the lsn and secsize attributes in existing code with lsn[0]
  and seczise[0], if they are sure that the ISO9660 image they are
  dealing with doesn't use multi extent files. Also if the code is
  not compatible with the new 64-bit size attribute, they can use
  extsize[0] instead of size.

An example of such changes is illustrated with the applications modified by this proposal in the examples/ directory (option 1) and the test directory (option 2, since we don't have test with multi-extents).

Considering the way libcdio is implemented however, by letting the downstream applications handle LSNs directly, I do not think we have much of any other solution but to also add the requirement for such applications to also handle extents. Either that or we would need to introduce the concept of "virtual" LSNs which, IMO, would probably be convoluted and could make applications break in a manner that would be more difficult to troubleshoot than the direct approach of exposing the extents.

Also, considering that are replacing integer attributes with an arrays of integers, we should be able to rely on the compiler throwing at the very least an explicit conversion warning for any existing code that needs to be updated for the new structure, which hopefully will help make this breaking change more palatable for libcdio users. In most case, the fix is a very straightforward one (add an outer loop for the extents and use that as an extent index for the new array attributes), so, while I am very aware that this proposal, if applied, will push some probably unwanted update effort downstream, that effort should hopefully be minimal.

Finally, I'll conclude with a few last details, in no particular order.

- I created a new git branch that contains this proposal:
http://git.savannah.gnu.org/cgit/libcdio.git/log/?h=pbatard-multiextent
You should be able to test it if you pull from the official repo and then issue 'git checkout pbatard-multiextent' to switch to it.

- I'm not entirely sure that the sector size array is entirely necessary (though it should cover our base in case someone really does create a weird image). However, using a non array attribute would require adding some extra checks, and I preferred to keep things simple.

- Not sure about adding a test for this one, even if I'd like to. There's Thomas' very helpful multiextent compressed ISO image, from:
https://dev.haiku-os.org/raw-attachment/ticket/8473/file_of_4gb.iso.bz2
However, since that image uncompresses to 4 GB, and then we might have to process another 4GB file, it looks like a tricky sale... I did of course conduct some limited testing on multiextent ISOs, for the modified applications, and validated that all the current libcdio tests passed on both Windows/MinGW and Linux, but of course a formal test would be nice.

- On the subject of testing, I had to comment out the 'test_legal_header' line in check_opts.sh as this was failing for me on MinGW32, and is unrelated to this proposal. This is the reason for the additional patch you'll see in pbatard-multiextent. Not exactly sure why it fails, as could manually validate that the output header does contain the sought regexp data. Could be an issue with the 'grep' from MinGW32, or newlines maybe...

- You can also browse the content of this proposal online at:
http://git.savannah.gnu.org/cgit/libcdio.git/commit/?h=pbatard-multiextent&id=c93341a28bba1842d7df89d784951eccc18050ff


Regards,

/Pete
From c93341a28bba1842d7df89d784951eccc18050ff Mon Sep 17 00:00:00 2001
From: Pete Batard <address@hidden>
Date: Tue, 5 Jun 2018 13:42:37 +0100
Subject: [PATCH 1/2] Add support for ISO9660 multi extent files

This *breaking* change alters the iso9660_stat_s struct an requires
any application processing a statbuf returned by _cdio_list_node_data()
to either:
- update their code to loop through the extents
- replace the lsn and secsize attributes in existing code with lsn[0]
  and seczise[0], if they are sure that the ISO9660 image they are
  dealing with doesn't use multi extent files. Also if the code is
  not compatible with the new 64-bit size attribute, they should use
  extsize[0] instead of size.
---
 example/extract.c        |  36 ++++---
 example/isofile.c        |  29 +++--
 example/isofile2.c       |  33 +++---
 example/isolist.c        |  12 ++-
 include/cdio/iso9660.h   |  18 +++-
 lib/iso9660/iso9660_fs.c | 228 +++++++++++++++++++++++----------------
 src/iso-read.c           |  12 +--
 src/util.c               |   8 +-
 test/testisocd.c         |   6 +-
 test/testisocd2.c        |   8 +-
 test/testisocd_joliet.c  |  10 +-
 11 files changed, 223 insertions(+), 177 deletions(-)

diff --git a/example/extract.c b/example/extract.c
index a9f5a313..314f7b5a 100644
--- a/example/extract.c
+++ b/example/extract.c
@@ -174,9 +174,9 @@ static int iso_extract_files(iso9660_t* p_iso, const char 
*psz_path)
   CdioListNode_t *p_entnode;
   iso9660_stat_t *p_statbuf;
   CdioISO9660FileList_t* p_entlist;
-  size_t i;
+  size_t i, j;
   lsn_t lsn;
-  int64_t i_file_length;
+  int64_t i_extent_length;
 
   if ((p_iso == NULL) || (psz_path == NULL))
     return 1;
@@ -210,22 +210,24 @@ static int iso_extract_files(iso9660_t* p_iso, const char 
*psz_path)
         fprintf(stderr, "  Unable to create file\n");
         goto out;
       }
-      i_file_length = p_statbuf->size;
-      for (i = 0; i_file_length > 0; i++) {
-        memset(buf, 0, ISO_BLOCKSIZE);
-        lsn = p_statbuf->lsn + i;
-        if (iso9660_iso_seek_read(p_iso, buf, lsn, 1) != ISO_BLOCKSIZE) {
-          fprintf(stderr, "  Error reading ISO9660 file %s at LSN %lu\n",
-            psz_iso_name, (long unsigned int)lsn);
-          goto out;
-        }
-        fwrite(buf, (size_t)MIN(i_file_length, ISO_BLOCKSIZE), 1, fd);
-        if (ferror(fd)) {
-         fprintf(stderr, "  Error writing file %s: %s\n", psz_iso_name,
-                 strerror(errno));
-          goto out;
+      for (j = 0; j < p_statbuf->extents; j++) {
+        i_extent_length = p_statbuf->extsize[j];
+        for (i = 0; i_extent_length > 0; i++) {
+          memset(buf, 0, ISO_BLOCKSIZE);
+          lsn = p_statbuf->lsn[j] + i;
+          if (iso9660_iso_seek_read(p_iso, buf, lsn, 1) != ISO_BLOCKSIZE) {
+            fprintf(stderr, "  Error reading ISO9660 file %s at LSN %lu\n",
+              psz_iso_name, (long unsigned int)lsn);
+            goto out;
+          }
+          fwrite(buf, (size_t)MIN(i_extent_length, ISO_BLOCKSIZE), 1, fd);
+          if (ferror(fd)) {
+            fprintf(stderr, "  Error writing file %s: %s\n", psz_iso_name,
+              strerror(errno));
+            goto out;
+          }
+          i_extent_length -= ISO_BLOCKSIZE;
         }
-        i_file_length -= ISO_BLOCKSIZE;
       }
       fclose(fd);
       fd = NULL;
diff --git a/example/isofile.c b/example/isofile.c
index bcfe06a5..0efb8056 100644
--- a/example/isofile.c
+++ b/example/isofile.c
@@ -67,7 +67,7 @@ main(int argc, const char *argv[])
 {
   iso9660_stat_t *p_statbuf;
   FILE *p_outfd;
-  int i;
+  int i, j;
   char const *psz_image;
   char const *psz_fname;
   iso9660_t *p_iso;
@@ -115,29 +115,26 @@ main(int argc, const char *argv[])
     }
 
   /* Copy the blocks from the ISO-9660 filesystem to the local filesystem. */
-  {
-    const unsigned int i_blocks = CEILING(p_statbuf->size, ISO_BLOCKSIZE);
-    for (i = 0; i < i_blocks ; i++) 
-    {
+  for (j = 0; j < p_statbuf->extents; j++) {
+    const unsigned int i_blocks = CEILING(p_statbuf->extsize[j], 
ISO_BLOCKSIZE);
+    for (i = 0; i < i_blocks ; i++) {
       char buf[ISO_BLOCKSIZE];
-      const lsn_t lsn = p_statbuf->lsn + i;
+      const lsn_t lsn = p_statbuf->lsn[j] + i;
 
       memset (buf, 0, ISO_BLOCKSIZE);
-      
-      if ( ISO_BLOCKSIZE != iso9660_iso_seek_read (p_iso, buf, lsn, 1) )
-      {
+
+      if ( ISO_BLOCKSIZE != iso9660_iso_seek_read (p_iso, buf, lsn, 1) ) {
        fprintf(stderr, "Error reading ISO 9660 file %s at LSN %lu\n",
                psz_fname, (long unsigned int) lsn);
        my_exit(4);
       }
-      
+
       fwrite (buf, ISO_BLOCKSIZE, 1, p_outfd);
-      
-      if (ferror (p_outfd))
-       {
-         perror ("fwrite()");
-         my_exit(5);
-       }
+
+      if (ferror (p_outfd)) {
+       perror ("fwrite()");
+       my_exit(5);
+      }
     }
   }
   
diff --git a/example/isofile2.c b/example/isofile2.c
index 7148f2fb..3c16c300 100644
--- a/example/isofile2.c
+++ b/example/isofile2.c
@@ -79,7 +79,7 @@ main(int argc, const char *argv[])
 {
   iso9660_stat_t *p_statbuf;
   FILE *p_outfd;
-  int i;
+  int i, j;
   char const *psz_image;
   char const *psz_fname;
   char translated_name[256];
@@ -135,28 +135,27 @@ main(int argc, const char *argv[])
     }
 
   /* Copy the blocks from the ISO-9660 filesystem to the local filesystem. */
-  {
-    const unsigned int i_blocks = CEILING(p_statbuf->size, ISO_BLOCKSIZE);
+  for (j = 0; j < p_statbuf->extents; j++) {
+    const unsigned int i_blocks = CEILING(p_statbuf->extsize[j], 
ISO_BLOCKSIZE);
     for (i = 0; i < i_blocks; i ++) {
-       char buf[ISO_BLOCKSIZE];
-       const lsn_t lsn = p_statbuf->lsn + i;
+      char buf[ISO_BLOCKSIZE];
+      const lsn_t lsn = p_statbuf->lsn[j] + i;
 
-       memset (buf, 0, ISO_BLOCKSIZE);
+      memset (buf, 0, ISO_BLOCKSIZE);
 
-       if ( 0 != cdio_read_data_sectors (p_cdio, buf, lsn, ISO_BLOCKSIZE, 1) )
-         {
-           fprintf(stderr, "Error reading ISO 9660 file at lsn %lu\n",
-                   (long unsigned int) p_statbuf->lsn);
-           my_exit(4);
-         }
+      if ( 0 != cdio_read_data_sectors (p_cdio, buf, lsn, ISO_BLOCKSIZE, 1) ) {
+       fprintf(stderr, "Error reading ISO 9660 file at lsn %lu\n",
+               (long unsigned int) lsn);
+       my_exit(4);
+      }
 
-       fwrite (buf, ISO_BLOCKSIZE, 1, p_outfd);
+      fwrite (buf, ISO_BLOCKSIZE, 1, p_outfd);
 
-       if (ferror (p_outfd)) {
-           perror ("fwrite()");
-           my_exit(5);
-       }
+      if (ferror (p_outfd)) {
+       perror ("fwrite()");
+       my_exit(5);
       }
+    }
   }
 
 
diff --git a/example/isolist.c b/example/isolist.c
index 1168250b..94b7a38a 100644
--- a/example/isolist.c
+++ b/example/isolist.c
@@ -101,19 +101,21 @@ main(int argc, const char *argv[])
   if (p_entlist) {
     _CDIO_LIST_FOREACH (p_entnode, p_entlist)
     {
+      int i;
       char filename[4096];
       iso9660_stat_t *p_statbuf =
        (iso9660_stat_t *) _cdio_list_node_data (p_entnode);
       iso9660_name_translate(p_statbuf->filename, filename);
-      printf ("%s [LSN %6d] %8u %s%s\n",
-             _STAT_DIR == p_statbuf->type ? "d" : "-",
-             p_statbuf->lsn, p_statbuf->size, psz_path, filename);
+      for (i = 0; i < p_statbuf->extents; i++) {
+       printf ("%s [LSN %6d] %8u %s%s\n",
+               _STAT_DIR == p_statbuf->type ? "d" : "-",
+               p_statbuf->lsn[i], p_statbuf->extsize[i], psz_path, filename);
+      }
     }
 
-   iso9660_filelist_free(p_entlist);
+    iso9660_filelist_free(p_entlist);
   }
 
-
   iso9660_close(p_iso);
   return 0;
 }
diff --git a/include/cdio/iso9660.h b/include/cdio/iso9660.h
index c653cdb8..ce28deb0 100644
--- a/include/cdio/iso9660.h
+++ b/include/cdio/iso9660.h
@@ -156,6 +156,9 @@ extern enum iso_vd_enum_s {
 /*! \brief Maximum number of characters in a volume-set id. */
 #define ISO_MAX_VOLUMESET_ID 128
 
+/*! \brief Maximum number of multi file extent licdio supports. */
+#define ISO_MAX_MULTIEXTENT 8
+
 /*! String inside frame which identifies an ISO 9660 filesystem. This
     string is the "id" field of an iso9660_pvd_t or an iso9660_svd_t.
 */
@@ -529,17 +532,22 @@ typedef CdioList_t CdioISO9660DirList_t;
 */
 struct iso9660_stat_s { /* big endian!! */
 
- iso_rock_statbuf_t rr;              /**< Rock Ridge-specific fields  */
+  iso_rock_statbuf_t rr;              /**< Rock Ridge-specific fields  */
 
   struct tm          tm;              /**< time on entry - FIXME merge with
                                          one of entries above, like ctime? */
-  lsn_t              lsn;             /**< start logical sector number */
-  uint32_t           size;            /**< total size in bytes */
-  uint32_t           secsize;         /**< number of sectors allocated */
+  uint64_t           size;            /**< total size in bytes */
+  uint8_t            extents;         /**< number of multiextents */
+                     /**v start logical sector number for each extent */
+  lsn_t              lsn[ISO_MAX_MULTIEXTENT];
+                     /**v size of each extent */
+  uint32_t           extsize[ISO_MAX_MULTIEXTENT];
+                     /**v number of sectors allocated for each extent */
+  uint32_t           secsize[ISO_MAX_MULTIEXTENT];
   iso9660_xa_t       xa;              /**< XA attributes */
   enum { _STAT_FILE = 1, _STAT_DIR = 2 } type;
   bool               b_xa;
-  char         filename[EMPTY_ARRAY_SIZE]; /**< filename */
+  char               filename[EMPTY_ARRAY_SIZE];    /**< filename */
 };
 
 /** A mask used in iso9660_ifs_read_vd which allows what kinds
diff --git a/lib/iso9660/iso9660_fs.c b/lib/iso9660/iso9660_fs.c
index 33f47711..4e6b3df0 100644
--- a/lib/iso9660/iso9660_fs.c
+++ b/lib/iso9660/iso9660_fs.c
@@ -299,8 +299,8 @@ check_pvd (const iso9660_pvd_t *p_pvd, cdio_log_level_t 
log_level)
 
   if (strncmp (p_pvd->id, ISO_STANDARD_ID, strlen (ISO_STANDARD_ID)))
     {
-      cdio_log (log_level, "unexpected ID encountered (expected `"
-               ISO_STANDARD_ID "', got `%.5s')", p_pvd->id);
+      cdio_log (log_level, "unexpected ID encountered (expected '"
+               ISO_STANDARD_ID "', got '%.5s')", p_pvd->id);
       return false;
     }
   return true;
@@ -777,13 +777,16 @@ iso9660_check_dir_block_end(iso9660_dir_t *p_iso9660_dir, 
unsigned *offset)
 
 
 static iso9660_stat_t *
-_iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, bool_3way_t b_xa,
-                        uint8_t u_joliet_level)
+_iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir,
+                        iso9660_stat_t *last_p_stat,
+                        bool_3way_t b_xa, uint8_t u_joliet_level)
 {
   uint8_t dir_len= iso9660_get_dir_len(p_iso9660_dir);
   iso711_t i_fname;
   unsigned int stat_len;
-  iso9660_stat_t *p_stat = NULL;
+  iso9660_stat_t *p_stat = last_p_stat;
+  char rr_fname[256] = "";
+  int  i_rr_fname;
 
   if (!dir_len) return NULL;
 
@@ -792,7 +795,9 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, 
bool_3way_t b_xa,
   /* .. string in statbuf is one longer than in p_iso9660_dir's listing '\1' */
   stat_len      = sizeof(iso9660_stat_t)+i_fname+2;
 
-  p_stat          = calloc(1, stat_len);
+  /* Reuse multiextent p_stat if not NULL */
+  if (!p_stat)
+    p_stat      = calloc(1, stat_len);
   if (!p_stat)
     {
     cdio_warn("Couldn't calloc(1, %d)", stat_len);
@@ -800,16 +805,25 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, 
bool_3way_t b_xa,
     }
   p_stat->type    = (p_iso9660_dir->file_flags & ISO_DIRECTORY)
     ? _STAT_DIR : _STAT_FILE;
-  p_stat->lsn     = from_733 (p_iso9660_dir->extent);
-  p_stat->size    = from_733 (p_iso9660_dir->size);
-  p_stat->secsize = _cdio_len2blocks (p_stat->size, ISO_BLOCKSIZE);
+  p_stat->lsn[p_stat->extents] = from_733 (p_iso9660_dir->extent);
+  p_stat->extsize[p_stat->extents] = from_733 (p_iso9660_dir->size);
+  p_stat->size += p_stat->extsize[p_stat->extents];
+  p_stat->secsize[p_stat->extents] = _cdio_len2blocks 
(p_stat->extsize[p_stat->extents], ISO_BLOCKSIZE);
   p_stat->rr.b3_rock = dunno; /*FIXME should do based on mask */
   p_stat->b_xa    = false;
 
+  /* Only resolve the full filename when we're not dealing with extent */
+  if ((p_iso9660_dir->file_flags & ISO_MULTIEXTENT) == 0)
   {
-    char rr_fname[256] = "";
-
-    int  i_rr_fname =
+    /* Check if this is the last part of a multiextent file */
+    if (p_stat->extents != 0) {
+      if (strcmp(p_stat->filename, &p_iso9660_dir->filename.str[1]) != 0) {
+       cdio_warn("Warning: Non consecutive multiextent file parts for '%s'", 
p_stat->filename);
+       free(p_stat);
+       return NULL;
+      }
+    }
+    i_rr_fname =
 #ifdef HAVE_ROCK
       get_rock_ridge_filename(p_iso9660_dir, rr_fname, p_stat);
 #else
@@ -856,8 +870,17 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, 
bool_3way_t b_xa,
        strncpy (p_stat->filename, &p_iso9660_dir->filename.str[1], i_fname);
       }
     }
+  } else {
+      /* Use the plain ISO-9660 name when dealing with a multiextent file part 
*/
+      strncpy(p_stat->filename, &p_iso9660_dir->filename.str[1], i_fname);
   }
-
+  if (p_stat->extents >= ISO_MAX_MULTIEXTENT) {
+      cdio_warn("Warning: Too many multiextent file parts for '%s'", 
p_stat->filename);
+      free(p_stat->rr.psz_symlink);
+      free(p_stat);
+      return NULL;
+  }
+  p_stat->extents++;
 
   iso9660_get_dtime(&(p_iso9660_dir->recording_time), true, &(p_stat->tm));
 
@@ -979,8 +1002,8 @@ _fs_stat_root (CdIo_t *p_cdio)
     p_iso9660_dir = &(p_env->pvd.root_directory_record) ;
 #endif
 
-    p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, b_xa,
-                                     p_env->u_joliet_level);
+    p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, NULL,
+                                     b_xa, p_env->u_joliet_level);
     return p_stat;
   }
 
@@ -1000,7 +1023,8 @@ _ifs_stat_root (iso9660_t *p_iso)
   p_iso9660_dir = &(p_iso->pvd.root_directory_record) ;
 #endif
 
-  p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, p_iso->b_xa,
+  p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, NULL,
+                                   p_iso->b_xa,
                                    p_iso->u_joliet_level);
   return p_stat;
 }
@@ -1032,18 +1056,18 @@ _fs_stat_traverse (const CdIo_t *p_cdio, const 
iso9660_stat_t *_root,
 
   cdio_assert (_root->type == _STAT_DIR);
 
-  _dirbuf = calloc(1, _root->secsize * ISO_BLOCKSIZE);
+  _dirbuf = calloc(1, _root->secsize[0] * ISO_BLOCKSIZE);
   if (!_dirbuf)
     {
-    cdio_warn("Couldn't calloc(1, %d)", _root->secsize * ISO_BLOCKSIZE);
+    cdio_warn("Couldn't calloc(1, %d)", _root->secsize[0] * ISO_BLOCKSIZE);
     return NULL;
     }
 
-  if (cdio_read_data_sectors (p_cdio, _dirbuf, _root->lsn, ISO_BLOCKSIZE,
-                             _root->secsize))
+  if (cdio_read_data_sectors (p_cdio, _dirbuf, _root->lsn[0], ISO_BLOCKSIZE,
+                             _root->secsize[0]))
       return NULL;
 
-  while (offset < (_root->secsize * ISO_BLOCKSIZE))
+  while (offset < (_root->secsize[0] * ISO_BLOCKSIZE))
     {
       iso9660_dir_t *p_iso9660_dir = (void *) &_dirbuf[offset];
       iso9660_stat_t *p_iso9660_stat;
@@ -1052,8 +1076,8 @@ _fs_stat_traverse (const CdIo_t *p_cdio, const 
iso9660_stat_t *_root,
       if (iso9660_check_dir_block_end(p_iso9660_dir, &offset))
        continue;
 
-      p_iso9660_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, dunno,
-                                       p_env->u_joliet_level);
+      p_iso9660_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, NULL,
+                                       dunno, p_env->u_joliet_level);
 
       cmp = strcmp(splitpath[0], p_iso9660_stat->filename);
 
@@ -1090,7 +1114,7 @@ _fs_stat_traverse (const CdIo_t *p_cdio, const 
iso9660_stat_t *_root,
       offset += iso9660_get_dir_len(p_iso9660_dir);
     }
 
-  cdio_assert (offset == (_root->secsize * ISO_BLOCKSIZE));
+  cdio_assert (offset == (_root->secsize[0] * ISO_BLOCKSIZE));
 
   /* not found */
   free (_dirbuf);
@@ -1103,11 +1127,12 @@ _fs_iso_stat_traverse (iso9660_t *p_iso, const 
iso9660_stat_t *_root,
 {
   unsigned offset = 0;
   uint8_t *_dirbuf = NULL;
-  int ret;
+  int ret, cmp;
+  iso9660_stat_t *p_stat = NULL;
+  iso9660_dir_t *p_iso9660_dir = NULL;
 
   if (!splitpath[0])
     {
-      iso9660_stat_t *p_stat;
       unsigned int len=sizeof(iso9660_stat_t) + strlen(_root->filename)+1;
       p_stat = calloc(1, len);
       cdio_assert (p_stat != NULL);
@@ -1124,30 +1149,29 @@ _fs_iso_stat_traverse (iso9660_t *p_iso, const 
iso9660_stat_t *_root,
 
   cdio_assert (_root->type == _STAT_DIR);
 
-  _dirbuf = calloc(1, _root->secsize * ISO_BLOCKSIZE);
+  _dirbuf = calloc(1, _root->secsize[0] * ISO_BLOCKSIZE);
   if (!_dirbuf)
     {
-    cdio_warn("Couldn't calloc(1, %d)", _root->secsize * ISO_BLOCKSIZE);
+    cdio_warn("Couldn't calloc(1, %d)", _root->secsize[0] * ISO_BLOCKSIZE);
     return NULL;
     }
 
-  ret = iso9660_iso_seek_read (p_iso, _dirbuf, _root->lsn, _root->secsize);
-  if (ret!=ISO_BLOCKSIZE*_root->secsize) {
+  ret = iso9660_iso_seek_read (p_iso, _dirbuf, _root->lsn[0], 
_root->secsize[0]);
+  if (ret!=ISO_BLOCKSIZE*_root->secsize[0]) {
     free(_dirbuf);
     return NULL;
   }
 
-  while (offset < (_root->secsize * ISO_BLOCKSIZE))
+  for (offset = 0; offset < (_root->secsize[0] * ISO_BLOCKSIZE);
+       offset += iso9660_get_dir_len(p_iso9660_dir))
     {
-      iso9660_dir_t *p_iso9660_dir = (void *) &_dirbuf[offset];
-      iso9660_stat_t *p_stat;
-      int cmp;
+      p_iso9660_dir = (void *) &_dirbuf[offset];
 
       if (iso9660_check_dir_block_end(p_iso9660_dir, &offset))
        continue;
 
-      p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, p_iso->b_xa,
-                                       p_iso->u_joliet_level);
+      p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, p_stat,
+                                       p_iso->b_xa, p_iso->u_joliet_level);
 
       if (!p_stat) {
        cdio_warn("Bad directory information for %s", splitpath[0]);
@@ -1155,6 +1179,10 @@ _fs_iso_stat_traverse (iso9660_t *p_iso, const 
iso9660_stat_t *_root,
        return NULL;
       }
 
+      /* If we have multiextent file parts, loop until the last one */
+      if (p_iso9660_dir->file_flags & ISO_MULTIEXTENT)
+        continue;
+
       cmp = strcmp(splitpath[0], p_stat->filename);
 
       if ( 0 != cmp && 0 == p_iso->u_joliet_level
@@ -1185,11 +1213,10 @@ _fs_iso_stat_traverse (iso9660_t *p_iso, const 
iso9660_stat_t *_root,
        return ret_stat;
       }
       iso9660_stat_free(p_stat);
-
-      offset += iso9660_get_dir_len(p_iso9660_dir);
+      p_stat = NULL;
     }
 
-  cdio_assert (offset == (_root->secsize * ISO_BLOCKSIZE));
+  cdio_assert (offset == (_root->secsize[0] * ISO_BLOCKSIZE));
 
   /* not found */
   free (_dirbuf);
@@ -1354,6 +1381,8 @@ CdioISO9660FileList_t *
 iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[])
 {
   generic_img_private_t *p_env;
+  iso9660_dir_t *p_iso9660_dir;
+  iso9660_stat_t *p_iso9660_stat = NULL;
   iso9660_stat_t *p_stat;
 
   if (!p_cdio)   return NULL;
@@ -1374,38 +1403,43 @@ iso9660_fs_readdir (CdIo_t *p_cdio, const char 
psz_path[])
     uint8_t *_dirbuf = NULL;
     CdioISO9660DirList_t *retval = _cdio_list_new ();
 
-    _dirbuf = calloc(1, p_stat->secsize * ISO_BLOCKSIZE);
+    _dirbuf = calloc(1, p_stat->secsize[0] * ISO_BLOCKSIZE);
     if (!_dirbuf)
       {
-      cdio_warn("Couldn't calloc(1, %d)", p_stat->secsize * ISO_BLOCKSIZE);
+      cdio_warn("Couldn't calloc(1, %d)", p_stat->secsize[0] * ISO_BLOCKSIZE);
       iso9660_stat_free(p_stat);
       iso9660_dirlist_free(retval);
       return NULL;
       }
 
-    if (cdio_read_data_sectors (p_cdio, _dirbuf, p_stat->lsn,
-                               ISO_BLOCKSIZE, p_stat->secsize)) {
+    if (cdio_read_data_sectors (p_cdio, _dirbuf, p_stat->lsn[0],
+                               ISO_BLOCKSIZE, p_stat->secsize[0])) {
       iso9660_stat_free(p_stat);
       iso9660_dirlist_free(retval);
       return NULL;
     }
 
-    while (offset < (p_stat->secsize * ISO_BLOCKSIZE))
+    while (offset < (p_stat->secsize[0] * ISO_BLOCKSIZE))
       {
-       iso9660_dir_t *p_iso9660_dir = (void *) &_dirbuf[offset];
-       iso9660_stat_t *p_iso9660_stat;
+       p_iso9660_dir = (void *) &_dirbuf[offset];
 
        if (iso9660_check_dir_block_end(p_iso9660_dir, &offset))
          continue;
 
-       p_iso9660_stat = _iso9660_dir_to_statbuf(p_iso9660_dir, dunno,
+       p_iso9660_stat = _iso9660_dir_to_statbuf(p_iso9660_dir,
+                                                p_iso9660_stat, dunno,
                                                 p_env->u_joliet_level);
-       _cdio_list_append (retval, p_iso9660_stat);
+       if ((p_iso9660_stat) &&
+           ((p_iso9660_dir->file_flags & ISO_MULTIEXTENT) == 0))
+         {
+           _cdio_list_append (retval, p_iso9660_stat);
+           p_iso9660_stat = NULL;
+         }
 
        offset += iso9660_get_dir_len(p_iso9660_dir);
       }
 
-    cdio_assert (offset == (p_stat->secsize * ISO_BLOCKSIZE));
+    cdio_assert (offset == (p_stat->secsize[0] * ISO_BLOCKSIZE));
 
     free(_dirbuf);
     iso9660_stat_free(p_stat);
@@ -1420,6 +1454,8 @@ iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[])
 CdioISO9660FileList_t *
 iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[])
 {
+  iso9660_dir_t *p_iso9660_dir;
+  iso9660_stat_t *p_iso9660_stat = NULL;
   iso9660_stat_t *p_stat;
 
   if (!p_iso)    return NULL;
@@ -1438,12 +1474,12 @@ iso9660_ifs_readdir (iso9660_t *p_iso, const char 
psz_path[])
     unsigned offset = 0;
     uint8_t *_dirbuf = NULL;
     CdioList_t *retval = _cdio_list_new ();
-    const size_t dirbuf_len = p_stat->secsize * ISO_BLOCKSIZE;
+    const size_t dirbuf_len = p_stat->secsize[0] * ISO_BLOCKSIZE;
 
 
     if (!dirbuf_len)
       {
-        cdio_warn("Invalid directory buffer sector size %u", p_stat->secsize);
+        cdio_warn("Invalid directory buffer sector size %u", 
p_stat->secsize[0]);
        iso9660_stat_free(p_stat);
        _cdio_list_free (retval, true, NULL);
         return NULL;
@@ -1458,7 +1494,7 @@ iso9660_ifs_readdir (iso9660_t *p_iso, const char 
psz_path[])
         return NULL;
       }
 
-    ret = iso9660_iso_seek_read (p_iso, _dirbuf, p_stat->lsn, p_stat->secsize);
+    ret = iso9660_iso_seek_read (p_iso, _dirbuf, p_stat->lsn[0], 
p_stat->secsize[0]);
     if (ret != dirbuf_len)       {
       _cdio_list_free (retval, true, NULL);
       iso9660_stat_free(p_stat);
@@ -1468,21 +1504,21 @@ iso9660_ifs_readdir (iso9660_t *p_iso, const char 
psz_path[])
 
     while (offset < (dirbuf_len))
       {
-       iso9660_dir_t *p_iso9660_dir = (void *) &_dirbuf[offset];
-       iso9660_stat_t *p_iso9660_stat;
+       p_iso9660_dir = (void *) &_dirbuf[offset];
 
        if (iso9660_check_dir_block_end(p_iso9660_dir, &offset))
          continue;
 
-       p_iso9660_stat = _iso9660_dir_to_statbuf(p_iso9660_dir, p_iso->b_xa,
+       p_iso9660_stat = _iso9660_dir_to_statbuf(p_iso9660_dir,
+                                                p_iso9660_stat,
+                                                p_iso->b_xa,
                                                 p_iso->u_joliet_level);
-
-       if (p_iso9660_stat)
-         _cdio_list_append (retval, p_iso9660_stat);
-       else {
-         cdio_warn("Invalid directory stat at offset %lu", (unsigned 
long)offset);
-         break;
-       }
+       if ((p_iso9660_stat) &&
+           ((p_iso9660_dir->file_flags & ISO_MULTIEXTENT) == 0))
+         {
+           _cdio_list_append(retval, p_iso9660_stat);
+           p_iso9660_stat = NULL;
+         }
 
        offset += iso9660_get_dir_len(p_iso9660_dir);
       }
@@ -1530,6 +1566,7 @@ find_lsn_recurse (void *p_image, iso9660_readdir_t 
iso9660_readdir,
       iso9660_stat_t *statbuf = _cdio_list_node_data (entnode);
       const char *psz_filename  = (char *) statbuf->filename;
       unsigned int len = strlen(psz_path) + strlen(psz_filename)+2;
+      size_t extent;
 
       if (*ppsz_full_filename != NULL) free(*ppsz_full_filename);
       *ppsz_full_filename = calloc(1, len);
@@ -1538,25 +1575,26 @@ find_lsn_recurse (void *p_image, iso9660_readdir_t 
iso9660_readdir,
       if (statbuf->type == _STAT_DIR
           && strcmp ((char *) statbuf->filename, ".")
           && strcmp ((char *) statbuf->filename, "..")) {
-       snprintf (*ppsz_full_filename, len, "%s%s/", psz_path, psz_filename);
+        snprintf (*ppsz_full_filename, len, "%s%s/", psz_path, psz_filename);
         _cdio_list_append (dirlist, strdup(*ppsz_full_filename));
       }
 
-      if (statbuf->lsn == lsn) {
-       const unsigned int len2 = 
sizeof(iso9660_stat_t)+strlen(statbuf->filename)+1;
-       iso9660_stat_t *ret_stat = calloc(1, len2);
-       if (!ret_stat)
-         {
-           iso9660_dirlist_free(dirlist);
-           cdio_warn("Couldn't calloc(1, %d)", len2);
-           free(*ppsz_full_filename);
-           *ppsz_full_filename = NULL;
-           return NULL;
-         }
-       memcpy(ret_stat, statbuf, len2);
-        iso9660_filelist_free (entlist);
-       iso9660_dirlist_free(dirlist);
-        return ret_stat;
+      for (extent = 0; extent < statbuf->extents; extent++) {
+        if (statbuf->lsn[extent] == lsn) {
+          const unsigned int len2 = 
sizeof(iso9660_stat_t)+strlen(statbuf->filename)+1;
+          iso9660_stat_t *ret_stat = calloc(1, len2);
+          if (!ret_stat) {
+            iso9660_dirlist_free(dirlist);
+            cdio_warn("Couldn't calloc(1, %d)", len2);
+            free(*ppsz_full_filename);
+            *ppsz_full_filename = NULL;
+            return NULL;
+          }
+          memcpy(ret_stat, statbuf, len2);
+          iso9660_filelist_free (entlist);
+          iso9660_dirlist_free(dirlist);
+          return ret_stat;
+        }
       }
 
     }
@@ -1576,7 +1614,7 @@ find_lsn_recurse (void *p_image, iso9660_readdir_t 
iso9660_readdir,
                                   ppsz_full_filename);
 
       if (NULL != ret_stat) {
-       iso9660_dirlist_free(dirlist);
+        iso9660_dirlist_free(dirlist);
         return ret_stat;
       }
     }
@@ -1736,53 +1774,53 @@ iso_have_rr_traverse (iso9660_t *p_iso, const 
iso9660_stat_t *_root,
 
   cdio_assert (_root->type == _STAT_DIR);
 
-  _dirbuf = calloc(1, _root->secsize * ISO_BLOCKSIZE);
+  _dirbuf = calloc(1, _root->secsize[0] * ISO_BLOCKSIZE);
   if (!_dirbuf)
     {
-    cdio_warn("Couldn't calloc(1, %d)", _root->secsize * ISO_BLOCKSIZE);
+    cdio_warn("Couldn't calloc(1, %d)", _root->secsize[0] * ISO_BLOCKSIZE);
     return dunno;
     }
 
-  ret = iso9660_iso_seek_read (p_iso, _dirbuf, _root->lsn, _root->secsize);
-  if (ret!=ISO_BLOCKSIZE*_root->secsize) {
+  ret = iso9660_iso_seek_read (p_iso, _dirbuf, _root->lsn[0], 
_root->secsize[0]);
+  if (ret!=ISO_BLOCKSIZE*_root->secsize[0]) {
     free(_dirbuf);
     return false;
   }
 
-  while (offset < (_root->secsize * ISO_BLOCKSIZE))
+  while (offset < (_root->secsize[0] * ISO_BLOCKSIZE))
     {
       iso9660_dir_t *p_iso9660_dir = (void *) &_dirbuf[offset];
       iso9660_stat_t *p_stat;
       unsigned int i_last_component = 1;
 
       if (iso9660_check_dir_block_end(p_iso9660_dir, &offset))
-       continue;
+        continue;
 
-      p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, p_iso->b_xa,
+      p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, NULL, p_iso->b_xa,
                                        p_iso->u_joliet_level);
       have_rr = p_stat->rr.b3_rock;
       if ( have_rr != yep) {
-       if (strlen(splitpath[0]) == 0)
-         have_rr = false;
-       else
-         have_rr = iso_have_rr_traverse (p_iso, p_stat, 
&splitpath[i_last_component],
+        if (strlen(splitpath[0]) == 0)
+          have_rr = false;
+        else
+          have_rr = iso_have_rr_traverse (p_iso, p_stat, 
&splitpath[i_last_component],
                                          pu_file_limit);
       }
       free(p_stat);
       if (have_rr != nope) {
-       free (_dirbuf);
-       return have_rr;
+        free (_dirbuf);
+        return have_rr;
       }
 
       offset += iso9660_get_dir_len(p_iso9660_dir);
       *pu_file_limit = (*pu_file_limit)-1;
       if ((*pu_file_limit) == 0) {
-       free (_dirbuf);
-       return dunno;
+        free (_dirbuf);
+        return dunno;
       }
     }
 
-  cdio_assert (offset == (_root->secsize * ISO_BLOCKSIZE));
+  cdio_assert (offset == (_root->secsize[0] * ISO_BLOCKSIZE));
 
   /* not found */
   free (_dirbuf);
diff --git a/src/iso-read.c b/src/iso-read.c
index 86474859..d36ab830 100644
--- a/src/iso-read.c
+++ b/src/iso-read.c
@@ -211,7 +211,7 @@ static int read_iso_file(const char *iso_name, const char 
*src,
                          FILE *outfd, size_t *bytes_written)
 {
   iso9660_stat_t *statbuf;
-  int i;
+  int i, j;
   iso9660_t *iso;
 
   iso = iso9660_open (iso_name);
@@ -239,22 +239,21 @@ static int read_iso_file(const char *iso_name, const char 
*src,
 
 
   /* Copy the blocks from the ISO-9660 filesystem to the local filesystem. */
-  for (i = 0; i < statbuf->size; i += ISO_BLOCKSIZE)
-    {
+  for (j = 0; j < statbuf->extents; j++) {
+    for (i = 0; i < statbuf->extsize[j]; i += ISO_BLOCKSIZE) {
       char buf[ISO_BLOCKSIZE];
 
       memset (buf, 0, ISO_BLOCKSIZE);
 
-      if ( ISO_BLOCKSIZE != iso9660_iso_seek_read (iso, buf, statbuf->lsn
+      if ( ISO_BLOCKSIZE != iso9660_iso_seek_read (iso, buf, statbuf->lsn[j]
                                                    + (i / ISO_BLOCKSIZE),
                                                    1) )
       {
         report(stderr, "Error reading ISO 9660 file at lsn %lu\n",
-               (long unsigned int) statbuf->lsn + (i / ISO_BLOCKSIZE));
+               (long unsigned int) statbuf->lsn[j] + (i / ISO_BLOCKSIZE));
         if (!opts.ignore) return 4;
       }
 
-
       fwrite (buf, ISO_BLOCKSIZE, 1, outfd);
 
       if (ferror (outfd))
@@ -263,6 +262,7 @@ static int read_iso_file(const char *iso_name, const char 
*src,
           return 5;
         }
     }
+  }
   iso9660_close(iso);
 
   *bytes_written = statbuf->size;
diff --git a/src/util.c b/src/util.c
index dde2f40f..9c142620 100644
--- a/src/util.c
+++ b/src/util.c
@@ -488,7 +488,7 @@ print_fs_attrs(iso9660_stat_t *p_statbuf, bool b_rock, bool 
b_xa,
             p_statbuf->rr.st_nlinks,
             p_statbuf->rr.st_uid,
             p_statbuf->rr.st_gid,
-            (long unsigned int) p_statbuf->lsn,
+            (long unsigned int) p_statbuf->lsn[0],
             S_ISLNK(p_statbuf->rr.st_mode)
             ? strlen(p_statbuf->rr.psz_symlink)
             : (unsigned int) p_statbuf->size );
@@ -501,18 +501,18 @@ print_fs_attrs(iso9660_stat_t *p_statbuf, bool b_rock, 
bool b_xa,
             uint16_from_be (p_statbuf->xa.user_id),
             uint16_from_be (p_statbuf->xa.group_id),
             p_statbuf->xa.filenum,
-            (long unsigned int) p_statbuf->lsn );
+            (long unsigned int) p_statbuf->lsn[0] );
 
     if (uint16_from_be(p_statbuf->xa.attributes) & XA_ATTR_MODE2FORM2) {
       report ( stdout, "%9u (%9u)",
-              (unsigned int) p_statbuf->secsize * M2F2_SECTOR_SIZE,
+              (unsigned int) p_statbuf->secsize[0] * M2F2_SECTOR_SIZE,
               (unsigned int) p_statbuf->size );
     } else
       report (stdout, "%9u", (unsigned int) p_statbuf->size);
   } else {
     report ( stdout,"  %c [LSN %6lu] %9u",
             (p_statbuf->type == _STAT_DIR) ? 'd' : '-',
-            (long unsigned int) p_statbuf->lsn,
+            (long unsigned int) p_statbuf->lsn[0],
             (unsigned int) p_statbuf->size );
   }
 
diff --git a/test/testisocd.c b/test/testisocd.c
index 6b1f60b6..686dd011 100644
--- a/test/testisocd.c
+++ b/test/testisocd.c
@@ -99,7 +99,7 @@ main(int argc, const char *argv[])
 
       char buf[ISO_BLOCKSIZE];
       char *psz_path = NULL;
-      const lsn_t i_lsn = p_statbuf->lsn;
+      const lsn_t i_lsn = p_statbuf->lsn[0];
       iso9660_stat_t *p_statbuf2 = iso9660_fs_find_lsn (p_cdio, i_lsn);
       iso9660_stat_t *p_statbuf3 =
        iso9660_fs_find_lsn_with_path (p_cdio, i_lsn, &psz_path);
@@ -107,7 +107,7 @@ main(int argc, const char *argv[])
       const unsigned int statbuf_test_size = 100;
 
       /* Compare the two statbufs. */
-      if (p_statbuf->lsn != p_statbuf2->lsn ||
+      if (p_statbuf->lsn[0] != p_statbuf2->lsn[0] ||
          p_statbuf->size != p_statbuf2->size ||
          p_statbuf->type != p_statbuf2->type) {
          fprintf(stderr, "File stat information between fs_stat and "
@@ -143,7 +143,7 @@ main(int argc, const char *argv[])
       if ( 0 != cdio_read_data_sectors (p_cdio, buf, i_lsn, ISO_BLOCKSIZE, 1) )
        {
          fprintf(stderr, "Error reading ISO 9660 file at lsn %lu\n",
-                 (long unsigned int) p_statbuf->lsn);
+                 (long unsigned int) p_statbuf->lsn[0]);
          rc=7;
        }
     exit:
diff --git a/test/testisocd2.c b/test/testisocd2.c
index a1187764..720e148d 100644
--- a/test/testisocd2.c
+++ b/test/testisocd2.c
@@ -105,13 +105,13 @@ main(int argc, const char *argv[])
       /* Now try getting the statbuf another way */
       char buf[ISO_BLOCKSIZE];
       char *psz_path = NULL;
-      const lsn_t i_lsn = p_statbuf->lsn;
+      const lsn_t i_lsn = p_statbuf->lsn[0];
       iso9660_stat_t *p_statbuf2 = iso9660_ifs_find_lsn (p_iso, i_lsn);
       iso9660_stat_t *p_statbuf3 =
        iso9660_ifs_find_lsn_with_path (p_iso, i_lsn, &psz_path);
 
       /* Compare the two statbufs. */
-      if (p_statbuf->lsn != p_statbuf2->lsn ||
+      if (p_statbuf->lsn[0] != p_statbuf2->lsn[0] ||
          p_statbuf->size != p_statbuf2->size ||
          p_statbuf->type != p_statbuf2->type) {
 
@@ -121,7 +121,7 @@ main(int argc, const char *argv[])
          goto exit;
       }
 
-      if (p_statbuf3->lsn != p_statbuf2->lsn ||
+      if (p_statbuf3->lsn[0] != p_statbuf2->lsn[0] ||
          p_statbuf3->size != p_statbuf2->size ||
          p_statbuf3->type != p_statbuf2->type) {
        rc = 4;
@@ -147,7 +147,7 @@ main(int argc, const char *argv[])
       if ( ISO_BLOCKSIZE != iso9660_iso_seek_read (p_iso, buf, i_lsn, 1) )
        {
          fprintf(stderr, "Error reading ISO 9660 file at lsn %lu\n",
-                 (long unsigned int) p_statbuf->lsn);
+                 (long unsigned int) p_statbuf->lsn[0]);
          rc = 7;
          goto exit;
        }
diff --git a/test/testisocd_joliet.c b/test/testisocd_joliet.c
index 8eedc2f2..f5789360 100644
--- a/test/testisocd_joliet.c
+++ b/test/testisocd_joliet.c
@@ -106,7 +106,7 @@ main(int argc, const char *argv[])
       /* Now try getting the statbuf another way */
       char buf[ISO_BLOCKSIZE];
       char *psz_path = NULL;
-      const lsn_t i_lsn = p_statbuf->lsn;
+      const lsn_t i_lsn = p_statbuf->lsn[0];
       iso9660_stat_t *p_statbuf2 = iso9660_ifs_find_lsn (p_iso, i_lsn);
       iso9660_stat_t *p_statbuf3 =
        iso9660_ifs_find_lsn_with_path (p_iso, i_lsn, &psz_path);
@@ -114,16 +114,16 @@ main(int argc, const char *argv[])
       const unsigned int statbuf_test_size = 100;
 
       /* Compare the two statbufs. */
-      if (p_statbuf->lsn != p_statbuf2->lsn ||
+      if (p_statbuf->lsn[0] != p_statbuf2->lsn[0] ||
          p_statbuf->size != p_statbuf2->size ||
          p_statbuf->type != p_statbuf2->type) {
 
          fprintf(stderr, "File stat information between fs_stat and "
                  "iso9660_ifs_find_lsn isn't the same\n");
          printf("statbuf  lsn: %d, size: %d, type: %d\n",
-                p_statbuf->lsn, p_statbuf->size, p_statbuf->type);
+                p_statbuf->lsn[0], p_statbuf->extsize[0], p_statbuf->type);
          printf("statbuf2 lsn: %d, size: %d, type: %d\n",
-                p_statbuf2->lsn, p_statbuf2->size, p_statbuf2->type);
+                p_statbuf2->lsn[0], p_statbuf2->extsize[0], p_statbuf2->type);
          rc=3;
          goto exit;
       }
@@ -157,7 +157,7 @@ main(int argc, const char *argv[])
       if ( ISO_BLOCKSIZE != iso9660_iso_seek_read (p_iso, buf, i_lsn, 1) )
        {
          fprintf(stderr, "Error reading ISO 9660 file at lsn %lu\n",
-                 (long unsigned int) p_statbuf->lsn);
+                 (long unsigned int) p_statbuf->lsn[0]);
          rc=7;
        }
     exit:
-- 
2.17.0.windows.1


reply via email to

[Prev in Thread] Current Thread [Next in Thread]