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