[Debburn-changes] r807 - in cdrkit/trunk: . genisoimage

93sam at alioth.debian.org 93sam at alioth.debian.org
Sun May 25 21:01:00 UTC 2008


Author: 93sam
Date: 2008-05-25 21:00:55 +0000 (Sun, 25 May 2008)
New Revision: 807

Modified:
   cdrkit/trunk/Changelog
   cdrkit/trunk/genisoimage/genisoimage.c
   cdrkit/trunk/genisoimage/genisoimage.h
   cdrkit/trunk/genisoimage/multi.c
   cdrkit/trunk/genisoimage/tree.c
Log:
genisoimage: Applied patch from Roman Rakus <rrakus at redhat.com> to
preserve directory permissions.


Modified: cdrkit/trunk/Changelog
===================================================================
--- cdrkit/trunk/Changelog	2008-05-25 20:46:17 UTC (rev 806)
+++ cdrkit/trunk/Changelog	2008-05-25 21:00:55 UTC (rev 807)
@@ -9,6 +9,8 @@
     on 64-bit arches.
   * genisoimage/checksum.[ch]: Added test code; changed internal
     layout slightly to make for easier debug.
+  * genisoimage: Applied patch from Roman Rakus <rrakus at redhat.com> to
+    preserve directory permissions.
 
  -- Steve McIntyre <93sam at debian.org>  Mon, 25 May 2008 21:22:26 +0100
 

Modified: cdrkit/trunk/genisoimage/genisoimage.c
===================================================================
--- cdrkit/trunk/genisoimage/genisoimage.c	2008-05-25 20:46:17 UTC (rev 806)
+++ cdrkit/trunk/genisoimage/genisoimage.c	2008-05-25 21:00:55 UTC (rev 807)
@@ -3051,7 +3051,7 @@
 	 * Create an empty root directory. If we ever scan it for real,
 	 * we will fill in the contents.
 	 */
-	find_or_create_directory(NULL, "", &de, TRUE);
+	find_or_create_directory(NULL, "", &de, TRUE, NULL);
 
 #ifdef APPLE_HYB
 	/* may need to set window layout of the volume */
@@ -3113,6 +3113,7 @@
 			char		*pnt;
 			char		*xpnt;
 			size_t		len;
