home *** CD-ROM | disk | FTP | other *** search
- /*
- * checkmode.c -- check file modes
- *
- * Copyright (C) 1990 Philip L. Budne
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 1, or (at your option)
- * any later version.
- *
- */
-
- # ifndef lint
- static char *rcsid = "$Id: checkmode.c,v 3.0 90/07/06 13:10:25 budd Rel $";
- static char Copyright[] = "Copyright (C) 1990 Philip L. Budne";
- # endif /* lint not defined */
-
- # include <sys/types.h>
- # include <sys/stat.h>
- # include <stdio.h>
-
- # define EOS '\0'
-
- # ifndef S_IRUSR /* sigh */
- # define S_IRUSR 0000400 /* read permission, owner */
- # define S_IWUSR 0000200 /* write permission, owner */
- # define S_IXUSR 0000100 /* execute/search permission, owner */
- # define S_IRGRP 0000040 /* read permission, group */
- # define S_IWGRP 0000020 /* write permission, grougroup */
- # define S_IXGRP 0000010 /* execute/search permission, group */
- # define S_IROTH 0000004 /* read permission, other */
- # define S_IWOTH 0000002 /* write permission, other */
- # define S_IXOTH 0000001 /* execute/search permission, other */
- # endif /* S_IRUSR not defined */
-
- # define USER (S_IRUSR|S_IWUSR|S_IXUSR|S_ISUID)
- # define GROUP (S_IRGRP|S_IWGRP|S_IXGRP|S_ISGID)
- # define OTHER (S_IROTH|S_IWOTH|S_IXOTH)
-
- # define READ (S_IRUSR|S_IRGRP|S_IROTH)
- # define WRITE (S_IWUSR|S_IWGRP|S_IWOTH)
- # define EXEC (S_IXUSR|S_IXGRP|S_IXOTH)
-
- # define SET (S_ISUID|S_ISGID)
-
- # define OCTAL(c) ((c) >= '0' && (c) <= '7')
-
- int thing(), thing1();
- void bad();
- char *cp;
-
- void
- usage() {
- fprintf( stderr, "Usage checkmode file mode_mask [bits_set]\n" );
- exit( 1 );
- }
-
- int
- main( c, v )
- int c;
- char **v;
- {
- int mask, bits;
- char op;
- struct stat st;
-
- if( c < 2 || c > 4 )
- usage();
-
- mask = thing( v[2] );
- if( c == 3 )
- bits = mask;
- else
- bits = thing( v[3] );
-
- if( *cp == '+' || *cp == '-' )
- op = *cp++;
- else
- op = '+';
-
- if( stat( v[1], &st ) < 0 ) {
- perror( v[1] );
- exit( 2 );
- }
-
- if( (st.st_mode & mask) == bits )
- exit( 0 );
- puts("nope");
- exit( 1 );
- } /* main */
-
- # define PEEK (*cp)
- # define NEXT (*cp++)
-
- int
- thing( p )
- char *p;
- {
- int m;
-
- cp = p;
-
- m = thing1();
- while( PEEK == '+' || PEEK == '-' ) {
- if( NEXT == '+' )
- m |= thing1(); /* add bits */
- else
- m &= ~thing1(); /* remove bits */
- }
- if( PEEK )
- bad();
- return( m );
- } /* thing */
-
- int
- thing1() {
- int m;
-
- if( OCTAL(PEEK) ) {
- m = 0;
- do
- m = (m<<3) | NEXT - '0';
- while( OCTAL(PEEK) );
- return( m );
- }
-
- switch( PEEK ) {
- case 'u':
- m = USER;
- NEXT;
- break;
- case 'g':
- m = GROUP;
- NEXT;
- break;
- case 'o':
- m = OTHER;
- NEXT;
- break;
- # ifdef S_ISVTX
- case 't':
- NEXT;
- return( S_ISVTX );
- # endif /* S_ISVTX defined */
- default:
- m = USER|GROUP|OTHER;
- break;
- }
-
- switch( PEEK ) {
- case 'r':
- m &= READ;
- break;
- case 'w':
- m &= WRITE;
- break;
- case 'x':
- m &= EXEC;
- break;
- case 's':
- m &= SET;
- break;
- case EOS:
- return( m );
- default:
- bad();
- }
- NEXT;
- return( m );
- }
-
- void
- bad() {
- fprintf( stderr, "Bad character in mode '%c'\n", PEEK );
- usage();
- }
-