PR/50119: Thomas Klausner: Add --timestamp option to tar.
This commit is contained in:
parent
d8a9f2abfc
commit
9158fb657d
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: options.c,v 1.116 2015/04/11 15:41:33 christos Exp $ */
|
||||
/* $NetBSD: options.c,v 1.117 2015/12/19 18:28:54 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -42,7 +42,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 4/18/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: options.c,v 1.116 2015/04/11 15:41:33 christos Exp $");
|
||||
__RCSID("$NetBSD: options.c,v 1.117 2015/12/19 18:28:54 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -64,6 +64,7 @@ __RCSID("$NetBSD: options.c,v 1.116 2015/04/11 15:41:33 christos Exp $");
|
|||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include <paths.h>
|
||||
#include <util.h>
|
||||
#include "pax.h"
|
||||
#include "options.h"
|
||||
#include "cpio.h"
|
||||
|
@ -76,6 +77,7 @@ __RCSID("$NetBSD: options.c,v 1.116 2015/04/11 15:41:33 christos Exp $");
|
|||
/*
|
||||
* Routines which handle command line options
|
||||
*/
|
||||
struct stat tst; /* Timestamp to set if non-0 */
|
||||
|
||||
static int nopids; /* tar mode: suppress "pids" for -p option */
|
||||
static char flgch[] = FLGCH; /* list of all possible flags (pax) */
|
||||
|
@ -88,6 +90,9 @@ static void printflg(unsigned int);
|
|||
static int c_frmt(const void *, const void *);
|
||||
static off_t str_offt(char *);
|
||||
static char *get_line(FILE *fp);
|
||||
#ifndef SMALL
|
||||
static int set_tstamp(const char *, struct stat *);
|
||||
#endif
|
||||
static void pax_options(int, char **);
|
||||
__dead static void pax_usage(void);
|
||||
static void tar_options(int, char **);
|
||||
|
@ -129,8 +134,9 @@ static int get_line_error;
|
|||
#define OPT_SPARSE 16
|
||||
#define OPT_XZ 17
|
||||
#define OPT_GNU 18
|
||||
#define OPT_TIMESTAMP 19
|
||||
#if !HAVE_NBTOOL_CONFIG_H
|
||||
#define OPT_CHROOT 19
|
||||
#define OPT_CHROOT 20
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -803,6 +809,8 @@ struct option tar_longopts[] = {
|
|||
{ "chroot", no_argument, 0,
|
||||
OPT_CHROOT },
|
||||
#endif
|
||||
{ "timestamp", required_argument, 0,
|
||||
OPT_TIMESTAMP },
|
||||
#if 0 /* Not implemented */
|
||||
{ "catenate", no_argument, 0, 'A' }, /* F */
|
||||
{ "concatenate", no_argument, 0, 'A' }, /* F */
|
||||
|
@ -1143,6 +1151,14 @@ tar_options(int argc, char **argv)
|
|||
case OPT_CHROOT:
|
||||
do_chroot = 1;
|
||||
break;
|
||||
#endif
|
||||
#ifndef SMALL
|
||||
case OPT_TIMESTAMP:
|
||||
if (set_tstamp(optarg, &tst) == -1) {
|
||||
tty_warn(1, "Invalid timestamp `%s'", optarg);
|
||||
tar_usage();
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
tar_usage();
|
||||
|
@ -2083,6 +2099,43 @@ get_line(FILE *f)
|
|||
return temp;
|
||||
}
|
||||
|
||||
#ifndef SMALL
|
||||
/*
|
||||
* set_tstamp()
|
||||
* Use a specific timestamp for all individual files created in the
|
||||
* archive
|
||||
*/
|
||||
static int
|
||||
set_tstamp(const char *b, struct stat *st)
|
||||
{
|
||||
time_t when;
|
||||
char *eb;
|
||||
long long l;
|
||||
|
||||
if (stat(b, st) != -1)
|
||||
return 0;
|
||||
|
||||
#ifndef HAVE_NBTOOL_CONFIG_H
|
||||
errno = 0;
|
||||
if ((when = parsedate(b, NULL, NULL)) == -1 && errno != 0)
|
||||
#endif
|
||||
{
|
||||
errno = 0;
|
||||
l = strtoll(b, &eb, 0);
|
||||
if (b == eb || *eb || errno)
|
||||
return -1;
|
||||
when = (time_t)l;
|
||||
}
|
||||
|
||||
st->st_ino = 1;
|
||||
#if HAVE_STRUCT_STAT_BIRTHTIME
|
||||
st->st_birthtime =
|
||||
#endif
|
||||
st->st_mtime = st->st_ctime = st->st_atime = when;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* no_op()
|
||||
* for those option functions where the archive format has nothing to do.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: tar.1,v 1.35 2015/04/11 16:22:07 wiz Exp $
|
||||
.\" $NetBSD: tar.1,v 1.36 2015/12/19 18:28:54 christos Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1996 SigmaSoft, Th. Lockert
|
||||
.\" All rights reserved.
|
||||
|
@ -25,7 +25,7 @@
|
|||
.\"
|
||||
.\" OpenBSD: tar.1,v 1.28 2000/11/09 23:58:56 aaron Exp
|
||||
.\"
|
||||
.Dd April 11, 2015
|
||||
.Dd December 19, 2015
|
||||
.Dt TAR 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -297,6 +297,19 @@ can be processed.
|
|||
Cause files of type directory being copied or archived, or archive members of
|
||||
type directory being extracted, to match only the directory file or archive
|
||||
member and not the file hierarchy rooted at the directory.
|
||||
.It Fl Fl timestamp Ar timestamp
|
||||
Store all modification times in the archive with the
|
||||
.Ar timestamp
|
||||
given instead of the actual modification time of the individual archive member
|
||||
so that repeatable builds are possible.
|
||||
The
|
||||
.Ar timestamp
|
||||
can be a
|
||||
.Pa pathname ,
|
||||
where the timestamps are derived from that file, a parseable date for
|
||||
.Xr parsedate 3
|
||||
(this option is not yet available in the tools build), or an integer value
|
||||
interpreted as the number of seconds from the Epoch.
|
||||
.El
|
||||
.Pp
|
||||
The options
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: tar.c,v 1.72 2015/06/16 22:31:08 christos Exp $ */
|
||||
/* $NetBSD: tar.c,v 1.73 2015/12/19 18:28:54 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -42,7 +42,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)tar.c 8.2 (Berkeley) 4/18/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: tar.c,v 1.72 2015/06/16 22:31:08 christos Exp $");
|
||||
__RCSID("$NetBSD: tar.c,v 1.73 2015/12/19 18:28:54 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -64,6 +64,8 @@ __RCSID("$NetBSD: tar.c,v 1.72 2015/06/16 22:31:08 christos Exp $");
|
|||
#include "extern.h"
|
||||
#include "tar.h"
|
||||
|
||||
extern struct stat tst;
|
||||
|
||||
/*
|
||||
* Routines for reading, writing and header identify of various versions of tar
|
||||
*/
|
||||
|
@ -587,6 +589,7 @@ tar_wr(ARCHD *arcn)
|
|||
{
|
||||
HD_TAR *hd;
|
||||
int len;
|
||||
uintmax_t mtime;
|
||||
char hdblk[sizeof(HD_TAR)];
|
||||
|
||||
/*
|
||||
|
@ -695,10 +698,11 @@ tar_wr(ARCHD *arcn)
|
|||
/*
|
||||
* copy those fields that are independent of the type
|
||||
*/
|
||||
mtime = tst.st_ino ? tst.st_mtime : arcn->sb.st_mtime;
|
||||
if (u32_oct((uintmax_t)arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 0) ||
|
||||
u32_oct((uintmax_t)arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 0) ||
|
||||
u32_oct((uintmax_t)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 0) ||
|
||||
u32_oct((uintmax_t)arcn->sb.st_mtime, hd->mtime, sizeof(hd->mtime), 1))
|
||||
u32_oct(mtime, hd->mtime, sizeof(hd->mtime), 1))
|
||||
goto out;
|
||||
|
||||
/*
|
||||
|
@ -1046,6 +1050,7 @@ ustar_wr(ARCHD *arcn)
|
|||
{
|
||||
HD_USTAR *hd;
|
||||
char *pt;
|
||||
uintmax_t mtime;
|
||||
char hdblk[sizeof(HD_USTAR)];
|
||||
const char *user, *group;
|
||||
|
||||
|
@ -1210,7 +1215,8 @@ ustar_wr(ARCHD *arcn)
|
|||
return size_err("UID", arcn);
|
||||
if (u32_oct((uintmax_t)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 3))
|
||||
return size_err("GID", arcn);
|
||||
if (u32_oct((uintmax_t)arcn->sb.st_mtime,hd->mtime,sizeof(hd->mtime),3))
|
||||
mtime = tst.st_ino ? tst.st_mtime : arcn->sb.st_mtime;
|
||||
if (u32_oct(mtime, hd->mtime, sizeof(hd->mtime), 3))
|
||||
return size_err("MTIME", arcn);
|
||||
user = user_from_uid(arcn->sb.st_uid, 1);
|
||||
group = group_from_gid(arcn->sb.st_gid, 1);
|
||||
|
|
Loading…
Reference in New Issue