5 Enclosed is an implementation of the `dirlib' package for MS-DOS.
6 The implementation is targeted for MS-C, although any reasonably
7 competent C compiler should manage. The package consists of:
11 testdir.c a q&d test program
13 The package tries to view directory naming in a Un*x light; in particular,
14 directories such as '/.' and '/..' (as well as `.' and `..' if your
15 current directory is root) are understood. Indefinite paths like
16 `/../.././../..' will correctly refer to the root (of the particular disk).
17 Names such as `a:////./../' are okay too.
19 I've tried to be as sensible about DTA's as possible, since you never
20 know who will be using one; they are set before use, and reset afterwards.
22 There is some cruft in the package, namely the way `seekdir' and
23 `telldir' are done. The code was derived from a little experimentation,
24 and may not work after a certain point (although I believe the 2.x version
25 to be solid). Caveat utilitor.
27 Documentation for the package is available in the public domain; the
28 package's functionality was derived from this documentation.
30 Bug reports and comments are welcome. Enjoy!
35 UUCP: {ucbvax,ihnp4,randvax,trwrb!trwspp,ism780}!ucla-cs!matt
36 ARPA: matt@LOCUS.UCLA.EDU
40 Modified for use in dmake by Dennis Vadura. Mostly just clean up and an
41 effort to make correctly typed objects are passed to functions in find.c.
42 Also deleted all dos version 2.0 specific code. It is not required any
49 * VER MM/DD/YY COMMENTS
50 * ---- -------- --------
51 * 0.99 02/24/86 Beta release to INTERNET
91 #define SUFFIX "\\*.*"
93 #define streq(a,b) (strcmp(a,b)==0)
106 * hack off drive designator if present
109 if (name
[1] == ':') {
110 cwd
= getdcwd(toupper(name
[0]) - 'A' + 1);
111 drive
[0] = name
[0]; drive
[1] = ':'; drive
[2] = '\0';
119 /* is the name 'rooted'? */
120 if ((*name
== '/') || (*name
== '\\')) ++rooted
;
122 /* see if we are at the root directory for this device */
126 * MSDOS '/' doesn't have a '.' or '..'
127 * also, double '/' sequences don't make sense.
128 * many ported programs expect them to work, so we fix it up...
131 /* chop off leading . and .. if at root */
132 if (atroot
&& (*name
== '.')) {
156 /* chop off leading /'s, /.'s and /..'s to make naming sensible */
157 while (*name
&& ((*name
== '/') || (*name
== '\\'))) {
158 if (*++name
== '.') {
186 * name should now look like: path/path/path
187 * we must now construct name based on whether or not it
188 * was 'rooted' (started with a /)
191 if (rooted
) cwd
= "";
194 if (!(nd
= (DIR *)malloc(
195 sizeof(DIR)+strlen(drive
)+strlen(cwd
)+strlen(SLASH
)+
196 strlen(name
)+strlen(SUFFIX
))))
199 /* create long name */
200 strcpy(nd
->dd_name
, drive
);
202 strcat(nd
->dd_name
, SLASH
);
203 strcat(nd
->dd_name
, cwd
);
206 strcat(nd
->dd_name
, SLASH
);
207 strcat(nd
->dd_name
, name
);
209 strcat(nd
->dd_name
, SUFFIX
);
212 if (!findfirst(&nd
->dd_name
[0], &nd
->dd_dta
)) {
226 static struct dirent dir
;
229 return (struct dirent
*) 0;
231 /* format structure */
232 dir
.d_ino
= 0; /* not valid for DOS */
234 strcpy(dir
.d_name
, dirp
->dd_dta
.name
);
235 dir
.d_namlen
= strlen(dir
.d_name
);
236 strlwr(dir
.d_name
); /* DOSism */
239 if (findnext(&dirp
->dd_dta
) != NULL
)
242 dirp
->dd_stat
= find_err
;
262 * check against DOS limits
265 if ((pos
< 0) || (pos
> 4095)) {
270 *(short *)&dirp
->dd_dta
.fcb
[13] = pos
+ 1;
273 if (findnext(&dirp
->dd_dta
))
276 dirp
->dd_stat
= find_err
;
284 return (long) (*(short *)&dirp
->dd_dta
.fcb
[13] - 2);