home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume18 / rh / rhdir.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-23  |  5.4 KB  |  246 lines

  1.  
  2. /* ----------------------------------------------------------------------
  3.  * FILE: rhdir.c
  4.  * (c) 1989 Ken Stauffer
  5.  * This file contains the "non portable" stuff dealing with
  6.  * directories.
  7.  * printentry(), ftw(), ftw1()
  8.  *
  9.  *
  10.  * ---------------------------------------------------------------------- */
  11.  
  12. #include "rh.h"
  13. #include <sys/types.h>
  14. #include <sys/stat.h>
  15.  
  16. #define user_index(b)    ((000777 & b) >> 6) + (b & S_ISUID ? 8 : 0) 
  17. #define group_index(b)    ((000077 & b) >> 3) + (b & S_ISGID ? 8 : 0)
  18. #define all_index(b)    ((000007 & b) + ((b & S_ISVTX) ? 8 : 0))
  19. #define ftype_index(b)    (b >> 13)
  20.  
  21. #define isdirect(b)    ((b&S_IFMT)==S_IFDIR)
  22.  
  23. #if SUN
  24.  
  25. #include <dirent.h>
  26. #define MAXPATHLEN    255
  27. #define islink(b)    ((b & S_IFLNK) == S_IFLNK)
  28. #define isproper(m)    ( isdirect(m) && !(((m)&S_IFLNK)==S_IFLNK) )
  29.  
  30. #endif
  31.  
  32. #if BSD
  33.  
  34. #include <sys/dir.h>
  35. #define MAXPATHLEN    255
  36. #define islink(b)    ((b & S_IFLNK) == S_IFLNK)
  37. #define isproper(m)    ( isdirect(m) && !(((m)&S_IFLNK)==S_IFLNK) )
  38.  
  39. #endif
  40.  
  41. #if XENIX || SYSV
  42.  
  43. #include <sys/dir.h>
  44. #define MAXPATHLEN    255
  45. #define islink(b)    (0)
  46. #define isproper(m)    isdirect(m)
  47. #define lstat        stat
  48.  
  49. #endif
  50.  
  51.  
  52. static int (*func)();
  53. static char filename[ MAXPATHLEN ];
  54.  
  55. /* ----------------------------------------------------------------------
  56.  * printentry:
  57.  *    Display filename,permissions and size in a '/bin/ls' like
  58.  *    format. Examines the dasha variable to see if more
  59.  *    info should be printed.
  60.  * uses the macros:
  61.  *    user_index(b)
  62.  *    group_index(b)
  63.  *    all_index(b)
  64.  *    ftype_index(b)
  65.  *
  66.  */
  67.  
  68. printentry(buf,name)
  69. struct stat *buf;
  70. char *name;
  71. {
  72.     char *t,*ctime();
  73.  
  74.     static char *ftype[]={ "p", "c" , 
  75.                    "d" , "b" ,  
  76.                    "-" , "l" , 
  77.                    "s" , "t" };
  78.  
  79.     static char *perm[]={ "---", "--x", "-w-", "-wx" ,
  80.                   "r--", "r-x", "rw-", "rwx" ,
  81.                   "--S", "--s", "-wS", "-ws" ,
  82.                   "r-S", "r-s", "rwS", "rws" };
  83.  
  84.     static char *perm2[]={ "---", "--x", "-w-", "-wx" ,
  85.                   "r--", "r-x", "rw-", "rwx" ,
  86.                   "--T", "--t", "-wT", "-wt" ,
  87.                   "r-T", "r-t", "rwT", "rwt" };
  88.  
  89.     if( dasha ) {
  90.         t = ctime(&buf->st_mtime);
  91.         t[24] = '\0';
  92.         printf("%s%s%s%s %4d %4d %6d %s %-s\n",
  93.             ftype[ ftype_index(buf->st_mode) ],
  94.             perm[ user_index(buf->st_mode) ],
  95.             perm[ group_index(buf->st_mode) ],
  96.             perm2[ all_index(buf->st_mode) ],
  97.             buf->st_uid,
  98.             buf->st_gid,
  99.             buf->st_size,
  100.             t+4,
  101.             name );
  102.     } else {
  103.         printf("%s%s%s%s %9d %-s\n",
  104.             ftype[ ftype_index(buf->st_mode) ],
  105.             perm[ user_index(buf->st_mode) ],
  106.             perm[ group_index(buf->st_mode) ],
  107.             perm2[ all_index(buf->st_mode) ],
  108.             buf->st_size,
  109.             name );
  110.     }
  111. }
  112.  
  113. /* ----------------------------------------------------------------------
  114.  * ftw:
  115.  *    Entry point to do the search, ftw is a front end
  116.  *    to the recursive fwt1.
  117.  *    ftw() places some of the arguments to global variables
  118.  *    so that they arguments would not have to be passed around to
  119.  *    ftw1().
  120.  *
  121.  */
  122.  
  123. ftw(f,fn,depth)
  124. char *f;
  125. int (*fn)();
  126. int depth;
  127. {
  128.     char *p;
  129.     struct stat statbuf;
  130.     int i;
  131.  
  132.     strcpy(filename,f);
  133.     if( filename[ strlen(filename)-1 ] != '/' ) {
  134.         filename[ strlen(f) ] = '/';
  135.         filename[ strlen(f)+1 ] = '\0';
  136.     }
  137.     func=fn;
  138.     
  139.     if( lstat(f,&statbuf) < 0 ) return(-1);
  140.  
  141.     (*func)(f,&statbuf);
  142.  
  143.     if( isproper( statbuf.st_mode ) ) fwt1(depth);
  144.  
  145.     return(0);
  146. }
  147.  
  148. /* ----------------------------------------------------------------------
  149.  * fwt1:
  150.  *    2 versions of this routine currently live here:
  151.  *    XENIX/SYSV, and SUN/BSD. They both differ in
  152.  *    the manner in which they access directories.
  153.  *    Any chnages needed to work on another system
  154.  *    should only have to made for this routine.
  155.  *
  156.  *    Below is the SUN/BSD version of fwt1()
  157.  *    --------------------------------------
  158.  *
  159.  */
  160.  
  161. #if SUN || BSD
  162.  
  163. static fwt1(depth)
  164. int depth;
  165. {
  166.  
  167. #if SUN
  168.     DIR *dirp;
  169.     struct dirent *dp;
  170. #else
  171.     DIR *dirp;
  172.     struct direct *dp;
  173. #endif
  174.     char *basep;
  175.     struct stat statbuf;
  176.  
  177.     if( !depth ) return;
  178.     basep=filename+strlen(filename);
  179.  
  180.     dirp=opendir(filename);
  181.     if( dirp == NULL ) return;
  182.     for(dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
  183.         if( dp->d_name[0]=='.' && dp->d_name[1]=='\0' ) continue;
  184.         if( dp->d_name[0]=='.' && dp->d_name[1]=='.' &&
  185.             dp->d_name[2]=='\0' ) continue;
  186.         strcpy(basep,dp->d_name);
  187.         if( lstat(filename,&statbuf) < 0 ) continue;
  188.         (*func)(filename,&statbuf);
  189.         if( isproper( statbuf.st_mode ) ) {
  190.             basep[ strlen(dp->d_name) ] = '/';
  191.             basep[ strlen(dp->d_name)+1 ] = '\0';
  192.             fwt1(depth-1);
  193.         }
  194.     }
  195.     closedir(dirp);
  196.     *basep = '\0';
  197. }
  198. #endif
  199.  
  200. /* ----------------------------------------------------------------------
  201.  * ftw1:
  202.  *    This function does the samething as ftw1() above, but is
  203.  *    meant for XENIX/SYSV type systems that do directory reading
  204.  *    "by hand"
  205.  *
  206.  *    Below is the XENIX/SYSV version of fwt1()
  207.  *    --------------------------------------
  208.  */
  209.  
  210. #if XENIX || SYSV
  211.  
  212. static fwt1(depth)
  213. int depth;
  214. {
  215.     char *basep;
  216.     FILE *dirp;
  217.     struct direct dp;
  218.     struct stat statbuf;
  219.     int count;
  220.  
  221.     if( !depth ) return;
  222.  
  223.     basep=filename+strlen(filename);
  224.     dirp=fopen(filename,"r");
  225.     if( dirp == NULL ) return;
  226.     for(count = fread(&dp,sizeof(struct direct),1,dirp); count;
  227.         count = fread(&dp,sizeof(struct direct),1,dirp) ) {
  228.  
  229.         if( dp.d_name[0]=='.' && dp.d_name[1]=='\0' ) continue;
  230.         if( dp.d_name[0]=='.' && dp.d_name[1]=='.' &&
  231.             dp.d_name[2]=='\0' ) continue;
  232.         strcpy(basep,dp.d_name);
  233.         if( lstat(filename,&statbuf) < 0 ) continue;
  234.         (*func)(filename,&statbuf);
  235.         if( isproper( statbuf.st_mode ) ) {
  236.             basep[ strlen(dp.d_name) ] = '/';
  237.             basep[ strlen(dp.d_name)+1 ] = '\0';
  238.             fwt1(depth-1);
  239.         }
  240.     }
  241.     fclose(dirp);
  242.     *basep = '\0';
  243. }
  244.  
  245. #endif
  246.