119840Sdist /* 2*63597Sbostic * Copyright (c) 1989, 1993 3*63597Sbostic * The Regents of the University of California. All rights reserved. 439829Sbostic * 542527Sbostic * %sccs.include.redist.c% 619840Sdist */ 716242Slayer 819840Sdist #ifndef lint 9*63597Sbostic static char copyright[] = 10*63597Sbostic "@(#) Copyright (c) 1989, 1993\n\ 11*63597Sbostic The Regents of the University of California. All rights reserved.\n"; 1234043Sbostic #endif /* not lint */ 1319840Sdist 1434043Sbostic #ifndef lint 15*63597Sbostic static char sccsid[] = "@(#)chmod.c 8.1 (Berkeley) 06/27/93"; 1634043Sbostic #endif /* not lint */ 1734043Sbostic 1816242Slayer #include <sys/types.h> 1916242Slayer #include <sys/stat.h> 2058142Sbostic 2158142Sbostic #include <err.h> 2252070Sbostic #include <errno.h> 2339829Sbostic #include <fts.h> 2439829Sbostic #include <stdio.h> 2552070Sbostic #include <stdlib.h> 2642010Sbostic #include <string.h> 2758142Sbostic #include <unistd.h> 2816242Slayer 2952070Sbostic void usage __P((void)); 3052070Sbostic 3152070Sbostic int 3224503Ssam main(argc, argv) 3334043Sbostic int argc; 3452070Sbostic char *argv[]; 3516242Slayer { 3653782Selan register FTS *ftsp; 3739829Sbostic register FTSENT *p; 3839829Sbostic register int oct, omode; 3952070Sbostic mode_t *set; 4053782Selan int ch, fflag, rflag, hflag, Hflag; 4158142Sbostic int fts_options, retval; 4252070Sbostic char *ep, *mode; 4316242Slayer 4453782Selan fts_options = FTS_PHYSICAL; 4553782Selan fflag = rflag = hflag = Hflag = 0; 4653782Selan while ((ch = getopt(argc, argv, "HRfhrwx")) != EOF) 4734043Sbostic switch((char)ch) { 4853782Selan case 'H': 4953782Selan Hflag = 1; 5053782Selan fts_options |= FTS_COMFOLLOW; 5153782Selan break; 5224503Ssam case 'R': 5347072Sbostic rflag = 1; 5424503Ssam break; 5547072Sbostic case 'f': /* no longer documented */ 5647072Sbostic fflag = 1; 5724503Ssam break; 5853782Selan case 'h': 5953782Selan hflag = 1; 6053782Selan fts_options &= ~FTS_PHYSICAL; 6153782Selan fts_options |= FTS_LOGICAL; 6253782Selan break; 6347072Sbostic case 'r': /* "-[rwx]" are valid file modes */ 6439829Sbostic case 'w': 6539829Sbostic case 'x': 6639829Sbostic --optind; 6739829Sbostic goto done; 6834043Sbostic case '?': 6924503Ssam default: 7039829Sbostic usage(); 7123482Smckusick } 7234043Sbostic done: argv += optind; 7334043Sbostic argc -= optind; 7434043Sbostic 7539829Sbostic if (argc < 2) 7639829Sbostic usage(); 7739829Sbostic 7839829Sbostic mode = *argv; 7939829Sbostic if (*mode >= '0' && *mode <= '7') { 8052070Sbostic omode = (int)strtol(mode, &ep, 8); 8152070Sbostic if (omode < 0 || *ep) 8258142Sbostic errx(1, "invalid file mode: %s", mode); 8339829Sbostic oct = 1; 8439829Sbostic } else { 8558142Sbostic if ((set = setmode(mode)) == NULL) 8658142Sbostic errx(1, "invalid file mode: %s", mode); 8739829Sbostic oct = 0; 8816242Slayer } 8934043Sbostic 9039829Sbostic retval = 0; 9153782Selan if ((ftsp = fts_open(++argv, fts_options, 0)) == NULL) 9263596Sbostic err(1, ""); 9353782Selan while (p = fts_read(ftsp)) 9453782Selan switch(p->fts_info) { 9553782Selan case FTS_D: 9653782Selan if (!rflag) 9753782Selan fts_set(ftsp, p, FTS_SKIP); 9863596Sbostic case FTS_SL: 9963596Sbostic case FTS_SLNONE: 10053782Selan break; 10153782Selan case FTS_DNR: 10253782Selan case FTS_ERR: 10353782Selan case FTS_NS: 10458142Sbostic err(1, "%s", p->fts_path); 10553782Selan default: 10663596Sbostic if (p->fts_info == FTS_SL && !(hflag || 10753782Selan (Hflag && p->fts_level == FTS_ROOTLEVEL))) 10853782Selan continue; 10953782Selan if (chmod(p->fts_accpath, oct ? omode : 11058142Sbostic getmode(set, p->fts_statp->st_mode)) && !fflag) { 11158142Sbostic warn(p->fts_path); 11258142Sbostic retval = 1; 11358142Sbostic } 11453782Selan break; 11553782Selan } 11639829Sbostic exit(retval); 11716242Slayer } 11816242Slayer 11952070Sbostic void 12039829Sbostic usage() 12116242Slayer { 12253782Selan (void)fprintf(stderr, "usage: chmod [-HRh] mode file ...\n"); 12339829Sbostic exit(1); 12416242Slayer } 125