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:
Greg Lehey 2007-04-09 02:19:37 +00:00
parent 482ee864ab
commit 3481910d32
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=168525
2 changed files with 130 additions and 23 deletions

View File

@ -43,6 +43,7 @@
.Nd change file access and modification times
.Sh SYNOPSIS
.Nm
.Op Fl A Ar [-][[hh]mm]SS
.Op Fl acfhm
.Op Fl r Ar file
.Op Fl t Ar [[CC]YY]MMDDhhmm[.SS]
@ -50,17 +51,79 @@
.Sh DESCRIPTION
The
.Nm
utility sets the modification and access times of files to the
current time of day.
If the file does not exist, it is created with default permissions.
utility sets the modification and access times of files.
If any 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
The following options are available:
.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
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
flag is also specified.
flags is also specified.
.It Fl c
Do not create the file if it does not exist.
The
@ -80,15 +143,17 @@ implies
and thus will not create any new files.
.It Fl m
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
flag is also specified.
flags is also specified.
.It Fl r
Use the access and modifications times from the specified file
instead of the current time of day.
.It Fl t
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]
where each pair of letters represents the following:
.Pp
@ -110,15 +175,15 @@ Otherwise, a
.Dq CC
value of 20 is used.
.It Ar MM
The month of the year, from 1 to 12.
The month of the year, from 01 to 12.
.It Ar DD
the day of the month, from 1 to 31.
the day of the month, from 01 to 31.
.It Ar hh
The hour of the day, from 0 to 23.
The hour of the day, from 00 to 23.
.It Ar mm
The minute of the hour, from 0 to 59.
The minute of the hour, from 00 to 59.
.It Ar SS
The second of the minute, from 0 to 61.
The second of the minute, from 00 to 61.
.El
.Pp
If the

View File

@ -62,7 +62,8 @@ int rw(char *, struct stat *, int);
void stime_arg1(char *, struct timeval *);
void stime_arg2(char *, int, struct timeval *);
void stime_file(char *, struct timeval *);
void usage(void);
int timeoffset(char *);
void usage(char *);
int
main(int argc, char *argv[])
@ -71,17 +72,22 @@ main(int argc, char *argv[])
struct timeval tv[2];
int (*stat_f)(const char *, struct stat *);
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 *myname;
aflag = cflag = fflag = mflag = timeset = 0;
myname = argv[0];
Aflag = aflag = cflag = fflag = mflag = timeset = 0;
stat_f = stat;
utimes_f = utimes;
if (gettimeofday(&tv[0], NULL))
err(1, "gettimeofday");
while ((ch = getopt(argc, argv, "acfhmr:t:")) != -1)
while ((ch = getopt(argc, argv, "A:acfhmr:t:")) != -1)
switch(ch) {
case 'A':
Aflag = timeoffset(optarg);
break;
case 'a':
aflag = 1;
break;
@ -109,13 +115,13 @@ main(int argc, char *argv[])
break;
case '?':
default:
usage();
usage(myname);
}
argc -= optind;
argv += optind;
/* Default is both -a and -m. */
if (aflag == 0 && mflag == 0)
/* -a and -m are default unless one of them or -A is set. */
if (aflag == 0 && mflag == 0 && Aflag == 0)
aflag = mflag = 1;
/*
@ -136,7 +142,7 @@ main(int argc, char *argv[])
tv[1] = tv[0];
if (*argv == NULL)
usage();
usage(myname);
for (rval = 0; *argv; ++argv) {
/* See if the file exists. */
@ -158,10 +164,15 @@ main(int argc, char *argv[])
continue;
}
/* If -a or -m are not set, base time on current file time. */
if (!aflag)
TIMESPEC_TO_TIMEVAL(&tv[0], &sb.st_atimespec);
if (!mflag)
TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtimespec);
if (Aflag) {
tv[0].tv_sec += Aflag;
tv[1].tv_sec += Aflag;
}
/* Try utimes(2). */
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;
}
/* 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
stime_file(char *fname, struct timeval *tvp)
{
@ -347,8 +388,9 @@ err: rval = 1;
}
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);
}