Metadata across the host boundary¶
Acorn files carry side-channel metadata that does not exist on a modern host filesystem:
a 32-bit load address (where the file goes in memory),
a 32-bit exec address (where execution starts after load),
an access byte (owner and public read, write, execute and lock), and
on RISC OS files, a 12-bit filetype encoded inside the load address.
A plain cp image.ssd:$.HELLO hello would lose every byte of
this — host filesystems do not have a column for “Acorn exec
address”. The four commands that cross the host boundary —
disc get, disc put, disc export, disc import —
therefore accept a --meta-format option that names how
metadata is carried over the boundary. The choice has trade-offs,
and the wrong choice silently loses information. This page is the
single source of truth on what each format does and when each is
the right pick.
The four commands that cross the host boundary¶
Command |
Direction |
Default |
|---|---|---|
|
image → host (one file) |
|
|
host → image (one file) |
import cascade (see What gets tried on import) |
|
image → host (whole tree) |
|
|
host → image (whole tree) |
import cascade |
disc cp between two image specs does not appear here — it
copies inside oaknut’s own representation, so metadata travels
fully without needing a host side-channel. disc cat and
disc type print only the file’s bytes and never touch
metadata.
The --meta-format choices¶
Every host-boundary command accepts the same seven values:
Value |
What it carries |
On-disk shape |
|---|---|---|
|
filename, load, exec, length, attr |
|
|
owner, load, exec, perm |
|
|
load, exec, attr |
|
|
load, exec, attr, owner |
|
|
load, exec or filetype |
Filename rewritten: |
|
load, exec |
Filename rewritten: |
|
nothing |
Just the bytes. Metadata is lost. |
Pick based on what you want next:
You want a single, widely-understood, archival-safe sidecar.
Use inf-trad (the default). The .inf companion file is a
short text line every Acorn-era utility recognises, and it travels
through ZIP, tar, rsync, dropbox, USB sticks, and email
attachments unchanged.
You are talking to a PiEconetBridge file server.
Use inf-pieb (when staging files on disc) or xattr-pieb
(when storing on a Linux filesystem PiEconetBridge will serve
from). These omit the Acorn filename field but include the Econet
owner ID — pass --owner N to set it. PiEconetBridge stores
permissions in its own perm byte, which swaps the lock (&04)
and execute-only (&08) bits relative to the Acorn access byte and
uses &80 for hidden, which disc holds as the hidden attribute;
disc translates it in both directions, so access always reads and
prints the Acorn way.
You want zero sidecar clutter and zero filename changes.
Use xattr-acorn. The metadata lives in extended attributes
attached directly to the file on disc. Caveat: xattrs survive
local copies on Linux/macOS but do not cross tar, ZIP, FAT,
SMB/CIFS shares, or most network protocols.
You want metadata to survive any host conversion.
Use filename-riscos or filename-mos. The metadata is in
the filename, so anything that preserves the filename preserves
the metadata. filename-riscos is the modern RISC OS convention
(many emulators and converters speak it); filename-mos is the
older BBC MOS form.
You explicitly do not want metadata (the file is plain data and
will not go back).
Use none. The file is written or read as raw bytes only.
What gets tried on import¶
disc put and disc import without --meta-format try
each metadata source in turn, stopping at the first that yields
results:
Traditional INF sidecar —
foo.bin.infnext to the data file. The line is parsed for load, exec, attr, and (for the traditional form) filename.Acorn xattrs —
user.acorn.*first; if absent, the reader also tries the PiEconetBridgeuser.econet_*namespace before giving up on xattrs. A separate explicit--meta-format xattr-piebcascade step would therefore be unreachable.RISC OS filename suffix —
,xxxor,llllllll,eeeeeeeeat the end of the host filename.
If none of the three yield metadata, the file is imported with
load_address=0, exec_address=0, and the access a new file gets
on the destination: WR/R on ADFS, WR/ on AFS and DFS. When a
sidecar does record access, disc put and disc import both apply
it; --access on put overrides it.
Traditional .inf files¶
A traditional .inf is read and written per the Stardot INF format
specification,
with J.G. Harston’s choices (Storing Acorn/BBC metadata on other systems) where it leaves room:
Fields may be dropped from the right, down to
name load. A missing exec address is the load address, and a missing access field means&33(WR/WR).A lock marker —
Locked,LOCKEDor a bareL, as DFS-era tools write in place of the length or access — means&19(LR/R).A symbolic access field is case-sensitive: upper-case letters are the owner’s rights and lower-case the public’s, so
WRrisWR/RandLWRisLWR/.Dis ignored. The slash formdiscitself uses (WR/R) is also accepted, case-insensitively, as on the command line.Six-digit DFS-style addresses such as
FF0E00are widened to&FFFF0E00.Names may be quoted and percent-encoded (
"MY FILE","A%22B"); the oldTAPEprefix, extra fields such asCRC=andOPT4=, andNEXTare recognised.
disc get and disc export write 8-digit addresses and a 2-digit hex
access byte, and quote and percent-encode any name that needs it. A name
is written in the image’s own character set, as its bytes are stored on
the disc: on DFS, £ is byte &60, so the sidecar for $.COST£
holds that byte, not Latin-1’s &A3. disc put and disc import decode a sidecar name in the
destination image’s character set. A ZIP
member without Acorn attributes has access &33, and its bundled
.inf files are read by the same rules.
To override the cascade, pass --meta-format VALUE and only
that format is consulted. Pass --meta-format none to ignore
all metadata sources and import bytes only.
Overriding metadata at import time¶
disc put also accepts --load HEX and --exec HEX for
ad-hoc cases that don’t fit any of the sidecar formats — for
example, putting a freshly-built binary onto a disc with an
explicit load address:
disc put 'hello.ssd:$.PROG' build/prog.bin --load 0x1900 --exec 0x1900
These override whatever the chosen --meta-format would have
read. --access does the same for the file’s access; see
File access below.
File access¶
Access is written as an access string: the owner’s rights to the left
of a /, the public’s (other users of a file server) to the right.
Letter |
Meaning |
|---|---|
|
may be read (and |
|
may be written |
|
may be executed; for the owner without |
|
locked: may not be deleted, renamed or overwritten |
|
private, written before the owner’s letters: the public may not
delete, rename or overwrite it (bit 7 of the access byte, the same
as |
So WR/R is owner read and write with public read, and LR/ a
locked, read-only file other users cannot read. E/ is a *RUN-only
file: it may be run but not loaded, the copy protection ROMFS and
cassette files use. Most filing systems treat a readable file as
executable, so E is shown only when neither R nor W is,
for the owner and the public alike (WR/E). The same value can be
given as the hex access byte (0x13, 19), which disc ls -H
displays.
Each filing system stores what it can. DFS records only a lock bit,
which also means read-only, so a DFS file reads as WR/ or LR/
and writing to DFS keeps only L. ADFS stores owner R, W,
E and L, public R, W and E, and P (New-format
D, E and F discs drop both execute bits and P); AFS stores owner
and public R and W and L;
ROMFS whether a file is readable (R/) or *RUN-only (E/). A copy between filing systems keeps as much as the
destination can store — so a file copied from DFS arrives with no public
access. A *RUN-only file (E/) copied to a filing system that cannot
store execute — AFS, DFS, or a New-format (D, E, F) ADFS disc — becomes
readable (R/) there instead, and disc warns that the copy protection
was not kept.
To change access:
disc chmod(Acorn alias*ACCESS) sets it on existing files, with wildcards and-r;--dry-runlists what would change.--accessondisc cpanddisc putsets it as the files are written.
Both take an absolute string (R/R, 0x19), which replaces the
access, or an incremental one starting with + or -, which edits
it: +/R grants public read, -W removes owner write, and clauses
combine (+L-W). On a Level 3 File Server, binaries other users run —
the contents of $.Library, shared games — need public read:
disc cp -r 'game.dsd::0.G' 'scsi0.dat:afs:$.EliteGame' --access +/R
disc chmod 'scsi0.dat:afs:$.Library.Elite*' R/R
Where the in-image name comes from¶
An Acorn filename can hold characters a host filename cannot — a
/ is legal on DFS but not on a host, so an exporter stores
test8/3 on disc as test8_3 on the host and records the true
name in the sidecar. On import, disc chooses the in-image leaf
name highest-priority first from:
--name— an explicit override (disc putonly), for a leaf the path syntax cannot express: one containing.(the Acorn separator), a leading space, or a file under a non-$root.the destination leaf, when
disc putis given one that names a file (disc put img:$.PROG filenames itPROG).the Acorn name the metadata source carries — a traditional INF’s filename field, or a filename-encoded name — recovering the name the host filename transliterated.
the host filename, with any encoded suffix stripped.
A disc put destination that names a directory — the root
$, or an existing directory — puts the file into it under the
derived name, so the sidecar name is used:
disc put tube.ssd:$ original/test8_3 --meta-format inf-trad
# -> in-image file test8/3 (from the INF, not the host's test8_3)
disc import always targets a directory, so every file it imports
uses its sidecar name where one is present, else the host filename.
Mixing formats in one direction¶
The chosen format applies uniformly across a bulk command —
disc export writes every file in the chosen --meta-format.
For mixed exports (some files as INF, others as RISC OS filenames)
run disc get per file with different --meta-format
values.
Imports are more flexible because the default cascade tries
multiple formats per file, so a host directory mixing INF
sidecars, xattr’d files, and filename-suffixed files imports
correctly as one disc import HOST_DIR invocation.
Datestamps are reported at face value¶
A RISC OS file’s datestamp (held in the load/exec fields alongside
the filetype) is a count of centiseconds since 1900 with no
timezone recorded. disc ls, disc stat and disc
get-datestamp report it exactly as stored — no timezone or
daylight-saving conversion, and no guess about which era’s
convention produced it.
This matters because the meaning of the stored instant is not fixed: RISC OS 3 and later store datestamps in UTC, while RISC OS 2 and earlier (the Arthur era) used the uncorrected system clock, usually set to local time. The disc does not record which. Reporting verbatim keeps oaknut’s output reproducible and independent of where or when you run it.
One visible consequence: a RISC OS Filer adjusts datestamps to the machine’s current timezone and daylight-saving setting when it displays them (a proleptic adjustment that ignores whether DST was actually in force on the file’s date). So on a DST-active machine the Filer can read up to an hour ahead of what oaknut reports. That is the Filer applying a local-time conversion oaknut deliberately does not — not a disagreement about the bytes.
DFS host (I/O processor) addresses¶
A DFS catalogue holds load and execution addresses in 18 bits. When the
top two of those bits are both set, the address belongs to the I/O
processor rather than a Second Processor, and DFS reports it as the
32-bit value &FFFFxxxx; any other pattern is a Second Processor
address below &30000. oaknut reads the same values, so a file copied
from DFS to AFS or ADFS still loads and runs in the I/O processor, and
the .inf sidecar disc get writes records FFFF1900.
DFS listings show the low three bytes, as *INFO does — FF1900 —
while the machine formats (--as json, --as tsv) carry the full
value. Writing &FFFF1900, &FF1900 or the raw &31900 to DFS
stores the same address. A 32-bit address with bits 16 and 17 both set,
such as &00031900, has no separate DFS form: it reads back as
&FFFF1900.
Address or datestamp? --metadata-lens¶
On ADFS a file’s load/exec fields hold either a real address pair
or a filetype-and-datestamp — distinguished by the RISC OS marker
“the top twelve bits of the load address are &FFF”. But that
marker overlaps genuine addresses — the &FFFFxxxx host-address
convention and the &FFFFFFFF “unset” sentinel both trip it — so
the reading cannot be chosen reliably from a single file’s bytes. It
is a format question: on DFS and the 8-bit ADFS shapes (S/M/L) a
load/exec pair is almost always a genuine address, while on the
Arthur and RISC OS ADFS shapes (D, E, F and their successors) it is
almost always a filetype and datestamp.
disc ls and disc stat therefore default to a lens each
filing system declares. Under the type-date lens a marked file
shows Filetype and Datestamp columns and its raw load/exec are
hidden from the human view (they are only the encoding); under the
addresses lens the Load and Exec columns are shown and the
decode is suppressed. The raw values are never lost either way — they
stay in --as json / --as tsv output, and disc get-load /
disc get-exec always report them.
Override the default with ``–metadata-lens``:
--metadata-lens=addressesforces the Load/Exec reading — use it when a RISC OS disc holds a genuinely addressed file, or when a coincidental&FFFshows a spurious date.--metadata-lens=type-dateforces the filetype/datestamp reading — use it to see a filetype you set on an 8-bit ADFS disc, which defaults to addresses.--metadata-lens=auto(the default) follows the filing system.
It changes the display only; the stored bytes are untouched. Set
OAKNUT_DISC_METADATA_LENS=addresses (or type-date) to make a
reading the default across commands.
A filing system that keeps its datestamp outside load/exec — the Acorn File Server, with its native two-byte date — is unaffected by the lens: its Datestamp column shows under either reading, alongside the real load/exec addresses.
Note
--raw-addresses (and OAKNUT_DISC_RAW_ADDRESSES) is a
deprecated alias for --metadata-lens=addresses, retained for
existing scripts.
Cross-host gotchas¶
xattr survival depends on the filesystem and the transport. Local Linux ext4 and macOS APFS preserve xattrs through
cpandmv. ZIP, tar (without--xattrs), FAT, exFAT, NTFS (the Linux driver), SMB/CIFS, and most cloud-storage clients strip them silently. If your files will travel, preferinf-tradorfilename-riscos.Sidecar files double the file count. A directory of 1000 Acorn files exported as
inf-tradlands as 2000 host files.filename-riscoskeeps the count at 1000 — useful for filename-sensitive contexts like ZIP archives.Filename-encoded metadata changes the host filename. A file saved as
$.PROGexports underfilename-riscosasPROG,FFFF1900,FFFF1900— handy for round-trip preservation, but you cannot also use the host filename to identify the file.The Acorn-side filename is only preserved by ``inf-trad``. All other formats use the host filename as the disc-side filename on re-import. If your Acorn filenames contain characters the host rejects (or vice-versa), the only round-trip-safe format is
inf-trad.
When in doubt, --meta-format inf-trad is the safest default
for archival and the most widely supported across other
Acorn-aware tooling.