Overview
ZIP archives used in the build environment can carry RISC OS-specific metadata so that filetypes, timestamps, attributes, and filenames survive transfer between non-RISC OS systems and RISC OS itself. The riscos-zip and riscos-unzip wrappers use the Python rozipinfo support code to read and write that metadata.
Two related representations are used:
- a RISC OS-specific ZIP extra field, which preserves the most information;
- an NFS-style filename encoding, used when cross-platform friendliness matters more than writing the RISC OS extra field.
The shipped rozipinfo.py module also makes an important distinction between reading and writing. When reading, it prefers the RISC OS extra field if present and then falls back to NFS-style filename encoding. When writing, it can either preserve full RISC OS metadata through the extra field or deliberately prefer the filename encoding for wider tool compatibility.
Metadata encodings
ZIP extra field structure
ZIP extra fields are stored as a sequence of chunks. The local rozipinfo.py implementation describes each chunk as:
| Offset | Size | Contents |
|---|---|---|
| 0 | 2 | Header identifier, little-endian. |
| 2 | 2 | Chunk data length, little-endian. |
| 4 | variable | Chunk data. |
The RISC OS-specific chunk uses header identifier &4341.
RISC OS-specific chunk
The current format understood by the local tooling stores a secondary 32-bit type word followed by four 32-bit values:
| Offset | Size | Contents |
|---|---|---|
| 0 | 4 | RISC OS extra-field format identifier. The known format is &30435241, described in the code as SparkFS information. |
| 4 | 4 | RISC OS load address. |
| 8 | 4 | RISC OS exec address. |
| 12 | 4 | RISC OS attributes. |
| 16 | 4 | Reserved for future expansion; written as zero. |
The local code refers to the format identifier as ARC0 in its little-endian word form and uses it to distinguish the recognised RISC OS metadata record from any future chunk layout.
The enclosing ZIP extra-field header still remains the standard 2-byte ID and 2-byte length wrapper, so the complete RISC OS extension on disc is:
| Offset | Size | Contents |
|---|---|---|
| 0 | 2 | ZIP extra-field header ID, &4341. |
| 2 | 2 | Chunk length, currently 20 bytes (5 × 4-byte words) for the recognised RISC OS record. |
| 4 | 20 | RISC OS record beginning with the ARC0-format word. |
Metadata represented
The ZIP extension support can represent:
| Field | Meaning |
|---|---|
| Filename | RISC OS filename in the archive, or an inferred host-side equivalent. |
| Load/exec | RISC OS load and exec addresses, including stamped filetype/timestamp values. |
| Filetype | Either explicit in the load address or inferred from the filename or text flag. |
| Object type | File or directory, inferred from attributes where needed. |
| Attributes | RISC OS access and lock bits, mapped from stored metadata. |
When a file has a stamped load and exec pair, the local code can reconstruct the corresponding RISC OS quin timestamp from those values.
The same support code also sanitises unsafe Unix-style relative path forms before exposing them as RISC OS filenames, so archive names such as ../evil are normalised rather than trusted verbatim.
NFS-style filename encoding
When the archive is written for cross-platform transfer rather than direct RISC OS use, the local support code can avoid writing the RISC OS extra field and instead encode metadata into the filename. The documented patterns are:
| Form | Meaning |
|---|---|
| filename,xxx | Filename with a RISC OS filetype suffix. |
| filename,llllllll,eeeeeeee | Filename with explicit load and exec addresses. |
This encoding is easier for general ZIP tools to preserve, but the extra-field form is preferred when the archive is intended primarily for RISC OS-aware tools because it preserves more information without depending on filename translation.
The installed code comments make the intended policy explicit:
- when reading, enable NFS interpretation as a fallback;
- when writing for direct RISC OS use, prefer the RISC OS extra field;
- when writing for non-RISC OS transfer, prefer the NFS filename encoding.
Defaults and inference
The local ZIP support uses these defaults and inferences when explicit metadata is absent:
| Item | Default or inference |
|---|---|
| Default filetype | Data, &FFD. |
| Default text filetype | Text, &FFF. |
| Directory marker | A directory object type, with a directory filetype represented internally through a stamped load address. |
The implementation also maps some common filename extensions and parent directory names to filetypes when nothing more explicit is present.
The built-in mappings in the shipped code include common text-oriented source extensions such as .txt, .c, .h, and .s, and parent directory names such as c/, h/, cmhg/, and def/.
Archive workflow
Creating and extracting a RISC OS-aware ZIP
This is the normal workflow for release archives in the build environment.
riscos-zip -v mytool.zip aif32/MyTool,ff8
riscos-unzip mytool.zip
riscos-unzip -l -v mytool.zip
The final -l -v listing shows the RISC OS filename, load/exec address, filetype, and attributes recovered from the archive entry, confirming the RISC OS metadata survived the round trip rather than only that the file extracted without error.