home *** CD-ROM | disk | FTP | other *** search
-
- /* ----------------------------------------------------------------------
- * FILE: rhdir.c
- * (c) 1989 Ken Stauffer
- * This file contains the "non portable" stuff dealing with
- * directories.
- * printentry(), ftw(), ftw1()
- *
- *
- * ---------------------------------------------------------------------- */
-
- #include "rh.h"
- #include <sys/types.h>
- #include <sys/stat.h>
-
- #define user_index(b) ((000777 & b) >> 6) + (b & S_ISUID ? 8 : 0)
- #define group_index(b) ((000077 & b) >> 3) + (b & S_ISGID ? 8 : 0)
- #define all_index(b) ((000007 & b) + ((b & S_ISVTX) ? 8 : 0))
- #define ftype_index(b) (b >> 13)
-
- #define isdirect(b) ((b&S_IFMT)==S_IFDIR)
-
- #if SUN
-
- #include <dirent.h>
- #define MAXPATHLEN 255
- #define islink(b) ((b & S_IFLNK) == S_IFLNK)
- #define isproper(m) ( isdirect(m) && !(((m)&S_IFLNK)==S_IFLNK) )
-
- #endif
-
- #if BSD
-
- #include <sys/dir.h>
- #define MAXPATHLEN 255
- #define islink(b) ((b & S_IFLNK) == S_IFLNK)
- #define isproper(m) ( isdirect(m) && !(((m)&S_IFLNK)==S_IFLNK) )
-
- #endif
-
- #if XENIX || SYSV
-
- #include <sys/dir.h>
- #define MAXPATHLEN 255
- #define islink(b) (0)
- #define isproper(m) isdirect(m)
- #define lstat stat
-
- #endif
-
-
- static int (*func)();
- static char filename[ MAXPATHLEN ];
-
- /* ----------------------------------------------------------------------
- * printentry:
- * Display filename,permissions and size in a '/bin/ls' like
- * format. Examines the dasha variable to see if more
- * info should be printed.
- * uses the macros:
- * user_index(b)
- * group_index(b)
- * all_index(b)
- * ftype_index(b)
- *
- */
-
- printentry(buf,name)
- struct stat *buf;
- char *name;
- {
- char *t,*ctime();
-
- static char *ftype[]={ "p", "c" ,
- "d" , "b" ,
- "-" , "l" ,
- "s" , "t" };
-
- static char *perm[]={ "---", "--x", "-w-", "-wx" ,
- "r--", "r-x", "rw-", "rwx" ,
- "--S", "--s", "-wS", "-ws" ,
- "r-S", "r-s", "rwS", "rws" };
-
- static char *perm2[]={ "---", "--x", "-w-", "-wx" ,
- "r--", "r-x", "rw-", "rwx" ,
- "--T", "--t", "-wT", "-wt" ,
- "r-T", "r-t", "rwT", "rwt" };
-
- if( dasha ) {
- t = ctime(&buf->st_mtime);
- t[24] = '\0';
- printf("%s%s%s%s %4d %4d %6d %s %-s\n",
- ftype[ ftype_index(buf->st_mode) ],
- perm[ user_index(buf->st_mode) ],
- perm[ group_index(buf->st_mode) ],
- perm2[ all_index(buf->st_mode) ],
- buf->st_uid,
- buf->st_gid,
- buf->st_size,
- t+4,
- name );
- } else {
- printf("%s%s%s%s %9d %-s\n",
- ftype[ ftype_index(buf->st_mode) ],
- perm[ user_index(buf->st_mode) ],
- perm[ group_index(buf->st_mode) ],
- perm2[ all_index(buf->st_mode) ],
- buf->st_size,
- name );
- }
- }
-
- /* ----------------------------------------------------------------------
- * ftw:
- * Entry point to do the search, ftw is a front end
- * to the recursive fwt1.
- * ftw() places some of the arguments to global variables
- * so that they arguments would not have to be passed around to
- * ftw1().
- *
- */
-
- ftw(f,fn,depth)
- char *f;
- int (*fn)();
- int depth;
- {
- char *p;
- struct stat statbuf;
- int i;
-
- strcpy(filename,f);
- if( filename[ strlen(filename)-1 ] != '/' ) {
- filename[ strlen(f) ] = '/';
- filename[ strlen(f)+1 ] = '\0';
- }
- func=fn;
-
- if( lstat(f,&statbuf) < 0 ) return(-1);
-
- (*func)(f,&statbuf);
-
- if( isproper( statbuf.st_mode ) ) fwt1(depth);
-
- return(0);
- }
-
- /* ----------------------------------------------------------------------
- * fwt1:
- * 2 versions of this routine currently live here:
- * XENIX/SYSV, and SUN/BSD. They both differ in
- * the manner in which they access directories.
- * Any chnages needed to work on another system
- * should only have to made for this routine.
- *
- * Below is the SUN/BSD version of fwt1()
- * --------------------------------------
- *
- */
-
- #if SUN || BSD
-
- static fwt1(depth)
- int depth;
- {
-
- #if SUN
- DIR *dirp;
- struct dirent *dp;
- #else
- DIR *dirp;
- struct direct *dp;
- #endif
- char *basep;
- struct stat statbuf;
-
- if( !depth ) return;
- basep=filename+strlen(filename);
-
- dirp=opendir(filename);
- if( dirp == NULL ) return;
- for(dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
- if( dp->d_name[0]=='.' && dp->d_name[1]=='\0' ) continue;
- if( dp->d_name[0]=='.' && dp->d_name[1]=='.' &&
- dp->d_name[2]=='\0' ) continue;
- strcpy(basep,dp->d_name);
- if( lstat(filename,&statbuf) < 0 ) continue;
- (*func)(filename,&statbuf);
- if( isproper( statbuf.st_mode ) ) {
- basep[ strlen(dp->d_name) ] = '/';
- basep[ strlen(dp->d_name)+1 ] = '\0';
- fwt1(depth-1);
- }
- }
- closedir(dirp);
- *basep = '\0';
- }
- #endif
-
- /* ----------------------------------------------------------------------
- * ftw1:
- * This function does the samething as ftw1() above, but is
- * meant for XENIX/SYSV type systems that do directory reading
- * "by hand"
- *
- * Below is the XENIX/SYSV version of fwt1()
- * --------------------------------------
- */
-
- #if XENIX || SYSV
-
- static fwt1(depth)
- int depth;
- {
- char *basep;
- FILE *dirp;
- struct direct dp;
- struct stat statbuf;
- int count;
-
- if( !depth ) return;
-
- basep=filename+strlen(filename);
- dirp=fopen(filename,"r");
- if( dirp == NULL ) return;
- for(count = fread(&dp,sizeof(struct direct),1,dirp); count;
- count = fread(&dp,sizeof(struct direct),1,dirp) ) {
-
- if( dp.d_name[0]=='.' && dp.d_name[1]=='\0' ) continue;
- if( dp.d_name[0]=='.' && dp.d_name[1]=='.' &&
- dp.d_name[2]=='\0' ) continue;
- strcpy(basep,dp.d_name);
- if( lstat(filename,&statbuf) < 0 ) continue;
- (*func)(filename,&statbuf);
- if( isproper( statbuf.st_mode ) ) {
- basep[ strlen(dp.d_name) ] = '/';
- basep[ strlen(dp.d_name)+1 ] = '\0';
- fwt1(depth-1);
- }
- }
- fclose(dirp);
- *basep = '\0';
- }
-
- #endif
-