Commit | Line | Data |
79072805 |
1 | /* $RCSfile: directory.c,v $$Revision: 4.1 $$Date: 92/08/07 18:24:42 $ |
b1248f16 |
2 | * |
3 | * (C) Copyright 1987, 1988, 1990 Diomidis Spinellis. |
4 | * |
6e21c824 |
5 | * You may distribute under the terms of either the GNU General Public |
6 | * License or the Artistic License, as specified in the README file. |
b1248f16 |
7 | * |
8 | * $Log: directory.c,v $ |
79072805 |
9 | * Revision 4.1 92/08/07 18:24:42 lwall |
10 | * |
6e21c824 |
11 | * Revision 4.0.1.1 91/06/07 11:22:24 lwall |
12 | * patch4: new copyright notice |
13 | * |
fe14fcc3 |
14 | * Revision 4.0 91/03/20 01:34:24 lwall |
15 | * 4.0 baseline. |
16 | * |
b1248f16 |
17 | * Revision 3.0.1.1 90/03/27 16:07:37 lwall |
18 | * patch16: MSDOS support |
19 | * |
20 | * Revision 1.3 90/03/16 22:39:40 dds |
21 | * Fixed malloc problem. |
22 | * |
23 | * Revision 1.2 88/07/23 00:08:39 dds |
24 | * Added inode non-zero filling. |
25 | * |
26 | * Revision 1.1 88/07/23 00:03:50 dds |
27 | * Initial revision |
28 | * |
29 | */ |
30 | |
31 | /* |
32 | * UNIX compatible directory access functions |
33 | */ |
34 | |
35 | #include <sys/types.h> |
36 | #include <sys/dir.h> |
37 | #include <stddef.h> |
38 | #include <stdlib.h> |
39 | #include <string.h> |
40 | #include <dos.h> |
41 | #include <ctype.h> |
42 | |
43 | /* |
44 | * File names are converted to lowercase if the |
45 | * CONVERT_TO_LOWER_CASE variable is defined. |
46 | */ |
47 | #define CONVERT_TO_LOWER_CASE |
48 | |
49 | #define PATHLEN 65 |
50 | |
51 | #ifndef lint |
79072805 |
52 | static char rcsid[] = "$RCSfile: directory.c,v $$Revision: 4.1 $$Date: 92/08/07 18:24:42 $"; |
b1248f16 |
53 | #endif |
54 | |
55 | DIR * |
56 | opendir(char *filename) |
57 | { |
58 | DIR *p; |
59 | char *oldresult, *result; |
60 | union REGS srv; |
61 | struct SREGS segregs; |
62 | register reslen = 0; |
63 | char scannamespc[PATHLEN]; |
64 | char *scanname = scannamespc; /* To take address we need a pointer */ |
65 | |
66 | /* |
67 | * Structure used by the MS-DOS directory system calls. |
68 | */ |
69 | struct dir_buff { |
70 | char reserved[21]; /* Reserved for MS-DOS */ |
71 | unsigned char attribute; /* Attribute */ |
72 | unsigned int time; /* Time */ |
73 | unsigned int date; /* Date */ |
74 | long size; /* Size of file */ |
75 | char fn[13]; /* Filename */ |
76 | } buffspc, *buff = &buffspc; |
77 | |
78 | |
79 | if (!(p = (DIR *) malloc(sizeof(DIR)))) |
80 | return NULL; |
81 | |
82 | /* Initialize result to use realloc on it */ |
83 | if (!(result = malloc(1))) { |
84 | free(p); |
85 | return NULL; |
86 | } |
87 | |
88 | /* Create the search pattern */ |
89 | strcpy(scanname, filename); |
90 | if (strchr("/\\", *(scanname + strlen(scanname) - 1)) == NULL) |
91 | strcat(scanname, "/*.*"); |
92 | else |
93 | strcat(scanname, "*.*"); |
94 | |
95 | segread(&segregs); |
96 | #if ( defined(M_I86LM) || defined(M_I86CM) || defined(M_I86HM) ) |
97 | segregs.ds = FP_SEG(buff); |
98 | srv.x.dx = FP_OFF(buff); |
99 | #else |
100 | srv.x.dx = (unsigned int) buff; |
101 | #endif |
102 | srv.h.ah = 0x1a; /* Set DTA to DS:DX */ |
103 | intdosx(&srv, &srv, &segregs); |
104 | |
105 | #if ( defined(M_I86LM) || defined(M_I86CM) || defined(M_I86HM) ) |
106 | segregs.ds = FP_SEG(scanname); |
107 | srv.x.dx = FP_OFF(scanname); |
108 | #else |
109 | srv.x.dx = (unsigned int) scanname; |
110 | #endif |
111 | srv.x.cx = 0xff; /* Search mode */ |
112 | |
113 | for (srv.h.ah = 0x4e; !intdosx(&srv, &srv, &segregs); srv.h.ah = 0x4f) { |
114 | if ((result = (char *) realloc(result, reslen + strlen(buff->fn) + 1)) == |
115 | NULL) { |
116 | free(p); |
117 | free(oldresult); |
118 | return NULL; |
119 | } |
120 | oldresult = result; |
121 | #ifdef CONVERT_TO_LOWER_CASE |
122 | strcpy(result + reslen, strlwr(buff->fn)); |
123 | #else |
124 | strcpy(result + reslen, buff->fn); |
125 | #endif |
126 | reslen += strlen(buff->fn) + 1; |
127 | } |
128 | |
129 | if (!(result = realloc(result, reslen + 1))) { |
130 | free(p); |
131 | free(oldresult); |
132 | return NULL; |
133 | } else { |
134 | p->start = result; |
135 | p->curr = result; |
136 | *(result + reslen) = '\0'; |
137 | return p; |
138 | } |
139 | } |
140 | |
141 | |
142 | struct direct * |
143 | readdir(DIR *dirp) |
144 | { |
145 | char *p; |
146 | register len; |
147 | static dummy; |
148 | |
149 | p = dirp->curr; |
150 | len = strlen(p); |
151 | if (*p) { |
152 | dirp->curr += len + 1; |
153 | strcpy(dirp->dirstr.d_name, p); |
154 | dirp->dirstr.d_namlen = len; |
155 | /* To fool programs */ |
156 | dirp->dirstr.d_ino = ++dummy; |
157 | return &(dirp->dirstr); |
158 | } else |
159 | return NULL; |
160 | } |
161 | |
162 | long |
163 | telldir(DIR *dirp) |
164 | { |
165 | return (long) dirp->curr; /* ouch! pointer to long cast */ |
166 | } |
167 | |
168 | void |
169 | seekdir(DIR *dirp, long loc) |
170 | { |
171 | dirp->curr = (char *) loc; /* ouch! long to pointer cast */ |
172 | } |
173 | |
174 | void |
175 | rewinddir(DIR *dirp) |
176 | { |
177 | dirp->curr = dirp->start; |
178 | } |
179 | |
180 | void |
181 | closedir(DIR *dirp) |
182 | { |
183 | free(dirp->start); |
184 | free(dirp); |
185 | } |