home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / fileutil / rh / rhdir.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-13  |  8.7 KB  |  369 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. #ifdef MSDOS
  18. #define user_index(b)   ((000700 & (b)) >> 6)
  19. #define dos_index(b)    (000007 & (b))
  20. #else
  21. #define user_index(b)   ((000700 & (b)) >> 6) + ((b) & S_ISUID ? 8 : 0)
  22. #define group_index(b)  ((000070 & b) >> 3) + ((b) & S_ISGID ? 8 : 0)
  23. #define all_index(b)    ((000007 & (b)) + (((b) & S_ISVTX) ? 8 : 0))
  24. #endif
  25.  
  26. #define ftype_index(b)    ((b) >> 13)
  27.  
  28. #define isdirect(b)    (((b)&S_IFMT)==S_IFDIR)
  29. #define isblk(b)    (((b)&S_IFMT)==S_IFBLK)
  30. #define ischr(b)    (((b)&S_IFMT)==S_IFCHR)
  31.  
  32. /*
  33.  * Some System do not define these macro's.
  34.  * If these macro's are missing, then use these ones:
  35.  *
  36.  * #define major(b)    ((b)>>8)
  37.  * #define minor(b)    ((b)&0xff)
  38.  *
  39.  */
  40.  
  41. #define isdot(s)    ((s)[1]=='\0' && (s)[0]=='.')
  42. #define isdotdot(s)    ((s)[2]=='\0' && (s)[1]=='.' && (s)[0]=='.')
  43.  
  44. #ifdef S_IFLNK
  45. #define islink(b)    (((b)&S_IFMT) == S_IFLNK)
  46. #else
  47. #define islink(b)    (0)
  48. #ifndef MSDOS
  49. #define    lstat        stat
  50. #endif
  51. #endif
  52.  
  53. #define isproper(m)    (isdirect(m) && !islink(m) && !attr.prune)
  54.  
  55. #ifdef    POSIX_DIRECTORY_LIBRARY
  56. #include <dirent.h>
  57. #else
  58. #include <sys/dir.h>
  59. #endif
  60.  
  61. #ifdef MSDOS
  62. int lstat(char *name, struct stat *buf)
  63. {
  64.   int rc;
  65.  
  66.   if ( rc = stat(name, buf) )
  67.     return rc;
  68.  
  69.   buf -> st_mode &= ~000077;
  70.  
  71.   if ( strcmp(name, ".") )
  72.   {
  73.     rc = getfmode(name);
  74.  
  75.     if ( rc & 0x04 )
  76.       buf -> st_mode |= S_ISYS;
  77.     if ( rc & 0x02 )
  78.       buf -> st_mode |= S_IHID;
  79.     if ( rc & 0x20 )
  80.       buf -> st_mode |= S_IMOD;
  81.   }
  82.  
  83.   return 0;
  84. }
  85. #endif
  86.  
  87. /*
  88.  * XXX - on BSD systems, this is defined in <sys/param.h>.
  89.  * On System V Release 3, it's defined inside "nami.c", and is,
  90.  * unfortunately, not in any include file.
  91.  * On systems other than those, no such simple limit exists.
  92.  * On BSD and S5R3 systems, as distributed by Berkeley and AT&T,
  93.  * respectively, it's 1024, so we set it to that.
  94.  */
  95. #define    MAXPATHLEN    1024
  96.  
  97. /* ----------------------------------------------------------------------
  98.  * printentry:
  99.  *    Display filename,permissions and size in a '/bin/ls' like
  100.  *    format. If verbose is non-zero then more information is
  101.  *    displayed.
  102.  * uses the macros:
  103.  *    user_index(b)
  104.  *    group_index(b)
  105.  *    all_index(b)
  106.  *    ftype_index(b)
  107.  *
  108.  */
  109.  
  110. printentry(verbose,buf,name)
  111. struct stat *buf;
  112. char *name;
  113. {
  114.     char *t,*ctime();
  115.  
  116.     static char *ftype[]={ "p", "c" ,
  117.                    "d" , "b" ,
  118.                    "-" , "l" ,
  119.                    "s" , "t" };
  120.  
  121.     static char *perm[]={ "---", "--x", "-w-", "-wx" ,
  122.                   "r--", "r-x", "rw-", "rwx" ,
  123.                   "--S", "--s", "-wS", "-ws" ,
  124.                   "r-S", "r-s", "rwS", "rws" };
  125.  
  126.     static char *perm2[]={ "---", "--x", "-w-", "-wx" ,
  127.                   "r--", "r-x", "rw-", "rwx" ,
  128.                   "--T", "--t", "-wT", "-wt" ,
  129.                   "r-T", "r-t", "rwT", "rwt" };
  130.  
  131. #ifdef MSDOS
  132.         static char *perm_dos[]={ "---", "--m", "-h-", "-hm" ,
  133.                               "s--", "s-m", "sh-", "shm" };
  134. #endif
  135.  
  136.     if( verbose ) {
  137.         t = ctime(&buf->st_mtime);
  138.                 t[24] = '\0';
  139.  
  140. #ifndef MSDOS
  141.                 if( ischr(buf->st_mode) || isblk(buf->st_mode) )
  142.                         printf("%s%s%s%s %4d %4d %3d,%3d %s %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_uid,
  148.                 buf->st_gid,
  149.                 major(buf->st_rdev),
  150.                 minor(buf->st_rdev),
  151.                 t+4,
  152.                 name );
  153.  
  154.         else
  155. #endif
  156. #ifdef MSDOS
  157.                         printf("%s%s%s %9ld %s %s\n",
  158.                                 ftype[ ftype_index(buf->st_mode) ],
  159.                 perm[ user_index(buf->st_mode) ],
  160.                                 perm_dos[ dos_index(buf->st_mode) ],
  161. #else
  162.                         printf("%s%s%s%s %4d %4d %9ld %s %s\n",
  163.                                 ftype[ ftype_index(buf->st_mode) ],
  164.                 perm[ user_index(buf->st_mode) ],
  165.                 perm[ group_index(buf->st_mode) ],
  166.                 perm2[ all_index(buf->st_mode) ],
  167.                 buf->st_uid,
  168.                 buf->st_gid,
  169. #endif
  170.                 buf->st_size,
  171.                 t+4,
  172.                                 name );
  173.  
  174.     } else {
  175.  
  176. #ifndef MSDOS
  177.         if( ischr(buf->st_mode) || isblk(buf->st_mode) )
  178.  
  179.                         printf("%s%s%s%s %3d,%3d %s\n",
  180.                 ftype[ ftype_index(buf->st_mode) ],
  181.                 perm[ user_index(buf->st_mode) ],
  182.                 perm[ group_index(buf->st_mode) ],
  183.                 perm2[ all_index(buf->st_mode) ],
  184.                 major(buf->st_rdev),
  185.                 minor(buf->st_rdev),
  186.                 name );
  187.  
  188.         else
  189. #endif
  190. #ifdef MSDOS
  191.                         printf("%s%s%s %9ld %s\n",
  192.                 ftype[ ftype_index(buf->st_mode) ],
  193.                 perm[ user_index(buf->st_mode) ],
  194.                                 perm_dos[ dos_index(buf->st_mode) ],
  195. #else
  196.                         printf("%s%s%s%s %9ld %s\n",
  197.                 ftype[ ftype_index(buf->st_mode) ],
  198.                 perm[ user_index(buf->st_mode) ],
  199.                 perm[ group_index(buf->st_mode) ],
  200.                                 perm2[ all_index(buf->st_mode) ],
  201. #endif
  202.                 buf->st_size,
  203.                 name );
  204.  
  205.     }
  206. }
  207.  
  208. /* ----------------------------------------------------------------------
  209.  * ftrw:
  210.  *    Entry point to do the search, ftrw is a front end
  211.  *    to the recursive fwt1.
  212.  *    ftrw() initializes some global variables and
  213.  *    builds the initial filename string which is passed to
  214.  *    ftw1().
  215.  */
  216.  
  217. ftrw(f,fn,depth)
  218. char *f;
  219. int (*fn)();
  220. int depth;
  221. {
  222.     char *p,filebuf[ MAXPATHLEN+1 ];
  223.     struct stat statbuf;
  224.     int last;
  225.  
  226.     attr.prune = 0;
  227.     attr.depth = 0;
  228.     attr.func=fn;
  229.     attr.fname = filebuf;
  230.     attr.buf = &statbuf;
  231.     strcpy(attr.fname,f);
  232.  
  233.     last = 0;
  234.     for(p=attr.fname; *p; p++)
  235.         if( *p == '/' ) last = 1;
  236.         else last = 0;
  237.  
  238. #ifndef MSDOS
  239.     if( !last ) { *p++ = '/'; *p = '\0'; }
  240. #endif
  241.  
  242.     if( lstat(attr.fname,attr.buf) < 0 ) return(-1);
  243.  
  244.     (*(attr.func))();
  245.  
  246.     if( isproper( attr.buf->st_mode ) ) fwt1(depth,p);
  247.  
  248.     return(0);
  249. }
  250.  
  251. /* ----------------------------------------------------------------------
  252.  * fwt1:
  253.  *    'p' points to the end of the string in attr.fname
  254.  *
  255.  *    2 versions of this routine currently live here:
  256.  *    "new-style", for systems with a BSD or POSIX-style
  257.  *    directory library, and systems without such a
  258.  *    directory library. They both differ in
  259.  *    the manner in which they access directories.
  260.  *    Any chnages needed to work on another system
  261.  *    should only have to made for this routine.
  262.  *
  263.  *    Below is the "directory library" version of fwt1()
  264.  *
  265.  */
  266.  
  267. #if defined(POSIX_DIRECTORY_LIBRARY) || defined(BSD) || defined(MSDOS)
  268.  
  269. static fwt1(depth,p)
  270. int depth;
  271. char *p;
  272. {
  273.     char *q,*s;
  274.     DIR *dirp;
  275. #ifdef POSIX_DIRECTORY_LIBRARY
  276.     struct dirent *dp;
  277. #else
  278.     struct direct *dp;
  279. #endif
  280.         int current;
  281.  
  282.     if( !depth ) return;
  283.     attr.depth += 1;
  284.  
  285.         dirp=opendir(attr.fname);
  286.         current = (strcmp(attr.fname, ".") == 0);
  287.  
  288.     if( dirp == NULL ) return;
  289.     for(dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
  290.                 if( isdot(dp->d_name) || isdotdot(dp->d_name) ) continue;
  291.                 if ( current )
  292.                   s = attr.fname;
  293.                 else
  294.                 {
  295.                   s = p;
  296. #ifdef MSDOS
  297.                   *s++ = '/';
  298. #endif
  299.                 }
  300.         q = dp->d_name;
  301.         while( *s++ = *q++ );
  302.         s -= 1;
  303.         if( lstat(attr.fname,attr.buf) < 0 ) continue;
  304.         (*(attr.func))();
  305.         if( isproper( attr.buf->st_mode ) ) {
  306. #ifndef MSDOS
  307.                         *s++ = '/';
  308. #endif
  309.             *s = '\0';
  310.             fwt1(depth-1,s);
  311.         }
  312.     }
  313.     closedir(dirp);
  314.     attr.depth -= 1;
  315.     attr.prune = 0;
  316.     *p = '\0';
  317. }
  318. #else
  319.  
  320. /* ----------------------------------------------------------------------
  321.  * fwt1:
  322.  *    This function does the same thing as fwt1() above, but is
  323.  *    meant for systems without a directory library, that does
  324.  *    directory reading "by hand".
  325.  *
  326.  *    Below is the "no directory library" version of fwt1()
  327.  *
  328.  */
  329.  
  330. static fwt1(depth,p)
  331. int depth;
  332. char *p;
  333. {
  334.     char *q,*s;
  335.     FILE *dirp;
  336.     struct direct dp;
  337.     int count;
  338.  
  339.     if( !depth ) return;
  340.     attr.depth += 1;
  341.  
  342.     dirp=fopen(attr.fname,"r");
  343.     if( dirp == NULL ) return;
  344.     for(count = fread(&dp,sizeof(struct direct),1,dirp); count;
  345.         count = fread(&dp,sizeof(struct direct),1,dirp) ) {
  346.  
  347.         if( isdot(dp.d_name) || isdotdot(dp.d_name) || dp.d_ino==0 )
  348.             continue;
  349.         s = p;
  350.         q = dp.d_name;
  351.         while( *s++ = *q++ );
  352.         s -= 1;
  353.  
  354.         if( lstat(attr.fname,attr.buf) < 0 ) continue;
  355.         (*(attr.func))();
  356.         if( isproper( attr.buf->st_mode ) ) {
  357.             *s++ = '/';
  358.             *s = '\0';
  359.             fwt1(depth-1,s);
  360.         }
  361.     }
  362.     fclose(dirp);
  363.     attr.depth -= 1;
  364.     attr.prune = 0;
  365.     *p = '\0';
  366. }
  367.  
  368. #endif
  369.