home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / fileutil / tcggrep2.arj / MSD_DIR2.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-24  |  5.7 KB  |  271 lines

  1. /*
  2.  * @(#)msd_dir.c 1.4 87/11/06    Public Domain.
  3.  *
  4.  *  A public domain implementation of BSD directory routines for
  5.  *  MS-DOS.  Written by Michael Rendell ({uunet,utai}michael@garfield),
  6.  *  August 1897
  7.  */
  8. /*
  9.  *  Slightly hacked by Barry Schwartz, Dec. 1989, and Aug. 1990.
  10.  */
  11. /* modified for Turbo C Jim Segrave 00:36:06 Sat Nov 24 1990
  12.    used Turbo intrinsics to set LARGE_DATA flag
  13.    added prototype, changed include names to match
  14.    redefined ino_t as unsigned
  15.    added code to expand '.' and '..' references in opendir, since
  16.    my Novel network doesn't work with stat() for these pathnames
  17.    The file norm_fil.c will convert a pathname to a fully qualified
  18.    path, eliminating '.' and '..' as it goes.
  19.    renamed setdta as _setdta to avoid name conflicts
  20. */
  21. #include    <sys/types.h>
  22. #include    <sys/stat.h>
  23. /*#include    <sys/dir.h>        <-- not until later! */
  24. #include    "msd_dir.h"
  25. #ifdef    __TURBOC__
  26. #  include    <alloc.h>
  27. #  include  <stdio.h>
  28. #  include  <stdlib.h>
  29. #  include    <dir.h>
  30. #else
  31. #  include    <malloc.h>
  32. #endif
  33. #include    <string.h>
  34. #include    <dos.h>
  35.  
  36. #undef LARGE_DATA
  37. #ifdef __TURBOC__
  38. #  if defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__)
  39. #    define LARGE_DATA
  40. #  endif
  41. #else
  42. #  if defined(M_I86CM) || defined(M_I86LM) || defined(M_I86HM)
  43. #    define LARGE_DATA
  44. #  endif
  45. #endif
  46.  
  47. #ifndef    NULL
  48. # define    NULL    0
  49. #endif    /* NULL */
  50.  
  51. #ifndef    MAXPATHLEN
  52. # define    MAXPATHLEN    255
  53. #endif    /* MAXPATHLEN */
  54.  
  55. /* attribute stuff */
  56. #define    A_RONLY        0x01
  57. #define    A_HIDDEN    0x02
  58. #define    A_SYSTEM    0x04
  59. #define    A_LABEL        0x08
  60. #define    A_DIR        0x10
  61. #define    A_ARCHIVE    0x20
  62.  
  63. /* dos call values */
  64. #define    DOSI_FINDF    0x4e
  65. #define    DOSI_FINDN    0x4f
  66. #define    DOSI_SDTA    0x1a
  67.  
  68. #define    Newisnull(a, t)        ((a = (t *) malloc(sizeof(t))) == (t *) NULL)
  69.  
  70. #if 0
  71.  
  72. #ifndef ATTRIBUTES
  73. /* #define    ATTRIBUTES        (A_DIR | A_HIDDEN | A_SYSTEM) */
  74. #define ATTRIBUTES    (A_RONLY | A_SYSTEM | A_DIR)
  75. #endif
  76.  
  77. #else
  78.  
  79. #define ATTRIBUTES    dos_file_attributes
  80. extern unsigned short ATTRIBUTES;
  81.  
  82. #endif
  83.  
  84. /* what find first/next calls look use */
  85. typedef struct {
  86.     char        d_buf[21];
  87.     char        d_attribute;
  88.     unsigned short    d_time;
  89.     unsigned short    d_date;
  90.     long        d_size;
  91.     char        d_name[13];
  92. } Dta_buf;
  93.  
  94. #ifdef    __TURBOC__
  95.   static    char    *getdirent (char *dir);
  96.   static    void    _setdta (void);
  97.   static    void    free_dircontents (struct _dircontents *dp);
  98. #  else
  99. static    char    *getdirent();
  100. static    void    _setdta();
  101. static    void    free_dircontents();
  102. #endif
  103.  
  104. static    Dta_buf        dtabuf;
  105. static    Dta_buf        *dtapnt = &dtabuf;
  106. static    union REGS    reg, nreg;
  107.  
  108. #if    defined(LARGE_DATA)
  109. static    struct SREGS    sreg;
  110. #endif
  111.  
  112. DIR    *
  113. opendir(name)
  114.     char    *name;
  115. {
  116.     struct    stat        statb;
  117.     DIR            *dirp;
  118.     char            c;
  119.     char            *s;
  120.     struct _dircontents    *dp;
  121.     char            nbuf[MAXPATHLEN + 1];
  122.     char            temp[256];
  123.  
  124.     if (norm_path (temp, name))
  125.         return (DIR *) NULL;
  126.     
  127.     if (stat(temp, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
  128.         return (DIR *) NULL;
  129.     if (Newisnull(dirp, DIR))
  130.         return (DIR *) NULL;
  131.     if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/')
  132.         (void) strcat(strcpy(nbuf, name), "\\*.*");
  133.     else
  134.         (void) strcat(strcpy(nbuf, name), "*.*");
  135.     dirp->dd_loc = 0;
  136.     _setdta();
  137.     dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
  138.     if ((s = getdirent(nbuf)) == (char *) NULL)
  139.         return dirp;
  140.     do {
  141.         if (Newisnull(dp, struct _dircontents) || (dp->_d_entry =
  142.             malloc((unsigned) (strlen(s) + 1))) == (char *) NULL)
  143.         {
  144.             if (dp)
  145.                 free((char *) dp);
  146.             free_dircontents(dirp->dd_contents);
  147.             return (DIR *) NULL;
  148.         }
  149.         if (dirp->dd_contents)
  150.             dirp->dd_cp = dirp->dd_cp->_d_next = dp;
  151.         else
  152.             dirp->dd_contents = dirp->dd_cp = dp;
  153.         (void) strcpy(dp->_d_entry, s);
  154.         dp->_d_next = (struct _dircontents *) NULL;
  155.     } while ((s = getdirent((char *) NULL)) != (char *) NULL);
  156.     dirp->dd_cp = dirp->dd_contents;
  157.  
  158.     return dirp;
  159. }
  160.  
  161. void
  162. closedir(dirp)
  163.     DIR    *dirp;
  164. {
  165.     free_dircontents(dirp->dd_contents);
  166.     free((char *) dirp);
  167. }
  168.  
  169. struct direct    *
  170. readdir(dirp)
  171.     DIR    *dirp;
  172. {
  173.     static    struct direct    dp;
  174.     
  175.     if (dirp->dd_cp == (struct _dircontents *) NULL)
  176.         return (struct direct *) NULL;
  177.     dp.d_namlen = dp.d_reclen =
  178.         strlen(strcpy(dp.d_name, dirp->dd_cp->_d_entry));
  179.     strlwr(dp.d_name);        /* JF */
  180.     dp.d_ino = 0;
  181.     dirp->dd_cp = dirp->dd_cp->_d_next;
  182.     dirp->dd_loc++;
  183.  
  184.     return &dp;
  185. }
  186.  
  187. void
  188. seekdir(dirp, off)
  189.     DIR    *dirp;
  190.     long    off;
  191. {
  192.     long            i = off;
  193.     struct _dircontents    *dp;
  194.  
  195.     if (off < 0)
  196.         return;
  197.     for (dp = dirp->dd_contents ; --i >= 0 && dp ; dp = dp->_d_next)
  198.         ;
  199.     dirp->dd_loc = off - (i + 1);
  200.     dirp->dd_cp = dp;
  201. }
  202.  
  203. long
  204. telldir(dirp)
  205.     DIR    *dirp;
  206. {
  207.     return dirp->dd_loc;
  208. }
  209.  
  210. static    void
  211. free_dircontents(dp)
  212.     struct    _dircontents    *dp;
  213. {
  214.     struct _dircontents    *odp;
  215.  
  216.     while (dp) {
  217.         if (dp->_d_entry)
  218.             free(dp->_d_entry);
  219.         dp = (odp = dp)->_d_next;
  220.         free((char *) odp);
  221.     }
  222. }
  223.  
  224. static    char    *
  225. getdirent(dir)
  226.     char    *dir;
  227. {
  228.     if (dir != (char *) NULL) {        /* get first entry */
  229.         reg.h.ah = DOSI_FINDF;
  230.         reg.h.cl = ATTRIBUTES;
  231. #if    defined(LARGE_DATA)
  232.         reg.x.dx = FP_OFF(dir);
  233.         sreg.ds = FP_SEG(dir);
  234. #else
  235.         reg.x.dx = (unsigned) dir;
  236. #endif
  237.     } else {                /* get next entry */
  238.         reg.h.ah = DOSI_FINDN;
  239. #if    defined(LARGE_DATA)
  240.         reg.x.dx = FP_OFF(dtapnt);
  241.         sreg.ds = FP_SEG(dtapnt);
  242. #else
  243.         reg.x.dx = (unsigned) dtapnt;
  244. #endif
  245.     }
  246. #if    defined(LARGE_DATA)
  247.     intdosx(®, &nreg, &sreg);
  248. #else
  249.     intdos(®, &nreg);
  250. #endif
  251.     if (nreg.x.cflag)
  252.         return (char *) NULL;
  253.  
  254.     return dtabuf.d_name;
  255. }
  256.  
  257. static    void
  258. _setdta()
  259. {
  260.     reg.h.ah = DOSI_SDTA;
  261. #if    defined(LARGE_DATA)
  262.     reg.x.dx = FP_OFF(dtapnt);
  263.     sreg.ds = FP_SEG(dtapnt);
  264.     intdosx(®, &nreg, &sreg);
  265. #else
  266.     reg.x.dx = (int) dtapnt;
  267.     intdos(®, &nreg);
  268. #endif
  269. }
  270.         
  271.