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 5.1 (Berkeley) 10/02/92"; 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/stat.h> 26 27 #include <errno.h> 28 #include <fcntl.h> 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <string.h> 32 #include <unistd.h> 33 34 static int dontcreate; /* set if -c option */ 35 static int force; /* set if -f option */ 36 37 void err __P((const char *, ...)); 38 int readwrite __P((char *, off_t)); 39 int touch __P((char *)); 40 __dead void usage __P((void)); 41 42 int 43 main(argc, argv) 44 int argc; 45 char *argv[]; 46 { 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 int 71 touch(filename) 72 char *filename; 73 { 74 struct stat sb; 75 76 if (stat(filename, &sb) == -1) { 77 if (!dontcreate) 78 return (readwrite(filename, (off_t)0)); 79 err("%s: %s", filename, strerror(ENOENT)); 80 return (1); 81 } 82 if ((sb.st_mode & S_IFMT) != S_IFREG) { 83 err("%s: %s", filename, strerror(EFTYPE)); 84 return (1); 85 } 86 if (!access(filename, R_OK | W_OK)) 87 return (readwrite(filename, sb.st_size)); 88 if (force) { 89 int retval; 90 91 if (chmod(filename, DEFFILEMODE)) { 92 err("%s: add permissions: %s", 93 filename, strerror(errno)); 94 return (1); 95 } 96 retval = readwrite(filename, sb.st_size); 97 if (chmod(filename, sb.st_mode)) { 98 err("%s: restore permissions: %s", 99 filename, strerror(errno)); 100 return (1); 101 } 102 return (retval); 103 } 104 err("%s: cannot touch\n", filename); 105 return (1); 106 } 107 108 int 109 readwrite(filename, size) 110 char *filename; 111 off_t size; 112 { 113 int fd; 114 char first; 115 116 if (size) { 117 fd = open(filename, O_RDWR, 0); 118 if (fd == -1) 119 goto error; 120 if (read(fd, &first, 1) != 1) 121 goto error; 122 if (lseek(fd, (off_t)0, SEEK_SET) == -1) 123 goto error; 124 if (write(fd, &first, 1) != 1) 125 goto error; 126 } else { 127 fd = creat(filename, DEFFILEMODE); 128 if (fd == -1) 129 goto error; 130 } 131 if (close(fd) == -1) { 132 error: err("%s: %s", filename, strerror(errno)); 133 return (1); 134 } 135 return (0); 136 } 137 138 __dead void 139 usage() 140 { 141 fprintf(stderr, "usage: touch [-cf] file ...\n"); 142 exit(1); 143 } 144 145 #if __STDC__ 146 #include <stdarg.h> 147 #else 148 #include <varargs.h> 149 #endif 150 151 void 152 #if __STDC__ 153 err(const char *fmt, ...) 154 #else 155 err(fmt, va_alist) 156 char *fmt; 157 va_dcl 158 #endif 159 { 160 va_list ap; 161 #if __STDC__ 162 va_start(ap, fmt); 163 #else 164 va_start(ap); 165 #endif 166 (void)fprintf(stderr, "touch: "); 167 (void)vfprintf(stderr, fmt, ap); 168 va_end(ap); 169 (void)fprintf(stderr, "\n"); 170 } 171