xref: /original-bsd/usr.bin/touch/touch.c (revision 81f57ac7)
1 /*
2  * Copyright (c) 1988 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 char copyright[] =
20 "@(#) Copyright (c) 1988 Regents of the University of California.\n\
21  All rights reserved.\n";
22 #endif /* not lint */
23 
24 #ifndef lint
25 static char sccsid[] = "@(#)touch.c	4.7 (Berkeley) 08/09/88";
26 #endif /* not lint */
27 
28 /*
29  * Attempt to set the modify date of a file to the current date.  If the
30  * file exists, read and write its first character.  If the file doesn't
31  * exist, create it, unless -c option prevents it.  If the file is read-only,
32  * -f forces chmod'ing and touch'ing.
33  */
34 #include <sys/types.h>
35 #include <sys/file.h>
36 #include <sys/stat.h>
37 #include <stdio.h>
38 
39 static int	dontcreate;	/* set if -c option */
40 static int	force;		/* set if -f option */
41 
42 main(argc, argv)
43 	int argc;
44 	char **argv;
45 {
46 	extern int optind;
47 	int ch, retval;
48 
49 	dontcreate = force = retval = 0;
50 	while ((ch = getopt(argc, argv, "cf")) != EOF)
51 		switch((char)ch) {
52 		case 'c':
53 			dontcreate = 1;
54 			break;
55 		case 'f':
56 			force = 1;
57 			break;
58 		case '?':
59 		default:
60 			usage();
61 		}
62 	if (!*(argv += optind))
63 		usage();
64 	do {
65 		retval |= touch(*argv);
66 	} while (*++argv);
67 	exit(retval);
68 }
69 
70 touch(filename)
71 	char *filename;
72 {
73 	struct stat statbuffer;
74 
75 	if (stat(filename, &statbuffer) == -1) {
76 		if (!dontcreate)
77 			return(readwrite(filename, 0L));
78 		fprintf(stderr, "touch: %s: does not exist\n", filename);
79 		return(1);
80 	}
81 	if ((statbuffer.st_mode & S_IFMT) != S_IFREG) {
82 		fprintf(stderr, "touch: %s: can only touch regular files\n",
83 		    filename);
84 		return(1);
85 	}
86 	if (!access(filename, R_OK | W_OK))
87 		return(readwrite(filename,statbuffer.st_size));
88 	if (force) {
89 		int retval;
90 
91 		if (chmod(filename, 0666)) {
92 			fprintf(stderr, "touch: %s: couldn't chmod: ",
93 			    filename);
94 			perror((char *)NULL);
95 			return(1);
96 		}
97 		retval = readwrite(filename, statbuffer.st_size);
98 		if (chmod(filename, statbuffer.st_mode)) {
99 			fprintf(stderr, "touch: %s: couldn't chmod back: ",
100 			    filename);
101 			perror((char *)NULL);
102 			return(1);
103 		}
104 		return(retval);
105 	}
106 	fprintf(stderr, "touch: %s: cannot touch\n", filename);
107 	return(1);
108 }
109 
110 readwrite(filename, size)
111 	char *filename;
112 	off_t size;
113 {
114 	int filedescriptor;
115 	char first;
116 	off_t lseek();
117 
118 	if (size) {
119 		filedescriptor = open(filename, O_RDWR, 0);
120 		if (filedescriptor == -1) {
121 error:			fprintf(stderr, "touch: %s: ", filename);
122 			perror((char *)NULL);
123 			return(1);
124 		}
125 		if (read(filedescriptor, &first, 1) != 1)
126 			goto error;
127 		if (lseek(filedescriptor, 0L, 0) == -1)
128 			goto error;
129 		if (write(filedescriptor, &first, 1) != 1)
130 			goto error;
131 	} else {
132 		filedescriptor = creat(filename, 0666);
133 		if (filedescriptor == -1)
134 			goto error;
135 	}
136 	if (close(filedescriptor) == -1)
137 		goto error;
138 	return(0);
139 }
140 
141 usage()
142 {
143 	fprintf(stderr, "usage: touch [-cf] file ...\n");
144 	exit(1);
145 }
146