Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle special dot and dotdot files #76

Merged
merged 1 commit into from
Oct 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/fat_fs.ml
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,8 @@ module Make (B: Mirage_block_lwt.S) = struct
(sectors_of_file fs f)

(** [find device fs path] returns a [find_result] corresponding to
the object stored at [path] *)
the object stored at [path]
XXX: doesn't handle the cases where path is: /a/../b or /a/./b *)
let find device fs path =
let readdir = function
| Dir ds -> Lwt.return (Ok ds)
Expand All @@ -219,6 +220,10 @@ module Make (B: Mirage_block_lwt.S) = struct
| [] ->
(match current with
| Dir ds -> Lwt.return (Ok (Dir ds))
| File ({Fat_name.dos = _, {Fat_name.is_dot = true; _}; _} as d) ->
Lwt.return (Ok (File d))
| File ({Fat_name.dos = _, {Fat_name.is_dotdot = true; _}; _} as d) ->
Lwt.return (Ok (File d))
| File {Fat_name.dos = _, {Fat_name.subdir = true; _}; _} ->
readdir current >|*= fun names ->
Ok (Dir names)
Expand Down
40 changes: 28 additions & 12 deletions src/fat_name.ml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ type dos = {
modify: datetime;
start_cluster: int;
file_size: int32;
is_dot: bool;
is_dotdot: bool;
}

(** Useful for streaming entries to/from the disk *)
Expand All @@ -77,18 +79,20 @@ let fake_root_entry = {
dos = 0, {
filename = ""; ext = ""; deleted = false; read_only = false;
hidden = false; system = false; volume = false; subdir = true; archive = false;
create = epoch; access = epoch; modify = epoch; start_cluster = 0; file_size = 0l
create = epoch; access = epoch; modify = epoch; start_cluster = 0; file_size = 0l;
is_dot = false; is_dotdot = false;
};
lfns = []
}

let is_dot filename =
filename = "."

let is_dotdot filename =
filename = ".."

let remove_padding x =
let rec inner = function
| -1 -> x
| n when x.[n] = ' ' -> inner (n-1)
| n -> String.sub x 0 (n + 1)
in
inner (String.length x - 1)
String.trim x

let file_size_of r = (snd r.dos).file_size
let deleted r = (snd r.dos).deleted
Expand All @@ -97,7 +101,9 @@ let filename_of r =
then r.utf_filename
else
let d = snd(r.dos) in
(remove_padding d.filename) ^ "." ^ (remove_padding d.ext)
let ext = (remove_padding d.ext) in
let filename = (remove_padding d.filename) in
if ext = "" then filename else filename ^ "." ^ ext

let to_single_entries r =
List.rev ((Dos (snd r.dos)) :: (List.map (fun l -> Lfn (snd l)) r.lfns))
Expand All @@ -119,7 +125,9 @@ let legal_dos_string x =
with Not_found -> false

let dot = Re.Str.regexp_string "."
let is_legal_dos_name filename = match Re.Str.split dot filename with
let is_legal_dos_name filename =
if (is_dot filename || is_dotdot filename) then true else
match Re.Str.split dot filename with
| [ one ] -> String.length one <= 8 && (legal_dos_string one)
| [ one; two ] -> String.length one <= 8
&& (String.length two <= 3)
Expand All @@ -137,6 +145,7 @@ let add_padding p n x =
let uppercase = Astring.String.Ascii.uppercase

let dos_name_of_filename filename =
if (is_dot filename || is_dotdot filename) then filename, "" else
if is_legal_dos_name filename
then match Re.Str.split dot filename with
| [ one ] -> add_padding ' ' 8 one, " "
Expand Down Expand Up @@ -200,7 +209,9 @@ let make ?(read_only=false) ?(system=false) ?(subdir=false) filename =
access = epoch;
modify = epoch;
start_cluster = start_cluster;
file_size = file_size
file_size = file_size;
is_dot = false;
is_dotdot = false
} in
let checksum = compute_checksum dos in
let lfns =
Expand Down Expand Up @@ -252,7 +263,10 @@ let to_string x =
let d = snd x.dos in
let y = trim_utf16 x.utf_filename in
let z = utf16_to_ascii y in
if z = "" then d.filename ^ "." ^ d.ext else z
let ext = (remove_padding d.ext) in
let filename = (remove_padding d.filename) in
if z = "" && ext = "" then filename else
if z = "" then filename ^ "." ^ ext else z

let int_to_hms time =
let hours = ((time lsr 11) land 0b11111) in
Expand Down Expand Up @@ -375,7 +389,9 @@ let unmarshal buf =
access = time_of_int last_access_date 0 0;
modify = time_of_int last_modify_date last_modify_time 0;
start_cluster = start_cluster;
file_size = file_size
file_size = file_size;
is_dot = (is_dot (remove_padding (Bytes.to_string filename)));
is_dotdot = (is_dotdot (remove_padding (Bytes.to_string filename)));
}
end

Expand Down
2 changes: 2 additions & 0 deletions src/fat_name.mli
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ type dos = {
modify: datetime;
start_cluster: int;
file_size: int32;
is_dot: bool;
is_dotdot: bool;
}
(** A DOS disk entry *)

Expand Down