home *** CD-ROM | disk | FTP | other *** search
- /*
- * chmod [ugoa][+-=][rwxstugo] files
- * change mode of files
- */
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.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 *ms;
- int um;
- struct stat st;
-
- main(argc,argv)
- char **argv;
- {
- register i;
- register char *p;
- int status = 0;
-
- if (argc < 3) {
- fprintf(stderr, "Usage: chmod [ugoa][+-=][rwxstugo] file ...\n");
- exit(255);
- }
- ms = argv[1];
- um = umask(0);
- newmode(0);
- for (i = 2; i < argc; i++) {
- p = argv[i];
- if (stat(p, &st) < 0) {
- fprintf(stderr, "chmod: can't access %s\n", p);
- ++status;
- continue;
- }
- ms = argv[1];
- if (chmod(p, newmode(st.st_mode)) < 0) {
- fprintf(stderr, "chmod: can't change %s\n", p);
- ++status;
- continue;
- }
- }
- exit(status);
- }
-
- newmode(nm)
- unsigned nm;
- {
- register o, m, b;
-
- m = abs();
- if (!*ms)
- return(m);
- do {
- m = who();
- while (o = what()) {
- b = where(nm);
- switch (o) {
- case '+':
- nm |= b & m;
- break;
- case '-':
- nm &= ~(b & m);
- break;
- case '=':
- nm &= ~m;
- nm |= b & m;
- break;
- }
- }
- } while (*ms++ == ',');
- if (*--ms) {
- fprintf(stderr, "chmod: invalid mode\n");
- exit(255);
- }
- return(nm);
- }
-
- abs()
- {
- register c, i;
-
- i = 0;
- while ((c = *ms++) >= '0' && c <= '7')
- i = (i << 3) + (c - '0');
- ms--;
- return(i);
- }
-
- who()
- {
- register m;
-
- m = 0;
- for (;;) switch (*ms++) {
- case 'u':
- m |= USER;
- continue;
- case 'g':
- m |= GROUP;
- continue;
- case 'o':
- m |= OTHER;
- continue;
- case 'a':
- m |= ALL;
- continue;
- default:
- ms--;
- if (m == 0)
- m = ALL & ~um;
- return m;
- }
- }
-
- what()
- {
- switch (*ms) {
- case '+':
- case '-':
- case '=':
- return *ms++;
- }
- return(0);
- }
-
- where(om)
- register om;
- {
- register m;
-
- m = 0;
- switch (*ms) {
- case 'u':
- m = (om & USER) >> 6;
- goto dup;
- case 'g':
- m = (om & GROUP) >> 3;
- goto dup;
- case 'o':
- m = (om & OTHER);
- dup:
- m &= (READ|WRITE|EXEC);
- m |= (m << 3) | (m << 6);
- ++ms;
- return m;
- }
- for (;;) switch (*ms++) {
- case 'r':
- m |= READ;
- continue;
- case 'w':
- m |= WRITE;
- continue;
- case 'x':
- m |= EXEC;
- continue;
- case 's':
- m |= SETID;
- continue;
- case 't':
- m |= STICKY;
- continue;
- default:
- ms--;
- return m;
- }
- }
-