xref: /csrg-svn/bin/chmod/chmod.c (revision 45639)
119840Sdist /*
239829Sbostic  * Copyright (c) 1989 The Regents of the University of California.
339829Sbostic  * All rights reserved.
439829Sbostic  *
542527Sbostic  * %sccs.include.redist.c%
619840Sdist  */
716242Slayer 
819840Sdist #ifndef lint
934043Sbostic char copyright[] =
1039829Sbostic "@(#) Copyright (c) 1989 The Regents of the University of California.\n\
1134043Sbostic  All rights reserved.\n";
1234043Sbostic #endif /* not lint */
1319840Sdist 
1434043Sbostic #ifndef lint
15*45639Sbostic static char sccsid[] = "@(#)chmod.c	5.17 (Berkeley) 11/21/90";
1634043Sbostic #endif /* not lint */
1734043Sbostic 
1816242Slayer #include <sys/types.h>
1916242Slayer #include <sys/stat.h>
2039829Sbostic #include <fts.h>
2139829Sbostic #include <stdio.h>
2242010Sbostic #include <string.h>
2316242Slayer 
2440269Sbostic extern int errno;
2539829Sbostic int retval;
2616242Slayer 
2724503Ssam main(argc, argv)
2834043Sbostic 	int argc;
2934043Sbostic 	char **argv;
3016242Slayer {
3140269Sbostic 	extern int optind;
3239829Sbostic 	register FTS *fts;
3339829Sbostic 	register FTSENT *p;
3439829Sbostic 	register int oct, omode;
3539829Sbostic 	register char *mode;
3640944Sbostic 	mode_t *set, *setmode();
3739829Sbostic 	struct stat sb;
3839829Sbostic 	int ch, fflag, rflag;
3916242Slayer 
4039829Sbostic 	fflag = rflag = 0;
4139829Sbostic 	while ((ch = getopt(argc, argv, "Rfrwx")) != EOF)
4234043Sbostic 		switch((char)ch) {
4324503Ssam 		case 'R':
4423482Smckusick 			rflag++;
4524503Ssam 			break;
4624503Ssam 		case 'f':
4724503Ssam 			fflag++;
4824503Ssam 			break;
4939829Sbostic 		/* "-[rwx]" are valid file modes */
5039829Sbostic 		case 'r':
5139829Sbostic 		case 'w':
5239829Sbostic 		case 'x':
5339829Sbostic 			--optind;
5439829Sbostic 			goto done;
5534043Sbostic 		case '?':
5624503Ssam 		default:
5739829Sbostic 			usage();
5823482Smckusick 		}
5934043Sbostic done:	argv += optind;
6034043Sbostic 	argc -= optind;
6134043Sbostic 
6239829Sbostic 	if (argc < 2)
6339829Sbostic 		usage();
6439829Sbostic 
6539829Sbostic 	mode = *argv;
6639829Sbostic 	if (*mode >= '0' && *mode <= '7') {
6739829Sbostic 		omode = (int)strtol(mode, (char **)NULL, 8);
6839829Sbostic 		oct = 1;
6939829Sbostic 	} else {
7040944Sbostic 		if (!(set = setmode(mode))) {
7139829Sbostic 			(void)fprintf(stderr, "chmod: invalid file mode.\n");
7239829Sbostic 			exit(1);
7339829Sbostic 		}
7439829Sbostic 		oct = 0;
7516242Slayer 	}
7634043Sbostic 
7739829Sbostic 	retval = 0;
7839829Sbostic 	if (rflag) {
7945601Sbostic 		if (!(fts = fts_open(++argv,
8043107Sbostic 		    oct ? FTS_NOSTAT|FTS_PHYSICAL : FTS_PHYSICAL, 0))) {
8139829Sbostic 			(void)fprintf(stderr, "chmod: %s.\n", strerror(errno));
8239829Sbostic 			exit(1);
8318473Smckusick 		}
84*45639Sbostic 		while (p = fts_read(fts))
85*45639Sbostic 			switch(p->fts_info) {
86*45639Sbostic 			case FTS_DNR:
87*45639Sbostic 				(void)fprintf(stderr,
88*45639Sbostic 				    "chmod: %s: unable to read.\n",
89*45639Sbostic 				    p->fts_path);
90*45639Sbostic 				break;
91*45639Sbostic 			case FTS_DNX:
92*45639Sbostic 				(void)fprintf(stderr,
93*45639Sbostic 				    "chmod: %s: unable to search.\n",
94*45639Sbostic 				    p->fts_path);
95*45639Sbostic 				break;
96*45639Sbostic 			case FTS_D:
97*45639Sbostic 			case FTS_DC:
98*45639Sbostic 				break;
99*45639Sbostic 			case FTS_ERR:
100*45639Sbostic 				(void)fprintf(stderr, "chmod: %s: %s.\n",
101*45639Sbostic 				    p->fts_path, strerror(errno));
102*45639Sbostic 				exit(1);
103*45639Sbostic 			case FTS_NS:
104*45639Sbostic 				(void)fprintf(stderr,
105*45639Sbostic 				    "chmod: %s: unable to stat.\n",
106*45639Sbostic 				    p->fts_path);
107*45639Sbostic 				break;
108*45639Sbostic 			default:
109*45639Sbostic 				if (chmod(p->fts_accpath, oct ? omode :
110*45639Sbostic 				    getmode(set, p->fts_statb.st_mode)) &&
111*45639Sbostic 				    !fflag)
11242202Sbostic 					error(p->fts_path);
113*45639Sbostic 				break;
11416242Slayer 			}
11539829Sbostic 		exit(retval);
11634043Sbostic 	}
11739829Sbostic 	if (oct) {
11839829Sbostic 		while (*++argv)
11939829Sbostic 			if (chmod(*argv, omode) && !fflag)
12039829Sbostic 				error(*argv);
12139829Sbostic 	} else
12239829Sbostic 		while (*++argv)
12340269Sbostic 			if ((lstat(*argv, &sb) ||
12440944Sbostic 			    chmod(*argv, getmode(set, sb.st_mode))) && !fflag)
12539829Sbostic 				error(*argv);
12639829Sbostic 	exit(retval);
12716242Slayer }
12816242Slayer 
12939829Sbostic error(name)
13039829Sbostic 	char *name;
13116242Slayer {
13239829Sbostic 	(void)fprintf(stderr, "chmod: %s: %s.\n", name, strerror(errno));
13339829Sbostic 	retval = 1;
13416242Slayer }
13516242Slayer 
13639829Sbostic usage()
13716242Slayer {
13839829Sbostic 	(void)fprintf(stderr, "chmod: chmod [-fR] mode file ...\n");
13939829Sbostic 	exit(1);
14016242Slayer }
141