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