+			int		node_is_dir;
 
 			/* insert -root prefix */
 			if (reloc_root != NULL) {
@@ -3160,7 +3161,9 @@
 				status = stat_filter(node, &st);
 			else
 				status = lstat_filter(node, &st);
-			if (status == 0 && S_ISDIR(st.st_mode)) {
+
+			node_is_dir = S_ISDIR(st.st_mode);
+			if (status == 0 && node_is_dir) {
 				len = strlen(graft_point);
 
 				if ((len <= (sizeof (graft_point) -1)) &&
@@ -3177,6 +3180,8 @@
 			 * Canonicalize the filename while parsing it.
 			 */
 			for (;;) {
+				struct stat* stat_template;
+
 				do {
 					while (xpnt[0] == '.' && xpnt[1] == '/')
 						xpnt += 2;
@@ -3204,9 +3209,22 @@
 						graft_dir->de_name,
 						graft_point);
 				}
-				graft_dir = find_or_create_directory(graft_dir,
-					graft_point,
-					NULL, TRUE);
+				/*
+				 * If the node being grafted is a
+				 * directory, then we want the last
+				 * directory in this graft chain to have
+				 * the ownership and permissions of the
+				 * source node.  Other directories in the
+				 * chain get default ownership and
+				 * permissions.
+				 */
+				stat_template = 
+				  (pnt[1] == '\0' && node_is_dir) ? &st : 0;
+
+ 				graft_dir = find_or_create_directory(graft_dir,
+					graft_point, NULL, TRUE, 
+					stat_template);
+
 				*pnt = PATH_SEPARATOR;
 				xpnt = pnt + 1;
 			}
@@ -3219,8 +3237,7 @@
 		}
 
 		/*
-		 * Now see whether the user wants to add a regular file, or a
-		 * directory at this point.
+		 * Get information on the node
 		 */
 		if (follow_links)
 			status = stat_filter(node, &st);
@@ -3238,6 +3255,10 @@
 			exit(1);
 #endif
 		} else {
+			/*
+			 * Now see whether the user wants to add a regular
+			 * file or a directory at this point.
+			 */
 			if (S_ISDIR(st.st_mode)) {
 				if (debug) {
 					fprintf(stderr, "graft_dir: '%s : %s', node: '%s', (scan)\n",

Modified: cdrkit/trunk/genisoimage/genisoimage.h
===================================================================
--- cdrkit/trunk/genisoimage/genisoimage.h	2008-05-25 20:46:17 UTC (rev 806)
+++ cdrkit/trunk/genisoimage/genisoimage.h	2008-05-25 21:00:55 UTC (rev 807)
@@ -433,8 +433,10 @@
 extern int lstat_filter(char *, struct stat *);
 extern int sort_tree(struct directory *);
 extern struct directory *
-find_or_create_directory(struct directory *, const char *, 
-								 struct directory_entry *self, int);
+find_or_create_directory(struct directory *, const char *,
+			 struct directory_entry *self,
+			 int,
+			 struct stat *stat_template);
 extern void	finish_cl_pl_entries(void);
 extern int	scan_directory_tree(struct directory *this_dir, char *path,
 										  struct directory_entry *self);

Modified: cdrkit/trunk/genisoimage/multi.c
===================================================================
--- cdrkit/trunk/genisoimage/multi.c	2008-05-25 20:46:17 UTC (rev 806)
+++ cdrkit/trunk/genisoimage/multi.c	2008-05-25 21:00:55 UTC (rev 807)
@@ -1641,7 +1641,7 @@
 
 		if (reloc_root && reloc_root[0]) {
 			/* also decend into new root before searching for files */
-			this_dir = find_or_create_directory(this_dir, reloc_root, NULL, TRUE);
+			this_dir = find_or_create_directory(this_dir, reloc_root, NULL, TRUE, NULL);
 			if (!this_dir) {
 				return (-1);
 			}
@@ -1707,7 +1707,7 @@
 				 */
 				child = find_or_create_directory(this_dir,
 					s_entry->whole_name,
-					s_entry, 1);
+					s_entry, 1, NULL);
 				dflag = merge_previous_session(child,
 					&odpnt->isorec,
 					NULL, reloc_old_root);

Modified: cdrkit/trunk/genisoimage/tree.c
===================================================================
--- cdrkit/trunk/genisoimage/tree.c	2008-05-25 20:46:17 UTC (rev 806)
+++ cdrkit/trunk/genisoimage/tree.c	2008-05-25 21:00:55 UTC (rev 807)
@@ -74,8 +74,8 @@
 int	lstat_filter(char *path, struct stat *st);
 static	int	sort_n_finish(struct directory *this_dir);
 static	void	generate_reloc_directory(void);
-static	void	attach_dot_entries(struct directory *dirnode,
-											 struct stat *parent_stat);
+static	void	attach_dot_entries(struct directory *dirnode, struct stat *dir_stat,
+					struct stat *parent_stat);
 static	void	update_nlink(struct directory_entry *s_entry, int value);
 static	void	increment_nlink(struct directory_entry *s_entry);
 char	*find_rr_attribute(unsigned char *pnt, int len, char *attr_type);
@@ -95,9 +95,10 @@
 void	generate_iso9660_directories(struct directory *node,
 											  FILE *outfile);
 struct directory *find_or_create_directory(struct directory *parent,
-														 const char *path,
-														 struct directory_entry *de,
-														 int flag);
+						const char *path,
+						struct directory_entry *de,
+						int flag,
+						struct stat* stat_template);
 static	void	delete_directory(struct directory *parent,
 										  struct directory *child);
 int	sort_tree(struct directory *node);
@@ -284,7 +285,9 @@
 	 */
 	if ((this_dir->dir_flags & (DIR_HAS_DOT | DIR_HAS_DOTDOT)) !=
 		(DIR_HAS_DOT | DIR_HAS_DOTDOT)) {
-		attach_dot_entries(this_dir, &fstatbuf);
+		fstatbuf.st_mode = new_dir_mode | S_IFDIR;
+		fstatbuf.st_nlink = 2;
+		attach_dot_entries(this_dir, &fstatbuf, &fstatbuf);
 	}
 	flush_file_hash();
 	s_entry = this_dir->contents;
@@ -840,7 +843,7 @@
 	/* Now create the . and .. entries in rr_moved */
 	/* Now create an actual directory  entry */
 	memset(&root_statbuf, 0x0, sizeof(struct stat)); /* be sure */
-	attach_dot_entries(reloc_dir, &root_statbuf);
+	attach_dot_entries(reloc_dir, &fstatbuf, &root_statbuf);
 }
 
 /*
@@ -848,12 +851,17 @@
  *
  * Purpose:		Create . and .. entries for a new directory.
  *
+ * Arguments:		dir_stat contains the ownership/permission information
+ *			for dirnode, and parent_stat contains 
+ *			ownership/permission information for its parent
+ *
+ *
  * Notes:		Only used for artificial directories that
  *			we are creating.
  */
 static void
-attach_dot_entries(struct directory *dirnode, 
-						 struct stat *parent_stat)
+attach_dot_entries(struct directory *dirnode, struct stat *dir_stat,
+			struct stat *parent_stat)
 {
 	struct directory_entry *s_entry;
 	struct directory_entry *orig_contents;
@@ -894,9 +902,6 @@
 		orig_contents = s_entry;
 
 		if (use_XA || use_RockRidge) {
-			if (parent_stat == NULL) {
-				parent_stat = &fstatbuf;
-			}
 			generate_xa_rr_attributes("",
 				"..", s_entry,
 				parent_stat,
@@ -934,15 +939,12 @@
 		dirnode->contents->next = orig_contents;
 
 		if (use_XA || use_RockRidge) {
-			fstatbuf.st_mode = new_dir_mode | S_IFDIR;
-			fstatbuf.st_nlink = 2;
 
 			if (dirnode == root) {
 				deep_flag |= NEED_CE | NEED_SP;	/* For extension record */
 			}
-			generate_xa_rr_attributes("",
-				".", s_entry,
-				&fstatbuf, &fstatbuf, deep_flag);
+			generate_xa_rr_attributes("", ".", s_entry,
+				dir_stat, dir_stat, deep_flag);
 		}
 		dirnode->dir_flags |= DIR_HAS_DOT;
 	}
@@ -1646,11 +1648,11 @@
 				}
 				child = find_or_create_directory(reloc_dir,
 					whole_path,
-					s_entry, 1);
+					s_entry, 1, NULL);
 			} else {
 				child = find_or_create_directory(this_dir,
 					whole_path,
-					s_entry, 1);
+					s_entry, 1, NULL);
 				/*
 				 * If unable to scan directory, mark this as a
 				 * non-directory
@@ -1985,14 +1987,14 @@
 		 */
 		s_entry1->filedir = reloc_dir;
 		child = find_or_create_directory(reloc_dir, whole_path,
-			s_entry1, 0);
+			s_entry1, 0, NULL);
 /*		if (!no_scandir)*/
 		if (!0)
 			scan_directory_tree(child, whole_path, s_entry1);
 		s_entry1->filedir = this_dir;
 
 		statbuf.st_size = (off_t)0;
-		statbuf.st_mode &= 0777;
+//		statbuf.st_mode &= 0777;
 		set_733((char *) s_entry->isorec.size, 0);
 		s_entry->realsize=0;
 		s_entry->size = 0;
@@ -2091,7 +2093,7 @@
 			struct directory *child;
 
 			child = find_or_create_directory(this_dir, whole_path,
-				s_entry, 1);
+				s_entry, 1, NULL);
 			if (no_scandir)
 				dflag = 1;
 			else
