Added merge-overlay.lsp utility for merging down an overlay.
authorRalph Ronnquist <rrq@rrq.au>
Wed, 25 Oct 2023 12:18:26 +0000 (23:18 +1100)
committerRalph Ronnquist <rrq@rrq.au>
Wed, 25 Oct 2023 12:18:26 +0000 (23:18 +1100)
merge-overlay.lsp [new file with mode: 0755]

diff --git a/merge-overlay.lsp b/merge-overlay.lsp
new file mode 100755 (executable)
index 0000000..ec44ba4
--- /dev/null
@@ -0,0 +1,68 @@
+#!/usr/bin/newlisp
+
+;
+; Copy from a fusefile overlay file onto a fusefile. This may be done
+; so as to "merge down" an overlay in an overlay stack. Eg, assume the
+; original fusefile had overlay stack A:B:C then C could be merged
+; onto an A:B stack, or B merged onto A; the latter allowing a
+; subsequent A:C stack corresponding to previous A:B:C.
+;
+; Arguments: <fusefile> <overlay>
+
+(map set '(FUSEFILE OVERLAY) (-2 (main-args)))
+
+(setf FF.fd (open FUSEFILE "u") OL.fd (open OVERLAY "r"))
+
+(define (die)
+  (write-line 2 (join (map string (args)) " "))
+  (exit 1))
+
+; Read N unsigned 64-bit integers from OL.fd, returned as a list of them.
+(define (rd-uint64 FD N)
+  (let ((B (* N 8)) (BUFFER nil) (HEAD "") (OUT '()))
+    (while (and (> B) (> (read FD BUFFER B)))
+      (dec B (length BUFFER))
+      (extend HEAD BUFFER)
+      (let ((I (/ (length HEAD) 8)))
+        (when (> I)
+          (extend OUT (unpack (dup "Lu" ) HEAD))
+          (setf HEAD ((* 8 I) HEAD)))))
+    (when (> B) (die "Cannot read" N "table entries"))
+    OUT))
+
+(define (copy-data AT SIZE)
+  (let ((BUFFER nil) (N 0))
+    (when (null? (seek FF.fd AT)) (die "Cannot seek" FUSEFILE AT))
+    (when (null? (seek OL.fd AT)) (die "Cannot seek" OVERLAY AT))
+    (while (> SIZE)
+      (when (<= (read OL.fd BUFFER SIZE)) (die "Failed reading" SIZE "bytes"))
+      (dec SIZE (length BUFFER))
+      (while (and (> (length BUFFER))
+                  (setf N (write FF.fd BUFFER (length BUFFER))))
+        (setf BUFFER (N BUFFER)))
+      (when (> (length BUFFER)) (die "Failed writing" AT SIZE ))
+      )))
+
+(when (< FF.fd) (die "Cannot open" FUSEFILE))
+(when (< OL.fd) (die "Cannot open" OVERLAY))
+
+(when (null?  (seek OL.fd (setf P (file-info FUSEFILE 0))))
+  (die "Seek error:" P))
+
+(setf N (rd-uint64 OL.fd 1))
+(when (null? N) (die "Cannot read" OVERLAY "table count."))
+(setf N (N 0))
+
+; Check size
+(when (!= (+ P 8 (* N 16)) (file-info OVERLAY 0))
+  (die "Wrong size for " OVERLAY "which should be" (+ P 8 (* N 16))))
+
+(setf TABLE (rd-uint64 OL.fd (* 2 N)))
+(when (null? TABLE) (die "Cannot read" OVERLAY "table"))
+
+(dolist (ENTRY (explode TABLE 2))
+  (println (format "copy %s/%d:%d" (cons OVERLAY ENTRY)))
+  (copy-data (ENTRY 0) (- (ENTRY 1) (ENTRY 0))))
+
+"dumpoverlay.lsp"
+(exit 0)