1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
/* touch.c : change timestamp of a file
*
* Copyright 2012 Choubey Ji <warior.linux@gmail.com>
*
* See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/touch.html
USE_TOUCH(NEWTOY(touch, "acd:mr:t:[!dtr]", TOYFLAG_BIN))
config TOUCH
bool "touch"
default y
help
usage: touch [-amc] [-d DATE] [-t TIME] [-r FILE] FILE...
Update the access and modification times of each FILE to the current time.
-a change access time
-m change modification time
-c don't create file
-d set time to DATE (in YYYY-MM-DDThh:mm:SS[.frac][tz] format)
-t set time to TIME (in [[CC]YY]MMDDhhmm[.ss][frac] format)
-r set time same as reference FILE
*/
#define FOR_touch
#include "toys.h"
GLOBALS(
char *time;
char *file;
char *date;
)
// Fetch access and/or modification time of a file
int fetch(char *file, struct timeval *tv, unsigned flags)
{
struct stat st;
if (stat(TT.file, &st)) return 1;
if (flags & FLAG_a) {
tv[0].tv_sec = st.st_atime;
tv[0].tv_usec = st.st_atim.tv_nsec/1000;
}
if (flags & FLAG_m) {
tv[1].tv_sec = st.st_mtime;
tv[1].tv_usec = st.st_mtim.tv_nsec/1000;
}
return 0;
}
void touch_main(void)
{
struct timeval tv[2];
struct tm tm;
char **ss, *date, *s;
int flag, fd, i, len;
// Set time from clock?
gettimeofday(tv, NULL);
localtime_r(&(tv->tv_sec), &tm);
// Set time from -d?
if (toys.optflags & (FLAG_t|FLAG_d)) {
if (toys.optflags & FLAG_d) {
date = TT.date;
i = strlen(date);
if (i && i < sizeof(toybuf)) {
// Trailing Z means UTC timezone, don't expect libc to know this.
if (toupper(date[i])=='Z') {
putenv("TZ=UTC");
strcpy(toybuf, date);
toybuf[i] = 0;
date = toybuf;
gmtime_r(&(tv->tv_sec), &tm);
}
s = strptime(date, "%Y-%m-%dT%T", &tm);
if (s && *s=='.') {
sscanf(s, ".%d%n", &i, &len);
s += len;
tv->tv_usec = i;
}
} else s = 0;
// Set time from -t?
} else {
strcpy(toybuf, "%Y%m%d%H%M");
date = TT.time;
for (i=0;i<3;i++) {
s = strptime(date, toybuf+(i&2), &tm);
if (s) break;
toybuf[1]='y';
}
if (s && *s=='.') {
int count = sscanf(s, ".%2d%u%n", &(tm.tm_sec), &i, &len);
if (count==2) tv->tv_usec = i;
s += len;
}
}
errno = 0;
tv->tv_sec = mktime(&tm);
if (!s || *s || errno == EOVERFLOW) {
// Warn Indiana Jones the monkey died.
perror_exit("bad '%s'", date);
}
}
tv[1]=tv[0];
// Set time from -r?
if (TT.file && fetch(TT.file, tv, FLAG_a|FLAG_m))
perror_exit("-r '%s'", TT.file);
// Ok, we've got a time. Flip -am flags so now it's the ones we _keep_.
flag = (~toys.optflags) & (FLAG_m|FLAG_a);
// Loop through files on command line
for (ss=toys.optargs; *ss;) {
if ((flag == (FLAG_m|FLAG_a) || !fetch(*ss, tv, flag)) && !utimes(*ss, tv))
ss++;
else if (toys.optflags & FLAG_c) ss++;
else if (-1 != (fd = open(*ss, O_CREAT, 0666))) close(fd);
else perror_msg("'%s'", *ss++);
}
}
|