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. --------------------------------------------------------------------------