[Libburn] libisofs patch (3rd revision)

Todd Kulesza todd@dropline.net
Mon, 23 Feb 2004 00:40:15 -0500


--=-fMZma97fpKrRtkm/7Dmr
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

OK, last patch for tonight, I promise... This one adds support for
writing the directory and file structure.  All that remains is to write
the files themselves and libisofs will be (sort of) functional; it
should be able to write level-1 ISOs, at any rate.  Right now the files
it writes are all of size 0:

root@llyr:/home/fflew# ls -l /mnt/tmp/
total 6
-r-xr-xr-x    1 root     root     0 Feb 23 00:21 anothertest2_txt*
-r-xr-xr-x    1 root     root     0 Feb 23 00:21 anothertest_txt*
dr-xr-xr-x    1 root     root  2048 Feb 23 00:21 folder1/
dr-xr-xr-x    1 root     root  2048 Feb 23 00:21 folder2/
dr-xr-xr-x    1 root     root  2048 Feb 23 00:21 folder3/
-r-xr-xr-x    1 root     root     0 Feb 23 00:21 test_txt*
-r-xr-xr-x    1 root     root     0 Feb 23 00:21
zinstallpkg_0_4_1_i686_1nis_tgz*
root@llyr:/home/fflew#

I've tried to keep the coding style consistent with what already existed
in libisofs.  Let me know if there's anything to clean up or styled
differently.

Todd

On Sun, 2004-02-22 at 17:39, Todd Kulesza wrote:
> Here's another cumulative patch.  It includes all of the changes from my
> last two, plus partial support for writing out directory records. 
> libisofs can finally create ISO images which are successfully detected
> as valid ISO9660 filesystems! (they're completely empty filesystems, but
> still... ;)
> 
> Todd
> 
> On Mon, 2004-02-16 at 01:55, Todd Kulesza wrote:
> > Ignore that last patch--this one goes a step further and includes the
> > ability to write out the Path Tables.  It also fixes what I think was a
> > typo in iso_add_tree_dir() where the parent->children pointer is
> > decremented.  I've fixed this to decrement parent->nchildren instead.  I
> > also patched up the iso_add_tree_dir() function to update the parent
> > pointers for each grandchild node when the child node is reallocated,
> > otherwise the parent pointers get all fucked up every time
> > iso_add_tree_dir() is called.
> > 
> > Damn Ben, you weren't kidding when you said this lib is a beast to hack
> > on :)
> > 
> > Todd
> > 
> > On Sat, 2004-02-14 at 00:06, Todd Kulesza wrote:
> > > The attached patch fixes a small bug in the iso_lsb() function, fixes
> > > get_path_table_size() to calculate the length of the Path Tables
> > > correctly, and adds support for calculating the size of directory
> > > records.  Still can't write ISOs, but getting ever-so-slightly closer...
> > > 
> > > Todd
> > > 
> > > 

--=-fMZma97fpKrRtkm/7Dmr
Content-Disposition: attachment; filename=libisofs.diff
Content-Type: text/x-patch; name=libisofs.diff; charset=UTF-8
Content-Transfer-Encoding: 7bit

