]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Add --gid, --gname, --uid, --uname options to tar.
authorTim Kientzle <kientzle@gmail.com>
Sat, 1 May 2010 21:18:38 +0000 (17:18 -0400)
committerTim Kientzle <kientzle@gmail.com>
Sat, 1 May 2010 21:18:38 +0000 (17:18 -0400)
These allow you to override the user/group information both
when creating an archive and when restoring an archive.
I've also reimplemented --numeric-owner to be a synonym
for --gname="" --uname="".

Still needs tests...

SVN-Revision: 2349

tar/bsdtar.1
tar/bsdtar.c
tar/bsdtar.h
tar/cmdline.c
tar/read.c
tar/write.c

index 1aa49496374cfd1d368d2e0c32c244707e8f913b..41e35ccdc3df5dfd1bddb3aa3aad0d84a1d33d5b 100644 (file)
@@ -199,6 +199,27 @@ the default is
 .Pa /dev/sa0 ;
 on Linux, the default is
 .Pa /dev/st0 .
+.It Fl Fl gid Ar id
+Use the provided group id number.
+On extract, this overrides the group id in the archive;
+the group name in the archive will be ignored.
+On create, this overrides the group id read from disk;
+if
+.Fl Fl gname
+is not also specified, the group name will be set to
+match the group id.
+.It Fl Fl gname Ar name
+Use the provided group name.
+On extract, this overrides the group name in the archive;
+if the provided group name does not exist on the system,
+the group id
+(from the archive or from the
+.Fl Fl gid
+option)
+will be used instead.
+On create, this sets the group name that will be stored
+in the archive;
+the name will not be verified against the system group database.
 .It Fl H
 (c and r mode only)
 Symbolic links named on the command line will be followed; the
@@ -331,9 +352,15 @@ and the default behavior if
 .Nm
 is run as non-root.
 .It Fl Fl numeric-owner
-(x mode only)
-Ignore symbolic user and group names when restoring archives to disk,
-only numeric uid and gid values will be obeyed.
+This is equivalent to
+.Fl Fl uname
+.Qq
+.Fl Fl gname
+.Qq .
+On extract, it causes user and group names in the archive
+to be ignored in favor of the numeric user and group ids.
+On create, it causes user and group names to not be stored
+in the archive.
 .It Fl O , Fl Fl to-stdout
 (x, t modes only)
 In extract (-x) mode, files will be written to standard out rather than
@@ -543,6 +570,25 @@ This flag also causes
 to remove intervening directory symlinks instead of
 reporting an error.
 See the SECURITY section below for more details.
+.It Fl Fl uid Ar id
+Use the provided user id number and ignore the user
+name from the archive.
+On create, if
+.Fl Fl uname
+is not also specified, the user name will be set to
+match the user id.
+.It Fl Fl uname Ar name
+Use the provided user name.
+On extract, this overrides the user name in the archive;
+if the provided user name does not exist on the system,
+it will be ignored and the user id
+(from the archive or from the
+.Fl Fl uid
+option)
+will be used instead.
+On create, this sets the user name that will be stored
+in the archive;
+the name is not verified against the system user database.
 .It Fl Fl use-compress-program Ar program
 Pipe the input (in x or t mode) or the output (in c mode) through
 .Pa program
index eb0fd70e2ea3a5e329d4ee78ee64f6b6b3dd47c2..f0690fa3b56ce301739568bc994de746b978b4cb 100644 (file)
@@ -149,6 +149,8 @@ main(int argc, char **argv)
        bsdtar = &bsdtar_storage;
        memset(bsdtar, 0, sizeof(*bsdtar));
        bsdtar->fd = -1; /* Mark as "unused" */
+       bsdtar->gid = -1;
+       bsdtar->uid = -1;
        option_o = 0;
 
 #if defined(HAVE_SIGACTION) && (defined(SIGINFO) || defined(SIGUSR1))
