Skip to content

evaluate the validity of historical TODO improvement areas #288

Description

@rdmark

TODO.md Validity Audit

Audit date: 2026-07-07
Auditor: GPT-5.5

This report checks each bullet in TODO.md against the current source tree.
Pretty much all of these items were noted by the original creator of this project, with a handful of exceptions.

Statuses mean:

  • valid: still describes missing or incomplete behavior.
  • partially valid: some implementation exists, but the TODO is not fully satisfied or its scope has changed.
  • resolved: the requested behavior is implemented well enough that the bullet is stale.
  • stale: the old wording no longer matches the current architecture.
  • unclear: no decisive local evidence either way.

Summary

Status Count
valid 18
partially valid 7
resolved 6
stale 0
unclear 0

General Client Shortcomings

TODO item Status Evidence and notes
integration with avahi/bonjour valid No Avahi, Bonjour, DNS-SD, or mDNS implementation is present. lib/identify.c only notes that server identification "could later use mDNS".
shutting down notices aren't honoured resolved DSI attention packets are parsed in lib/dsi.c; AFPATTN_CRASH and AFPATTN_SHUTDOWN set shutdown state, fetch server messages when needed, and call loop_disconnect().

Command Line Client

TODO item Status Evidence and notes
paginate directory listings with >256 files resolved Low-level directory reads loop in 256-entry batches in lib/lowlevel.c. The stateless API also loops and exposes start, count, and eod in daemon/stateless.c; cmdline/cmdline_afp.c has remote_readdir_all() to collect pages.

FUSE Client

TODO item Status Evidence and notes
do correct address/signature matching; right now we don't actually use the signature partially valid The current stateless resume/reconnect path matches by server name/address and auth in daemon/commands.c, and find_server_by_signature() exists in lib/afp.c, but no current caller uses the server signature for session matching. For FUSE mounts, the architecture is now mostly one daemon per mount, so the original FUSE-specific wording is stale, but the broader signature-matching gap remains.

AFP 3.x

TODO item Status Evidence and notes
filenames have a maximum length of 255, but AFP 3.x allows for much more partially valid invalid_filename() allows 1024-byte UTF-8 path components for AFP 3.x, so this is not purely true anymore. However, AFP_MAX_PATH is still 768, many public structures use fixed AFP_MAX_PATH buffers, and ml_statfs() still reports f_namemax = 255.
ACL support valid AFP ACL command IDs and kSupportsACLs exist in headers, but there are no afp_getacl/afp_setacl implementations or stateless/FUSE API surface. docs/FEATURES.md still says ACLs have not been implemented.

AFP 2.x

TODO item Status Evidence and notes
use getsrvrinfo to get connection IP address to make room for AT valid The URL structure still has an AT protocol enum and zone, but afp_get_address() is TCP/IP via getaddrinfo(), and docs/FEATURES.md says AppleTalk is unsupported.
connection recovery: open files valid Open forks are tracked in lib/forklist.c, but reconnect only reopens volumes in afp_server_reconnect(); there is no replay of open forks with fresh fork IDs.
connection recovery: locked files valid Byte-range locks are taken and released around individual read/write calls in lib/lowlevel.c. There is no persisted lock journal or replay across reconnect.
desktop database support partially valid Desktop code exists for OpenDT/CloseDT, comments, and icons in lib/proto_desktop.c and lib/resource.c. Broader desktop database support remains incomplete, and docs/FEATURES.md says only comments are actually implemented.
UTF8 flag is now server-specific, but it should be volume-specific valid afp_connect_volume() derives encoding from each volume's kSupportsUTF8Names, but writes it into server->path_encoding, so one volume can still change the whole server object's path encoding.

Authentication

