2020-07-02 11:13:51 +08:00
|
|
|
|
From 531cabc88e9ecdc3231fad6e4856869baa9a91ef Mon Sep 17 00:00:00 2001
|
|
|
|
|
|
From: Roberto Sassu <roberto.sassu@huawei.com>
|
|
|
|
|
|
Date: Wed, 22 May 2019 09:04:39 +0200
|
|
|
|
|
|
Subject: [PATCH] cpio: add option to add file metadata in copy-out mode
|
|
|
|
|
|
|
|
|
|
|
|
This patch adds the -e <type> option to include file metadata in the
|
|
|
|
|
|
image. At the moment, only the xattr type is supported.
|
|
|
|
|
|
|
|
|
|
|
|
If the xattr type is selected, the patch includes an additional file for
|
|
|
|
|
|
each file passed to stdin, with special name 'METADATA!!!'. The
|
|
|
|
|
|
additional file might contain multiple metadata records. The format of
|
|
|
|
|
|
each record is:
|
|
|
|
|
|
|
|
|
|
|
|
<metadata len (ASCII, 8 chars)><version><type><metadata>
|
|
|
|
|
|
|
|
|
|
|
|
The format of metadata for the xattr type is:
|
|
|
|
|
|
|
|
|
|
|
|
<xattr name>\0<xattr value>
|
|
|
|
|
|
|
|
|
|
|
|
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
|
|
|
|
|
|
---
|
|
|
|
|
|
doc/cpio.texi | 3 ++
|
2020-07-30 16:57:59 +08:00
|
|
|
|
src/copyout.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
|
|
|
|
|
|
src/dstring.c | 26 +++++++++--
|
2020-07-02 11:13:51 +08:00
|
|
|
|
src/dstring.h | 1 +
|
|
|
|
|
|
src/extern.h | 4 +-
|
|
|
|
|
|
src/global.c | 2 +
|
2020-07-30 16:57:59 +08:00
|
|
|
|
src/initramfs.h | 21 +++++++++
|
|
|
|
|
|
src/main.c | 22 +++++++++
|
2020-07-02 11:13:51 +08:00
|
|
|
|
8 files changed, 211 insertions(+), 8 deletions(-)
|
|
|
|
|
|
create mode 100644 src/initramfs.h
|
|
|
|
|
|
|
|
|
|
|
|
diff --git a/doc/cpio.texi b/doc/cpio.texi
|
2020-07-30 16:57:59 +08:00
|
|
|
|
index 31a15fa..03d9585 100644
|
2020-07-02 11:13:51 +08:00
|
|
|
|
--- a/doc/cpio.texi
|
|
|
|
|
|
+++ b/doc/cpio.texi
|
2020-07-30 16:57:59 +08:00
|
|
|
|
@@ -276,6 +276,9 @@ Set the I/O block size to the given @var{number} of bytes.
|
2020-07-02 11:13:51 +08:00
|
|
|
|
@item -D @var{dir}
|
|
|
|
|
|
@itemx --directory=@var{dir}
|
|
|
|
|
|
Change to directory @var{dir}
|
|
|
|
|
|
+@item -e @var{type}
|
|
|
|
|
|
+@itemx --file-metadata=@var{type}
|
|
|
|
|
|
+Include in the image file metadata with the specified type.
|
|
|
|
|
|
@item --force-local
|
|
|
|
|
|
Treat the archive file as local, even if its name contains colons.
|
|
|
|
|
|
@item -F [[@var{user}@@]@var{host}:]@var{archive-file}
|
|
|
|
|
|
diff --git a/src/copyout.c b/src/copyout.c
|
2020-07-30 16:57:59 +08:00
|
|
|
|
index 4b7336b..fdafb37 100644
|
2020-07-02 11:13:51 +08:00
|
|
|
|
--- a/src/copyout.c
|
|
|
|
|
|
+++ b/src/copyout.c
|
|
|
|
|
|
@@ -22,6 +22,7 @@
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
|
+#include <sys/xattr.h>
|
|
|
|
|
|
#include "filetypes.h"
|
|
|
|
|
|
#include "cpiohdr.h"
|
|
|
|
|
|
#include "dstring.h"
|
|
|
|
|
|
@@ -589,6 +590,94 @@ assign_string (char **pvar, char *value)
|
|
|
|
|
|
*pvar = p;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
+static int
|
|
|
|
|
|
+write_xattrs (int metadata_fd, char *path)
|
|
|
|
|
|
+{
|
|
|
|
|
|
+ struct metadata_hdr hdr = { .c_version = 1, .c_type = TYPE_XATTR };
|
|
|
|
|
|
+ char str[sizeof(hdr.c_size) + 1];
|
|
|
|
|
|
+ char *xattr_list = NULL;
|
|
|
|
|
|
+ char *list_ptr = NULL;
|
|
|
|
|
|
+ char *xattr_value = NULL;
|
|
|
|
|
|
+ ssize_t list_len, name_len, value_len, len;
|
|
|
|
|
|
+ int ret = -EINVAL;
|
|
|
|
|
|
+
|
|
|
|
|
|
+ if (metadata_fd < 0)
|
|
|
|
|
|
+ return 0;
|
|
|
|
|
|
+
|
|
|
|
|
|
+ list_len = llistxattr(path, NULL, 0);
|
|
|
|
|
|
+ if (list_len <= 0)
|
|
|
|
|
|
+ return -ENOENT;
|
|
|
|
|
|
+
|
|
|
|
|
|
+ list_ptr = xattr_list = malloc(list_len);
|
|
|
|
|
|
+ if (!list_ptr) {
|
|
|
|
|
|
+ error (0, 0, _("out of memory"));
|
|
|
|
|
|
+ return ret;
|
|
|
|
|
|
+ }
|
|
|
|
|
|
+
|
|
|
|
|
|
+ len = llistxattr(path, xattr_list, list_len);
|
|
|
|
|
|
+ if (len != list_len)
|
|
|
|
|
|
+ goto out;
|
|
|
|
|
|
+
|
|
|
|
|
|
+ if (ftruncate(metadata_fd, 0))
|
|
|
|
|
|
+ goto out;
|
|
|
|
|
|
+
|
|
|
|
|
|
+ lseek(metadata_fd, 0, SEEK_SET);
|
|
|
|
|
|
+
|
|
|
|
|
|
+ while (list_ptr < xattr_list + list_len) {
|
|
|
|
|
|
+ name_len = strlen(list_ptr);
|
|
|
|
|
|
+
|
|
|
|
|
|
+ value_len = lgetxattr(path, list_ptr, NULL, 0);
|
|
|
|
|
|
+ if (value_len < 0) {
|
|
|
|
|
|
+ error (0, 0, _("cannot get xattrs"));
|
|
|
|
|
|
+ break;
|
|
|
|
|
|
+ }
|
|
|
|
|
|
+
|
|
|
|
|
|
+ if (value_len) {
|
|
|
|
|
|
+ xattr_value = malloc(value_len);
|
|
|
|
|
|
+ if (!xattr_value) {
|
|
|
|
|
|
+ error (0, 0, _("out of memory"));
|
|
|
|
|
|
+ break;
|
|
|
|
|
|
+ }
|
|
|
|
|
|
+ } else {
|
|
|
|
|
|
+ xattr_value = NULL;
|
|
|
|
|
|
+ }
|
|
|
|
|
|
+
|
|
|
|
|
|
+ len = lgetxattr(path, list_ptr, xattr_value, value_len);
|
|
|
|
|
|
+ if (len != value_len)
|
|
|
|
|
|
+ break;
|
|
|
|
|
|
+
|
|
|
|
|
|
+ snprintf(str, sizeof(str), "%.8lx",
|
|
|
|
|
|
+ sizeof(hdr) + name_len + 1 + value_len);
|
|
|
|
|
|
+
|
|
|
|
|
|
+ memcpy(hdr.c_size, str, sizeof(hdr.c_size));
|
|
|
|
|
|
+
|
|
|
|
|
|
+ if (write(metadata_fd, &hdr, sizeof(hdr)) != sizeof(hdr))
|
|
|
|
|
|
+ break;
|
|
|
|
|
|
+
|
|
|
|
|
|
+ if (write(metadata_fd, list_ptr, name_len + 1) != name_len + 1)
|
|
|
|
|
|
+ break;
|
|
|
|
|
|
+
|
|
|
|
|
|
+ if (write(metadata_fd, xattr_value, value_len) != value_len)
|
|
|
|
|
|
+ break;
|
|
|
|
|
|
+
|
|
|
|
|
|
+ if (fsync(metadata_fd))
|
|
|
|
|
|
+ break;
|
|
|
|
|
|
+
|
|
|
|
|
|
+ list_ptr += name_len + 1;
|
|
|
|
|
|
+ free(xattr_value);
|
|
|
|
|
|
+ xattr_value = NULL;
|
|
|
|
|
|
+ }
|
|
|
|
|
|
+
|
|
|
|
|
|
+ free(xattr_value);
|
|
|
|
|
|
+out:
|
|
|
|
|
|
+ free(xattr_list);
|
|
|
|
|
|
+
|
|
|
|
|
|
+ if (list_ptr != xattr_list + list_len)
|
|
|
|
|
|
+ return ret;
|
|
|
|
|
|
+
|
|
|
|
|
|
+ return 0;
|
|
|
|
|
|
+}
|
|
|
|
|
|
+
|
|
|
|
|
|
/* Read a list of file names from the standard input
|
|
|
|
|
|
and write a cpio collection on the standard output.
|
|
|
|
|
|
The format of the header depends on the compatibility (-c) flag. */
|
2020-07-30 16:57:59 +08:00
|
|
|
|
@@ -603,6 +692,8 @@ process_copy_out ()
|
2020-07-02 11:13:51 +08:00
|
|
|
|
int in_file_des; /* Source file descriptor. */
|
|
|
|
|
|
int out_file_des; /* Output file descriptor. */
|
|
|
|
|
|
char *orig_file_name = NULL;
|
|
|
|
|
|
+ char template[] = "/tmp/cpio-metadata-XXXXXX";
|
|
|
|
|
|
+ int ret, metadata_fd, metadata = 0, old_metadata, hard_link;
|
|
|
|
|
|
|
|
|
|
|
|
/* Initialize the copy out. */
|
|
|
|
|
|
ds_init (&input_name, 128);
|
2020-07-30 16:57:59 +08:00
|
|
|
|
@@ -635,9 +726,37 @@ process_copy_out ()
|
2020-07-02 11:13:51 +08:00
|
|
|
|
prepare_append (out_file_des);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
+ /* Create a temporary file to store file metadata */
|
|
|
|
|
|
+ if (metadata_type != TYPE_NONE) {
|
|
|
|
|
|
+ metadata_fd = mkstemp(template);
|
|
|
|
|
|
+ if (metadata_fd < 0) {
|
|
|
|
|
|
+ error (0, 0, _("cannot create temporary file"));
|
|
|
|
|
|
+ return;
|
|
|
|
|
|
+ }
|
|
|
|
|
|
+ }
|
|
|
|
|
|
+
|
|
|
|
|
|
/* Copy files with names read from stdin. */
|
|
|
|
|
|
- while (ds_fgetstr (stdin, &input_name, name_end) != NULL)
|
|
|
|
|
|
+ while ((metadata_type != TYPE_NONE && metadata) ||
|
|
|
|
|
|
+ ds_fgetstr (stdin, &input_name, name_end) != NULL)
|
|
|
|
|
|
{
|
|
|
|
|
|
+ old_metadata = metadata;
|
|
|
|
|
|
+ hard_link = 0;
|
|
|
|
|
|
+
|
|
|
|
|
|
+ if (metadata) {
|
|
|
|
|
|
+ metadata = 0;
|
|
|
|
|
|
+
|
|
|
|
|
|
+ if (metadata_type != TYPE_XATTR) {
|
|
|
|
|
|
+ error (0, 0, _("metadata type not supported"));
|
|
|
|
|
|
+ continue;
|
|
|
|
|
|
+ }
|
|
|
|
|
|
+
|
|
|
|
|
|
+ ret = write_xattrs(metadata_fd, orig_file_name);
|
|
|
|
|
|
+ if (ret < 0)
|
|
|
|
|
|
+ continue;
|
|
|
|
|
|
+
|
|
|
|
|
|
+ ds_sgetstr (template, &input_name, name_end);
|
|
|
|
|
|
+ }
|
|
|
|
|
|
+
|
|
|
|
|
|
/* Check for blank line. */
|
|
|
|
|
|
if (input_name.ds_string[0] == 0)
|
|
|
|
|
|
{
|
2020-07-30 16:57:59 +08:00
|
|
|
|
@@ -667,8 +786,15 @@ process_copy_out ()
|
2020-07-02 11:13:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
-
|
|
|
|
|
|
- assign_string (&orig_file_name, input_name.ds_string);
|
|
|
|
|
|
+
|
|
|
|
|
|
+ if (old_metadata) {
|
|
|
|
|
|
+ assign_string (&orig_file_name, template);
|
|
|
|
|
|
+ ds_sgetstr (METADATA_FILENAME, &input_name, name_end);
|
|
|
|
|
|
+ file_hdr.c_mode |= 0x10000;
|
|
|
|
|
|
+ } else {
|
|
|
|
|
|
+ assign_string (&orig_file_name, input_name.ds_string);
|
|
|
|
|
|
+ }
|
|
|
|
|
|
+
|
|
|
|
|
|
cpio_safer_name_suffix (input_name.ds_string, false,
|
|
|
|
|
|
!no_abs_paths_flag, true);
|
2020-07-30 16:57:59 +08:00
|
|
|
|
cpio_set_c_name (&file_hdr, input_name.ds_string);
|
|
|
|
|
|
@@ -700,6 +826,7 @@ process_copy_out ()
|
2020-07-02 11:13:51 +08:00
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
add_link_defer (&file_hdr);
|
|
|
|
|
|
+ hard_link = 1;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-07-30 16:57:59 +08:00
|
|
|
|
@@ -836,6 +963,8 @@ process_copy_out ()
|
2020-07-02 11:13:51 +08:00
|
|
|
|
fprintf (stderr, "%s\n", orig_file_name);
|
|
|
|
|
|
if (dot_flag)
|
|
|
|
|
|
fputc ('.', stderr);
|
|
|
|
|
|
+ if (metadata_type != TYPE_NONE && !old_metadata && !hard_link)
|
|
|
|
|
|
+ metadata = 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-30 16:57:59 +08:00
|
|
|
|
@@ -875,6 +1004,11 @@ process_copy_out ()
|
2020-07-02 11:13:51 +08:00
|
|
|
|
(unsigned long) blocks), (unsigned long) blocks);
|
|
|
|
|
|
}
|
2020-07-30 16:57:59 +08:00
|
|
|
|
cpio_file_stat_free (&file_hdr);
|
2020-07-02 11:13:51 +08:00
|
|
|
|
+
|
|
|
|
|
|
+ if (metadata_type != TYPE_NONE) {
|
|
|
|
|
|
+ close(metadata_fd);
|
|
|
|
|
|
+ unlink(template);
|
|
|
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff --git a/src/dstring.c b/src/dstring.c
|
2020-07-30 16:57:59 +08:00
|
|
|
|
index e9c063f..1021d21 100644
|
2020-07-02 11:13:51 +08:00
|
|
|
|
--- a/src/dstring.c
|
|
|
|
|
|
+++ b/src/dstring.c
|
2020-07-30 16:57:59 +08:00
|
|
|
|
@@ -58,8 +58,8 @@ ds_resize (dynamic_string *string, int size)
|
2020-07-02 11:13:51 +08:00
|
|
|
|
Return NULL if end of file is detected. Otherwise,
|
|
|
|
|
|
Return a pointer to the null-terminated string in S. */
|
|
|
|
|
|
|
|
|
|
|
|
-char *
|
|
|
|
|
|
-ds_fgetstr (FILE *f, dynamic_string *s, char eos)
|
|
|
|
|
|
+static char *
|
|
|
|
|
|
+ds_fgetstr_common (FILE *f, char *input_string, dynamic_string *s, char eos)
|
|
|
|
|
|
{
|
|
|
|
|
|
int insize; /* Amount needed for line. */
|
|
|
|
|
|
int strsize; /* Amount allocated for S. */
|
2020-07-30 16:57:59 +08:00
|
|
|
|
@@ -70,7 +70,10 @@ ds_fgetstr (FILE *f, dynamic_string *s, char eos)
|
2020-07-02 11:13:51 +08:00
|
|
|
|
strsize = s->ds_length;
|
|
|
|
|
|
|
|
|
|
|
|
/* Read the input string. */
|
|
|
|
|
|
- next_ch = getc (f);
|
|
|
|
|
|
+ if (input_string)
|
|
|
|
|
|
+ next_ch = *input_string++;
|
|
|
|
|
|
+ else
|
|
|
|
|
|
+ next_ch = getc (f);
|
|
|
|
|
|
while (next_ch != eos && next_ch != EOF)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (insize >= strsize - 1)
|
2020-07-30 16:57:59 +08:00
|
|
|
|
@@ -79,7 +82,10 @@ ds_fgetstr (FILE *f, dynamic_string *s, char eos)
|
2020-07-02 11:13:51 +08:00
|
|
|
|
strsize = s->ds_length;
|
|
|
|
|
|
}
|
|
|
|
|
|
s->ds_string[insize++] = next_ch;
|
|
|
|
|
|
- next_ch = getc (f);
|
|
|
|
|
|
+ if (input_string)
|
|
|
|
|
|
+ next_ch = *input_string++;
|
|
|
|
|
|
+ else
|
|
|
|
|
|
+ next_ch = getc (f);
|
|
|
|
|
|
}
|
|
|
|
|
|
s->ds_string[insize++] = '\0';
|
|
|
|
|
|
|
2020-07-30 16:57:59 +08:00
|
|
|
|
@@ -90,6 +96,12 @@ ds_fgetstr (FILE *f, dynamic_string *s, char eos)
|
2020-07-02 11:13:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-30 16:57:59 +08:00
|
|
|
|
char *
|
2020-07-02 11:13:51 +08:00
|
|
|
|
+ds_fgetstr (FILE *f, dynamic_string *s, char eos)
|
|
|
|
|
|
+{
|
|
|
|
|
|
+ return ds_fgetstr_common (f, NULL, s, eos);
|
|
|
|
|
|
+}
|
|
|
|
|
|
+
|
2020-07-30 16:57:59 +08:00
|
|
|
|
+char *
|
2020-07-02 11:13:51 +08:00
|
|
|
|
ds_fgets (FILE *f, dynamic_string *s)
|
|
|
|
|
|
{
|
2020-07-30 16:57:59 +08:00
|
|
|
|
return ds_fgetstr (f, s, '\n');
|
|
|
|
|
|
@@ -100,3 +112,9 @@ ds_fgetname (FILE *f, dynamic_string *s)
|
2020-07-02 11:13:51 +08:00
|
|
|
|
{
|
|
|
|
|
|
return ds_fgetstr (f, s, '\0');
|
|
|
|
|
|
}
|
|
|
|
|
|
+
|
|
|
|
|
|
+char *
|
|
|
|
|
|
+ds_sgetstr (char *input_string, dynamic_string *s, char eos)
|
|
|
|
|
|
+{
|
|
|
|
|
|
+ return ds_fgetstr_common (NULL, input_string, s, eos);
|
|
|
|
|
|
+}
|
|
|
|
|
|
diff --git a/src/dstring.h b/src/dstring.h
|
2020-07-30 16:57:59 +08:00
|
|
|
|
index b5135fe..f5f95ec 100644
|
2020-07-02 11:13:51 +08:00
|
|
|
|
--- a/src/dstring.h
|
|
|
|
|
|
+++ b/src/dstring.h
|
|
|
|
|
|
@@ -49,3 +49,4 @@ void ds_resize (dynamic_string *string, int size);
|
|
|
|
|
|
char *ds_fgetname (FILE *f, dynamic_string *s);
|
|
|
|
|
|
char *ds_fgets (FILE *f, dynamic_string *s);
|
|
|
|
|
|
char *ds_fgetstr (FILE *f, dynamic_string *s, char eos);
|
|
|
|
|
|
+char *ds_sgetstr (char *input_string, dynamic_string *s, char eos);
|
|
|
|
|
|
diff --git a/src/extern.h b/src/extern.h
|
2020-07-30 16:57:59 +08:00
|
|
|
|
index 11ac6bf..f295fcf 100644
|
2020-07-02 11:13:51 +08:00
|
|
|
|
--- a/src/extern.h
|
|
|
|
|
|
+++ b/src/extern.h
|
|
|
|
|
|
@@ -19,6 +19,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
#include "paxlib.h"
|
|
|
|
|
|
#include "quotearg.h"
|
|
|
|
|
|
+#include "initramfs.h"
|
|
|
|
|
|
#include "quote.h"
|
|
|
|
|
|
|
|
|
|
|
|
enum archive_format
|
|
|
|
|
|
@@ -99,7 +100,8 @@ extern char output_is_seekable;
|
|
|
|
|
|
extern int (*xstat) ();
|
|
|
|
|
|
extern void (*copy_function) ();
|
|
|
|
|
|
extern char *change_directory_option;
|
|
|
|
|
|
-
|
|
|
|
|
|
+extern enum metadata_types metadata_type;
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
|
|
|
|
/* copyin.c */
|
|
|
|
|
|
void warn_junk_bytes (long bytes_skipped);
|
|
|
|
|
|
diff --git a/src/global.c b/src/global.c
|
2020-07-30 16:57:59 +08:00
|
|
|
|
index fb3abe9..0c40be0 100644
|
2020-07-02 11:13:51 +08:00
|
|
|
|
--- a/src/global.c
|
|
|
|
|
|
+++ b/src/global.c
|
|
|
|
|
|
@@ -199,3 +199,5 @@ char *change_directory_option;
|
|
|
|
|
|
int renumber_inodes_option;
|
|
|
|
|
|
int ignore_devno_option;
|
|
|
|
|
|
|
|
|
|
|
|
+/* include file metadata into the image */
|
|
|
|
|
|
+enum metadata_types metadata_type = TYPE_NONE;
|
|
|
|
|
|
diff --git a/src/initramfs.h b/src/initramfs.h
|
|
|
|
|
|
new file mode 100644
|
|
|
|
|
|
index 0000000..88abae7
|
|
|
|
|
|
--- /dev/null
|
|
|
|
|
|
+++ b/src/initramfs.h
|
|
|
|
|
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
+/* SPDX-License-Identifier: GPL-2.0+ */
|
|
|
|
|
|
+/*
|
|
|
|
|
|
+ * include/linux/initramfs.h
|
|
|
|
|
|
+ *
|
|
|
|
|
|
+ * Include file for file metadata in the initial ram disk.
|
|
|
|
|
|
+ */
|
|
|
|
|
|
+#ifndef _LINUX_INITRAMFS_H
|
|
|
|
|
|
+#define _LINUX_INITRAMFS_H
|
|
|
|
|
|
+
|
|
|
|
|
|
+#define METADATA_FILENAME "METADATA!!!"
|
|
|
|
|
|
+
|
|
|
|
|
|
+enum metadata_types { TYPE_NONE, TYPE_XATTR, TYPE__LAST };
|
|
|
|
|
|
+
|
|
|
|
|
|
+struct metadata_hdr {
|
|
|
|
|
|
+ char c_size[8]; /* total size including c_size field */
|
|
|
|
|
|
+ char c_version; /* header version */
|
|
|
|
|
|
+ char c_type; /* metadata type */
|
|
|
|
|
|
+ char c_metadata[]; /* metadata */
|
|
|
|
|
|
+} __attribute__((packed));
|
|
|
|
|
|
+
|
|
|
|
|
|
+#endif /*_LINUX_INITRAMFS_H*/
|
|
|
|
|
|
diff --git a/src/main.c b/src/main.c
|
2020-07-30 16:57:59 +08:00
|
|
|
|
index 6f90055..e343286 100644
|
2020-07-02 11:13:51 +08:00
|
|
|
|
--- a/src/main.c
|
|
|
|
|
|
+++ b/src/main.c
|
2020-07-30 16:57:59 +08:00
|
|
|
|
@@ -199,6 +199,8 @@ static struct argp_option options[] = {
|
2020-07-02 11:13:51 +08:00
|
|
|
|
{"device-independent", DEVICE_INDEPENDENT_OPTION, NULL, 0,
|
|
|
|
|
|
N_("Create device-independent (reproducible) archives") },
|
|
|
|
|
|
{"reproducible", 0, NULL, OPTION_ALIAS },
|
|
|
|
|
|
+ {"file-metadata", 'e', N_("TYPE"), 0,
|
|
|
|
|
|
+ N_("Include file metadata"), GRID+1 },
|
|
|
|
|
|
#undef GRID
|
|
|
|
|
|
|
|
|
|
|
|
/* ********** */
|
2020-07-30 16:57:59 +08:00
|
|
|
|
@@ -292,6 +294,22 @@ warn_control (char *arg)
|
2020-07-02 11:13:51 +08:00
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
+static enum metadata_types
|
|
|
|
|
|
+parse_metadata_type(char *arg)
|
|
|
|
|
|
+{
|
|
|
|
|
|
+ static char *metadata_type_str[TYPE__LAST] = {
|
|
|
|
|
|
+ [TYPE_NONE] = "none",
|
|
|
|
|
|
+ [TYPE_XATTR] = "xattr",
|
|
|
|
|
|
+ };
|
|
|
|
|
|
+ int i;
|
|
|
|
|
|
+
|
|
|
|
|
|
+ for (i = 0; i < TYPE__LAST; i++)
|
|
|
|
|
|
+ if (!strcmp (metadata_type_str[i], arg))
|
|
|
|
|
|
+ return i;
|
|
|
|
|
|
+
|
|
|
|
|
|
+ return TYPE_NONE;
|
|
|
|
|
|
+}
|
|
|
|
|
|
+
|
|
|
|
|
|
static error_t
|
|
|
|
|
|
parse_opt (int key, char *arg, struct argp_state *state)
|
|
|
|
|
|
{
|
2020-07-30 16:57:59 +08:00
|
|
|
|
@@ -354,6 +372,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
|
2020-07-02 11:13:51 +08:00
|
|
|
|
copy_matching_files = false;
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
+ case 'e': /* Metadata type. */
|
|
|
|
|
|
+ metadata_type = parse_metadata_type(arg);
|
|
|
|
|
|
+ break;
|
|
|
|
|
|
+
|
|
|
|
|
|
case 'E': /* Pattern file name. */
|
|
|
|
|
|
pattern_file_name = arg;
|
|
|
|
|
|
break;
|
|
|
|
|
|
--
|
2020-07-30 16:57:59 +08:00
|
|
|
|
1.8.3.1
|
2020-07-02 11:13:51 +08:00
|
|
|
|
|