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*40269Sbostic static char sccsid[] = "@(#)chmod.c 5.9 (Berkeley) 03/05/90"; 2634043Sbostic #endif /* not lint */ 2734043Sbostic 2816242Slayer #include <sys/types.h> 2916242Slayer #include <sys/stat.h> 3039829Sbostic #include <fts.h> 3139829Sbostic #include <stdio.h> 3239829Sbostic #include <strings.h> 3316242Slayer 34*40269Sbostic extern int errno; 3539829Sbostic int retval; 3616242Slayer 3724503Ssam main(argc, argv) 3834043Sbostic int argc; 3934043Sbostic char **argv; 4016242Slayer { 41*40269Sbostic extern int optind; 4239829Sbostic register FTS *fts; 4339829Sbostic register FTSENT *p; 4439829Sbostic register int oct, omode; 4539829Sbostic register char *mode; 4639829Sbostic struct stat sb; 4739829Sbostic int ch, fflag, rflag; 4816242Slayer 4939829Sbostic fflag = rflag = 0; 5039829Sbostic while ((ch = getopt(argc, argv, "Rfrwx")) != EOF) 5134043Sbostic switch((char)ch) { 5224503Ssam case 'R': 5323482Smckusick rflag++; 5424503Ssam break; 5524503Ssam case 'f': 5624503Ssam fflag++; 5724503Ssam break; 5839829Sbostic /* "-[rwx]" are valid file modes */ 5939829Sbostic case 'r': 6039829Sbostic case 'w': 6139829Sbostic case 'x': 6239829Sbostic --optind; 6339829Sbostic goto done; 6434043Sbostic case '?': 6524503Ssam default: 6639829Sbostic usage(); 6723482Smckusick } 6834043Sbostic done: argv += optind; 6934043Sbostic argc -= optind; 7034043Sbostic 7139829Sbostic if (argc < 2) 7239829Sbostic usage(); 7339829Sbostic 7439829Sbostic mode = *argv; 7539829Sbostic if (*mode >= '0' && *mode <= '7') { 7639829Sbostic omode = (int)strtol(mode, (char **)NULL, 8); 7739829Sbostic oct = 1; 7839829Sbostic } else { 79*40269Sbostic if (setmode(mode) == -1) { 8039829Sbostic (void)fprintf(stderr, "chmod: invalid file mode.\n"); 8139829Sbostic exit(1); 8239829Sbostic } 8339829Sbostic oct = 0; 8416242Slayer } 8534043Sbostic 8639829Sbostic retval = 0; 8739829Sbostic if (rflag) { 8839829Sbostic if (!(fts = ftsopen(++argv, 8939829Sbostic (oct ? FTS_NOSTAT : 0)|FTS_MULTIPLE|FTS_PHYSICAL, 0))) { 9039829Sbostic (void)fprintf(stderr, "chmod: %s.\n", strerror(errno)); 9139829Sbostic exit(1); 9218473Smckusick } 9339829Sbostic while (p = ftsread(fts)) { 9439829Sbostic if (p->info == FTS_D) 9534043Sbostic continue; 9639829Sbostic if (p->info == FTS_ERR) { 9739829Sbostic if (!fflag) 9839829Sbostic error(p->path); 9939829Sbostic continue; 10016242Slayer } 101*40269Sbostic if (chmod(p->accpath, 102*40269Sbostic oct ? omode : getmode(p->statb.st_mode) && !fflag)) 10339829Sbostic error(p->path); 10416242Slayer } 10539829Sbostic exit(retval); 10634043Sbostic } 10739829Sbostic if (oct) { 10839829Sbostic while (*++argv) 10939829Sbostic if (chmod(*argv, omode) && !fflag) 11039829Sbostic error(*argv); 11139829Sbostic } else 11239829Sbostic while (*++argv) 113*40269Sbostic if ((lstat(*argv, &sb) || 114*40269Sbostic chmod(*argv, getmode(sb.st_mode))) && !fflag) 11539829Sbostic error(*argv); 11639829Sbostic exit(retval); 11716242Slayer } 11816242Slayer 11939829Sbostic error(name) 12039829Sbostic char *name; 12116242Slayer { 12239829Sbostic (void)fprintf(stderr, "chmod: %s: %s.\n", name, strerror(errno)); 12339829Sbostic retval = 1; 12416242Slayer } 12516242Slayer 12639829Sbostic usage() 12716242Slayer { 12839829Sbostic (void)fprintf(stderr, "chmod: chmod [-fR] mode file ...\n"); 12939829Sbostic exit(1); 13016242Slayer } 131