aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDavid M. Syzdek <syzdek@bindlebinaries.com>2019-07-09 20:19:23 -0800
committerDavid M. Syzdek <syzdek@bindlebinaries.com>2019-07-09 20:19:23 -0800
commit394a0d3e396ad040ff58c8677cd72ec43a045025 (patch)
treedf32f60ab152c52e3654c305d81edd678a4c7c6a
parentcdea9c13bac836ae8cad6bfdcf0ab88f18fdec30 (diff)
downloadsecurecoreutils-394a0d3e396ad040ff58c8677cd72ec43a045025.tar.gz
securecoreutils-394a0d3e396ad040ff58c8677cd72ec43a045025.tar.bz2
securecoreutils-394a0d3e396ad040ff58c8677cd72ec43a045025.tar.xz
securecoreutils-394a0d3e396ad040ff58c8677cd72ec43a045025.zip
Adding touch widget
-rw-r--r--Makefile.am3
-rw-r--r--src/securecoreutils.c7
-rw-r--r--src/widget-touch.c390
-rw-r--r--src/widget-touch.h66
4 files changed, 466 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am
index 92f4a98..8cbd60c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -110,6 +110,8 @@ src_securecoreutils_SOURCES = $(include_HEADERS) \
110 src/widget-rmdir.h \ 110 src/widget-rmdir.h \
111 src/widget-tail.c \ 111 src/widget-tail.c \
112 src/widget-tail.h \ 112 src/widget-tail.h \
113 src/widget-touch.c \
114 src/widget-touch.h \
113 src/widget-zcat.c \ 115 src/widget-zcat.c \
114 src/widget-zcat.h \ 116 src/widget-zcat.h \
115 src/lzw/headers.h \ 117 src/lzw/headers.h \
@@ -136,6 +138,7 @@ install-widget-symlinks:
136 ( cd $(DESTDIR)$(bindir); ln -sf securecoreutils $(SCU_PREFIX)rm; ) 138 ( cd $(DESTDIR)$(bindir); ln -sf securecoreutils $(SCU_PREFIX)rm; )
137 ( cd $(DESTDIR)$(bindir); ln -sf securecoreutils $(SCU_PREFIX)rmdir; ) 139 ( cd $(DESTDIR)$(bindir); ln -sf securecoreutils $(SCU_PREFIX)rmdir; )
138 ( cd $(DESTDIR)$(bindir); ln -sf securecoreutils $(SCU_PREFIX)tail; ) 140 ( cd $(DESTDIR)$(bindir); ln -sf securecoreutils $(SCU_PREFIX)tail; )
141 ( cd $(DESTDIR)$(bindir); ln -sf securecoreutils $(SCU_PREFIX)touch; )
139 ( cd $(DESTDIR)$(bindir); ln -sf securecoreutils $(SCU_PREFIX)zcat; ) 142 ( cd $(DESTDIR)$(bindir); ln -sf securecoreutils $(SCU_PREFIX)zcat; )
140 ( cd $(DESTDIR)$(bindir); ln -sf securecoreutils $(SCU_PREFIX)bzcat; ) 143 ( cd $(DESTDIR)$(bindir); ln -sf securecoreutils $(SCU_PREFIX)bzcat; )
141 ( cd $(DESTDIR)$(bindir); ln -sf securecoreutils $(SCU_PREFIX)gzcat; ) 144 ( cd $(DESTDIR)$(bindir); ln -sf securecoreutils $(SCU_PREFIX)gzcat; )
diff --git a/src/securecoreutils.c b/src/securecoreutils.c
index 233694e..015146d 100644
--- a/src/securecoreutils.c
+++ b/src/securecoreutils.c
@@ -60,6 +60,7 @@
60#include "widget-rm.h" 60#include "widget-rm.h"
61#include "widget-rmdir.h" 61#include "widget-rmdir.h"
62#include "widget-tail.h" 62#include "widget-tail.h"
63#include "widget-touch.h"
63#include "widget-zcat.h" 64#include "widget-zcat.h"
64 65
65 66
@@ -146,6 +147,12 @@ const scu_widget scu_widget_map[] =
146 scu_widget_tail, // widget function 147 scu_widget_tail, // widget function
147 }, 148 },
148 { 149 {
150 "touch", // widget name
151 "Updates access and modify timestamps of file.", // widget description
152 (const char * const[]) { _PREFIX"touch", NULL }, // widget alias
153 scu_widget_touch, // widget function
154 },
155 {
149 "version", // widget name 156 "version", // widget name
150 NULL, // widget description 157 NULL, // widget description
151 NULL, // widget alias 158 NULL, // widget alias
diff --git a/src/widget-touch.c b/src/widget-touch.c
new file mode 100644
index 0000000..4c1fa29
--- /dev/null
+++ b/src/widget-touch.c
@@ -0,0 +1,390 @@
1/*
2 * Secure Core Utilities
3 * Copyright (C) 2015, 2017 David M. Syzdek <david@syzdek.net>.
4 *
5 * @SYZDEK_BSD_LICENSE_START@
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * * Neither the name of David M. Syzdek nor the
17 * names of its contributors may be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID M SYZDEK BE LIABLE FOR
24 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * @SYZDEK_BSD_LICENSE_END@
33 */
34#include "widget-touch.h"
35
36///////////////
37// //
38// Headers //
39// //
40///////////////
41#ifdef __SECURECOREUTILS_PMARK
42#pragma mark - Headers
43#endif
44
45#include <assert.h>
46#include <errno.h>
47#include <stdio.h>
48#include <string.h>
49#include <strings.h>
50#include <sys/types.h>
51#include <sys/stat.h>
52#include <sys/time.h>
53#include <unistd.h>
54#include <fcntl.h>
55#include <time.h>
56
57
58//////////////////
59// //
60// Prototypes //
61// //
62//////////////////
63#ifdef __SECURECOREUTILS_PMARK
64#pragma mark - Prototypes
65#endif
66
67void scu_widget_touch_usage(scu_config * cnf);
68time_t scu_widget_touch_strtime(char *restrict s, time_t t);
69
70
71/////////////////
72// //
73// Functions //
74// //
75/////////////////
76#ifdef __SECURECOREUTILS_PMARK
77#pragma mark - Functions
78#endif
79
80int scu_widget_touch(scu_config * cnf)
81{
82 int c;
83 int opt_index;
84 int rc;
85 int fd;
86 int opts;
87 int oflags;
88 int sflags;
89 time_t t;
90 char * reffile;
91 struct stat sb;
92 struct stat refsb;
93 struct timeval curtime[2];
94 struct timeval settime[2];
95
96 // getopt options
97 static char short_opt[] = "+cfhqr:t:Vv";
98 static struct option long_opt[] =
99 {
100 {"no-create", no_argument, NULL, 'c' },
101 {"help", no_argument, NULL, 'h' },
102 {"quiet", no_argument, NULL, 'q' },
103 {"reference", no_argument, NULL, 'r' },
104 {"silent", no_argument, NULL, 'q' },
105 {"version", no_argument, NULL, 'V' },
106 {"verbose", no_argument, NULL, 'v' },
107 { NULL, 0, NULL, 0 }
108 };
109
110 assert(cnf != NULL);
111 cnf->short_opt = short_opt;
112
113 opts = -1;
114 oflags = O_CREAT;
115 sflags = SCU_ONOTEXISTS;
116 reffile = NULL;
117 t = time(NULL);
118 curtime[0].tv_sec = curtime[1].tv_sec = t;
119 curtime[0].tv_usec = curtime[1].tv_usec = 0;
120 settime[0].tv_sec = settime[1].tv_sec = t;
121 settime[0].tv_usec = settime[1].tv_usec = 0;
122
123 while((c = getopt_long(cnf->argc, cnf->argv, short_opt, long_opt, &opt_index)) != -1)
124 {
125 switch(c)
126 {
127 case -1: /* no more arguments */
128 case 0: /* long options toggles */
129 break;
130
131 case 'a':
132 if (opts != 2)
133 {
134 fprintf(stderr, "%s: %s: incompatible options\n", PROGRAM_NAME, cnf->widget->name);
135 fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME);
136 return(1);
137 };
138 opts = 0;
139 break;
140
141 case 'c':
142 oflags ^= O_CREAT;
143 break;
144
145 case 'f':
146 break;
147
148 case 'h':
149 scu_widget_touch_usage(cnf);
150 return(0);
151
152 case 'm':
153 if (opts != 2)
154 {
155 fprintf(stderr, "%s: %s: incompatible options\n", PROGRAM_NAME, cnf->widget->name);
156 fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME);
157 return(1);
158 };
159 opts = 1;
160 break;
161
162 case 'r':
163 if (settime[0].tv_sec != t)
164 {
165 fprintf(stderr, "%s: %s: incompatible options\n", PROGRAM_NAME, cnf->widget->name);
166 fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME);
167 return(1);
168 };
169 reffile = optarg;
170 break;
171
172 case 's':
173 cnf->quiet = 1;
174 if ((cnf->verbose))
175 {
176 fprintf(stderr, "%s: %s: incompatible options\n", PROGRAM_NAME, cnf->widget->name);
177 fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME);
178 return(1);
179 };
180 break;
181
182 case 't':
183 if ((reffile))
184 {
185 fprintf(stderr, "%s: %s: incompatible options\n", PROGRAM_NAME, cnf->widget->name);
186 fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME);
187 return(1);
188 };
189 if ((settime[1].tv_sec = scu_widget_touch_strtime(optarg, t)) == 0)
190 {
191 fprintf(stderr, "%s: %s: invalid time specification\n", PROGRAM_NAME, cnf->widget->name);
192 fprintf(stderr, "Try `%s %s --help' for more information.\n", PROGRAM_NAME, cnf->widget->name);
193 return(1);
194 };
195 settime[0].tv_sec = settime[1].tv_sec;
196 break;
197
198 case 'V':
199 printf("%s widget\n", cnf->widget->name);
200 scu_version();
201 return(0);
202
203 case 'v':
204 cnf->verbose++;
205 if ((cnf->quiet))
206 {
207 fprintf(stderr, "%s: %s: incompatible options\n", PROGRAM_NAME, cnf->widget->name);
208 fprintf(stderr, "Try `%s %s --help' for more information.\n", PROGRAM_NAME, cnf->widget->name);
209 return(1);
210 };
211 break;
212
213 case '?':
214 fprintf(stderr, "Try `%s %s --help' for more information.\n", PROGRAM_NAME, cnf->widget->name);
215 return(1);
216
217 default:
218 fprintf(stderr, "%s: %s: unrecognized option `--%c'\n", PROGRAM_NAME, cnf->widget->name, c);
219 fprintf(stderr, "Try `%s %s --help' for more information.\n", PROGRAM_NAME, cnf->widget->name);
220 return(1);
221 };
222 };
223
224 if ((cnf->argc - optind) < 1)
225 {
226 fprintf(stderr, "%s: %s: missing required argument\n", PROGRAM_NAME, cnf->widget->name);
227 fprintf(stderr, "Try `%s %s --help' for more information.\n", PROGRAM_NAME, cnf->widget->name);
228 return(1);
229 };
230 if ((cnf->argc - optind) > 1)
231 {
232 fprintf(stderr, "%s: unrecognized argument `-- %s'\n", PROGRAM_NAME, cnf->argv[optind+1]);
233 fprintf(stderr, "Try `%s %s --help' for more information.\n", PROGRAM_NAME, cnf->widget->name);
234 return(1);
235 };
236
237
238 // checks file for restriction validations
239 if ((rc = scu_pathcheck(cnf->argv[optind], sflags)) != 0)
240 {
241 fprintf(stderr, "%s: %s: %s\n", PROGRAM_NAME, cnf->widget->name, scu_strerror(rc));
242 return(1);
243 };
244
245
246 // obtains current atime/time or creates file if needed
247 if ((rc = stat(cnf->argv[optind], &sb)) != -1)
248 {
249 curtime[0].tv_sec = sb.st_atime;
250 curtime[1].tv_sec = sb.st_mtime;
251 }
252 else if ((oflags & O_CREAT) == O_CREAT)
253 {
254 if ((fd = open(cnf->argv[optind], oflags)) == -1)
255 {
256 fprintf(stderr, "%s: %s: %s\n", PROGRAM_NAME, cnf->widget->name, strerror(errno));
257 return(1);
258 };
259 close(fd);
260 }
261 else
262 return(0);
263
264
265 // obtains time stamp from reference file
266 if (reffile != NULL)
267 {
268 if ((rc = scu_pathcheck(reffile, 0)) != 0)
269 {
270 fprintf(stderr, "%s: %s: reference file: %s\n", PROGRAM_NAME, cnf->widget->name, scu_strerror(rc));
271 return(1);
272 };
273 if ((rc = stat(reffile, &refsb)) == -1)
274 {
275 fprintf(stderr, "%s: %s: reference file: %s\n", PROGRAM_NAME, cnf->widget->name, strerror(errno));
276 return(1);
277 };
278 settime[0].tv_sec = refsb.st_atime;
279 settime[1].tv_sec = refsb.st_mtime;
280 };
281
282
283 // determines whether to update atime, mtime, or both
284 if ( (opts == 0) || (opts == -1) )
285 {
286 curtime[0].tv_sec = settime[0].tv_sec;
287 };
288 if ( (opts == 1) || (opts == -1) )
289 {
290 curtime[1].tv_sec = settime[1].tv_sec;
291 };
292
293
294 // updates time stamps
295 if ((rc = utimes(cnf->argv[optind], curtime)) == -1)
296 {
297 fprintf(stderr, "%s: %s: %s\n", PROGRAM_NAME, cnf->widget->name, strerror(errno));
298 return(1);
299 };
300
301 return(0);
302}
303
304
305time_t scu_widget_touch_strtime(char *restrict s, time_t t)
306{
307
308 size_t len;
309 char * ptr;
310 struct tm tm_time;
311
312 ptr = NULL;
313 len = strlen(s);
314
315 localtime_r(&t, &tm_time);
316
317 // CCYYMMDDhhmm.SS
318 if (len == 15)
319 {
320 if ((ptr = strptime(s, "%Y%m%d%H%M.%S\0", &tm_time)) != NULL)
321 t = mktime(&tm_time);
322 };
323
324 // YYMMDDhhmm.SS
325 if (len == 13)
326 {
327 localtime_r(&t, &tm_time);
328 if ((ptr = strptime(s, "%y%m%d%H%M.%S\0", &tm_time)) != NULL)
329 t = mktime(&tm_time);
330 };
331
332 // MMDDhhmm.SS
333 if (len == 11)
334 {
335 localtime_r(&t, &tm_time);
336 if ((ptr = strptime(s, "%m%d%H%M.%S\0", &tm_time)) != NULL)
337 t = mktime(&tm_time);
338 };
339
340 // CCYYMMDDhhmm
341 if (len == 12)
342 {
343 localtime_r(&t, &tm_time);
344 if ((ptr = strptime(s, "%Y%m%d%H%M\0", &tm_time)) != NULL)
345 t = mktime(&tm_time);
346 };
347
348 // YYMMDDhhmm
349 if (len == 10)
350 {
351 localtime_r(&t, &tm_time);
352 if ((ptr = strptime(s, "%y%m%d%H%M\0", &tm_time)) != NULL)
353 t = mktime(&tm_time);
354 };
355
356 // MMDDhhmm
357 if (len == 8)
358 {
359 localtime_r(&t, &tm_time);
360 if ((ptr = strptime(s, "%m%d%H%M\0", &tm_time)) != NULL)
361 t = mktime(&tm_time);
362 };
363
364 // return invalid if string contains more than a date
365 if ( (ptr == NULL) || (ptr[0] != '\0') )
366 return(0);
367
368 return(t);
369}
370
371
372void scu_widget_touch_usage(scu_config * cnf)
373{
374 scu_usage_summary(cnf, " [OPTIONS] file");
375 printf("\n");
376 scu_usage_options(cnf);
377 printf(" -a change only access time\n");
378 printf(" -c, --no-create do not create files\n");
379 printf(" -f ignored (for compatibility with GNU coreutils)\n");
380 printf(" -m change only modification time\n");
381 printf(" -r, --reference=FILE use file's timestamp instead of current time\n");
382 printf(" -t STAMP use time STAMP with format of [[CC]YY]MMDDhhmm[.ss]\n");
383 printf("\n");
384 scu_usage_restrictions();
385 printf("\n");
386 return;
387}
388
389
390/* end of source */
diff --git a/src/widget-touch.h b/src/widget-touch.h
new file mode 100644
index 0000000..e410748
--- /dev/null
+++ b/src/widget-touch.h
@@ -0,0 +1,66 @@
1/*
2 * Secure Core Utilities
3 * Copyright (C) 2015, 2017 David M. Syzdek <david@syzdek.net>.
4 *
5 * @SYZDEK_BSD_LICENSE_START@
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * * Neither the name of David M. Syzdek nor the
17 * names of its contributors may be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID M SYZDEK BE LIABLE FOR
24 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * @SYZDEK_BSD_LICENSE_END@
33 */
34/**
35 * @file securecoreutils.c
36 * Secure Core Utils widget wrapper
37 */
38#ifndef __SRC_WIDGET_TOUCH_H
39#define __SRC_WIDGET_TOUCH_H 1
40
41
42///////////////
43// //
44// Headers //
45// //
46///////////////
47#ifdef __SECURECOREUTILS_PMARK
48#pragma mark - Headers
49#endif
50
51#include "securecoreutils.h"
52
53
54//////////////////
55// //
56// Prototypes //
57// //
58//////////////////
59#ifdef __SECURECOREUTILS_PMARK
60#pragma mark - Prototypes
61#endif
62
63int scu_widget_touch(scu_config * cnf);
64
65
66#endif /* end of header */