diff --git a/bin/dune b/bin/dune index 92a5c5a..f7f3805 100644 --- a/bin/dune +++ b/bin/dune @@ -1,5 +1,4 @@ (executables - (names main) - (public_names fat) - (libraries fat-filesystem mirage-block-unix cmdliner - io-page-unix)) + (names main shell) + (public_names fat shell) + (libraries fat-filesystem mirage-block-unix cmdliner)) diff --git a/bin/impl.ml b/bin/impl.ml index f28cfb7..04f362f 100644 --- a/bin/impl.ml +++ b/bin/impl.ml @@ -22,7 +22,7 @@ open Common have specific code to handle is to 'fail' the Lwt thread with the exception Failure "user-readable message". *) -let fail fmt = Fmt.kstrf Lwt.fail_with fmt +let fail fmt = Fmt.kstr Lwt.fail_with fmt let (>>*=) m f = m >>= function | Error e -> fail "%a" Filesystem.pp_write_error (e :> Filesystem.write_error) @@ -180,7 +180,7 @@ let cat common filename path = let rec loop offset = Filesystem.read fs path offset 1024 >>*= fun bufs -> List.iter (fun x -> print_string (Cstruct.to_string x)) bufs; - let copied = List.fold_left (+) 0 (List.map Cstruct.len bufs) in + let copied = List.fold_left (+) 0 (List.map Cstruct.length bufs) in if copied < 1024 then Lwt.return () else loop (offset + copied) diff --git a/bin/main.ml b/bin/main.ml index 3bdfc93..365eed1 100644 --- a/bin/main.ml +++ b/bin/main.ml @@ -42,7 +42,7 @@ let common_options_t = let unbuffered = let doc = "Use unbuffered I/O (via O_DIRECT)." in Arg.(value & flag & info ["unbuffered"] ~docs ~doc) in - Term.(pure Common.make $ debug $ verb $ unbuffered) + Term.(const Common.make $ debug $ verb $ unbuffered) let filename = let doc = Printf.sprintf "Path to the FAT image file." in @@ -65,8 +65,10 @@ let create_cmd = let size = let doc = "Size of the image" in Arg.(value & pos 1 string "16MiB" & info [] ~doc) in - Term.(ret(pure Impl.create $ common_options_t $ filename $ size)), - Term.info "create" ~sdocs:_common_options ~doc ~man + let term = Term.(ret(const Impl.create $ common_options_t $ filename $ size)) + and info = Cmd.info "create" ~sdocs:_common_options ~doc ~man + in + Cmd.v info term let add_cmd = let doc = "add files to a FAT image" in @@ -75,8 +77,10 @@ let add_cmd = `P "Add a set of files to a FAT filesystem image." ] @ help in let files = Arg.(non_empty & pos_all file [] & info [] ~docv:"FILE") in - Term.(ret(pure Impl.add $ common_options_t $ filename $ files)), - Term.info "add" ~sdocs:_common_options ~doc ~man + let term = Term.(ret(const Impl.add $ common_options_t $ filename $ files)) + and info = Cmd.info "add" ~sdocs:_common_options ~doc ~man + in + Cmd.v info term let list_cmd = let doc = "list files in a FAT image" in @@ -84,8 +88,10 @@ let list_cmd = `S "DESCRIPTION"; `P "List the set of files contained within a FAT filesystem image." ] @ help in - Term.(ret(pure Impl.list $ common_options_t $ filename)), - Term.info "list" ~sdocs:_common_options ~doc ~man + let term = Term.(ret(const Impl.list $ common_options_t $ filename)) + and info = Cmd.info "list" ~sdocs:_common_options ~doc ~man + in + Cmd.v info term let cat_cmd = let doc = "extract a single file from a FAT image" in @@ -93,18 +99,21 @@ let cat_cmd = `S "DESCRIPTION"; `P "extract a single file from a FAT filesystem image." ] @ help in - Term.(ret(pure Impl.cat $ common_options_t $ filename $ path)), - Term.info "cat" ~sdocs:_common_options ~doc ~man + let term = Term.(ret(const Impl.cat $ common_options_t $ filename $ path)) + and info = Cmd.info "cat" ~sdocs:_common_options ~doc ~man + in + Cmd.v info term let default_cmd = - let doc = "manipulate FAT filesystem images" in - let man = help in - Term.(ret (pure (fun _ -> `Help (`Pager, None)) $ common_options_t)), - Term.info "fat" ~version:"1.0.0" ~sdocs:_common_options ~doc ~man + Term.(ret (const (fun _ -> `Help (`Pager, None)) $ common_options_t)) let cmds = [create_cmd; add_cmd; list_cmd; cat_cmd] -let _ = - match Term.eval_choice default_cmd cmds with - | `Error _ -> exit 1 - | _ -> exit 0 +let () = + let doc = "manipulate FAT filesystem images" in + let man = help in + let info = + Cmd.info "fat" ~version:"%%VERSION%%" ~sdocs:_common_options ~doc ~man + in + let group = Cmd.group ~default:default_cmd info cmds in + exit (Cmd.eval group) diff --git a/bin/shell.ml b/bin/shell.ml index 58ac1d3..5be4cd1 100644 --- a/bin/shell.ml +++ b/bin/shell.ml @@ -1,8 +1,7 @@ (* This is a toplevel-like test program *) open Lwt.Infix -open Mirage_fs -module Test = Fat.FS(Block) +module Test = Fat.Make(Block) let with_file flags filename f = Lwt_unix.openfile filename flags 0o0 >>= fun file -> @@ -14,7 +13,7 @@ let with_file flags filename f = Lwt_unix.close file >>= fun () -> Lwt.fail x) -let fail fmt = Fmt.kstrf Lwt.fail_with fmt +let fail fmt = Fmt.kstr Lwt.fail_with fmt let (>>|=) m f = m >>= function | Error e -> fail "%a" Test.pp_error e @@ -58,7 +57,7 @@ let main filename _create_size = let n = ref 0 in List.iter (fun buf -> Printf.printf "%s" (Cstruct.to_string buf); - n := !n + (Cstruct.len buf) + n := !n + (Cstruct.length buf) ) datas; Printf.printf "\n%!"; if !n <> file_size @@ -160,10 +159,10 @@ let main filename _create_size = inner (snd(parse_path x)) in - let space = Re_str.regexp_string " " in + let space = Re.Str.regexp_string " " in let rec loop () = Printf.printf "A:%s> %!" (Path.to_string !cwd); - match Re_str.split space (input_line stdin) with + match Re.Str.split space (input_line stdin) with | [ "dir" ] -> do_dir "" >>= loop | [ "dir"; path ] -> do_dir path >>= loop | [ "cd"; path ] -> do_cd path >>= loop diff --git a/fat-filesystem.opam b/fat-filesystem.opam index ee1c03d..618acb1 100644 --- a/fat-filesystem.opam +++ b/fat-filesystem.opam @@ -8,23 +8,23 @@ bug-reports: "https://github.com/mirage/ocaml-fat/issues" depends: [ "ocaml" {>= "4.06.0"} "dune" {>= "1.0"} - "cstruct" {>= "3.0.0"} + "cstruct" {>= "6.0.0"} "ppx_cstruct" "rresult" "lwt" {>= "2.4.3"} - "mirage-block" {>= "2.0.0"} - "mirage-block-unix" {>= "2.5.0"} + "mirage-block" {>= "3.0.0"} + "mirage-block-unix" {>= "2.13.0"} "mirage-kv" "mirage-block-combinators" {with-test} - "io-page-unix" {>= "2.0.0"} - "io-page" {>= "2.0.0"} + "io-page" {>= "2.4.0"} "re" {>= "1.7.2"} - "cmdliner" + "cmdliner" {>= "1.1.0"} "astring" + "fmt" {>= "0.8.7"} "alcotest" {with-test} ] build: [ - ["dune" "subst"] {pinned} + ["dune" "subst"] {dev} ["dune" "build" "-p" name "-j" jobs] ["dune" "runtest" "-p" name] {with-test} ] diff --git a/src/fat.ml b/src/fat.ml index 24f8d41..ad2b368 100644 --- a/src/fat.ml +++ b/src/fat.ml @@ -89,8 +89,8 @@ module Make (B: Mirage_block.S) = struct let read_sectors bps device xs = let buf = alloc (List.length xs * bps) in let rec split buf = - if Cstruct.len buf = 0 then [] - else if Cstruct.len buf <= bps then [ buf ] + if Cstruct.length buf = 0 then [] + else if Cstruct.length buf <= bps then [ buf ] else Cstruct.sub buf 0 bps :: (split (Cstruct.shift buf bps)) in let page = alloc bps in @@ -146,7 +146,7 @@ module Make (B: Mirage_block.S) = struct let fat = Fat_entry.make boot format in let root_sectors = Fat_boot_sector.sectors_of_root_dir boot in let root = alloc (List.length root_sectors * 512) in - for i = 0 to Cstruct.len root - 1 do Cstruct.set_uint8 root i 0 done; + for i = 0 to Cstruct.length root - 1 do Cstruct.set_uint8 root i 0 done; let fs = { boot = boot; format = format; fat = fat; root = root } in Ok fs @@ -175,12 +175,12 @@ module Make (B: Mirage_block.S) = struct let get_fs sector = match Fat_boot_sector.unmarshal sector with | Error reason -> - Fmt.kstrf Lwt.fail_with + Fmt.kstr Lwt.fail_with "error unmarshalling first sector of block device: %s" reason | Ok boot -> match Fat_boot_sector.detect_format boot with | Error reason -> - Fmt.kstrf Lwt.fail_with + Fmt.kstr Lwt.fail_with "error detecting the format of block device: %s" reason | Ok format -> Lwt.return (boot, format) in @@ -200,7 +200,7 @@ module Make (B: Mirage_block.S) = struct >>= function | Ok t -> Lwt.return t | Error e -> - Fmt.kstrf Lwt.fail_with "error reading essential sectors: %a" pp_error e + Fmt.kstr Lwt.fail_with "error reading essential sectors: %a" pp_error e let disconnect _ = Lwt.return () @@ -496,7 +496,7 @@ module Make (B: Mirage_block.S) = struct | Ok buffer -> let buffer = Cstruct.sub buffer preceeding - (Cstruct.len buffer - preceeding - succeeding) + (Cstruct.length buffer - preceeding - succeeding) in Ok [ buffer ] diff --git a/src/fat.mli b/src/fat.mli index cb5df23..0be4dfa 100644 --- a/src/fat.mli +++ b/src/fat.mli @@ -48,7 +48,12 @@ module Make (B: Mirage_block.S): sig val pp_write_error: write_error Fmt.t (** [pp_write_error] is the pretty-printer for write errors. *) - include Mirage_device.S + type t + (** The type representing the internal state of the device *) + + val disconnect: t -> unit Lwt.t + (** Disconnect from the device. While this might take some time to + complete, it can never result in an error. *) val connect : B.t -> t Lwt.t val format : B.t -> int64 -> (t, write_error) result Lwt.t diff --git a/src/fat_boot_sector.ml b/src/fat_boot_sector.ml index 73451b1..7d75a22 100644 --- a/src/fat_boot_sector.ml +++ b/src/fat_boot_sector.ml @@ -60,7 +60,7 @@ let _ = assert(sizeof = 512) let fat_id = 0xf8 (* fixed disk *) let marshal (buf: Cstruct.t) t = - for i = 0 to Cstruct.len buf - 1 do + for i = 0 to Cstruct.length buf - 1 do Cstruct.set_uint8 buf i 0 done; set_t_oem_name t.oem_name 0 buf; @@ -81,8 +81,8 @@ let marshal (buf: Cstruct.t) t = let unmarshal (buf: Cstruct.t) : (t, string) result = let open Rresult in - ( if Cstruct.len buf < sizeof - then Error (Printf.sprintf "boot sector too small: %d < %d" (Cstruct.len buf) sizeof) + ( if Cstruct.length buf < sizeof + then Error (Printf.sprintf "boot sector too small: %d < %d" (Cstruct.length buf) sizeof) else Ok () ) >>= fun () -> let signature = get_t_signature buf in ( if signature <> 0xaa55 diff --git a/src/fat_entry.ml b/src/fat_entry.ml index 9530474..7911fb4 100644 --- a/src/fat_entry.ml +++ b/src/fat_entry.ml @@ -29,7 +29,7 @@ let to_string = function type fat = Cstruct.t let of_fat16 n fat = - if Cstruct.len fat < (2 * n + 2) + if Cstruct.length fat < (2 * n + 2) then Bad else let x = Cstruct.LE.get_uint16 fat (2 * n) in @@ -44,7 +44,7 @@ let to_fat16 n fat x = Cstruct.LE.set_uint16 fat (2 * n) x' let of_fat32 n fat = - if Cstruct.len fat < (4 * n + 4) + if Cstruct.length fat < (4 * n + 4) then Bad else let x = Cstruct.LE.get_uint32 fat (4 * n) in diff --git a/src/fat_name.ml b/src/fat_name.ml index b73e2ff..7700cc7 100644 --- a/src/fat_name.ml +++ b/src/fat_name.ml @@ -331,7 +331,7 @@ let sizeof = sizeof_name let _ = assert(sizeof_lfn = sizeof_name) let unmarshal buf = - if Cstruct.len buf = 0 + if Cstruct.length buf = 0 then End else if get_lfn_v_0f buf = 0x0f then begin let seq = get_lfn_seq buf in @@ -392,7 +392,7 @@ let unmarshal buf = end let marshal (buf: Cstruct.t) t = - for i = 0 to Cstruct.len buf - 1 do + for i = 0 to Cstruct.length buf - 1 do Cstruct.set_uint8 buf i 0 done; match t with @@ -450,7 +450,7 @@ let marshal (buf: Cstruct.t) t = let blocks buf = let rec loop acc offset remaining = - if Cstruct.len remaining < sizeof (* ignore extra space at the end *) + if Cstruct.length remaining < sizeof (* ignore extra space at the end *) then List.rev acc else let this = offset, (Cstruct.sub remaining 0 sizeof) in @@ -504,7 +504,7 @@ let next bits = Note the update may be beyond the end of [block] indicating more space needs to be allocated. *) let add block r = - let after_block = Cstruct.len block in + let after_block = Cstruct.length block in let next_byte = match next block with | Some b -> b | None -> after_block in diff --git a/src/fat_sector_map.ml b/src/fat_sector_map.ml index c1d944c..1576f0e 100644 --- a/src/fat_sector_map.ml +++ b/src/fat_sector_map.ml @@ -40,13 +40,13 @@ let byte_range bps start len = let clip (preceeding, _, succeeding) = function | [] -> [] - | [c] -> [Cstruct.sub c preceeding (Cstruct.len c - succeeding - preceeding)] + | [c] -> [Cstruct.sub c preceeding (Cstruct.length c - succeeding - preceeding)] | c :: cs -> let cs' = List.rev cs in let last = List.hd cs' in let middle' = List.tl cs' in - let last = Cstruct.sub last 0 (Cstruct.len last - succeeding) in - let head = Cstruct.sub c preceeding (Cstruct.len c - preceeding) in + let last = Cstruct.sub last 0 (Cstruct.length last - succeeding) in + let head = Cstruct.sub c preceeding (Cstruct.length c - preceeding) in head :: (List.rev middle') @ [ last ] let compose a b = diff --git a/src/fat_update.ml b/src/fat_update.ml index 46e1f98..6e1a2a6 100644 --- a/src/fat_update.ml +++ b/src/fat_update.ml @@ -20,11 +20,11 @@ type data = let bytes = function | String x -> String.length x - | Cstruct x -> Cstruct.len x + | Cstruct x -> Cstruct.length x let string_of_data = function | String x -> Printf.sprintf "(string of length %d)" (String.length x) - | Cstruct x -> Printf.sprintf "(Cstruct.t of length %d)" (Cstruct.len x) + | Cstruct x -> Printf.sprintf "(Cstruct.t of length %d)" (Cstruct.length x) type t = { offset: int64; @@ -48,7 +48,7 @@ let apply buf { offset; data } = let offset = Int64.to_int offset in match data with | String x -> Cstruct.blit_from_string x 0 buf offset (String.length x) - | Cstruct x -> Cstruct.blit x 0 buf offset (Cstruct.len x) + | Cstruct x -> Cstruct.blit x 0 buf offset (Cstruct.length x) let sub offset length = let offset = Int64.to_int offset in diff --git a/test/dune b/test/dune index 9bf6a80..f1f3b21 100644 --- a/test/dune +++ b/test/dune @@ -1,5 +1,5 @@ (test (libraries fat-filesystem lwt lwt.unix cstruct alcotest - mirage-block-unix io-page.unix mirage-block mirage-block-combinators) + mirage-block-unix mirage-block mirage-block-combinators) (name test) (deps (glob_files *.dat))) diff --git a/test/test.ml b/test/test.ml index 51c6695..e26849e 100644 --- a/test/test.ml +++ b/test/test.ml @@ -19,7 +19,7 @@ open Block module MemFS = Fat.Make(Mirage_block_combinators.Mem) -let fail fmt = Fmt.kstrf Lwt.fail_with fmt +let fail fmt = Fmt.kstr Lwt.fail_with fmt let (>>*=) m f = m >>= function | Error e -> fail "%a" MemFS.pp_write_error (e :> MemFS.write_error) @@ -213,7 +213,7 @@ let make_pattern tag length = assert (String.length tag <= length); let buffer = alloc length in Cstruct.blit_from_string tag 0 buffer 0 (String.length tag); - for i = String.length tag to Cstruct.len buffer - 1 do + for i = String.length tag to Cstruct.length buffer - 1 do Cstruct.set_char buffer i tag.[i mod (String.length tag)] done; buffer @@ -285,7 +285,7 @@ let test_read () = let buffer = make_pattern "basic writing test " length in MemFS.write fs filename 0 buffer >>*= fun () -> MemFS.read fs filename 0 length >>*= fun buffers -> - let count buffers = List.fold_left (+) 0 (List.map Cstruct.len buffers) in + let count buffers = List.fold_left (+) 0 (List.map Cstruct.length buffers) in Alcotest.(check int) __LOC__ length (count buffers); MemFS.read fs filename 0 (length * 2) >>*= fun buffers -> Alcotest.(check int) __LOC__ length (count buffers); @@ -324,7 +324,7 @@ let test_write ((filename: string), (_offset, length)) () = let cstruct = Alcotest.testable (fun ppf x -> - Fmt.pf ppf "\"%s\"(%d)" (Cstruct.to_string x) (Cstruct.len x) + Fmt.pf ppf "\"%s\"(%d)" (Cstruct.to_string x) (Cstruct.length x) ) Cstruct.equal in Alcotest.(check cstruct) __LOC__ buffer (List.hd buffers);