? libburn/null.lo
Index: libisofs/tree.c
===================================================================
RCS file: /cvs/burn/burn/libisofs/tree.c,v
retrieving revision 1.6
diff -p -u -r1.6 tree.c
--- libisofs/tree.c	10 Dec 2003 05:45:26 -0000	1.6
+++ libisofs/tree.c	23 Feb 2004 05:33:30 -0000
@@ -76,7 +76,7 @@ iso_tree_add_dir (struct iso_tree_dir **
 {
 	struct iso_tree_dir *parent;
 	struct iso_tree_dir *d;
-	int i;
+	int i, j;
 
 	if (!(dparent && *dparent && name)) return NULL;
 
@@ -90,7 +90,7 @@ iso_tree_add_dir (struct iso_tree_dir **
 
 	if (!iso_tree_dir_set_name (&d, name)) {
 		/* we don't unalloc the end of the array but that's ok :> */
-		parent->children--;
+		parent->nchildren--;
 		d = NULL;
 	} else {
 		d->volume = volume;
@@ -99,8 +99,14 @@ iso_tree_add_dir (struct iso_tree_dir **
 		d->volset = parent->volset;
 	}
 
-	for (i = 0; i < parent->nchildren; ++i)
+	/* since 'parent->children' was set to a new memory location, fix the
+	 * 'parent' references */
+	for (i = 0; i < parent->nchildren; ++i) {
 		*parent->children[i].me = &parent->children[i];
+		for (j = 0; j < parent->children[i].nchildren; ++j) {
+			parent->children[i].children[j].parent = &parent->children[i];
+		}
+	}
 
 	return d->me;
 }
Index: libisofs/tree.h
===================================================================
RCS file: /cvs/burn/burn/libisofs/tree.h,v
retrieving revision 1.6
diff -p -u -r1.6 tree.h
--- libisofs/tree.h	10 Dec 2003 05:45:26 -0000	1.6
+++ libisofs/tree.h	23 Feb 2004 05:33:31 -0000
@@ -58,9 +58,12 @@ struct iso_tree_dir
 	/* the logical block at which the dir will be placed
 	   in the volume */
 	int logical_block;
-	/* XXX not really sure what this is the size of */
+	/* the number of bytes needed to hold the directory record
+	 * for each file and subdirectory of this directory */
 	int size;
-
+	/* the position of the directory in the path table */
+	short position;
+	
 	struct iso_tree_dir *parent;
 
 	struct iso_tree_dir *children;
Index: libisofs/util.c
===================================================================
RCS file: /cvs/burn/burn/libisofs/util.c,v
retrieving revision 1.3
diff -p -u -r1.3 util.c
--- libisofs/util.c	10 Feb 2004 12:45:20 -0000	1.3
+++ libisofs/util.c	23 Feb 2004 05:33:31 -0000
@@ -131,7 +131,7 @@ iso_lsb(unsigned char *buf, int num, int
 	assert (bytes <= sizeof (int));
 
 	for (i = 0; i < bytes; ++i)
-		buf[i] = num << (sizeof (int)-1-i) >> (sizeof (int) - 1) << i;
+		buf[i] = (num >> (8 * i)) & 0xff;
 }
 
 void
Index: libisofs/writer.c
===================================================================
RCS file: /cvs/burn/burn/libisofs/writer.c,v
retrieving revision 1.15
diff -p -u -r1.15 writer.c
--- libisofs/writer.c	10 Feb 2004 12:45:20 -0000	1.15
+++ libisofs/writer.c	23 Feb 2004 05:33:32 -0000
@@ -10,6 +10,13 @@
 
 #define APPLICATION_ID "LIBBURN SUITE (C) 2002 D.FOREMAN/B.JANSENS"
 
+enum dir_type
+{
+	DIR_TYPE_SELF,
+	DIR_TYPE_PARENT,
+	DIR_TYPE_NORMAL
+};
+
 static void iso_next_state (struct iso_write_target *target);
 static int iso_source_get_size (struct burn_source *src);
 static void iso_source_free (struct burn_source *src);
@@ -31,9 +38,13 @@ static int iso_write_path_table (struct 
 				 int lsb);
 static int iso_write_dir_record (struct iso_write_target *target,
 				 unsigned char *buffer,
-				 struct iso_tree_dir **dir);
+				 struct iso_tree_dir **dir,
+				 enum dir_type type);
 static void iso_write_file_id (unsigned char *buf, int size,
 			       struct iso_tree_file **f);
+static int iso_write_dir_records (struct iso_write_target *t,
+				  unsigned char *buffer,
+				  enum burn_source_status *err);
 
 static int
 get_path_table_size (struct iso_tree_dir **ddir)
@@ -43,8 +54,9 @@ get_path_table_size (struct iso_tree_dir
 	
 	assert (dir);
 	
+	/* a path table record is 8 bytes + the length of the directory identifier */
 	if (iso_tree_dir_get_name(ddir, ISO_FILE_NAME_ISO))
-		size += strlen (dir->isoname1);
+		size += (8 + strlen (dir->isoname1));
 	else
 	{
 		/* if iso_tree_dir_get_name is NULL, this is the root dir
@@ -52,6 +64,10 @@ get_path_table_size (struct iso_tree_dir
 		size += 10;
 	}
 	
+	/* pad the field if the directory identifier is an odd number of bytes */
+	if (size % 2)
+		size++;
+	
 	for (i = 0; i < dir->nchildren; i++)
 		size += get_path_table_size (dir->children[i].me);
 	
@@ -105,23 +121,47 @@ iso_source_free (struct burn_source *src
 	free (target);
 }
 
+static int
+get_directory_record_length (const char *isoname)
+{
+	int size;
+	
+	/* size = the length of the filename + 33 bytes (9.1) */
+	size = 33 + strlen (isoname);
+	/* if size is odd, pad it with a single byte (9.1.12) */
+	if (size % 2)
+		size++;
+	
+	return size;
+}
+
 void
 iso_dir_layout (struct iso_write_target *target,
 		struct iso_tree_dir **ddir)
 {
-	int i;
+	int i, length;
 	struct iso_tree_dir *dir = *ddir;
 
 	dir->logical_block = target->logical_block++;
-	dir->size = 0; /* XXX wtf goes here? */
+	length = 0;
 
 	for (i = 0; i < dir->nfiles; ++i) {
+		/* XXX: need to get size of files and all that stuff */
 		dir->files[i].logical_block = 0;
 		dir->files[i].size = 0;
+		length += get_directory_record_length (dir->files[i].isoname1);
 	}
 
-	for (i = 0; i < dir->nchildren; ++i)
+	for (i = 0; i < dir->nchildren; ++i) {
 		iso_dir_layout (target, dir->children[i].me);
+		length += get_directory_record_length (dir->children[i].isoname1);
+	}
+	
+	/* dir->size is the number of bytes needed to hold the directory record
+	 * for each file and subdirectory of 'dir', padded to use up all of the
+	 * bytes of a physical sector. */
+	dir->size = ((length / target->phys_sector_size) + 1)
+		     * target->phys_sector_size;
 }
 
 void
@@ -145,12 +185,12 @@ iso_target_layout (struct iso_write_targ
 	target->volume_space_size = 18;
 	target->logical_block_size = 2048;
 	target->path_table_size = get_path_table_size (target->volset->root);
-	/* leave a 1-block buffer after each path table */
+	/* put a 1-block buffer before each path table */
 	target->l_path_table_pos = 19;
 	target->volume_space_size += 2;
 	target->logical_block += 2;
 	target->total_size += 2 * target->phys_sector_size;
-	/* leave a 1-block buffer after each path table */
+	/* put a 1-block buffer before each path table */
 	target->m_path_table_pos = 21;
 	target->volume_space_size += 2;
 	target->logical_block += 2;
@@ -193,6 +233,9 @@ iso_next_state (struct iso_write_target 
 	case ISO_WRITE_M_PATH_TABLE:
 		target->state_data.path_tables.sectors = 0;
 		break;
+	case ISO_WRITE_DIR_RECORDS:
+		target->state_data.dir_records.sectors = 0;
+		break;
 	case ISO_WRITE_DONE:
 		break;
 	}
@@ -211,11 +254,13 @@ iso_source_generate (struct burn_source 
 		src->read_sub == NULL &&
 		src->get_size == iso_source_get_size);
 
-
 	/* make sure the app didn't fuck up badly. */
 	if (size != target->phys_sector_size)
 		return BURN_SOURCE_FAILED; /* XXX better code */
 
+	/* make sure 'buffer' doesn't have anything in it */
+	memset (buffer, 0, size);
+	
 	switch (target->state)
 	{
 	case ISO_WRITE_BEFORE:
@@ -225,6 +270,9 @@ iso_source_generate (struct burn_source 
 		next = iso_write_system_area (target, buffer, &err);
 		break;
 	case ISO_WRITE_PRI_VOL_DESC:
+		/* set target->logical_block to the logical block containing
+		 * the root directory record */
+		target->logical_block = 23;
 		next = iso_write_pri_volume (target, buffer, &err);
 		break;
 	case ISO_WRITE_VOL_DESC_TERMINATOR:
@@ -236,6 +284,9 @@ iso_source_generate (struct burn_source 
 	case ISO_WRITE_M_PATH_TABLE:
 		next = iso_write_path_table (target, buffer, &err, 0);
 		break;
+	case ISO_WRITE_DIR_RECORDS:
+		next = iso_write_dir_records (target, buffer, &err);
+		break;
 	case ISO_WRITE_DONE:
 		err = BURN_SOURCE_EOF;
 		break;
@@ -302,7 +353,7 @@ iso_write_pri_volume (struct iso_write_t
 	/* location of optional occurance of type m path table (8.4.17) */
 	iso_msb (&buffer[152], 0, 4);
 	/* directory record for root directory (8.4.18) */
-	iso_write_dir_record (t, &buffer[156], t->volset->root);
+	iso_write_dir_record (t, &buffer[156], t->volset->root, DIR_TYPE_SELF);
 	/* volume set identifier (8.4.19) */
 	iso_d_strcpy (&buffer[190], 128, t->volset->volumeset_id);
 	/* publisher identifier (8.4.20) */
@@ -355,16 +406,18 @@ iso_write_file_id (unsigned char *buf, i
 int
 iso_write_dir_record (struct iso_write_target *t,
 		      unsigned char *buffer,
-		      struct iso_tree_dir **ddir)
+		      struct iso_tree_dir **ddir,
+		      enum dir_type type)
 {
 	int len_fi;
 	const char *fi = NULL;
 	int sz;
 	struct iso_tree_dir *dir = *ddir;
 
-	if (!dir->fullname)
+	if (type != DIR_TYPE_NORMAL)
 		len_fi = 1;
 	else {
+		assert (dir->parent);
 		fi = iso_tree_dir_get_name (ddir, ISO_FILE_NAME_ISO);
 		len_fi = strlen (fi);
 	}
@@ -392,10 +445,72 @@ iso_write_dir_record (struct iso_write_t
 	/* length of file identifier (9.1.10) */
 	buffer[32] = len_fi;
 	/* file identifier */
-	if (!dir->fullname)
+	if (type == DIR_TYPE_SELF)
 		buffer[33] = 0;
 	else
-		iso_d_strcpy (&buffer[33], len_fi, fi);
+	{
+		if (type == DIR_TYPE_PARENT)
+			buffer[33] = 1;
+		else
+			iso_d_strcpy (&buffer[33], len_fi, fi);
+	}
+	if (!(len_fi % 2))
+		buffer[33 + len_fi] = 0;
+
+	return sz;
+}
+
+/* write the file record as per (9.1) */
+int
+iso_write_file_record (struct iso_write_target *t,
+		       unsigned char *buffer,
+		       struct iso_tree_file **ffile,
+		       enum dir_type type)
+{
+	int len_fi;
+	const char *fi = NULL;
+	int sz;
+	struct iso_tree_file *file = *ffile;
+	
+	if (type != DIR_TYPE_NORMAL)
+		len_fi = 1;
+	else {
+		fi = iso_tree_file_get_name (ffile, ISO_FILE_NAME_ISO);
+		len_fi = strlen (fi);
+	}
+
+	sz = 33 + len_fi + !(len_fi % 2);
+
+	/* length of directory record (9.1.1) */
+	buffer[0] = sz;
+	/* extended attribute record length (9.1.2) */
+	buffer[1] = 0; /* XXX allow for extended attribute records */
+	/* location of extent (9.1.3) */
+	iso_bb (&buffer[2], file->logical_block, 4);
+	/* data length (9.1.4) */
+	iso_bb (&buffer[10], file->size, 4);
+	/* recording date and time (9.1.5) */
+	iso_datetime_7(&buffer[18], t->now);
+	/* file flags (9.1.6) */
+	buffer[25] = ISO_FILE_FLAG_NORMAL;
+	/* file unit size (9.1.7) */
+	buffer[26] = 0; /* XXX support this shit? */
+	/* interleave gap size (9.1.8) */
+	buffer[27] = 0; /* XXX support this shit? */
+	/* volume sequence number (9.1.9) */
+	iso_bb (&buffer[28], file->volume + 1, 2);
+	/* length of file identifier (9.1.10) */
+	buffer[32] = len_fi;
+	/* file identifier */
+	if (type == DIR_TYPE_SELF)
+		buffer[33] = 0;
+	else
+	{
+		if (type == DIR_TYPE_PARENT)
+			buffer[33] = 1;
+		else
+			iso_d_strcpy (&buffer[33], len_fi, fi);
+	}
 	if (!(len_fi % 2))
 		buffer[33 + len_fi] = 0;
 
@@ -420,21 +535,261 @@ iso_write_volume_terminator (struct iso_
 	return 1;
 }
 
+/* write the path record for 'ddir' into 'buffer' */
+static int
+write_path_table_record (unsigned char *buffer,
+			 struct iso_tree_dir **ddir,
+			 int *position, 
+			 int lsb)
+{
+	int len, bytes_written;
+	short parent_position;
+	const char *name;
+	struct iso_tree_dir *dir = *ddir;
+	
+	/* set the position in the path table of this directory */
+	dir->position = *position;
+	/* increment the position for the next path table record */
+	*position += 1;
+	if (dir->parent)
+		parent_position = dir->parent->position;
+	else
+		parent_position = 1;
+	
+	name = dir->isoname1;
+	if (name)
+		len = strlen (name);
+	else
+		len = 1;
+	
+	/* the directory identifier length (9.4.1) */
+	buffer[0] = len;
+	/* the extended attribute record length (9.4.2) */
+	buffer[1] = 0;
+	/* location of extent (9.4.3) */
+	if (lsb)
+		iso_lsb (&buffer[2], dir->logical_block, 4);
+	else
+		iso_msb (&buffer[2], dir->logical_block, 4);
+	/* parent directory record (9.4.4) */
+	if (lsb)
+		iso_lsb (&buffer[6], parent_position, 2);
+	else
+		iso_msb (&buffer[6], parent_position, 2);
+	/* the directory identifier (9.4.5) */
+	if (name)
+		memcpy (&buffer[8], name, len);
+	else
+		memset (&buffer[8], 0, len);
+	/* padding field (9.4.6) */
+	if (len % 2) {
+		bytes_written = 9 + len;
+		buffer[bytes_written] = 0;
+	}
+	else
+		bytes_written = 8 + len;
+	
+	return bytes_written;
+}
+
+/* recursive function used to write the path records for each level
+ * of the file system sequentially, i.e. root, then all children of
+ * root, then all grandchildren of root, then all great-grandchildren
+ * of root, etc. */
+static int
+write_path_table_records (unsigned char *buffer, 
+			  struct iso_tree_dir **ddir,
+			  int level,
+			  int *position, 
+			  int lsb)
+{
+	int i, offset;
+	struct iso_tree_dir *dir = *ddir;
+	
+	/* ISO9660 only allows directories to be nested 8-deep */
+	if (level >= 8)
+		return 0;
+	
+	if (!level)
+		offset = write_path_table_record (buffer, ddir, position, lsb);
+	else {
+		offset = 0;
+		for (i = 0; i < dir->nchildren; ++i) {
+			offset += write_path_table_records (buffer + offset, 
+							    dir->children[i].me,
+							    level - 1,
+							    position, 
+							    lsb);
+		}
+	}
+	
+	return offset;
+}
+
 /* writes set of path table records */
-int iso_write_path_table (struct iso_write_target *t,
+int
+iso_write_path_table (struct iso_write_target *t,
 			  unsigned char *buffer,
 			  enum burn_source_status *err,
 			  int lsb)
 {
+	int i, offset, position;
 	struct iso_state_path_tables *state = &t->state_data.path_tables;
-
-	/* XXX replace == 0 with < (size of path table) */
-	if (state->sectors == 0) {
-		/* XXX replace these 0xff's with actual path table data */
-		memset (buffer, 0xff, t->phys_sector_size);
-	} else {
+	
+	if (state->sectors) {
+		offset = 0;
+		position = 1;
+		
+		for (i = 0; i < 8; ++i) {
+			offset += write_path_table_records (buffer + offset, 
+							    t->volset->root, 
+							    i, 
+							    &position, 
+							    lsb);
+		}
+	}
+	else {
 		/* empty buffer sector */
 		memset (buffer, 0, t->phys_sector_size);
 	}
+	
 	return (++state->sectors == 2);
 }
+
+static struct iso_tree_dir **
+find_dir_at_block (struct iso_tree_dir **ddir,
+		   int block)
+{
+	int i;
+	struct iso_tree_dir *dir = *ddir;
+	struct iso_tree_dir **to_write = NULL;
+	
+	if (dir->logical_block == block)
+		to_write = ddir;
+	else
+	{
+		for (i = 0; (i < dir->nchildren) && !to_write; ++i)
+		{
+			to_write = find_dir_at_block (dir->children[i].me, 
+						      block);
+		}
+	}
+	
+	if (to_write)
+		return to_write;
+	else
+		return NULL;
+}
+
+/* write the records for children of 'dir' */
+static void
+write_child_records (struct iso_write_target *t,
+	       unsigned char *buffer,
+	       enum burn_source_status *err,
+	       struct iso_tree_dir *dir)
+{
+	int file_counter, dir_counter, order, offset;
+	
+	file_counter = dir_counter = offset = 0;
+	
+	while ((file_counter < dir->nfiles) ||
+	       (dir_counter < dir->nchildren))
+	{
+		/* if there are files and dirs, compare them
+		 * to figure out which comes 1st alphabetically */
+		if ((file_counter < dir->nfiles) &&
+		    (dir_counter < dir->nchildren))
+		{
+			order =  strcmp (
+				dir->children[dir_counter].isoname1,
+				dir->files[file_counter].isoname1);
+		}
+		else
+		{
+			
+			if (file_counter < dir->nfiles)
+				/* only files are left */
+				order = 1;
+			else
+				/* only dirs are left */
+				order = -1;
+		}
+		
+		if (order < 0)
+		{
+			offset += iso_write_dir_record (t, 
+							buffer + offset,
+							dir->children[dir_counter].me,
+							DIR_TYPE_NORMAL);
+			dir_counter++;
+		}
+		else
+		{
+			offset += iso_write_file_record (t,
+							 buffer + offset,
+							 dir->files[file_counter].me,
+							 DIR_TYPE_NORMAL);
+			file_counter++;
+		}
+		
+	}
+
+	return;
+}
+
+/* write out the next directory record */
+int
+iso_write_dir_records (struct iso_write_target *t,
+		       unsigned char *buffer,
+		       enum burn_source_status *err)
+{
+	int finished, offset;
+	struct iso_tree_dir **ddir, *dir;
+	struct iso_state_dir_records *state = &t->state_data.dir_records;
+	
+	finished = 0; /* set to 1 when all directory records have been written */
+	
+	if (state->sectors++)
+	{
+		/* t->logical_block is the next block to write.  find the dir record
+		 * which belongs there and write it out.  if none exists, we're done
+		 * writing the directory records. */
+	
+		ddir = find_dir_at_block (t->volset->root, t->logical_block);
+		if (ddir)
+		{
+			/* 1) write the record for this directory
+			 * 2) write the record for the parent directory
+			 * 3) write the records for all child files and directories
+			 */
+			dir = *ddir;
+			offset = iso_write_dir_record (t, 
+						       buffer, 
+						       ddir, 
+						       DIR_TYPE_SELF);
+			if (!dir->parent)
+			{
+				/* this is the root directory */
+				offset += iso_write_dir_record (t, 
+								buffer + offset, 
+								ddir, 
+								DIR_TYPE_PARENT);
+			}
+			else
+			{
+				offset += iso_write_dir_record (t,
+								buffer + offset,
+								dir->parent->me,
+								DIR_TYPE_PARENT);
+			}
+			
+			write_child_records (t, buffer + offset, err, dir);
+			
+			t->logical_block++;
+		}
+		else
+			finished = 1;
+	}
+	
+	return finished;
+}
Index: libisofs/writer.h
===================================================================
RCS file: /cvs/burn/burn/libisofs/writer.h,v
retrieving revision 1.10
diff -p -u -r1.10 writer.h
--- libisofs/writer.h	10 Feb 2004 12:45:20 -0000	1.10
+++ libisofs/writer.h	23 Feb 2004 05:33:32 -0000
@@ -17,6 +17,7 @@ enum iso_write_state
 	ISO_WRITE_VOL_DESC_TERMINATOR,
 	ISO_WRITE_L_PATH_TABLE,
 	ISO_WRITE_M_PATH_TABLE,
+	ISO_WRITE_DIR_RECORDS,
 
 	ISO_WRITE_DONE
 };
@@ -29,7 +30,8 @@ enum
 	ISO_FILE_FLAG_ASSOCIATED  = 1 << 2,
 	ISO_FILE_FLAG_RECORD      = 1 << 3,
 	ISO_FILE_FLAG_PROTECTION  = 1 << 4,
-	ISO_FILE_FLAG_MULTIEXTENT = 1 << 7
+	ISO_FILE_FLAG_MULTIEXTENT = 1 << 7,
+	ISO_FILE_FLAG_NORMAL	  = 0
 };
 
 struct iso_write_target
@@ -45,7 +47,8 @@ struct iso_write_target
 	/* size of the total output */
 	int total_size;
 
-	/* the next available logical block */
+	/* when compiling the iso, this is the next available logical block.
+	 * when writing the iso, this is the next block to write. */
 	int logical_block;
 	/* The number of Logical Blocks for the Volume Space */
 	int volume_space_size;
@@ -71,6 +74,11 @@ struct iso_write_target
 			   written */
 			int sectors;
 		} path_tables;
+		struct iso_state_dir_records {
+			/* how many sectors in the directory records area have
+			   been written */
+			int sectors;
+		} dir_records;
 	} state_data;
 };
 

--=-fMZma97fpKrRtkm/7Dmr--