Add proper d- and t-flag support to touch(1)
except the [,frac], [.frac] respectively, but that's ok.
This commit is contained in:
		
							
								
								
									
										2
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								README
									
									
									
									
									
								
							@@ -73,7 +73,7 @@ The following tools are implemented ('*' == finished, '#' == UTF-8 support,
 | 
				
			|||||||
=* tar             non-posix                    none
 | 
					=* tar             non-posix                    none
 | 
				
			||||||
=* tee             yes                          none
 | 
					=* tee             yes                          none
 | 
				
			||||||
#* test            yes                          none
 | 
					#* test            yes                          none
 | 
				
			||||||
=* touch           yes                          none (-d) (-t)
 | 
					=* touch           yes                          none
 | 
				
			||||||
#* tr              yes                          none
 | 
					#* tr              yes                          none
 | 
				
			||||||
=* true            yes                          none
 | 
					=* true            yes                          none
 | 
				
			||||||
=* tty             yes                          none
 | 
					=* tty             yes                          none
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										41
									
								
								touch.1
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								touch.1
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
				
			|||||||
.Dd February 19, 2015
 | 
					.Dd February 9, 2015
 | 
				
			||||||
.Dt TOUCH 1
 | 
					.Dt TOUCH 1
 | 
				
			||||||
.Os sbase
 | 
					.Os sbase
 | 
				
			||||||
.Sh NAME
 | 
					.Sh NAME
 | 
				
			||||||
@@ -7,11 +7,11 @@
 | 
				
			|||||||
.Sh SYNOPSIS
 | 
					.Sh SYNOPSIS
 | 
				
			||||||
.Nm
 | 
					.Nm
 | 
				
			||||||
.Op Fl acm
 | 
					.Op Fl acm
 | 
				
			||||||
.Op Fl r Ar ref_file | Fl t Ar timestamp
 | 
					.Op Fl d Ar time | Fl r Ar ref_file | Fl T Ar time | Fl t Ar time
 | 
				
			||||||
.Ar file ...
 | 
					.Ar file ...
 | 
				
			||||||
.Sh DESCRIPTION
 | 
					.Sh DESCRIPTION
 | 
				
			||||||
.Nm
 | 
					.Nm
 | 
				
			||||||
sets the access or modification time of each
 | 
					sets the access and modification time of each
 | 
				
			||||||
.Ar file
 | 
					.Ar file
 | 
				
			||||||
to the current time of day. If
 | 
					to the current time of day. If
 | 
				
			||||||
.Ar file
 | 
					.Ar file
 | 
				
			||||||
@@ -25,19 +25,30 @@ Set the access | modification time of
 | 
				
			|||||||
Don't create
 | 
					Don't create
 | 
				
			||||||
.Ar file
 | 
					.Ar file
 | 
				
			||||||
if it doesn't exist, not affecting exit status.
 | 
					if it doesn't exist, not affecting exit status.
 | 
				
			||||||
 | 
					.It Fl d Ar time
 | 
				
			||||||
 | 
					Set the
 | 
				
			||||||
 | 
					.Ar time
 | 
				
			||||||
 | 
					of the format YYYY-MM-DDThh:mm:SS[Z] used for
 | 
				
			||||||
 | 
					.Op Fl am .
 | 
				
			||||||
.It Fl r Ar ref_file
 | 
					.It Fl r Ar ref_file
 | 
				
			||||||
Set the timestamp
 | 
					Set the
 | 
				
			||||||
to be used with
 | 
					.Ar time
 | 
				
			||||||
 | 
					used for
 | 
				
			||||||
.Op Fl am
 | 
					.Op Fl am
 | 
				
			||||||
to the modification time of
 | 
					to the modification time of
 | 
				
			||||||
.Ar ref_file .
 | 
					.Ar ref_file .
 | 
				
			||||||
.It Fl t Ar timestamp
 | 
					.It Fl T Ar time
 | 
				
			||||||
Set the
 | 
					Set the
 | 
				
			||||||
.Ar timestamp
 | 
					.Ar time
 | 
				
			||||||
to be used with
 | 
					used for
 | 
				
			||||||
.Op Fl am
 | 
					.Op Fl am
 | 
				
			||||||
given as the number of seconds since the
 | 
					given as the number of seconds since the
 | 
				
			||||||
Unix epoch 1970-01-01T00:00:00Z.
 | 
					Unix epoch 1970-01-01T00:00:00Z.
 | 
				
			||||||
 | 
					.It Fl t Ar time
 | 
				
			||||||
 | 
					Set the
 | 
				
			||||||
 | 
					.Ar time
 | 
				
			||||||
 | 
					of the format [[CC]YY]MMDDhhmm[.SS] used for
 | 
				
			||||||
 | 
					.Op Fl am .
 | 
				
			||||||
.El
 | 
					.El
 | 
				
			||||||
.Sh SEE ALSO
 | 
					.Sh SEE ALSO
 | 
				
			||||||
.Xr date 1
 | 
					.Xr date 1
 | 
				
			||||||
@@ -46,10 +57,10 @@ The
 | 
				
			|||||||
.Nm
 | 
					.Nm
 | 
				
			||||||
utility is compliant with the
 | 
					utility is compliant with the
 | 
				
			||||||
.St -p1003.1-2008
 | 
					.St -p1003.1-2008
 | 
				
			||||||
specification except for
 | 
					specification, except from fractional seconds in the
 | 
				
			||||||
.Fl d
 | 
					.Op Fl d
 | 
				
			||||||
and the
 | 
					argument.
 | 
				
			||||||
.Ar timestamp
 | 
					.Pp
 | 
				
			||||||
format of the
 | 
					The
 | 
				
			||||||
.Fl t
 | 
					.Op Fl T
 | 
				
			||||||
flag.
 | 
					flag is an extension to this specification.
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										63
									
								
								touch.c
									
									
									
									
									
								
							
							
						
						
									
										63
									
								
								touch.c
									
									
									
									
									
								
							@@ -4,6 +4,7 @@
 | 
				
			|||||||
#include <errno.h>
 | 
					#include <errno.h>
 | 
				
			||||||
#include <fcntl.h>
 | 
					#include <fcntl.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
#include <time.h>
 | 
					#include <time.h>
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
#include <utime.h>
 | 
					#include <utime.h>
 | 
				
			||||||
@@ -43,6 +44,61 @@ touch(const char *file)
 | 
				
			|||||||
	touch(file);
 | 
						touch(file);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					time_t
 | 
				
			||||||
 | 
					parsetime(char *str, time_t current)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct tm *cur, t;
 | 
				
			||||||
 | 
						char *format;
 | 
				
			||||||
 | 
						size_t len = strlen(str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cur = localtime(¤t);
 | 
				
			||||||
 | 
						t.tm_isdst = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (len) {
 | 
				
			||||||
 | 
						/* -t flag argument */
 | 
				
			||||||
 | 
						case 8:
 | 
				
			||||||
 | 
							t.tm_sec = 0;
 | 
				
			||||||
 | 
							t.tm_year = cur->tm_year;
 | 
				
			||||||
 | 
							format = "%m%d%H%M";
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 10:
 | 
				
			||||||
 | 
							t.tm_sec = 0;
 | 
				
			||||||
 | 
							format = "%y%m%d%H%M";
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 11:
 | 
				
			||||||
 | 
							t.tm_year = cur->tm_year;
 | 
				
			||||||
 | 
							format = "%m%d%H%M.%S";
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 12:
 | 
				
			||||||
 | 
							t.tm_sec = 0;
 | 
				
			||||||
 | 
							format = "%Y%m%d%H%M";
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 13:
 | 
				
			||||||
 | 
							format = "%y%m%d%H%M.%S";
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 15:
 | 
				
			||||||
 | 
							format = "%Y%m%d%H%M.%S";
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						/* -d flag argument */
 | 
				
			||||||
 | 
						case 19:
 | 
				
			||||||
 | 
							format = "%Y-%m-%dT%H:%M:%S";
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 20:
 | 
				
			||||||
 | 
							/* only Zulu-timezone supported */
 | 
				
			||||||
 | 
							if (str[19] != 'Z')
 | 
				
			||||||
 | 
								goto default;
 | 
				
			||||||
 | 
							format = "%Y-%m-%dT%H:%M:%S%Z";
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							eprintf("Invalid date format length\n", str);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!strptime(str, format, &t))
 | 
				
			||||||
 | 
							weprintf("strptime %s: Invalid date format\n", str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return mktime(&t);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
usage(void)
 | 
					usage(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -72,15 +128,20 @@ main(int argc, char *argv[])
 | 
				
			|||||||
			eprintf("stat '%s':", ref);
 | 
								eprintf("stat '%s':", ref);
 | 
				
			||||||
		t = st.st_mtime;
 | 
							t = st.st_mtime;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 't':
 | 
						case 'T':
 | 
				
			||||||
		t = estrtonum(EARGF(usage()), 0, LLONG_MAX);
 | 
							t = estrtonum(EARGF(usage()), 0, LLONG_MAX);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
						case 't':
 | 
				
			||||||
 | 
							t = parsetime(EARGF(usage()), t);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		usage();
 | 
							usage();
 | 
				
			||||||
	} ARGEND;
 | 
						} ARGEND;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (argc < 1)
 | 
						if (argc < 1)
 | 
				
			||||||
		usage();
 | 
							usage();
 | 
				
			||||||
 | 
						if (!aflag && !mflag)
 | 
				
			||||||
 | 
							aflag = mflag = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (; argc > 0; argc--, argv++)
 | 
						for (; argc > 0; argc--, argv++)
 | 
				
			||||||
		touch(argv[0]);
 | 
							touch(argv[0]);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user