⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 crdir.c

📁 一个使用IPX协议在两台机器间传送文件的程序
💻 C
字号:
/*

   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 )
   {

      c_set_path(dir);

      crd->cdir_depth = 0;
      crd->options = options;
      c_strncpy(crd->pat, pat, CRDIR_MAX_FILE);

      if ( (options & CRDIR_REL_PATH) == 0 )
      {

         c_strncpy(crd->pn, _c_delimiter_to_host(dir), CRDIR_MAX_PATHNAME);
         c_strncpy(crd->spn, _c_delimiter_to_host(dir), CRDIR_MAX_PATHNAME);
   
         if ( crd->pn[0] == '\0' )
            strcpy(crd->pn, _c_delimiter_to_host("./"));
         if ( crd->spn[0] == '\0' )
            strcpy(crd->spn, _c_delimiter_to_host("./"));
   
         if ( strcmp( crd->pn+strlen(crd->pn)-1, _c_delimiter_to_host("/")) != 0 )
            strcat(crd->pn, _c_delimiter_to_host("/"));
         if ( strcmp( crd->spn+strlen(crd->spn)-1, _c_delimiter_to_host("/")) != 0 )
            strcat(crd->spn, _c_delimiter_to_host("/"));
      }
      else
      {
         strcpy(crd->pn, _c_delimiter_to_host("./"));
         strcpy(crd->spn, _c_delimiter_to_host("./"));
      }

      crd->pn_end_pos[crd->cdir_depth] = strlen(crd->pn);
      crd->spn_end_pos[crd->cdir_depth] = strlen(crd->spn);


                                        
      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, char *sname, int is_dir)
{
   size_t pn_len, spn_len, name_len, sname_len;

   pn_len = strlen(crd->pn);
   spn_len = strlen(crd->spn);

   name_len = strlen(name);
   sname_len = strlen(sname);

   if ( spn_len+sname_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->spn+spn_len, sname);

   strcpy(crd->pn+pn_len+name_len, _c_delimiter_to_host("/"));
   strcpy(crd->spn+spn_len+sname_len, _c_delimiter_to_host("/"));

   crd->pn_end_pos[crd->cdir_depth] = pn_len+name_len+1;
   crd->spn_end_pos[crd->cdir_depth] = spn_len+sname_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';
         crd->spn[crd->spn_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';
         crd->spn[crd->spn_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';
   crd->spn[crd->spn_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), c_get_short_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), c_get_short_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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -