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*52070Sbostic static char sccsid[] = "@(#)chmod.c 5.20 (Berkeley) 12/28/91"; 1634043Sbostic #endif /* not lint */ 1734043Sbostic 1816242Slayer #include <sys/types.h> 1916242Slayer #include <sys/stat.h> 20*52070Sbostic #include <errno.h> 2139829Sbostic #include <fts.h> 22*52070Sbostic #include <unistd.h> 2339829Sbostic #include <stdio.h> 24*52070Sbostic #include <stdlib.h> 2542010Sbostic #include <string.h> 2616242Slayer 2739829Sbostic int retval; 2816242Slayer 29*52070Sbostic void err __P((const char *, ...)); 30*52070Sbostic void error __P((char *)); 31*52070Sbostic void usage __P((void)); 32*52070Sbostic 33*52070Sbostic int 3424503Ssam main(argc, argv) 3534043Sbostic int argc; 36*52070Sbostic char *argv[]; 3716242Slayer { 3839829Sbostic register FTS *fts; 3939829Sbostic register FTSENT *p; 4039829Sbostic register int oct, omode; 4139829Sbostic struct stat sb; 42*52070Sbostic mode_t *set; 4339829Sbostic int ch, fflag, rflag; 44*52070Sbostic char *ep, *mode; 4516242Slayer 4639829Sbostic fflag = rflag = 0; 4739829Sbostic while ((ch = getopt(argc, argv, "Rfrwx")) != EOF) 4834043Sbostic switch((char)ch) { 4924503Ssam case 'R': 5047072Sbostic rflag = 1; 5124503Ssam break; 5247072Sbostic case 'f': /* no longer documented */ 5347072Sbostic fflag = 1; 5424503Ssam break; 5547072Sbostic case 'r': /* "-[rwx]" are valid file modes */ 5639829Sbostic case 'w': 5739829Sbostic case 'x': 5839829Sbostic --optind; 5939829Sbostic goto done; 6034043Sbostic case '?': 6124503Ssam default: 6239829Sbostic usage(); 6323482Smckusick } 6434043Sbostic done: argv += optind; 6534043Sbostic argc -= optind; 6634043Sbostic 6739829Sbostic if (argc < 2) 6839829Sbostic usage(); 6939829Sbostic 7039829Sbostic mode = *argv; 7139829Sbostic if (*mode >= '0' && *mode <= '7') { 72*52070Sbostic omode = (int)strtol(mode, &ep, 8); 73*52070Sbostic if (omode < 0 || *ep) 74*52070Sbostic err("invalid file mode: %s", mode); 7539829Sbostic oct = 1; 7639829Sbostic } else { 77*52070Sbostic if (!(set = setmode(mode))) 78*52070Sbostic err("invalid file mode: %s", mode); 7939829Sbostic oct = 0; 8016242Slayer } 8134043Sbostic 8239829Sbostic retval = 0; 8339829Sbostic if (rflag) { 84*52070Sbostic if ((fts = fts_open(++argv, 85*52070Sbostic oct ? FTS_NOSTAT|FTS_PHYSICAL : FTS_PHYSICAL, 0)) == NULL) 86*52070Sbostic err("%s", strerror(errno)); 8745639Sbostic while (p = fts_read(fts)) 8845639Sbostic switch(p->fts_info) { 8945639Sbostic case FTS_D: 9045639Sbostic break; 9147235Sbostic case FTS_DNR: 9245639Sbostic case FTS_ERR: 9347235Sbostic case FTS_NS: 94*52070Sbostic err("%s: %s", p->fts_path, strerror(errno)); 9545639Sbostic default: 9645639Sbostic if (chmod(p->fts_accpath, oct ? omode : 9745639Sbostic getmode(set, p->fts_statb.st_mode)) && 9845639Sbostic !fflag) 9942202Sbostic error(p->fts_path); 10045639Sbostic break; 10116242Slayer } 10239829Sbostic exit(retval); 10334043Sbostic } 10439829Sbostic if (oct) { 10539829Sbostic while (*++argv) 10639829Sbostic if (chmod(*argv, omode) && !fflag) 10739829Sbostic error(*argv); 10839829Sbostic } else 10939829Sbostic while (*++argv) 11040269Sbostic if ((lstat(*argv, &sb) || 11140944Sbostic chmod(*argv, getmode(set, sb.st_mode))) && !fflag) 11239829Sbostic error(*argv); 11339829Sbostic exit(retval); 11416242Slayer } 11516242Slayer 116*52070Sbostic void 11739829Sbostic error(name) 11839829Sbostic char *name; 11916242Slayer { 120*52070Sbostic (void)fprintf(stderr, "chmod: %s: %s\n", name, strerror(errno)); 12139829Sbostic retval = 1; 12216242Slayer } 12316242Slayer 124*52070Sbostic void 12539829Sbostic usage() 12616242Slayer { 127*52070Sbostic (void)fprintf(stderr, "usage: chmod [-R] mode file ...\n"); 12839829Sbostic exit(1); 12916242Slayer } 130*52070Sbostic 131*52070Sbostic #if __STDC__ 132*52070Sbostic #include <stdarg.h> 133*52070Sbostic #else 134*52070Sbostic #include <varargs.h> 135*52070Sbostic #endif 136*52070Sbostic 137*52070Sbostic void 138*52070Sbostic #if __STDC__ 139*52070Sbostic err(const char *fmt, ...) 140*52070Sbostic #else 141*52070Sbostic err(fmt, va_alist) 142*52070Sbostic char *fmt; 143*52070Sbostic va_dcl 144*52070Sbostic #endif 145*52070Sbostic { 146*52070Sbostic va_list ap; 147*52070Sbostic #if __STDC__ 148*52070Sbostic va_start(ap, fmt); 149*52070Sbostic #else 150*52070Sbostic va_start(ap); 151*52070Sbostic #endif 152*52070Sbostic (void)fprintf(stderr, "chmod: "); 153*52070Sbostic (void)vfprintf(stderr, fmt, ap); 154*52070Sbostic va_end(ap); 155*52070Sbostic (void)fprintf(stderr, "\n"); 156*52070Sbostic exit(1); 157*52070Sbostic /* NOTREACHED */ 158*52070Sbostic } 159