blob: bead28fb6a80f78a1cb76cc1c81ff48487521ede [file] [log] [blame]
Rob Landley28964802008-01-19 17:08:39 -06001/* vi: set sw=4 ts=4:
2 *
Rob Landley8ae467c2007-10-31 01:13:36 -05003 * touch.c - Modify a file's timestamps.
4 *
5 * Copyright (C) 2007 Charlie Shepherd <masterdriverz@gentoo.org>
Rob Landleyfece5cb2007-12-03 20:05:57 -06006 *
Rob Landley5c67e352007-12-11 15:41:31 -06007 * See http://www.opengroup.org/onlinepubs/009695399/utilities/touch.html
Rob Landley28964802008-01-19 17:08:39 -06008
Rob Landley0f8c4c52008-02-12 19:05:44 -06009USE_TOUCH(NEWTOY(touch, "l#t:r:mca", TOYFLAG_BIN|TOYFLAG_UMASK))
Rob Landley55928b12008-01-19 17:43:27 -060010
Rob Landley28964802008-01-19 17:08:39 -060011config 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 Landley56dac2a2007-06-18 00:17:04 -040026
27#include "toys.h"
28
Rob Landleyb1aaba12008-01-20 17:25:44 -060029DEFINE_GLOBALS(
30 char *ref_file;
31 char *time;
32 long length;
33)
34
35#define TT this.touch
36
Rob Landley07c78d32007-12-28 03:29:33 -060037#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 Landley56dac2a2007-06-18 00:17:04 -040043
Rob Landleyefda21c2007-11-29 18:14:37 -060044void touch_main(void)
Rob Landley56dac2a2007-06-18 00:17:04 -040045{
Rob Landley8ae467c2007-10-31 01:13:36 -050046 char *arg;
Rob Landley7abb9762007-11-30 04:37:24 -060047 int i, set_a, set_m;
Rob Landley8ae467c2007-10-31 01:13:36 -050048 time_t curr_a, curr_m;
49
Rob Landley7abb9762007-11-30 04:37:24 -060050 set_a = !!(toys.optflags & OPT_ATIME);
51 set_m = !!(toys.optflags & OPT_MTIME);
Rob Landley8ae467c2007-10-31 01:13:36 -050052
Rob Landley7abb9762007-11-30 04:37:24 -060053 // Use timestamp on a file
54 if (toys.optflags & OPT_REFERENCE) {
Rob Landley8ae467c2007-10-31 01:13:36 -050055 struct stat sb;
Rob Landley7abb9762007-11-30 04:37:24 -060056
57 if (toys.optflags & OPT_TIME)
58 error_exit("Redundant time source");
Rob Landleyb1aaba12008-01-20 17:25:44 -060059 xstat(TT.ref_file, &sb);
Rob Landley8ae467c2007-10-31 01:13:36 -050060 curr_m = sb.st_mtime;
61 curr_a = sb.st_atime;
Rob Landley7abb9762007-11-30 04:37:24 -060062
63 // Use time specified on command line.
64 } else if (toys.optflags & OPT_TIME) {
Rob Landley8ae467c2007-10-31 01:13:36 -050065 struct tm t;
66 time_t curr;
67 char *c;
Rob Landley7abb9762007-11-30 04:37:24 -060068
Rob Landley8ae467c2007-10-31 01:13:36 -050069 curr = time(NULL);
Rob Landley7abb9762007-11-30 04:37:24 -060070 if (localtime_r(&curr, &t)
Rob Landleyb1aaba12008-01-20 17:25:44 -060071 || !(c = strptime(TT.time, "%m%d%H%M", &t))
Rob Landley7abb9762007-11-30 04:37:24 -060072 || *c || -1==(curr_a = curr_m = mktime(&t)))
73 {
Rob Landleyb1aaba12008-01-20 17:25:44 -060074 error_exit("Unknown time %s", TT.time);
Rob Landley7abb9762007-11-30 04:37:24 -060075 }
76
77 // use current time
78 } else curr_m = curr_a = time(NULL);
Rob Landley8ae467c2007-10-31 01:13:36 -050079
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 Landley07c78d32007-12-28 03:29:33 -060087 if (stat(arg, &sb)) {
88 if (!(toys.optflags & OPT_NOCREATE)) {
Rob Landley07c78d32007-12-28 03:29:33 -060089 xcreate(arg, O_CREAT, 0644);
Rob Landley8ae467c2007-10-31 01:13:36 -050090 if (stat(arg, &sb))
91 goto error;
92 }
Rob Landley8ae467c2007-10-31 01:13:36 -050093 }
94
95 if ((set_a+set_m) == 1) {
96 /* We've been asked to only change one */
Rob Landley7abb9762007-11-30 04:37:24 -060097 if (set_a) buf.modtime = sb.st_mtime;
98 else if (set_m) buf.actime = sb.st_atime;
Rob Landley8ae467c2007-10-31 01:13:36 -050099 }
100
Rob Landley7abb9762007-11-30 04:37:24 -0600101 if (toys.optflags & OPT_LENGTH)
Rob Landleyb1aaba12008-01-20 17:25:44 -0600102 if (truncate(arg, TT.length))
Charlie Shepherd627dc772007-11-10 10:03:01 +0000103 goto error;
Charlie Shepherdd42ed832007-11-10 09:30:02 +0000104 if (utime(arg, &buf))
Charlie Shepherd627dc772007-11-10 10:03:01 +0000105error:
Charlie Shepherdd42ed832007-11-10 09:30:02 +0000106 perror_exit(arg);
Rob Landley8ae467c2007-10-31 01:13:36 -0500107 }
Rob Landley56dac2a2007-06-18 00:17:04 -0400108}