home *** CD-ROM | disk | FTP | other *** search
- /*
-
- CRDIR.C
-
- compatible recursive directory search
-
- */
-
- #include <stdlib.h>
- #include <string.h>
- #include "ccommon.h"
- #include "crdir.h"
-
- #ifdef C_DOS
- #include <direct.h>
- #endif
-
- static char *_c_delimiter_to_host(char *s)
- {
- static char t[CRDIR_MAX_PATHNAME];
- int i = 0;
- while( i < CRDIR_MAX_PATHNAME)
- {
- t[i] = s[i];
- #ifdef C_UNIX
- if ( t[i] == '\\' )
- t[i] = C_DELIMITER_CHAR;
- #endif
- #ifdef C_DOS
- if ( t[i] == '/' )
- t[i] = C_DELIMITER_CHAR;
- #endif
- if ( t[i] == '\0' )
- break;
- i++;
- }
- t[CRDIR_MAX_PATHNAME-1] = '\0';
- return t;
- }
-
-
-
- CRDIR *c_openrdir(char *dir, char *pat, int options)
- {
- CRDIR *crd;
- crd = (CRDIR *)malloc(sizeof(struct _CRDIR_struct));
- if ( crd != NULL )
- {
- crd->cdir_depth = 0;
- crd->options = options;
- c_strncpy(crd->pat, pat, CRDIR_MAX_FILE);
- c_strncpy(crd->pn, _c_delimiter_to_host(dir), CRDIR_MAX_PATHNAME);
- if ( crd->pn[0] == '\0' )
- strcpy(crd->pn, _c_delimiter_to_host("./"));
- if ( strcmp( crd->pn+strlen(crd->pn)-1, _c_delimiter_to_host("/")) != 0 )
- strcat(crd->pn, _c_delimiter_to_host("/"));
- crd->pn_end_pos[crd->cdir_depth] = strlen(crd->pn);
- c_chdir(crd->pn);
- crd->cdir_list[crd->cdir_depth] = c_opendir(".", crd->pat, crd->options);
- if ( crd->cdir_list[crd->cdir_depth] != NULL )
- {
- crd->cdir_depth++;
- crd->mem_dir = NULL;
- return crd;
- }
- free(crd);
- }
- return NULL;
- }
-
- static int _c_push_rdir(CRDIR *crd, char *name, int is_dir)
- {
- size_t pn_len, name_len;
- pn_len = strlen(crd->pn);
- name_len = strlen(name);
- if ( pn_len+name_len+2 >= CRDIR_MAX_PATHNAME )
- return 0;
- if ( crd->cdir_depth >= CRDIR_MAX_DEPTH )
- return 0;
- if ( crd->cdir_depth == 0 )
- return 0;
- strcpy(crd->pn+pn_len, name);
- strcpy(crd->pn+pn_len+name_len, _c_delimiter_to_host("/"));
- crd->pn_end_pos[crd->cdir_depth] = pn_len+name_len+1;
- crd->cdir_list[crd->cdir_depth] = NULL;
- if ( is_dir != 0 )
- {
- if ( c_chdir(name) != 0 )
- {
- crd->pn[crd->pn_end_pos[crd->cdir_depth-1]] = '\0';
- /* printf("c_chdir(%s) failed\n", name); */
- return 0;
- }
- crd->cdir_list[crd->cdir_depth] = c_opendir(".", crd->pat, crd->options);
- if ( crd->cdir_list[crd->cdir_depth] == NULL )
- {
- crd->pn[crd->pn_end_pos[crd->cdir_depth-1]] = '\0';
- /* printf("opendir() failed\n"); */
- return 0;
- }
- }
- crd->cdir_depth++;
- return 1;
- }
-
- static int _c_pop_rdir(CRDIR *crd)
- {
- if ( crd->cdir_depth == 0 )
- return 0;
- crd->cdir_depth--;
- if ( crd->cdir_list[crd->cdir_depth] != NULL )
- {
- c_closedir(crd->cdir_list[crd->cdir_depth]);
- if ( crd->cdir_depth != 0 )
- {
- c_chdir("..");
- }
- }
- crd->pn[crd->pn_end_pos[crd->cdir_depth-1]] = '\0';
- return 1;
- }
-
- struct c_dirent *c_readrdir(CRDIR *crd)
- {
- size_t pos;
- struct c_dirent *de;
- if ( crd->cdir_depth == 0 )
- return NULL;
- if ( (crd->options & CRDIR_GO_DIRS) != 0 )
- {
- for(;;)
- {
- if ( crd->cdir_depth == 0 )
- return NULL;
- pos = crd->cdir_depth-1;
- if ( crd->mem_dir != NULL )
- {
- de = crd->mem_dir;
- crd->mem_dir = NULL;
- _c_push_rdir(crd, c_get_name(de), 1);
- continue; /* return c_readrdir(crd); */
- }
- de = c_readdir(crd->cdir_list[pos]);
- if ( de != NULL )
- {
- if ( c_is_dir(de) != 0 )
- {
- if ( strcmp(c_get_name(de),".") == 0 )
- continue; /* return c_readrdir(crd); */
- if ( strcmp(c_get_name(de),"..") == 0 )
- continue; /* return c_readrdir(crd); */
-
- if ( (crd->options & CRDIR_RET_DIRS) != 0 )
- {
- crd->mem_dir = de;
- return de;
- }
- _c_push_rdir(crd, c_get_name(de), 1);
- continue; /* return c_readrdir(crd); */
- }
- return de;
- }
- if ( _c_pop_rdir(crd) != 0 )
- {
- /* return c_readrdir(crd); */
- continue;
- }
- else
- break;
- }
- }
- else
- {
- pos = crd->cdir_depth-1;
- for(;;)
- {
- de = c_readdir(crd->cdir_list[pos]);
- if ( de == NULL )
- break;
- if ( c_is_dir(de) != 0 )
- {
- if ( (crd->options & CRDIR_RET_DIRS) != 0 )
- return de;
- }
- else
- {
- return de;
- }
- }
- }
- return NULL;
- }
-
- void c_closerdir(CRDIR *crd)
- {
- if ( crd == NULL )
- return;
- while( _c_pop_rdir(crd) != 0 )
- ;
- free(crd);
- }
-
- #ifdef CRDIR_MAIN
- #include <stdio.h>
- void main(void)
- {
- CRDIR *d;
- struct c_dirent *e;
- d = c_openrdir(".", "*.exe", CRDIR_DEFAULT);
- for(;;)
- {
- e = c_readrdir(d);
- if ( e == NULL )
- break;
- printf("%d %s %-14s %s\n", d->cdir_depth, d->pn, e->d_short_name, e->d_name);
- }
- c_closerdir(d);
- c_io_clear();
- }
- #endif
-