1 ;; This code is intended for an embedded binary with an "archive" of
2 ;; files appended to it. The appended archive is marked by a array of
3 ;; 40 "x", and consists by archive elements the format of
4 ;; "pathname\nsize\nbytes[size]".
6 ;; When there is an in-core archive, then the first member will be
7 ;; invoked as "main script".
9 ;; archives:archives is a hashmap for loadable files
10 ;; core:core is the running binary file
11 ;; archive:main is the name of the first on-core member
12 ;; archive:incore is the byte position into core for the archive
16 (define core:core (read-file (main-args 0)))
22 (constant 'AR "/usr/bin/ar")
24 (define (archive:archive PATH)
25 ;;(write-line 2 (string (list 'archive PATH)))
26 (map (fn (F) (archives F PATH) F)
27 (exec (format "%s t %s" AR PATH))))
29 (define (get-ar PATH MEMBER)
30 ;;(write-line 2 (string (list 'get-ar PATH MEMBER)))
31 (let ((I (pipe)) (O (pipe)) (DATA "") (ALL "")
33 (close (I 1)) (close (O 0)) (close 0)
34 (process (format "%s p %s %s" AR PATH MEMBER) (I 0) (O 1)))))
36 (close (O 1)) (close (I 0)) (close (I 1))
37 (while (> (or (read (O 0) DATA 1000000) 0)) (extend ALL DATA))
41 (define (get PATH MEMBER)
42 (if (list? PATH) ((PATH 0) (PATH 1) core)
43 (ends-with PATH ".a") (get-ar PATH MEMBER)))
45 ;; Discover and load an in-core archive by means of a marker row of 40
46 ;; "x", and then a series of pathname\nsize\nbytes[size] members.
47 (if (find (dup "x" 40) core nil 391704)
48 (let ((P (+ $it 41))) ; skip marker and newline
50 (while (regex "([^\n]+)\n([^\n]+)\n" core 0 P)
51 (let ((N $1) (S (int $2)) (L (length $0)))
53 (unless main (setf main N))
54 (archives N (list P S))
56 (write-line 2 (string "not packed")))
63 (fn () (if (archives (args 0))
64 (eval-string (archive:get $it (args 0)) MAIN)
67 (letex (READ-FILE read-file)
69 (if (archives (args 0)) (archive:get $it (args 0))
70 (READ-FILE (args 0)))))
73 (fn () (if (archives (args 0)) true (FILE? (args 0)))))
76 (when archive:main (load archive:main) (exit 0))