diff options
-rw-r--r-- | bin/tar2sqfs/options.c | 11 | ||||
-rw-r--r-- | bin/tar2sqfs/process_tarball.c | 21 | ||||
-rw-r--r-- | bin/tar2sqfs/tar2sqfs.1 | 10 | ||||
-rw-r--r-- | bin/tar2sqfs/tar2sqfs.h | 2 |
4 files changed, 43 insertions, 1 deletions
diff --git a/bin/tar2sqfs/options.c b/bin/tar2sqfs/options.c index b631a1e..7727a47 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" @@ -42,6 +43,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" @@ -83,6 +88,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; @@ -119,6 +125,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 7492f27..40a8157 100644 --- a/bin/tar2sqfs/process_tarball.c +++ b/bin/tar2sqfs/process_tarball.c @@ -203,6 +203,7 @@ int process_tarball(istream_t *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); @@ -251,6 +252,26 @@ int process_tarball(istream_t *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 300ab81..2098e8e 100644 --- a/bin/tar2sqfs/tar2sqfs.1 +++ b/bin/tar2sqfs/tar2sqfs.1 @@ -23,6 +23,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 d127aa0..915d89c 100644 --- a/bin/tar2sqfs/tar2sqfs.h +++ b/bin/tar2sqfs/tar2sqfs.h @@ -16,11 +16,13 @@ #include <getopt.h> #include <string.h> #include <stdio.h> +#include <errno.h> /* options.c */ 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; |