Home | History | Annotate | Line # | Download | only in touch
touch.c revision 1.1
      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, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  * 3. All advertising materials mentioning features or use of this software
     14  *    must display the following acknowledgement:
     15  *	This product includes software developed by the University of
     16  *	California, Berkeley and its contributors.
     17  * 4. Neither the name of the University nor the names of its contributors
     18  *    may be used to endorse or promote products derived from this software
     19  *    without specific prior written permission.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     31  * SUCH DAMAGE.
     32  */
     33 
     34 #ifndef lint
     35 char copyright[] =
     36 "@(#) Copyright (c) 1988 Regents of the University of California.\n\
     37  All rights reserved.\n";
     38 #endif /* not lint */
     39 
     40 #ifndef lint
     41 static char sccsid[] = "@(#)touch.c	4.8 (Berkeley) 6/1/90";
     42 #endif /* not lint */
     43 
     44 /*
     45  * Attempt to set the modify date of a file to the current date.  If the
     46  * file exists, read and write its first character.  If the file doesn't
     47  * exist, create it, unless -c option prevents it.  If the file is read-only,
     48  * -f forces chmod'ing and touch'ing.
     49  */
     50 #include <sys/types.h>
     51 #include <sys/file.h>
     52 #include <sys/stat.h>
     53 #include <stdio.h>
     54 
     55 static int	dontcreate;	/* set if -c option */
     56 static int	force;		/* set if -f option */
     57 
     58 main(argc, argv)
     59 	int argc;
     60 	char **argv;
     61 {
     62 	extern int optind;
     63 	int ch, retval;
     64 
     65 	dontcreate = force = retval = 0;
     66 	while ((ch = getopt(argc, argv, "cf")) != EOF)
     67 		switch((char)ch) {
     68 		case 'c':
     69 			dontcreate = 1;
     70 			break;
     71 		case 'f':
     72 			force = 1;
     73 			break;
     74 		case '?':
     75 		default:
     76 			usage();
     77 		}
     78 	if (!*(argv += optind))
     79 		usage();
     80 	do {
     81 		retval |= touch(*argv);
     82 	} while (*++argv);
     83 	exit(retval);
     84 }
     85 
     86 touch(filename)
     87 	char *filename;
     88 {
     89 	struct stat statbuffer;
     90 
     91 	if (stat(filename, &statbuffer) == -1) {
     92 		if (!dontcreate)
     93 			return(readwrite(filename, 0L));
     94 		fprintf(stderr, "touch: %s: does not exist\n", filename);
     95 		return(1);
     96 	}
     97 	if ((statbuffer.st_mode & S_IFMT) != S_IFREG) {
     98 		fprintf(stderr, "touch: %s: can only touch regular files\n",
     99 		    filename);
    100 		return(1);
    101 	}
    102 	if (!access(filename, R_OK | W_OK))
    103 		return(readwrite(filename,statbuffer.st_size));
    104 	if (force) {
    105 		int retval;
    106 
    107 		if (chmod(filename, 0666)) {
    108 			fprintf(stderr, "touch: %s: couldn't chmod: ",
    109 			    filename);
    110 			perror((char *)NULL);
    111 			return(1);
    112 		}
    113 		retval = readwrite(filename, statbuffer.st_size);
    114 		if (chmod(filename, statbuffer.st_mode)) {
    115 			fprintf(stderr, "touch: %s: couldn't chmod back: ",
    116 			    filename);
    117 			perror((char *)NULL);
    118 			return(1);
    119 		}
    120 		return(retval);
    121 	}
    122 	fprintf(stderr, "touch: %s: cannot touch\n", filename);
    123 	return(1);
    124 }
    125 
    126 readwrite(filename, size)
    127 	char *filename;
    128 	off_t size;
    129 {
    130 	int filedescriptor;
    131 	char first;
    132 	off_t lseek();
    133 
    134 	if (size) {
    135 		filedescriptor = open(filename, O_RDWR, 0);
    136 		if (filedescriptor == -1) {
    137 error:			fprintf(stderr, "touch: %s: ", filename);
    138 			perror((char *)NULL);
    139 			return(1);
    140 		}
    141 		if (read(filedescriptor, &first, 1) != 1)
    142 			goto error;
    143 		if (lseek(filedescriptor, 0L, 0) == -1)
    144 			goto error;
    145 		if (write(filedescriptor, &first, 1) != 1)
    146 			goto error;
    147 	} else {
    148 		filedescriptor = creat(filename, 0666);
    149 		if (filedescriptor == -1)
    150 			goto error;
    151 	}
    152 	if (close(filedescriptor) == -1)
    153 		goto error;
    154 	return(0);
    155 }
    156 
    157 usage()
    158 {
    159 	fprintf(stderr, "usage: touch [-cf] file ...\n");
    160 	exit(1);
    161 }
    162