Module Name: src Committed By: christos Date: Sat Jan 28 02:35:46 UTC 2012
Modified Files: src/usr.sbin/makefs: cd9660.c cd9660.h ffs.c makefs.8 makefs.c makefs.h walk.c src/usr.sbin/makefs/cd9660: cd9660_write.c Log Message: Patch from Jung-uk Kim (jkim at FreeBSD dot org) to allow contents of multiple directories to be merged to the current image. To generate a diff of this commit: cvs rdiff -u -r1.34 -r1.35 src/usr.sbin/makefs/cd9660.c cvs rdiff -u -r1.17 -r1.18 src/usr.sbin/makefs/cd9660.h cvs rdiff -u -r1.45 -r1.46 src/usr.sbin/makefs/ffs.c cvs rdiff -u -r1.37 -r1.38 src/usr.sbin/makefs/makefs.8 cvs rdiff -u -r1.30 -r1.31 src/usr.sbin/makefs/makefs.c cvs rdiff -u -r1.23 -r1.24 src/usr.sbin/makefs/makefs.h cvs rdiff -u -r1.24 -r1.25 src/usr.sbin/makefs/walk.c cvs rdiff -u -r1.14 -r1.15 src/usr.sbin/makefs/cd9660/cd9660_write.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.sbin/makefs/cd9660.c diff -u src/usr.sbin/makefs/cd9660.c:1.34 src/usr.sbin/makefs/cd9660.c:1.35 --- src/usr.sbin/makefs/cd9660.c:1.34 Tue Aug 23 15:57:24 2011 +++ src/usr.sbin/makefs/cd9660.c Fri Jan 27 21:35:46 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: cd9660.c,v 1.34 2011/08/23 19:57:24 christos Exp $ */ +/* $NetBSD: cd9660.c,v 1.35 2012/01/28 02:35:46 christos Exp $ */ /* * Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan @@ -103,7 +103,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) && !defined(__lint) -__RCSID("$NetBSD: cd9660.c,v 1.34 2011/08/23 19:57:24 christos Exp $"); +__RCSID("$NetBSD: cd9660.c,v 1.35 2012/01/28 02:35:46 christos Exp $"); #endif /* !__lint */ #include <string.h> @@ -480,8 +480,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); @@ -1592,24 +1590,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 */ Index: src/usr.sbin/makefs/cd9660.h diff -u src/usr.sbin/makefs/cd9660.h:1.17 src/usr.sbin/makefs/cd9660.h:1.18 --- src/usr.sbin/makefs/cd9660.h:1.17 Wed Jun 22 22:35:56 2011 +++ src/usr.sbin/makefs/cd9660.h Fri Jan 27 21:35:46 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: cd9660.h,v 1.17 2011/06/23 02:35:56 enami Exp $ */ +/* $NetBSD: cd9660.h,v 1.18 2012/01/28 02:35:46 christos Exp $ */ /* * Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan @@ -245,8 +245,6 @@ typedef struct _iso9660_disk { cd9660node *rootNode; - const char *rootFilesystemPath; - /* Important sector numbers here */ /* primaryDescriptor.type_l_path_table*/ int64_t primaryBigEndianTableSector; @@ -346,7 +344,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 */ Index: src/usr.sbin/makefs/ffs.c diff -u src/usr.sbin/makefs/ffs.c:1.45 src/usr.sbin/makefs/ffs.c:1.46 --- src/usr.sbin/makefs/ffs.c:1.45 Sun Oct 9 17:33:43 2011 +++ src/usr.sbin/makefs/ffs.c Fri Jan 27 21:35:46 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ffs.c,v 1.45 2011/10/09 21:33:43 christos Exp $ */ +/* $NetBSD: ffs.c,v 1.46 2012/01/28 02:35:46 christos Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -71,7 +71,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) && !defined(__lint) -__RCSID("$NetBSD: ffs.c,v 1.45 2011/10/09 21:33:43 christos Exp $"); +__RCSID("$NetBSD: ffs.c,v 1.46 2012/01/28 02:35:46 christos Exp $"); #endif /* !__lint */ #include <sys/param.h> @@ -784,8 +784,8 @@ ffs_populate_dir(const char *dir, fsnode continue; /* skip hard-linked entries */ cur->inode->flags |= FI_WRITTEN; - if (snprintf(path, sizeof(path), "%s/%s", dir, cur->name) - >= sizeof(path)) + if ((size_t)snprintf(path, sizeof(path), "%s/%s/%s", cur->root, + cur->path, cur->name) >= sizeof(path)) errx(1, "Pathname too long."); if (cur->child != NULL) Index: src/usr.sbin/makefs/makefs.8 diff -u src/usr.sbin/makefs/makefs.8:1.37 src/usr.sbin/makefs/makefs.8:1.38 --- src/usr.sbin/makefs/makefs.8:1.37 Sun Oct 9 17:33:43 2011 +++ src/usr.sbin/makefs/makefs.8 Fri Jan 27 21:35:46 2012 @@ -1,4 +1,4 @@ -.\" $NetBSD: makefs.8,v 1.37 2011/10/09 21:33:43 christos Exp $ +.\" $NetBSD: makefs.8,v 1.38 2012/01/28 02:35:46 christos Exp $ .\" .\" Copyright (c) 2001-2003 Wasabi Systems, Inc. .\" All rights reserved. @@ -33,7 +33,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd October 9, 2011 +.Dd January 27, 2012 .Dt MAKEFS 8 .Os .Sh NAME @@ -56,6 +56,7 @@ .Op Fl t Ar fs-type .Ar image-file .Ar directory +.Op Ar extra-directory ... .Sh DESCRIPTION The utility .Nm @@ -63,6 +64,13 @@ creates a file system image into .Ar image-file from the directory tree .Ar directory . +If any optional directory trees are passed in the +.Ar extra-directory +arguments, then the directory tree of each argument will be merged +into the +.Ar directory +first before creating +.Ar image-file . No special devices or privileges are required to perform this task. .Pp The options are as follows: Index: src/usr.sbin/makefs/makefs.c diff -u src/usr.sbin/makefs/makefs.c:1.30 src/usr.sbin/makefs/makefs.c:1.31 --- src/usr.sbin/makefs/makefs.c:1.30 Mon Aug 15 10:45:01 2011 +++ src/usr.sbin/makefs/makefs.c Fri Jan 27 21:35:46 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: makefs.c,v 1.30 2011/08/15 14:45:01 wiz Exp $ */ +/* $NetBSD: makefs.c,v 1.31 2012/01/28 02:35:46 christos Exp $ */ /* * Copyright (c) 2001-2003 Wasabi Systems, Inc. @@ -41,7 +41,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) && !defined(__lint) -__RCSID("$NetBSD: makefs.c,v 1.30 2011/08/15 14:45:01 wiz Exp $"); +__RCSID("$NetBSD: makefs.c,v 1.31 2012/01/28 02:35:46 christos Exp $"); #endif /* !__lint */ #include <assert.h> @@ -92,7 +92,7 @@ main(int argc, char *argv[]) fstype_t *fstype; fsinfo_t fsoptions; fsnode *root; - int ch, len; + int ch, i, len; char *specfile; setprogname(argv[0]); @@ -245,7 +245,7 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; - if (argc != 2) + if (argc < 2) usage(); /* -x must be accompanied by -F */ @@ -254,9 +254,21 @@ main(int argc, char *argv[]) /* walk the tree */ TIMER_START(start); - root = walk_dir(argv[1], NULL); + root = walk_dir(argv[1], ".", NULL, NULL); TIMER_RESULTS(start, "walk_dir"); + /* append extra directory */ + for (i = 2; i < argc; i++) { + struct stat sb; + 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, argv[1], root, fsoptions.onlyspec); @@ -265,7 +277,7 @@ main(int argc, char *argv[]) if (debug & DEBUG_DUMP_FSNODES) { printf("\nparent: %s\n", argv[1]); - dump_fsnodes(".", root); + dump_fsnodes(root); putchar('\n'); } @@ -319,7 +331,7 @@ usage(void) "usage: %s [-x] [-B endian] [-b free-blocks] [-d debug-mask]\n" "\t[-F mtree-specfile] [-f free-files] [-M minimum-size]\n" "\t[-m maximum-size] [-N userdb-dir] [-o fs-options] [-S sector-size]\n" -"\t[-s image-size] [-t fs-type] image-file directory\n", +"\t[-s image-size] [-t fs-type] image-file directory [extra-directory ...]\n", prog); exit(1); } Index: src/usr.sbin/makefs/makefs.h diff -u src/usr.sbin/makefs/makefs.h:1.23 src/usr.sbin/makefs/makefs.h:1.24 --- src/usr.sbin/makefs/makefs.h:1.23 Mon Jul 18 18:52:37 2011 +++ src/usr.sbin/makefs/makefs.h Fri Jan 27 21:35:46 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: makefs.h,v 1.23 2011/07/18 22:52:37 tron Exp $ */ +/* $NetBSD: makefs.h,v 1.24 2012/01/28 02:35:46 christos Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -102,6 +102,8 @@ typedef struct _fsnode { uint32_t type; /* type of entry */ fsinode *inode; /* actual inode data */ char *symlink; /* symlink target */ + const char *root; /* root path */ + char *path; /* directory name */ char *name; /* file name */ int flags; /* misc flags */ } fsnode; @@ -154,10 +156,10 @@ 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); 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 *); Index: src/usr.sbin/makefs/walk.c diff -u src/usr.sbin/makefs/walk.c:1.24 src/usr.sbin/makefs/walk.c:1.25 --- src/usr.sbin/makefs/walk.c:1.24 Sun Dec 28 16:51:46 2008 +++ src/usr.sbin/makefs/walk.c Fri Jan 27 21:35:46 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: walk.c,v 1.24 2008/12/28 21:51:46 christos Exp $ */ +/* $NetBSD: walk.c,v 1.25 2012/01/28 02:35:46 christos Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -41,7 +41,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) && !defined(__lint) -__RCSID("$NetBSD: walk.c,v 1.24 2008/12/28 21:51:46 christos Exp $"); +__RCSID("$NetBSD: walk.c,v 1.25 2012/01/28 02:35:46 christos Exp $"); #endif /* !__lint */ #include <sys/param.h> @@ -61,40 +61,69 @@ __RCSID("$NetBSD: walk.c,v 1.24 2008/12/ 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 = last = cur; + } else + last = first = prev = NULL; 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); @@ -106,22 +135,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; } } @@ -151,22 +209,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; @@ -215,6 +278,7 @@ free_fsnodes(fsnode *node) free(cur->inode); if (cur->symlink) free(cur->symlink); + free(cur->path); free(cur->name); free(cur); } @@ -366,14 +430,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; } @@ -481,19 +547,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) @@ -512,10 +577,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); } Index: src/usr.sbin/makefs/cd9660/cd9660_write.c diff -u src/usr.sbin/makefs/cd9660/cd9660_write.c:1.14 src/usr.sbin/makefs/cd9660/cd9660_write.c:1.15 --- src/usr.sbin/makefs/cd9660/cd9660_write.c:1.14 Tue Jan 4 04:48:21 2011 +++ src/usr.sbin/makefs/cd9660/cd9660_write.c Fri Jan 27 21:35:46 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: cd9660_write.c,v 1.14 2011/01/04 09:48:21 wiz Exp $ */ +/* $NetBSD: cd9660_write.c,v 1.15 2012/01/28 02:35:46 christos Exp $ */ /* * Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan @@ -37,7 +37,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) && !defined(__lint) -__RCSID("$NetBSD: cd9660_write.c,v 1.14 2011/01/04 09:48:21 wiz Exp $"); +__RCSID("$NetBSD: cd9660_write.c,v 1.15 2012/01/28 02:35:46 christos Exp $"); #endif /* !__lint */ static int cd9660_write_volume_descriptors(FILE *); @@ -297,7 +297,7 @@ cd9660_write_file(FILE *fd, cd9660node * __func__, (int)inode->st.st_ino, inode->ino)); inode->flags |= FI_WRITTEN; cd9660_compute_full_filename(writenode, - temp_file_name, 0); + temp_file_name); ret = cd9660_copy_file(fd, writenode->fileDataSector, temp_file_name); if (ret == 0)