|
|
1.1 ! root 1: /* ! 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: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #if defined(LIBC_SCCS) && !defined(lint) ! 21: static char sccsid[] = "@(#)setmode.c 5.3 (Berkeley) 6/1/90"; ! 22: #endif /* LIBC_SCCS and not lint */ ! 23: ! 24: #include <sys/types.h> ! 25: #include <sys/stat.h> ! 26: #include <errno.h> ! 27: #include <stdio.h> ! 28: ! 29: #define setbits set[0] ! 30: #define clrbits set[1] ! 31: #define Xbits set[2] ! 32: ! 33: mode_t ! 34: getmode(set, omode) ! 35: mode_t *set, omode; ! 36: { ! 37: register mode_t newmode; ! 38: ! 39: newmode = omode & clrbits; ! 40: newmode |= setbits; ! 41: if (omode & (S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH)) ! 42: newmode |= Xbits; ! 43: return(newmode); ! 44: } ! 45: ! 46: #define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) ! 47: #define CLR(a) { clrbits |= a; setbits &= ~(a); Xbits &= ~(a); } ! 48: ! 49: mode_t * ! 50: setmode(p) ! 51: register char *p; ! 52: { ! 53: extern int errno; ! 54: register int perm, who; ! 55: register char op; ! 56: mode_t mask, *set; ! 57: int permXbits; ! 58: char *malloc(); ! 59: ! 60: /* ! 61: * get a copy of the mask for the permissions that are mask ! 62: * relative. Flip the bits, we want what's not set. ! 63: */ ! 64: (void)umask(mask = umask(0)); ! 65: mask = ~mask; ! 66: ! 67: if (!(set = (mode_t *)malloc((u_int)(sizeof(mode_t) * 3)))) { ! 68: errno = ENOMEM; ! 69: return(NULL); ! 70: } ! 71: ! 72: setbits = clrbits = Xbits = 0; ! 73: ! 74: /* ! 75: * if an absolute number, get it and return; disallow non-octal ! 76: * digits or illegal bits. ! 77: */ ! 78: if (isdigit(*p)) { ! 79: setbits = (mode_t)strtol(p, (char **)0, 8); ! 80: clrbits = ~(STANDARD_BITS|S_ISTXT); ! 81: Xbits = 0; ! 82: while (*++p) ! 83: if (*p < '0' || *p > '7') ! 84: return(NULL); ! 85: if (setbits & clrbits) ! 86: return(NULL); ! 87: return(set); ! 88: } ! 89: ! 90: if (!*p) ! 91: return(NULL); ! 92: /* ! 93: * accumulate bits to add and subtract from each clause of ! 94: * the symbolic mode ! 95: */ ! 96: for (;;) { ! 97: for (who = 0;; ++p) ! 98: switch (*p) { ! 99: case 'a': ! 100: who |= STANDARD_BITS; ! 101: break; ! 102: case 'u': ! 103: who |= S_ISUID|S_IRWXU; ! 104: break; ! 105: case 'g': ! 106: who |= S_ISGID|S_IRWXG; ! 107: break; ! 108: case 'o': ! 109: who |= S_IRWXO; ! 110: break; ! 111: default: ! 112: goto getop; ! 113: } ! 114: ! 115: getop: if ((op = *p++) != '+' && op != '-' && op != '=') ! 116: return(NULL); ! 117: ! 118: who &= ~S_ISTXT; ! 119: for (perm = 0;; ++p) ! 120: switch (*p) { ! 121: case 'r': ! 122: perm |= S_IRUSR|S_IRGRP|S_IROTH; ! 123: break; ! 124: case 's': ! 125: /* if only "other" bits ignore set-id */ ! 126: if (who & ~S_IRWXO) ! 127: perm |= S_ISUID|S_ISGID; ! 128: break; ! 129: case 't': ! 130: /* if only "other" bits ignore sticky */ ! 131: if (who & ~S_IRWXO) { ! 132: who |= S_ISTXT; ! 133: perm |= S_ISTXT; ! 134: } ! 135: break; ! 136: case 'w': ! 137: perm |= S_IWUSR|S_IWGRP|S_IWOTH; ! 138: break; ! 139: case 'X': ! 140: permXbits = S_IXUSR|S_IXGRP|S_IXOTH; ! 141: break; ! 142: case 'x': ! 143: perm |= S_IXUSR|S_IXGRP|S_IXOTH; ! 144: break; ! 145: default: ! 146: goto apply; ! 147: } ! 148: ! 149: apply: switch(op) { ! 150: case '+': ! 151: /* ! 152: * If no perm value, skip. If no who value, use umask ! 153: * bits. Don't bother clearing any bits, getmode ! 154: * clears first, then sets. ! 155: */ ! 156: if (perm || permXbits) { ! 157: if (!who) ! 158: who = mask; ! 159: if (permXbits) ! 160: Xbits |= who & permXbits; ! 161: setbits |= who & perm; ! 162: } ! 163: break; ! 164: case '-': ! 165: /* ! 166: * If no perm value, skip. If no who value, use ! 167: * owner, group, and other. ! 168: */ ! 169: if (perm) { ! 170: if (!who) ! 171: who = S_IRWXU|S_IRWXG|S_IRWXO; ! 172: CLR(who & perm); ! 173: } ! 174: break; ! 175: case '=': ! 176: /* ! 177: * If no who value, clear all the bits. Otherwise, ! 178: * clear the bits specified by who. ! 179: */ ! 180: if (!who) { ! 181: CLR(STANDARD_BITS); ! 182: who = mask; ! 183: } else ! 184: CLR(who); ! 185: if (perm) ! 186: setbits |= who & perm; ! 187: break; ! 188: } ! 189: ! 190: if (!*p) ! 191: break; ! 192: if (*p != ',') ! 193: goto getop; ! 194: ++p; ! 195: } ! 196: clrbits = ~clrbits; ! 197: return(set); ! 198: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.