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