25 #include <sys/types.h>
32 #define MAX_OPEN_FILES 32
62 #define realpath(r,a) _fullpath(a,r,PATH_MAX)
69 ff.result_is_valid = 0;
72 for (
int a = 0; a < 26; a++) {
73 drives[a].dir_path[0] = 0;
85 if (files[a].
fd >= 0) {
94 for (
int a = 0; a < 26; a++)
96 closedir(drives[a].
dir);
106 drives[
drive].dir_path[0] = 0;
109 drives[
drive].dir = NULL;
114 char path_resolved[PATH_MAX];
115 if (!realpath(
dir_path, path_resolved)) {
116 conprintf(
"CPMFS: drive %c cannot be mounted, realpath() failure\r\n",
drive +
'A');
119 if (dirbase_part_only) {
125 int len = strlen(path_resolved);
126 if (len > PATH_MAX - 14) {
127 conprintf(
"CPMFS: drive %c cannot be mounted, too long path\r\n",
drive +
'A');
130 DIR *
dir = opendir(path_resolved);
132 conprintf(
"CPMFS: drive %c cannot be mounted, host directory cannot be open\r\n",
drive +
'A');
137 path_resolved[len] = 0;
144 conprintf(
"CPMFS: drive %c <- %s\r\n",
drive +
'A', path_resolved);
146 drives[
drive].ro = 0;
149 conprintf(
"CPMFS: drive %c has been selected as the current (first mount)\r\n",
drive +
'A');
156 return ff.result_is_valid ? ff.host_path : NULL;
160 static int fn_part (
char *dest,
const char *src,
int len,
int maxlen,
int jokery )
164 for (
int a = 0, c = 32; a < maxlen; a++) {
175 }
else if (c ==
'?') {
179 }
else if (c >=
'a' && c <=
'z') {
180 *dest++ = c -
'a' +
'A';
181 }
else if (c < 32 || c >= 127) {
195 static int fn_take_apart (
const char *
name,
char *base_name,
char *ext_name,
int jokery )
197 char *p = strchr(
name,
'.');
199 p ==
name || !p[1] ||
200 fn_part(base_name,
name, p -
name, 8, jokery) ||
201 fn_part(ext_name, p + 1, strlen(p + 1), 3, jokery)
203 fn_part(base_name,
name, strlen(
name), 8, jokery) ||
204 fn_part(ext_name, NULL, 0, 3, jokery)
209 static int pattern_match (
void )
211 for (
int a = 0; a < 8 + 3; a++)
212 if (ff.pattern[a] !=
'?' && ff.found[a] != ff.pattern[a])
221 ff.result_is_valid = 0;
222 if (ff.stop_search) {
226 DIR *
dir = drives[ff.drive].dir;
228 DEBUGPRINT(
"FCB: FIND: drive %c directory is not open?!" NL, ff.drive);
233 struct dirent *entry = readdir(
dir);
235 DEBUGPRINT(
"FCB: FIND: entry NULL returned, end of directory maybe?" NL);
239 if (fn_take_apart(entry->d_name, ff.found, ff.found + 8, 0)) {
240 DEBUGPRINT(
"FCB: FIND: ruling out filename \"%s\"" NL, entry->d_name);
244 DEBUGPRINT(
"FCB: FIND: considering formatted filename \"%s\"" NL, ff.found);
245 if (pattern_match()) {
246 DEBUGPRINT(
"FCB: FIND: no pattern match for this file" NL);
250 strcpy(ff.host_name, entry->d_name);
251 strcpy(ff.host_path, drives[ff.drive].dir_path);
252 strcat(ff.host_path, entry->d_name);
253 DEBUGPRINT(
"FCB: FIND: trying to stat file: %s" NL, ff.host_path);
254 if (stat(ff.host_path, &ff.st)) {
258 if ((ff.st.st_mode & S_IFMT) != S_IFREG) {
259 DEBUGPRINT(
"FCB: FIND: skipping file, not a regular one!" NL);
266 ff.result_is_valid = 1;
271 memcpy(res + 1, ff.found, 11);
276 return ff.options & 3;
287 ff.result_is_valid = 0;
291 for (
int a = 0; a < 8 + 3; a++) {
292 Uint8 c = input[a + 1] & 0x7F;
295 if (c >=
'a' && c <=
'z')
299 drive = input[0] & 0x7F;
303 FATAL(
"%s(): non-FCB input is not implemented yet", __func__);
307 if (drive < 0 || drive > 26 || !drives[
drive].
dir)