static int mode_munch(mode_t *mode, const char* p) { char op=0; mode_t affected_bits, ch_mode; int doneFlag = 0; #ifdef DEBUG char tmp[10]; #endif #ifdef DEBUG modechopper(*mode, tmp); printf("modemuncher: got base mode = %s\n", tmp); #endif while (!doneFlag) { /* step 0 -- clear temporary variables */ affected_bits=0; ch_mode=0; /* step 1 -- who's affected? */ #ifdef DEBUG printf("modemuncher step 1\n"); #endif /* mode string given in rwxrwxrwx format */ if (*p== 'r' || *p == '-') return rwxrwxrwx(mode, p); /* mode string given in ugoa+-=rwx format */ for ( ; ; p++) switch (*p) { case 'u': affected_bits |= 04700; break; case 'g': affected_bits |= 02070; break; case 'o': affected_bits |= 01007; break; case 'a': affected_bits |= 07777; break; /* ignore spaces */ case ' ': break; default: goto no_more_affected; } no_more_affected: /* If none specified, affect all bits. */ if (affected_bits == 0) affected_bits = 07777; /* step 2 -- how is it changed? */ #ifdef DEBUG printf("modemuncher step 2 (*p='%c')\n", *p); #endif switch (*p) { case '+': case '-': case '=': op = *p; break; /* ignore spaces */ case ' ': break; default: return -1; /* failed! -- bad operator */ } /* step 3 -- what are the changes? */ #ifdef DEBUG printf("modemuncher step 3\n"); #endif for (p++ ; *p!=0 ; p++) switch (*p) { case 'r': ch_mode |= 00444; break; case 'w': ch_mode |= 00222; break; case 'x': ch_mode |= 00111; break; case 's': /* Set the setuid/gid bits if `u' or `g' is selected. */ ch_mode |= 06000; break; /* ignore spaces */ case ' ': break; default: goto specs_done; } specs_done: /* step 4 -- apply the changes */ #ifdef DEBUG printf("modemuncher step 4\n"); #endif if (*p != ',') doneFlag = 1; if (*p != 0 && *p != ' ' && *p != ',') { #ifdef DEBUG printf("modemuncher: comma error!\n"); printf("modemuncher: doneflag = %u\n", doneFlag); #endif return -2; /* failed! -- bad mode change */ } p++; /*if (!ch_mode) return -2;*/ /* failed! -- bad mode change */ if (ch_mode) switch (op) { case '+': *mode |= ch_mode & affected_bits; break; case '-': *mode &= ~(ch_mode & affected_bits); break; case '=': *mode = ch_mode & affected_bits; break; default: return -3; /* failed! -- unknown error */ } } #ifdef DEBUG modechopper(*mode, tmp); printf("modemuncher: returning mode = %s\n", tmp); #endif return 0; /* successful call */ }
static int mode_munch(mode_t *mode, const char* p) { char op=0; mode_t affected_bits, ch_mode; int done = 0; while (!done) { /* step 0 -- clear temporary variables */ affected_bits=0; ch_mode=0; /* step 1 -- who's affected? */ /* mode string given in rwxrwxrwx format */ if (*p== 'r' || *p == '-') return rwxrwxrwx(mode, p); /* mode string given in ugoa+-=rwx format */ for ( ; ; p++) switch (*p) { case 'u': affected_bits |= 04700; break; case 'g': affected_bits |= 02070; break; case 'o': affected_bits |= 01007; break; case 'a': affected_bits |= 07777; break; case ' ': /* ignore spaces */ break; default: goto no_more_affected; } no_more_affected: /* If none specified, affect all bits. */ if (affected_bits == 0) affected_bits = 07777; /* step 2 -- how is it changed? */ switch (*p) { case '+': case '-': case '=': op = *p; break; case ' ': /* ignore spaces */ break; default: return -1; /* failed! -- bad operator */ } /* step 3 -- what are the changes? */ for (p++ ; *p!=0 ; p++) switch (*p) { case 'r': ch_mode |= 00444; break; case 'w': ch_mode |= 00222; break; case 'x': ch_mode |= 00111; break; case 's': /* Set the setuid/gid bits if `u' or `g' is selected. */ ch_mode |= 06000; break; case ' ': /* ignore spaces */ break; default: goto specs_done; } specs_done: /* step 4 -- apply the changes */ if (*p != ',') done = 1; if (*p != 0 && *p != ' ' && *p != ',') return -2; /* failed! -- bad mode change */ p++; if (ch_mode) switch (op) { case '+': *mode |= ch_mode & affected_bits; break; case '-': *mode &= ~(ch_mode & affected_bits); break; case '=': *mode = ch_mode & affected_bits; break; default: return -3; /* failed! -- unknown error */ } } return 0; /* successful call */ }