home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Mint / mntlib32.zoo / ftw.c < prev    next >
C/C++ Source or Header  |  1992-09-05  |  3KB  |  115 lines

  1. /*
  2. **  FTW
  3. **  Walk a directory hierarchy from a given point, calling a user-supplied
  4. **  function at each thing we find.  If we go below a specified depth,
  5. **  recycle file descriptors.
  6. */
  7.  
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <stdlib.h>
  11. #include <types.h>
  12. #include <stat.h>
  13. #ifdef __TURBOC__
  14. #include <sys\dir.h>
  15. #else
  16. #include <sys/dir.h>
  17. #endif
  18. #include <ftw.h>
  19.  
  20. #define EQ(a, b)    (strcmp((a), (b)) == 0)
  21.  
  22. int
  23. ftw(directory, funcptr, depth)
  24.     char         *directory;
  25.     int            (*funcptr) __PROTO((char *, struct stat *, int));
  26.     int              depth;
  27. {
  28.     register DIR     *dirp;
  29.     struct direct     *entp;
  30.     struct stat          stats;
  31.     register char     *p;
  32.     register long      i;
  33. #ifndef __MINT__
  34.     long          seekpoint;
  35. #endif
  36.     char         *fullpath;
  37.  
  38. #ifndef __MINT__
  39.     seekpoint = 0;    /* avoid spurious warning from gcc -Wall */
  40. #endif
  41.  
  42.     /* If can't stat, tell the user so. */
  43.     if (stat(directory, &stats) < 0)
  44.     return (*funcptr)(directory, &stats, FTW_NS);
  45.  
  46.     /* If it's not a directory, call the user's function. */
  47.     if ((stats.st_mode & S_IFMT) != S_IFDIR)
  48.     /* Saying "FTW_F" here is lying; what if this is a symlink? */
  49.     return (*funcptr)(directory, &stats, FTW_F);
  50.  
  51.     /* Open directory; if we can't, tell the user so. */
  52.     dirp = opendir(directory);
  53.     if (dirp == NULL)
  54.     return (*funcptr)(directory, &stats, FTW_DNR);
  55.  
  56.     /* See if user wants to go further. */
  57.     i = (*funcptr)(directory, &stats, FTW_D);
  58.     if (i) {
  59.     closedir(dirp);
  60.     return (int)i;
  61.     }
  62.  
  63.     /* Get ready to hold the full paths. */
  64.     i = strlen(directory);
  65.     fullpath = (char *) malloc( (size_t) (i + 1 + MAXNAMLEN + 1) );
  66.     if (fullpath == NULL) {
  67.     closedir(dirp);
  68.     return -1;
  69.     }
  70.     (void)strcpy(fullpath, directory);
  71.     p = &fullpath[i];
  72.     if (i && p[-1] != '/')
  73.     *p++ = '/';
  74.  
  75.     /* Read all entries in the directory.. */
  76.     while ((entp = readdir(dirp)) != 0)
  77.     if (!EQ(entp->d_name, ".") && !EQ(entp->d_name, "..")) {
  78. #ifndef __MINT__
  79.         if (depth <= 1) {
  80.         /* Going too deep; checkpoint and close this directory. */
  81.         seekpoint = telldir(dirp);
  82.         closedir(dirp);
  83.         dirp = NULL;
  84.         }
  85. #endif
  86.         /* Process the file. */
  87.         (void)strcpy(p, entp->d_name);
  88.         i = ftw(fullpath, funcptr, depth - 1);
  89.         if (i) {
  90.         /* User's finished; clean up. */
  91.         free(fullpath);
  92.         if (dirp)
  93.             closedir(dirp);
  94.         return (int)i;
  95.         }
  96.  
  97. #ifndef __MINT__
  98.         /* Reopen the directory if necessary. */
  99.         if (dirp == NULL) {
  100.         dirp = opendir(directory);
  101.         if (dirp == NULL) {
  102.             free(fullpath);
  103.             return -1;
  104.         }
  105.         seekdir(dirp, seekpoint);
  106.         }
  107. #endif
  108.     }
  109.  
  110.     /* Clean up. */
  111.     free(fullpath);
  112.     closedir(dirp);
  113.     return 0;
  114. }
  115.