Add --verbose|-v to test-chmtime
This allows us replace perl when getting the mtime of a file because of time zone conversions, though at the moment only one platform which does this has been identified: Cygwin when used with ActiveState Perl (as usual). The output format is: <mtime1> TAB <filename1> <LF> <mtime2> TAB <filename2> <LF> ... which, if only mtime is needed can be parsed with cut(1): test-chmtime -v +0 filename1 | cut -f 1 Also, the change adds a description of programs features, with examples. Signed-off-by: Alex Riesen <ariesen@harmanbecker.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Alex Riesen committed
Oct 30, 2008 at 10:00 UTC
0ea9ca07aa76bef80c066b1a70366cf90caa703d
1 file changed
+70
-21
test-chmtime.c
+70
-21
@@ -1,39 +1,83 @@
1
+/*
2
+ * This program can either change modification time of the given
3
+ * file(s) or just print it. The program does not change atime nor
4
+ * ctime (their values are explicitely preserved).
5
+ *
6
+ * The mtime can be changed to an absolute value:
7
+ *
8
+ * test-chmtime =<seconds> file...
9
+ *
10
+ * Relative to the current time as returned by time(3):
11
+ *
12
+ * test-chmtime =+<seconds> (or =-<seconds>) file...
13
+ *
14
+ * Or relative to the current mtime of the file:
15
+ *
16
+ * test-chmtime <seconds> file...
17
+ * test-chmtime +<seconds> (or -<seconds>) file...
18
+ *
19
+ * Examples:
20
+ *
21
+ * To just print the mtime use --verbose and set the file mtime offset to 0:
22
+ *
23
+ * test-chmtime -v +0 file
24
+ *
25
+ * To set the mtime to current time:
26
+ *
27
+ * test-chmtime =+0 file
28
+ *
29
+ */
30
#include "git-compat-util.h"
31
#include <utime.h>
32
4
-static const char usage_str[] = "(+|=|=+|=-|-)<seconds> <file>...";
33
+static const char usage_str[] = "-v|--verbose (+|=|=+|=-|-)<seconds> <file>...";
34
6
-int main(int argc, const char *argv[])
35
+static int timespec_arg(const char *arg, long int *set_time, int *set_eq)
36
{
8
- int i;
9
- int set_eq;
10
- long int set_time;
37
char *test;
12
- const char *timespec;
13
-
14
- if (argc < 3)
15
- goto usage;
16
-
17
- timespec = argv[1];
18
- set_eq = (*timespec == '=') ? 1 : 0;
19
- if (set_eq) {
38
+ const char *timespec = arg;
39
+ *set_eq = (*timespec == '=') ? 1 : 0;
40
+ if (*set_eq) {
41
timespec++;
42
if (*timespec == '+') {
22
- set_eq = 2; /* relative "in the future" */
43
+ *set_eq = 2; /* relative "in the future" */
44
timespec++;
45
}
46
}
26
- set_time = strtol(timespec, &test, 10);
47
+ *set_time = strtol(timespec, &test, 10);
48
if (*test) {
28
- fprintf(stderr, "Not a base-10 integer: %s\n", argv[1] + 1);
29
- goto usage;
49
+ fprintf(stderr, "Not a base-10 integer: %s\n", arg + 1);
50
+ return 0;
51
}
31
- if ((set_eq && set_time < 0) || set_eq == 2) {
52
+ if ((*set_eq && *set_time < 0) || *set_eq == 2) {
53
time_t now = time(NULL);
33
- set_time += now;
54
+ *set_time += now;
55
}
56
+ return 1;
57
+}
58
+
59
+int main(int argc, const char *argv[])
60
+{
61
+ static int verbose;
62
36
- for (i = 2; i < argc; i++) {
63
+ int i = 1;
64
+ /* no mtime change by default */
65
+ int set_eq = 0;
66
+ long int set_time = 0;
67
+
68
+ if (argc < 3)
69
+ goto usage;
70
+
71
+ if (strcmp(argv[i], "--verbose") == 0 || strcmp(argv[i], "-v") == 0) {
72
+ verbose = 1;
73
+ ++i;
74
+ }
75
+ if (timespec_arg(argv[i], &set_time, &set_eq))
76
+ ++i;
77
+ else
78
+ goto usage;
79
+
80
+ for (; i < argc; i++) {
81
struct stat sb;
82
struct utimbuf utb;
83
@@ -46,7 +90,12 @@ int main(int argc, const char *argv[])
90
utb.actime = sb.st_atime;
91
utb.modtime = set_eq ? set_time : sb.st_mtime + set_time;
92
49
- if (utime(argv[i], &utb) < 0) {
93
+ if (verbose) {
94
+ uintmax_t mtime = utb.modtime < 0 ? 0: utb.modtime;
95
+ printf("%"PRIuMAX"\t%s\n", mtime, argv[i]);
96
+ }
97
+
98
+ if (utb.modtime != sb.st_mtime && utime(argv[i], &utb) < 0) {
99
fprintf(stderr, "Failed to modify time on %s: %s\n",
100
argv[i], strerror(errno));
101
return -1;