1795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall#include <stdio.h>
2795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall#include <string.h>
3795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall#include <sys/types.h>
4795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall#include <fcntl.h>
5795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall#include <sys/stat.h>
6795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall#include <stdlib.h>
7795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall#include <fcntl.h>
8795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall
9795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrallstatic void usage(void)
10795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall{
11795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall        fprintf(stderr, "touch: usage: touch [-alm] [-t time_t] <file>\n");
12795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall        exit(1);
13795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall}
14795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall
15795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrallint touch_main(int argc, char *argv[])
16795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall{
17795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall        int i, fd, aflag = 0, mflag = 0, debug = 0, flags = 0;
18795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall        struct timespec specified_time, times[2];
19795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall        char *file = 0;
20795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall
21795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall        specified_time.tv_nsec = UTIME_NOW;
22795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall
23795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall        for (i = 1; i < argc; i++) {
24795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall            if (argv[i][0] == '-') {
25795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                /* an option */
26795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                const char *arg = argv[i]+1;
27795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                while (arg[0]) {
28795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                    switch (arg[0]) {
29795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                    case 'a': aflag = 1; break;
30795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                    case 'm': mflag = 1; break;
31795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                    case 't':
32795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                        if ((i+1) >= argc)
33795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                            usage();
34795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                        specified_time.tv_sec = atol(argv[++i]);
35795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                        if (specified_time.tv_sec == 0) {
36795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                            fprintf(stderr, "touch: invalid time_t\n");
37795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                            exit(1);
38795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                        }
39795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                        specified_time.tv_nsec = 0;
40795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                        break;
41795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                    case 'l': flags |= AT_SYMLINK_NOFOLLOW; break;
42795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                    case 'd': debug = 1; break;
43795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                    default:
44795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                        usage();
45795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                    }
46795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                    arg++;
47795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                }
48795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall            } else {
49795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                /* not an option, and only accept one filename */
50795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                if (i+1 != argc)
51795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                    usage();
52795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                file = argv[i];
53795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall            }
54795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall        }
55795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall
56795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall        if (! file) {
57795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall            fprintf(stderr, "touch: no file specified\n");
58795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall            exit(1);
59795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall        }
60795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall
61795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall        if (access(file, F_OK))
62795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall            if ((fd=creat(file, 0666)) != -1)
63795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall                close(fd);
64795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall
65795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall        if ((mflag == 0) && (aflag == 0))
66795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall            aflag = mflag = 1;
67795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall
68795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall        if (aflag)
69795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall            times[0] = specified_time;
70795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall        else
71795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall            times[0].tv_nsec = UTIME_OMIT;
72795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall
73795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall        if (mflag)
74795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall            times[1] = specified_time;
75795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall        else
76795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall            times[1].tv_nsec = UTIME_OMIT;
77795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall
78795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall        if (debug) {
79795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall            fprintf(stderr, "file = %s\n", file);
80795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall            fprintf(stderr, "times[0].tv_sec = %ld, times[0].tv_nsec = %ld\n", times[0].tv_sec, times[0].tv_nsec);
81795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall            fprintf(stderr, "times[1].tv_sec = %ld, times[1].tv_nsec = %ld\n", times[1].tv_sec, times[1].tv_nsec);
82795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall            fprintf(stderr, "flags = 0x%8.8x\n", flags);
83795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall        }
84795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall
85795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall        return utimensat(AT_FDCWD, file, times, flags);
86795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall}
87795165bc1512faa121083c6bf3ce6f6d83ce59e6Ken Sumrall
88