home *** CD-ROM | disk | FTP | other *** search
/ Software Recommendations - 1998 Season 1 / DNBCD4.iso / share / DOS / ipxcopy / SRC.ZIP / SRC / CDIRENT.C < prev    next >
Encoding:
Text File  |  1996-09-11  |  14.3 KB  |  726 lines

  1. /*
  2.  
  3.    CDIRENT.C
  4.  
  5.    (c) 1996 Oliver Kraus
  6.  
  7. */
  8.  
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <ctype.h>
  12. #include "ccommon.h"
  13. #include "cdirent.h"
  14. #include "cio.h"
  15.  
  16. #ifdef C_DOS
  17. #include <dos.h>
  18. #include <direct.h>
  19. #include "dpmicall.h"
  20. #endif
  21.  
  22. #ifdef C_UNIX
  23. #include <sys/types.h>
  24. #include <sys/stat.h>
  25. #include <dirent.h>
  26. #endif
  27.  
  28. #define CDIR_EXPAND_MEM 8192
  29.  
  30. unsigned char c_translation[] =
  31. {
  32.       0, /*    */
  33.       1, /*  */
  34.       2, /*  */
  35.       3, /*  */
  36.       4, /*  */
  37.       5, /*  */
  38.       6, /*  */
  39.       7, /*  */
  40.       8, /*  */
  41.           9, /*   */
  42.          10, /*   */
  43.      11, /*   */
  44.      12, /*   */
  45.      13, /*  */
  46.      14, /*  */
  47.      15, /*  */
  48.      16, /*  */
  49.      17, /*  */
  50.      18, /*  */
  51.      19, /*  */
  52.      20, /* ╢ */
  53.      21, /* º */
  54.      22, /*  */
  55.      23, /*  */
  56.      24, /*  */
  57.      25, /*  */
  58.      26, /*    */
  59.      27, /*  */
  60.      28, /*  */
  61.      29, /*  */
  62.      30, /*    */
  63.      31, /*    */
  64.      32, /*    */
  65.      33, /* ! */
  66.      34, /* " */
  67.      35, /* # */
  68.      36, /* $ */
  69.      37, /* % */
  70.      38, /* & */
  71.      39, /* ' */
  72.      40, /* ( */
  73.      41, /* ) */
  74.      42, /* * */
  75.      43, /* + */
  76.      44, /* , */
  77.      45, /* - */
  78.      46, /* . */
  79.      47, /* / */
  80.      48, /* 0 */
  81.      49, /* 1 */
  82.      50, /* 2 */
  83.      51, /* 3 */
  84.      52, /* 4 */
  85.      53, /* 5 */
  86.      54, /* 6 */
  87.      55, /* 7 */
  88.      56, /* 8 */
  89.      57, /* 9 */
  90.      58, /* : */
  91.      59, /* ; */
  92.      60, /* < */
  93.      61, /* = */
  94.      62, /* > */
  95.      63, /* ? */
  96.      64, /* @ */
  97.     'A', /* A */
  98.     'B', /* B */
  99.     'C', /* C */
  100.     'D', /* D */
  101.     'E', /* E */
  102.     'F', /* F */
  103.     'G', /* G */
  104.     'H', /* H */
  105.     'I', /* I */
  106.     'J', /* J */
  107.     'K', /* K */
  108.     'L', /* L */
  109.     'M', /* M */
  110.     'N', /* N */
  111.     'O', /* O */
  112.     'P', /* P */
  113.     'Q', /* Q */
  114.     'R', /* R */
  115.     'S', /* S */
  116.     'T', /* T */
  117.     'U', /* U */
  118.     'V', /* V */
  119.     'W', /* W */
  120.     'X', /* X */
  121.     'Y', /* Y */
  122.     'Z', /* Z */
  123.      91, /* [ */
  124.      92, /* \ */
  125.      93, /* ] */
  126.      94, /* ^ */
  127.      95, /* _ */
  128.      96, /* ` */
  129.     'A', /* a */
  130.     'B', /* b */
  131.     'C', /* c */
  132.     'D', /* d */
  133.     'E', /* e */
  134.     'F', /* f */
  135.     'G', /* g */
  136.     'H', /* h */
  137.     'I', /* i */
  138.     'J', /* j */
  139.     'K', /* k */
  140.     'L', /* l */
  141.     'M', /* m */
  142.     'N', /* n */
  143.     'O', /* o */
  144.     'P', /* p */
  145.     'Q', /* q */
  146.     'R', /* r */
  147.     'S', /* s */
  148.     'T', /* t */
  149.     'U', /* u */
  150.     'V', /* v */
  151.     'W', /* w */
  152.     'X', /* x */
  153.     'Y', /* y */
  154.     'Z', /* z */
  155.     123, /* { */
  156.     124, /* | */
  157.     125, /* } */
  158.     126, /* ~ */
  159.     127, /* ü */
  160.     128, /* ╟ */
  161.     'U', /* ⁿ */
  162.     'E', /* Θ */
  163.     'A', /* Γ */
  164.     'A', /* Σ */
  165.     'A', /* α */
  166.     'A', /* σ */
  167.     'C', /* τ */
  168.     'E', /* Ω */
  169.     'E', /* δ */
  170.     'E', /* Φ */
  171.     'I', /* ∩ */
  172.     'I', /* ε */
  173.     'I', /* ∞ */
  174.     'A', /* ─ */
  175.     'A', /* ┼ */
  176.     'E', /* ╔ */
  177.     145, /* µ */
  178.     'A', /* ╞ */
  179.     'O', /* ⌠ */
  180.     'O', /* ÷ */
  181.     'O', /* ≥ */
  182.     'U', /* √ */
  183.     'U', /* ∙ */
  184.     'Y', /*   */
  185.     'O', /* ╓ */
  186.     'U', /* ▄ */
  187.     'C', /* ó */
  188.     156, /* ú */
  189.     157, /* Ñ */
  190.     158, /* ñ */
  191.     159, /* û */
  192.     'A', /* ß */
  193.     'I', /* φ */
  194.     'O', /* ≤ */
  195.     'U', /* · */
  196.     'N', /* ± */
  197.     'N', /* ╤ */
  198.     166, /* ¬ */
  199.     167, /* ║ */
  200.     168, /* ┐ */
  201.     169, /* ¿ */
  202.     170, /* ¼ */
  203.         171, /* ╜ */
  204.     172, /* ╝ */
  205.     173, /* í */
  206.     174, /* ½ */
  207.     175, /* » */
  208.     176, /* ù */
  209.     177, /* ÿ */
  210.     178, /* Ö */
  211.     179, /* ■ */
  212.     180, /* │ */
  213.     181, /* ┤ */
  214.     182, /* ╡ */
  215.     183, /* ╕ */
  216.     184, /* ╣ */
  217.     185, /* á */
  218.     186, /* ª */
  219.     187, /* ⌐ */
  220.     188, /* ¡ */
  221.     189, /* ╗ */
  222.     190, /* ╛ */
  223.     191, /* └ */
  224.     192, /* ┴ */
  225.     193, /* ┬ */
  226.     194, /* ├ */
  227.     195, /* ╚ */
  228.     196, /* ² */
  229.     197, /* ╩ */
  230.     198, /* ╚ */
  231.     199, /* ╠ */
  232.  
  233.     200, /*    */
  234.     201, /*    */
  235.     202, /*    */
  236.     203, /*    */
  237.         204, /*  */
  238.     205, /*    */
  239.     206, /*    */
  240.     207, /*    */
  241.     208, /*    */
  242.     209, /*    */
  243.     210, /*    */
  244.     211, /*    */
  245.     212, /*    */
  246.     213, /*    */
  247.     214, /*    */
  248.     215, /*    */
  249.     216, /*    */
  250.     217, /*    */
  251.     218, /*    */
  252.     219, /*    */
  253.     220, /*    */
  254.     221, /*    */
  255.     222, /*    */
  256.     223, /*    */
  257.     224, /*    */
  258.         'S', /* ▀ */
  259.     226, /*    */
  260.     227, /*    */
  261.     228, /*    */
  262.     229, /*    */
  263.     230, /*    */
  264.     231, /*    */
  265.     232, /*    */
  266.     233, /*    */
  267.     234, /*    */
  268.     235, /*    */
  269.     236, /*    */
  270.     237, /*    */
  271.     238, /*    */
  272.     239, /*    */
  273.     240, /*    */
  274.     241, /*    */
  275.     242, /*    */
  276.     243, /*    */
  277.     244, /*    */
  278.     245, /*    */
  279.     246, /*    */
  280.     247, /*    */
  281.     248, /*    */
  282.     249, /*    */
  283.     250, /*    */
  284.     251, /*    */
  285.     252, /*    */
  286.     253, /*    */
  287.     254, /*    */
  288.     255  /*    */
  289. };
  290.  
  291. #define c_toupper(c) (c_translation[(unsigned char)(c)])
  292.  
  293. char *c_strupr(char *s)
  294. {
  295.    char *t = s;
  296.    if ( s != NULL )
  297.    {
  298.       while(*s != '\0')
  299.       {
  300.          *s = c_toupper(*s);
  301.          s++;
  302.       }
  303.    }
  304.    return t;
  305. }
  306.  
  307. int patmat(char *raw, char *pat)
  308. {
  309.    if ( *pat == '\0' )
  310.       return *raw == '\0';                  /*  *raw == '\0' ? 1 : 0  */
  311.  
  312.    if (*pat != '*')                         /* if pattern is not a '*'*/
  313.    {
  314.       if (*raw == '\0')                     /*  if end of raw then    */
  315.           return( 0 ) ;                     /*     mismatch           */
  316.       while ((*pat == '?') || (*pat == *raw))  /*  if chars match then   */
  317.       {
  318.          raw++; pat++;
  319.          if ( *pat == '\0' )
  320.             return *raw == '\0';            /* *raw == '\0' ? 1 : 0   */
  321.       }
  322.    }  /* no else !!! */                     /* no match, if pat is not '*' */
  323.    if (*pat == '*')                         /* if pattern is a '*'    */
  324.    {
  325.       while(*pat == '*')                    /* ignore more '*'        */
  326.          pat++;
  327.       if (*(pat  ) == '\0')                 /*    if it is end of pat */
  328.          return( 1 ) ;                      /*    then match          */
  329.  
  330.       while( *raw != '\0' )                 /*    else hunt for match */
  331.       {
  332.          if((*pat == '?') || (*pat == *raw))
  333.          {
  334.             if (patmat(++raw, pat+1) != 0)  /*      if found,match    */
  335.                  return( 1 ) ;              /*        rest of pat     */
  336.          }
  337.          else
  338.          {
  339.             raw++;
  340.          }
  341.       }
  342.    }
  343.    return( 0 ) ;                            /*  no match found        */
  344. }
  345.  
  346. int upatmat(char *raw, char *pat)
  347. {
  348.    if ( *pat == '\0' )
  349.       return *raw == '\0';                  /*  *raw == '\0' ? 1 : 0  */
  350.  
  351.    if (*pat != '*')                         /* if pattern is not a '*'*/
  352.    {
  353.       if (*raw == '\0')                     /*  if end of raw then    */
  354.           return( 0 ) ;                     /*     mismatch           */
  355.       while (((unsigned char)*pat == c_toupper(*raw)) || (*pat == '?'))
  356.       {
  357.          raw++; pat++;
  358.          if ( *pat == '\0' )
  359.             return *raw == '\0';            /* *raw == '\0' ? 1 : 0   */
  360.       }
  361.    }  /* no else !!! */                     /* no match, if pat is not '*' */
  362.    if (*pat == '*')                         /* if pattern is a '*'    */
  363.    {
  364.       while(*pat == '*')                    /* ignore more '*'        */
  365.          pat++;
  366.       if (*(pat  ) == '\0')                 /*    if it is end of pat */
  367.          return( 1 ) ;                      /*    then match          */
  368.  
  369.       while( *raw != '\0' )                 /*    else hunt for match */
  370.       {
  371.          if (((unsigned char)*pat == c_toupper(*raw)) || (*pat == '?'))
  372.          {
  373.             if (upatmat(++raw, pat+1) != 0) /*      if found,match    */
  374.                  return( 1 ) ;              /*        rest of pat     */
  375.          }
  376.          else
  377.          {
  378.             raw++;
  379.          }
  380.       }
  381.    }
  382.    return( 0 ) ;                            /*  no match found        */
  383. }
  384.  
  385. int _add_name(CDIR *dirp, char *name, char *short_name, unsigned long size, int is_dir)
  386. {
  387.    size_t len;
  388.    struct c_dirent *de;
  389.    if ( name == NULL )
  390.       return 1;
  391.    if ( name[0] == '\0' )
  392.       return 1;
  393.  
  394.    if ( (dirp->options & CDIR_MATCH_ALL) == 0 )
  395.    {
  396.       if ( is_dir == 0 )
  397.       {
  398.          if ( dirp->pat[0] == '\0' )
  399.             return 1;
  400.          if ( dirp->patmat_fn(name, dirp->pat) == 0 )
  401.             if ( dirp->patmat_fn(short_name, dirp->pat) == 0 )
  402.                return 1;
  403.       }
  404.    }
  405.    len = strlen(name)+1+sizeof(struct c_dirent);
  406.    len = (size_t)(len + sizeof(long) - (size_t)1) & (size_t)0x0fffffffc;
  407.    while ( dirp->cnt+len > dirp->max )
  408.    {
  409.       char *ptr;
  410.       ptr = (char *)realloc(dirp->ptr, dirp->max+CDIR_EXPAND_MEM);
  411.       if ( ptr == NULL )
  412.          return 0;
  413.       dirp->ptr = ptr;
  414.       dirp->max += CDIR_EXPAND_MEM;
  415.    }
  416.    de = (struct c_dirent *)(dirp->ptr+dirp->cnt);
  417.    de->d_size = size;
  418.    /* de->d_ino = 0L; */
  419.    de->d_off = 0L;
  420.    de->d_reclen = (unsigned short)len;
  421.    de->d_is_dir = (short)is_dir;
  422.    strcpy(de->d_name, name);
  423.    strncpy(de->d_short_name, short_name, 14);
  424.    de->d_short_name[13] = '\0';
  425.    dirp->cnt += len;
  426.    return 1;
  427. }
  428.  
  429. #ifdef C_DOS
  430.  
  431. int _add_dos_files(CDIR *dirp)
  432. {
  433.    struct _find_t fileinfo;
  434.    if ( _dos_findfirst("*.*",
  435.       _A_SUBDIR | _A_NORMAL | _A_HIDDEN | _A_RDONLY | _A_ARCH | _A_SYSTEM,
  436.       &fileinfo) == 0 )
  437.    {
  438.       do
  439.       {
  440.          if ( _add_name(dirp,
  441.                fileinfo.name,
  442.                fileinfo.name,
  443.                fileinfo.size,
  444.                (fileinfo.attrib & _A_SUBDIR)==0?0:1 ) == 0 )
  445.             return 0;
  446.       } while(_dos_findnext(&fileinfo) == 0);
  447.    }
  448.    return 1;
  449. }
  450.  
  451. struct _win95_find_data
  452. {
  453.    unsigned long attr;
  454.    unsigned long create_time1;
  455.    unsigned long create_time2;
  456.    unsigned long access_time1;
  457.    unsigned long access_time2;
  458.    unsigned long modify_time1;
  459.    unsigned long modify_time2;
  460.    unsigned long size1;    /* high bytes */
  461.    unsigned long size2;    /* low bytes */
  462.    char fill[8];
  463.    char long_name[260];
  464.    char short_name[14];
  465. };
  466.  
  467. #ifdef C_DIRECT_16_
  468. int _add_longfile(CDIR *dirp)
  469. {
  470.    unsigned short handle;
  471.    char far *search = "*";
  472.    struct _win95_find_data fd;
  473.  
  474.    union REGS r;
  475.    struct SREGS s;
  476.  
  477.    r.x.ax = 0x0714e;
  478.    r.h.cl = 0x0ff;   /* every attrib ok */
  479.    r.h.ch = 0;   /* no attrib req. */
  480.    r.x.si = 0; /* win95 time format?? */
  481.    s.ds = (unsigned)(((unsigned long)search)>>16);
  482.    r.x.dx = (unsigned)(((unsigned long)search)&0x0ffffUL);
  483.    s.es = (unsigned)(((unsigned long)((void far *)&fd))>>16);
  484.    r.x.di = (unsigned)(((unsigned long)((void far *)&fd))&0x0ffffUL);
  485.    int86x(0x021, &r, &r, &s);
  486.    if ( r.x.cflag != 0 )
  487.       return 0;
  488.    handle = (unsigned short)r.x.ax;
  489.  
  490.    for(;;)
  491.    {
  492.       if ( _add_name(dirp,
  493.             fd.long_name,
  494.             fd.short_name,
  495.             fd.size2,
  496.             (fd.attr&0x010)==0?0:1 ) == 0 )
  497.          break;
  498.  
  499.       r.x.ax = 0x0714f;
  500.       r.x.bx = handle;
  501.       r.x.si = 0; /* win95 time format?? */
  502.       s.es = (unsigned)(((unsigned long)((void far *)&fd))>>16);
  503.       r.x.di = (unsigned)(((unsigned long)((void far *)&fd))&0x0ffffUL);
  504.       int86x(0x021, &r, &r, &s);
  505.       if ( r.x.cflag != 0 )
  506.          break;
  507.    }
  508.    r.x.ax = 0x071a1;
  509.    r.x.bx = handle;
  510.    int86x(0x021, &r, &r, &s);
  511.  
  512.    return 1;
  513. }
  514. #endif
  515.  
  516.  
  517. int _add_dpmi_longfile(CDIR *dirp)
  518. {
  519.    unsigned short handle;
  520.    short sel_search, seg_search;
  521.    short sel_fd, seg_fd;
  522.    rminfo_struct rmi;
  523.    struct _win95_find_data fd;
  524.  
  525.    if ( dpmi_alloc_dos_memory(4, &sel_search, &seg_search ) == 0 )
  526.       return 0;
  527.    if ( dpmi_alloc_dos_memory(sizeof(struct _win95_find_data), &sel_fd, &seg_fd ) == 0 )
  528.    {
  529.       dpmi_free_dos_memory(sel_search);
  530.       return 0;
  531.    }
  532.    dpmi_copy_to_dos(sel_search, (void *)"*", 2);
  533.  
  534.    rmi.eax = 0x0714eL;
  535.    rmi.ecx = 0x0ffL;   /* every attrib ok, no attrib req. */
  536.    rmi.esi = 0L;       /* win95 time format?? */
  537.    rmi.ds = seg_search;
  538.    rmi.edx = 0L;
  539.    rmi.es = seg_fd;
  540.    rmi.edi = 0L;
  541.    if ( dpmi_simulate_rmi(0x021, &rmi) != 0 )
  542.       return 0;
  543.    handle = (unsigned short)rmi.eax;
  544.  
  545.    for(;;)
  546.    {
  547.       dpmi_copy_from_dos(sel_fd, &fd, sizeof(struct _win95_find_data));
  548.       if ( _add_name(dirp,
  549.             fd.long_name,
  550.             fd.short_name,
  551.             fd.size2,
  552.             (fd.attr&0x010)==0?0:1 ) == 0 )
  553.          break;
  554.  
  555.       rmi.eax = 0x0714fL;
  556.       rmi.ebx = (long)handle;
  557.       rmi.esi = 0L;       /* win95 time format?? */
  558.       rmi.es = seg_fd;
  559.       rmi.edi = 0L;
  560.       if ( dpmi_simulate_rmi(0x021, &rmi) != 0 )
  561.          break;
  562.    }
  563.    rmi.eax = 0x071a1L;
  564.    rmi.ebx = (long)handle;
  565.    dpmi_simulate_rmi(0x021, &rmi);
  566.  
  567.    dpmi_free_dos_memory(sel_fd);
  568.    dpmi_free_dos_memory(sel_search);
  569.  
  570.    return 1;
  571. }
  572.  
  573. int _add_files(CDIR *dirp)
  574. {
  575.    if ( c_is_long_filename() != 0 )
  576.       return _add_dpmi_longfile(dirp);
  577.    return _add_dos_files(dirp);
  578. }
  579.  
  580. #endif
  581.  
  582.  
  583. #ifdef C_UNIX
  584. int _add_files(CDIR *dirp)
  585. {
  586.    DIR *d;
  587.    struct dirent *e;
  588.    struct stat s;
  589.    d = opendir(".");
  590.    if ( d == NULL )
  591.       return 0;
  592.    for(;;)
  593.    {
  594.       e = readdir(d);
  595.       if ( e == NULL )
  596.          break;
  597.       if ( stat(e->d_name, &s) != 0 )
  598.       {
  599.          closedir(d);
  600.          return 0;
  601.       }
  602.       if ( _add_name(dirp,
  603.             e->d_name,
  604.             "",
  605.             s.st_size,
  606.             (s.st_mode&S_IFDIR)!=0?1:0 ) == 0 )
  607.          break;
  608.    }
  609.    closedir(d);
  610.    return 1;
  611. }
  612.  
  613. #endif
  614.  
  615.  
  616. CDIR *c_opendir(const char *path, const char *pat, int options)
  617. {
  618.    CDIR *d;
  619.    d = (CDIR *)malloc(sizeof(struct _CDIR_struct));
  620.    if ( d != NULL )
  621.    {
  622.       d->options = options;
  623.       d->path = (char *)malloc(strlen(path)+2);
  624.       if ( d->path != NULL )
  625.       {
  626.          strcpy(d->path, path);
  627.          d->pat = (char *)malloc(strlen(pat)+2);
  628.          if ( d->pat != NULL )
  629.          {
  630.             strcpy(d->pat, pat);
  631.             d->ptr = (char *)malloc(CDIR_EXPAND_MEM);
  632.             if ( d->ptr != NULL )
  633.             {
  634.                d->max = (size_t)CDIR_EXPAND_MEM;
  635.                d->cnt = (size_t)0;
  636.                d->pos = 0;
  637.                d->patmat_fn = patmat;
  638.                if ( (options & CDIR_MATCH_CASE) == 0 )
  639.                {
  640.                   d->patmat_fn = upatmat;
  641.                   c_strupr(d->pat);
  642.                }
  643.  
  644.                c_chdir(path);
  645.                if ( _add_files(d) == 0 )
  646.                {
  647.                   /* ... */
  648.                }
  649.                return d;
  650.             }
  651.             free(d->pat);
  652.          }
  653.          free(d->path);
  654.       }
  655.       free(d);
  656.    }
  657.    return NULL;
  658. }
  659.  
  660. int c_closedir(CDIR *dirp)
  661. {
  662.    if ( dirp != NULL )
  663.    {
  664.       free(dirp->ptr);
  665.       free(dirp->pat);
  666.       free(dirp->path);
  667.       free(dirp);
  668.    }
  669.    return 1;
  670. }
  671.  
  672. struct c_dirent *c_readdir(CDIR *dirp)
  673. {
  674.    struct c_dirent *de;
  675.    if ( dirp == NULL )
  676.       return NULL;
  677.    if ( dirp->pos >= dirp->cnt )
  678.       return NULL;
  679.    de = (struct c_dirent *)(dirp->pos+dirp->ptr);
  680.    dirp->pos += de->d_reclen;
  681.    return de;
  682. }
  683.  
  684. void c_rewinddir(CDIR *dirp)
  685. {
  686.    if ( dirp == NULL )
  687.       return;
  688.    dirp->pos = 0;
  689. }
  690.  
  691. long c_telldir(CDIR *dirp)
  692. {
  693.    if ( dirp == NULL )
  694.       return -1L;
  695.    return (long)dirp->pos;
  696. }
  697.  
  698. void c_seekdir(CDIR *dirp, long pos)
  699. {
  700.    if ( dirp == NULL )
  701.       return;
  702.    dirp->pos = (size_t)pos;
  703. }
  704.  
  705. #ifdef CDIRENT_MAIN
  706. #include <stdio.h>
  707. void main(void)
  708. {
  709.    CDIR *d;
  710.    struct c_dirent *e;
  711.    d = c_opendir(".", "*", 0);
  712.    for(;;)
  713.    {
  714.       e = c_readdir(d);
  715.       if ( e == NULL )
  716.          break;
  717.       if ( c_is_dir(e) != 0 )
  718.          printf("<dir> ");
  719.       else
  720.          printf("      ");
  721.       printf("%-14s %s\n", e->d_short_name, e->d_name);
  722.    }
  723.    c_closedir(d);
  724. }
  725. #endif
  726.