| Rob Landley | 2896480 | 2008-01-19 17:08:39 -0600 | [diff] [blame] | 1 | /* vi: set sw=4 ts=4: |
| 2 | * |
| Rob Landley | 8ae467c | 2007-10-31 01:13:36 -0500 | [diff] [blame] | 3 | * touch.c - Modify a file's timestamps. |
| 4 | * |
| 5 | * Copyright (C) 2007 Charlie Shepherd <masterdriverz@gentoo.org> |
| Rob Landley | fece5cb | 2007-12-03 20:05:57 -0600 | [diff] [blame] | 6 | * |
| Rob Landley | 5c67e35 | 2007-12-11 15:41:31 -0600 | [diff] [blame] | 7 | * See http://www.opengroup.org/onlinepubs/009695399/utilities/touch.html |
| Rob Landley | 2896480 | 2008-01-19 17:08:39 -0600 | [diff] [blame] | 8 | |
| Rob Landley | 0f8c4c5 | 2008-02-12 19:05:44 -0600 | [diff] [blame] | 9 | USE_TOUCH(NEWTOY(touch, "l#t:r:mca", TOYFLAG_BIN|TOYFLAG_UMASK)) |
| Rob Landley | 55928b1 | 2008-01-19 17:43:27 -0600 | [diff] [blame] | 10 | |
| Rob Landley | 2896480 | 2008-01-19 17:08:39 -0600 | [diff] [blame] | 11 | config TOUCH |
| 12 | bool "touch" |
| 13 | default y |
| 14 | help |
| 15 | usage: touch [-acm] [-r FILE] [-t MMDDhhmm] [-l bytes] FILE... |
| 16 | |
| 17 | Change file timestamps, ensure file existance and change file length. |
| 18 | |
| 19 | -a Only change the access time. |
| 20 | -c Do not create the file if it doesn't exist. |
| 21 | -l Length to truncate (or sparsely extend) file to. |
| 22 | -m Only change the modification time. |
| 23 | -r Reference file to take timestamps from. |
| 24 | -t Time to change {a,m}time to. |
| 25 | */ |
| Rob Landley | 56dac2a | 2007-06-18 00:17:04 -0400 | [diff] [blame] | 26 | |
| 27 | #include "toys.h" |
| 28 | |
| Rob Landley | b1aaba1 | 2008-01-20 17:25:44 -0600 | [diff] [blame] | 29 | DEFINE_GLOBALS( |
| 30 | char *ref_file; |
| 31 | char *time; |
| 32 | long length; |
| 33 | ) |
| 34 | |
| 35 | #define TT this.touch |
| 36 | |
| Rob Landley | 07c78d3 | 2007-12-28 03:29:33 -0600 | [diff] [blame] | 37 | #define OPT_MTIME 0x01 |
| 38 | #define OPT_NOCREATE 0x02 |
| 39 | #define OPT_ATIME 0x04 |
| 40 | #define OPT_REFERENCE 0x08 |
| 41 | #define OPT_TIME 0x10 |
| 42 | #define OPT_LENGTH 0x20 |
| Rob Landley | 56dac2a | 2007-06-18 00:17:04 -0400 | [diff] [blame] | 43 | |
| Rob Landley | efda21c | 2007-11-29 18:14:37 -0600 | [diff] [blame] | 44 | void touch_main(void) |
| Rob Landley | 56dac2a | 2007-06-18 00:17:04 -0400 | [diff] [blame] | 45 | { |
| Rob Landley | 8ae467c | 2007-10-31 01:13:36 -0500 | [diff] [blame] | 46 | char *arg; |
| Rob Landley | 7abb976 | 2007-11-30 04:37:24 -0600 | [diff] [blame] | 47 | int i, set_a, set_m; |
| Rob Landley | 8ae467c | 2007-10-31 01:13:36 -0500 | [diff] [blame] | 48 | time_t curr_a, curr_m; |
| 49 | |
| Rob Landley | 7abb976 | 2007-11-30 04:37:24 -0600 | [diff] [blame] | 50 | set_a = !!(toys.optflags & OPT_ATIME); |
| 51 | set_m = !!(toys.optflags & OPT_MTIME); |
| Rob Landley | 8ae467c | 2007-10-31 01:13:36 -0500 | [diff] [blame] | 52 | |
| Rob Landley | 7abb976 | 2007-11-30 04:37:24 -0600 | [diff] [blame] | 53 | // Use timestamp on a file |
| 54 | if (toys.optflags & OPT_REFERENCE) { |
| Rob Landley | 8ae467c | 2007-10-31 01:13:36 -0500 | [diff] [blame] | 55 | struct stat sb; |
| Rob Landley | 7abb976 | 2007-11-30 04:37:24 -0600 | [diff] [blame] | 56 | |
| 57 | if (toys.optflags & OPT_TIME) |
| 58 | error_exit("Redundant time source"); |
| Rob Landley | b1aaba1 | 2008-01-20 17:25:44 -0600 | [diff] [blame] | 59 | xstat(TT.ref_file, &sb); |
| Rob Landley | 8ae467c | 2007-10-31 01:13:36 -0500 | [diff] [blame] | 60 | curr_m = sb.st_mtime; |
| 61 | curr_a = sb.st_atime; |
| Rob Landley | 7abb976 | 2007-11-30 04:37:24 -0600 | [diff] [blame] | 62 | |
| 63 | // Use time specified on command line. |
| 64 | } else if (toys.optflags & OPT_TIME) { |
| Rob Landley | 8ae467c | 2007-10-31 01:13:36 -0500 | [diff] [blame] | 65 | struct tm t; |
| 66 | time_t curr; |
| 67 | char *c; |
| Rob Landley | 7abb976 | 2007-11-30 04:37:24 -0600 | [diff] [blame] | 68 | |
| Rob Landley | 8ae467c | 2007-10-31 01:13:36 -0500 | [diff] [blame] | 69 | curr = time(NULL); |
| Rob Landley | 7abb976 | 2007-11-30 04:37:24 -0600 | [diff] [blame] | 70 | if (localtime_r(&curr, &t) |
| Rob Landley | b1aaba1 | 2008-01-20 17:25:44 -0600 | [diff] [blame] | 71 | || !(c = strptime(TT.time, "%m%d%H%M", &t)) |
| Rob Landley | 7abb976 | 2007-11-30 04:37:24 -0600 | [diff] [blame] | 72 | || *c || -1==(curr_a = curr_m = mktime(&t))) |
| 73 | { |
| Rob Landley | b1aaba1 | 2008-01-20 17:25:44 -0600 | [diff] [blame] | 74 | error_exit("Unknown time %s", TT.time); |
| Rob Landley | 7abb976 | 2007-11-30 04:37:24 -0600 | [diff] [blame] | 75 | } |
| 76 | |
| 77 | // use current time |
| 78 | } else curr_m = curr_a = time(NULL); |
| Rob Landley | 8ae467c | 2007-10-31 01:13:36 -0500 | [diff] [blame] | 79 | |
| 80 | for (i = 0; (arg = toys.optargs[i]); i++) { |
| 81 | struct utimbuf buf; |
| 82 | struct stat sb; |
| 83 | |
| 84 | buf.modtime = curr_m; |
| 85 | buf.actime = curr_a; |
| 86 | |
| Rob Landley | 07c78d3 | 2007-12-28 03:29:33 -0600 | [diff] [blame] | 87 | if (stat(arg, &sb)) { |
| 88 | if (!(toys.optflags & OPT_NOCREATE)) { |
| Rob Landley | 07c78d3 | 2007-12-28 03:29:33 -0600 | [diff] [blame] | 89 | xcreate(arg, O_CREAT, 0644); |
| Rob Landley | 8ae467c | 2007-10-31 01:13:36 -0500 | [diff] [blame] | 90 | if (stat(arg, &sb)) |
| 91 | goto error; |
| 92 | } |
| Rob Landley | 8ae467c | 2007-10-31 01:13:36 -0500 | [diff] [blame] | 93 | } |
| 94 | |
| 95 | if ((set_a+set_m) == 1) { |
| 96 | /* We've been asked to only change one */ |
| Rob Landley | 7abb976 | 2007-11-30 04:37:24 -0600 | [diff] [blame] | 97 | if (set_a) buf.modtime = sb.st_mtime; |
| 98 | else if (set_m) buf.actime = sb.st_atime; |
| Rob Landley | 8ae467c | 2007-10-31 01:13:36 -0500 | [diff] [blame] | 99 | } |
| 100 | |
| Rob Landley | 7abb976 | 2007-11-30 04:37:24 -0600 | [diff] [blame] | 101 | if (toys.optflags & OPT_LENGTH) |
| Rob Landley | b1aaba1 | 2008-01-20 17:25:44 -0600 | [diff] [blame] | 102 | if (truncate(arg, TT.length)) |
| Charlie Shepherd | 627dc77 | 2007-11-10 10:03:01 +0000 | [diff] [blame] | 103 | goto error; |
| Charlie Shepherd | d42ed83 | 2007-11-10 09:30:02 +0000 | [diff] [blame] | 104 | if (utime(arg, &buf)) |
| Charlie Shepherd | 627dc77 | 2007-11-10 10:03:01 +0000 | [diff] [blame] | 105 | error: |
| Charlie Shepherd | d42ed83 | 2007-11-10 09:30:02 +0000 | [diff] [blame] | 106 | perror_exit(arg); |
| Rob Landley | 8ae467c | 2007-10-31 01:13:36 -0500 | [diff] [blame] | 107 | } |
| Rob Landley | 56dac2a | 2007-06-18 00:17:04 -0400 | [diff] [blame] | 108 | } |