home *** CD-ROM | disk | FTP | other *** search
- From: guido@cwi.nl.UUCP (Guido van Rossum)
- Newsgroups: comp.sources.misc
- Subject: {open,read,close}dir for MS-DOS
- Message-ID: <2930@ncoast.UUCP>
- Date: 17 Jul 87 22:29:56 GMT
- Sender: allbery@ncoast.UUCP
- Lines: 248
- Approved: allbery@ncoast.UUCP
- X-Archive: comp.sources.misc/8707/51
-
- Since Rich Salz in comp.sources.unix asked for MS-DOS (and other)
- implementations of Doug Gwyn's directory package, here's what I am using
- myself. It's only opendir, readdir and closedir, but I've written
- several programs that use it and port problemless between several Unix
- flavours, MS-DOS and the Apple Macintosh.
- --
- Guido van Rossum, Centre for Mathematics and Computer Science (CWI), Amsterdam
- guido@cwi.nl or mcvax!guido or (from ARPAnet) guido%cwi.nl@seismo.css.gov
-
- : This is a shell archive.
- : Extract with 'sh this_file'.
- echo 'Start of pack.out, part 01 out of 01:'
- echo 'x - README'
- sed 's/^X//' > 'README' << 'EOF'
- XHere's something for MS-DOS that makes it easier to port Unix programs
- Xthat scan directories: an implementation of opendir, readdir and
- Xclosedir.
- X
- XIt's a rather minimal implementation, e.g., it allows only one open
- Xdirectory at a time, and there are no rewinddir, telldir and seekdir,
- Xbut I suspect these are much less used than readdir.
- X
- XThis works with Microsoft C 4.0 (and also used to work with 3.0).
- XOwners of other compilers are on their own.
- X
- XBeing sick and tired of copyright wars I hereby place this code in the
- Xpublic domain, although it would still be nice if my name remained in
- Xredistributed or changed copies of the source.
- X
- XGuido van Rossum
- XCWI, dept. AA
- XKruislaan 413
- X1098 SJ Amsterdam
- X
- XPhone: + 20 - 5924138
- X
- XE-mail: guido@cwi.nl
- EOF
- echo 'x - dir.c'
- sed 's/^X//' > 'dir.c' << 'EOF'
- X/*
- X * MS-DOS version of UNIX directory access package.
- X * (opendir, readdir, closedir).
- X * Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
- X */
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <errno.h>
- X#include <dos.h>
- Xextern int errno;
- X#define MAXPATH 64
- X
- X#include "dir.h"
- Xstatic char *firstf();
- Xstatic char *nextf();
- X
- Xtypedef int bool;
- X#define TRUE 1
- X#define FALSE 0
- X#define EOS '\0'
- X#define NULL 0
- X
- Xstatic char dirpath[MAXPATH+1]= "";
- Xstatic bool busy= FALSE;
- X
- X/*
- X * Open a directory.
- X * This MS-DOS version allows only one directory to be open at a time.
- X * The path must exist and be a directory.
- X * Then it only saves the file name and returns a pointer to it.
- X */
- X
- Xchar *
- Xopendir(path)
- X char *path;
- X{
- X struct stat buffer;
- X
- X if (dirpath[0] != EOS) {
- X errno= EMFILE;
- X return NULL; /* Only one directory can be open at a time */
- X }
- X if (stat(path, &buffer) == -1)
- X return NULL; /* Directory doesn't exist */
- X if ((buffer.st_mode & S_IFMT) != S_IFDIR) {
- X errno= ENOENT;
- X return NULL; /* Not a directory */
- X }
- X strcpy(dirpath, path);
- X path= dirpath + strlen(dirpath);
- X if (path > dirpath && path[-1] != ':' && path[-1] != '/' &&
- X path[-1] != '\\')
- X *path++ = '\\';
- X strcpy(path, "*.*");
- X busy= FALSE; /* Tell readdir this is the first time */
- X return dirpath;
- X}
- X
- X/*
- X * Close a directory.
- X * We must clear the first char of dirpath to signal opendir that
- X * no directory is open.
- X */
- X
- Xclosedir(dirp)
- X char *dirp;
- X{
- X dirp[0]= EOS;
- X}
- X
- X/*
- X * Read the next directory entry.
- X */
- X
- Xstruct direct *
- Xreaddir(dp)
- X char *dp;
- X{
- X static struct direct buffer;
- X char *p;
- X
- X if (!busy)
- X p= firstf(dp);
- X else
- X p= nextf();
- X busy= (p != NULL);
- X if (!busy)
- X return NULL;
- X strcpy(buffer.d_name, p);
- X buffer.d_namlen= strlen(p);
- X return &buffer;
- X}
- X
- X/*
- X * Low-level implementation -- access to DOS system calls FIRST and NEXT.
- X */
- X
- Xstatic char dta[64]; /* Device Transfer Area */
- X
- X/* File attributes */
- X#define READONLY 0x01
- X#define HIDDEN 0x02
- X#define SYSTEM 0x04
- X#define VOLUMEID 0x08
- X#define DIRECTORY 0x10
- X#define ARCHIVE 0x20
- X
- X#define MATCHATTR (HIDDEN|SYSTEM|DIRECTORY)
- X
- Xstatic char *
- Xfirstf(pat)
- X char *pat;
- X{
- X int flags;
- X union REGS regs;
- X struct SREGS segregs;
- X
- X setdta(dta);
- X
- X segread(&segregs);
- X regs.h.ah = 0x4e;
- X regs.x.cx = MATCHATTR;
- X#ifdef M_I86LM /* Large Model -- far pointers */
- X regs.x.dx = FP_OFF(pat);
- X segregs.ds = FP_SEG(pat);
- X#else
- X regs.x.dx = (int) pat;
- X#endif
- X flags= intdosx(®s, ®s, &segregs);
- X if (regs.x.cflag)
- X return NULL;
- X fixfile();
- X return dta + 30;
- X}
- X
- Xstatic char *
- Xnextf()
- X{
- X int flags;
- X union REGS regs;
- X
- X setdta(dta);
- X
- X regs.h.ah = 0x4f;
- X flags= intdos(®s, ®s);
- X if (regs.x.cflag)
- X return NULL;
- X fixfile();
- X return dta + 30;
- X}
- X
- X/*
- X * Convert the file name in the Device Transfer Area to lower case.
- X */
- X
- Xstatic
- Xfixfile()
- X{
- X char *cp;
- X
- X for (cp= dta+30; *cp != EOS; ++cp)
- X *cp= tolower(*cp);
- X}
- X
- X/*
- X * Tell MS-DOS where the Device Transfer Area is.
- X */
- X
- Xstatic
- Xsetdta(dta)
- X char *dta;
- X{
- X union REGS regs;
- X struct SREGS segregs;
- X
- X segread(&segregs);
- X regs.h.ah = 0x1a;
- X#ifdef M_I86LM /* Large Model -- far pointers */
- X regs.x.dx = FP_OFF(dta);
- X segregs.ds = FP_SEG(dta);
- X#else
- X regs.x.dx = (int) dta;
- X#endif
- X intdosx(®s, ®s, &segregs);
- X}
- EOF
- echo 'x - dir.h'
- sed 's/^X//' > 'dir.h' << 'EOF'
- X/*
- X * Interface for MS-DOS version of UNIX directory access package.
- X * (opendir, readdir, closedir).
- X * Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
- X */
- X
- Xstruct direct {
- X char d_namlen;
- X char d_name[13];
- X};
- X
- Xtypedef char DIR;
- X
- XDIR *opendir();
- Xstruct direct *readdir();
- EOF
- echo 'Part 01 out of 01 of pack.out complete.'
- exit 0
-