svn commit: r230795 - in head/usr.sbin/makefs: . cd9660

Martin Matuska mm at FreeBSD.org
Mon Feb 20 21:19:36 UTC 2012


Thanks for the patch, I see it has been adopted by NetBSD.

I have seen there has been recently activity in makefs.

IMO makefs should be moved to vendor/contrib (originates fron NetBSD)
the same way libarchive was moved. Or are we doing the main (or our very
own) development of makefs? If we are, it wouldn't be bad to give a
statement to clarify this.

Dňa 31. 1. 2012 1:32, Jung-uk Kim  wrote / napísal(a):
> Author: jkim
> Date: Tue Jan 31 00:32:37 2012
> New Revision: 230795
> URL: http://svn.freebsd.org/changeset/base/230795
> 
> Log:
>   Allow contents of multiple directories to be merged to the current image.
>   Note this patch was submitted to NetBSD and they already adopted it.
>   
>   http://mail-index.netbsd.org/source-changes/2012/01/28/msg031078.html
>   
>   MFC after:	1 week
> 
> Modified:
>   head/usr.sbin/makefs/cd9660.c
>   head/usr.sbin/makefs/cd9660.h
>   head/usr.sbin/makefs/cd9660/cd9660_write.c
>   head/usr.sbin/makefs/ffs.c
>   head/usr.sbin/makefs/makefs.8
>   head/usr.sbin/makefs/makefs.c
>   head/usr.sbin/makefs/makefs.h
>   head/usr.sbin/makefs/walk.c
> 
> Modified: head/usr.sbin/makefs/cd9660.c
> ==============================================================================
> --- head/usr.sbin/makefs/cd9660.c	Tue Jan 31 00:12:51 2012	(r230794)
> +++ head/usr.sbin/makefs/cd9660.c	Tue Jan 31 00:32:37 2012	(r230795)
> @@ -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);
> @@ -1568,24 +1566,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: head/usr.sbin/makefs/cd9660.h
> ==============================================================================
> --- head/usr.sbin/makefs/cd9660.h	Tue Jan 31 00:12:51 2012	(r230794)
> +++ head/usr.sbin/makefs/cd9660.h	Tue Jan 31 00:32:37 2012	(r230795)
> @@ -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: head/usr.sbin/makefs/cd9660/cd9660_write.c
> ==============================================================================
> --- head/usr.sbin/makefs/cd9660/cd9660_write.c	Tue Jan 31 00:12:51 2012	(r230794)
> +++ head/usr.sbin/makefs/cd9660/cd9660_write.c	Tue Jan 31 00:32:37 2012	(r230795)
> @@ -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: head/usr.sbin/makefs/ffs.c
> ==============================================================================
> --- head/usr.sbin/makefs/ffs.c	Tue Jan 31 00:12:51 2012	(r230794)
> +++ head/usr.sbin/makefs/ffs.c	Tue Jan 31 00:32:37 2012	(r230795)
> @@ -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: head/usr.sbin/makefs/makefs.8
> ==============================================================================
> --- head/usr.sbin/makefs/makefs.8	Tue Jan 31 00:12:51 2012	(r230794)
> +++ head/usr.sbin/makefs/makefs.8	Tue Jan 31 00:32:37 2012	(r230795)
> @@ -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: head/usr.sbin/makefs/makefs.c
> ==============================================================================
> --- head/usr.sbin/makefs/makefs.c	Tue Jan 31 00:12:51 2012	(r230794)
> +++ head/usr.sbin/makefs/makefs.c	Tue Jan 31 00:32:37 2012	(r230795)
> @@ -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: head/usr.sbin/makefs/makefs.h
> ==============================================================================
> --- head/usr.sbin/makefs/makefs.h	Tue Jan 31 00:12:51 2012	(r230794)
> +++ head/usr.sbin/makefs/makefs.h	Tue Jan 31 00:32:37 2012	(r230795)
> @@ -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: head/usr.sbin/makefs/walk.c
> ==============================================================================
> --- head/usr.sbin/makefs/walk.c	Tue Jan 31 00:12:51 2012	(r230794)
> +++ head/usr.sbin/makefs/walk.c	Tue Jan 31 00:32:37 2012	(r230795)
> @@ -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);
>  }
>  
>  


More information about the svn-src-head mailing list