# HG changeset patch # User Rob Landley # Date 1353110495 21600 # Node ID 9fb5fe6eb13fcf332dfe1d1d6d8e4d980a35047a # Parent 7b316e3c0e11d920cd32d12557d54d84e54cd8d9 More touch cleanup to use generic infrastructure: use getdate() from libc, use flag macros, option parsing can collect argument strings in global block, use existing perror_* macros. diff -r 7b316e3c0e11 -r 9fb5fe6eb13f lib/portability.h --- a/lib/portability.h Fri Nov 16 15:44:45 2012 -0600 +++ b/lib/portability.h Fri Nov 16 18:01:35 2012 -0600 @@ -27,6 +27,8 @@ // Another one. "Function prototypes shall be provided." but aren't. // http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html char *crypt(const char *key, const char *salt); +// And again, from all the way back in posix-2001 +struct tm *getdate(const char *string); // When building under obsolete glibc, hold its hand a bit. diff -r 7b316e3c0e11 -r 9fb5fe6eb13f toys/posix/touch.c --- a/toys/posix/touch.c Fri Nov 16 15:44:45 2012 -0600 +++ b/toys/posix/touch.c Fri Nov 16 18:01:35 2012 -0600 @@ -5,7 +5,7 @@ * * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/touch.html -USE_TOUCH(NEWTOY(touch, "mrt", TOYFLAG_BIN)) +USE_TOUCH(NEWTOY(touch, "mr:t:", TOYFLAG_BIN)) config TOUCH bool "th" @@ -18,119 +18,43 @@ -t STAMP use [[CC]YY]MMDDhhmm[.ss] instead of current time */ +#define FOR_touch #include "toys.h" -int check_date_format(char *date_input) -{ - int count_date_digit = 0; - unsigned long long flag_b4_sec; - int flag_af_sec; - char *date_store = (char *)malloc(12 * sizeof(char)); - - while(date_input[count_date_digit] != '.') { - date_store[count_date_digit] = date_input[count_date_digit]; - count_date_digit++; - } - date_store[count_date_digit++] = '\0'; - flag_b4_sec = atoll(date_store); - date_store[0] = date_input[count_date_digit++]; - date_store[1] = date_input[count_date_digit]; - date_store[2] = '\0'; - flag_af_sec = atoi(date_store); - if(date_store[0] == '0' && date_store[1] == '0') flag_af_sec = 1; - if(flag_b4_sec && flag_af_sec) return 0; - else return -1; -} - -/* function to return number of seconds since epoch till the given date */ -time_t get_time_sec(char *date_input) -{ - int count_date_digit = 0; - char mm[3]; - char year[5]; - time_t time_of_modify; - struct tm t_yyyymmddhhss; - - while(date_input[count_date_digit] != '.') { - if(count_date_digit < 4) - year[count_date_digit] = date_input[count_date_digit]; - count_date_digit++; - if(count_date_digit == 4) { - year[count_date_digit] = '\0'; - t_yyyymmddhhss.tm_year = atoi(year)-1900; - break; - } - } - mm[0] = date_input[4]; - mm[1] = date_input[5]; - mm[2] = '\0'; - t_yyyymmddhhss.tm_mon = (atoi(mm) - 1); - mm[0] = date_input[6]; - mm[1] = date_input[7]; - mm[2] = '\0'; - t_yyyymmddhhss.tm_mday = atoi(mm); - mm[0] = date_input[8]; - mm[1] = date_input[9]; - mm[2] = '\0'; - t_yyyymmddhhss.tm_hour = atoi(mm); - mm[0] = date_input[10]; - mm[1] = date_input[11]; - mm[2] = '\0'; - t_yyyymmddhhss.tm_min = atoi(mm); - mm[0] = date_input[13]; - mm[1] = date_input[14]; - mm[2] = '\0'; - t_yyyymmddhhss.tm_sec = atoi(mm); - time_of_modify = mktime(&t_yyyymmddhhss); - return time_of_modify; -} +GLOBALS( + char *date; + char *file; +) void touch_main(void) { - int fd, touch_flag_t = 0, touch_flag_m = 0, touch_flag_r = 0; + int fd; time_t now; struct utimbuf modinfo; - struct stat filestat; + struct stat st; + + if (TT.date) { + struct tm *tm = getdate(TT.date); - if (!toys.optflags) { - time(&now); - modinfo.modtime = now; - modinfo.actime = now; - } else { - if (toys.optflags & 1) { - touch_flag_t = 1; - if ((toys.optflags >> 2) & 1) touch_flag_m = 1; - } + if (!tm) perror_exit("bad date '%s'", TT.date); + now = mktime(tm); + } else time(&now); + modinfo.modtime = now; + modinfo.actime = now; - if ((toys.optflags >> 1) & 1) touch_flag_r = 1; - - if (toys.optflags >> 2) touch_flag_m = 1; + if (TT.file) { + xstat(TT.file, &st); + modinfo.modtime = st.st_mtime; + modinfo.actime = st.st_atime; } - if (touch_flag_t) { - if (!check_date_format(toys.optargs[0])) { - modinfo.modtime = get_time_sec((char *)toys.optargs[0]); - modinfo.actime = get_time_sec(toys.optargs[0]); - } else { - perror_msg("Invalid date format, -t [yyyyMMddhhmm.ss]"); - toys.exitval = EXIT_FAILURE; - } - } - if(touch_flag_r) { - if(stat(toys.optargs[0], &filestat) < 0) { - printf("Error : unable to get information for file %s\n", toys.optargs[0]); - toys.exitval = EXIT_FAILURE; - } - modinfo.modtime = filestat.st_mtime; - modinfo.actime = filestat.st_atime; - } - if(touch_flag_m) { - if(stat(toys.optargs[toys.optc - 1], &filestat) < 0) { + if (toys.optflags & FLAG_m) { + if(stat(toys.optargs[toys.optc - 1], &st) < 0) { toys.exitval = EXIT_FAILURE; return; } - modinfo.actime = filestat.st_atime; - if(!(touch_flag_r | touch_flag_t)) { + modinfo.actime = st.st_atime; + if(!(toys.optflags & (FLAG_r|FLAG_t))) { time(&now); modinfo.modtime = now; } @@ -140,10 +64,8 @@ close(fd); utime(toys.optargs[toys.optc - 1], &modinfo); } else { - perror("unable to create the file"); + perror_msg("can't create '%s'", toys.optargs[toys.optc-1]); toys.exitval = EXIT_FAILURE; } } } - -