Use ocamldoc in each directory.
[virt-df.git] / diskzip / diskzip.ml
index d857681..75fffc6 100644 (file)
@@ -20,7 +20,9 @@
 open Unix
 open Printf
 
+open Int63.Operators
 open Diskzip_gettext.Gettext
+module Bitmap = Diskzip_bitmap
 
 type output = File of string | Dir of string
 type extcompress = BZip2 | GZip | External of string
@@ -29,16 +31,19 @@ let rec main () =
   (* Program name changes behaviour. *)
   let compressing =
     let name = Sys.argv.(0) in
-    let name = Filename.basename name in       (* just the executable name *)
-    let name = Filename.chop_extension name in (* remove .opt or .exe *)
+    let name = Filename.basename name in (* just the executable name *)
+    let name =                          (* remove .opt or .exe *)
+      try Filename.chop_extension name
+      with Invalid_argument("Filename.chop_extension") -> name in
     let name = String.lowercase name in
     match name with
     | "diskzcat" -> false
     | "diskzip" -> true
-    | name ->
+    | _ ->
        eprintf
          (f_"diskzip: unknown executable name '%s', assuming 'diskzip'\n")
-         name in
+         name;
+       true in
   let compressing = ref compressing in
 
   (* Command line argument parsing. *)
@@ -86,9 +91,9 @@ let rec main () =
     "-j", Arg.Unit (set_extcompress BZip2),
       " " ^ s_"Pipe the output/input through bzip2";
     "-o", Arg.String set_output,
-      "path" ^ s_"Set the output filename or directory name";
+      "path " ^ s_"Set the output filename or directory name";
     "-p", Arg.String (fun prog -> set_extcompress (External prog) ()),
-      "prog" ^ s_"Pipe the output/input through external program";
+      "prog " ^ s_"Pipe the output/input through external program";
     "--version", Arg.Unit version,
       " " ^ s_"Display version and exit";
     "-z", Arg.Unit (set_extcompress GZip),
@@ -134,6 +139,77 @@ OPTIONS" in
   else
     go_decompress ?output extcompress args
 
+(* Do compression. *)
+and go_compress extcompress images =
+  (* Create a Diskimage machine description from the requested images.  This
+   * also checks that everything we need is readable.
+   *)
+  let machine =
+    Diskimage.open_machine "diskzip" (List.map (fun n -> (n,n)) images) in
+
+  (* Scan the images for filesystems. *)
+  let machine = Diskimage.scan_machine machine in
+
+  (* Create ownership tables. *)
+  let ownership = Diskimage.create_ownership machine in
+
+  (* Create ownership bitmap for each disk. *)
+  List.iter (
+    fun { Diskimage.d_name = name; d_dev = disk } ->
+      let blocksize = disk#blocksize in
+      let size = disk#size in          (* Size in bytes. *)
+      let nr_blocks = size /^ blocksize in (* Number of disk sectors. *)
+
+      if !Diskimage.debug then
+       eprintf "Creating bitmap for %s (%s sectors) ...\n%!"
+         disk#name (Int63.to_string nr_blocks);
+
+      (* Create an empty bitmap, one bit per sector. *)
+      let bitmap = Bitmap.create nr_blocks in
+
+      (* Get the lookup function for this disk. *)
+      let lookup = Diskimage.get_owners_lookup machine ownership disk in
+
+      (* Lookup each sector. *)
+      Bitmap.iter_set (
+       fun blk _ ->
+         let owners = lookup blk in
+         false
+      ) bitmap
+  ) machine.Diskimage.m_disks;
+
+  (* Redirect output through external pipe if asked. *)
+  (match extcompress with
+   | None -> ()
+   | Some prog ->
+       let prog, progargs =
+        match prog with
+        | BZip2 -> "bzip2", [|"bzip2"; "-c"|]
+        | GZip -> "gzip", [|"gzip"; "-c"|]
+        | External prog -> "sh", [|"sh"; "-c"; prog |] in
+       let rfd, wfd = pipe () in
+       let pid = fork () in
+       if pid = 0 then (               (* child *)
+        close wfd;
+        dup2 rfd stdin;
+        close rfd;
+        execvp prog progargs
+       ) else (                                (* parent *)
+        close rfd;
+        dup2 wfd stdout;
+        close wfd
+       )
+  )
+
+
+
+
+
+
+
+
+
+
 and go_decompress ?output extcompress args =
   (* Read the input, which may be a single named file, or a series of
    * files (we just concatenate them).  We may have to feed the input
@@ -195,47 +271,6 @@ and go_decompress ?output extcompress args =
 
 
 
-(* Do compression. *)
-and go_compress extcompress images =
-  (* Create a Diskimage machine description from the requested images.  This
-   * also checks that everything we need is readable.
-   *)
-  let machine =
-    Diskimage.open_machine "diskzip" (List.map (fun n -> (n,n)) images) in
-
-  (* Scan the images for filesystems. *)
-  let machine = Diskimage.scan_machine machine in
-
-  (* Redirect output through external pipe if asked. *)
-  (match extcompress with
-   | None -> ()
-   | Some prog ->
-       let prog, progargs =
-        match prog with
-        | BZip2 -> "bzip2", [|"bzip2"; "-c"|]
-        | GZip -> "gzip", [|"gzip"; "-c"|]
-        | External prog -> "sh", [|"sh"; "-c"; prog |] in
-       let rfd, wfd = pipe () in
-       let pid = fork () in
-       if pid = 0 then (               (* child *)
-        close wfd;
-        dup2 rfd stdin;
-        close rfd;
-        execvp prog progargs
-       ) else (                                (* parent *)
-        close rfd;
-        dup2 wfd stdout;
-        close wfd
-       )
-  )
-
-
-
-
-
-
-
-
 (*
 (* Since we have the wonderful pa_bitmatch, might as well use it to
  * define a robust binary format for the compressed files.