Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F161687546
D57411.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D57411.diff
View Options
Index: usr.bin/xinstall/install.1
===================================================================
--- usr.bin/xinstall/install.1
+++ usr.bin/xinstall/install.1
@@ -187,11 +187,25 @@
symbolic
.It Sy m
mixed
+.It Sy c
+metalog contents reference
.El
.Pp
Absolute and relative have effect only for symbolic links.
Mixed links
are hard links for files on the same filesystem, symbolic otherwise.
+.Pp
+The
+.Ar c
+link type does not create a filesystem object.
+Instead, the source file's absolute path is recorded using the
+.Xr mtree 5
+.Cm contents
+tag in the
+.Ar metalog
+file.
+It must be used with
+.Fl M Ar metalog .
.It Fl M Ar metalog
Write the metadata associated with each item installed to
.Ar metalog
Index: usr.bin/xinstall/tests/install_test.sh
===================================================================
--- usr.bin/xinstall/tests/install_test.sh
+++ usr.bin/xinstall/tests/install_test.sh
@@ -32,6 +32,8 @@
install -s -d dir1
atf_check -s not-exit:0 -e match:"specified together" \
install -s -l s testf copyf
+ atf_check -s not-exit:0 -e match:"requires -M metalog" \
+ install -l c testf copyf
}
atf_test_case copy_to_empty
Index: usr.bin/xinstall/xinstall.c
===================================================================
--- usr.bin/xinstall/xinstall.c
+++ usr.bin/xinstall/xinstall.c
@@ -95,6 +95,7 @@
#define LN_HARD 0x04
#define LN_SYMBOLIC 0x08
#define LN_MIXED 0x10
+#define LN_CONTENTS 0x20
#define DIRECTORY 0x01 /* Tell install it's a directory. */
#define SETFLAGS 0x02 /* Tell install to set flags. */
@@ -155,7 +156,8 @@
static void install(const char *, const char *, u_long, u_int);
static void install_dir(char *);
static void metadata_log(const char *, const char *, struct timespec *,
- const char *, const char *, off_t);
+ const char *, const char *, off_t, const char *);
+static void parse_l_args(const char *p);
static int parseid(const char *, id_t *);
static int strip(const char *, int, const char *, char **);
static void usage(void);
@@ -168,7 +170,6 @@
u_long fset;
int ch, no_target;
u_int iflags;
- char *p;
const char *to_name;
uint64_t num;
@@ -209,32 +210,7 @@
digest = optarg;
break;
case 'l':
- for (p = optarg; *p != '\0'; p++)
- switch (*p) {
- case 's':
- dolink &= ~(LN_HARD|LN_MIXED);
- dolink |= LN_SYMBOLIC;
- break;
- case 'h':
- dolink &= ~(LN_SYMBOLIC|LN_MIXED);
- dolink |= LN_HARD;
- break;
- case 'm':
- dolink &= ~(LN_SYMBOLIC|LN_HARD);
- dolink |= LN_MIXED;
- break;
- case 'a':
- dolink &= ~LN_RELATIVE;
- dolink |= LN_ABSOLUTE;
- break;
- case 'r':
- dolink &= ~LN_ABSOLUTE;
- dolink |= LN_RELATIVE;
- break;
- default:
- errx(1, "%c: invalid link type", *p);
- /* NOTREACHED */
- }
+ parse_l_args(optarg);
break;
case 'M':
metafile = optarg;
@@ -299,6 +275,11 @@
usage();
}
+ if ((dolink & LN_CONTENTS) && metafile == NULL) {
+ warnx("-l c requires -M metalog");
+ usage();
+ }
+
/*
* Default permissions based on whether we're a directory or not, since
* an +X may mean that we need to set the execute bit.
@@ -427,6 +408,42 @@
/* NOTREACHED */
}
+static void
+parse_l_args(const char *p)
+{
+ for (p = optarg; *p != '\0'; p++) {
+ switch (*p) {
+ case 'c':
+ dolink &= ~(LN_SYMBOLIC | LN_HARD | LN_MIXED);
+ dolink |= LN_CONTENTS;
+ break;
+ case 's':
+ dolink &= ~(LN_CONTENTS | LN_HARD | LN_MIXED);
+ dolink |= LN_SYMBOLIC;
+ break;
+ case 'h':
+ dolink &= ~(LN_CONTENTS | LN_SYMBOLIC | LN_MIXED);
+ dolink |= LN_HARD;
+ break;
+ case 'm':
+ dolink &= ~(LN_CONTENTS | LN_SYMBOLIC | LN_HARD);
+ dolink |= LN_MIXED;
+ break;
+ case 'a':
+ dolink &= ~LN_RELATIVE;
+ dolink |= LN_ABSOLUTE;
+ break;
+ case 'r':
+ dolink &= ~LN_ABSOLUTE;
+ dolink |= LN_RELATIVE;
+ break;
+ default:
+ errx(1, "%c: invalid link type", *p);
+ /* NOTREACHED */
+ }
+ }
+}
+
static char *
digest_file(const char *name)
{
@@ -673,7 +690,25 @@
const char *base, *dir;
struct stat to_sb;
- /* Try hard links first. */
+ /* First check for mtree contents reference. */
+ if (dolink & LN_CONTENTS) {
+ struct stat from_sb;
+ char *dres;
+
+ if (dolink & LN_RELATIVE)
+ errx(EX_OSERR, "relative contents not yet supported");
+ if (stat(from_name, &from_sb))
+ err(EX_OSERR, "%s: stat", from_name);
+ if (realpath(from_name, src) == NULL)
+ err(EX_OSERR, "%s: realpath", from_name);
+ dres = digest_file(from_name);
+ metadata_log(to_name, "file", NULL, NULL, dres,
+ from_sb.st_size, src);
+ free(dres);
+ return;
+ }
+
+ /* Try hard links next. */
if (dolink & (LN_HARD|LN_MIXED)) {
if (do_link(from_name, to_name, target_sb) == -1) {
if ((dolink & LN_HARD) || errno != EXDEV)
@@ -709,7 +744,7 @@
fflags = NULL;
dres = digest_file(from_name);
metadata_log(to_name, "file", NULL, NULL,
- dres, to_sb.st_size);
+ dres, to_sb.st_size, NULL);
free(dres);
mode = omode;
owner = oowner;
@@ -727,7 +762,7 @@
err(EX_OSERR, "%s: realpath", from_name);
do_symlink(src, to_name, target_sb);
/* XXX: src may point outside of destdir */
- metadata_log(to_name, "link", NULL, src, NULL, 0);
+ metadata_log(to_name, "link", NULL, src, NULL, 0, NULL);
return;
}
@@ -736,7 +771,8 @@
/* this is already a relative link */
do_symlink(from_name, to_name, target_sb);
/* XXX: from_name may point outside of destdir. */
- metadata_log(to_name, "link", NULL, from_name, NULL, 0);
+ metadata_log(to_name, "link", NULL, from_name, NULL, 0,
+ NULL);
return;
}
@@ -797,7 +833,7 @@
do_symlink(lnk, to_name, target_sb);
/* XXX: Link may point outside of destdir. */
- metadata_log(to_name, "link", NULL, lnk, NULL, 0);
+ metadata_log(to_name, "link", NULL, lnk, NULL, 0, NULL);
return;
}
@@ -807,7 +843,7 @@
*/
do_symlink(from_name, to_name, target_sb);
/* XXX: from_name may point outside of destdir. */
- metadata_log(to_name, "link", NULL, from_name, NULL, 0);
+ metadata_log(to_name, "link", NULL, from_name, NULL, 0, NULL);
}
/*
@@ -1084,7 +1120,8 @@
if (!devnull)
(void)close(from_fd);
- metadata_log(to_name, "file", tsb, NULL, digestresult, to_sb.st_size);
+ metadata_log(to_name, "file", tsb, NULL, digestresult, to_sb.st_size,
+ NULL);
free(digestresult);
}
@@ -1392,7 +1429,7 @@
if (chmod(path, mode))
warn("chmod %o %s", mode, path);
}
- metadata_log(path, "dir", NULL, NULL, NULL, 0);
+ metadata_log(path, "dir", NULL, NULL, NULL, 0, NULL);
}
/*
@@ -1403,7 +1440,8 @@
*/
static void
metadata_log(const char *path, const char *type, struct timespec *ts,
- const char *slink, const char *digestresult, off_t size)
+ const char *slink, const char *digestresult, off_t size,
+ const char *contents)
{
static const char extra[] = { ' ', '\t', '\n', '\\', '#', '\0' };
const char *p;
@@ -1413,10 +1451,12 @@
if (!metafp)
return;
- /* Buffer for strsnvis(3), used for both path and slink. */
+ /* Buffer for strsnvis(3), used for path, slink, and contents. */
buflen = strlen(path);
if (slink && strlen(slink) > buflen)
buflen = strlen(slink);
+ if (contents && strlen(contents) > buflen)
+ buflen = strlen(contents);
buflen = 4 * buflen + 1;
if ((buf = malloc(buflen)) == NULL) {
warn(NULL);
@@ -1469,6 +1509,10 @@
strsnvis(buf, buflen, slink, VIS_CSTYLE, extra);
fprintf(metafp, " link=%s", buf);
}
+ if (contents) {
+ strsnvis(buf, buflen, contents, VIS_OCTAL, extra);
+ fprintf(metafp, " contents=%s", buf);
+ }
if (*type == 'f') /* type=file */
fprintf(metafp, " size=%llu", (unsigned long long)size);
if (ts != NULL && dopreserve)
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Jul 6, 11:18 PM (10 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34732290
Default Alt Text
D57411.diff (7 KB)
Attached To
Mode
D57411: xinstall: Add metalog contents reference link type
Attached
Detach File
Event Timeline
Log In to Comment