@@ -2217,18 +2219,25 @@
  * Function:	find_or_create_directory
  *
  * Purpose:	Locate a directory entry in the tree, create if needed.
+ * 		If a directory is created and stat_template is non-null,
+ *		create the directory with ownership, permissions, etc.,
+ *		from stat_template, otherwise use fallback defaults.
  *
  * Arguments:	parent & de are never NULL at the same time.
  */
 struct directory *
-find_or_create_directory(struct directory *parent, const char *path, 
-								 struct directory_entry *de, int flag)
+find_or_create_directory(struct directory *parent,
+			 const char *path, 
+			 struct directory_entry *de,
+			 int flag,
+			 struct stat *stat_template)
 {
 	struct directory *dpnt;
 	struct directory_entry *orig_de;
 	struct directory *next_brother;
 	const char	*cpnt;
 	const char	*pnt;
+	struct stat	my_statbuf;
 
 	orig_de = de;
 
@@ -2287,18 +2296,27 @@
 						volume_sequence_number);
 		iso9660_file_length(pnt, de, 1);
 
+		/*
+		 * If we were given a stat template, use it for
+		 * ownership/permissions, otherwise use fallback defaults.
+		 */
 		init_fstatbuf();
+		if (stat_template) {
+			my_statbuf = *stat_template;
+		} else {
+			my_statbuf = fstatbuf; /* defaults */
+			my_statbuf.st_mode = new_dir_mode;
+		}
+		my_statbuf.st_mode &= ~S_IFMT; /* zero out file type */
+		my_statbuf.st_mode |= S_IFDIR; /* force to be a directory */
+		my_statbuf.st_nlink = 2;
+		
 		/*
-		 * It doesn't exist for real, so we cannot add any
-		 * XA or Rock Ridge attributes.
+		 * Apply attributes from my_statbuf to the new directory.
 		 */
 		if (use_XA || use_RockRidge) {
-			fstatbuf.st_mode = new_dir_mode | S_IFDIR;
-			fstatbuf.st_nlink = 2;
-			generate_xa_rr_attributes("",
-				(char *) pnt, de,
-				&fstatbuf,
-				&fstatbuf, 0);
+			generate_xa_rr_attributes("", (char *) pnt, de,
+				&my_statbuf, &my_statbuf, 0);
 		}
 		iso9660_date(de->isorec.date, fstatbuf.st_mtime);
 #ifdef APPLE_HYB
