[hackers] [sbase] Add proper d- and t-flag support to touch(1) || FRIGN

From: <git_AT_suckless.org>
Date: Thu, 19 Feb 2015 19:00:50 +0100 (CET)

commit e67a7726d415cb83484fe9d8c8c49e7ff0c00276
Author: FRIGN <dev_AT_frign.de>
Date: Thu Feb 19 18:54:56 2015 +0100

    Add proper d- and t-flag support to touch(1)
    
    except the [,frac], [.frac] respectively, but that's ok.

diff --git a/README b/README
index 7bdf7bd..025d25f 100644
--- a/README
+++ b/README
_AT_@ -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
index 33a7bfb..3230b18 100644
--- a/touch.1
+++ b/touch.1
_AT_@ -1,4 +1,4 @@
-.Dd February 19, 2015
+.Dd February 9, 2015
 .Dt TOUCH 1
 .Os sbase
 .Sh NAME
_AT_@ -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
_AT_@ -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
_AT_@ -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
index e836e27..41ff21c 100644
--- a/touch.c
+++ b/touch.c
_AT_@ -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>
_AT_@ -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(&current);
+ 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)
 {
_AT_@ -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]);
Received on Thu Feb 19 2015 - 19:00:50 CET

This archive was generated by hypermail 2.3.0 : Thu Feb 19 2015 - 19:12:08 CET