Add the pack package: mirror to zim or self-contained binary
BuildZIM walks a cloned host directory, turns every file into a content entry with a MIME inferred from its extension, picks a main page, and adds the standard metadata plus a mainPage redirect. state.json is skipped. BuildBinary appends the archive to a copy of kage behind a KAGEPCK1 trailer, and Embedded detects that trailer at startup so the binary serves itself. Handler maps / to the main page and /path to a content entry, the same handler the embedded viewer uses.
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
package pack
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
// Embedded inspects the running executable for an appended ZIM archive. If the
|
||||
// KAGEPCK1 trailer is present, it returns a ReaderAt bounded to the archive, its
|
||||
// size, and ok=true; the file handle stays open for the life of the process so
|
||||
// the viewer can serve from it. A normal kage build has no trailer, so the cost
|
||||
// to every ordinary invocation is one Open plus a 24-byte ReadAt.
|
||||
func Embedded() (ra io.ReaderAt, size int64, ok bool) {
|
||||
exe, err := os.Executable()
|
||||
if err != nil {
|
||||
return nil, 0, false
|
||||
}
|
||||
f, err := os.Open(exe)
|
||||
if err != nil {
|
||||
return nil, 0, false
|
||||
}
|
||||
info, err := f.Stat()
|
||||
if err != nil {
|
||||
_ = f.Close()
|
||||
return nil, 0, false
|
||||
}
|
||||
total := info.Size()
|
||||
if total < int64(trailerLen) {
|
||||
_ = f.Close()
|
||||
return nil, 0, false
|
||||
}
|
||||
|
||||
tr := make([]byte, trailerLen)
|
||||
if _, err := f.ReadAt(tr, total-int64(trailerLen)); err != nil {
|
||||
_ = f.Close()
|
||||
return nil, 0, false
|
||||
}
|
||||
if string(tr[:8]) != trailerMagic || string(tr[trailerLen-8:]) != trailerMagic {
|
||||
_ = f.Close()
|
||||
return nil, 0, false
|
||||
}
|
||||
zlen := int64(binary.LittleEndian.Uint64(tr[8:16]))
|
||||
start := total - int64(trailerLen) - zlen
|
||||
if zlen <= 0 || start < 0 {
|
||||
_ = f.Close()
|
||||
return nil, 0, false
|
||||
}
|
||||
return io.NewSectionReader(f, start, zlen), zlen, true
|
||||
}
|
||||
Reference in New Issue
Block a user