X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=diskzip%2Fdiskzip.ml;h=75fffc60f7de64344b4408d2671f7040e670ba74;hb=10ae94c252bfc3e744407115274fd3d92957d026;hp=d857681adbeb829fc3d92338c2edbb5457e5114c;hpb=0b2bee9a672e5884f17ef231daf12daa89c26126;p=virt-df.git diff --git a/diskzip/diskzip.ml b/diskzip/diskzip.ml index d857681..75fffc6 100644 --- a/diskzip/diskzip.ml +++ b/diskzip/diskzip.ml @@ -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.