home *** CD-ROM | disk | FTP | other *** search
/ Software Recommendations - 1998 Season 1 / DNBCD4.iso / share / DOS / ipxcopy / SRC.ZIP / SRC / CRDIR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-12  |  5.0 KB  |  221 lines

  1. /*
  2.  
  3.    CRDIR.C
  4.  
  5.    compatible recursive directory search
  6.  
  7. */
  8.  
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include "ccommon.h"
  12. #include "crdir.h"
  13.  
  14. #ifdef C_DOS
  15. #include <direct.h>
  16. #endif
  17.  
  18. static char *_c_delimiter_to_host(char *s)
  19. {
  20.    static char t[CRDIR_MAX_PATHNAME];
  21.    int i = 0;
  22.    while( i < CRDIR_MAX_PATHNAME)
  23.    {
  24.       t[i] = s[i];
  25. #ifdef C_UNIX
  26.       if ( t[i] == '\\' )
  27.          t[i] = C_DELIMITER_CHAR;
  28. #endif
  29. #ifdef C_DOS
  30.       if ( t[i] == '/' )
  31.          t[i] = C_DELIMITER_CHAR;
  32. #endif
  33.       if ( t[i] == '\0' )
  34.          break;
  35.       i++;
  36.    }
  37.    t[CRDIR_MAX_PATHNAME-1] = '\0';
  38.    return t;
  39. }
  40.  
  41.  
  42.  
  43. CRDIR *c_openrdir(char *dir, char *pat, int options)
  44. {
  45.    CRDIR *crd;
  46.    crd = (CRDIR *)malloc(sizeof(struct _CRDIR_struct));
  47.    if ( crd != NULL )
  48.    {
  49.       crd->cdir_depth = 0;
  50.       crd->options = options;
  51.       c_strncpy(crd->pat, pat, CRDIR_MAX_FILE);
  52.       c_strncpy(crd->pn, _c_delimiter_to_host(dir), CRDIR_MAX_PATHNAME);
  53.       if ( crd->pn[0] == '\0' )
  54.          strcpy(crd->pn, _c_delimiter_to_host("./"));
  55.       if ( strcmp( crd->pn+strlen(crd->pn)-1, _c_delimiter_to_host("/")) != 0 )
  56.          strcat(crd->pn, _c_delimiter_to_host("/"));
  57.       crd->pn_end_pos[crd->cdir_depth] = strlen(crd->pn);
  58.       c_chdir(crd->pn);
  59.       crd->cdir_list[crd->cdir_depth] = c_opendir(".", crd->pat, crd->options);
  60.       if ( crd->cdir_list[crd->cdir_depth] != NULL )
  61.       {
  62.          crd->cdir_depth++;
  63.          crd->mem_dir = NULL;
  64.          return crd;
  65.       }
  66.       free(crd);
  67.    }
  68.    return NULL;
  69. }
  70.  
  71. static int _c_push_rdir(CRDIR *crd, char *name, int is_dir)
  72. {
  73.    size_t pn_len, name_len;
  74.    pn_len = strlen(crd->pn);
  75.    name_len = strlen(name);
  76.    if ( pn_len+name_len+2 >= CRDIR_MAX_PATHNAME )
  77.       return 0;
  78.    if ( crd->cdir_depth >= CRDIR_MAX_DEPTH )
  79.       return 0;
  80.    if ( crd->cdir_depth == 0 )
  81.       return 0;
  82.    strcpy(crd->pn+pn_len, name);
  83.    strcpy(crd->pn+pn_len+name_len, _c_delimiter_to_host("/"));
  84.    crd->pn_end_pos[crd->cdir_depth] = pn_len+name_len+1;
  85.    crd->cdir_list[crd->cdir_depth] = NULL;
  86.    if ( is_dir != 0 )
  87.    {
  88.       if ( c_chdir(name) != 0 )
  89.       {
  90.          crd->pn[crd->pn_end_pos[crd->cdir_depth-1]] = '\0';
  91.          /* printf("c_chdir(%s) failed\n", name); */
  92.          return 0;
  93.       }
  94.       crd->cdir_list[crd->cdir_depth] = c_opendir(".", crd->pat, crd->options);
  95.       if ( crd->cdir_list[crd->cdir_depth] == NULL )
  96.       {
  97.          crd->pn[crd->pn_end_pos[crd->cdir_depth-1]] = '\0';
  98.          /* printf("opendir() failed\n"); */
  99.          return 0;
  100.       }
  101.    }
  102.    crd->cdir_depth++;
  103.    return 1;
  104. }
  105.  
  106. static int _c_pop_rdir(CRDIR *crd)
  107. {
  108.    if ( crd->cdir_depth == 0 )
  109.       return 0;
  110.    crd->cdir_depth--;
  111.    if ( crd->cdir_list[crd->cdir_depth] != NULL )
  112.    {
  113.       c_closedir(crd->cdir_list[crd->cdir_depth]);
  114.       if ( crd->cdir_depth != 0 )
  115.       {
  116.          c_chdir("..");
  117.       }
  118.    }
  119.    crd->pn[crd->pn_end_pos[crd->cdir_depth-1]] = '\0';
  120.    return 1;
  121. }
  122.  
  123. struct c_dirent *c_readrdir(CRDIR *crd)
  124. {
  125.    size_t pos;
  126.    struct c_dirent *de;
  127.    if ( crd->cdir_depth == 0 )
  128.       return NULL;
  129.    if ( (crd->options & CRDIR_GO_DIRS) != 0 )
  130.    {
  131.       for(;;)
  132.       {
  133.          if ( crd->cdir_depth == 0 )
  134.             return NULL;
  135.          pos = crd->cdir_depth-1;
  136.          if ( crd->mem_dir != NULL )
  137.          {
  138.             de = crd->mem_dir;
  139.             crd->mem_dir = NULL;
  140.             _c_push_rdir(crd, c_get_name(de), 1);
  141.             continue; /* return c_readrdir(crd); */
  142.          }
  143.          de = c_readdir(crd->cdir_list[pos]);
  144.          if ( de != NULL )
  145.          {
  146.             if ( c_is_dir(de) != 0 )
  147.             {
  148.                if ( strcmp(c_get_name(de),".") == 0 )
  149.                   continue; /* return c_readrdir(crd); */
  150.                if ( strcmp(c_get_name(de),"..") == 0 )
  151.                   continue; /* return c_readrdir(crd); */
  152.  
  153.                if ( (crd->options & CRDIR_RET_DIRS) != 0 )
  154.                {
  155.                   crd->mem_dir = de;
  156.                   return de;
  157.                }
  158.                _c_push_rdir(crd, c_get_name(de), 1);
  159.                continue; /* return c_readrdir(crd); */
  160.             }
  161.             return de;
  162.          }
  163.          if ( _c_pop_rdir(crd) != 0 )
  164.          {
  165.             /* return c_readrdir(crd); */
  166.             continue;
  167.          }
  168.          else
  169.             break;
  170.       }
  171.    }
  172.    else
  173.    {
  174.       pos = crd->cdir_depth-1;
  175.       for(;;)
  176.       {
  177.          de = c_readdir(crd->cdir_list[pos]);
  178.          if ( de == NULL )
  179.             break;
  180.          if ( c_is_dir(de) != 0 )
  181.          {
  182.             if ( (crd->options & CRDIR_RET_DIRS) != 0 )
  183.                return de;
  184.          }
  185.          else
  186.          {
  187.             return de;
  188.          }
  189.       }
  190.    }
  191.    return NULL;
  192. }
  193.  
  194. void c_closerdir(CRDIR *crd)
  195. {
  196.    if ( crd == NULL )
  197.       return;
  198.    while( _c_pop_rdir(crd) != 0 )
  199.       ;
  200.    free(crd);
  201. }
  202.  
  203. #ifdef CRDIR_MAIN
  204. #include <stdio.h>
  205. void main(void)
  206. {
  207.    CRDIR *d;
  208.    struct c_dirent *e;
  209.    d = c_openrdir(".", "*.exe", CRDIR_DEFAULT);
  210.    for(;;)
  211.    {
  212.       e = c_readrdir(d);
  213.       if ( e == NULL )
  214.          break;
  215.       printf("%d %s %-14s %s\n", d->cdir_depth, d->pn, e->d_short_name, e->d_name);
  216.    }
  217.    c_closerdir(d);
  218.    c_io_clear();
  219. }
  220. #endif
  221.