2 Mode Muncher -- modemuncher.c
6 [ME monchen, perh. influenced by MF mangier to eat --more at MANGER]
7 :to chew with a crunching sound: eat with relish
8 :to chew food with a crunching sound: eat food with relish
11 The NeXT Digital Edition of Webster's Ninth New Collegiate Dictionary
12 and Webster's Collegiate Thesaurus
15 /* struct for rwx <-> POSIX constant lookup tables */
22 typedef struct modeLookup modeLookup
;
24 static modeLookup modesel
[] =
26 /* RWX char Posix Constant */
38 {(char)NULL
, (mode_t
)-1} /* do not delete this line */
43 static int rwxrwxrwx(mode_t
*mode
, const char *p
)
46 mode_t tmp_mode
= *mode
;
48 tmp_mode
&= ~(S_ISUID
| S_ISGID
); /* turn off suid and sgid flags */
49 for (count
=0; count
<9; count
++)
51 if (*p
== modesel
[count
].rwx
) tmp_mode
|= modesel
[count
].bits
; /* set a bit */
52 else if (*p
== '-') tmp_mode
&= ~modesel
[count
].bits
; /* clear a bit */
53 else if (*p
=='s') switch(count
)
55 case 2: /* turn on suid flag */
56 tmp_mode
|= S_ISUID
| S_IXUSR
;
59 case 5: /* turn on sgid flag */
60 tmp_mode
|= S_ISGID
| S_IXGRP
;
64 return -4; /* failed! -- bad rwxrwxrwx mode change */
73 static void modechopper(mode_t mode
, char *p
)
75 /* requires char p[10] */
81 for (count
=0; count
<9; count
++)
83 if (mode
& modesel
[count
].bits
) *p
= modesel
[count
].rwx
;
88 *p
=0; /* to finish the string */
90 /* dealing with suid and sgid flags */
91 if (mode
& S_ISUID
) pp
[2] = (mode
& S_IXUSR
) ? 's' : 'S';
92 if (mode
& S_ISGID
) pp
[5] = (mode
& S_IXGRP
) ? 's' : 'S';
96 static int mode_munch(mode_t
*mode
, const char* p
)
100 mode_t affected_bits
, ch_mode
;
107 modechopper(*mode
, tmp
);
108 printf("modemuncher: got base mode = %s\n", tmp
);
113 /* step 0 -- clear temporary variables */
117 /* step 1 -- who's affected? */
120 printf("modemuncher step 1\n");
123 /* mode string given in rwxrwxrwx format */
124 if (*p
== 'r' || *p
== '-') return rwxrwxrwx(mode
, p
);
126 /* mode string given in ugoa+-=rwx format */
131 affected_bits
|= 04700;
135 affected_bits
|= 02070;
139 affected_bits
|= 01007;
143 affected_bits
|= 07777;
152 goto no_more_affected
;
156 /* If none specified, affect all bits. */
157 if (affected_bits
== 0) affected_bits
= 07777;
159 /* step 2 -- how is it changed? */
162 printf("modemuncher step 2 (*p='%c')\n", *p
);
178 return -1; /* failed! -- bad operator */
182 /* step 3 -- what are the changes? */
185 printf("modemuncher step 3\n");
188 for (p
++ ; *p
!=0 ; p
++)
204 /* Set the setuid/gid bits if `u' or `g' is selected. */
217 /* step 4 -- apply the changes */
220 printf("modemuncher step 4\n");
222 if (*p
!= ',') doneFlag
= 1;
223 if (*p
!= 0 && *p
!= ' ' && *p
!= ',')
227 printf("modemuncher: comma error!\n");
228 printf("modemuncher: doneflag = %u\n", doneFlag
);
230 return -2; /* failed! -- bad mode change */
234 /*if (!ch_mode) return -2;*/ /* failed! -- bad mode change */
235 if (ch_mode
) switch (op
)
238 *mode
= *mode
|= ch_mode
& affected_bits
;
242 *mode
= *mode
&= ~(ch_mode
& affected_bits
);
246 *mode
= ch_mode
& affected_bits
;
250 return -3; /* failed! -- unknown error */
254 modechopper(*mode
, tmp
);
255 printf("modemuncher: returning mode = %s\n", tmp
);
258 return 0; /* successful call */