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),
25 # define MAXPATHLEN 255
26 #endif /* MAXPATHLEN */
34 #define A_ARCHIVE 0x20
37 #define DOSI_FINDF 0x4e
38 #define DOSI_FINDN 0x4f
39 #define DOSI_SDTA 0x1a
41 #define Newisnull(a, t) ((a = (t *) malloc(sizeof(t))) == (t *) NULL)
42 /* #define ATTRIBUTES (A_DIR | A_HIDDEN | A_SYSTEM) */
43 #define ATTRIBUTES (A_RONLY | A_SYSTEM | A_DIR)
45 /* what find first/next calls look use */
50 unsigned short d_time;
51 unsigned short d_date;
58 static char *getdirent ();
59 static void mysetdta ();
60 static void free_dircontents ();
62 static Dta_buf dtabuf;
63 static Dta_buf *dtapnt = &dtabuf;
64 static union REGS reg, nreg;
67 static struct SREGS sreg;
78 struct _dircontents *dp;
79 char nbuf[MAXPATHLEN + 1];
81 if (stat (name, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
83 if (Newisnull (dirp, DIR))
85 if (*name && (c = name[strlen (name) - 1]) != '\\' && c != '/')
86 (void) strcat (strcpy (nbuf, name), "\\*.*");
88 (void) strcat (strcpy (nbuf, name), "*.*");
91 dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
92 if ((s = getdirent (nbuf)) == (char *) NULL)
96 if (Newisnull (dp, struct _dircontents) || (dp->_d_entry =
97 malloc ((unsigned) (strlen (s) + 1))) == (char *) NULL)
101 free_dircontents (dirp->dd_contents);
104 if (dirp->dd_contents)
105 dirp->dd_cp = dirp->dd_cp->_d_next = dp;
107 dirp->dd_contents = dirp->dd_cp = dp;
108 (void) strcpy (dp->_d_entry, s);
109 dp->_d_next = (struct _dircontents *) NULL;
111 while ((s = getdirent ((char *) NULL)) != (char *) NULL);
112 dirp->dd_cp = dirp->dd_contents;
121 free_dircontents (dirp->dd_contents);
122 free ((char *) dirp);
129 static struct dirent dp;
131 if (dirp->dd_cp == (struct _dircontents *) NULL)
132 return (struct dirent *) NULL;
133 dp.d_namlen = dp.d_reclen =
134 strlen (strcpy (dp.d_name, dirp->dd_cp->_d_entry));
135 strlwr (dp.d_name); /* JF */
137 dirp->dd_cp = dirp->dd_cp->_d_next;
149 struct _dircontents *dp;
153 for (dp = dirp->dd_contents; --i >= 0 && dp; dp = dp->_d_next)
155 dirp->dd_loc = off - (i + 1);
167 free_dircontents (dp)
168 struct _dircontents *dp;
170 struct _dircontents *odp;
176 dp = (odp = dp)->_d_next;
185 if (dir != (char *) NULL)
186 { /* get first entry */
187 reg.h.ah = DOSI_FINDF;
188 reg.h.cl = ATTRIBUTES;
190 reg.x.dx = FP_OFF (dir);
191 sreg.ds = FP_SEG (dir);
193 reg.x.dx = (unsigned) dir;
197 { /* get next entry */
198 reg.h.ah = DOSI_FINDN;
200 reg.x.dx = FP_OFF (dtapnt);
201 sreg.ds = FP_SEG (dtapnt);
203 reg.x.dx = (unsigned) dtapnt;
207 intdosx (®, &nreg, &sreg);
209 intdos (®, &nreg);
212 return (char *) NULL;
214 return dtabuf.d_name;
220 reg.h.ah = DOSI_SDTA;
222 reg.x.dx = FP_OFF (dtapnt);
223 sreg.ds = FP_SEG (dtapnt);
224 intdosx (®, &nreg, &sreg);
226 reg.x.dx = (int) dtapnt;
227 intdos (®, &nreg);