xref: /original-bsd/usr.bin/touch/touch.c (revision 3f73ce2f)
1 /*
2  * Copyright (c) 1988 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 char copyright[] =
10 "@(#) Copyright (c) 1988 Regents of the University of California.\n\
11  All rights reserved.\n";
12 #endif /* not lint */
13 
14 #ifndef lint
15 static char sccsid[] = "@(#)touch.c	4.8 (Berkeley) 06/01/90";
16 #endif /* not lint */
17 
18 /*
19  * Attempt to set the modify date of a file to the current date.  If the
20  * file exists, read and write its first character.  If the file doesn't
21  * exist, create it, unless -c option prevents it.  If the file is read-only,
22  * -f forces chmod'ing and touch'ing.
23  */
24 #include <sys/types.h>
25 #include <sys/file.h>
26 #include <sys/stat.h>
27 #include <stdio.h>
28 
29 static int	dontcreate;	/* set if -c option */
30 static int	force;		/* set if -f option */
31 
32 main(argc, argv)
33 	int argc;
34 	char **argv;
35 {
36 	extern int optind;
37 	int ch, retval;
38 
39 	dontcreate = force = retval = 0;
40 	while ((ch = getopt(argc, argv, "cf")) != EOF)
41 		switch((char)ch) {
42 		case 'c':
43 			dontcreate = 1;
44 			break;
45 		case 'f':
46 			force = 1;
47 			break;
48 		case '?':
49 		default:
50 			usage();
51 		}
52 	if (!*(argv += optind))
53 		usage();
54 	do {
55 		retval |= touch(*argv);
56 	} while (*++argv);
57 	exit(retval);
58 }
59 
60 touch(filename)
61 	char *filename;
62 {
63 	struct stat statbuffer;
64 
65 	if (stat(filename, &statbuffer) == -1) {
66 		if (!dontcreate)
67 			return(readwrite(filename, 0L));
68 		fprintf(stderr, "touch: %s: does not exist\n", filename);
69 		return(1);
70 	}
71 	if ((statbuffer.st_mode & S_IFMT) != S_IFREG) {
72 		fprintf(stderr, "touch: %s: can only touch regular files\n",
73 		    filename);
74 		return(1);
75 	}
76 	if (!access(filename, R_OK | W_OK))
77 		return(readwrite(filename,statbuffer.st_size));
78 	if (force) {
79 		int retval;
80 
81 		if (chmod(filename, 0666)) {
82 			fprintf(stderr, "touch: %s: couldn't chmod: ",
83 			    filename);
84 			perror((char *)NULL);
85 			return(1);
86 		}
87 		retval = readwrite(filename, statbuffer.st_size);
88 		if (chmod(filename, statbuffer.st_mode)) {
89 			fprintf(stderr, "touch: %s: couldn't chmod back: ",
90 			    filename);
91 			perror((char *)NULL);
92 			return(1);
93 		}
94 		return(retval);
95 	}
96 	fprintf(stderr, "touch: %s: cannot touch\n", filename);
97 	return(1);
98 }
99 
100 readwrite(filename, size)
101 	char *filename;
102 	off_t size;
103 {
104 	int filedescriptor;
105 	char first;
106 	off_t lseek();
107 
108 	if (size) {
109 		filedescriptor = open(filename, O_RDWR, 0);
110 		if (filedescriptor == -1) {
111 error:			fprintf(stderr, "touch: %s: ", filename);
112 			perror((char *)NULL);
113 			return(1);
114 		}
115 		if (read(filedescriptor, &first, 1) != 1)
116 			goto error;
117 		if (lseek(filedescriptor, 0L, 0) == -1)
118 			goto error;
119 		if (write(filedescriptor, &first, 1) != 1)
120 			goto error;
121 	} else {
122 		filedescriptor = creat(filename, 0666);
123 		if (filedescriptor == -1)
124 			goto error;
125 	}
126 	if (close(filedescriptor) == -1)
127 		goto error;
128 	return(0);
129 }
130 
131 usage()
132 {
133 	fprintf(stderr, "usage: touch [-cf] file ...\n");
134 	exit(1);
135 }
136