diff options
| -rw-r--r-- | test-chmtime.c | 91 | 
1 files changed, 70 insertions, 21 deletions
| diff --git a/test-chmtime.c b/test-chmtime.c index 90da448ebe..d5358cbaac 100644 --- a/test-chmtime.c +++ b/test-chmtime.c @@ -1,39 +1,83 @@ +/* + * This program can either change modification time of the given + * file(s) or just print it. The program does not change atime nor + * ctime (their values are explicitely preserved). + * + * The mtime can be changed to an absolute value: + * + *	test-chmtime =<seconds> file... + * + * Relative to the current time as returned by time(3): + * + *	test-chmtime =+<seconds> (or =-<seconds>) file... + * + * Or relative to the current mtime of the file: + * + *	test-chmtime <seconds> file... + *	test-chmtime +<seconds> (or -<seconds>) file... + * + * Examples: + * + * To just print the mtime use --verbose and set the file mtime offset to 0: + * + *	test-chmtime -v +0 file + * + * To set the mtime to current time: + * + *	test-chmtime =+0 file + * + */  #include "git-compat-util.h"  #include <utime.h> -static const char usage_str[] = "(+|=|=+|=-|-)<seconds> <file>..."; +static const char usage_str[] = "-v|--verbose (+|=|=+|=-|-)<seconds> <file>..."; -int main(int argc, const char *argv[]) +static int timespec_arg(const char *arg, long int *set_time, int *set_eq)  { -	int i; -	int set_eq; -	long int set_time;  	char *test; -	const char *timespec; - -	if (argc < 3) -		goto usage; - -	timespec = argv[1]; -	set_eq = (*timespec == '=') ? 1 : 0; -	if (set_eq) { +	const char *timespec = arg; +	*set_eq = (*timespec == '=') ? 1 : 0; +	if (*set_eq) {  		timespec++;  		if (*timespec == '+') { -			set_eq = 2; /* relative "in the future" */ +			*set_eq = 2; /* relative "in the future" */  			timespec++;  		}  	} -	set_time = strtol(timespec, &test, 10); +	*set_time = strtol(timespec, &test, 10);  	if (*test) { -		fprintf(stderr, "Not a base-10 integer: %s\n", argv[1] + 1); -		goto usage; +		fprintf(stderr, "Not a base-10 integer: %s\n", arg + 1); +		return 0;  	} -	if ((set_eq && set_time < 0) || set_eq == 2) { +	if ((*set_eq && *set_time < 0) || *set_eq == 2) {  		time_t now = time(NULL); -		set_time += now; +		*set_time += now;  	} +	return 1; +} + +int main(int argc, const char *argv[]) +{ +	static int verbose; -	for (i = 2; i < argc; i++) { +	int i = 1; +	/* no mtime change by default */ +	int set_eq = 0; +	long int set_time = 0; + +	if (argc < 3) +		goto usage; + +	if (strcmp(argv[i], "--verbose") == 0 || strcmp(argv[i], "-v") == 0) { +		verbose = 1; +		++i; +	} +	if (timespec_arg(argv[i], &set_time, &set_eq)) +		++i; +	else +		goto usage; + +	for (; i < argc; i++) {  		struct stat sb;  		struct utimbuf utb; @@ -46,7 +90,12 @@ int main(int argc, const char *argv[])  		utb.actime = sb.st_atime;  		utb.modtime = set_eq ? set_time : sb.st_mtime + set_time; -		if (utime(argv[i], &utb) < 0) { +		if (verbose) { +			uintmax_t mtime = utb.modtime < 0 ? 0: utb.modtime; +			printf("%"PRIuMAX"\t%s\n", mtime, argv[i]); +		} + +		if (utb.modtime != sb.st_mtime && utime(argv[i], &utb) < 0) {  			fprintf(stderr, "Failed to modify time on %s: %s\n",  			        argv[i], strerror(errno));  			return -1; | 
