aboutsummaryrefslogtreecommitdiffstats
path: root/src/dosnames.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dosnames.c')
-rw-r--r--src/dosnames.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/dosnames.c b/src/dosnames.c
index b98b8d3..f1e060f 100644
--- a/src/dosnames.c
+++ b/src/dosnames.c
@@ -74,6 +74,17 @@ static int dos_search_name(const struct dos_file_list *dl, const uint8_t *name)
return 0;
}
+static const struct dos_file_list *dos_search_unix_name(const struct dos_file_list *dl,
+ const char *name)
+{
+ for(; dl && dl->unixname; dl++)
+ {
+ if(!strcmp(dl->unixname, name))
+ return dl;
+ }
+ return 0;
+}
+
// Sort unix entries so that '~' and '.' comes before other chars
static int dos_unix_sort(const struct dirent **s1, const struct dirent **s2)
{
@@ -608,3 +619,67 @@ struct dos_file_list *dos_find_first_file_fcb(int addr)
{
return find_first_file(dos_unix_path_fcb(addr, 1));
}
+
+char *dos_real_path(char drive, const char *unix_path)
+{
+ char *ret = 0;
+ // Start by normalizing both base and given paths
+ char *base = realpath(get_base_path(drive), 0);
+ if(!base)
+ return 0;
+ char *path = realpath(unix_path, 0);
+ if(!path)
+ {
+ free(base);
+ return 0;
+ }
+ debug(debug_dos, "dos_real_path: base='%s' path='%s'\n", base, path);
+ // Now, see if the path is actually a descendent of base
+ size_t l = strlen(base), k = strlen(path);
+ if(strncmp(base, path, l) || (path[l] != '/' && path[l]))
+ {
+ debug(debug_dos, "dos_real_path: no common base\n");
+ }
+ else if(k - l > 62)
+ {
+ debug(debug_dos, "dos_real_path: path too long for DOS\n");
+ }
+ else
+ {
+ // Convert remaining components
+ ret = calloc(1, 64);
+ strncat(ret, "C:", 64);
+
+ path[l] = 0;
+ while(++l < k)
+ {
+ // Extract one component
+ char *sep = strchr(path + l, '/');
+ // Cut string there
+ if(!sep)
+ sep = path + k;
+ else
+ *sep = 0;
+ // And search the DOS path name
+ struct dos_file_list *fl = dos_read_dir(path, "*.*");
+ path[l - 1] = '/';
+ const struct dos_file_list *sl = dos_search_unix_name(fl, path);
+ if(!sl)
+ {
+ dos_free_file_list(fl);
+ debug(debug_dos, "dos_real_path: path not found: '%s' in '%s'\n",
+ path + l, path);
+ free(base);
+ free(path);
+ return 0;
+ }
+ strncat(ret, "\\", 64);
+ strncat(ret, (const char *)sl->dosname, 64);
+ dos_free_file_list(fl);
+ l = sep - path;
+ }
+ }
+ free(base);
+ free(path);
+ return ret;
+}
Un proyecto texto-plano.xyz