move to /var
[unix-history] / usr / src / bin / chmod / chmod.c
CommitLineData
bcf1365c 1/*
6aa2c2f8
KB
2 * Copyright (c) 1989 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
bcf1365c
DF
16 */
17
18#ifndef lint
8cc66a82 19char copyright[] =
6aa2c2f8 20"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
8cc66a82
KB
21 All rights reserved.\n";
22#endif /* not lint */
23
24#ifndef lint
0f3ab199 25static char sccsid[] = "@(#)chmod.c 5.13 (Berkeley) %G%";
8cc66a82 26#endif /* not lint */
473911a1 27
473911a1
KL
28#include <sys/types.h>
29#include <sys/stat.h>
6aa2c2f8
KB
30#include <fts.h>
31#include <stdio.h>
6ebcb998 32#include <string.h>
473911a1 33
3600788a 34extern int errno;
6aa2c2f8 35int retval;
473911a1 36
3d6dbb93 37main(argc, argv)
8cc66a82
KB
38 int argc;
39 char **argv;
473911a1 40{
3600788a 41 extern int optind;
6aa2c2f8
KB
42 register FTS *fts;
43 register FTSENT *p;
44 register int oct, omode;
45 register char *mode;
34353049 46 mode_t *set, *setmode();
6aa2c2f8
KB
47 struct stat sb;
48 int ch, fflag, rflag;
6aa2c2f8
KB
49
50 fflag = rflag = 0;
51 while ((ch = getopt(argc, argv, "Rfrwx")) != EOF)
8cc66a82 52 switch((char)ch) {
3d6dbb93 53 case 'R':
fe196551 54 rflag++;
3d6dbb93 55 break;
3d6dbb93
SL
56 case 'f':
57 fflag++;
58 break;
6aa2c2f8
KB
59 /* "-[rwx]" are valid file modes */
60 case 'r':
61 case 'w':
62 case 'x':
8cc66a82 63 --optind;
3d6dbb93 64 goto done;
6aa2c2f8
KB
65 case '?':
66 default:
67 usage();
fe196551 68 }
8cc66a82
KB
69done: argv += optind;
70 argc -= optind;
71
6aa2c2f8
KB
72 if (argc < 2)
73 usage();
74
75 mode = *argv;
76 if (*mode >= '0' && *mode <= '7') {
77 omode = (int)strtol(mode, (char **)NULL, 8);
78 oct = 1;
79 } else {
34353049 80 if (!(set = setmode(mode))) {
6aa2c2f8
KB
81 (void)fprintf(stderr, "chmod: invalid file mode.\n");
82 exit(1);
83 }
84 oct = 0;
473911a1 85 }
8cc66a82 86
6aa2c2f8
KB
87 retval = 0;
88 if (rflag) {
89 if (!(fts = ftsopen(++argv,
90 (oct ? FTS_NOSTAT : 0)|FTS_MULTIPLE|FTS_PHYSICAL, 0))) {
91 (void)fprintf(stderr, "chmod: %s.\n", strerror(errno));
92 exit(1);
3d6dbb93 93 }
6aa2c2f8 94 while (p = ftsread(fts)) {
0f3ab199 95 if (p->fts_info == FTS_D)
6aa2c2f8 96 continue;
0f3ab199 97 if (p->fts_info == FTS_ERR) {
6aa2c2f8 98 if (!fflag)
0f3ab199 99 error(p->fts_path);
8cc66a82 100 continue;
473911a1 101 }
0f3ab199
KB
102 if (chmod(p->fts_accpath, oct ?
103 omode : getmode(set, p->fts_statb.st_mode)) &&
104 !fflag)
105 error(p->fts_path);
473911a1 106 }
6aa2c2f8 107 exit(retval);
473911a1 108 }
6aa2c2f8
KB
109 if (oct) {
110 while (*++argv)
111 if (chmod(*argv, omode) && !fflag)
112 error(*argv);
113 } else
114 while (*++argv)
3600788a 115 if ((lstat(*argv, &sb) ||
34353049 116 chmod(*argv, getmode(set, sb.st_mode))) && !fflag)
6aa2c2f8
KB
117 error(*argv);
118 exit(retval);
473911a1
KL
119}
120
6aa2c2f8
KB
121error(name)
122 char *name;
473911a1 123{
6aa2c2f8
KB
124 (void)fprintf(stderr, "chmod: %s: %s.\n", name, strerror(errno));
125 retval = 1;
473911a1
KL
126}
127
6aa2c2f8 128usage()
473911a1 129{
6aa2c2f8
KB
130 (void)fprintf(stderr, "chmod: chmod [-fR] mode file ...\n");
131 exit(1);
473911a1 132}