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*47072Sbostic static char sccsid[] = "@(#)chmod.c 5.18 (Berkeley) 03/07/91"; 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': 44*47072Sbostic rflag = 1; 4524503Ssam break; 46*47072Sbostic case 'f': /* no longer documented */ 47*47072Sbostic fflag = 1; 4824503Ssam break; 49*47072Sbostic case 'r': /* "-[rwx]" are valid file modes */ 5039829Sbostic case 'w': 5139829Sbostic case 'x': 5239829Sbostic --optind; 5339829Sbostic goto done; 5434043Sbostic case '?': 5524503Ssam default: 5639829Sbostic usage(); 5723482Smckusick } 5834043Sbostic done: argv += optind; 5934043Sbostic argc -= optind; 6034043Sbostic 6139829Sbostic if (argc < 2) 6239829Sbostic usage(); 6339829Sbostic 6439829Sbostic mode = *argv; 6539829Sbostic if (*mode >= '0' && *mode <= '7') { 6639829Sbostic omode = (int)strtol(mode, (char **)NULL, 8); 6739829Sbostic oct = 1; 6839829Sbostic } else { 6940944Sbostic if (!(set = setmode(mode))) { 7039829Sbostic (void)fprintf(stderr, "chmod: invalid file mode.\n"); 7139829Sbostic exit(1); 7239829Sbostic } 7339829Sbostic oct = 0; 7416242Slayer } 7534043Sbostic 7639829Sbostic retval = 0; 7739829Sbostic if (rflag) { 7845601Sbostic if (!(fts = fts_open(++argv, 7943107Sbostic oct ? FTS_NOSTAT|FTS_PHYSICAL : FTS_PHYSICAL, 0))) { 8039829Sbostic (void)fprintf(stderr, "chmod: %s.\n", strerror(errno)); 8139829Sbostic exit(1); 8218473Smckusick } 8345639Sbostic while (p = fts_read(fts)) 8445639Sbostic switch(p->fts_info) { 8545639Sbostic case FTS_DNR: 8645639Sbostic (void)fprintf(stderr, 8745639Sbostic "chmod: %s: unable to read.\n", 8845639Sbostic p->fts_path); 8945639Sbostic break; 9045639Sbostic case FTS_DNX: 9145639Sbostic (void)fprintf(stderr, 9245639Sbostic "chmod: %s: unable to search.\n", 9345639Sbostic p->fts_path); 9445639Sbostic break; 9545639Sbostic case FTS_D: 9645639Sbostic case FTS_DC: 9745639Sbostic break; 9845639Sbostic case FTS_ERR: 9945639Sbostic (void)fprintf(stderr, "chmod: %s: %s.\n", 10045639Sbostic p->fts_path, strerror(errno)); 10145639Sbostic exit(1); 10245639Sbostic case FTS_NS: 10345639Sbostic (void)fprintf(stderr, 10445639Sbostic "chmod: %s: unable to stat.\n", 10545639Sbostic p->fts_path); 10645639Sbostic break; 10745639Sbostic default: 10845639Sbostic if (chmod(p->fts_accpath, oct ? omode : 10945639Sbostic getmode(set, p->fts_statb.st_mode)) && 11045639Sbostic !fflag) 11142202Sbostic error(p->fts_path); 11245639Sbostic break; 11316242Slayer } 11439829Sbostic exit(retval); 11534043Sbostic } 11639829Sbostic if (oct) { 11739829Sbostic while (*++argv) 11839829Sbostic if (chmod(*argv, omode) && !fflag) 11939829Sbostic error(*argv); 12039829Sbostic } else 12139829Sbostic while (*++argv) 12240269Sbostic if ((lstat(*argv, &sb) || 12340944Sbostic chmod(*argv, getmode(set, sb.st_mode))) && !fflag) 12439829Sbostic error(*argv); 12539829Sbostic exit(retval); 12616242Slayer } 12716242Slayer 12839829Sbostic error(name) 12939829Sbostic char *name; 13016242Slayer { 13139829Sbostic (void)fprintf(stderr, "chmod: %s: %s.\n", name, strerror(errno)); 13239829Sbostic retval = 1; 13316242Slayer } 13416242Slayer 13539829Sbostic usage() 13616242Slayer { 137*47072Sbostic (void)fprintf(stderr, "chmod: chmod [-R] mode file ...\n"); 13839829Sbostic exit(1); 13916242Slayer } 140