1 #include <stdio.h> 2 #include <string.h> 3 #include <sys/types.h> 4 #include <fcntl.h> 5 #include <sys/stat.h> 6 #include <stdlib.h> 7 #include <fcntl.h> 8 #include <time.h> 9 10 static void usage(void) 11 { 12 fprintf(stderr, "touch: usage: touch [-alm] [-t YYYYMMDD[.hhmmss]] <file>\n"); 13 exit(1); 14 } 15 16 static time_t parse_time(char *s) 17 { 18 struct tm tm; 19 int day = atoi(s); 20 int hour = 0; 21 22 while (*s && *s != '.') { 23 s++; 24 } 25 26 if (*s) { 27 s++; 28 hour = atoi(s); 29 } 30 31 tm.tm_year = day / 10000 - 1900; 32 tm.tm_mon = (day % 10000) / 100 - 1; 33 tm.tm_mday = day % 100; 34 tm.tm_hour = hour / 10000; 35 tm.tm_min = (hour % 10000) / 100; 36 tm.tm_sec = hour % 100; 37 tm.tm_isdst = -1; 38 39 return mktime(&tm); 40 } 41 42 int touch_main(int argc, char *argv[]) 43 { 44 int i, fd, aflag = 0, mflag = 0, debug = 0, flags = 0; 45 struct timespec specified_time, times[2]; 46 char *file = 0; 47 48 specified_time.tv_nsec = UTIME_NOW; 49 50 for (i = 1; i < argc; i++) { 51 if (argv[i][0] == '-') { 52 /* an option */ 53 const char *arg = argv[i]+1; 54 while (arg[0]) { 55 switch (arg[0]) { 56 case 'a': aflag = 1; break; 57 case 'm': mflag = 1; break; 58 case 't': 59 if ((i+1) >= argc) 60 usage(); 61 specified_time.tv_sec = parse_time(argv[++i]); 62 if (specified_time.tv_sec == -1) { 63 fprintf(stderr, "touch: invalid timestamp specified\n"); 64 exit(1); 65 } 66 specified_time.tv_nsec = 0; 67 break; 68 case 'l': flags |= AT_SYMLINK_NOFOLLOW; break; 69 case 'd': debug = 1; break; 70 default: 71 usage(); 72 } 73 arg++; 74 } 75 } else { 76 /* not an option, and only accept one filename */ 77 if (i+1 != argc) 78 usage(); 79 file = argv[i]; 80 } 81 } 82 83 if (! file) { 84 fprintf(stderr, "touch: no file specified\n"); 85 exit(1); 86 } 87 88 if (access(file, F_OK)) 89 if ((fd=creat(file, 0666)) != -1) 90 close(fd); 91 92 if ((mflag == 0) && (aflag == 0)) 93 aflag = mflag = 1; 94 95 if (aflag) 96 times[0] = specified_time; 97 else 98 times[0].tv_nsec = UTIME_OMIT; 99 100 if (mflag) 101 times[1] = specified_time; 102 else 103 times[1].tv_nsec = UTIME_OMIT; 104 105 if (debug) { 106 fprintf(stderr, "file = %s\n", file); 107 fprintf(stderr, "times[0].tv_sec = %ld, times[0].tv_nsec = %ld\n", times[0].tv_sec, times[0].tv_nsec); 108 fprintf(stderr, "times[1].tv_sec = %ld, times[1].tv_nsec = %ld\n", times[1].tv_sec, times[1].tv_nsec); 109 fprintf(stderr, "flags = 0x%8.8x\n", flags); 110 } 111 112 return utimensat(AT_FDCWD, file, times, flags); 113 } 114 115