Introduction
Introduction Statistics Contact Development Disclaimer Help
touch.c - sbase - suckless unix tools
git clone git://git.suckless.org/sbase
Log
Files
Refs
README
LICENSE
---
touch.c (2796B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include <sys/stat.h>
3
4 #include <errno.h>
5 #include <fcntl.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <time.h>
9 #include <unistd.h>
10
11 #include "util.h"
12
13 static int aflag;
14 static int cflag;
15 static int mflag;
16 static struct timespec times[2] = {{.tv_nsec = UTIME_NOW}};
17
18 static void
19 touch(const char *file)
20 {
21 int fd, ret;
22
23 if (utimensat(AT_FDCWD, file, times, 0) == 0)
24 return;
25 if (errno != ENOENT)
26 eprintf("utimensat %s:", file);
27 if (cflag)
28 return;
29 if ((fd = open(file, O_WRONLY | O_CREAT | O_EXCL, 0666)) < 0)
30 eprintf("open %s:", file);
31 ret = futimens(fd, times);
32 close(fd);
33 if (ret < 0)
34 eprintf("futimens %s:", file);
35 }
36
37 static time_t
38 parsetime(char *str)
39 {
40 time_t now;
41 struct tm *cur, t = { 0 };
42 int zulu = 0;
43 char *format;
44 size_t len = strlen(str);
45
46 if ((now = time(NULL)) == -1)
47 eprintf("time:");
48 if (!(cur = localtime(&now)))
49 eprintf("localtime:");
50 t.tm_isdst = -1;
51
52 switch (len) {
53 /* -t flag argument */
54 case 8:
55 t.tm_year = cur->tm_year;
56 format = "%m%d%H%M";
57 break;
58 case 10:
59 format = "%y%m%d%H%M";
60 break;
61 case 11:
62 t.tm_year = cur->tm_year;
63 format = "%m%d%H%M.%S";
64 break;
65 case 12:
66 format = "%Y%m%d%H%M";
67 break;
68 case 13:
69 format = "%y%m%d%H%M.%S";
70 break;
71 case 15:
72 format = "%Y%m%d%H%M.%S";
73 break;
74 /* -d flag argument */
75 case 19:
76 format = "%Y-%m-%dT%H:%M:%S";
77 break;
78 case 20:
79 /* only Zulu-timezone supported */
80 if (str[19] != 'Z')
81 eprintf("Invalid time zone\n");
82 str[19] = 0;
83 zulu = 1;
84 format = "%Y-%m-%dT%H:%M:%S";
85 break;
86 default:
87 eprintf("Invalid date format length\n", str);
88 }
89
90 if (!strptime(str, format, &t))
91 eprintf("strptime %s: Invalid date format\n", str);
92 if (zulu) {
93 t.tm_hour += t.tm_gmtoff / 60;
94 t.tm_gmtoff = 0;
95 t.tm_zone = "Z";
96 }
97
98 return mktime(&t);
99 }
100
101 static void
102 usage(void)
103 {
104 eprintf("usage: %s [-acm] [-d time | -r ref_file | -t time | -T …
105 "file ...\n", argv0);
106 }
107
108 int
109 main(int argc, char *argv[])
110 {
111 struct stat st;
112 char *ref = NULL;
113
114 ARGBEGIN {
115 case 'a':
116 aflag = 1;
117 break;
118 case 'c':
119 cflag = 1;
120 break;
121 case 'd':
122 case 't':
123 times[0].tv_sec = parsetime(EARGF(usage()));
124 times[0].tv_nsec = 0;
125 break;
126 case 'm':
127 mflag = 1;
128 break;
129 case 'r':
130 ref = EARGF(usage());
131 if (stat(ref, &st) < 0)
132 eprintf("stat '%s':", ref);
133 times[0] = st.st_atim;
134 times[1] = st.st_mtim;
135 break;
136 case 'T':
137 times[0].tv_sec = estrtonum(EARGF(usage()), 0, LLONG_MAX…
138 times[0].tv_nsec = 0;
139 break;
140 default:
141 usage();
142 } ARGEND
143
144 if (!argc)
145 usage();
146 if (!aflag && !mflag)
147 aflag = mflag = 1;
148 if (!ref)
149 times[1] = times[0];
150 if (!aflag)
151 times[0].tv_nsec = UTIME_OMIT;
152 if (!mflag)
153 times[1].tv_nsec = UTIME_OMIT;
154
155 for (; *argv; argc--, argv++)
156 touch(*argv);
157
158 return 0;
159 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.