ferry@htsa.uucp (Ferry Rietveld) (01/24/89)
When I received my Minix (1.2) from P-H (about 1 year after ordering !!)suprisingly it did not support a symbolic chmod , which I find more appealing
then using octal [ 8-( ] numbers . So i decided to write one myself.
And here it is !!!
o / cut here
---------x----------------------------------------------------------------
o \
/*
** usage : chmod mode files ...
** mode -> OctalInt | Symbolic .
** Symbolic -> [who] op perm {[op] perm} { ',' [who] op perm {[op] perm} }
** who -> 'u' | 'g' | 'o' .
** op -> '+' | '-' | '=' .
** perm -> 'r' | 'w' | 'x' | 's' | 't' .
**
** Written by Ferry Rietveld
** date 01-15-89 .
*/
#ifdef unix
#include <sys/types.h>
#include <sys/stat.h>
#define prints(x,y) printf(x,y)
#else
#include <stat.h>
#endif
#include <stdio.h>
#include <ctype.h>
#define AND '-'
#define OR '+'
#define IS '='
#define rwx(q) in(q,"rwx")
#define rwxst(q) in(q,"rwxst")
int OrMode = 0 , AndMode = 07777 ;
main (argc, argv)
int argc;
char **argv;
{
int i, fiddle = 0, count = 0 , step, Mode ;
struct stat fstat ;
if (argc < 3) Usage ();
if( isdigit(argv[1][0]) ) Mode = intmode (argv[1]);
else fiddle = 1 ; /* fool around with | and & & flags */
for (i = 2; i < argc; i++) {
OrMode = 0 , AndMode = 07777 ;
if (stat(argv[i],&fstat) < 0) {
prints("Chmod : can't stat %s\n",argv[i]);
count++;
}
else {
step = 0 ;
if (fiddle) {
do { /* Here there is no way back,
** change the old mode.
*/
OrMode = 0 ; AndMode = 07777 ;
step=Set_flags(argv[1],step) ;
fstat.st_mode = fstat.st_mode & AndMode ;
fstat.st_mode |= OrMode ;
} while (step!=0) ;
Mode = fstat.st_mode ;
}
if (chmod (argv[i], Mode) < 0) {
prints("Chmod : can't change %s\n",argv[i]);
count++;
}
}
}
exit (count);
}
/*
** Parse the flag string and set the apropriate bits
*/
Set_flags(mode,i)
char *mode;
int i ;
{
int usr= -1, grp= -1, otr= -1, flag = 1, op;
while (mode[i]) {
switch (mode[i++]) { /* First char */
case 'a' : break ;
case 'u' : usr = 6 ; flag=0 ; break ;
case 'g' : grp = 3 ; flag=0 ; break ;
case 'o' : otr = 0 ; flag=0 ; break ;
case '+' : /* Same as - */ ;
case '-' : /* Same as = */ ;
case '=' : if (flag) { usr=6;grp=3;otr=0; } ;
i-- ; /* miner designer fault */
while (in(mode[i],"+-=")) {
op = mode[i++] ;
while (rwxst(mode[i])) {
Bit_rwx(mode[i],usr,op) ;
Bit_rwx(mode[i],grp,op) ;
Bit_rwx(mode[i++],otr,op) ;
}
}
usr = grp = otr = -1 ;
flag = 1 ;
break ;
case ',' : return ( i ) ;
default : Usage() ;
}
}
return ( 0 ) ;
} /* Set_flags */
/*
** Set up the mask for setting or clearing a single bit
*/
Bit_rwx(c,shift,UpDown)
char c;
int shift, UpDown;
{
if (shift==-1) return ;
if (UpDown==OR) {
switch(c) {
case 'r': shift++ ;
case 'w': shift++ ;
case 'x': OrMode |= (001<<shift) ; break;
case 's': if (shift) OrMode |=(01000<<shift/3);
else Usage() ;
break;
case 't': if (!shift) OrMode |=(01000<<shift/3);
else Usage() ;
break;
}
return ;
}
if (UpDown==AND) {
switch(c) {
case 'r': shift++ ;
case 'w': shift++ ;
case 'x': AndMode &= ~(0001<<shift) ; break;
case 's': if (shift) AndMode &= ~(01000<<shift/3);
else Usage() ;
break;
case 't': if (!shift) AndMode &= ~(01000<<shift/3);
else Usage() ;
break;
} /* switch */
return ;
}
/*
** For securety reasons UMASK should be taken into account
** for the next setting of a bit
*/
switch(c) {
case 'r': OrMode |= (0004<<shift) ; break;
case 'w': OrMode |= (0002<<shift) ; break;
case 'x': OrMode |= (0001<<shift) ; break;
}
AndMode &= ~(0007<<shift) ;
}
int intmode (Octs)
char *Octs;
{
int c, i=0;
while ((c = *Octs++) >= '0' && c <= '7')
i = (i<<3) + (c - '0');
if (c != '\0') Usage ();
return (i);
}
Usage () {
#ifdef unix
prints ("Usage: Chmod [ugoa] [+-=] [rwxst] file ...\n","");
#else
prints ("Usage: Chmod [ugoa] [+-=] [rwxst] file ...\n");
#endif
exit (255);
}
/*
** A simple IN set test
*/
int in(c,str)
char c, *str;
{
while ( *str ) if (*str++==c) return (1) ;
return (0) ;
}
__________________________________________________________________________
Ferry Rietveld. AHA - TMF
mail : ...hp4nl!htsa!ferry Europaboulevard 23
tel : 020 -446586 1079 PC Amsterdam.
--------------------------------------------------------------------------