home *** CD-ROM | disk | FTP | other *** search
/ ftp.muug.mb.ca / 2014.06.ftp.muug.mb.ca.tar / ftp.muug.mb.ca / pub / src / perl / msdos / directory.c < prev    next >
C/C++ Source or Header  |  1992-04-11  |  4KB  |  184 lines

  1. /* $RCSfile: directory.c,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:22:24 $
  2.  *
  3.  *    (C) Copyright 1987, 1988, 1990 Diomidis Spinellis.
  4.  *
  5.  *    You may distribute under the terms of either the GNU General Public
  6.  *    License or the Artistic License, as specified in the README file.
  7.  *
  8.  * $Log:    directory.c,v $
  9.  * Revision 4.0.1.1  91/06/07  11:22:24  lwall
  10.  * patch4: new copyright notice
  11.  * 
  12.  * Revision 4.0  91/03/20  01:34:24  lwall
  13.  * 4.0 baseline.
  14.  * 
  15.  * Revision 3.0.1.1  90/03/27  16:07:37  lwall
  16.  * patch16: MSDOS support
  17.  * 
  18.  * Revision 1.3  90/03/16  22:39:40  dds
  19.  * Fixed malloc problem.
  20.  *
  21.  * Revision 1.2  88/07/23  00:08:39  dds
  22.  * Added inode non-zero filling.
  23.  *
  24.  * Revision 1.1  88/07/23  00:03:50  dds
  25.  * Initial revision
  26.  *
  27.  */
  28.  
  29. /*
  30.  * UNIX compatible directory access functions
  31.  */
  32.  
  33. #include <sys/types.h>
  34. #include <sys/dir.h>
  35. #include <stddef.h>
  36. #include <stdlib.h>
  37. #include <string.h>
  38. #include <dos.h>
  39. #include <ctype.h>
  40.  
  41. /*
  42.  * File names are converted to lowercase if the
  43.  * CONVERT_TO_LOWER_CASE variable is defined.
  44.  */
  45. #define CONVERT_TO_LOWER_CASE
  46.  
  47. #define PATHLEN 65
  48.  
  49. #ifndef lint
  50. static char rcsid[] = "$RCSfile: directory.c,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:22:24 $";
  51. #endif
  52.  
  53. DIR *
  54. opendir(char *filename)
  55. {
  56.     DIR            *p;
  57.     char           *oldresult, *result;
  58.     union REGS      srv;
  59.     struct SREGS    segregs;
  60.     register        reslen = 0;
  61.     char            scannamespc[PATHLEN];
  62.     char        *scanname = scannamespc;    /* To take address we need a pointer */
  63.  
  64.     /*
  65.      * Structure used by the MS-DOS directory system calls.
  66.      */
  67.     struct dir_buff {
  68.         char            reserved[21];    /* Reserved for MS-DOS */
  69.         unsigned char   attribute;    /* Attribute */
  70.         unsigned int    time;        /* Time */
  71.         unsigned int    date;        /* Date */
  72.         long            size;        /* Size of file */
  73.         char            fn[13];        /* Filename */
  74.     } buffspc, *buff = &buffspc;
  75.  
  76.  
  77.     if (!(p = (DIR *) malloc(sizeof(DIR))))
  78.         return NULL;
  79.  
  80.     /* Initialize result to use realloc on it */
  81.     if (!(result = malloc(1))) {
  82.         free(p);
  83.         return NULL;
  84.     }
  85.  
  86.     /* Create the search pattern */
  87.     strcpy(scanname, filename);
  88.     if (strchr("/\\", *(scanname + strlen(scanname) - 1)) == NULL)
  89.         strcat(scanname, "/*.*");
  90.     else
  91.         strcat(scanname, "*.*");
  92.  
  93.     segread(&segregs);
  94. #if ( defined(M_I86LM) || defined(M_I86CM) || defined(M_I86HM) )
  95.     segregs.ds = FP_SEG(buff);
  96.     srv.x.dx = FP_OFF(buff);
  97. #else
  98.     srv.x.dx = (unsigned int) buff;
  99. #endif
  100.     srv.h.ah = 0x1a;    /* Set DTA to DS:DX */
  101.     intdosx(&srv, &srv, &segregs);
  102.  
  103. #if ( defined(M_I86LM) || defined(M_I86CM) || defined(M_I86HM) )
  104.     segregs.ds = FP_SEG(scanname);
  105.     srv.x.dx = FP_OFF(scanname);
  106. #else
  107.     srv.x.dx = (unsigned int) scanname;
  108. #endif
  109.     srv.x.cx = 0xff;    /* Search mode */
  110.  
  111.     for (srv.h.ah = 0x4e; !intdosx(&srv, &srv, &segregs); srv.h.ah = 0x4f) {
  112.         if ((result = (char *) realloc(result, reslen + strlen(buff->fn) + 1)) ==
  113.  NULL) {
  114.             free(p);
  115.             free(oldresult);
  116.             return NULL;
  117.         }
  118.         oldresult = result;
  119. #ifdef CONVERT_TO_LOWER_CASE
  120.         strcpy(result + reslen, strlwr(buff->fn));
  121. #else
  122.         strcpy(result + reslen, buff->fn);
  123. #endif
  124.         reslen += strlen(buff->fn) + 1;
  125.     }
  126.  
  127.     if (!(result = realloc(result, reslen + 1))) {
  128.         free(p);
  129.         free(oldresult);
  130.         return NULL;
  131.     } else {
  132.         p->start = result;
  133.         p->curr = result;
  134.         *(result + reslen) = '\0';
  135.         return p;
  136.     }
  137. }
  138.  
  139.  
  140. struct direct  *
  141. readdir(DIR *dirp)
  142. {
  143.     char           *p;
  144.     register        len;
  145.     static          dummy;
  146.  
  147.     p = dirp->curr;
  148.     len = strlen(p);
  149.     if (*p) {
  150.         dirp->curr += len + 1;
  151.         strcpy(dirp->dirstr.d_name, p);
  152.         dirp->dirstr.d_namlen = len;
  153.         /* To fool programs */
  154.         dirp->dirstr.d_ino = ++dummy;
  155.         return &(dirp->dirstr);
  156.     } else
  157.         return NULL;
  158. }
  159.  
  160. long
  161. telldir(DIR *dirp)
  162. {
  163.     return (long) dirp->curr;    /* ouch! pointer to long cast */
  164. }
  165.  
  166. void
  167. seekdir(DIR *dirp, long loc)
  168. {
  169.     dirp->curr = (char *) loc;    /* ouch! long to pointer cast */
  170. }
  171.  
  172. void
  173. rewinddir(DIR *dirp)
  174. {
  175.     dirp->curr = dirp->start;
  176. }
  177.  
  178. void
  179. closedir(DIR *dirp)
  180. {
  181.     free(dirp->start);
  182.     free(dirp);
  183. }
  184.