home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1993 #2 / Image.iso / os2 / gtak212b.zip / SOURCE.ZIP / 1.10 / msd_dir.c < prev    next >
C/C++ Source or Header  |  1992-09-02  |  5KB  |  241 lines

  1. /*****************************************************************************
  2.  * $Id: msd_dir.c,v 1.2 1992/09/02 20:08:18 ak Exp $
  3.  *****************************************************************************
  4.  * $Log: msd_dir.c,v $
  5.  * Revision 1.2  1992/09/02  20:08:18  ak
  6.  * Version AK200
  7.  * - Tape access
  8.  * - Quick file access
  9.  * - OS/2 extended attributes
  10.  * - Some OS/2 fixes
  11.  * - Some fixes of Kai Uwe Rommel
  12.  *
  13.  * Revision 1.1.1.1  1992/09/02  19:22:02  ak
  14.  * Original GNU Tar 1.10 with some filenames changed for FAT compatibility.
  15.  *
  16.  * Revision 1.1  1992/09/02  19:22:00  ak
  17.  * Initial revision
  18.  *
  19.  *****************************************************************************/
  20.  
  21. static char *rcsid = "$Id: msd_dir.c,v 1.2 1992/09/02 20:08:18 ak Exp $";
  22.  
  23. /*
  24.  * @(#)msd_dir.c 1.4 87/11/06    Public Domain.
  25.  *
  26.  *  A public domain implementation of BSD directory routines for
  27.  *  MS-DOS.  Written by Michael Rendell ({uunet,utai}michael@garfield),
  28.  *  August 1897
  29.  */
  30.  
  31. #include    <sys/types.h>
  32. #include    <sys/stat.h>
  33. #include    "msd_dir.h"
  34. #ifndef __TURBOC__
  35. #include    <malloc.h>
  36. #endif
  37. #include    <string.h>
  38. #include    <dos.h>
  39.  
  40. #ifndef    NULL
  41. # define    NULL    0
  42. #endif    /* NULL */
  43.  
  44. #ifndef    MAXPATHLEN
  45. # define    MAXPATHLEN    255
  46. #endif    /* MAXPATHLEN */
  47.  
  48. /* attribute stuff */
  49. #define    A_RONLY        0x01
  50. #define    A_HIDDEN    0x02
  51. #define    A_SYSTEM    0x04
  52. #define    A_LABEL        0x08
  53. #define    A_DIR        0x10
  54. #define    A_ARCHIVE    0x20
  55.  
  56. /* dos call values */
  57. #define    DOSI_FINDF    0x4e
  58. #define    DOSI_FINDN    0x4f
  59. #define    DOSI_SDTA    0x1a
  60.  
  61. #define    Newisnull(a, t)        ((a = (t *) malloc(sizeof(t))) == (t *) NULL)
  62. /* #define    ATTRIBUTES        (A_DIR | A_HIDDEN | A_SYSTEM) */
  63. #define ATTRIBUTES    (A_RONLY | A_SYSTEM | A_DIR)
  64.  
  65. /* what find first/next calls look use */
  66. typedef struct {
  67.     char        d_buf[21];
  68.     char        d_attribute;
  69.     unsigned short    d_time;
  70.     unsigned short    d_date;
  71.     long        d_size;
  72.     char        d_name[13];
  73. } Dta_buf;
  74.  
  75. static    char    *getdirent();
  76. static    void    mysetdta();
  77. static    void    free_dircontents();
  78.  
  79. static    Dta_buf        dtabuf;
  80. static    Dta_buf        *dtapnt = &dtabuf;
  81. static    union REGS    reg, nreg;
  82.  
  83. #if    defined(M_I86LM)
  84. static    struct SREGS    sreg;
  85. #endif
  86.  
  87. DIR    *
  88. opendir(name)
  89.     char    *name;
  90. {
  91.     struct    stat        statb;
  92.     DIR            *dirp;
  93.     char            c;
  94.     char            *s;
  95.     struct _dircontents    *dp;
  96.     char            nbuf[MAXPATHLEN + 1];
  97.     
  98.     if (stat(name, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
  99.         return (DIR *) NULL;
  100.     if (Newisnull(dirp, DIR))
  101.         return (DIR *) NULL;
  102.     if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/')
  103.         (void) strcat(strcpy(nbuf, name), "\\*.*");
  104.     else
  105.         (void) strcat(strcpy(nbuf, name), "*.*");
  106.     dirp->dd_loc = 0;
  107.     mysetdta();
  108.     dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
  109.     if ((s = getdirent(nbuf)) == (char *) NULL)
  110.         return dirp;
  111.     do {
  112.         if (Newisnull(dp, struct _dircontents) || (dp->_d_entry =
  113.             malloc((unsigned) (strlen(s) + 1))) == (char *) NULL)
  114.         {
  115.             if (dp)
  116.                 free((char *) dp);
  117.             free_dircontents(dirp->dd_contents);
  118.             return (DIR *) NULL;
  119.         }
  120.         if (dirp->dd_contents)
  121.             dirp->dd_cp = dirp->dd_cp->_d_next = dp;
  122.         else
  123.             dirp->dd_contents = dirp->dd_cp = dp;
  124.         (void) strcpy(dp->_d_entry, s);
  125.         dp->_d_next = (struct _dircontents *) NULL;
  126.     } while ((s = getdirent((char *) NULL)) != (char *) NULL);
  127.     dirp->dd_cp = dirp->dd_contents;
  128.  
  129.     return dirp;
  130. }
  131.  
  132. void
  133. closedir(dirp)
  134.     DIR    *dirp;
  135. {
  136.     free_dircontents(dirp->dd_contents);
  137.     free((char *) dirp);
  138. }
  139.  
  140. struct direct    *
  141. readdir(dirp)
  142.     DIR    *dirp;
  143. {
  144.     static    struct direct    dp;
  145.     
  146.     if (dirp->dd_cp == (struct _dircontents *) NULL)
  147.         return (struct direct *) NULL;
  148.     dp.d_namlen = dp.d_reclen =
  149.         strlen(strcpy(dp.d_name, dirp->dd_cp->_d_entry));
  150.     strlwr(dp.d_name);        /* JF */
  151.     dp.d_ino = 0;
  152.     dirp->dd_cp = dirp->dd_cp->_d_next;
  153.     dirp->dd_loc++;
  154.  
  155.     return &dp;
  156. }
  157.  
  158. void
  159. seekdir(dirp, off)
  160.     DIR    *dirp;
  161.     long    off;
  162. {
  163.     long            i = off;
  164.     struct _dircontents    *dp;
  165.  
  166.     if (off < 0)
  167.         return;
  168.     for (dp = dirp->dd_contents ; --i >= 0 && dp ; dp = dp->_d_next)
  169.         ;
  170.     dirp->dd_loc = off - (i + 1);
  171.     dirp->dd_cp = dp;
  172. }
  173.  
  174. long
  175. telldir(dirp)
  176.     DIR    *dirp;
  177. {
  178.     return dirp->dd_loc;
  179. }
  180.  
  181. static    void
  182. free_dircontents(dp)
  183.     struct    _dircontents    *dp;
  184. {
  185.     struct _dircontents    *odp;
  186.  
  187.     while (dp) {
  188.         if (dp->_d_entry)
  189.             free(dp->_d_entry);
  190.         dp = (odp = dp)->_d_next;
  191.         free((char *) odp);
  192.     }
  193. }
  194.  
  195. static    char    *
  196. getdirent(dir)
  197.     char    *dir;
  198. {
  199.     if (dir != (char *) NULL) {        /* get first entry */
  200.         reg.h.ah = DOSI_FINDF;
  201.         reg.h.cl = ATTRIBUTES;
  202. #if    defined(M_I86LM)
  203.         reg.x.dx = FP_OFF(dir);
  204.         sreg.ds = FP_SEG(dir);
  205. #else
  206.         reg.x.dx = (unsigned) dir;
  207. #endif
  208.     } else {                /* get next entry */
  209.         reg.h.ah = DOSI_FINDN;
  210. #if    defined(M_I86LM)
  211.         reg.x.dx = FP_OFF(dtapnt);
  212.         sreg.ds = FP_SEG(dtapnt);
  213. #else
  214.         reg.x.dx = (unsigned) dtapnt;
  215. #endif
  216.     }
  217. #if    defined(M_I86LM)
  218.     intdosx(®, &nreg, &sreg);
  219. #else
  220.     intdos(®, &nreg);
  221. #endif
  222.     if (nreg.x.cflag)
  223.         return (char *) NULL;
  224.  
  225.     return dtabuf.d_name;
  226. }
  227.  
  228. static    void
  229. mysetdta()
  230. {
  231.     reg.h.ah = DOSI_SDTA;
  232. #if    defined(M_I86LM)
  233.     reg.x.dx = FP_OFF(dtapnt);
  234.     sreg.ds = FP_SEG(dtapnt);
  235.     intdosx(®, &nreg, &sreg);
  236. #else
  237.     reg.x.dx = (int) dtapnt;
  238.     intdos(®, &nreg);
  239. #endif
  240. }
  241.