119840Sdist /* 239829Sbostic * Copyright (c) 1989 The Regents of the University of California. 339829Sbostic * All rights reserved. 439829Sbostic * 5*42527Sbostic * %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*42527Sbostic static char sccsid[] = "@(#)chmod.c 5.14 (Berkeley) 05/31/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) { 7939829Sbostic if (!(fts = ftsopen(++argv, 8039829Sbostic (oct ? FTS_NOSTAT : 0)|FTS_MULTIPLE|FTS_PHYSICAL, 0))) { 8139829Sbostic (void)fprintf(stderr, "chmod: %s.\n", strerror(errno)); 8239829Sbostic exit(1); 8318473Smckusick } 8439829Sbostic while (p = ftsread(fts)) { 8542202Sbostic if (p->fts_info == FTS_D) 8634043Sbostic continue; 8742202Sbostic if (p->fts_info == FTS_ERR) { 8839829Sbostic if (!fflag) 8942202Sbostic error(p->fts_path); 9039829Sbostic continue; 9116242Slayer } 9242202Sbostic if (chmod(p->fts_accpath, oct ? 9342202Sbostic omode : getmode(set, p->fts_statb.st_mode)) && 9442202Sbostic !fflag) 9542202Sbostic error(p->fts_path); 9616242Slayer } 9739829Sbostic exit(retval); 9834043Sbostic } 9939829Sbostic if (oct) { 10039829Sbostic while (*++argv) 10139829Sbostic if (chmod(*argv, omode) && !fflag) 10239829Sbostic error(*argv); 10339829Sbostic } else 10439829Sbostic while (*++argv) 10540269Sbostic if ((lstat(*argv, &sb) || 10640944Sbostic chmod(*argv, getmode(set, sb.st_mode))) && !fflag) 10739829Sbostic error(*argv); 10839829Sbostic exit(retval); 10916242Slayer } 11016242Slayer 11139829Sbostic error(name) 11239829Sbostic char *name; 11316242Slayer { 11439829Sbostic (void)fprintf(stderr, "chmod: %s: %s.\n", name, strerror(errno)); 11539829Sbostic retval = 1; 11616242Slayer } 11716242Slayer 11839829Sbostic usage() 11916242Slayer { 12039829Sbostic (void)fprintf(stderr, "chmod: chmod [-fR] mode file ...\n"); 12139829Sbostic exit(1); 12216242Slayer } 123