TODO item Status Evidence and notes
ClientKRB valid UAM_CLIENTKRB is defined and the UAM string exists, but no Kerberos login implementation is registered in lib/uams.c. proto_session.c explicitly says kGetKerberosSessionKey is unsupported.
reconnection partially valid Generic reconnect and stateless resume exist (afp_server_reconnect(), afp_sl_resume(), FUSE suspend/resume). The AFP Recon1 UAM is still not implemented or registered, and DHX/DHX2 still contain FIXME comments about stashing keys for Reconnect UAM support.
Open directory integration valid Server flags are displayed by afpgetstatus, but there is no Open Directory integration layer or authentication implementation.

Performance

TODO item Status Evidence and notes
in mknod(), you only need to do the setfiledirparms if the mode or perms are different resolved fuse_mknod() calls ml_creat(), and ml_creat() now deliberately skips FPSetFileDirParms after FPCreateFile; mode changes are left to later chmod paths.
asynchronous unlocking valid ll_read() and ll_write() synchronously call ll_handle_unlocking() before returning. There is no async unlock queue.
use rx and tx quantums properly partially valid Writes use server->tx_quantum; reads chunk by server->rx_quantum; the DSI open-session reply parses server tx quantum. However afp_server_connect() still hardcodes rx_quantum = 128 * 1024 after measuring status latency, so this is only partly addressed.
queue writes to be one tx quantum partially valid ll_write() chunks each AFP write to at most tx_quantum, but writes are synchronous; there is no queued/coalesced write pipeline.
optimize locking valid Current reads/writes take byte-range locks around every operation and release synchronously. No broader lock coalescing, caching, or optimization layer is visible.
don't go back through the select loop to read what comes after the DSI packet valid dsi_recv() reads the DSI header and returns immediately for non-empty payloads, with a comment saying the rest of the packet will be read next time.
make a preallocated pool of dsi requests valid dsi_send() still allocates each struct dsi_request with malloc().
make a preallocated pool for dsi messages valid There is a per-server incoming_buffer, but no message pool; temporary protocol messages and attention contexts are still allocated ad hoc.
is_dir function should look in did cache valid is_dir() contains a disabled #if 0 cache lookup, and the active path always calls afp_getfiledirparms(). The current DID cache entry does not store isdir.
check to see how Mac OS does locking on writes valid The code has macOS compatibility notes for open access flags, but no local test or documented conclusion for write locking behavior.
large block writes for FUSE 3.x valid FUSE 3 is detected, but the operations table does not implement write_buf, and init does not request or tune large-write capabilities such as max_write/big writes.

Protocol Bugs

TODO item Status Evidence and notes
Netatalk Client doesn't handle the situation where the server is shutdown resolved Shutdown attention notices and close-session packets disconnect the server; EOF/protocol read errors in dsi_recv() cause loop_disconnect() and leave the server in SERVER_STATE_DISCONNECTED for later reconnect. A narrower "mid-transaction recovery" gap remains, but that is covered by reconnect reliability/open-file bullets.
reconnect isn't reliable partially valid Reconnect support has been substantially improved: pending requests are failed/flushed, connection generations reject stale replies, FUSE suspend/resume exists, and stateless resume exists. Remaining gaps include open fork and lock replay, signature matching, and docs that still say mid-transaction recovery is not supported.
If a DSI stream gets broken or there's a protocol error, the connection should be reset resolved dsi_recv() returns -1 for read errors, EOF, oversized payloads, unknown DSI commands, and other protocol errors; process_server_fds() then calls loop_disconnect().
for logins, fpLoginExt should be used instead of fpLogin valid afp_loginext() exists and SRP uses it, but the normal UAM implementations still call afp_login()/afpLogin for No User Auth, Cleartext, Randnum, DHX, and DHX2.
for fpCreateFile, use soft creates resolved ml_creat() uses kFPSoftCreate; ll_open() also uses soft creates for O_CREAT without O_EXCL and hard creates only for exclusive creation.
honour volume's HasConfigInfo flag valid HasConfigInfo is defined for FPGetSrvrParms volume flags and those flags are parsed into volume->flags, but no behavior appears to branch on HasConfigInfo.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions