Add proper d- and t-flag support to touch(1)
except the [,frac], [.frac] respectively, but that's ok.
This commit is contained in:
parent
c2b400bbd8
commit
b00a00703f
2
README
2
README
@ -73,7 +73,7 @@ The following tools are implemented ('*' == finished, '#' == UTF-8 support,
|
|||||||
=* tar non-posix none
|
=* tar non-posix none
|
||||||
=* tee yes none
|
=* tee yes none
|
||||||
#* test yes none
|
#* test yes none
|
||||||
=* touch yes none (-d) (-t)
|
=* touch yes none
|
||||||
#* tr yes none
|
#* tr yes none
|
||||||
=* true yes none
|
=* true yes none
|
||||||
=* tty yes none
|
=* tty yes none
|
||||||
|
41
touch.1
41
touch.1
@ -1,4 +1,4 @@
|
|||||||
.Dd February 19, 2015
|
.Dd February 9, 2015
|
||||||
.Dt TOUCH 1
|
.Dt TOUCH 1
|
||||||
.Os sbase
|
.Os sbase
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -7,11 +7,11 @@
|
|||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl acm
|
.Op Fl acm
|
||||||
.Op Fl r Ar ref_file | Fl t Ar timestamp
|
.Op Fl d Ar time | Fl r Ar ref_file | Fl T Ar time | Fl t Ar time
|
||||||
.Ar file ...
|
.Ar file ...
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
.Nm
|
.Nm
|
||||||
sets the access or modification time of each
|
sets the access and modification time of each
|
||||||
.Ar file
|
.Ar file
|
||||||
to the current time of day. If
|
to the current time of day. If
|
||||||
.Ar file
|
.Ar file
|
||||||
@ -25,19 +25,30 @@ Set the access | modification time of
|
|||||||
Don't create
|
Don't create
|
||||||
.Ar file
|
.Ar file
|
||||||
if it doesn't exist, not affecting exit status.
|
if it doesn't exist, not affecting exit status.
|
||||||
|
.It Fl d Ar time
|
||||||
|
Set the
|
||||||
|
.Ar time
|
||||||
|
of the format YYYY-MM-DDThh:mm:SS[Z] used for
|
||||||
|
.Op Fl am .
|
||||||
.It Fl r Ar ref_file
|
.It Fl r Ar ref_file
|
||||||
Set the timestamp
|
Set the
|
||||||
to be used with
|
.Ar time
|
||||||
|
used for
|
||||||
.Op Fl am
|
.Op Fl am
|
||||||
to the modification time of
|
to the modification time of
|
||||||
.Ar ref_file .
|
.Ar ref_file .
|
||||||
.It Fl t Ar timestamp
|
.It Fl T Ar time
|
||||||
Set the
|
Set the
|
||||||
.Ar timestamp
|
.Ar time
|
||||||
to be used with
|
used for
|
||||||
.Op Fl am
|
.Op Fl am
|
||||||
given as the number of seconds since the
|
given as the number of seconds since the
|
||||||
Unix epoch 1970-01-01T00:00:00Z.
|
Unix epoch 1970-01-01T00:00:00Z.
|
||||||
|
.It Fl t Ar time
|
||||||
|
Set the
|
||||||
|
.Ar time
|
||||||
|
of the format [[CC]YY]MMDDhhmm[.SS] used for
|
||||||
|
.Op Fl am .
|
||||||
.El
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr date 1
|
.Xr date 1
|
||||||
@ -46,10 +57,10 @@ The
|
|||||||
.Nm
|
.Nm
|
||||||
utility is compliant with the
|
utility is compliant with the
|
||||||
.St -p1003.1-2008
|
.St -p1003.1-2008
|
||||||
specification except for
|
specification, except from fractional seconds in the
|
||||||
.Fl d
|
.Op Fl d
|
||||||
and the
|
argument.
|
||||||
.Ar timestamp
|
.Pp
|
||||||
format of the
|
The
|
||||||
.Fl t
|
.Op Fl T
|
||||||
flag.
|
flag is an extension to this specification.
|
||||||
|
63
touch.c
63
touch.c
@ -4,6 +4,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <utime.h>
|
#include <utime.h>
|
||||||
@ -43,6 +44,61 @@ touch(const char *file)
|
|||||||
touch(file);
|
touch(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
time_t
|
||||||
|
parsetime(char *str, time_t current)
|
||||||
|
{
|
||||||
|
struct tm *cur, t;
|
||||||
|
char *format;
|
||||||
|
size_t len = strlen(str);
|
||||||
|
|
||||||
|
cur = localtime(¤t);
|
||||||
|
t.tm_isdst = -1;
|
||||||
|
|
||||||
|
switch (len) {
|
||||||
|
/* -t flag argument */
|
||||||
|
case 8:
|
||||||
|
t.tm_sec = 0;
|
||||||
|
t.tm_year = cur->tm_year;
|
||||||
|
format = "%m%d%H%M";
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
t.tm_sec = 0;
|
||||||
|
format = "%y%m%d%H%M";
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
t.tm_year = cur->tm_year;
|
||||||
|
format = "%m%d%H%M.%S";
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
t.tm_sec = 0;
|
||||||
|
format = "%Y%m%d%H%M";
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
format = "%y%m%d%H%M.%S";
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
format = "%Y%m%d%H%M.%S";
|
||||||
|
break;
|
||||||
|
/* -d flag argument */
|
||||||
|
case 19:
|
||||||
|
format = "%Y-%m-%dT%H:%M:%S";
|
||||||
|
break;
|
||||||
|
case 20:
|
||||||
|
/* only Zulu-timezone supported */
|
||||||
|
if (str[19] != 'Z')
|
||||||
|
goto default;
|
||||||
|
format = "%Y-%m-%dT%H:%M:%S%Z";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
eprintf("Invalid date format length\n", str);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strptime(str, format, &t))
|
||||||
|
weprintf("strptime %s: Invalid date format\n", str);
|
||||||
|
|
||||||
|
return mktime(&t);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
@ -72,15 +128,20 @@ main(int argc, char *argv[])
|
|||||||
eprintf("stat '%s':", ref);
|
eprintf("stat '%s':", ref);
|
||||||
t = st.st_mtime;
|
t = st.st_mtime;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 'T':
|
||||||
t = estrtonum(EARGF(usage()), 0, LLONG_MAX);
|
t = estrtonum(EARGF(usage()), 0, LLONG_MAX);
|
||||||
break;
|
break;
|
||||||
|
case 't':
|
||||||
|
t = parsetime(EARGF(usage()), t);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
} ARGEND;
|
} ARGEND;
|
||||||
|
|
||||||
if (argc < 1)
|
if (argc < 1)
|
||||||
usage();
|
usage();
|
||||||
|
if (!aflag && !mflag)
|
||||||
|
aflag = mflag = 1;
|
||||||
|
|
||||||
for (; argc > 0; argc--, argv++)
|
for (; argc > 0; argc--, argv++)
|
||||||
touch(argv[0]);
|
touch(argv[0]);
|
||||||
|
Loading…
Reference in New Issue
Block a user