summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bin/tar2sqfs/options.c11
-rw-r--r--bin/tar2sqfs/process_tarball.c21
-rw-r--r--bin/tar2sqfs/tar2sqfs.110
-rw-r--r--bin/tar2sqfs/tar2sqfs.h2
4 files changed, 43 insertions, 1 deletions
diff --git a/bin/tar2sqfs/options.c b/bin/tar2sqfs/options.c
index 19017a9..d9c4238 100644
--- a/bin/tar2sqfs/options.c
+++ b/bin/tar2sqfs/options.c
@@ -19,6 +19,7 @@ static struct option long_opts[] = {
{ "no-xattr", no_argument, NULL, 'x' },
{ "no-keep-time", no_argument, NULL, 'k' },
{ "exportable", no_argument, NULL, 'e' },
+ { "no-symlink-retarget", no_argument, NULL, 'S' },
{ "no-tail-packing", no_argument, NULL, 'T' },
{ "force", no_argument, NULL, 'f' },
{ "quiet", no_argument, NULL, 'q' },
@@ -27,7 +28,7 @@ static struct option long_opts[] = {
{ NULL, 0, NULL, 0 },
};
-static const char *short_opts = "r:c:b:B:d:X:j:Q:sxekfqThV";
+static const char *short_opts = "r:c:b:B:d:X:j:Q:sxekfqSThV";
static const char *usagestr =
"Usage: tar2sqfs [OPTIONS...] <sqfsfile>\n"
@@ -43,6 +44,10 @@ static const char *usagestr =
" xattrs, ...) are stored in the root inode.\n"
" If not set and a tarbal has an entry for './'\n"
" or '/', it becomes the root instead.\n"
+" --no-symlink-retarget, -S If --root-becomes is used, link targets are\n"
+" adjusted if they are prefixed by the root\n"
+" path. If this flag is set, symlinks are left\n"
+" untouched and only hard links are changed.\n"
"\n"
" --compressor, -c <name> Select the compressor to use.\n"
" A list of available compressors is below.\n"
@@ -90,6 +95,7 @@ static const char *usagestr =
bool dont_skip = false;
bool keep_time = true;
bool no_tail_pack = false;
+bool no_symlink_retarget = false;
sqfs_writer_cfg_t cfg;
char *root_becomes = NULL;
@@ -106,6 +112,9 @@ void process_args(int argc, char **argv)
break;
switch (i) {
+ case 'S':
+ no_symlink_retarget = true;
+ break;
case 'T':
no_tail_pack = true;
break;
diff --git a/bin/tar2sqfs/process_tarball.c b/bin/tar2sqfs/process_tarball.c
index 1de35fa..984a1ef 100644
--- a/bin/tar2sqfs/process_tarball.c
+++ b/bin/tar2sqfs/process_tarball.c
@@ -156,6 +156,7 @@ int process_tarball(FILE *input_file, sqfs_writer_t *sqfs)
sqfs_u64 offset, count;
sparse_map_t *m;
size_t rootlen;
+ char *target;
int ret;
rootlen = root_becomes == NULL ? 0 : strlen(root_becomes);
@@ -204,6 +205,26 @@ int process_tarball(FILE *input_file, sqfs_writer_t *sqfs)
stderr);
skip = true;
}
+
+ if (hdr.link_target != NULL &&
+ (hdr.is_hard_link || !no_symlink_retarget)) {
+ target = strdup(hdr.link_target);
+ if (target == NULL) {
+ fprintf(stderr, "packing '%s': %s\n",
+ hdr.name, strerror(errno));
+ goto fail;
+ }
+
+ if (canonicalize_name(target) == 0 &&
+ !strncmp(target, root_becomes, rootlen) &&
+ target[rootlen] == '/') {
+ memmove(hdr.link_target,
+ target + rootlen,
+ strlen(target + rootlen) + 1);
+ }
+
+ free(target);
+ }
} else if (hdr.name[0] == '\0') {
is_root = true;
}
diff --git a/bin/tar2sqfs/tar2sqfs.1 b/bin/tar2sqfs/tar2sqfs.1
index da344ec..a2eb084 100644
--- a/bin/tar2sqfs/tar2sqfs.1
+++ b/bin/tar2sqfs/tar2sqfs.1
@@ -20,6 +20,16 @@ paths this way, i.e. if the archive contains an entry for \fB./\fR, it becomes
the root node and the prefix is stripped from all paths (and similar for
absolute paths and \fB/\fR).
.TP
+\fB\-\-no\-symlink\-retarget\fR, \fB\-S\fR
+If \-\-root\-becomes is used, link targets are adjusted if they are prefixed by
+the root path. By default, this is also done on symbolic links, that have a
+target that is prefixed by the root path and they are converted to aboluste
+paths with the prefix removed. However, because symlinks can point across mount
+points, this may actually be intended for some use cases.
+
+This flag allows changing the default behaviour, so only hard links are
+retargeted.
+.TP
\fB\-\-compressor\fR, \fB\-c\fR <name>
Select the compressor to use.
Run \fBtar2sqfs \-\-help\fR to get a list of all available compressors
diff --git a/bin/tar2sqfs/tar2sqfs.h b/bin/tar2sqfs/tar2sqfs.h
index a27a50b..08cdc4d 100644
--- a/bin/tar2sqfs/tar2sqfs.h
+++ b/bin/tar2sqfs/tar2sqfs.h
@@ -17,6 +17,7 @@
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
+#include <errno.h>
#ifdef _WIN32
#include <io.h>
@@ -26,6 +27,7 @@
extern bool dont_skip;
extern bool keep_time;
extern bool no_tail_pack;
+extern bool no_symlink_retarget;
extern sqfs_writer_cfg_t cfg;
extern char *root_becomes;