oaknut-afs
A Python library for reading, writing, and creating Acorn Level 3 File Server (AFS) disc partitions — the private on-disc filesystem the Level 3 File Server served to BBC Micro, Master, and Archimedes clients over Econet.
AFS is a hierarchical, multi-user filesystem: it has real directories, a
per-file owner and public access model, and a $.Passwords file of user
accounts. It is identified by the AFS0 magic in its info sectors.
Part of a dual-partition disc. An AFS filesystem does not occupy a disc alone — it lives in the tail cylinders of an old-map ADFS disc. The real
WFSINITutility (and oaknut'sinitialise()) shrinks the ADFS partition and carves the AFS region out of the space freed. oaknut-afs reads and writes that region; oaknut-adfs handles the host.
Part of the oaknut monorepo.
What it does
- Read and write an AFS partition: browse the directory tree, read and write files, create and remove directories, and edit metadata (owner and public access, the native two-byte datestamp).
- Partition and initialise (
initialise()): theWFSINITanalogue — repartition an old-map ADFS disc and lay down an empty AFS filesystem in the tail, with its map, root, and$.Passwordsfile. - Manage users (
UserSpec,PasswordsFile): create accounts with passwords and disc-space allocations; the built-inSyst,Boot, andWelcomeaccounts are handled. - Import a host tree (
import_host_tree()): populate a new filesystem from a directory of files with.infsidecars. - Merge (
merge()) two AFS partitions, and emplace shipped libraries (SHIPPED_LIBRARIES) such as the standardLibrary.
Passwords are stored as the file server stored them: up to six cleartext ASCII
bytes in $.Passwords, with no encryption — oaknut reproduces the format
faithfully rather than obscuring it.
Installation
uv add oaknut-afs # or: pip install oaknut-afs
oaknut-afs works with any PEP 517 build
front-end and package manager; the examples use
uv.
Usage
Creating and populating a filesystem
from oaknut.afs import AFS, UserSpec
with AFS.create_file(
"server.dat",
capacity="10MB",
disc_name="Server",
users=[UserSpec(name="RJS", quota="2MB")],
) as afs:
# Creating the RJS account also creates its home directory, $.RJS.
(afs.root / "RJS" / "ReadMe").write_text("Welcome to the file server.\n")
Reading
from oaknut.afs import AFS
with AFS.from_file("server.dat") as afs:
for entry in afs.root.iterdir():
print(entry.name)
text = (afs.root / "RJS" / "ReadMe").read_text()
For dual ADFS + AFS discs, the
disc
CLI reaches the AFS partition through the ADFS host with an afs: prefix
(disc ls 'server.dat:afs:$'), routed by content identification.
Development
The package is developed in the oaknut workspace. From the repository root:
uv sync # install all workspace members editable
uv run pytest packages/oaknut-afs/tests # this package's tests
uv run ruff check # lint
Architecture
oaknut-afs depends on oaknut-adfs (to place and read the partition within its
ADFS host), oaknut-discimage, and oaknut-file, and contributes AFS to the
oaknut.filesystem extension axis so that AFS partitions are identified,
listed, and read through the disc CLI alongside the disc-based filing
systems. Sector-level access comes from
oaknut-discimage;
metadata and the acorn codec from
oaknut-file.
Further reading
- AFS0 on-disc format — Rick Murray's notes on the Level 3 File Server's private format.
- Acorn Econet — the network the file server served over.
License
MIT — see LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file oaknut_afs-12.14.1.tar.gz.
File metadata
- Download URL: oaknut_afs-12.14.1.tar.gz
- Upload date:
- Size: 207.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6f8bed61e6b19c89dd7f73c3759dce257b1b5908f6e92f302c9e9c77d26bd9d9
|
|
| MD5 |
753380a336706df36508e54a944424d2
|
|
| BLAKE2b-256 |
db84f2d4f2507ab80a305fee56379f7efbf9e60cf464e348a32109a1fbb5f5f6
|
File details
Details for the file oaknut_afs-12.14.1-py3-none-any.whl.
File metadata
- Download URL: oaknut_afs-12.14.1-py3-none-any.whl
- Upload date:
- Size: 158.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
29b237e15a10b2761ca4e250a646ce480809352ff86c27e9e77b5f755a126deb
|
|
| MD5 |
d02fa864fe28650d5b5210f38edc1ed4
|
|
| BLAKE2b-256 |
91f935bbfe9bc198435fa31ea6641c2d951bdd846d36e23be6e508a70b51f067
|