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