SCCS-vsn: bin/chmod/chmod.c 5.4
-static char sccsid[] = "@(#)chmod.c 5.3 (Berkeley) %G%";
-#endif not lint
+static char sccsid[] = "@(#)chmod.c 5.4 (Berkeley) %G%";
+#endif
/*
* chmod options mode files
* where
/*
* chmod options mode files
* where
- * mode is [ugoa][+-=][rwxXstugo] or a octal number
- * options are -R
+ * mode is [ugoa][+-=][rwxXstugo] or an octal number
+ * options are -Rf
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/dir.h>
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/dir.h>
-#define USER 05700 /* user's bits */
-#define GROUP 02070 /* group's bits */
-#define OTHER 00007 /* other's bits */
-#define ALL 01777 /* all (note absence of setuid, etc) */
-
-#define READ 00444 /* read permit */
-#define WRITE 00222 /* write permit */
-#define EXEC 00111 /* exec permit */
-#define SETID 06000 /* set[ug]id */
-#define STICKY 01000 /* sticky bit */
-
char *modestring, *ms;
int um;
int status;
char *modestring, *ms;
int um;
int status;
-main(argc,argv)
-char **argv;
+main(argc, argv)
+ char *argv[];
register char *p, *flags;
register char *p, *flags;
+ register int i;
+ struct stat st;
- fprintf(stderr
- ,"Usage: chmod [-R] [ugoa][+-=][rwxXstugo] file ...\n");
+ fprintf(stderr,
+ "Usage: chmod [-Rf] [ugoa][+-=][rwxXstugo] file ...\n");
- if (*argv[0] == '-') {
- if (strcmp(argv[0], "-R") == 0) {
+ while (argc > 0 && argv[0][0] == '-') {
+ for (p = &argv[0][1]; *p; p++) switch (*p) {
+
+ case 'R':
+ break;
+
+ case 'f':
+ fflag++;
+ break;
+
+ default:
+ goto done;
um = umask(0);
(void) newmode(0);
for (i = 1; i < argc; i++) {
p = argv[i];
um = umask(0);
(void) newmode(0);
for (i = 1; i < argc; i++) {
p = argv[i];
+ /* do stat for directory arguments */
- fprintf(stderr, "chmod: can't access %s\n", p);
- ++status;
+ status += error("can't access %s", p);
- if (rflag && st.st_mode & S_IFDIR) {
+ if (rflag && st.st_mode&S_IFDIR) {
status += chmodr(p, newmode(st.st_mode));
status += chmodr(p, newmode(st.st_mode));
- } else if (chmod(p, newmode(st.st_mode)) < 0) {
- fprintf(stderr, "chmod: can't change %s\n", p);
- ++status;
+ continue;
+ }
+ if (chmod(p, newmode(st.st_mode)) < 0) {
+ status += error("can't change %s", p);
- register DIR *dirp;
- register struct direct *dp;
- register struct stat st;
- char savedir[1024];
-
- if (getwd(savedir) == 0) {
- fprintf(stderr, "chmod: %s\n", savedir);
- exit(255);
- }
+ register DIR *dirp;
+ register struct direct *dp;
+ register struct stat st;
+ char savedir[1024];
+ int ecode;
+ if (getwd(savedir) == 0)
+ fatal(255, "%s", savedir);
- ** chmod what we are given before doing it's contents
- */
- chmod(dir, newmode(mode));
-
- chdir(dir);
- if ((dirp = opendir(".")) == NULL) {
- perror(dir);
- return(1);
- }
+ * Change what we are given before doing it's contents
+ */
+ if (chmod(dir, newmode(mode)) < 0 && error("can't change %s", dir))
+ return (1);
+ if (chdir(dir) < 0)
+ return (Perror(dir));
+ if ((dirp = opendir(".")) == NULL)
+ return (Perror(dir));
dp = readdir(dirp);
dp = readdir(dirp); /* read "." and ".." */
dp = readdir(dirp);
dp = readdir(dirp); /* read "." and ".." */
for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
- if (stat(dp->d_name, &st) < 0) {
- fprintf(stderr, "chmod: can't access %s\n", dp->d_name);
- return(1);
+ if (lstat(dp->d_name, &st) < 0) {
+ ecode = error("can't access %s", dp->d_name);
+ if (ecode)
+ break;
+ continue;
+ }
+ if (st.st_mode&S_IFDIR) {
+ ecode = chmodr(dp->d_name, newmode(st.st_mode));
+ if (ecode)
+ break;
+ continue;
- if (st.st_mode & S_IFDIR)
- chmodr(dp->d_name, newmode(st.st_mode));
- else
- chmod(dp->d_name, newmode(st.st_mode));
+ if (chmod(dp->d_name, newmode(st.st_mode)) < 0 &&
+ (ecode = error("can't change %s", dp->d_name)))
+ break;
- chdir(savedir);
- return(0);
+ if (chdir(savedir) < 0)
+ fatal(255, "can't change back to %s", savedir);
+ return (ecode);
+}
+
+error(fmt, a)
+ char *fmt, *a;
+{
+
+ if (!fflag) {
+ fprintf(stderr, "chmod: ");
+ fprintf(stderr, fmt, a);
+ putc('\n', stderr);
+ }
+ return (!fflag);
+}
+
+fatal(status, fmt, a)
+ int status;
+ char *fmt, *a;
+{
+
+ fflag = 0;
+ (void) error(fmt, a);
+ exit(status);
+}
+
+Perror(s)
+ char *s;
+{
+
+ fprintf(stderr, "chmod: ");
+ perror(s);
+ return (1);
{
register o, m, b;
int savem;
{
register o, m, b;
int savem;
ms = modestring;
savem = nm;
m = abs();
ms = modestring;
savem = nm;
m = abs();
+ if (*ms == '\0')
+ return (m);
do {
m = who();
while (o = what()) {
do {
m = who();
while (o = what()) {
}
}
} while (*ms++ == ',');
}
}
} while (*ms++ == ',');
- if (*--ms) {
- fprintf(stderr, "chmod: invalid mode\n");
- exit(255);
- }
- return(nm);
+ if (*--ms)
+ fatal(255, "invalid mode");
+ return (nm);
while ((c = *ms++) >= '0' && c <= '7')
i = (i << 3) + (c - '0');
ms--;
while ((c = *ms++) >= '0' && c <= '7')
i = (i << 3) + (c - '0');
ms--;
+#define USER 05700 /* user's bits */
+#define GROUP 02070 /* group's bits */
+#define OTHER 00007 /* other's bits */
+#define ALL 01777 /* all (note absence of setuid, etc) */
+
+#define READ 00444 /* read permit */
+#define WRITE 00222 /* write permit */
+#define EXEC 00111 /* exec permit */
+#define SETID 06000 /* set[ug]id */
+#define STICKY 01000 /* sticky bit */
+
ms--;
if (m == 0)
m = ALL & ~um;
ms--;
if (m == 0)
m = ALL & ~um;
case '+':
case '-':
case '=':
case '+':
case '-':
case '=':
m &= (READ|WRITE|EXEC);
m |= (m << 3) | (m << 6);
++ms;
m &= (READ|WRITE|EXEC);
m |= (m << 3) | (m << 6);
++ms;
}
for (;;) switch (*ms++) {
case 'r':
}
for (;;) switch (*ms++) {
case 'r':