123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- /*
- * @(#)msd_dir.c 1.4 87/11/06 Public Domain.
- *
- * A public domain implementation of BSD directory routines for
- * MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield),
- * August 1897
- */
- #include <sys/types.h>
- #include <sys/stat.h>
- #include "msd_dir.h"
- #ifndef __TURBOC__
- #include <malloc.h>
- #endif
- #include <string.h>
- #include <dos.h>
- #ifndef NULL
- # define NULL 0
- #endif /* NULL */
- #ifndef MAXPATHLEN
- # define MAXPATHLEN 255
- #endif /* MAXPATHLEN */
- /* attribute stuff */
- #define A_RONLY 0x01
- #define A_HIDDEN 0x02
- #define A_SYSTEM 0x04
- #define A_LABEL 0x08
- #define A_DIR 0x10
- #define A_ARCHIVE 0x20
- /* dos call values */
- #define DOSI_FINDF 0x4e
- #define DOSI_FINDN 0x4f
- #define DOSI_SDTA 0x1a
- #define Newisnull(a, t) ((a = (t *) malloc(sizeof(t))) == (t *) NULL)
- /* #define ATTRIBUTES (A_DIR | A_HIDDEN | A_SYSTEM) */
- #define ATTRIBUTES (A_RONLY | A_SYSTEM | A_DIR)
- /* what find first/next calls look use */
- typedef struct {
- char d_buf[21];
- char d_attribute;
- unsigned short d_time;
- unsigned short d_date;
- long d_size;
- char d_name[13];
- } Dta_buf;
- static char *getdirent();
- static void mysetdta();
- static void free_dircontents();
- static Dta_buf dtabuf;
- static Dta_buf *dtapnt = &dtabuf;
- static union REGS reg, nreg;
- #if defined(M_I86LM)
- static struct SREGS sreg;
- #endif
- DIR *
- opendir(name)
- char *name;
- {
- struct stat statb;
- DIR *dirp;
- char c;
- char *s;
- struct _dircontents *dp;
- char nbuf[MAXPATHLEN + 1];
-
- if (stat(name, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
- return (DIR *) NULL;
- if (Newisnull(dirp, DIR))
- return (DIR *) NULL;
- if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/')
- (void) strcat(strcpy(nbuf, name), "\\*.*");
- else
- (void) strcat(strcpy(nbuf, name), "*.*");
- dirp->dd_loc = 0;
- mysetdta();
- dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
- if ((s = getdirent(nbuf)) == (char *) NULL)
- return dirp;
- do {
- if (Newisnull(dp, struct _dircontents) || (dp->_d_entry =
- malloc((unsigned) (strlen(s) + 1))) == (char *) NULL)
- {
- if (dp)
- free((char *) dp);
- free_dircontents(dirp->dd_contents);
- return (DIR *) NULL;
- }
- if (dirp->dd_contents)
- dirp->dd_cp = dirp->dd_cp->_d_next = dp;
- else
- dirp->dd_contents = dirp->dd_cp = dp;
- (void) strcpy(dp->_d_entry, s);
- dp->_d_next = (struct _dircontents *) NULL;
- } while ((s = getdirent((char *) NULL)) != (char *) NULL);
- dirp->dd_cp = dirp->dd_contents;
- return dirp;
- }
- void
- closedir(dirp)
- DIR *dirp;
- {
- free_dircontents(dirp->dd_contents);
- free((char *) dirp);
- }
- struct dirent *
- readdir(dirp)
- DIR *dirp;
- {
- static struct dirent dp;
-
- if (dirp->dd_cp == (struct _dircontents *) NULL)
- return (struct dirent *) NULL;
- dp.d_namlen = dp.d_reclen =
- strlen(strcpy(dp.d_name, dirp->dd_cp->_d_entry));
- strlwr(dp.d_name); /* JF */
- dp.d_ino = 0;
- dirp->dd_cp = dirp->dd_cp->_d_next;
- dirp->dd_loc++;
- return &dp;
- }
- void
- seekdir(dirp, off)
- DIR *dirp;
- long off;
- {
- long i = off;
- struct _dircontents *dp;
- if (off < 0)
- return;
- for (dp = dirp->dd_contents ; --i >= 0 && dp ; dp = dp->_d_next)
- ;
- dirp->dd_loc = off - (i + 1);
- dirp->dd_cp = dp;
- }
- long
- telldir(dirp)
- DIR *dirp;
- {
- return dirp->dd_loc;
- }
- static void
- free_dircontents(dp)
- struct _dircontents *dp;
- {
- struct _dircontents *odp;
- while (dp) {
- if (dp->_d_entry)
- free(dp->_d_entry);
- dp = (odp = dp)->_d_next;
- free((char *) odp);
- }
- }
- static char *
- getdirent(dir)
- char *dir;
- {
- if (dir != (char *) NULL) { /* get first entry */
- reg.h.ah = DOSI_FINDF;
- reg.h.cl = ATTRIBUTES;
- #if defined(M_I86LM)
- reg.x.dx = FP_OFF(dir);
- sreg.ds = FP_SEG(dir);
- #else
- reg.x.dx = (unsigned) dir;
- #endif
- } else { /* get next entry */
- reg.h.ah = DOSI_FINDN;
- #if defined(M_I86LM)
- reg.x.dx = FP_OFF(dtapnt);
- sreg.ds = FP_SEG(dtapnt);
- #else
- reg.x.dx = (unsigned) dtapnt;
- #endif
- }
- #if defined(M_I86LM)
- intdosx(®, &nreg, &sreg);
- #else
- intdos(®, &nreg);
- #endif
- if (nreg.x.cflag)
- return (char *) NULL;
- return dtabuf.d_name;
- }
- static void
- mysetdta()
- {
- reg.h.ah = DOSI_SDTA;
- #if defined(M_I86LM)
- reg.x.dx = FP_OFF(dtapnt);
- sreg.ds = FP_SEG(dtapnt);
- intdosx(®, &nreg, &sreg);
- #else
- reg.x.dx = (int) dtapnt;
- intdos(®, &nreg);
- #endif
- }
|