touch: Use special UTIME_NOW and UTIME_OMIT values
This allows users to touch files they have write access to, but aren't the
owner.
Also, remove utime.h include (not necessary since
4132561c17
), and make sure to check the return
value of localtime (potentially preventing a NULL pointer derefence).
This commit is contained in:
parent
36a0a6cd92
commit
2e5f1281ed
24
touch.c
24
touch.c
|
@ -7,14 +7,13 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <utime.h>
|
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
static int aflag;
|
static int aflag;
|
||||||
static int cflag;
|
static int cflag;
|
||||||
static int mflag;
|
static int mflag;
|
||||||
static struct timespec times[2];
|
static struct timespec times[2] = {{.tv_nsec = UTIME_NOW}};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
touch(const char *file)
|
touch(const char *file)
|
||||||
|
@ -28,10 +27,6 @@ touch(const char *file)
|
||||||
if (cflag)
|
if (cflag)
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
if (!aflag)
|
|
||||||
times[0] = st.st_atim;
|
|
||||||
if (!mflag)
|
|
||||||
times[1] = st.st_mtim;
|
|
||||||
if (utimensat(AT_FDCWD, file, times, 0) < 0)
|
if (utimensat(AT_FDCWD, file, times, 0) < 0)
|
||||||
eprintf("utimensat %s:", file);
|
eprintf("utimensat %s:", file);
|
||||||
return;
|
return;
|
||||||
|
@ -45,14 +40,18 @@ touch(const char *file)
|
||||||
}
|
}
|
||||||
|
|
||||||
static time_t
|
static time_t
|
||||||
parsetime(char *str, time_t current)
|
parsetime(char *str)
|
||||||
{
|
{
|
||||||
|
time_t now;
|
||||||
struct tm *cur, t = { 0 };
|
struct tm *cur, t = { 0 };
|
||||||
int zulu = 0;
|
int zulu = 0;
|
||||||
char *format;
|
char *format;
|
||||||
size_t len = strlen(str);
|
size_t len = strlen(str);
|
||||||
|
|
||||||
cur = localtime(¤t);
|
if ((now = time(NULL)) == -1)
|
||||||
|
eprintf("time:");
|
||||||
|
if (!(cur = localtime(&now)))
|
||||||
|
eprintf("localtime:");
|
||||||
t.tm_isdst = -1;
|
t.tm_isdst = -1;
|
||||||
|
|
||||||
switch (len) {
|
switch (len) {
|
||||||
|
@ -116,7 +115,6 @@ main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
char *ref = NULL;
|
char *ref = NULL;
|
||||||
clock_gettime(CLOCK_REALTIME, ×[0]);
|
|
||||||
|
|
||||||
ARGBEGIN {
|
ARGBEGIN {
|
||||||
case 'a':
|
case 'a':
|
||||||
|
@ -127,7 +125,8 @@ main(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
case 't':
|
case 't':
|
||||||
times[0].tv_sec = parsetime(EARGF(usage()), times[0].tv_sec);
|
times[0].tv_sec = parsetime(EARGF(usage()));
|
||||||
|
times[0].tv_nsec = 0;
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
mflag = 1;
|
mflag = 1;
|
||||||
|
@ -141,6 +140,7 @@ main(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
case 'T':
|
case 'T':
|
||||||
times[0].tv_sec = estrtonum(EARGF(usage()), 0, LLONG_MAX);
|
times[0].tv_sec = estrtonum(EARGF(usage()), 0, LLONG_MAX);
|
||||||
|
times[0].tv_nsec = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
|
@ -152,6 +152,10 @@ main(int argc, char *argv[])
|
||||||
aflag = mflag = 1;
|
aflag = mflag = 1;
|
||||||
if (!ref)
|
if (!ref)
|
||||||
times[1] = times[0];
|
times[1] = times[0];
|
||||||
|
if (!aflag)
|
||||||
|
times[0].tv_nsec = UTIME_OMIT;
|
||||||
|
if (!mflag)
|
||||||
|
times[1].tv_nsec = UTIME_OMIT;
|
||||||
|
|
||||||
for (; *argv; argc--, argv++)
|
for (; *argv; argc--, argv++)
|
||||||
touch(*argv);
|
touch(*argv);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user