diff options
Diffstat (limited to 'browse.c')
-rw-r--r-- | browse.c | 156 |
1 files changed, 112 insertions, 44 deletions
@@ -44,7 +44,9 @@ #include "download.h" #include "file.h" #include "http.h" +#include "str.h" #include "template.h" +#include "upload.h" #include "url.h" /* @@ -53,7 +55,7 @@ SLIST_HEAD(, file) list; /* - * browse url = r->pname / BROWSE_URL / file->path / file->name + * browse url = r->pname / BROWSE_URL / file->path */ static size_t build_browse_url(struct kreq * r, struct file * file) @@ -65,7 +67,7 @@ build_browse_url(struct kreq * r, struct file * file) return 0; action_url_len = url_build(action_url, PATH_MAX, r->pname, BROWSE_URL, - file->path, file->name, NULL); + file->path, NULL); if (action_url_len == 0 || action_url_len >= PATH_MAX) { kutil_warn(r, NULL, "browse: action URL overflow: %s", action_url); @@ -82,16 +84,25 @@ build_browse_url(struct kreq * r, struct file * file) } static int -build_file_list(struct kreq * r, const char *request_dir) +build_file_list(struct kreq * r, const struct file * request_dir) { bool action_url_ok; - char *file_name; + char file_path[PATH_MAX], request_dir_path[PATH_MAX]; DIR *data_dir; + size_t file_path_len, request_dir_len; struct dirent *dir; struct file *file; struct file *last_file; - data_dir = opendir(request_dir); + request_dir_len = file_get_data_path(request_dir, request_dir_path, + PATH_MAX); + if (request_dir_len == 0) { + kutil_warn(r, NULL, + "browse: Unable to build request dir path: %s", + request_dir_path); + return -1; + } + data_dir = opendir(request_dir_path); if (NULL == data_dir) return -1; @@ -99,16 +110,24 @@ build_file_list(struct kreq * r, const char *request_dir) last_file = NULL; while ((dir = readdir(data_dir)) != NULL) { /* ignore special . and .. folders */ - file_name = dir->d_name; - if (strcmp(".", file_name) == 0 || strcmp("..", file_name) == 0) + if (strcmp(".", dir->d_name) == 0 + || strcmp("..", dir->d_name) == 0) + continue; + /* build file path */ + file_path_len = url_build(file_path, PATH_MAX, r->path, + dir->d_name, NULL); + if (file_path_len == 0 || file_path_len >= PATH_MAX) { + kutil_warn(r, NULL, + "browse: unable to build file, skipping %s", + dir->d_name); continue; + } /* build file */ - file = file_new(r->path, strlen(r->path), dir->d_name, - dir->d_namlen); + file = file_new(file_path); if (file == NULL) { kutil_warn(r, NULL, "browse: unable to allocate file, skipping %s", - file_name); + dir->d_name); continue; } /* build action url */ @@ -119,7 +138,7 @@ build_file_list(struct kreq * r, const char *request_dir) if (!action_url_ok) { kutil_warn(r, NULL, "browse: unable to build action url, skipping %s", - file_name); + dir->d_name); file_free(file); continue; } @@ -136,10 +155,8 @@ build_file_list(struct kreq * r, const char *request_dir) return 0; } -static const char *const template_keys[] = {"icon", "name", "url", "size"}; - /* - * data required in the template function + * data required in the template functions */ struct template_data { struct kreq *r; @@ -147,9 +164,45 @@ struct template_data { struct file *f; }; +static const char *const header_template_keys[] = {"upload_url"}; + +static int +header_template_callback(size_t index, void *arg) +{ + struct kreq *r; + struct khtmlreq *html; + struct template_data *data; + + if (arg == NULL) { + kutil_warn(NULL, NULL, + "Invalid data for browse header template"); + return 0; + } + data = arg; + r = data->r; + html = data->html; + + switch (index) { + case 0: + /* upload_url */ + K_OK(khtml_puts(html, data->f->action_url), r); + break; + default: + kutil_warnx(r, NULL, + "Invalid key index for browse header template: %zd", + index); + return 0; + } + + return 1; +} + +static const char *const file_template_keys[] = {"icon", "name", "url", "size"}; + static int -template_callback(size_t index, void *arg) +file_template_callback(size_t index, void *arg) { + char *basename; struct kreq *r; struct khtmlreq *html; struct template_data *data; @@ -158,7 +211,7 @@ template_callback(size_t index, void *arg) char size_read[] = {'k', 'M', 'G'}; if (arg == NULL) { - kutil_warn(NULL, NULL, "Invalid data for browse template"); + kutil_warn(NULL, NULL, "Invalid data for browse file template"); return 0; } data = arg; @@ -172,7 +225,14 @@ template_callback(size_t index, void *arg) break; case 1: /* name */ - K_OK(khtml_puts(html, data->f->name), r); + basename = file_get_basename(data->f); + if (basename == NULL) { + kutil_warnx(r, NULL, + "browse: unable to get file name: %s", + data->f->path); + break; + } + K_OK(khtml_puts(html, basename), r); break; case 2: /* url */ @@ -195,7 +255,7 @@ template_callback(size_t index, void *arg) break; default: kutil_warnx(r, NULL, - "Invalid key index for browse template: %zd", + "Invalid key index for browse file template: %zd", index); return 0; } @@ -206,9 +266,6 @@ template_callback(size_t index, void *arg) struct http_ret browse(struct kreq * r) { - size_t url_len; - char current_dir[PATH_MAX]; - char *data_dir; struct file *file; struct page_template *tmpl; struct http_ret ret; @@ -217,6 +274,7 @@ browse(struct kreq * r) struct template_data data; /* initialize vars */ + file = NULL; tmpl = NULL; /* initialize return structure for success */ @@ -224,16 +282,6 @@ browse(struct kreq * r) KHTTP_200, "" }; - /* check that data dir is configured */ - data_dir = config_data_dir(); - if (data_dir == NULL) { - ret = (struct http_ret) { - KHTTP_400, - "browse: data dir is not configured" - }; - goto end; - } - /* check that the requested URL can be safely processed */ if (!check_request_path(r->path, r->suffix)) { ret = (struct http_ret) { @@ -243,28 +291,37 @@ browse(struct kreq * r) goto end; } /* list requested directory content */ - url_len = url_build(current_dir, PATH_MAX, data_dir, r->path, - NULL); - if (url_len == 0) { + file = file_new(r->path); + if (file == NULL) { + ret = (struct http_ret) { + KHTTP_404, + "browse: Unable to build data file" + }; + goto end; + } + if (!file->is_dir) { ret = (struct http_ret) { KHTTP_404, - "browse: Unable to build data path" + "browse: Invalid data file" }; goto end; } - if (url_len >= PATH_MAX) { + if (build_upload_url(r, file) == 0) { ret = (struct http_ret) { - KHTTP_414, "" + KHTTP_500, + "browse: Can't build upload url" }; goto end; } - if (build_file_list(r, current_dir) < 0) { + + if (build_file_list(r, file) < 0) { ret = (struct http_ret) { KHTTP_500, "browse: Unable to build file list" }; goto end; } + /* read template */ tmpl = page_template_new(BROWSE_URL); if (tmpl == NULL) { @@ -274,21 +331,29 @@ browse(struct kreq * r) }; goto end; } + /* we have all the data we need, we can start to write output page */ http_open(r, KHTTP_200, r->mime); K_OK(khttp_puts(r, tmpl->header), r); - K_OK(khttp_puts(r, tmpl->page_header), r); K_OK(khtml_open(&html, r, 0), r); - /* print file list */ - template.key = template_keys; - template.keysz = 4; - template.cb = template_callback; + /* print browse header with action buttons for current dir */ + template.key = header_template_keys; + template.keysz = 1; + template.cb = header_template_callback; template.arg = &data; data.r = r; data.html = &html; + data.f = file; + K_OK(khttp_template_buf(r, &template, tmpl->page_header, + strlen(tmpl->page_header)), r); + + /* print file list */ + template.key = file_template_keys; + template.keysz = 4; + template.cb = file_template_callback; SLIST_FOREACH(file, &list, files) { data.f = file; @@ -304,7 +369,10 @@ browse(struct kreq * r) /* free page template and file list */ end: page_template_free(tmpl); - file = NULL; + if (file != NULL) { + free(file); + file = NULL; + } while (!SLIST_EMPTY(&list)) { file = SLIST_FIRST(&list); SLIST_REMOVE_HEAD(&list, files); |