aboutsummaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c114
1 files changed, 77 insertions, 37 deletions
diff --git a/main.c b/main.c
index 3702706..e42236d 100644
--- a/main.c
+++ b/main.c
@@ -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;