home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / chmod.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-01-10  |  2.4 KB  |  178 lines

  1. /*
  2.  * chmod [ugoa][+-=][rwxstugo] files
  3.  *  change mode of files
  4.  */
  5. #include <stdio.h>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8.  
  9. #define    USER    05700    /* user's bits */
  10. #define    GROUP    02070    /* group's bits */
  11. #define    OTHER    00007    /* other's bits */
  12. #define    ALL    01777    /* all (note absence of setuid, etc) */
  13.  
  14. #define    READ    00444    /* read permit */
  15. #define    WRITE    00222    /* write permit */
  16. #define    EXEC    00111    /* exec permit */
  17. #define    SETID    06000    /* set[ug]id */
  18. #define    STICKY    01000    /* sticky bit */
  19.  
  20. char    *ms;
  21. int    um;
  22. struct    stat st;
  23.  
  24. main(argc,argv)
  25. char **argv;
  26. {
  27.     register i;
  28.     register char *p;
  29.     int status = 0;
  30.  
  31.     if (argc < 3) {
  32.         fprintf(stderr, "Usage: chmod [ugoa][+-=][rwxstugo] file ...\n");
  33.         exit(255);
  34.     }
  35.     ms = argv[1];
  36.     um = umask(0);
  37.     newmode(0);
  38.     for (i = 2; i < argc; i++) {
  39.         p = argv[i];
  40.         if (stat(p, &st) < 0) {
  41.             fprintf(stderr, "chmod: can't access %s\n", p);
  42.             ++status;
  43.             continue;
  44.         }
  45.         ms = argv[1];
  46.         if (chmod(p, newmode(st.st_mode)) < 0) {
  47.             fprintf(stderr, "chmod: can't change %s\n", p);
  48.             ++status;
  49.             continue;
  50.         }
  51.     }
  52.     exit(status);
  53. }
  54.  
  55. newmode(nm)
  56. unsigned nm;
  57. {
  58.     register o, m, b;
  59.  
  60.     m = abs();
  61.     if (!*ms)
  62.         return(m);
  63.     do {
  64.         m = who();
  65.         while (o = what()) {
  66.             b = where(nm);
  67.             switch (o) {
  68.             case '+':
  69.                 nm |= b & m;
  70.                 break;
  71.             case '-':
  72.                 nm &= ~(b & m);
  73.                 break;
  74.             case '=':
  75.                 nm &= ~m;
  76.                 nm |= b & m;
  77.                 break;
  78.             }
  79.         }
  80.     } while (*ms++ == ',');
  81.     if (*--ms) {
  82.         fprintf(stderr, "chmod: invalid mode\n");
  83.         exit(255);
  84.     }
  85.     return(nm);
  86. }
  87.  
  88. abs()
  89. {
  90.     register c, i;
  91.  
  92.     i = 0;
  93.     while ((c = *ms++) >= '0' && c <= '7')
  94.         i = (i << 3) + (c - '0');
  95.     ms--;
  96.     return(i);
  97. }
  98.  
  99. who()
  100. {
  101.     register m;
  102.  
  103.     m = 0;
  104.     for (;;) switch (*ms++) {
  105.     case 'u':
  106.         m |= USER;
  107.         continue;
  108.     case 'g':
  109.         m |= GROUP;
  110.         continue;
  111.     case 'o':
  112.         m |= OTHER;
  113.         continue;
  114.     case 'a':
  115.         m |= ALL;
  116.         continue;
  117.     default:
  118.         ms--;
  119.         if (m == 0)
  120.             m = ALL & ~um;
  121.         return m;
  122.     }
  123. }
  124.  
  125. what()
  126. {
  127.     switch (*ms) {
  128.     case '+':
  129.     case '-':
  130.     case '=':
  131.         return *ms++;
  132.     }
  133.     return(0);
  134. }
  135.  
  136. where(om)
  137. register om;
  138. {
  139.     register m;
  140.  
  141.     m = 0;
  142.     switch (*ms) {
  143.     case 'u':
  144.         m = (om & USER) >> 6;
  145.         goto dup;
  146.     case 'g':
  147.         m = (om & GROUP) >> 3;
  148.         goto dup;
  149.     case 'o':
  150.         m = (om & OTHER);
  151.     dup:
  152.         m &= (READ|WRITE|EXEC);
  153.         m |= (m << 3) | (m << 6);
  154.         ++ms;
  155.         return m;
  156.     }
  157.     for (;;) switch (*ms++) {
  158.     case 'r':
  159.         m |= READ;
  160.         continue;
  161.     case 'w':
  162.         m |= WRITE;
  163.         continue;
  164.     case 'x':
  165.         m |= EXEC;
  166.         continue;
  167.     case 's':
  168.         m |= SETID;
  169.         continue;
  170.     case 't':
  171.         m |= STICKY;
  172.         continue;
  173.     default:
  174.         ms--;
  175.         return m;
  176.     }
  177. }
  178.