1 /* Touch - change file access and modification times.
3 * Usage: see end of file
5 * Conforms to P1003.2 draft 10, sec. 4.62, except that time values
6 * are not checked for validity, but passed on to mktime, so that
7 * 9301990000 will refer to Apr. 9th 1993. As a side effect, leap
8 * seconds are not handled correctly.
10 * Authors: Original author unknown. Rewritten for POSIX by
11 * Peter Holzer (hp@vmars.tuwien.ac.at).
15 * Revision 1.1 2005/04/21 14:55:35 beng
18 * Revision 1.1.1.1 2005/04/20 13:33:47 beng
19 * Initial import of minix 2.0.4
21 * Revision 1.8 1994/03/17 21:39:19 hjp
22 * fixed bug with 4-digit years
24 * Revision 1.7 1994/03/15 00:43:27 hjp
25 * Changes from kjb (vmd 1.6.25.1):
27 * nonstandard flag 0 to make file very old
29 * Revision 1.6 1994/02/12 17:26:33 hjp
30 * fixed -a and -m flags
32 * Revision 1.5 1994/02/12 16:04:13 hjp
33 * fixed bug when -t argument was not given
34 * removed debugging code
35 * run through pretty to get Minix layout
37 * Revision 1.4 1994/02/07 21:23:11 hjp
42 #define _POSIX_C_SOURCE 2 /* getopt */
45 #include <sys/types.h>
56 #define val2(string) ((string)[0] * 10 + (string)[1] - '0' * 11)
57 #define val4(string) (val2(string) * 100 + val2(string + 2))
65 unsigned int to_change
= 0;
69 _PROTOTYPE(int main
, (int argc
, char **argv
));
70 _PROTOTYPE(int doit
, (char *name
, struct utimbuf tvp
));
71 _PROTOTYPE(void usage
, (void));
72 _PROTOTYPE(time_t parsetime
, (const char *string
, formatT format
));
74 time_t parsetime(string
, format
)
82 l
= strspn(string
, "0123456789");
83 if (l
% 2 == 1) return -1;
84 if (string
[l
] != '\0' && (string
[l
] != '.' || format
== OLD
)) {
89 /* Last two digits are year */
90 tm
.tm_year
= val2(string
+ 8);
91 if (tm
.tm_year
<= 68) tm
.tm_year
+= 100;
94 tm
= *localtime(&touchtime
);
100 /* First four digits are year */
101 tm
.tm_year
= val4(string
) - 1900;
103 } else if (l
== 10) {
104 /* First two digits are year */
105 tm
.tm_year
= val2(string
);
106 if (tm
.tm_year
<= 68) tm
.tm_year
+= 100;
110 tm
= *localtime(&touchtime
);
115 tm
.tm_mon
= val2(string
) - 1;
117 tm
.tm_mday
= val2(string
);
119 tm
.tm_hour
= val2(string
);
121 tm
.tm_min
= val2(string
);
123 if (format
== NEW
&& string
[0] == '.') {
124 if (isdigit(string
[1]) && isdigit(string
[2]) &&
126 tm
.tm_sec
= val2(string
+ 1);
134 touchtime
= mktime(&tm
);
146 struct utimbuf touchtimes
;
150 auxtime
= time((time_t *) NULL
);
151 touchtimes
.modtime
= auxtime
;
152 touchtimes
.actime
= auxtime
;
154 while ((c
= getopt(argc
, argv
, "r:t:acm0")) != EOF
) {
157 if (stat(optarg
, &sb
) == -1) {
158 fprintf(stderr
, "%s: cannot stat %s: %s\n",
159 cmnd
, optarg
, strerror(errno
));
162 touchtimes
.modtime
= sb
.st_mtime
;
163 touchtimes
.actime
= sb
.st_atime
;
166 auxtime
= parsetime(optarg
, NEW
);
167 if (auxtime
== (time_t) - 1) usage();
168 touchtimes
.modtime
= auxtime
;
169 touchtimes
.actime
= auxtime
;
171 case 'a': to_change
|= ATIME
; break;
172 case 'm': to_change
|= MTIME
; break;
173 case 'c': no_creat
= 1; break;
175 touchtimes
.modtime
= touchtimes
.actime
= 0;
177 case '?': usage(); break;
181 if (to_change
== 0) {
182 to_change
= ATIME
| MTIME
;
184 if (optind
== argc
) usage();
186 /* Now check for old style time argument */
187 if (strcmp(argv
[optind
- 1], "--") != 0 &&
188 (auxtime
= parsetime(argv
[optind
], OLD
)) != (time_t) - 1) {
189 touchtimes
.modtime
= auxtime
;
190 touchtimes
.actime
= auxtime
;
192 if (optind
== argc
) usage();
194 while (optind
< argc
) {
195 if (doit(argv
[optind
], touchtimes
) > 0) {
196 fprintf(stderr
, "%s: cannot touch %s: %s\n",
197 cmnd
, argv
[optind
], strerror(errno
));
213 if (to_change
!= (ATIME
| MTIME
)) {
215 if (stat(name
, &sb
) != -1) {
216 if (!(to_change
& ATIME
)) {
217 tvp
.actime
= sb
.st_atime
;
219 tvp
.modtime
= sb
.st_mtime
;
223 if (utime(name
, &tvp
) == 0) return 0;
224 if (errno
!= ENOENT
) return 1;
225 if (no_creat
== 1) return 0;
226 if ((fd
= creat(name
, 0666)) >= 0) {
227 if (fstat(fd
, &sb
) != -1) {
228 if (!(to_change
& ATIME
)) {
229 tvp
.actime
= sb
.st_atime
;
231 tvp
.modtime
= sb
.st_mtime
;
237 if (utime(name
, &tvp
) == 0) return 0;
245 fprintf(stderr
, "Usage: %s [-c] [-a] [-m] [-r file] [-t [CC[YY]]MMDDhhmm[.ss]] "
246 "[MMDDhhmm[YY]] file...\n", cmnd
);