febootstrap: Add --save-temps option to save temporary files on exit.
[febootstrap.git] / febootstrap.ml
index 8fee7b9..7e48206 100644 (file)
@@ -72,6 +72,20 @@ let () =
       ) packages
     ) in
 
+  (* Canonicalize the name of directories, so that /a and /a/ are the same. *)
+  let files =
+    List.map (
+      fun (filename, ft, pkg) ->
+        let len = String.length filename in
+        let filename =
+          if len > 1 (* don't rewrite "/" *) && ft.ft_dir
+            && filename.[len-1] = '/' then
+              String.sub filename 0 (len-1)
+          else
+            filename in
+        (filename, ft, pkg)
+    ) files in
+
   (* Sort and combine duplicate files. *)
   let files =
     let files = List.sort compare files in
@@ -79,16 +93,24 @@ let () =
     let combine (name1, ft1, pkg1) (name2, ft2, pkg2) =
       (* Rules for combining files. *)
       if ft1.ft_config || ft2.ft_config then (
-        eprintf "febootstrap: error: %s is a config file which is listed in two packages (%s, %s)\n"
-          name1 pkg1 pkg2;
-        exit 1
-      );
-      if (ft1.ft_dir || ft2.ft_dir) && (not (ft1.ft_dir && ft2.ft_dir)) then (
+       (* It's a fairly frequent bug in Fedora for two packages to
+        * incorrectly list the same config file.  Allow this, provided
+        * the size of both files is 0.
+        *)
+       if ft1.ft_size = 0 && ft2.ft_size = 0 then
+         (name1, ft1, pkg1)
+       else (
+          eprintf "febootstrap: error: %s is a config file which is listed in two packages (%s, %s)\n"
+            name1 pkg1 pkg2;
+          exit 1
+       )
+      )
+      else if (ft1.ft_dir || ft2.ft_dir) && (not (ft1.ft_dir && ft2.ft_dir)) then (
         eprintf "febootstrap: error: %s appears as both directory and ordinary file (%s, %s)\n"
           name1 pkg1 pkg2;
         exit 1
-      );
-      if ft1.ft_ghost then
+      )
+      else if ft1.ft_ghost then
         (name2, ft2, pkg2)
       else
         (name1, ft1, pkg1)
@@ -126,7 +148,8 @@ let () =
             else (
               insert_dir parent;
               let newdir = (parent, { ft_dir = true; ft_config = false;
-                                      ft_ghost = false; ft_mode = 0o40755 },
+                                      ft_ghost = false; ft_mode = 0o40755;
+                                     ft_size = 0 },
                             "") in
               newdir :: loop parent
             )
@@ -140,23 +163,25 @@ let () =
   if false then (
     List.iter (
       fun (name, { ft_dir = dir; ft_ghost = ghost; ft_config = config;
-                   ft_mode = mode }, pkg) ->
-        printf "%s [%s%s%s%o] from %s\n" name
+                   ft_mode = mode; ft_size = size }, pkg) ->
+        printf "%s [%s%s%s%o %d] from %s\n" name
           (if dir then "dir " else "")
           (if ghost then "ghost " else "")
           (if config then "config " else "")
-          mode
+          mode size
           pkg
     ) files
   );
 
   (* Split the list of files into ones for hostfiles and ones for base image. *)
-  let p_hmac = Str.regexp "/\\.*\\.hmac$" in
+  let p_hmac = Str.regexp "^\\..*\\.hmac$" in
 
   let hostfiles = ref []
   and baseimgfiles = ref [] in
   List.iter (
     fun (path, {ft_dir = dir; ft_ghost = ghost; ft_config = config} ,_ as f) ->
+      let file = Filename.basename path in
+
       (* Ignore boot files, kernel, kernel modules.  Supermin appliances
        * are booted from external kernel and initrd, and
        * febootstrap-supermin-helper copies the host kernel modules.
@@ -176,7 +201,7 @@ let () =
         hostfiles := f :: !hostfiles
 
       (* Ignore FIPS files (.*.hmac) (RHBZ#654638). *)
-      else if Str.string_match p_hmac path 0 then ()
+      else if Str.string_match p_hmac file 0 then ()
 
       (* Ghost files are created empty in the base image. *)
       else if ghost then