home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume1 / 8707 / 51 < prev    next >
Encoding:
Internet Message Format  |  1990-07-13  |  5.5 KB

  1. From: guido@cwi.nl.UUCP (Guido van Rossum)
  2. Newsgroups: comp.sources.misc
  3. Subject: {open,read,close}dir for MS-DOS
  4. Message-ID: <2930@ncoast.UUCP>
  5. Date: 17 Jul 87 22:29:56 GMT
  6. Sender: allbery@ncoast.UUCP
  7. Lines: 248
  8. Approved: allbery@ncoast.UUCP
  9. X-Archive: comp.sources.misc/8707/51
  10.  
  11. Since Rich Salz in comp.sources.unix asked for MS-DOS (and other)
  12. implementations of Doug Gwyn's directory package, here's what I am using
  13. myself.  It's only opendir, readdir and closedir, but I've written
  14. several programs that use it and port problemless between several Unix
  15. flavours, MS-DOS and the Apple Macintosh.
  16. --
  17. Guido van Rossum, Centre for Mathematics and Computer Science (CWI), Amsterdam
  18. guido@cwi.nl or mcvax!guido or (from ARPAnet) guido%cwi.nl@seismo.css.gov
  19.  
  20. : This is a shell archive.
  21. : Extract with 'sh this_file'.
  22. echo 'Start of pack.out, part 01 out of 01:'
  23. echo 'x - README'
  24. sed 's/^X//' > 'README' << 'EOF'
  25. XHere's something for MS-DOS that makes it easier to port Unix programs
  26. Xthat scan directories: an implementation of opendir, readdir and
  27. Xclosedir.
  28. X
  29. XIt's a rather minimal implementation, e.g., it allows only one open
  30. Xdirectory at a time, and there are no rewinddir, telldir and seekdir,
  31. Xbut I suspect these are much less used than readdir.
  32. X
  33. XThis works with Microsoft C 4.0 (and also used to work with 3.0).
  34. XOwners of other compilers are on their own.
  35. X
  36. XBeing sick and tired of copyright wars I hereby place this code in the
  37. Xpublic domain, although it would still be nice if my name remained in
  38. Xredistributed or changed copies of the source.
  39. X
  40. XGuido van Rossum
  41. XCWI, dept. AA
  42. XKruislaan 413
  43. X1098 SJ  Amsterdam
  44. X
  45. XPhone: + 20 - 5924138
  46. X
  47. XE-mail: guido@cwi.nl
  48. EOF
  49. echo 'x - dir.c'
  50. sed 's/^X//' > 'dir.c' << 'EOF'
  51. X/*
  52. X * MS-DOS version of UNIX directory access package.
  53. X * (opendir, readdir, closedir).
  54. X * Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
  55. X */
  56. X
  57. X#include <sys/types.h>
  58. X#include <sys/stat.h>
  59. X#include <errno.h>
  60. X#include <dos.h>
  61. Xextern int errno;
  62. X#define MAXPATH 64
  63. X
  64. X#include "dir.h"
  65. Xstatic char *firstf();
  66. Xstatic char *nextf();
  67. X
  68. Xtypedef int bool;
  69. X#define TRUE 1
  70. X#define FALSE 0
  71. X#define EOS '\0'
  72. X#define NULL 0
  73. X
  74. Xstatic char dirpath[MAXPATH+1]= "";
  75. Xstatic bool busy= FALSE;
  76. X
  77. X/*
  78. X * Open a directory.
  79. X * This MS-DOS version allows only one directory to be open at a time.
  80. X * The path must exist and be a directory.
  81. X * Then it only saves the file name and returns a pointer to it.
  82. X */
  83. X
  84. Xchar *
  85. Xopendir(path)
  86. X    char *path;
  87. X{
  88. X    struct stat buffer;
  89. X
  90. X    if (dirpath[0] != EOS) {
  91. X         errno= EMFILE;
  92. X         return NULL; /* Only one directory can be open at a time */
  93. X    }
  94. X    if (stat(path, &buffer) == -1)
  95. X        return NULL; /* Directory doesn't exist */
  96. X    if ((buffer.st_mode & S_IFMT) != S_IFDIR) {
  97. X        errno= ENOENT;
  98. X        return NULL; /* Not a directory */
  99. X    }
  100. X    strcpy(dirpath, path);
  101. X    path= dirpath + strlen(dirpath);
  102. X    if (path > dirpath && path[-1] != ':' && path[-1] != '/' &&
  103. X            path[-1] != '\\')
  104. X        *path++ = '\\';
  105. X    strcpy(path, "*.*");
  106. X    busy= FALSE; /* Tell readdir this is the first time */
  107. X    return dirpath;
  108. X}
  109. X
  110. X/*
  111. X * Close a directory.
  112. X * We must clear the first char of dirpath to signal opendir that
  113. X * no directory is open.
  114. X */
  115. X
  116. Xclosedir(dirp)
  117. X    char *dirp;
  118. X{
  119. X    dirp[0]= EOS;
  120. X}
  121. X
  122. X/*
  123. X * Read the next directory entry.
  124. X */
  125. X
  126. Xstruct direct *
  127. Xreaddir(dp)
  128. X    char *dp;
  129. X{
  130. X    static struct direct buffer;
  131. X    char *p;
  132. X
  133. X    if (!busy)
  134. X        p= firstf(dp);
  135. X    else
  136. X        p= nextf();
  137. X    busy= (p != NULL);
  138. X    if (!busy)
  139. X        return NULL;
  140. X    strcpy(buffer.d_name, p);
  141. X    buffer.d_namlen= strlen(p);
  142. X    return &buffer;
  143. X}
  144. X
  145. X/*
  146. X * Low-level implementation -- access to DOS system calls FIRST and NEXT.
  147. X */
  148. X
  149. Xstatic char dta[64]; /* Device Transfer Area */
  150. X
  151. X/* File attributes */
  152. X#define READONLY    0x01
  153. X#define HIDDEN        0x02
  154. X#define SYSTEM        0x04
  155. X#define VOLUMEID    0x08
  156. X#define DIRECTORY    0x10
  157. X#define ARCHIVE        0x20
  158. X
  159. X#define MATCHATTR    (HIDDEN|SYSTEM|DIRECTORY)
  160. X
  161. Xstatic char *
  162. Xfirstf(pat)
  163. X    char *pat;
  164. X{
  165. X    int flags;
  166. X    union REGS regs;
  167. X    struct SREGS segregs;
  168. X
  169. X    setdta(dta);
  170. X
  171. X    segread(&segregs);
  172. X    regs.h.ah = 0x4e;
  173. X    regs.x.cx = MATCHATTR;
  174. X#ifdef M_I86LM /* Large Model -- far pointers */
  175. X    regs.x.dx = FP_OFF(pat);
  176. X    segregs.ds = FP_SEG(pat);
  177. X#else
  178. X    regs.x.dx = (int) pat;
  179. X#endif
  180. X    flags= intdosx(®s, ®s, &segregs);
  181. X    if (regs.x.cflag)
  182. X    return NULL;
  183. X    fixfile();
  184. X    return dta + 30;
  185. X}
  186. X
  187. Xstatic char *
  188. Xnextf()
  189. X{
  190. X    int flags;
  191. X    union REGS regs;
  192. X
  193. X    setdta(dta);
  194. X
  195. X    regs.h.ah = 0x4f;
  196. X    flags= intdos(®s, ®s);
  197. X    if (regs.x.cflag)
  198. X    return NULL;
  199. X    fixfile();
  200. X    return dta + 30;
  201. X}
  202. X
  203. X/*
  204. X * Convert the file name in the Device Transfer Area to lower case.
  205. X */
  206. X
  207. Xstatic
  208. Xfixfile()
  209. X{
  210. X    char *cp;
  211. X
  212. X    for (cp= dta+30; *cp != EOS; ++cp)
  213. X        *cp= tolower(*cp);
  214. X}
  215. X
  216. X/*
  217. X * Tell MS-DOS where the Device Transfer Area is.
  218. X */
  219. X
  220. Xstatic
  221. Xsetdta(dta)
  222. X    char *dta;
  223. X{
  224. X    union REGS regs;
  225. X    struct SREGS segregs;
  226. X
  227. X    segread(&segregs);
  228. X    regs.h.ah = 0x1a;
  229. X#ifdef M_I86LM /* Large Model -- far pointers */
  230. X    regs.x.dx = FP_OFF(dta);
  231. X    segregs.ds = FP_SEG(dta);
  232. X#else
  233. X    regs.x.dx = (int) dta;
  234. X#endif
  235. X    intdosx(®s, ®s, &segregs);
  236. X}
  237. EOF
  238. echo 'x - dir.h'
  239. sed 's/^X//' > 'dir.h' << 'EOF'
  240. X/*
  241. X * Interface for MS-DOS version of UNIX directory access package.
  242. X * (opendir, readdir, closedir).
  243. X * Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
  244. X */
  245. X
  246. Xstruct direct {
  247. X    char d_namlen;
  248. X    char d_name[13];
  249. X};
  250. X
  251. Xtypedef char DIR;
  252. X
  253. XDIR *opendir();
  254. Xstruct direct *readdir();
  255. EOF
  256. echo 'Part 01 out of 01 of pack.out complete.'
  257. exit 0
  258.