[Libburn] libisofs patch

Todd Kulesza todd@dropline.net
Sat, 14 Feb 2004 00:06:33 -0500


--=-+b2JFfdfiKEOjaZ7Hi3M
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

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



--=-+b2JFfdfiKEOjaZ7Hi3M
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/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	14 Feb 2004 04:56:44 -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	14 Feb 2004 04:56:45 -0000
@@ -43,8 +43,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 +53,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 +110,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) {
 		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)
+	{
 		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

--=-+b2JFfdfiKEOjaZ7Hi3M--