#include <ctype.h>#include <inttypes.h>#include <stdbool.h>#include <stdint.h>#include <stdlib.h>#include <string.h>#include <sys/stat.h>#include <unistd.h>#include <talloc.h>#include <atalk/cnid.h>#include <atalk/directory.h>#include <atalk/errchk.h>#include <atalk/globals.h>#include <atalk/logger.h>#include <atalk/spotlight.h>#include <atalk/util.h>#include <atalk/volume.h>#include "etc/afpd/volume.h"#include "etc/spotlight/spotlight_private.h"Data Structures | |
| struct | sl_did_cache_ent |
| struct | sl_cnid_query |
Macros | |
| #define | SL_CNID_START_RESULTS 10000 |
| #define | SL_CNID_MAX_CAP SPOTLIGHT_RESULTS_LIMIT_MAX |
| #define | SL_CNID_GROWTH 8 |
| #define | SL_CNID_DBD_HARD_CAP 10000 |
| #define | SL_CNID_MIN_TERMLEN 3 |
| #define | SL_CNID_MAX_TERMS 8 |
| #define | SL_CNID_PAGE_SIZE 20 |
| #define | SL_CNID_MAX_DEPTH 64 |
| #define | SL_CNID_DCACHE_MAX 4096 |
Functions | |
| static int | cnid_comp_fn (const void *p1, const void *p2) |
| static int | cnid32_comp_fn (const void *p1, const void *p2) |
| static char * | sl_cnid_quoted_value (TALLOC_CTX *mem_ctx, const char *p, const char **endp) |
| Extract the quoted value starting at or after p. | |
| static bool | sl_cnid_add_term (char **terms, int *count, char *term) |
| static int | sl_cnid_extract_terms (TALLOC_CTX *mem_ctx, const char *qstring, char **terms, int max_terms) |
| Extract all filename search terms from a Spotlight query. | |
| static const char * | sl_dcache_get (struct sl_cnid_query *csq, cnid_t did) |
| static void | sl_dcache_put (struct sl_cnid_query *csq, cnid_t did, const char *path) |
| static char * | sl_cnid_to_path (TALLOC_CTX *mem_ctx, const struct vol *vol, struct sl_cnid_query *csq, cnid_t cnid) |
| Reconstruct the full filesystem path for a CNID. | |
| static int | sl_cnid_init (AFPObj *obj) |
| static void | sl_cnid_close (AFPObj *obj) |
| static int | sl_cnid_fill_results (slq_t *slq) |
| Emit up to SL_CNID_PAGE_SIZE results from the private CNID buffer. | |
| static int | sl_cnid_cap_for (uint64_t want, int nterms) |
| static int | sl_cnid_collect (slq_t *slq, struct sl_cnid_query *csq, char **terms, int nterms, cnid_t scope_did) |
| Search every term into the candidate buffer and deduplicate. | |
| static bool | sl_cnid_scope_is_vol_root (const char *scope, const char *vol_path) |
| static int | sl_cnid_open_query (slq_t *slq) |
| static int | sl_cnid_fetch_results (slq_t *slq) |
| static void | sl_cnid_close_query (slq_t *slq) |
Variables | |
| const sl_backend_ops | sl_cnid_ops |
| #define SL_CNID_DBD_HARD_CAP 10000 |
| #define SL_CNID_DCACHE_MAX 4096 |
| #define SL_CNID_GROWTH 8 |
| #define SL_CNID_MAX_CAP SPOTLIGHT_RESULTS_LIMIT_MAX |
| #define SL_CNID_MAX_DEPTH 64 |
| #define SL_CNID_MAX_TERMS 8 |
| #define SL_CNID_MIN_TERMLEN 3 |
| #define SL_CNID_PAGE_SIZE 20 |
| #define SL_CNID_START_RESULTS 10000 |
|
static |
|
static |
|
static |
Append term to terms unless already present.
|
static |
Candidate capacity for want results across nterms search terms.
Every term needs a full CNID_FIND_MIN_RESULTS batch of room or cnid_find() refuses the call, so a small limit still allocates enough for all the terms; the surplus is trimmed from the results afterwards.
|
static |
|
static |
|
static |
Search every term into the candidate buffer and deduplicate.
Finder joins one predicate per typed word with ||, so the terms are alternatives: one cnid_find() per term into the shared buffer, then a sort and unique pass because a name can match more than one term. Each call's slice is kept a multiple of CNID_FIND_MIN_RESULTS so the DBD pagination loop fills complete batches.
Restartable: count and the truncation flag are reset on entry so the caller can re-run against a grown buffer.
|
static |
Extract all filename search terms from a Spotlight query.
Handles the common macOS patterns: kMDItemFSName = "foo*"cd → "foo" kMDItemDisplayName = "*foo*"cd → "foo" _kMDItemFileName = "foo*"cd → "foo" *=="foo*"cdw → "foo"
Finder splits a multi-word search into one predicate per word joined with ||, so every extracted term contributes to the result set. Named filename attributes take precedence; the *== "any attribute" form is scanned only when no named attribute matched. Duplicate terms are collapsed.
|
static |
|
static |
Emit up to SL_CNID_PAGE_SIZE results from the private CNID buffer.
Iterates over the remaining entries in csq->cnids[csq->pos..csq->count-1], resolving each CNID to a filesystem path and adding it to query_results. Stops after SL_CNID_PAGE_SIZE accepted results or when the buffer is exhausted, whichever comes first.
Sets slq_state to: SLQ_STATE_FULL — page is full, more results remain; client must poll SLQ_STATE_DONE — all results have been delivered SLQ_STATE_ERROR — add_filemeta() failed
|
static |
|
static |
|
static |
Extract the quoted value starting at or after p.
Scans to the first unescaped closing quote, strips unescaped leading/trailing '*' wildcards, drops one wrapping escaped-quote pair (Finder's exact-phrase delimiters; the substring search preserves adjacency by construction) and removes the remaining backslash escapes.
| mem_ctx | talloc context for the returned term |
| p | query-string position the scan starts from |
| endp | set to just past the closing quote when a quoted span was found (even if the term is rejected), NULL when no quoted span follows — the caller must stop scanning then |
|
static |
True when scope names the volume root (ignoring trailing slashes).
|
static |
Reconstruct the full filesystem path for a CNID.
Walks the DID chain upward via repeated cnid_resolve() calls, prepending path components, until reaching DIRDID_ROOT or a directory whose path is already memoized in the query's cache. Ancestor directory paths discovered along the way are memoized, so results sharing a directory resolve it once per query.
| mem_ctx | talloc context for the returned string |
| vol | volume whose CNID database to query |
| csq | per-query state carrying the directory memo |
| cnid | network-byte-order CNID (as returned by cnid_find) |
|
static |
|
static |
| const sl_backend_ops sl_cnid_ops |