@@ -2310,8 +2328,8 @@
 
 			/* fill in the defaults */
 			memset(hfs_ent, 0, sizeof (hfsdirent));
-			hfs_ent->crdate = fstatbuf.st_ctime;
-			hfs_ent->mddate = fstatbuf.st_mtime;
+			hfs_ent->crdate = my_statbuf.st_ctime;
+			hfs_ent->mddate = my_statbuf.st_mtime;
 
 			de->hfs_ent = hfs_ent;
 
@@ -2347,6 +2365,7 @@
 
 	if (orig_de == NULL) {
 		struct stat	xstatbuf;
+		struct stat	parent_statbuf;
 		int		sts;
 
 		/*
@@ -2358,16 +2377,19 @@
 		if (parent == NULL || parent->whole_name[0] == '\0')
 			sts = -1;
 		else
-			sts = stat_filter(parent->whole_name, &xstatbuf);
+			sts = stat_filter(parent->whole_name, &parent_statbuf);
+		
+		if (sts != 0) {
+			parent_statbuf = fstatbuf;
+			parent_statbuf.st_mode = new_dir_mode | S_IFDIR;
+			parent_statbuf.st_nlink = 2;
+		}
+		
 		if (debug && parent) {
 			fprintf(stderr, "stat parent->whole_name: '%s' -> %d.\n",
 				parent->whole_name, sts);
 		}
-		if (sts == 0) {
-			attach_dot_entries(dpnt, &xstatbuf);
-		} else {
-			attach_dot_entries(dpnt, &fstatbuf);
-		}
+		attach_dot_entries(dpnt, &my_statbuf, &parent_statbuf);
 	}
 	if (!parent || parent == root) {
 		if (!root) {




More information about the Debburn-changes mailing list