xref: /csrg-svn/bin/chmod/chmod.c (revision 42010)
119840Sdist /*
239829Sbostic  * Copyright (c) 1989 The Regents of the University of California.
339829Sbostic  * All rights reserved.
439829Sbostic  *
539829Sbostic  * Redistribution and use in source and binary forms are permitted
639829Sbostic  * provided that the above copyright notice and this paragraph are
739829Sbostic  * duplicated in all such forms and that any documentation,
839829Sbostic  * advertising materials, and other materials related to such
939829Sbostic  * distribution and use acknowledge that the software was developed
1039829Sbostic  * by the University of California, Berkeley.  The name of the
1139829Sbostic  * University may not be used to endorse or promote products derived
1239829Sbostic  * from this software without specific prior written permission.
1339829Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1439829Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1539829Sbostic  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1619840Sdist  */
1716242Slayer 
1819840Sdist #ifndef lint
1934043Sbostic char copyright[] =
2039829Sbostic "@(#) Copyright (c) 1989 The Regents of the University of California.\n\
2134043Sbostic  All rights reserved.\n";
2234043Sbostic #endif /* not lint */
2319840Sdist 
2434043Sbostic #ifndef lint
25*42010Sbostic static char sccsid[] = "@(#)chmod.c	5.12 (Berkeley) 05/15/90";
2634043Sbostic #endif /* not lint */
2734043Sbostic 
2816242Slayer #include <sys/types.h>
2916242Slayer #include <sys/stat.h>
3039829Sbostic #include <fts.h>
3139829Sbostic #include <stdio.h>
32*42010Sbostic #include <string.h>
3316242Slayer 
3440269Sbostic extern int errno;
3539829Sbostic int retval;
3616242Slayer 
3724503Ssam main(argc, argv)
3834043Sbostic 	int argc;
3934043Sbostic 	char **argv;
4016242Slayer {
4140269Sbostic 	extern int optind;
4239829Sbostic 	register FTS *fts;
4339829Sbostic 	register FTSENT *p;
4439829Sbostic 	register int oct, omode;
4539829Sbostic 	register char *mode;
4640944Sbostic 	mode_t *set, *setmode();
4739829Sbostic 	struct stat sb;
4839829Sbostic 	int ch, fflag, rflag;
4916242Slayer 
5039829Sbostic 	fflag = rflag = 0;
5139829Sbostic 	while ((ch = getopt(argc, argv, "Rfrwx")) != EOF)
5234043Sbostic 		switch((char)ch) {
5324503Ssam 		case 'R':
5423482Smckusick 			rflag++;
5524503Ssam 			break;
5624503Ssam 		case 'f':
5724503Ssam 			fflag++;
5824503Ssam 			break;
5939829Sbostic 		/* "-[rwx]" are valid file modes */
6039829Sbostic 		case 'r':
6139829Sbostic 		case 'w':
6239829Sbostic 		case 'x':
6339829Sbostic 			--optind;
6439829Sbostic 			goto done;
6534043Sbostic 		case '?':
6624503Ssam 		default:
6739829Sbostic 			usage();
6823482Smckusick 		}
6934043Sbostic done:	argv += optind;
7034043Sbostic 	argc -= optind;
7134043Sbostic 
7239829Sbostic 	if (argc < 2)
7339829Sbostic 		usage();
7439829Sbostic 
7539829Sbostic 	mode = *argv;
7639829Sbostic 	if (*mode >= '0' && *mode <= '7') {
7739829Sbostic 		omode = (int)strtol(mode, (char **)NULL, 8);
7839829Sbostic 		oct = 1;
7939829Sbostic 	} else {
8040944Sbostic 		if (!(set = setmode(mode))) {
8139829Sbostic 			(void)fprintf(stderr, "chmod: invalid file mode.\n");
8239829Sbostic 			exit(1);
8339829Sbostic 		}
8439829Sbostic 		oct = 0;
8516242Slayer 	}
8634043Sbostic 
8739829Sbostic 	retval = 0;
8839829Sbostic 	if (rflag) {
8939829Sbostic 		if (!(fts = ftsopen(++argv,
9039829Sbostic 		    (oct ? FTS_NOSTAT : 0)|FTS_MULTIPLE|FTS_PHYSICAL, 0))) {
9139829Sbostic 			(void)fprintf(stderr, "chmod: %s.\n", strerror(errno));
9239829Sbostic 			exit(1);
9318473Smckusick 		}
9439829Sbostic 		while (p = ftsread(fts)) {
9539829Sbostic 			if (p->info == FTS_D)
9634043Sbostic 				continue;
9739829Sbostic 			if (p->info == FTS_ERR) {
9839829Sbostic 				if (!fflag)
9939829Sbostic 					error(p->path);
10039829Sbostic 				continue;
10116242Slayer 			}
10240944Sbostic 			if (chmod(p->accpath, oct ?
10341116Sbostic 			    omode : getmode(set, p->statb.st_mode)) && !fflag)
10439829Sbostic 				error(p->path);
10516242Slayer 		}
10639829Sbostic 		exit(retval);
10734043Sbostic 	}
10839829Sbostic 	if (oct) {
10939829Sbostic 		while (*++argv)
11039829Sbostic 			if (chmod(*argv, omode) && !fflag)
11139829Sbostic 				error(*argv);
11239829Sbostic 	} else
11339829Sbostic 		while (*++argv)
11440269Sbostic 			if ((lstat(*argv, &sb) ||
11540944Sbostic 			    chmod(*argv, getmode(set, sb.st_mode))) && !fflag)
11639829Sbostic 				error(*argv);
11739829Sbostic 	exit(retval);
11816242Slayer }
11916242Slayer 
12039829Sbostic error(name)
12139829Sbostic 	char *name;
12216242Slayer {
12339829Sbostic 	(void)fprintf(stderr, "chmod: %s: %s.\n", name, strerror(errno));
12439829Sbostic 	retval = 1;
12516242Slayer }
12616242Slayer 
12739829Sbostic usage()
12816242Slayer {
12939829Sbostic 	(void)fprintf(stderr, "chmod: chmod [-fR] mode file ...\n");
13039829Sbostic 	exit(1);
13116242Slayer }
132