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"|] in Fuse.main args { Fuse.default_operations with getattr = getattr; readdir = readdir; read = read; readlink = readlink; }