- (* Parse in the *.info files. These have historically had a few different
- * formats that we need to support.
- *)
- let infos = List.map (
- fun filename ->
- (* Get the basename (for getting the .data file later on). *)
- let basename = Filename.chop_suffix filename ".info" in
-
- let chan = open_in filename in
- let line = input_line chan in
-
- (* Kernel version string. *)
- let version, arch =
- if Pcre.pmatch ~rex:re_oldformat line then (
- (* If the file starts with "RPM: \d+: ..." then it's the
- * original Fedora format. Everything in one line.
- *)
- let subs = Pcre.exec ~rex:re_oldformat line in
- (* let name = Pcre.get_substring subs 1 in *)
- let version = Pcre.get_substring subs 2 in
- let release = Pcre.get_substring subs 3 in
- let arch = Pcre.get_substring subs 4 in
- close_in chan;
- (* XXX Map name -> PAE, hugemem etc. *)
- (* name, *) sprintf "%s-%s.%s" version release arch, arch
- ) else (
- (* New-style "key: value" entries, up to end of file or the first
- * blank line.
- *)
- let (*name,*) version, release, arch =
- (*ref "",*) ref "", ref "", ref "" in
- let rec loop line =
- try
- let subs = Pcre.exec ~rex:re_keyvalue line in
- let key = Pcre.get_substring subs 1 in
- let value = Pcre.get_substring subs 2 in
- (*if key = "Name" then name := value
- else*) if key = "Version" then version := value
- else if key = "Release" then release := value
- else if key = "Architecture" then arch := value;
- let line = input_line chan in
- loop line
- with
- Not_found | End_of_file ->
- close_in chan
- in
- loop line;
- let (*name,*) version, release, arch =
- (*!name,*) !version, !release, !arch in
- if (*name = "" ||*) version = "" || release = "" || arch = "" then
- failwith (sprintf "%s: missing Name, Version, Release or Architecture key" filename);
- (* XXX Map name -> PAE, hugemem etc. *)
- (* name, *) sprintf "%s-%s.%s" version release arch, arch
- ) in
-
- (*printf "%s -> %s %s\n%!" basename version arch;*)
-
- (basename, version, arch)
- ) infos in
-
- (* For quick access to the opener strings, build a hash. *)
- let openers = Hashtbl.create 13 in
- List.iter (
- fun (name, (opener, closer, _, _)) ->
- Hashtbl.add openers opener (closer, name)
- ) what;
-
- (* Now read the data files and parse out the structures of interest. *)
- let datas = List.map (
- fun (basename, version, arch) ->
- let file_exists name =
- try Unix.access name [Unix.F_OK]; true
- with Unix.Unix_error _ -> false
- in
- let close_process_in cmd chan =
- match Unix.close_process_in chan with
- | Unix.WEXITED 0 -> ()
- | Unix.WEXITED i ->
- eprintf "%s: command exited with code %d\n" cmd i; exit i
- | Unix.WSIGNALED i ->
- eprintf "%s: command exited with signal %d\n" cmd i; exit 1
- | Unix.WSTOPPED i ->
- eprintf "%s: command stopped by signal %d\n" cmd i; exit 1
- in
-
- (* Open the data file, uncompressing it on the fly if necessary. *)
- let chan, close =
- if file_exists (basename ^ ".data") then
- open_in (basename ^ ".data"), close_in
- else if file_exists (basename ^ ".data.gz") then (
- let cmd =
- sprintf "gzip -cd %s" (Filename.quote (basename ^ ".data.gz")) in
- Unix.open_process_in cmd, close_process_in cmd
- )
- else if file_exists (basename ^ ".data.bz2") then (
- let cmd =
- sprintf "bzip2 -cd %s" (Filename.quote (basename ^ ".data.bz2")) in
- Unix.open_process_in cmd, close_process_in cmd
- ) else
- failwith
- (sprintf "%s: cannot find corresponding data file" basename) in
-
- (* Read the data file in, looking for structures of interest to us. *)
- let bodies = Hashtbl.create 13 in
- let rec loop () =
- let line = input_line chan in