@@ -278,12 +280,19 @@ main(int argc, char **argv)
                case OPTION_FORMAT: /* GNU tar, others */
                        bsdtar->create_format = bsdtar->optarg;
                        break;
-               case OPTION_OPTIONS:
-                       bsdtar->option_options = bsdtar->optarg;
-                       break;
                case 'f': /* SUSv2 */
                        bsdtar->filename = bsdtar->optarg;
                        break;
+               case OPTION_GID: /* cpio */
+                       t = atoi(bsdtar->optarg);
+                       if (t < 0)
+                               lafe_errc(1, 0,
+                                   "Argument to --gid must be positive");
+                       bsdtar->gid = t;
+                       break;
+               case OPTION_GNAME: /* cpio */
+                       bsdtar->gname = bsdtar->optarg;
+                       break;
                case 'H': /* BSD convention */
                        bsdtar->symlink_mode = 'H';
                        break;
@@ -411,7 +420,8 @@ main(int argc, char **argv)
                        bsdtar->option_null++;
                        break;
                case OPTION_NUMERIC_OWNER: /* GNU tar */
-                       bsdtar->option_numeric_owner++;
+                       bsdtar->uname = "";
+                       bsdtar->gname = "";
                        break;
                case 'O': /* GNU tar */
                        bsdtar->option_stdout = 1;
@@ -422,6 +432,9 @@ main(int argc, char **argv)
                case OPTION_ONE_FILE_SYSTEM: /* GNU tar */
                        bsdtar->option_dont_traverse_mounts = 1;
                        break;
+               case OPTION_OPTIONS:
+                       bsdtar->option_options = bsdtar->optarg;
+                       break;
 #if 0
                /*
                 * The common BSD -P option is not necessary, since
@@ -487,6 +500,16 @@ main(int argc, char **argv)
                case 'u': /* SUSv2 */
                        set_mode(bsdtar, opt);
                        break;
+               case OPTION_UID: /* cpio */
+                       t = atoi(bsdtar->optarg);
+                       if (t < 0)
+                               lafe_errc(1, 0,
+                                   "Argument to --uid must be positive");
+                       bsdtar->uid = t;
+                       break;
+               case OPTION_UNAME: /* cpio */
+                       bsdtar->uname = bsdtar->optarg;
+                       break;
                case 'v': /* SUSv2 */
                        bsdtar->verbose++;
                        break;
