Files
fuse-tar/bin/main.ml

75 lines
2.5 KiB
OCaml

module Octal = Octal
module Tar = Tar
let tar_path = if Array.length Sys.argv < 2 then
failwith "No tar path supplied"
else Array.get Sys.argv 1
let (root, tar_ch) = Tar.parse_tar tar_path
(* let () = Tar.print_tree "" root *)
let rec getattr path =
match Tar.find path root with
| None -> raise (Unix.Unix_error (Unix.ENOENT, "hi1", "hi1"))
| Some (File (_, md)) -> md
| Some (Directory (_, md)) -> md
| Some (InferredDirectory (_, md)) -> md
| Some (Symlink (_, md)) -> md
| Some (Hardlink (p)) -> getattr p
let rec readdir path _i =
match Tar.find path root with
| None -> raise (Unix.Unix_error (Unix.ENOENT, "234", "234"))
| Some (Hardlink linked_path)
| Some (Symlink (linked_path, _)) ->
if String.equal linked_path path then
raise (Unix.Unix_error (Unix.ENOENT, "read", path))
else
readdir linked_path _i
| Some (File (_, _)) -> raise (Unix.Unix_error (Unix.ENOENT, "345", "345"))
| Some (InferredDirectory (children, _))
| Some (Directory (children, _)) ->
["."; ".."] @ (List.map (fun (name, _) -> name) (Tar.NameMap.to_list children))
(* There seems to be a bug here - the amount argument given to this function
is NOT the correct requested amount. The buffer size is correct though
so I'm taking that as the source of truth.
*)
let rec read path buf offset _amount =
(*
let () = Printf.printf "PARAMS %d %d %d\n" (Int64.to_int offset) amount (Bigarray.Array1.dim buf) in
let () = Out_channel.flush_all () in*)
match Tar.find path root with
| None -> raise (Unix.Unix_error (Unix.ENOENT, "read", path))
| Some (Hardlink linked_path)
| Some (Symlink (linked_path, _)) ->
if String.equal linked_path path then
raise (Unix.Unix_error (Unix.ENOENT, "read", path))
else
read linked_path buf offset _amount
| Some (File (fo, md)) ->
(let (file_buf,read) = (Tar.read_file (File (fo, md)) tar_ch offset (Bigarray.Array1.dim buf)) in
Bytes.iteri (fun i c -> Bigarray.Array1.set buf i c) file_buf;
read)
| _ -> raise (Unix.Unix_error (Unix.EISDIR, "read", path))
let readlink path =
match Tar.find path root with
| Some (Symlink (path, _)) ->
path
| _ -> raise (Unix.Unix_error (Unix.ENOENT, "readlink", path))
let _ =
let args = Array.append (Array.sub Sys.argv 1 ((Array.length Sys.argv) - 1)) [|"-o";"use_ino";"-o";"allow_other"|] in
Fuse.main args
{
Fuse.default_operations with
getattr = getattr;
readdir = readdir;
read = read;
readlink = readlink;
}