commit b00a00703f3b8d77b3cbfcabd0c7d762e6c8133a
parent c2b400bbd8eeebb46093de31c6f7098e3eb3b817
Author: FRIGN <dev@frign.de>
Date: Thu, 19 Feb 2015 18:54:56 +0100
Add proper d- and t-flag support to touch(1)
except the [,frac], [.frac] respectively, but that's ok.
Diffstat:
M | README | | | 2 | +- |
M | touch.1 | | | 41 | ++++++++++++++++++++++++++--------------- |
M | touch.c | | | 63 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- |
3 files changed, 89 insertions(+), 17 deletions(-)
diff --git a/README b/README
@@ -73,7 +73,7 @@ The following tools are implemented ('*' == finished, '#' == UTF-8 support,
=* tar non-posix none
=* tee yes none
#* test yes none
-=* touch yes none (-d) (-t)
+=* touch yes none
#* tr yes none
=* true yes none
=* tty yes none
diff --git a/touch.1 b/touch.1
@@ -1,4 +1,4 @@
-.Dd February 19, 2015
+.Dd February 9, 2015
.Dt TOUCH 1
.Os sbase
.Sh NAME
@@ -7,11 +7,11 @@
.Sh SYNOPSIS
.Nm
.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 ...
.Sh DESCRIPTION
.Nm
-sets the access or modification time of each
+sets the access and modification time of each
.Ar file
to the current time of day. If
.Ar file
@@ -25,19 +25,30 @@ Set the access | modification time of
Don't create
.Ar file
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
-Set the timestamp
-to be used with
+Set the
+.Ar time
+used for
.Op Fl am
to the modification time of
.Ar ref_file .
-.It Fl t Ar timestamp
+.It Fl T Ar time
Set the
-.Ar timestamp
-to be used with
+.Ar time
+used for
.Op Fl am
given as the number of seconds since the
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
.Sh SEE ALSO
.Xr date 1
@@ -46,10 +57,10 @@ The
.Nm
utility is compliant with the
.St -p1003.1-2008
-specification except for
-.Fl d
-and the
-.Ar timestamp
-format of the
-.Fl t
-flag.
+specification, except from fractional seconds in the
+.Op Fl d
+argument.
+.Pp
+The
+.Op Fl T
+flag is an extension to this specification.
diff --git a/touch.c b/touch.c
@@ -4,6 +4,7 @@
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
+#include <string.h>
#include <time.h>
#include <unistd.h>
#include <utime.h>
@@ -43,6 +44,61 @@ touch(const char *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
usage(void)
{
@@ -72,15 +128,20 @@ main(int argc, char *argv[])
eprintf("stat '%s':", ref);
t = st.st_mtime;
break;
- case 't':
+ case 'T':
t = estrtonum(EARGF(usage()), 0, LLONG_MAX);
break;
+ case 't':
+ t = parsetime(EARGF(usage()), t);
+ break;
default:
usage();
} ARGEND;
if (argc < 1)
usage();
+ if (!aflag && !mflag)
+ aflag = mflag = 1;
for (; argc > 0; argc--, argv++)
touch(argv[0]);