# ports/: third-party C programs One directory per program ("a port"), the way Alpine's APKBUILDs and the BSD ports trees do it: ``` ports// ├── .sha256 the pinned release tarball: "SHA256 file-name" ├── .url where to download it, one URL per line: upstream, then mirrors ├── patches/ our changes, applied in order (0001-*.patch, ...) └── build.sh unpack -> patch -> CC=toolchain/foundry-cc configure -> make -> install into out/staging ``` Every port is built as a **static-PIE** with `toolchain/foundry-cc` (see docs/porting.md). No tarball is ever committed; `cache/` is git-ignored and every download is checked against the SHA256 here. `ports/fetch.sh NAME` downloads into `cache/` (trying each URL until one gives the pinned SHA256); `make ports` fetches and builds every port listed in `FOUNDRY_PORTS` (`config.mk`) and the image gets each one as `/bin/NAME`. ## dash 0.5.12 The first port: `CC=toolchain/foundry-cc ./configure --host=x86_64-linux-musl && make`, no patches needed. About 216 KB, a static-PIE. Installed as **`/bin/dash`**, *not* `/bin/sh`: the kernel starts `/bin/sh` as its shell, and that stays `rbsh` until kernel request K5 (contract v2); then dash becomes `/bin/sh` for POSIX scripts while `rbsh` stays the login shell. `make test` runs `dash /mnt/disk0/scripts/dash-test.sh` (15 checks: arithmetic, functions, case, globbing, pipes into our Rust tools, redirections, here-documents, background jobs + `wait`, `trap`, ...). Download note: upstream (gondor.apana.org.au) answered HTTP 500 on 2026-10-31; Debian's `dash_0.5.12.orig.tar.gz` is byte-identical (same SHA256) and is the second URL. Later: **sbase** (M4) and **busybox** (M5). Later: **sbase** (M4) and **busybox** (M5). Their applets go to `/usr/lib/busybox`, *off* the default `PATH`, so the Rust tools stay the default (see docs/plan.md).