Add -A flag to adjust existing time stamps.
Print name by which program was started in usage() message. MFC after: 2 weeks
This commit is contained in:
parent
482ee864ab
commit
3481910d32
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=168525
@ -43,6 +43,7 @@
|
|||||||
.Nd change file access and modification times
|
.Nd change file access and modification times
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
|
.Op Fl A Ar [-][[hh]mm]SS
|
||||||
.Op Fl acfhm
|
.Op Fl acfhm
|
||||||
.Op Fl r Ar file
|
.Op Fl r Ar file
|
||||||
.Op Fl t Ar [[CC]YY]MMDDhhmm[.SS]
|
.Op Fl t Ar [[CC]YY]MMDDhhmm[.SS]
|
||||||
@ -50,17 +51,79 @@
|
|||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
The
|
The
|
||||||
.Nm
|
.Nm
|
||||||
utility sets the modification and access times of files to the
|
utility sets the modification and access times of files.
|
||||||
current time of day.
|
If any file does not exist, it is created with default permissions.
|
||||||
If the file does not exist, it is created with default permissions.
|
.Pp
|
||||||
|
By default,
|
||||||
|
.Nm
|
||||||
|
changes both modification and access times. The
|
||||||
|
.Fl a
|
||||||
|
and
|
||||||
|
.Fl m
|
||||||
|
flags may be used to select the access time or the modification time
|
||||||
|
individually.
|
||||||
|
Selecting both is equivalent to the default.
|
||||||
|
The base times for the modification are both set to the current time.
|
||||||
|
The
|
||||||
|
.Fl t
|
||||||
|
flag explicitly specifies a single time for both values, and the
|
||||||
|
.Fl r
|
||||||
|
flag specifies to set the times from those of a different file.
|
||||||
|
The
|
||||||
|
.Fl A
|
||||||
|
flag adjusts the values by a specified amount.
|
||||||
|
This adjustment is done after first establishing the base times.
|
||||||
.Pp
|
.Pp
|
||||||
The following options are available:
|
The following options are available:
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
|
.It Fl A
|
||||||
|
Adjust the access and modification time stamps for the file by the
|
||||||
|
specified value.
|
||||||
|
This flag is intended for use in modifying files with a time stamp
|
||||||
|
relative to an incorrect time zone.
|
||||||
|
It always modifies both the access time and the modification time.
|
||||||
|
.Pp
|
||||||
|
The argument is of the form
|
||||||
|
.Dq [-][[hh]mm]SS
|
||||||
|
where each pair of letters represents the following:
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -width Ds -compact -offset indent
|
||||||
|
.It Ar -
|
||||||
|
Make the adjustment negative: the new time stamp is set to be before
|
||||||
|
the old one.
|
||||||
|
.It Ar hh
|
||||||
|
The hour of the day, from 00 to 23.
|
||||||
|
.It Ar mm
|
||||||
|
The minute of the hour, from 00 to 59.
|
||||||
|
.It Ar SS
|
||||||
|
The second of the minute, from 00 to 59.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
When used in conjunction with the
|
||||||
|
.Fl a
|
||||||
|
flag only, the modification time is adjusted by the time specified as
|
||||||
|
argument to the
|
||||||
|
.Fl A
|
||||||
|
flag, while the access time is modified from the base time described
|
||||||
|
above.
|
||||||
|
Similarly, when used in conjunction with the
|
||||||
|
.Fl m
|
||||||
|
flag only, the access time is adjusted by the time specified as
|
||||||
|
argument to the
|
||||||
|
.Fl A
|
||||||
|
flag, while the access time is modified from the base time described
|
||||||
|
above.
|
||||||
|
.Pp
|
||||||
|
If the file does not exist, and creation is allowed,
|
||||||
|
.Fl A
|
||||||
|
does not change its time stamps.
|
||||||
.It Fl a
|
.It Fl a
|
||||||
Change the access time of the file.
|
Change the access time of the file.
|
||||||
The modification time of the file is not changed unless the
|
The modification time of the file is not changed unless one of the
|
||||||
|
.Fl A
|
||||||
|
or
|
||||||
.Fl m
|
.Fl m
|
||||||
flag is also specified.
|
flags is also specified.
|
||||||
.It Fl c
|
.It Fl c
|
||||||
Do not create the file if it does not exist.
|
Do not create the file if it does not exist.
|
||||||
The
|
The
|
||||||
@ -80,15 +143,17 @@ implies
|
|||||||
and thus will not create any new files.
|
and thus will not create any new files.
|
||||||
.It Fl m
|
.It Fl m
|
||||||
Change the modification time of the file.
|
Change the modification time of the file.
|
||||||
The access time of the file is not changed unless the
|
The access time of the file is not changed unless one of the
|
||||||
|
.Fl A
|
||||||
|
or
|
||||||
.Fl a
|
.Fl a
|
||||||
flag is also specified.
|
flags is also specified.
|
||||||
.It Fl r
|
.It Fl r
|
||||||
Use the access and modifications times from the specified file
|
Use the access and modifications times from the specified file
|
||||||
instead of the current time of day.
|
instead of the current time of day.
|
||||||
.It Fl t
|
.It Fl t
|
||||||
Change the access and modification times to the specified time.
|
Change the access and modification times to the specified time.
|
||||||
The argument should be in the form
|
The argument is of the form
|
||||||
.Dq [[CC]YY]MMDDhhmm[.SS]
|
.Dq [[CC]YY]MMDDhhmm[.SS]
|
||||||
where each pair of letters represents the following:
|
where each pair of letters represents the following:
|
||||||
.Pp
|
.Pp
|
||||||
@ -110,15 +175,15 @@ Otherwise, a
|
|||||||
.Dq CC
|
.Dq CC
|
||||||
value of 20 is used.
|
value of 20 is used.
|
||||||
.It Ar MM
|
.It Ar MM
|
||||||
The month of the year, from 1 to 12.
|
The month of the year, from 01 to 12.
|
||||||
.It Ar DD
|
.It Ar DD
|
||||||
the day of the month, from 1 to 31.
|
the day of the month, from 01 to 31.
|
||||||
.It Ar hh
|
.It Ar hh
|
||||||
The hour of the day, from 0 to 23.
|
The hour of the day, from 00 to 23.
|
||||||
.It Ar mm
|
.It Ar mm
|
||||||
The minute of the hour, from 0 to 59.
|
The minute of the hour, from 00 to 59.
|
||||||
.It Ar SS
|
.It Ar SS
|
||||||
The second of the minute, from 0 to 61.
|
The second of the minute, from 00 to 61.
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
If the
|
If the
|
||||||
|
@ -62,7 +62,8 @@ int rw(char *, struct stat *, int);
|
|||||||
void stime_arg1(char *, struct timeval *);
|
void stime_arg1(char *, struct timeval *);
|
||||||
void stime_arg2(char *, int, struct timeval *);
|
void stime_arg2(char *, int, struct timeval *);
|
||||||
void stime_file(char *, struct timeval *);
|
void stime_file(char *, struct timeval *);
|
||||||
void usage(void);
|
int timeoffset(char *);
|
||||||
|
void usage(char *);
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
@ -71,17 +72,22 @@ main(int argc, char *argv[])
|
|||||||
struct timeval tv[2];
|
struct timeval tv[2];
|
||||||
int (*stat_f)(const char *, struct stat *);
|
int (*stat_f)(const char *, struct stat *);
|
||||||
int (*utimes_f)(const char *, const struct timeval *);
|
int (*utimes_f)(const char *, const struct timeval *);
|
||||||
int aflag, cflag, fflag, mflag, ch, fd, len, rval, timeset;
|
int Aflag, aflag, cflag, fflag, mflag, ch, fd, len, rval, timeset;
|
||||||
char *p;
|
char *p;
|
||||||
|
char *myname;
|
||||||
|
|
||||||
aflag = cflag = fflag = mflag = timeset = 0;
|
myname = argv[0];
|
||||||
|
Aflag = aflag = cflag = fflag = mflag = timeset = 0;
|
||||||
stat_f = stat;
|
stat_f = stat;
|
||||||
utimes_f = utimes;
|
utimes_f = utimes;
|
||||||
if (gettimeofday(&tv[0], NULL))
|
if (gettimeofday(&tv[0], NULL))
|
||||||
err(1, "gettimeofday");
|
err(1, "gettimeofday");
|
||||||
|
|
||||||
while ((ch = getopt(argc, argv, "acfhmr:t:")) != -1)
|
while ((ch = getopt(argc, argv, "A:acfhmr:t:")) != -1)
|
||||||
switch(ch) {
|
switch(ch) {
|
||||||
|
case 'A':
|
||||||
|
Aflag = timeoffset(optarg);
|
||||||
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
aflag = 1;
|
aflag = 1;
|
||||||
break;
|
break;
|
||||||
@ -109,13 +115,13 @@ main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
usage();
|
usage(myname);
|
||||||
}
|
}
|
||||||
argc -= optind;
|
argc -= optind;
|
||||||
argv += optind;
|
argv += optind;
|
||||||
|
|
||||||
/* Default is both -a and -m. */
|
/* -a and -m are default unless one of them or -A is set. */
|
||||||
if (aflag == 0 && mflag == 0)
|
if (aflag == 0 && mflag == 0 && Aflag == 0)
|
||||||
aflag = mflag = 1;
|
aflag = mflag = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -136,7 +142,7 @@ main(int argc, char *argv[])
|
|||||||
tv[1] = tv[0];
|
tv[1] = tv[0];
|
||||||
|
|
||||||
if (*argv == NULL)
|
if (*argv == NULL)
|
||||||
usage();
|
usage(myname);
|
||||||
|
|
||||||
for (rval = 0; *argv; ++argv) {
|
for (rval = 0; *argv; ++argv) {
|
||||||
/* See if the file exists. */
|
/* See if the file exists. */
|
||||||
@ -158,10 +164,15 @@ main(int argc, char *argv[])
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If -a or -m are not set, base time on current file time. */
|
||||||
if (!aflag)
|
if (!aflag)
|
||||||
TIMESPEC_TO_TIMEVAL(&tv[0], &sb.st_atimespec);
|
TIMESPEC_TO_TIMEVAL(&tv[0], &sb.st_atimespec);
|
||||||
if (!mflag)
|
if (!mflag)
|
||||||
TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtimespec);
|
TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtimespec);
|
||||||
|
if (Aflag) {
|
||||||
|
tv[0].tv_sec += Aflag;
|
||||||
|
tv[1].tv_sec += Aflag;
|
||||||
|
}
|
||||||
|
|
||||||
/* Try utimes(2). */
|
/* Try utimes(2). */
|
||||||
if (!utimes_f(*argv, tv))
|
if (!utimes_f(*argv, tv))
|
||||||
@ -286,6 +297,36 @@ stime_arg2(char *arg, int year, struct timeval *tvp)
|
|||||||
tvp[0].tv_usec = tvp[1].tv_usec = 0;
|
tvp[0].tv_usec = tvp[1].tv_usec = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Calculate a time offset in seconds, given an arg of the format [-]HHMMSS. */
|
||||||
|
int
|
||||||
|
timeoffset(char *arg)
|
||||||
|
{
|
||||||
|
int offset;
|
||||||
|
int isneg;
|
||||||
|
|
||||||
|
offset = 0;
|
||||||
|
isneg = *arg == '-';
|
||||||
|
if (isneg)
|
||||||
|
arg++;
|
||||||
|
switch (strlen(arg)) {
|
||||||
|
default: /* invalid */
|
||||||
|
errx(1, "Invalid offset spec, must be [-][[HH]MM]SS");
|
||||||
|
|
||||||
|
case 6: /* HHMMSS */
|
||||||
|
offset = ATOI2(arg);
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case 4: /* MMSS */
|
||||||
|
offset = offset * 60 + ATOI2(arg);
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case 2: /* SS */
|
||||||
|
offset = offset * 60 + ATOI2(arg);
|
||||||
|
}
|
||||||
|
if (isneg)
|
||||||
|
return (-offset);
|
||||||
|
else
|
||||||
|
return (offset);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
stime_file(char *fname, struct timeval *tvp)
|
stime_file(char *fname, struct timeval *tvp)
|
||||||
{
|
{
|
||||||
@ -347,8 +388,9 @@ err: rval = 1;
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
usage(void)
|
usage(char *myname)
|
||||||
{
|
{
|
||||||
(void)fprintf(stderr, "usage: touch [-acfhm] [-r file] [-t [[CC]YY]MMDDhhmm[.SS]] file ...\n");
|
fprintf(stderr, "usage:\n" "%s [-A [-][[hh]mm]SS] [-acfhm] [-r file] "
|
||||||
|
"[-t [[CC]YY]MMDDhhmm[.SS]] file ...\n", myname);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user