|
|
022f11 |
From a9492cf1a031ddcec9d2e6f879731bc49122e7e1 Mon Sep 17 00:00:00 2001
|
|
|
022f11 |
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
|
022f11 |
Date: Thu, 29 Aug 2013 13:26:51 +0100
|
|
|
022f11 |
Subject: [PATCH] daemon: tar: Use a temporary file to pass excludes to tar
|
|
|
022f11 |
command (RHBZ#1001875).
|
|
|
022f11 |
|
|
|
022f11 |
Use tar -X option instead of tar --exclude=... option.
|
|
|
022f11 |
|
|
|
022f11 |
(cherry picked from commit 91c162586cc2170ea224016307016153f3d081b5)
|
|
|
022f11 |
---
|
|
|
022f11 |
daemon/tar.c | 78 +++++++++++++++++++++++++++++++++++-------------------------
|
|
|
022f11 |
1 file changed, 46 insertions(+), 32 deletions(-)
|
|
|
022f11 |
|
|
|
022f11 |
diff --git a/daemon/tar.c b/daemon/tar.c
|
|
|
022f11 |
index 51f82f8..da19de7 100644
|
|
|
022f11 |
--- a/daemon/tar.c
|
|
|
022f11 |
+++ b/daemon/tar.c
|
|
|
022f11 |
@@ -239,41 +239,60 @@ do_txz_in (const char *dir)
|
|
|
022f11 |
return do_tar_in (dir, "xz");
|
|
|
022f11 |
}
|
|
|
022f11 |
|
|
|
022f11 |
-/* Turn list 'excludes' into list of " --excludes=..." strings, all
|
|
|
022f11 |
- * properly quoted. Caller must free the returned string.
|
|
|
022f11 |
+/* Turn list 'excludes' into a temporary file, and return a string
|
|
|
022f11 |
+ * containing the temporary file name. Caller must unlink the file
|
|
|
022f11 |
+ * and free the string.
|
|
|
022f11 |
*/
|
|
|
022f11 |
static char *
|
|
|
022f11 |
-make_excludes_args (char *const *excludes)
|
|
|
022f11 |
+make_exclude_from_file (char *const *excludes)
|
|
|
022f11 |
{
|
|
|
022f11 |
- DECLARE_STRINGSBUF (strings);
|
|
|
022f11 |
size_t i;
|
|
|
022f11 |
- char *s, *ret;
|
|
|
022f11 |
+ int fd;
|
|
|
022f11 |
+ char template[] = "/tmp/excludesXXXXXX";
|
|
|
022f11 |
+ char *ret;
|
|
|
022f11 |
+
|
|
|
022f11 |
+ fd = mkstemp (template);
|
|
|
022f11 |
+ if (fd == -1) {
|
|
|
022f11 |
+ reply_with_perror ("mkstemp");
|
|
|
022f11 |
+ return NULL;
|
|
|
022f11 |
+ }
|
|
|
022f11 |
|
|
|
022f11 |
for (i = 0; excludes[i] != NULL; ++i) {
|
|
|
022f11 |
- if (asprintf_nowarn (&s, " --exclude=%Q", excludes[i]) == -1) {
|
|
|
022f11 |
- reply_with_perror ("asprintf");
|
|
|
022f11 |
- free_stringslen (strings.argv, strings.size);
|
|
|
022f11 |
- return NULL;
|
|
|
022f11 |
+ if (strchr (excludes[i], '\n')) {
|
|
|
022f11 |
+ reply_with_error ("tar-out: excludes file patterns cannot contain \\n character");
|
|
|
022f11 |
+ goto error;
|
|
|
022f11 |
}
|
|
|
022f11 |
- if (add_string_nodup (&strings, s) == -1) {
|
|
|
022f11 |
- free (s);
|
|
|
022f11 |
- return NULL;
|
|
|
022f11 |
+
|
|
|
022f11 |
+ if (xwrite (fd, excludes[i], strlen (excludes[i])) == -1 ||
|
|
|
022f11 |
+ xwrite (fd, "\n", 1) == -1) {
|
|
|
022f11 |
+ reply_with_perror ("write");
|
|
|
022f11 |
+ goto error;
|
|
|
022f11 |
}
|
|
|
022f11 |
- }
|
|
|
022f11 |
|
|
|
022f11 |
- if (end_stringsbuf (&strings) == -1)
|
|
|
022f11 |
- return NULL;
|
|
|
022f11 |
+ if (verbose)
|
|
|
022f11 |
+ fprintf (stderr, "tar-out: adding excludes pattern '%s'\n", excludes[i]);
|
|
|
022f11 |
+ }
|
|
|
022f11 |
|
|
|
022f11 |
- ret = concat_strings (strings.argv);
|
|
|
022f11 |
- if (!ret) {
|
|
|
022f11 |
- reply_with_perror ("concat");
|
|
|
022f11 |
- free_stringslen (strings.argv, strings.size);
|
|
|
022f11 |
- return NULL;
|
|
|
022f11 |
+ if (close (fd) == -1) {
|
|
|
022f11 |
+ reply_with_perror ("close");
|
|
|
022f11 |
+ fd = -1;
|
|
|
022f11 |
+ goto error;
|
|
|
022f11 |
}
|
|
|
022f11 |
+ fd = -1;
|
|
|
022f11 |
|
|
|
022f11 |
- free_stringslen (strings.argv, strings.size);
|
|
|
022f11 |
+ ret = strdup (template);
|
|
|
022f11 |
+ if (ret == NULL) {
|
|
|
022f11 |
+ reply_with_perror ("strdup");
|
|
|
022f11 |
+ goto error;
|
|
|
022f11 |
+ }
|
|
|
022f11 |
|
|
|
022f11 |
return ret;
|
|
|
022f11 |
+
|
|
|
022f11 |
+ error:
|
|
|
022f11 |
+ if (fd >= 0)
|
|
|
022f11 |
+ close (fd);
|
|
|
022f11 |
+ unlink (template);
|
|
|
022f11 |
+ return NULL;
|
|
|
022f11 |
}
|
|
|
022f11 |
|
|
|
022f11 |
/* Has one FileOut parameter. */
|
|
|
022f11 |
@@ -287,7 +306,7 @@ do_tar_out (const char *dir, const char *compress, int numericowner,
|
|
|
022f11 |
const char *filter;
|
|
|
022f11 |
int r;
|
|
|
022f11 |
FILE *fp;
|
|
|
022f11 |
- CLEANUP_FREE char *excludes_args = NULL;
|
|
|
022f11 |
+ CLEANUP_UNLINK_FREE char *exclude_from_file = NULL;
|
|
|
022f11 |
CLEANUP_FREE char *cmd = NULL;
|
|
|
022f11 |
char buffer[GUESTFS_MAX_CHUNK_SIZE];
|
|
|
022f11 |
|
|
|
022f11 |
@@ -313,15 +332,9 @@ do_tar_out (const char *dir, const char *compress, int numericowner,
|
|
|
022f11 |
numericowner = 0;
|
|
|
022f11 |
|
|
|
022f11 |
if ((optargs_bitmask & GUESTFS_TAR_OUT_EXCLUDES_BITMASK)) {
|
|
|
022f11 |
- excludes_args = make_excludes_args (excludes);
|
|
|
022f11 |
- if (!excludes_args)
|
|
|
022f11 |
- return -1;
|
|
|
022f11 |
- } else {
|
|
|
022f11 |
- excludes_args = strdup ("");
|
|
|
022f11 |
- if (excludes_args == NULL) {
|
|
|
022f11 |
- reply_with_perror ("strdup");
|
|
|
022f11 |
+ exclude_from_file = make_exclude_from_file (excludes);
|
|
|
022f11 |
+ if (!exclude_from_file)
|
|
|
022f11 |
return -1;
|
|
|
022f11 |
- }
|
|
|
022f11 |
}
|
|
|
022f11 |
|
|
|
022f11 |
/* Check the filename exists and is a directory (RHBZ#908322). */
|
|
|
022f11 |
@@ -342,11 +355,12 @@ do_tar_out (const char *dir, const char *compress, int numericowner,
|
|
|
022f11 |
}
|
|
|
022f11 |
|
|
|
022f11 |
/* "tar -C /sysroot%s -cf - ." but we have to quote the dir. */
|
|
|
022f11 |
- if (asprintf_nowarn (&cmd, "%s -C %Q%s%s%s -cf - .",
|
|
|
022f11 |
+ if (asprintf_nowarn (&cmd, "%s -C %Q%s%s%s%s -cf - .",
|
|
|
022f11 |
str_tar,
|
|
|
022f11 |
buf, filter,
|
|
|
022f11 |
numericowner ? " --numeric-owner" : "",
|
|
|
022f11 |
- excludes_args) == -1) {
|
|
|
022f11 |
+ exclude_from_file ? " -X " : "",
|
|
|
022f11 |
+ exclude_from_file ? exclude_from_file : "") == -1) {
|
|
|
022f11 |
reply_with_perror ("asprintf");
|
|
|
022f11 |
return -1;
|
|
|
022f11 |
}
|
|
|
022f11 |
--
|
|
|
022f11 |
1.8.3.1
|
|
|
022f11 |
|