From owner-svn-src-stable-9@FreeBSD.ORG Mon Feb 20 18:49:12 2012 Return-Path: Delivered-To: svn-src-stable-9@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 08228106566B; Mon, 20 Feb 2012 18:49:12 +0000 (UTC) (envelope-from jkim@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id E94D08FC18; Mon, 20 Feb 2012 18:49:11 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q1KInBqN063593; Mon, 20 Feb 2012 18:49:11 GMT (envelope-from jkim@svn.freebsd.org) Received: (from jkim@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q1KInBVQ063584; Mon, 20 Feb 2012 18:49:11 GMT (envelope-from jkim@svn.freebsd.org) Message-Id: <201202201849.q1KInBVQ063584@svn.freebsd.org> From: Jung-uk Kim Date: Mon, 20 Feb 2012 18:49:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r231942 - in stable/9/usr.sbin/makefs: . cd9660 X-BeenThere: svn-src-stable-9@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for only the 9-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 20 Feb 2012 18:49:12 -0000 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); }