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