diff options
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 114 |
1 files changed, 77 insertions, 37 deletions
@@ -46,6 +46,14 @@ struct user_args struct dynstr d; int fd; bool fifo; + void *state; +}; + +struct search +{ + struct cftw *cftw; + struct dynstr root, res; + struct page_search search; }; static struct handler *handler; @@ -647,24 +655,18 @@ static void search_results_free(struct page_search *const s) } } -struct search_args -{ - const char *root, *res; - struct page_search *s; -}; - static int search_fn(const char *const fpath, const struct stat *const sb, bool *const done, void *const user) { static const size_t limit = 200; - const struct search_args *const sa = user; - const char *rel = fpath + strlen(sa->root); - struct page_search *const res = sa->s; + struct search *const s = user; + const char *rel = fpath + strlen(s->root.str); + struct page_search *const res = &s->search; struct page_search_result *results = NULL, *r = NULL; rel += strspn(rel, "/"); - if (wildcard_cmp(rel, sa->res, false)) + if (wildcard_cmp(rel, s->res.str, false)) return 0; else if (!(results = realloc(res->results, (res->n + 1) * sizeof *res->results))) @@ -689,7 +691,7 @@ static int search_fn(const char *const fpath, const struct stat *const sb, if (++res->n >= limit) { - sa->s->limit_exceeded = true; + s->search.limit_exceeded = true; *done = true; } @@ -701,42 +703,62 @@ failure: return -1; } -static int do_search(const char *const abs, const char *const root, - const char *const res, struct page_search *const s) +static void free_search(struct search *const s) { - struct search_args sa = - { - .root = root, - .res = res, - .s = s - }; + if (!s) + return; + + search_results_free(&s->search); + dynstr_free(&s->root); + dynstr_free(&s->res); + cftw_free(s->cftw); + free(s); +} - s->root = root; +static int search_step(const struct http_payload *const p, + struct http_response *const r, void *const user) +{ + const struct user_args *const ua = user; + struct search *const s = ua->state; - if (cftw(abs, search_fn, &sa)) + switch (cftw_step(s->cftw)) { - fprintf(stderr, "%s: cftw failed\n", __func__); - return -1; + case CFTW_OK: + + if (page_search(r, &s->search)) + { + fprintf(stderr, "%s: page_search failed\n", __func__); + goto failure; + } + + free_search(s); + break; + + case CFTW_FATAL: + goto failure; + + case CFTW_AGAIN: + break; } return 0; + +failure: + free_search(s); + return -1; } static int search(const struct http_payload *const p, struct http_response *const r, void *const user) { int ret = -1; - const struct user_args *const args = user; + struct search *s = NULL; + struct user_args *const args = user; const struct auth *const a = args->a; const char *const username = p->cookie.field, *const root = auth_dir(a); int (*f)(struct http_response *); char *dir = NULL; struct dynstr userd, d, res; - struct page_search s = - { - .username = username, - .adir = root - }; dynstr_init(&userd); dynstr_init(&d); @@ -767,25 +789,42 @@ static int search(const struct http_payload *const p, fprintf(stderr, "%s: dynstr_append d failed\n", __func__); goto end; } - else if ((ret = do_search(d.str, userd.str, res.str, &s))) + else if ((!(s = malloc(sizeof *s)))) { - if (ret < 0) - fprintf(stderr, "%s: do_search failed\n", __func__); + fprintf(stderr, "%s: malloc(3): %s\n", __func__, strerror(errno)); + goto end; + } + + *s = (const struct search){0}; + dynstr_init(&s->root); + dynstr_init(&s->res); + if (!(s->cftw = cftw(d.str, search_fn, s))) + { + fprintf(stderr, "%s: cftw failed\n", __func__); goto end; } - else if ((ret = page_search(r, &s))) + else if (dynstr_dup(&s->root, &userd) + || dynstr_dup(&s->res, &res)) { - fprintf(stderr, "%s: page_search failed\n", __func__); + fprintf(stderr, "%s: dynstr_dup failed\n", __func__); goto end; } + *r = (const struct http_response){.step = search_step}; + s->search.root = s->root.str; + args->state = s; + ret = 0; + end: free(dir); - dynstr_free(&userd); dynstr_free(&d); + dynstr_free(&userd); dynstr_free(&res); - search_results_free(&s); + + if (ret) + free_search(s); + return ret; } @@ -947,7 +986,8 @@ static int check_length(const unsigned long long len, const struct http_cookie *const c, struct http_response *const r, void *const user) { - struct auth *const a = user; + const struct user_args *const ua = user; + const struct auth *const a = ua->a; const char *const username = c->field; bool has_quota; unsigned long long quota; |
