summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Guenther <guenther@cvs.openbsd.org>2015-03-19 05:14:25 +0000
committerPhilip Guenther <guenther@cvs.openbsd.org>2015-03-19 05:14:25 +0000
commitac96b236166f8ac2ecd3cd82b494036fbea13644 (patch)
treeee265f853d5ec79ef3472c8dd8a0159b01de3358
parent6881585d49d6e5caab620945aacc7211d533b8c1 (diff)
Use struct timespec internally. This gives nanosecond precision to pax -rw
and a basis for support of mtime and atime values in pax-format extended header records. ok millert@
-rw-r--r--bin/pax/ar_subs.c86
-rw-r--r--bin/pax/buf_subs.c6
-rw-r--r--bin/pax/cpio.c11
-rw-r--r--bin/pax/extern.h11
-rw-r--r--bin/pax/file_subs.c45
-rw-r--r--bin/pax/ftree.c6
-rw-r--r--bin/pax/pax.h12
-rw-r--r--bin/pax/tables.c21
-rw-r--r--bin/pax/tables.h4
9 files changed, 96 insertions, 106 deletions
diff --git a/bin/pax/ar_subs.c b/bin/pax/ar_subs.c
index 8f0a28c4717..b95b1c2d317 100644
--- a/bin/pax/ar_subs.c
+++ b/bin/pax/ar_subs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ar_subs.c,v 1.44 2015/03/17 03:23:17 guenther Exp $ */
+/* $OpenBSD: ar_subs.c,v 1.45 2015/03/19 05:14:24 guenther Exp $ */
/* $NetBSD: ar_subs.c,v 1.5 1995/03/21 09:07:06 cgd Exp $ */
/*-
@@ -148,6 +148,26 @@ list(void)
pat_chk();
}
+static int
+cmp_file_times(int mtime_flag, int ctime_flag, ARCHD *arcn, struct stat *sbp)
+{
+ struct stat sb;
+
+ if (sbp == NULL) {
+ if (lstat(arcn->name, &sb) != 0)
+ return (0);
+ sbp = &sb;
+ }
+
+ if (ctime_flag && mtime_flag)
+ return (timespeccmp(&arcn->sb.st_mtim, &sbp->st_mtim, <=) &&
+ timespeccmp(&arcn->sb.st_ctim, &sbp->st_ctim, <=));
+ else if (ctime_flag)
+ return (timespeccmp(&arcn->sb.st_ctim, &sbp->st_ctim, <=));
+ else
+ return (timespeccmp(&arcn->sb.st_mtim, &sbp->st_mtim, <=));
+}
+
/*
* extract()
* extract the member(s) of an archive as specified by user supplied
@@ -161,7 +181,6 @@ extract(void)
int res;
off_t cnt;
ARCHD archd;
- struct stat sb;
int fd;
time_t now;
@@ -227,22 +246,10 @@ extract(void)
* file AFTER the name mod. In honesty the pax spec is probably
* flawed in this respect.
*/
- if ((uflag || Dflag) && ((lstat(arcn->name, &sb) == 0))) {
- if (uflag && Dflag) {
- if ((arcn->sb.st_mtime <= sb.st_mtime) &&
- (arcn->sb.st_ctime <= sb.st_ctime)) {
- (void)rd_skip(arcn->skip + arcn->pad);
- continue;
- }
- } else if (Dflag) {
- if (arcn->sb.st_ctime <= sb.st_ctime) {
- (void)rd_skip(arcn->skip + arcn->pad);
- continue;
- }
- } else if (arcn->sb.st_mtime <= sb.st_mtime) {
- (void)rd_skip(arcn->skip + arcn->pad);
- continue;
- }
+ if ((uflag || Dflag) &&
+ cmp_file_times(uflag, Dflag, arcn, NULL)) {
+ (void)rd_skip(arcn->skip + arcn->pad);
+ continue;
}
/*
@@ -263,22 +270,10 @@ extract(void)
* Non standard -Y and -Z flag. When the existing file is
* same age or newer skip
*/
- if ((Yflag || Zflag) && ((lstat(arcn->name, &sb) == 0))) {
- if (Yflag && Zflag) {
- if ((arcn->sb.st_mtime <= sb.st_mtime) &&
- (arcn->sb.st_ctime <= sb.st_ctime)) {
- (void)rd_skip(arcn->skip + arcn->pad);
- continue;
- }
- } else if (Yflag) {
- if (arcn->sb.st_ctime <= sb.st_ctime) {
- (void)rd_skip(arcn->skip + arcn->pad);
- continue;
- }
- } else if (arcn->sb.st_mtime <= sb.st_mtime) {
- (void)rd_skip(arcn->skip + arcn->pad);
- continue;
- }
+ if ((Yflag || Zflag) &&
+ cmp_file_times(Yflag, Zflag, arcn, NULL)) {
+ (void)rd_skip(arcn->skip + arcn->pad);
+ continue;
}
if (vflag) {
@@ -851,14 +846,7 @@ copy(void)
if (res == 0) {
ftree_skipped_newer(arcn);
- if (uflag && Dflag) {
- if ((arcn->sb.st_mtime<=sb.st_mtime) &&
- (arcn->sb.st_ctime<=sb.st_ctime))
- continue;
- } else if (Dflag) {
- if (arcn->sb.st_ctime <= sb.st_ctime)
- continue;
- } else if (arcn->sb.st_mtime <= sb.st_mtime)
+ if (cmp_file_times(uflag, Dflag, arcn, &sb))
continue;
}
}
@@ -883,17 +871,9 @@ copy(void)
* Non standard -Y and -Z flag. When the existing file is
* same age or newer skip
*/
- if ((Yflag || Zflag) && ((lstat(arcn->name, &sb) == 0))) {
- if (Yflag && Zflag) {
- if ((arcn->sb.st_mtime <= sb.st_mtime) &&
- (arcn->sb.st_ctime <= sb.st_ctime))
- continue;
- } else if (Yflag) {
- if (arcn->sb.st_ctime <= sb.st_ctime)
- continue;
- } else if (arcn->sb.st_mtime <= sb.st_mtime)
- continue;
- }
+ if ((Yflag || Zflag) &&
+ cmp_file_times(Yflag, Zflag, arcn, NULL))
+ continue;
if (vflag) {
(void)safe_print(arcn->name, listf);
diff --git a/bin/pax/buf_subs.c b/bin/pax/buf_subs.c
index 36fcce445bf..cac45294436 100644
--- a/bin/pax/buf_subs.c
+++ b/bin/pax/buf_subs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: buf_subs.c,v 1.26 2015/01/16 06:39:32 deraadt Exp $ */
+/* $OpenBSD: buf_subs.c,v 1.27 2015/03/19 05:14:24 guenther Exp $ */
/* $NetBSD: buf_subs.c,v 1.5 1995/03/21 09:07:08 cgd Exp $ */
/*-
@@ -629,7 +629,7 @@ wr_rdfile(ARCHD *arcn, int ifd, off_t *left)
paxwarn(1, "File changed size during read %s", arcn->org_name);
else if (fstat(ifd, &sb) < 0)
syswarn(1, errno, "Failed stat on %s", arcn->org_name);
- else if (arcn->sb.st_mtime != sb.st_mtime)
+ else if (timespeccmp(&arcn->sb.st_mtim, &sb.st_mtim, !=))
paxwarn(1, "File %s was modified during copy to archive",
arcn->org_name);
*left = size;
@@ -803,7 +803,7 @@ cp_file(ARCHD *arcn, int fd1, int fd2)
arcn->org_name, arcn->name);
else if (fstat(fd1, &sb) < 0)
syswarn(1, errno, "Failed stat of %s", arcn->org_name);
- else if (arcn->sb.st_mtime != sb.st_mtime)
+ else if (timespeccmp(&arcn->sb.st_mtim, &sb.st_mtim, !=))
paxwarn(1, "File %s was modified during copy to %s",
arcn->org_name, arcn->name);
diff --git a/bin/pax/cpio.c b/bin/pax/cpio.c
index 55950c144ad..8ff8836b80f 100644
--- a/bin/pax/cpio.c
+++ b/bin/pax/cpio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpio.c,v 1.26 2015/03/17 03:23:17 guenther Exp $ */
+/* $OpenBSD: cpio.c,v 1.27 2015/03/19 05:14:24 guenther Exp $ */
/* $NetBSD: cpio.c,v 1.5 1995/03/21 09:07:13 cgd Exp $ */
/*-
@@ -298,7 +298,8 @@ cpio_rd(ARCHD *arcn, char *buf)
arcn->sb.st_mtime = INT_MAX; /* XXX 2038 */
else
arcn->sb.st_mtime = val;
- arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
+ arcn->sb.st_mtim.tv_nsec = 0;
+ arcn->sb.st_ctim = arcn->sb.st_atim = arcn->sb.st_mtim;
arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize,sizeof(hd->c_filesize),
OCT);
@@ -572,7 +573,8 @@ vcpio_rd(ARCHD *arcn, char *buf)
arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), HEX);
arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), HEX);
arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime,sizeof(hd->c_mtime),HEX);
- arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
+ arcn->sb.st_mtim.tv_nsec = 0;
+ arcn->sb.st_ctim = arcn->sb.st_atim = arcn->sb.st_mtim;
arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize,
sizeof(hd->c_filesize), HEX);
arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink),
@@ -892,7 +894,8 @@ bcpio_rd(ARCHD *arcn, char *buf)
((off_t)(SHRT_EXT(hd->h_filesize_2)));
nsz = (int)(SHRT_EXT(hd->h_namesize));
}
- arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
+ arcn->sb.st_mtim.tv_nsec = 0;
+ arcn->sb.st_ctim = arcn->sb.st_atim = arcn->sb.st_mtim;
/*
* check the file name size, if bogus give up. otherwise read the file
diff --git a/bin/pax/extern.h b/bin/pax/extern.h
index 866e119a03e..12a939157cb 100644
--- a/bin/pax/extern.h
+++ b/bin/pax/extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: extern.h,v 1.52 2015/03/15 21:53:09 guenther Exp $ */
+/* $OpenBSD: extern.h,v 1.53 2015/03/19 05:14:24 guenther Exp $ */
/* $NetBSD: extern.h,v 1.5 1996/03/26 23:54:16 mrg Exp $ */
/*-
@@ -141,8 +141,10 @@ int chk_same(ARCHD *);
int node_creat(ARCHD *);
int unlnk_exist(char *, int);
int chk_path(char *, uid_t, gid_t);
-void set_ftime(char *fnm, time_t mtime, time_t atime, int frc);
-void fset_ftime(char *fnm, int, time_t mtime, time_t atime, int frc);
+void set_ftime(const char *, const struct timespec *,
+ const struct timespec *, int);
+void fset_ftime(const char *, int, const struct timespec *,
+ const struct timespec *, int);
int set_ids(char *, uid_t, gid_t);
int fset_ids(char *, int, uid_t, gid_t);
void set_pmode(char *, mode_t);
@@ -282,7 +284,8 @@ int map_dev(ARCHD *, u_long, u_long);
#endif /* NOCPIO */
int atdir_start(void);
void atdir_end(void);
-void add_atdir(char *, dev_t, ino_t, time_t, time_t);
+void add_atdir(char *, dev_t, ino_t, const struct timespec *,
+ const struct timespec *);
int do_atdir(const char *, dev_t, ino_t);
int dir_start(void);
void add_dir(char *, struct stat *, int);
diff --git a/bin/pax/file_subs.c b/bin/pax/file_subs.c
index 4bfc2eb6907..fe14c598361 100644
--- a/bin/pax/file_subs.c
+++ b/bin/pax/file_subs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: file_subs.c,v 1.46 2015/03/15 06:05:59 guenther Exp $ */
+/* $OpenBSD: file_subs.c,v 1.47 2015/03/19 05:14:24 guenther Exp $ */
/* $NetBSD: file_subs.c,v 1.4 1995/03/21 09:07:18 cgd Exp $ */
/*-
@@ -147,8 +147,8 @@ file_close(ARCHD *arcn, int fd)
if (pmode)
fset_pmode(arcn->name, fd, arcn->sb.st_mode);
if (patime || pmtime)
- fset_ftime(arcn->name, fd, arcn->sb.st_mtime,
- arcn->sb.st_atime, 0);
+ fset_ftime(arcn->name, fd, &arcn->sb.st_mtim,
+ &arcn->sb.st_atim, 0);
if (close(fd) < 0)
syswarn(0, errno, "Unable to close file descriptor on %s",
arcn->name);
@@ -525,7 +525,7 @@ badlink:
}
if (patime || pmtime)
- set_ftime(nm, arcn->sb.st_mtime, arcn->sb.st_atime, 0);
+ set_ftime(nm, &arcn->sb.st_mtim, &arcn->sb.st_atim, 0);
return(0);
}
@@ -676,14 +676,14 @@ chk_path(char *name, uid_t st_uid, gid_t st_gid)
*/
void
-set_ftime(char *fnm, time_t mtime, time_t atime, int frc)
+set_ftime(const char *fnm, const struct timespec *mtimp,
+ const struct timespec *atimp, int frc)
{
struct timespec tv[2];
- tv[0].tv_sec = atime;
- tv[0].tv_nsec = 0L;
- tv[1].tv_sec = mtime;
- tv[1].tv_nsec = 0L;
+ tv[0] = *atimp;
+ tv[1] = *mtimp;
+
if (!frc) {
/*
* if we are not forcing, only set those times the user wants
@@ -704,14 +704,15 @@ set_ftime(char *fnm, time_t mtime, time_t atime, int frc)
}
void
-fset_ftime(char *fnm, int fd, time_t mtime, time_t atime, int frc)
+fset_ftime(const char *fnm, int fd, const struct timespec *mtimp,
+ const struct timespec *atimp, int frc)
{
struct timespec tv[2];
- tv[0].tv_sec = atime;
- tv[0].tv_nsec = 0L;
- tv[1].tv_sec = mtime;
- tv[1].tv_nsec = 0L;
+
+ tv[0] = *atimp;
+ tv[1] = *mtimp;
+
if (!frc) {
/*
* if we are not forcing, only set those times the user wants
@@ -834,10 +835,12 @@ set_attr(const struct file_times *ft, int force_times, mode_t mode,
/* Whew, it's a match! Is there anything to change? */
if (do_mode && (mode & ABITS) != (sb.st_mode & ABITS))
fset_pmode(ft->ft_name, fd, mode);
- if (((force_times || patime) && ft->ft_atime != sb.st_atime) ||
- ((force_times || pmtime) && ft->ft_mtime != sb.st_mtime))
- fset_ftime(ft->ft_name, fd, ft->ft_mtime,
- ft->ft_atime, force_times);
+ if (((force_times || patime) &&
+ timespeccmp(&ft->ft_atim, &sb.st_atim, !=)) ||
+ ((force_times || pmtime) &&
+ timespeccmp(&ft->ft_mtim, &sb.st_mtim, !=)))
+ fset_ftime(ft->ft_name, fd, &ft->ft_mtim,
+ &ft->ft_atim, force_times);
r = 0;
}
close(fd);
@@ -1042,8 +1045,8 @@ rdfile_close(ARCHD *arcn, int *fd)
* user wants last access time reset
*/
if (tflag)
- fset_ftime(arcn->org_name, *fd, arcn->sb.st_mtime,
- arcn->sb.st_atime, 1);
+ fset_ftime(arcn->org_name, *fd, &arcn->sb.st_mtim,
+ &arcn->sb.st_atim, 1);
(void)close(*fd);
*fd = -1;
@@ -1100,7 +1103,7 @@ set_crc(ARCHD *arcn, int fd)
paxwarn(1, "File changed size %s", arcn->org_name);
else if (fstat(fd, &sb) < 0)
syswarn(1, errno, "Failed stat on %s", arcn->org_name);
- else if (arcn->sb.st_mtime != sb.st_mtime)
+ else if (timespeccmp(&arcn->sb.st_mtim, &sb.st_mtim, !=))
paxwarn(1, "File %s was modified during read", arcn->org_name);
else if (lseek(fd, (off_t)0L, SEEK_SET) < 0)
syswarn(1, errno, "File rewind failed on: %s", arcn->org_name);
diff --git a/bin/pax/ftree.c b/bin/pax/ftree.c
index e6319838245..93de8b711d7 100644
--- a/bin/pax/ftree.c
+++ b/bin/pax/ftree.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ftree.c,v 1.37 2015/03/09 04:23:29 guenther Exp $ */
+/* $OpenBSD: ftree.c,v 1.38 2015/03/19 05:14:24 guenther Exp $ */
/* $NetBSD: ftree.c,v 1.4 1995/03/21 09:07:21 cgd Exp $ */
/*-
@@ -443,8 +443,8 @@ next_file(ARCHD *arcn)
if (!tflag)
break;
add_atdir(ftent->fts_path, arcn->sb.st_dev,
- arcn->sb.st_ino, arcn->sb.st_mtime,
- arcn->sb.st_atime);
+ arcn->sb.st_ino, &arcn->sb.st_mtim,
+ &arcn->sb.st_atim);
break;
case S_IFCHR:
arcn->type = PAX_CHR;
diff --git a/bin/pax/pax.h b/bin/pax/pax.h
index f06ad38be69..3aebf68ed4b 100644
--- a/bin/pax/pax.h
+++ b/bin/pax/pax.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pax.h,v 1.26 2015/03/17 03:23:17 guenther Exp $ */
+/* $OpenBSD: pax.h,v 1.27 2015/03/19 05:14:24 guenther Exp $ */
/* $NetBSD: pax.h,v 1.3 1995/03/21 09:07:41 cgd Exp $ */
/*-
@@ -221,11 +221,11 @@ typedef struct {
* at the given name has the indicated dev+ino.
*/
struct file_times {
- ino_t ft_ino; /* inode number to verify */
- time_t ft_mtime; /* times to set */
- time_t ft_atime;
- char *ft_name; /* name of file to set the times on */
- dev_t ft_dev; /* device number to verify */
+ ino_t ft_ino; /* inode number to verify */
+ struct timespec ft_mtim; /* times to set */
+ struct timespec ft_atim;
+ char *ft_name; /* name of file to set the times on */
+ dev_t ft_dev; /* device number to verify */
};
/*
diff --git a/bin/pax/tables.c b/bin/pax/tables.c
index 308e05b1b58..220f594a5f3 100644
--- a/bin/pax/tables.c
+++ b/bin/pax/tables.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tables.c,v 1.46 2015/03/17 03:23:17 guenther Exp $ */
+/* $OpenBSD: tables.c,v 1.47 2015/03/19 05:14:24 guenther Exp $ */
/* $NetBSD: tables.c,v 1.4 1995/03/21 09:07:45 cgd Exp $ */
/*-
@@ -420,11 +420,11 @@ chk_ftime(ARCHD *arcn)
/*
* found the file, compare the times, save the newer
*/
- if (arcn->sb.st_mtime > pt->mtime) {
+ if (timespeccmp(&arcn->sb.st_mtim, &pt->mtim, >)) {
/*
* file is newer
*/
- pt->mtime = arcn->sb.st_mtime;
+ pt->mtim = arcn->sb.st_mtim;
return(0);
}
/*
@@ -444,7 +444,7 @@ chk_ftime(ARCHD *arcn)
*/
if ((pt->seek = lseek(ffd, (off_t)0, SEEK_END)) >= 0) {
if (write(ffd, arcn->name, namelen) == namelen) {
- pt->mtime = arcn->sb.st_mtime;
+ pt->mtim = arcn->sb.st_mtim;
pt->namelen = namelen;
pt->fow = ftab[indx];
ftab[indx] = pt;
@@ -734,7 +734,7 @@ sltab_process_one(struct slinode *s, struct slpath *p, const char *first,
set_pmode(path, mode);
if (patime || pmtime)
- set_ftime(path, sb.st_mtime, sb.st_atime, 0);
+ set_ftime(path, &sb.st_mtim, &sb.st_atim, 0);
/*
* If we tried to link to first but failed, then this new symlink
@@ -1289,7 +1289,8 @@ atdir_end(void)
*/
void
-add_atdir(char *fname, dev_t dev, ino_t ino, time_t mtime, time_t atime)
+add_atdir(char *fname, dev_t dev, ino_t ino, const struct timespec *mtimp,
+ const struct timespec *atimp)
{
ATDIR *pt;
sigset_t allsigs, savedsigs;
@@ -1329,8 +1330,8 @@ add_atdir(char *fname, dev_t dev, ino_t ino, time_t mtime, time_t atime)
if ((pt->ft.ft_name = strdup(fname)) != NULL) {
pt->ft.ft_dev = dev;
pt->ft.ft_ino = ino;
- pt->ft.ft_mtime = mtime;
- pt->ft.ft_atime = atime;
+ pt->ft.ft_mtim = *mtimp;
+ pt->ft.ft_atim = *atimp;
pt->fow = atab[indx];
atab[indx] = pt;
sigprocmask(SIG_SETMASK, &savedsigs, NULL);
@@ -1491,8 +1492,8 @@ add_dir(char *name, struct stat *psb, int frc_mode)
" directory: %s", name);
return;
}
- dblk->ft.ft_mtime = psb->st_mtime;
- dblk->ft.ft_atime = psb->st_atime;
+ dblk->ft.ft_mtim = psb->st_mtim;
+ dblk->ft.ft_atim = psb->st_atim;
dblk->ft.ft_ino = psb->st_ino;
dblk->ft.ft_dev = psb->st_dev;
dblk->mode = psb->st_mode & ABITS;
diff --git a/bin/pax/tables.h b/bin/pax/tables.h
index 238986f5bb8..55eeb959284 100644
--- a/bin/pax/tables.h
+++ b/bin/pax/tables.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tables.h,v 1.15 2015/03/09 04:23:29 guenther Exp $ */
+/* $OpenBSD: tables.h,v 1.16 2015/03/19 05:14:24 guenther Exp $ */
/* $NetBSD: tables.h,v 1.3 1995/03/21 09:07:47 cgd Exp $ */
/*-
@@ -79,7 +79,7 @@ typedef struct hrdlnk {
*/
typedef struct ftm {
off_t seek; /* location in scratch file */
- time_t mtime; /* files last modification time */
+ struct timespec mtim; /* files last modification time */
struct ftm *fow;
int namelen; /* file name length */
} FTM;