Added -Hh documentation.
[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 *
27c71911 5 * %sccs.include.redist.c%
bcf1365c
DF
6 */
7
8#ifndef lint
8cc66a82 9char copyright[] =
6aa2c2f8 10"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
8cc66a82
KB
11 All rights reserved.\n";
12#endif /* not lint */
13
14#ifndef lint
834beb60 15static char sccsid[] = "@(#)chmod.c 5.21 (Berkeley) %G%";
8cc66a82 16#endif /* not lint */
473911a1 17
473911a1
KL
18#include <sys/types.h>
19#include <sys/stat.h>
a22be226 20#include <errno.h>
6aa2c2f8 21#include <fts.h>
a22be226 22#include <unistd.h>
6aa2c2f8 23#include <stdio.h>
a22be226 24#include <stdlib.h>
6ebcb998 25#include <string.h>
473911a1 26
6aa2c2f8 27int retval;
473911a1 28
a22be226
KB
29void err __P((const char *, ...));
30void error __P((char *));
31void usage __P((void));
32
33int
3d6dbb93 34main(argc, argv)
8cc66a82 35 int argc;
a22be226 36 char *argv[];
473911a1 37{
6aa2c2f8
KB
38 register FTS *fts;
39 register FTSENT *p;
40 register int oct, omode;
6aa2c2f8 41 struct stat sb;
a22be226 42 mode_t *set;
6aa2c2f8 43 int ch, fflag, rflag;
a22be226 44 char *ep, *mode;
6aa2c2f8
KB
45
46 fflag = rflag = 0;
47 while ((ch = getopt(argc, argv, "Rfrwx")) != EOF)
8cc66a82 48 switch((char)ch) {
3d6dbb93 49 case 'R':
36c26652 50 rflag = 1;
3d6dbb93 51 break;
36c26652
KB
52 case 'f': /* no longer documented */
53 fflag = 1;
3d6dbb93 54 break;
36c26652 55 case 'r': /* "-[rwx]" are valid file modes */
6aa2c2f8
KB
56 case 'w':
57 case 'x':
8cc66a82 58 --optind;
3d6dbb93 59 goto done;
6aa2c2f8
KB
60 case '?':
61 default:
62 usage();
fe196551 63 }
8cc66a82
KB
64done: argv += optind;
65 argc -= optind;
66
6aa2c2f8
KB
67 if (argc < 2)
68 usage();
69
70 mode = *argv;
71 if (*mode >= '0' && *mode <= '7') {
a22be226
KB
72 omode = (int)strtol(mode, &ep, 8);
73 if (omode < 0 || *ep)
74 err("invalid file mode: %s", mode);
6aa2c2f8
KB
75 oct = 1;
76 } else {
a22be226
KB
77 if (!(set = setmode(mode)))
78 err("invalid file mode: %s", mode);
6aa2c2f8 79 oct = 0;
473911a1 80 }
8cc66a82 81
6aa2c2f8
KB
82 retval = 0;
83 if (rflag) {
a22be226
KB
84 if ((fts = fts_open(++argv,
85 oct ? FTS_NOSTAT|FTS_PHYSICAL : FTS_PHYSICAL, 0)) == NULL)
86 err("%s", strerror(errno));
c19052a5
KB
87 while (p = fts_read(fts))
88 switch(p->fts_info) {
c19052a5 89 case FTS_D:
c19052a5 90 break;
28234b31 91 case FTS_DNR:
c19052a5 92 case FTS_ERR:
28234b31 93 case FTS_NS:
a22be226 94 err("%s: %s", p->fts_path, strerror(errno));
c19052a5
KB
95 default:
96 if (chmod(p->fts_accpath, oct ? omode :
834beb60 97 getmode(set, p->fts_statp->st_mode)) &&
c19052a5 98 !fflag)
0f3ab199 99 error(p->fts_path);
c19052a5 100 break;
473911a1 101 }
6aa2c2f8 102 exit(retval);
473911a1 103 }
6aa2c2f8
KB
104 if (oct) {
105 while (*++argv)
106 if (chmod(*argv, omode) && !fflag)
107 error(*argv);
108 } else
109 while (*++argv)
3600788a 110 if ((lstat(*argv, &sb) ||
34353049 111 chmod(*argv, getmode(set, sb.st_mode))) && !fflag)
6aa2c2f8
KB
112 error(*argv);
113 exit(retval);
473911a1
KL
114}
115
a22be226 116void
6aa2c2f8
KB
117error(name)
118 char *name;
473911a1 119{
a22be226 120 (void)fprintf(stderr, "chmod: %s: %s\n", name, strerror(errno));
6aa2c2f8 121 retval = 1;
473911a1
KL
122}
123
a22be226 124void
6aa2c2f8 125usage()
473911a1 126{
a22be226
KB
127 (void)fprintf(stderr, "usage: chmod [-R] mode file ...\n");
128 exit(1);
129}
130
131#if __STDC__
132#include <stdarg.h>
133#else
134#include <varargs.h>
135#endif
136
137void
138#if __STDC__
139err(const char *fmt, ...)
140#else
141err(fmt, va_alist)
142 char *fmt;
143 va_dcl
144#endif
145{
146 va_list ap;
147#if __STDC__
148 va_start(ap, fmt);
149#else
150 va_start(ap);
151#endif
152 (void)fprintf(stderr, "chmod: ");
153 (void)vfprintf(stderr, fmt, ap);
154 va_end(ap);
155 (void)fprintf(stderr, "\n");
6aa2c2f8 156 exit(1);
a22be226 157 /* NOTREACHED */
473911a1 158}