Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 20 Feb 2012 18:49:11 +0000 (UTC)
From:      Jung-uk Kim <jkim@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r231942 - in stable/9/usr.sbin/makefs: . cd9660
Message-ID:  <201202201849.q1KInBVQ063584@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jkim
Date: Mon Feb 20 18:49:11 2012
New Revision: 231942
URL: http://svn.freebsd.org/changeset/base/231942

Log:
  MFC:	r230795
  
  Allow contents of multiple directories to be merged to the current image.

Modified:
  stable/9/usr.sbin/makefs/cd9660.c
  stable/9/usr.sbin/makefs/cd9660.h
  stable/9/usr.sbin/makefs/cd9660/cd9660_write.c
  stable/9/usr.sbin/makefs/ffs.c
  stable/9/usr.sbin/makefs/makefs.8
  stable/9/usr.sbin/makefs/makefs.c
  stable/9/usr.sbin/makefs/makefs.h
  stable/9/usr.sbin/makefs/walk.c
Directory Properties:
  stable/9/usr.sbin/makefs/   (props changed)

Modified: stable/9/usr.sbin/makefs/cd9660.c
==============================================================================
--- stable/9/usr.sbin/makefs/cd9660.c	Mon Feb 20 17:09:52 2012	(r231941)
+++ stable/9/usr.sbin/makefs/cd9660.c	Mon Feb 20 18:49:11 2012	(r231942)
@@ -472,8 +472,6 @@ cd9660_makefs(const char *image, const c
 		return;
 	}
 
-	diskStructure.rootFilesystemPath = dir;
-
 	if (diskStructure.verbose_level > 0)
 		printf("cd9660_makefs: image %s directory %s root %p\n",
 		    image, dir, root);
@@ -1584,24 +1582,15 @@ cd9660_generate_path_table(void)
 }
 
 void
-cd9660_compute_full_filename(cd9660node *node, char *buf, int level)
+cd9660_compute_full_filename(cd9660node *node, char *buf)
 {
-	cd9660node *parent;
-
-	parent = (node->rr_real_parent == NULL ?
-		  node->parent : node->rr_real_parent);
-	if (parent != NULL) {
-		cd9660_compute_full_filename(parent, buf, level + 1);
-		strcat(buf, node->node->name);
-	} else {
-		/* We are at the root */
-		strcat(buf, diskStructure.rootFilesystemPath);
-		if (buf[strlen(buf) - 1] == '/')
-			buf[strlen(buf) - 1] = '\0';
-	}
+	int len;
 
-	if (level != 0)
-		strcat(buf, "/");
+	len = CD9660MAXPATH + 1;
+	len = snprintf(buf, len, "%s/%s/%s", node->node->root,
+	    node->node->path, node->node->name);
+	if (len > CD9660MAXPATH)
+		errx(1, "Pathname too long.");
 }
 
 /* NEW filename conversion method */

