home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume25 / finger / part02 / checkmode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-03  |  3.1 KB  |  177 lines

  1. /*
  2.  * checkmode.c -- check file modes
  3.  *
  4.  * Copyright (C) 1990 Philip L. Budne
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 1, or (at your option)
  9.  * any later version.
  10.  *
  11.  */
  12.  
  13. # ifndef lint
  14. static char *rcsid = "$Id: checkmode.c,v 3.0 90/07/06 13:10:25 budd Rel $";
  15. static char Copyright[] = "Copyright (C) 1990 Philip L. Budne";
  16. # endif /* lint not defined */
  17.  
  18. # include <sys/types.h>
  19. # include <sys/stat.h>
  20. # include <stdio.h>
  21.  
  22. # define EOS '\0'
  23.  
  24. # ifndef S_IRUSR            /* sigh */
  25. # define S_IRUSR 0000400        /* read permission, owner */
  26. # define S_IWUSR 0000200        /* write permission, owner */
  27. # define S_IXUSR 0000100        /* execute/search permission, owner */
  28. # define S_IRGRP 0000040        /* read permission, group */
  29. # define S_IWGRP 0000020        /* write permission, grougroup */
  30. # define S_IXGRP 0000010        /* execute/search permission, group */
  31. # define S_IROTH 0000004        /* read permission, other */
  32. # define S_IWOTH 0000002        /* write permission, other */
  33. # define S_IXOTH 0000001        /* execute/search permission, other */
  34. # endif /* S_IRUSR not defined */
  35.  
  36. # define USER    (S_IRUSR|S_IWUSR|S_IXUSR|S_ISUID)
  37. # define GROUP    (S_IRGRP|S_IWGRP|S_IXGRP|S_ISGID)
  38. # define OTHER    (S_IROTH|S_IWOTH|S_IXOTH)
  39.  
  40. # define READ    (S_IRUSR|S_IRGRP|S_IROTH)
  41. # define WRITE    (S_IWUSR|S_IWGRP|S_IWOTH)
  42. # define EXEC    (S_IXUSR|S_IXGRP|S_IXOTH)
  43.  
  44. # define SET    (S_ISUID|S_ISGID)
  45.  
  46. # define OCTAL(c) ((c) >= '0' && (c) <= '7')
  47.  
  48. int thing(), thing1();
  49. void bad();
  50. char *cp;
  51.  
  52. void
  53. usage() {
  54.     fprintf( stderr, "Usage checkmode file mode_mask [bits_set]\n" );
  55.     exit( 1 );
  56. }
  57.  
  58. int
  59. main( c, v )
  60.     int c;
  61.     char **v;
  62. {
  63.     int mask, bits;
  64.     char op;
  65.     struct stat st;
  66.  
  67.     if( c < 2 || c > 4 )
  68.     usage();
  69.  
  70.     mask = thing( v[2] );
  71.     if( c == 3 )
  72.     bits = mask;
  73.     else
  74.     bits = thing( v[3] );
  75.  
  76.     if( *cp == '+' || *cp == '-' )
  77.     op = *cp++;
  78.     else
  79.     op = '+';
  80.  
  81.     if( stat( v[1], &st ) < 0 ) {
  82.     perror( v[1] );
  83.     exit( 2 );
  84.     }
  85.  
  86.     if( (st.st_mode & mask) == bits )
  87.     exit( 0 );
  88.     puts("nope");
  89.     exit( 1 );
  90. } /* main */
  91.  
  92. # define PEEK (*cp)
  93. # define NEXT (*cp++)
  94.  
  95. int
  96. thing( p )
  97.     char *p;
  98. {
  99.     int m;
  100.  
  101.     cp = p;
  102.  
  103.     m = thing1();
  104.     while( PEEK == '+' || PEEK == '-' ) {
  105.     if( NEXT == '+' )
  106.         m |= thing1();        /* add bits */
  107.     else
  108.         m &= ~thing1();        /* remove bits */
  109.     }
  110.     if( PEEK )
  111.     bad();
  112.     return( m );
  113. } /* thing */
  114.  
  115. int
  116. thing1() {
  117.     int m;
  118.  
  119.     if( OCTAL(PEEK) ) {
  120.     m = 0;
  121.     do
  122.         m = (m<<3) | NEXT - '0';
  123.     while( OCTAL(PEEK) );
  124.     return( m );
  125.     }
  126.  
  127.     switch( PEEK ) {
  128.     case 'u':
  129.     m = USER;
  130.     NEXT;
  131.     break;
  132.     case 'g':
  133.     m = GROUP;
  134.     NEXT;
  135.     break;
  136.     case 'o':
  137.     m = OTHER;
  138.     NEXT;
  139.     break;
  140. # ifdef S_ISVTX
  141.     case 't':
  142.     NEXT;
  143.     return( S_ISVTX );
  144. # endif /* S_ISVTX defined */
  145.     default:
  146.     m = USER|GROUP|OTHER;
  147.     break;
  148.     }
  149.  
  150.     switch( PEEK ) {
  151.     case 'r':
  152.     m &= READ;
  153.     break;
  154.     case 'w':
  155.     m &= WRITE;
  156.     break;
  157.     case 'x':
  158.     m &= EXEC;
  159.     break;
  160.     case 's':
  161.     m &= SET;
  162.     break;
  163.     case EOS:
  164.     return( m );
  165.     default:
  166.     bad();
  167.     }
  168.     NEXT;
  169.     return( m );
  170. }
  171.  
  172. void
  173. bad() {
  174.     fprintf( stderr, "Bad character in mode '%c'\n", PEEK );
  175.     usage();
  176. }
  177.