msd_dir.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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. #include <sys/types.h>
  9. #include <sys/stat.h>
  10. #include "msd_dir.h"
  11. #ifndef __TURBOC__
  12. #include <malloc.h>
  13. #endif
  14. #include <string.h>
  15. #include <dos.h>
  16. #ifndef NULL
  17. # define NULL 0
  18. #endif /* NULL */
  19. #ifndef MAXPATHLEN
  20. # define MAXPATHLEN 255
  21. #endif /* MAXPATHLEN */
  22. /* attribute stuff */
  23. #define A_RONLY 0x01
  24. #define A_HIDDEN 0x02
  25. #define A_SYSTEM 0x04
  26. #define A_LABEL 0x08
  27. #define A_DIR 0x10
  28. #define A_ARCHIVE 0x20
  29. /* dos call values */
  30. #define DOSI_FINDF 0x4e
  31. #define DOSI_FINDN 0x4f
  32. #define DOSI_SDTA 0x1a
  33. #define Newisnull(a, t) ((a = (t *) malloc(sizeof(t))) == (t *) NULL)
  34. /* #define ATTRIBUTES (A_DIR | A_HIDDEN | A_SYSTEM) */
  35. #define ATTRIBUTES (A_RONLY | A_SYSTEM | A_DIR)
  36. /* what find first/next calls look use */
  37. typedef struct {
  38. char d_buf[21];
  39. char d_attribute;
  40. unsigned short d_time;
  41. unsigned short d_date;
  42. long d_size;
  43. char d_name[13];
  44. } Dta_buf;
  45. static char *getdirent();
  46. static void mysetdta();
  47. static void free_dircontents();
  48. static Dta_buf dtabuf;
  49. static Dta_buf *dtapnt = &dtabuf;
  50. static union REGS reg, nreg;
  51. #if defined(M_I86LM)
  52. static struct SREGS sreg;
  53. #endif
  54. DIR *
  55. opendir(name)
  56. char *name;
  57. {
  58. struct stat statb;
  59. DIR *dirp;
  60. char c;
  61. char *s;
  62. struct _dircontents *dp;
  63. char nbuf[MAXPATHLEN + 1];
  64. if (stat(name, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
  65. return (DIR *) NULL;
  66. if (Newisnull(dirp, DIR))
  67. return (DIR *) NULL;
  68. if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/')
  69. (void) strcat(strcpy(nbuf, name), "\\*.*");
  70. else
  71. (void) strcat(strcpy(nbuf, name), "*.*");
  72. dirp->dd_loc = 0;
  73. mysetdta();
  74. dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
  75. if ((s = getdirent(nbuf)) == (char *) NULL)
  76. return dirp;
  77. do {
  78. if (Newisnull(dp, struct _dircontents) || (dp->_d_entry =
  79. malloc((unsigned) (strlen(s) + 1))) == (char *) NULL)
  80. {
  81. if (dp)
  82. free((char *) dp);
  83. free_dircontents(dirp->dd_contents);
  84. return (DIR *) NULL;
  85. }
  86. if (dirp->dd_contents)
  87. dirp->dd_cp = dirp->dd_cp->_d_next = dp;
  88. else
  89. dirp->dd_contents = dirp->dd_cp = dp;
  90. (void) strcpy(dp->_d_entry, s);
  91. dp->_d_next = (struct _dircontents *) NULL;
  92. } while ((s = getdirent((char *) NULL)) != (char *) NULL);
  93. dirp->dd_cp = dirp->dd_contents;
  94. return dirp;
  95. }
  96. void
  97. closedir(dirp)
  98. DIR *dirp;
  99. {
  100. free_dircontents(dirp->dd_contents);
  101. free((char *) dirp);
  102. }
  103. struct dirent *
  104. readdir(dirp)
  105. DIR *dirp;
  106. {
  107. static struct dirent dp;
  108. if (dirp->dd_cp == (struct _dircontents *) NULL)
  109. return (struct dirent *) NULL;
  110. dp.d_namlen = dp.d_reclen =
  111. strlen(strcpy(dp.d_name, dirp->dd_cp->_d_entry));
  112. strlwr(dp.d_name); /* JF */
  113. dp.d_ino = 0;
  114. dirp->dd_cp = dirp->dd_cp->_d_next;
  115. dirp->dd_loc++;
  116. return &dp;
  117. }
  118. void
  119. seekdir(dirp, off)
  120. DIR *dirp;
  121. long off;
  122. {
  123. long i = off;
  124. struct _dircontents *dp;
  125. if (off < 0)
  126. return;
  127. for (dp = dirp->dd_contents ; --i >= 0 && dp ; dp = dp->_d_next)
  128. ;
  129. dirp->dd_loc = off - (i + 1);
  130. dirp->dd_cp = dp;
  131. }
  132. long
  133. telldir(dirp)
  134. DIR *dirp;
  135. {
  136. return dirp->dd_loc;
  137. }
  138. static void
  139. free_dircontents(dp)
  140. struct _dircontents *dp;
  141. {
  142. struct _dircontents *odp;
  143. while (dp) {
  144. if (dp->_d_entry)
  145. free(dp->_d_entry);
  146. dp = (odp = dp)->_d_next;
  147. free((char *) odp);
  148. }
  149. }
  150. static char *
  151. getdirent(dir)
  152. char *dir;
  153. {
  154. if (dir != (char *) NULL) { /* get first entry */
  155. reg.h.ah = DOSI_FINDF;
  156. reg.h.cl = ATTRIBUTES;
  157. #if defined(M_I86LM)
  158. reg.x.dx = FP_OFF(dir);
  159. sreg.ds = FP_SEG(dir);
  160. #else
  161. reg.x.dx = (unsigned) dir;
  162. #endif
  163. } else { /* get next entry */
  164. reg.h.ah = DOSI_FINDN;
  165. #if defined(M_I86LM)
  166. reg.x.dx = FP_OFF(dtapnt);
  167. sreg.ds = FP_SEG(dtapnt);
  168. #else
  169. reg.x.dx = (unsigned) dtapnt;
  170. #endif
  171. }
  172. #if defined(M_I86LM)
  173. intdosx(&reg, &nreg, &sreg);
  174. #else
  175. intdos(&reg, &nreg);
  176. #endif
  177. if (nreg.x.cflag)
  178. return (char *) NULL;
  179. return dtabuf.d_name;
  180. }
  181. static void
  182. mysetdta()
  183. {
  184. reg.h.ah = DOSI_SDTA;
  185. #if defined(M_I86LM)
  186. reg.x.dx = FP_OFF(dtapnt);
  187. sreg.ds = FP_SEG(dtapnt);
  188. intdosx(&reg, &nreg, &sreg);
  189. #else
  190. reg.x.dx = (int) dtapnt;
  191. intdos(&reg, &nreg);
  192. #endif
  193. }