summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--touch.c92
1 files changed, 90 insertions, 2 deletions
diff --git a/touch.c b/touch.c
index 97da03a..05dd721 100644
--- a/touch.c
+++ b/touch.c
@@ -23,10 +23,12 @@
*/
#define _POSIX_C_SOURCE 200809L
+#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <locale.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
@@ -62,6 +64,92 @@ static int touch(const char *path, struct timespec times[2], int create)
return 0;
}
+static int twodigits(const char *s)
+{
+ char buf[3] = { s[0], s[1], '\0' };
+ if (!(isdigit(buf[0]) && isdigit(buf[1]))) {
+ return -1;
+ }
+ return atoi(buf);
+}
+
+static struct timespec convert_date(const char *date)
+{
+ (void)date;
+ struct timespec ts = { 0 };
+ return ts;
+}
+
+static struct timespec convert_time(const char *date)
+{
+ struct timespec ts = { 0 };
+ time_t now = time(NULL);
+ struct tm *tm = localtime(&now);
+ tm->tm_yday = 0;
+ tm->tm_wday = 0;
+ int century = -1;
+
+ char *dot = strchr(date, '.');
+ if (dot) {
+ if (strlen(dot + 1) != 2) {
+ fprintf(stderr, "invalid time %s\n", date);
+ exit(1);
+ }
+ /* TODO: 00 - 60 */
+ tm->tm_sec = twodigits(dot + 1);
+ } else {
+ tm->tm_sec = 0;
+ }
+
+ switch (strlen(date) - (dot ? 3 : 0)) {
+ case 12:
+ century = twodigits(date) - 19;
+ date += 2;
+ /* FALLTHRU */
+ case 10:
+ /* TODO: 00 - 99 */
+ if (century == -1) {
+ tm->tm_year = twodigits(date);
+ if (00 <= tm->tm_year && tm->tm_year <= 68) {
+ tm->tm_year += 100;
+ }
+ } else {
+ tm->tm_year = (century * 100) + twodigits(date);
+ }
+ date += 2;
+ /* FALLTHRU */
+ case 8:
+ /* TODO: 01 - 12 */
+ tm->tm_mon = twodigits(date) - 1;
+ date += 2;
+ /* FALLTHRU */
+ case 6:
+ /* TODO: 01 - 31 */
+ tm->tm_mday = twodigits(date);
+ date += 2;
+ /* FALLTHRU */
+ case 4:
+ /* TODO: 00 - 23 */
+ tm->tm_hour = twodigits(date);
+ date += 2;
+ /* FALLTHRU */
+ case 2:
+ /* TODO: 00 - 59 */
+ tm->tm_min = twodigits(date);
+ break;
+ default:
+ fprintf(stderr, "invalide time %s\n", date);
+ exit(1);
+ }
+
+ /* TODO: account for TZ */
+ /* TODO: time too great to represent */
+
+ ts.tv_sec = mktime(tm);
+
+ return ts;
+}
+
int main(int argc, char *argv[])
{
setlocale(LC_ALL, "");
@@ -126,10 +214,10 @@ int main(int argc, char *argv[])
times[1].tv_nsec = UTIME_NOW;
break;
case DATE:
- /* TODO */
+ times[0] = times[1] = convert_date(source);
break;
case TIME:
- /* TODO */
+ times[0] = times[1] = convert_time(source);
break;
case FILE:
if (stat(source, &st) != 0) {