Modified: stable/9/usr.sbin/makefs/cd9660.h
==============================================================================
--- stable/9/usr.sbin/makefs/cd9660.h	Mon Feb 20 17:09:52 2012	(r231941)
+++ stable/9/usr.sbin/makefs/cd9660.h	Mon Feb 20 18:49:11 2012	(r231942)
@@ -244,8 +244,6 @@ typedef struct _iso9660_disk {
 
 	cd9660node *rootNode;
 
-	const char *rootFilesystemPath;
-
 	/* Important sector numbers here */
 	/* primaryDescriptor.type_l_path_table*/
 	int64_t primaryBigEndianTableSector;
@@ -345,7 +343,7 @@ int	cd9660_setup_boot_volume_descriptor(
 int	cd9660_write_image(const char *image);
 int	cd9660_copy_file(FILE *, off_t, const char *);
 
-void	cd9660_compute_full_filename(cd9660node *, char *, int);
+void	cd9660_compute_full_filename(cd9660node *, char *);
 int	cd9660_compute_record_size(cd9660node *);
 
 /* Debugging functions */

Modified: stable/9/usr.sbin/makefs/cd9660/cd9660_write.c
==============================================================================
--- stable/9/usr.sbin/makefs/cd9660/cd9660_write.c	Mon Feb 20 17:09:52 2012	(r231941)
+++ stable/9/usr.sbin/makefs/cd9660/cd9660_write.c	Mon Feb 20 18:49:11 2012	(r231942)
@@ -296,7 +296,7 @@ cd9660_write_file(FILE *fd, cd9660node *
 			inode->flags |= FI_WRITTEN;
 			if (writenode->node->contents == NULL)
 				cd9660_compute_full_filename(writenode,
-				    temp_file_name, 0);
+				    temp_file_name);
 			ret = cd9660_copy_file(fd, writenode->fileDataSector,
 			    (writenode->node->contents != NULL) ?
 			    writenode->node->contents : temp_file_name);

Modified: stable/9/usr.sbin/makefs/ffs.c
==============================================================================
--- stable/9/usr.sbin/makefs/ffs.c	Mon Feb 20 17:09:52 2012	(r231941)
+++ stable/9/usr.sbin/makefs/ffs.c	Mon Feb 20 18:49:11 2012	(r231942)
@@ -780,8 +780,8 @@ ffs_populate_dir(const char *dir, fsnode
 		cur->inode->flags |= FI_WRITTEN;
 
 		if (cur->contents == NULL) {
-			if (snprintf(path, sizeof(path), "%s/%s", dir,
-			    cur->name) >= sizeof(path))
+			if (snprintf(path, sizeof(path), "%s/%s/%s", cur->root,
+			    cur->path, cur->name) >= (int)sizeof(path))
 				errx(1, "Pathname too long.");
 		}
 

Modified: stable/9/usr.sbin/makefs/makefs.8
==============================================================================
--- stable/9/usr.sbin/makefs/makefs.8	Mon Feb 20 17:09:52 2012	(r231941)
+++ stable/9/usr.sbin/makefs/makefs.8	Mon Feb 20 18:49:11 2012	(r231942)
@@ -35,7 +35,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 10, 2009
+.Dd January 30, 2012
 .Dt MAKEFS 8
 .Os
 .Sh NAME
@@ -58,6 +58,7 @@
 .Op Fl t Ar fs-type
 .Ar image-file
 .Ar directory | manifest
+.Op Ar extra-directory ...
 .Sh DESCRIPTION
 The utility
 .Nm
@@ -67,6 +68,15 @@ from the directory tree
 .Ar directory
 or from the mtree manifest
 .Ar manifest .
+If optional directory tree
+.Ar extra-directory
+is passed, then the directory tree of each argument will be merged
+into the
+.Ar directory
+or
+.Ar manifest
+first before creating
+.Ar image-file .
 No special devices or privileges are required to perform this task.
 .Pp
 The options are as follows:

Modified: stable/9/usr.sbin/makefs/makefs.c
==============================================================================
--- stable/9/usr.sbin/makefs/makefs.c	Mon Feb 20 17:09:52 2012	(r231941)
+++ stable/9/usr.sbin/makefs/makefs.c	Mon Feb 20 18:49:11 2012	(r231942)
@@ -87,7 +87,7 @@ main(int argc, char *argv[])
 	fstype_t	*fstype;
 	fsinfo_t	 fsoptions;
 	fsnode		*root;
-	int	 	 ch, len;
+	int	 	 ch, i, len;
 	char		*subtree;
 	char		*specfile;
 
@@ -241,7 +241,7 @@ main(int argc, char *argv[])
 	argc -= optind;
 	argv += optind;
 
-	if (argc != 2)
+	if (argc < 2)
 		usage();
 
 	/* -x must be accompanied by -F */
@@ -260,7 +260,7 @@ main(int argc, char *argv[])
 	case S_IFDIR:		/* walk the tree */
 		subtree = argv[1];
 		TIMER_START(start);
-		root = walk_dir(subtree, NULL);
+		root = walk_dir(subtree, ".", NULL, NULL);
 		TIMER_RESULTS(start, "walk_dir");
 		break;
 	case S_IFREG:		/* read the manifest file */
@@ -274,6 +274,17 @@ main(int argc, char *argv[])
 		/* NOTREACHED */
 	}
 
+	/* append extra directory */
+	for (i = 2; i < argc; i++) {
+		if (stat(argv[i], &sb) == -1)
+			err(1, "Can't stat `%s'", argv[i]);
+		if (!S_ISDIR(sb.st_mode))
+			errx(1, "%s: not a directory", argv[i]);
+		TIMER_START(start);
+		root = walk_dir(argv[i], ".", NULL, root);
+		TIMER_RESULTS(start, "walk_dir2");
+	}
+
 	if (specfile) {		/* apply a specfile */
 		TIMER_START(start);
 		apply_specfile(specfile, subtree, root, fsoptions.onlyspec);
@@ -282,7 +293,7 @@ main(int argc, char *argv[])
 
 	if (debug & DEBUG_DUMP_FSNODES) {
 		printf("\nparent: %s\n", subtree);
-		dump_fsnodes(".", root);
+		dump_fsnodes(root);
 		putchar('\n');
 	}
 
@@ -336,7 +347,7 @@ usage(void)
 "usage: %s [-t fs-type] [-o fs-options] [-d debug-mask] [-B endian]\n"
 "\t[-S sector-size] [-M minimum-size] [-m maximum-size] [-s image-size]\n"
 "\t[-b free-blocks] [-f free-files] [-F mtree-specfile] [-x]\n"
-"\t[-N userdb-dir] image-file directory | manifest\n",
+"\t[-N userdb-dir] image-file directory | manifest [extra-directory ...]\n",
 	    prog);
 	exit(1);
 }

Modified: stable/9/usr.sbin/makefs/makefs.h
==============================================================================
--- stable/9/usr.sbin/makefs/makefs.h	Mon Feb 20 17:09:52 2012	(r231941)
+++ stable/9/usr.sbin/makefs/makefs.h	Mon Feb 20 18:49:11 2012	(r231942)
@@ -94,6 +94,8 @@ typedef struct _fsnode {
 	fsinode		*inode;		/* actual inode data */
 	char		*symlink;	/* symlink target */
 	char		*contents;	/* file to provide contents */
+	const char	*root;		/* root path */
+	char		*path;		/* directory name */
 	char		*name;		/* file name */
 	int		flags;		/* misc flags */
 } fsnode;
@@ -147,11 +149,11 @@ typedef struct {
 
 
 void		apply_specfile(const char *, const char *, fsnode *, int);
-void		dump_fsnodes(const char *, fsnode *);
+void		dump_fsnodes(fsnode *);
 const char *	inode_type(mode_t);
 fsnode *	read_mtree(const char *, fsnode *);
 int		set_option(option_t *, const char *, const char *);
-fsnode *	walk_dir(const char *, fsnode *);
+fsnode *	walk_dir(const char *, const char *, fsnode *, fsnode *);
 void		free_fsnodes(fsnode *);
 
 void		ffs_prep_opts(fsinfo_t *);

Modified: stable/9/usr.sbin/makefs/walk.c
==============================================================================
--- stable/9/usr.sbin/makefs/walk.c	Mon Feb 20 17:09:52 2012	(r231941)
+++ stable/9/usr.sbin/makefs/walk.c	Mon Feb 20 18:49:11 2012	(r231942)
@@ -57,40 +57,70 @@ __FBSDID("$FreeBSD$");
 
 static	void	 apply_specdir(const char *, NODE *, fsnode *, int);
 static	void	 apply_specentry(const char *, NODE *, fsnode *);
-static	fsnode	*create_fsnode(const char *, struct stat *);
+static	fsnode	*create_fsnode(const char *, const char *, const char *,
+			       struct stat *);
 static	fsinode	*link_check(fsinode *);
 
 
 /*
  * walk_dir --
- *	build a tree of fsnodes from `dir', with a parent fsnode of `parent'
- *	(which may be NULL for the root of the tree).
+ *	build a tree of fsnodes from `root' and `dir', with a parent
+ *	fsnode of `parent' (which may be NULL for the root of the tree).
+ *	append the tree to a fsnode of `join' if it is not NULL.
  *	each "level" is a directory, with the "." entry guaranteed to be
  *	at the start of the list, and without ".." entries.
  */
 fsnode *
-walk_dir(const char *dir, fsnode *parent)
+walk_dir(const char *root, const char *dir, fsnode *parent, fsnode *join)
 {
-	fsnode		*first, *cur, *prev;
+	fsnode		*first, *cur, *prev, *last;
 	DIR		*dirp;
 	struct dirent	*dent;
 	char		path[MAXPATHLEN + 1];
 	struct stat	stbuf;
+	char		*name, *rp;
+	int		dot, len;
 
+	assert(root != NULL);
 	assert(dir != NULL);
 
+	len = snprintf(path, sizeof(path), "%s/%s", root, dir);
+	if (len >= (int)sizeof(path))
+		errx(1, "Pathname too long.");
 	if (debug & DEBUG_WALK_DIR)
-		printf("walk_dir: %s %p\n", dir, parent);
-	if ((dirp = opendir(dir)) == NULL)
-		err(1, "Can't opendir `%s'", dir);
-	first = prev = NULL;
+		printf("walk_dir: %s %p\n", path, parent);
+	if ((dirp = opendir(path)) == NULL)
+		err(1, "Can't opendir `%s'", path);
+	rp = path + strlen(root) + 1;
+	if (join != NULL) {
+		first = cur = join;
+		while (cur->next != NULL)
+			cur = cur->next;
+		prev = cur;
+	} else
+		first = prev = NULL;
+	last = prev;
 	while ((dent = readdir(dirp)) != NULL) {
-		if (strcmp(dent->d_name, "..") == 0)
-			continue;
+		name = dent->d_name;
+		dot = 0;
+		if (name[0] == '.')
+			switch (name[1]) {
+			case '\0':	/* "." */
+				if (join != NULL)
+					continue;
+				dot = 1;
+				break;
+			case '.':	/* ".." */
+				if (name[2] == '\0')
+					continue;
+				/* FALLTHROUGH */
+			default:
+				dot = 0;
+			}
 		if (debug & DEBUG_WALK_DIR_NODE)
-			printf("scanning %s/%s\n", dir, dent->d_name);
-		if (snprintf(path, sizeof(path), "%s/%s", dir, dent->d_name)
-		    >= sizeof(path))
+			printf("scanning %s/%s/%s\n", root, dir, name);
+		if (snprintf(path + len, sizeof(path) - len, "/%s", name) >=
+		    (int)sizeof(path) - len)
 			errx(1, "Pathname too long.");
 		if (lstat(path, &stbuf) == -1)
 			err(1, "Can't lstat `%s'", path);
@@ -102,22 +132,51 @@ walk_dir(const char *dir, fsnode *parent
 		}
 #endif
 
-		cur = create_fsnode(dent->d_name, &stbuf);
+		if (join != NULL) {
+			cur = join->next;
+			for (;;) {
+				if (cur == NULL || strcmp(cur->name, name) == 0)
+					break;
+				if (cur == last) {
+					cur = NULL;
+					break;
+				}
+				cur = cur->next;
+			}
+			if (cur != NULL) {
+				if (S_ISDIR(cur->type) &&
+				    S_ISDIR(stbuf.st_mode)) {
+					if (debug & DEBUG_WALK_DIR_NODE)
+						printf("merging %s with %p\n",
+						    path, cur->child);
+					cur->child = walk_dir(root, rp, cur,
+					    cur->child);
+					continue;
+				}
+				errx(1, "Can't merge %s `%s' with existing %s",
+				    inode_type(stbuf.st_mode), path,
+				    inode_type(cur->type));
+			}
+		}
+
+		cur = create_fsnode(root, dir, name, &stbuf);
 		cur->parent = parent;
-		if (strcmp(dent->d_name, ".") == 0) {
+		if (dot) {
 				/* ensure "." is at the start of the list */
 			cur->next = first;
 			first = cur;
 			if (! prev)
 				prev = cur;
+			cur->first = first;
 		} else {			/* not "." */
 			if (prev)
 				prev->next = cur;
 			prev = cur;
 			if (!first)
 				first = cur;
+			cur->first = first;
 			if (S_ISDIR(cur->type)) {
-				cur->child = walk_dir(path, cur);
+				cur->child = walk_dir(root, rp, cur, NULL);
 				continue;
 			}
 		}
@@ -147,22 +206,27 @@ walk_dir(const char *dir, fsnode *parent
 				err(1, "Memory allocation error");
 		}
 	}
-	for (cur = first; cur != NULL; cur = cur->next)
-		cur->first = first;
+	assert(first != NULL);
+	if (join == NULL)
+		for (cur = first->next; cur != NULL; cur = cur->next)
+			cur->first = first;
 	if (closedir(dirp) == -1)
-		err(1, "Can't closedir `%s'", dir);
+		err(1, "Can't closedir `%s/%s'", root, dir);
 	return (first);
 }
 
 static fsnode *
-create_fsnode(const char *name, struct stat *stbuf)
+create_fsnode(const char *root, const char *path, const char *name,
+    struct stat *stbuf)
 {
 	fsnode *cur;
 
 	if ((cur = calloc(1, sizeof(fsnode))) == NULL ||
+	    (cur->path = strdup(path)) == NULL ||
 	    (cur->name = strdup(name)) == NULL ||
 	    (cur->inode = calloc(1, sizeof(fsinode))) == NULL)
 		err(1, "Memory allocation error");
+	cur->root = root;
 	cur->type = stbuf->st_mode & S_IFMT;
 	cur->inode->nlink = 1;
 	cur->inode->st = *stbuf;
@@ -211,6 +275,7 @@ free_fsnodes(fsnode *node)
 			free(cur->inode);
 		if (cur->symlink)
 			free(cur->symlink);
+		free(cur->path);
 		free(cur->name);
 		free(cur);
 	}
@@ -388,14 +453,16 @@ apply_specdir(const char *dir, NODE *spe
 			stbuf.st_mtimensec = stbuf.st_atimensec =
 			    stbuf.st_ctimensec = start_time.tv_nsec;
 #endif
-			curfsnode = create_fsnode(curnode->name, &stbuf);
+			curfsnode = create_fsnode(".", ".", curnode->name,
+			    &stbuf);
 			curfsnode->parent = dirnode->parent;
 			curfsnode->first = dirnode;
 			curfsnode->next = dirnode->next;
 			dirnode->next = curfsnode;
 			if (curfsnode->type == S_IFDIR) {
 					/* for dirs, make "." entry as well */
-				curfsnode->child = create_fsnode(".", &stbuf);
+				curfsnode->child = create_fsnode(".", ".", ".",
+				    &stbuf);
 				curfsnode->child->parent = curfsnode;
 				curfsnode->child->first = curfsnode->child;
 			}
@@ -503,19 +570,18 @@ apply_specentry(const char *dir, NODE *s
 
 /*
  * dump_fsnodes --
- *	dump the fsnodes from `cur', based in the directory `dir'
+ *	dump the fsnodes from `cur'
  */
 void
-dump_fsnodes(const char *dir, fsnode *root)
+dump_fsnodes(fsnode *root)
 {
 	fsnode	*cur;
 	char	path[MAXPATHLEN + 1];
 
-	assert (dir != NULL);
-	printf("dump_fsnodes: %s %p\n", dir, root);
+	printf("dump_fsnodes: %s %p\n", root->path, root);
 	for (cur = root; cur != NULL; cur = cur->next) {
-		if (snprintf(path, sizeof(path), "%s/%s", dir, cur->name)
-		    >= sizeof(path))
+		if (snprintf(path, sizeof(path), "%s/%s", cur->path,
+		    cur->name) >= (int)sizeof(path))
 			errx(1, "Pathname too long.");
 
 		if (debug & DEBUG_DUMP_FSNODES_VERBOSE)
@@ -534,10 +600,10 @@ dump_fsnodes(const char *dir, fsnode *ro
 
 		if (cur->child) {
 			assert (cur->type == S_IFDIR);
-			dump_fsnodes(path, cur->child);
+			dump_fsnodes(cur->child);
 		}
 	}
-	printf("dump_fsnodes: finished %s\n", dir);
+	printf("dump_fsnodes: finished %s/%s\n", root->path, root->name);
 }
 
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201202201849.q1KInBVQ063584>