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);
>  }
>  
>  
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to