Index: walk.c =================================================================== --- walk.c (revision 246091) +++ walk.c (working copy) @@ -59,7 +59,6 @@ static void apply_specentry(const char *, NODE *, fsnode *); static fsnode *create_fsnode(const char *, const char *, const char *, struct stat *); -static fsinode *link_check(fsinode *); /* @@ -644,7 +643,7 @@ /* This was borrowed from du.c and tweaked to keep an fsnode * pointer instead. -- dbj@netbsd.org */ -static fsinode * +fsinode * link_check(fsinode *entry) { static struct entry { Index: makefs.c =================================================================== --- makefs.c (revision 246091) +++ makefs.c (working copy) @@ -73,6 +73,7 @@ }; u_int debug; +int dupsok; struct timespec start_time; static fstype_t *get_fstype(const char *); @@ -112,7 +113,7 @@ start_time.tv_sec = start.tv_sec; start_time.tv_nsec = start.tv_usec * 1000; - while ((ch = getopt(argc, argv, "B:b:d:f:F:M:m:N:o:ps:S:t:x")) != -1) { + while ((ch = getopt(argc, argv, "B:b:Dd:f:F:M:m:N:o:ps:S:t:x")) != -1) { switch (ch) { case 'B': @@ -148,6 +149,10 @@ } break; + case 'D': + dupsok = 1; + break; + case 'd': debug = strtoll(optarg, NULL, 0); break; Index: makefs.h =================================================================== --- makefs.h (revision 246091) +++ makefs.h (working copy) @@ -167,7 +167,7 @@ void cd9660_cleanup_opts(fsinfo_t *); void cd9660_makefs(const char *, const char *, fsnode *, fsinfo_t *); - +extern int dupsok; extern u_int debug; extern struct timespec start_time; @@ -279,6 +279,8 @@ struct fs; void ffs_fragacct_swap(struct fs *, int, int32_t [], int, int); +fsinode *link_check(fsinode *); + /* * Declarations for compat routines. */ Index: mtree.c =================================================================== --- mtree.c (revision 246091) +++ mtree.c (working copy) @@ -508,8 +508,8 @@ { char keyword[PATH_MAX]; char *name, *p, *value; - struct group *grent; - struct passwd *pwent; + gid_t gid; + uid_t uid; struct stat *st, sb; intmax_t num; u_long flset, flclr; @@ -585,11 +585,10 @@ error = ENOATTR; break; } - grent = getgrnam(value); - if (grent != NULL) - st->st_gid = grent->gr_gid; + if (gid_from_group(value, &gid) == 0) + st->st_gid = gid; else - error = errno; + error = EINVAL; } else error = ENOSYS; break; @@ -698,11 +697,10 @@ error = ENOATTR; break; } - pwent = getpwnam(value); - if (pwent != NULL) - st->st_uid = pwent->pw_uid; + if (uid_from_user(value, &uid) == 0) + st->st_uid = uid; else - error = errno; + error = EINVAL; } else error = ENOSYS; break; @@ -781,6 +779,24 @@ return (0); } + /* + * Check for hardlinks. If the contents key is used, then the check + * will only trigger if the contents file is a link even if it is used + * by more than one file + */ + if (sb.st_nlink > 1) { + fsinode *curino; + + st->st_ino = sb.st_ino; + st->st_dev = sb.st_dev; + curino = link_check(node->inode); + if (curino != NULL) { + free(node->inode); + node->inode = curino; + node->inode->nlink++; + } + } + free(node->contents); node->contents = name; st->st_size = sb.st_size; @@ -881,8 +897,12 @@ if (strcmp(name, node->name) == 0) { if (def == true) { - mtree_error("duplicate definition of %s", - name); + if (!dupsok) + mtree_error("duplicate definition of %s", + name); + else + mtree_warning("duplicate definition " + "of %s", name); return (0); } @@ -970,15 +990,15 @@ do { *cp++ = '\0'; - /* Disallow '.' and '..' as components. */ - if (IS_DOT(pathspec) || IS_DOTDOT(pathspec)) { - mtree_error("absolute path cannot contain . " - "or .. components"); + /* Disallow '..' as a component. */ + if (IS_DOTDOT(pathspec)) { + mtree_error("absolute path cannot contain " + ".. component"); goto out; } - /* Ignore multiple adjacent slashes. */ - if (pathspec[0] != '\0') + /* Ignore multiple adjacent slashes and '.'. */ + if (pathspec[0] != '\0' && !IS_DOT(pathspec)) error = read_mtree_spec1(fp, false, pathspec); memmove(pathspec, cp, strlen(cp) + 1); cp = strchr(pathspec, '/'); Index: makefs.8 =================================================================== --- makefs.8 (revision 246091) +++ makefs.8 (working copy) @@ -43,7 +43,7 @@ .Nd create a file system image from a directory tree or a mtree manifest .Sh SYNOPSIS .Nm -.Op Fl px +.Op Fl Dpx .Op Fl B Ar byte-order .Op Fl b Ar free-blocks .Op Fl d Ar debug-mask @@ -106,6 +106,8 @@ suffix may be provided to indicate that .Ar free-blocks indicates a percentage of the calculated image size. +.It Fl D +Treat duplicate paths in an mtree manifest as warnings not error. .It Fl d Ar debug-mask Enable various levels of debugging, depending upon which bits are set in