aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c20
-rw-r--r--page.c101
-rw-r--r--page.h12
3 files changed, 106 insertions, 27 deletions
diff --git a/main.c b/main.c
index 66328a8..7fca16d 100644
--- a/main.c
+++ b/main.c
@@ -700,14 +700,20 @@ static int getnode(const struct http_payload *const p,
goto end;
}
- const struct page_quota *const ppq = available ?
- &(const struct page_quota)
- {
- .cur = cur,
- .max = max
- } : NULL;
+ const struct page_resource pr =
+ {
+ .r = r,
+ .args = p->args,
+ .n_args = p->n_args,
+ .dir = dir.str,
+ .root = root.str,
+ .res = d.str,
+ .q = available ?
+ &(const struct page_quota) {.cur = cur, .max = max }
+ : NULL
+ };
- ret = page_resource(r, dir.str, root.str, d.str, ppq);
+ ret = page_resource(&pr);
end:
dynstr_free(&dir);
diff --git a/page.c b/page.c
index e731177..6c67484 100644
--- a/page.c
+++ b/page.c
@@ -16,6 +16,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include <strings.h>
#include <time.h>
#define PROJECT_NAME "slcl"
@@ -243,11 +244,50 @@ end:
return ret;
}
+static int prepare_preview(struct html_node *const n,
+ const struct stat *const sb, const char *const dir, const char *const name)
+{
+ int ret = -1;
+ struct html_node *a;
+ struct dynstr d;
+
+ dynstr_init(&d);
+
+ if (!S_ISREG(sb->st_mode))
+ return 0;
+ else if (!(a = html_node_add_child(n, "a")))
+ {
+ fprintf(stderr, "%s: html_node_add_child form failed\n", __func__);
+ goto end;
+ }
+ else if (dynstr_append(&d, "%s%s?preview=1", dir, name))
+ {
+ fprintf(stderr, "%s: dynstr_append failed\n", __func__);
+ goto end;
+ }
+ else if (html_node_add_attr(a, "href", d.str))
+ {
+ fprintf(stderr, "%s: html_node_add_attr failed\n", __func__);
+ goto end;
+ }
+ else if (html_node_set_value(a, "Preview"))
+ {
+ fprintf(stderr, "%s: html_node_set_value value failed\n", __func__);
+ goto end;
+ }
+
+ ret = 0;
+
+end:
+ dynstr_free(&d);
+ return ret;
+}
+
static int add_element(struct html_node *const n, const char *const dir,
const char *const res, const char *const name)
{
int ret = -1;
- enum {NAME, SIZE, DATE, SHARE, COLUMNS};
+ enum {NAME, SIZE, DATE, SHARE, PREVIEW, COLUMNS};
struct html_node *tr, *td[COLUMNS];
struct dynstr path;
const char *const sep = res[strlen(res) - 1] != '/' ? "/" : "";
@@ -301,6 +341,11 @@ static int add_element(struct html_node *const n, const char *const dir,
fprintf(stderr, "%s: prepare_date failed\n", __func__);
goto end;
}
+ else if (prepare_preview(td[PREVIEW], &sb, dir, name))
+ {
+ fprintf(stderr, "%s: prepare_date failed\n", __func__);
+ goto end;
+ }
ret = 0;
@@ -867,13 +912,12 @@ end:
return ret;
}
-static int list_dir(struct http_response *const r, const char *const dir,
- const char *const root, const char *const res,
- const struct page_quota *const q)
+static int list_dir(const struct page_resource *const pr)
{
int ret = -1;
struct dynstr out;
- struct html_node *table, *const html = resource_layout(dir, q, &table);
+ struct html_node *table,
+ *const html = resource_layout(pr->dir, pr->q, &table);
dynstr_init(&out);
@@ -882,7 +926,7 @@ static int list_dir(struct http_response *const r, const char *const dir,
fprintf(stderr, "%s: resource_layout failed\n", __func__);
goto end;
}
- else if (add_elements(root, res, dir, table))
+ else if (add_elements(pr->root, pr->res, pr->dir, table))
{
fprintf(stderr, "%s: read_elements failed\n", __func__);
goto end;
@@ -898,7 +942,7 @@ static int list_dir(struct http_response *const r, const char *const dir,
goto end;
}
- *r = (const struct http_response)
+ *pr->r = (const struct http_response)
{
.status = HTTP_STATUS_OK,
.buf.rw = out.str,
@@ -906,7 +950,7 @@ static int list_dir(struct http_response *const r, const char *const dir,
.free = free
};
- if (http_response_add_header(r, "Content-Type", "text/html"))
+ if (http_response_add_header(pr->r, "Content-Type", "text/html"))
{
fprintf(stderr, "%s: http_response_add_header failed\n", __func__);
goto end;
@@ -924,7 +968,7 @@ end:
}
static int serve_file(struct http_response *const r,
- const struct stat *const sb, const char *const res)
+ const struct stat *const sb, const char *const res, const bool preview)
{
int ret = -1;
FILE *const f = fopen(res, "rb");
@@ -949,6 +993,14 @@ static int serve_file(struct http_response *const r,
fprintf(stderr, "%s: basename(3) failed\n", __func__);
goto end;
}
+ else if (preview)
+ {
+ if (dynstr_append(&d, "inline"))
+ {
+ fprintf(stderr, "%s: dynstr_append inline failed\n", __func__);
+ goto end;
+ }
+ }
else if (dynstr_append(&d, "attachment; filename=\"%s\"", bn))
{
fprintf(stderr, "%s: dynstr_append attachment failed\n", __func__);
@@ -1007,19 +1059,32 @@ static int page_not_found(struct http_response *const r)
return 0;
}
-int page_resource(struct http_response *const r, const char *const dir,
- const char *const root, const char *const res,
- const struct page_quota *const q)
+static bool preview(const struct page_resource *const pr)
+{
+ for (size_t i = 0; i < pr->n_args; i++)
+ {
+ const struct http_arg *const a = &pr->args[i];
+
+ if (!strcmp(a->key, "preview")
+ && (!strcmp(a->value, "1")
+ || !strcasecmp(a->value, "true")))
+ return true;
+ }
+
+ return false;
+}
+
+int page_resource(const struct page_resource *const pr)
{
struct stat sb;
- if (stat(res, &sb))
+ if (stat(pr->res, &sb))
{
fprintf(stderr, "%s: stat(2) %s: %s\n",
- __func__, res, strerror(errno));
+ __func__, pr->res, strerror(errno));
if (errno == ENOENT)
- return page_not_found(r);
+ return page_not_found(pr->r);
else
return -1;
}
@@ -1027,9 +1092,9 @@ int page_resource(struct http_response *const r, const char *const dir,
const mode_t m = sb.st_mode;
if (S_ISDIR(m))
- return list_dir(r, dir, root, res, q);
+ return list_dir(pr);
else if (S_ISREG(m))
- return serve_file(r, &sb, res);
+ return serve_file(pr->r, &sb, pr->res, preview(pr));
fprintf(stderr, "%s: unexpected st_mode %jd\n", __func__, (intmax_t)m);
return -1;
@@ -1101,7 +1166,7 @@ int page_public(struct http_response *const r, const char *const res)
fprintf(stderr, "%s: resolve_link failed\n", __func__);
goto end;
}
- else if (serve_file(r, &sb, path))
+ else if (serve_file(r, &sb, path, false))
{
fprintf(stderr, "%s: serve_file failed\n", __func__);
goto end;
diff --git a/page.h b/page.h
index 094a21e..bd47138 100644
--- a/page.h
+++ b/page.h
@@ -8,13 +8,21 @@ struct page_quota
unsigned long long cur, max;
};
+struct page_resource
+{
+ struct http_response *r;
+ const char *dir, *root, *res;
+ const struct page_quota *q;
+ const struct http_arg *args;
+ size_t n_args;
+};
+
int page_login(struct http_response *r);
int page_style(struct http_response *r);
int page_failed_login(struct http_response *r);
int page_forbidden(struct http_response *r);
int page_bad_request(struct http_response *r);
-int page_resource(struct http_response *r, const char *dir, const char *root,
- const char *res, const struct page_quota *q);
+int page_resource(const struct page_resource *r);
int page_public(struct http_response *r, const char *res);
int page_share(struct http_response *r, const char *path);
int page_quota_exceeded(struct http_response *r, unsigned long long len,