diff options
-rw-r--r-- | touch.c | 92 |
1 files changed, 90 insertions, 2 deletions
@@ -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) { |