aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/portability.h2
-rw-r--r--toys/posix/touch.c126
2 files changed, 26 insertions, 102 deletions
diff --git a/lib/portability.h b/lib/portability.h
index 33e2672f..1b5667ce 100644
--- a/lib/portability.h
+++ b/lib/portability.h
@@ -27,6 +27,8 @@ char *strptime(const char *buf, const char *format, struct tm *tm);
// 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 --git a/toys/posix/touch.c b/toys/posix/touch.c
index 30e3748f..938863d6 100644
--- a/toys/posix/touch.c
+++ b/toys/posix/touch.c
@@ -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 @@ config TOUCH
-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 (!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 (TT.date) {
+ struct tm *tm = getdate(TT.date);
- if ((toys.optflags >> 1) & 1) touch_flag_r = 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 >> 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 @@ void touch_main(void)
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;
}
}
}
-
-