home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume21 / rh2 / part01 / rhdir.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-03-21  |  6.7 KB  |  298 lines

  1.  
  2. /* ----------------------------------------------------------------------
  3.  * FILE: rhdir.c
  4.  * VERSION: 2
  5.  * Written by: Ken Stauffer
  6.  * This file contains the "non portable" stuff dealing with
  7.  * directories.
  8.  * printentry(), ftrw(), fwt1()
  9.  *
  10.  *
  11.  * ---------------------------------------------------------------------- */
  12.  
  13. #include "rh.h"
  14. #include <sys/types.h>
  15. #include <sys/stat.h>
  16.  
  17. #define user_index(b)    ((000777 & (b)) >> 6) + ((b) & S_ISUID ? 8 : 0) 
  18. #define group_index(b)    ((000077 & b) >> 3) + ((b) & S_ISGID ? 8 : 0)
  19. #define all_index(b)    ((000007 & (b)) + (((b) & S_ISVTX) ? 8 : 0))
  20. #define ftype_index(b)    ((b) >> 13)
  21.  
  22. #define isdirect(b)    (((b)&S_IFMT)==S_IFDIR)
  23. #define isblk(b)    (((b)&S_IFMT)==S_IFBLK)
  24. #define ischr(b)    (((b)&S_IFMT)==S_IFCHR)
  25.  
  26. /*
  27.  * Some System do not define these macro's.
  28.  * If these macro's are missing, then use these ones:
  29.  *
  30.  * #define major(b)    ((b)>>8)
  31.  * #define minor(b)    ((b)&0xff)
  32.  *
  33.  */
  34.  
  35. #define isdot(s)    ((s)[1]=='\0' && (s)[0]=='.')
  36. #define isdotdot(s)    ((s)[2]=='\0' && (s)[1]=='.' && (s)[0]=='.')
  37.  
  38. #ifdef S_IFLNK
  39. #define islink(b)    (((b)&S_IFMT) == S_IFLNK)
  40. #else
  41. #define islink(b)    (0)
  42. #define    lstat        stat
  43. #endif
  44.  
  45. #define isproper(m)    (isdirect(m) && !islink(m) && !attr.prune)
  46.  
  47. #ifdef    POSIX_DIRECTORY_LIBRARY
  48. #include <dirent.h>
  49. #else
  50. #include <sys/dir.h>
  51. #endif
  52.  
  53. /*
  54.  * XXX - on BSD systems, this is defined in <sys/param.h>.
  55.  * On System V Release 3, it's defined inside "nami.c", and is,
  56.  * unfortunately, not in any include file.
  57.  * On systems other than those, no such simple limit exists.
  58.  * On BSD and S5R3 systems, as distributed by Berkeley and AT&T,
  59.  * respectively, it's 1024, so we set it to that.
  60.  */
  61. #define    MAXPATHLEN    1024
  62.  
  63. /* ----------------------------------------------------------------------
  64.  * printentry:
  65.  *    Display filename,permissions and size in a '/bin/ls' like
  66.  *    format. If verbose is non-zero then more information is
  67.  *    displayed.
  68.  * uses the macros:
  69.  *    user_index(b)
  70.  *    group_index(b)
  71.  *    all_index(b)
  72.  *    ftype_index(b)
  73.  *
  74.  */
  75.  
  76. printentry(verbose,buf,name)
  77. struct stat *buf;
  78. char *name;
  79. {
  80.     char *t,*ctime();
  81.  
  82.     static char *ftype[]={ "p", "c" , 
  83.                    "d" , "b" ,  
  84.                    "-" , "l" , 
  85.                    "s" , "t" };
  86.  
  87.     static char *perm[]={ "---", "--x", "-w-", "-wx" ,
  88.                   "r--", "r-x", "rw-", "rwx" ,
  89.                   "--S", "--s", "-wS", "-ws" ,
  90.                   "r-S", "r-s", "rwS", "rws" };
  91.  
  92.     static char *perm2[]={ "---", "--x", "-w-", "-wx" ,
  93.                   "r--", "r-x", "rw-", "rwx" ,
  94.                   "--T", "--t", "-wT", "-wt" ,
  95.                   "r-T", "r-t", "rwT", "rwt" };
  96.  
  97.     if( verbose ) {
  98.         t = ctime(&buf->st_mtime);
  99.         t[24] = '\0';
  100.         if( ischr(buf->st_mode) || isblk(buf->st_mode) )
  101.  
  102.             printf("%s%s%s%s %4d %4d %3d,%3d %s %-s\n",
  103.                 ftype[ ftype_index(buf->st_mode) ],
  104.                 perm[ user_index(buf->st_mode) ],
  105.                 perm[ group_index(buf->st_mode) ],
  106.                 perm2[ all_index(buf->st_mode) ],
  107.                 buf->st_uid,
  108.                 buf->st_gid,
  109.                 major(buf->st_rdev),
  110.                 minor(buf->st_rdev),
  111.                 t+4,
  112.                 name );
  113.  
  114.         else
  115.  
  116.             printf("%s%s%s%s %4d %4d %6d %s %-s\n",
  117.                 ftype[ ftype_index(buf->st_mode) ],
  118.                 perm[ user_index(buf->st_mode) ],
  119.                 perm[ group_index(buf->st_mode) ],
  120.                 perm2[ all_index(buf->st_mode) ],
  121.                 buf->st_uid,
  122.                 buf->st_gid,
  123.                 buf->st_size,
  124.                 t+4,
  125.                 name );
  126.  
  127.     } else {
  128.  
  129.         if( ischr(buf->st_mode) || isblk(buf->st_mode) )
  130.  
  131.             printf("%s%s%s%s %3d,%3d %-s\n",
  132.                 ftype[ ftype_index(buf->st_mode) ],
  133.                 perm[ user_index(buf->st_mode) ],
  134.                 perm[ group_index(buf->st_mode) ],
  135.                 perm2[ all_index(buf->st_mode) ],
  136.                 major(buf->st_rdev),
  137.                 minor(buf->st_rdev),
  138.                 name );
  139.  
  140.         else
  141.  
  142.             printf("%s%s%s%s %9d %-s\n",
  143.                 ftype[ ftype_index(buf->st_mode) ],
  144.                 perm[ user_index(buf->st_mode) ],
  145.                 perm[ group_index(buf->st_mode) ],
  146.                 perm2[ all_index(buf->st_mode) ],
  147.                 buf->st_size,
  148.                 name );
  149.  
  150.     }
  151. }
  152.  
  153. /* ----------------------------------------------------------------------
  154.  * ftrw:
  155.  *    Entry point to do the search, ftrw is a front end
  156.  *    to the recursive fwt1.
  157.  *    ftrw() initializes some global variables and
  158.  *    builds the initial filename string which is passed to
  159.  *    ftw1().
  160.  */
  161.  
  162. ftrw(f,fn,depth)
  163. char *f;
  164. int (*fn)();
  165. int depth;
  166. {
  167.     char *p,filebuf[ MAXPATHLEN+1 ];
  168.     struct stat statbuf;
  169.     int last;
  170.  
  171.     attr.prune = 0;
  172.     attr.depth = 0;
  173.     attr.func=fn;
  174.     attr.fname = filebuf;
  175.     attr.buf = &statbuf;
  176.     strcpy(attr.fname,f);
  177.  
  178.     last = 0;
  179.     for(p=attr.fname; *p; p++)
  180.         if( *p == '/' ) last = 1;
  181.         else last = 0;
  182.  
  183.     if( !last ) { *p++ = '/'; *p = '\0'; }
  184.  
  185.     if( lstat(attr.fname,attr.buf) < 0 ) return(-1);
  186.  
  187.     (*(attr.func))();
  188.  
  189.     if( isproper( attr.buf->st_mode ) ) fwt1(depth,p);
  190.  
  191.     return(0);
  192. }
  193.  
  194. /* ----------------------------------------------------------------------
  195.  * fwt1:
  196.  *    'p' points to the end of the string in attr.fname
  197.  *
  198.  *    2 versions of this routine currently live here:
  199.  *    "new-style", for systems with a BSD or POSIX-style
  200.  *    directory library, and systems without such a
  201.  *    directory library. They both differ in
  202.  *    the manner in which they access directories.
  203.  *    Any chnages needed to work on another system
  204.  *    should only have to made for this routine.
  205.  *
  206.  *    Below is the "directory library" version of fwt1()
  207.  *
  208.  */
  209.  
  210. #if defined(POSIX_DIRECTORY_LIBRARY) || defined(BSD)
  211.  
  212. static fwt1(depth,p)
  213. int depth;
  214. char *p;
  215. {
  216.     char *q,*s;
  217.     DIR *dirp;
  218. #ifdef POSIX_DIRECTORY_LIBRARY
  219.     struct dirent *dp;
  220. #else
  221.     struct direct *dp;
  222. #endif
  223.     if( !depth ) return;
  224.     attr.depth += 1;
  225.  
  226.     dirp=opendir(attr.fname);
  227.     if( dirp == NULL ) return;
  228.     for(dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
  229.         if( isdot(dp->d_name) || isdotdot(dp->d_name) ) continue;
  230.         s = p;
  231.         q = dp->d_name;
  232.         while( *s++ = *q++ );
  233.         s -= 1;
  234.         if( lstat(attr.fname,attr.buf) < 0 ) continue;
  235.         (*(attr.func))();
  236.         if( isproper( attr.buf->st_mode ) ) {
  237.             *s++ = '/';
  238.             *s = '\0';
  239.             fwt1(depth-1,s);
  240.         }
  241.     }
  242.     closedir(dirp);
  243.     attr.depth -= 1;
  244.     attr.prune = 0;
  245.     *p = '\0';
  246. }
  247. #else
  248.  
  249. /* ----------------------------------------------------------------------
  250.  * fwt1:
  251.  *    This function does the same thing as fwt1() above, but is
  252.  *    meant for systems without a directory library, that does
  253.  *    directory reading "by hand".
  254.  *
  255.  *    Below is the "no directory library" version of fwt1()
  256.  *
  257.  */
  258.  
  259. static fwt1(depth,p)
  260. int depth;
  261. char *p;
  262. {
  263.     char *q,*s;
  264.     FILE *dirp;
  265.     struct direct dp;
  266.     int count;
  267.  
  268.     if( !depth ) return;
  269.     attr.depth += 1;
  270.  
  271.     dirp=fopen(attr.fname,"r");
  272.     if( dirp == NULL ) return;
  273.     for(count = fread(&dp,sizeof(struct direct),1,dirp); count;
  274.         count = fread(&dp,sizeof(struct direct),1,dirp) ) {
  275.  
  276.         if( isdot(dp.d_name) || isdotdot(dp.d_name) || dp.d_ino==0 )
  277.             continue;
  278.         s = p;
  279.         q = dp.d_name;
  280.         while( *s++ = *q++ ); 
  281.         s -= 1;
  282.  
  283.         if( lstat(attr.fname,attr.buf) < 0 ) continue;
  284.         (*(attr.func))();
  285.         if( isproper( attr.buf->st_mode ) ) {
  286.             *s++ = '/';
  287.             *s = '\0';
  288.             fwt1(depth-1,s);
  289.         }
  290.     }
  291.     fclose(dirp);
  292.     attr.depth -= 1;
  293.     attr.prune = 0;
  294.     *p = '\0';
  295. }
  296.  
  297. #endif
  298.