index 33371a47de43a71ae8193cc09265b3f10e1f7647..97826b288f40ebd378869c7c5217fd5104cfc9c3 100644 (file)
@@ -54,6 +54,10 @@ struct bsdtar {
        int               verbose;   /* -v */
        int               extract_flags; /* Flags for extract operation */
        int               strip_components; /* Remove this many leading dirs */
+       int               gid;  /* --gid */
+       const char       *gname; /* --gname */
+       int               uid;  /* --uid */
+       const char       *uname; /* --uname */
        char              mode; /* Program mode: 'c', 't', 'r', 'u', 'x' */
        char              symlink_mode; /* H or L, per BSD conventions */
        char              create_compression; /* j, y, or z */
@@ -68,7 +72,6 @@ struct bsdtar {
        char              option_no_owner; /* -o */
        char              option_no_subdirs; /* -n */
        char              option_null; /* --null */
-       char              option_numeric_owner; /* --numeric-owner */
        char              option_stdout; /* -O */
        char              option_totals; /* --totals */
        char              option_unlink_first; /* -U */
@@ -113,7 +116,8 @@ enum {
        OPTION_DISABLE_COPYFILE,
        OPTION_EXCLUDE,
        OPTION_FORMAT,
-       OPTION_OPTIONS,
+       OPTION_GID,
+       OPTION_GNAME,
        OPTION_HELP,
        OPTION_INCLUDE,
        OPTION_KEEP_NEWER_FILES,
@@ -128,10 +132,13 @@ enum {
        OPTION_NULL,
        OPTION_NUMERIC_OWNER,
        OPTION_ONE_FILE_SYSTEM,
+       OPTION_OPTIONS,
        OPTION_POSIX,
        OPTION_SAME_OWNER,
        OPTION_STRIP_COMPONENTS,
        OPTION_TOTALS,
+       OPTION_UID,
+       OPTION_UNAME,
        OPTION_USE_COMPRESS_PROGRAM,
        OPTION_VERSION
 };
index f53a7638530058dcf460ad055b4a0fa246f14d22..22346f154502db98a8a56fde874734fbd0f534c2 100644 (file)
@@ -85,6 +85,8 @@ static struct option {
        { "file",                 1, 'f' },
        { "files-from",           1, 'T' },
        { "format",               1, OPTION_FORMAT },
+       { "gid",                  1, OPTION_GID },
+       { "gname",                1, OPTION_GNAME },
        { "gunzip",               0, 'z' },
        { "gzip",                 0, 'z' },
        { "help",                 0, OPTION_HELP },
@@ -119,6 +121,8 @@ static struct option {
        { "strip-components",     1, OPTION_STRIP_COMPONENTS },
        { "to-stdout",            0, 'O' },
        { "totals",               0, OPTION_TOTALS },
+       { "uid",                  1, OPTION_UID },
+       { "uname",                1, OPTION_UNAME },
        { "uncompress",           0, 'Z' },
        { "unlink",               0, 'U' },
        { "unlink-first",         0, 'U' },
index b6b4a7e9f9859d012f29a95faf4d22bf8b2bb8ef..d5520dcbb243b23ffabb3bef4e3c8f6c04704f25 100644 (file)
@@ -204,10 +204,18 @@ read_archive(struct bsdtar *bsdtar, char mode)
                if (r == ARCHIVE_FATAL)
                        break;
 
-               if (bsdtar->option_numeric_owner) {
+               if (bsdtar->uid >= 0) {
+                       archive_entry_set_uid(entry, bsdtar->uid);
                        archive_entry_set_uname(entry, NULL);
+               }
+               if (bsdtar->gid >= 0) {
+                       archive_entry_set_gid(entry, bsdtar->gid);
                        archive_entry_set_gname(entry, NULL);
                }
+               if (bsdtar->uname)
+                       archive_entry_set_uname(entry, bsdtar->uname);
+               if (bsdtar->gname >= 0)
+                       archive_entry_set_gname(entry, bsdtar->gname);
 
                /*
                 * Exclude entries that are too old.
index ab370385cd5703d8d8b2f89d5519828f014ce2f1..4f3b5df17652ca39271e3c22aba10f19f7af7e6a 100644 (file)
@@ -833,6 +833,24 @@ write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path)
 #endif
                r = archive_read_disk_entry_from_file(bsdtar->diskreader,
                    entry, -1, st);
+               if (bsdtar->uid >= 0) {
+                       archive_entry_set_uid(entry, bsdtar->uid);
+                       if (!bsdtar->uname)
+                               archive_entry_set_gname(entry,
+                                   archive_read_disk_uname(bsdtar->diskreader,
+                                       bsdtar->uid));
+               }
+               if (bsdtar->gid >= 0) {
+                       archive_entry_set_gid(entry, bsdtar->gid);
+                       if (!bsdtar->gname)
+                               archive_entry_set_gname(entry,
+                                   archive_read_disk_gname(bsdtar->diskreader,
+                                       bsdtar->gid));
+               }
+               if (bsdtar->uname)
+                       archive_entry_set_uname(entry, bsdtar->uname);
+               if (bsdtar->gname)
+                       archive_entry_set_uname(entry, bsdtar->gname);
                if (r != ARCHIVE_OK)
                        lafe_warnc(archive_errno(bsdtar->diskreader),
                            "%s", archive_error_string(bsdtar->diskreader));