2 * @(#)msd_dir.c 1.4 87/11/06 Public Domain.
4 * A public domain implementation of BSD directory routines for
5 * MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield),
23 # define MAXPATHLEN 255
24 #endif /* MAXPATHLEN */
32 #define A_ARCHIVE 0x20
35 #define DOSI_FINDF 0x4e
36 #define DOSI_FINDN 0x4f
37 #define DOSI_SDTA 0x1a
39 #define Newisnull(a, t) ((a = (t *) malloc(sizeof(t))) == (t *) NULL)
40 /* #define ATTRIBUTES (A_DIR | A_HIDDEN | A_SYSTEM) */
41 #define ATTRIBUTES (A_RONLY | A_SYSTEM | A_DIR)
43 /* what find first/next calls look use */
47 unsigned short d_time;
48 unsigned short d_date;
53 static char *getdirent();
54 static void mysetdta();
55 static void free_dircontents();
57 static Dta_buf dtabuf;
58 static Dta_buf *dtapnt = &dtabuf;
59 static union REGS reg, nreg;
62 static struct SREGS sreg;
73 struct _dircontents *dp;
74 char nbuf[MAXPATHLEN + 1];
76 if (stat(name, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
78 if (Newisnull(dirp, DIR))
80 if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/')
81 (void) strcat(strcpy(nbuf, name), "\\*.*");
83 (void) strcat(strcpy(nbuf, name), "*.*");
86 dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
87 if ((s = getdirent(nbuf)) == (char *) NULL)
90 if (Newisnull(dp, struct _dircontents) || (dp->_d_entry =
91 malloc((unsigned) (strlen(s) + 1))) == (char *) NULL)
95 free_dircontents(dirp->dd_contents);
98 if (dirp->dd_contents)
99 dirp->dd_cp = dirp->dd_cp->_d_next = dp;
101 dirp->dd_contents = dirp->dd_cp = dp;
102 (void) strcpy(dp->_d_entry, s);
103 dp->_d_next = (struct _dircontents *) NULL;
104 } while ((s = getdirent((char *) NULL)) != (char *) NULL);
105 dirp->dd_cp = dirp->dd_contents;
114 free_dircontents(dirp->dd_contents);
122 static struct dirent dp;
124 if (dirp->dd_cp == (struct _dircontents *) NULL)
125 return (struct dirent *) NULL;
126 dp.d_namlen = dp.d_reclen =
127 strlen(strcpy(dp.d_name, dirp->dd_cp->_d_entry));
128 strlwr(dp.d_name); /* JF */
130 dirp->dd_cp = dirp->dd_cp->_d_next;
142 struct _dircontents *dp;
146 for (dp = dirp->dd_contents ; --i >= 0 && dp ; dp = dp->_d_next)
148 dirp->dd_loc = off - (i + 1);
161 struct _dircontents *dp;
163 struct _dircontents *odp;
168 dp = (odp = dp)->_d_next;
177 if (dir != (char *) NULL) { /* get first entry */
178 reg.h.ah = DOSI_FINDF;
179 reg.h.cl = ATTRIBUTES;
181 reg.x.dx = FP_OFF(dir);
182 sreg.ds = FP_SEG(dir);
184 reg.x.dx = (unsigned) dir;
186 } else { /* get next entry */
187 reg.h.ah = DOSI_FINDN;
189 reg.x.dx = FP_OFF(dtapnt);
190 sreg.ds = FP_SEG(dtapnt);
192 reg.x.dx = (unsigned) dtapnt;
196 intdosx(®, &nreg, &sreg);
201 return (char *) NULL;
203 return dtabuf.d_name;
209 reg.h.ah = DOSI_SDTA;
211 reg.x.dx = FP_OFF(dtapnt);
212 sreg.ds = FP_SEG(dtapnt);
213 intdosx(®, &nreg, &sreg);
215 reg.x.dx = (int) dtapnt;