af_retrieve(3)
π af_retrieve(3) β the AtFS retrieve interface, but make it make sense π
okay so this is the af_retrieve(3) page out of the Attribute Filesystem (AtFS) manual, and it's literally your backstage pass to pulling files back out of AtFS. no cap. β¨
π NAME π
af_find, af_cachefind, af_initattrs, af_getkey, af_dropkey, af_dropset, af_dropall β the AtFS retrieve interface π«Ά
πΈ SYNOPSIS πΈ
#include <atfs.h>
int af_find (Af_attrs *attrbuf, Af_set *resultset)
int af_cachefind (Af_attrs *attrbuf, Af_set *resultset)
int af_initattrs (Af_attrs *attrbuf)
int af_getkey (char *syspath, char *name, char *type, int gen, int rev,
Af_key *aso)
int af_dropkey (Af_key *key)
int af_dropset (Af_set *set)
int af_dropall (void)
π¦ DESCRIPTION π¦
so af_find and af_cachefind are the two besties that go get you ASOs by their attributes. af_find works on source objects only, and af_cachefind works on derived objects only. the keys of every ASO they find come back to you in resultset. lowkey important: the keys in resultset are returned in random order, so don't come for me about the ordering, it's not a thing. π
both of them expect resultset to be a pointer to an empty set structure β like, empty empty, bestie. and both of them return the number of ASOs they found. slay.
π the attribute buffer π
your retrieve arguments get passed in an attribute buffer called attrbuf. you should initialize attrbuf with af_initattrs before you call af_find (or, resp., af_cachefind). what does af_initattrs do? it disables every field in the attribute buffer. periodt. then your application can switch individual fields back on by setting whatever attribute value it actually wants. the initial settings of each field are listed down below, right next to the structure of the attribute buffer.
if you set one of the Af_user fields in the attribute buffer to AF_NOUSER, you only get ASOs selected where the corresponding user attribute is not set. and ngl, this only makes sense for af_locker, like when you specifically want to select ASOs that are not locked.
on the af_mode field, it does a bitwise comparison. so every ASO gets selected that has at least all the required mode bits (the ones you gave in af_mode) set in its own mode field. an exact match is not required. it's giving "close enough is close enough." π
the first two fields in the attribute buffer are the search space. generally the search space for a retrieve operation is a directory, and the directory name goes in the af_syspath field of the attribute buffer. if you don't give a system path at all? it searches the current directory. and heads up: the af_host field in the attribute buffer is ignored in the current implementation. π
π§ the attribute buffer structure π§
here it is, exactly as it is, initial values and all:
typedef struct { initial value
char af_host[MAXHOSTNAMELEN]; /* hostname (ignored) */""
char af_syspath[MAXPATHLEN+1]; /* system path */""
char af_name[MAXNAMLEN+1]; /* filename */"*"
char af_type[MAXTYPLEN]; /* filename extension (type) */"*"
int af_gen; /* generation number */-1
int af_rev; /* revision number */-1
int af_state; /* version state */ -1
Af_user af_owner; /* owner */{ "", "", "" }
Af_user af_author; /* author */{ "", "", "" }
off_t af_size; /* size of file */ -1
u_short af_mode; /* protection */0
Af_user af_locker; /* locker */{ "", "", "" }
time_t af_mtime; /* date of last modification */-1
time_t af_atime; /* date of last access */-1
time_t af_ctime; /* date of last status change*/-1
time_t af_stime; /* save date */-1
time_t af_ltime; /* date of last lock change */-1
char *af_udattrs[AF_MAXUDAS]; /* user defined attributes */
} Af_attrs;
π user defined attributes as retrieve arguments π
you can absolutely pass a list of user defined attributes as retrieve arguments. the pointer list af_udattrs in the attribute buffer gets filled with strings of the form name[=value]. and the list must be terminated by a nil pointer. don't forget that part, bestie, it's non-negotiable. π
the user defined attributes get interpreted like this:
- empty list (first entry is a nil pointer) β matches every ASO. π
""(first entry is an empty string) β matches every ASO that has no user defined attributes.name[=]β matches if a user defined attribute with the givennameis present.name=valueβ matches all ASOs that have a corresponding user defined attribute that has at least the givenvalue.
π af_getkey and friends π
af_getkey builds up an object key from a combination of attributes β pathname, name, type, generation number, revision number and variant name β that uniquely identifies a source ASO. on a successful completion, the found object key is returned in the buffer key. π₯
and here's a cute trick: instead of explicit version numbers, you can pass the pseudo-numbers AF_BUSYVERS, AF_FIRSTVERS or AF_LASTVERS to af_getkey. note that af_getkey works only on source objects.
so this call right here:
af_getkey ("", "otto", "c", AF_BUSYVERS, AF_BUSYVERS, key)
leads to the key of the file (busy version) named otto.c in the current directory. β¨
and this one:
af_getkey ("", "otto", "c", AF_LASTVERS, AF_LASTVERS, key)
delivers the last saved version (if present) of the history of otto.c. obsessed.
π«Ά giving your keys back (yes, you have to) π«Ά
once you've retrieved a key or a whole set of keys, the data for the corresponding object version(s) stays cached in memory for as long as your application doesn't explicitly hand the key back. it's giving "you borrowed my hoodie and i need it back." π
af_dropkeygives a key back and releases the object version.- a retrieved set of keys has to be given back with
af_dropset. af_dropallsets all reference counters for cached object versions to zero β which means it gives all formerly retrieved keys and sets back. it's the "everyone out of the pool" of AtFS. π
β DIAGNOSTICS β
af_find returns the number of found ASOs. upon error, -1 is returned and af_errno is set to the corresponding error number. so like, if you see -1, go check af_errno, bestie, it's telling you what's wrong. π
and that's the whole page, fr fr. this was af_retrieve(3) from AtFS-1.71, dated Fri Jun 25 14:33:18 1993 β yes, 1993, she's vintage and she's iconic, we stan a legacy filesystem. πβ¨
π¦ where this page comes from
- debian bookworm: atfs-dev 1.4pl6-15+b1
- ubuntu jammy: atfs-dev 1.4pl6-15
- ubuntu noble: atfs-dev 1.4pl6-16.1build1
- ubuntu resolute: atfs-dev 1.4pl6-17
- ubuntu stonking: atfs-dev 1.4pl6-17
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms