summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Douillet <vincent@vdouillet.fr>2023-11-28 08:38:19 +0100
committerVincent Douillet <vincent@vdouillet.fr>2023-11-29 15:45:28 +0100
commit43f65c76152017420ce723b4d4ef4230ff072818 (patch)
tree5c981b2d6949ebd5a5bdefe112383f6874d9342a
parenta8158372e4173f760d893516c0d8aecbb0e737ac (diff)
browse: use khttp_template
-rw-r--r--Makefile13
-rw-r--r--README.md2
-rw-r--r--browse.c76
-rw-r--r--config.h7
-rw-r--r--main.c4
-rwxr-xr-xtemplate/browse_file.html1
-rw-r--r--util.c43
-rw-r--r--util.h12
8 files changed, 145 insertions, 13 deletions
diff --git a/Makefile b/Makefile
index eace3fd..d269beb 100644
--- a/Makefile
+++ b/Makefile
@@ -30,15 +30,21 @@ CC=cc
CFLAGS_DEPS != pkg-config --cflags kcgi kcgi-html
LDFLAGS_DEPS != pkg-config --libs kcgi kcgi-html
-CFLAGS=-g -W -Wall -Wextra -DLOG_INFO $(CFLAGS_DEPS)
+CFLAGS=-O2 -DLOG_INFO $(CFLAGS_DEPS)
LDFLAGS=-static $(LDFLAGS_DEPS)
+.if make(debug)
+CFLAGS+=-g -W -Wall -Wextra -DTEMPLATE_DIR='"template"'
+.endif
+
+debug: main
+
all: main
.c.o:
$(CC) -o $@ -c $< $(CFLAGS)
-main: url.o http.o download.o browse.o main.o
+main: util.o url.o http.o download.o browse.o main.o
$(CC) -o $@ $> $(LDFLAGS)
env: env.o
@@ -48,7 +54,8 @@ kcgienv: kcgienv.o
$(CC) -o $@ $> $(LDFLAGS)
install:
- install -o www -g www -m 0500 main /var/www/cgi-bin/vault
+ install -D -o www -g www -m 0500 main /var/www/cgi-bin/vault
+ install -D -o www -g www -m 0440 template/browse_file.html /var/www/usr/share/vault/template/browse_file.html
clean:
rm -f *.o *.BAK main
diff --git a/README.md b/README.md
index 482d762..decf0e5 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ It should also compile and run on any POSIX OS with minor modifications, althoug
## Configure
-The parameters and their documentation are in the `config.h` source file. You should read and adjust this file as needed before you build.
+The parameters and their documentation are in the `config.h` source file. You should read and adjust this file as needed before you build. The default config assumes a chrooted web server and sets a data directory `/vault-data` (that is `/var/www/vault-data` outside of the chroot).
## Build & run
diff --git a/browse.c b/browse.c
index 0c81f83..23a1001 100644
--- a/browse.c
+++ b/browse.c
@@ -43,6 +43,7 @@
#include "config.h"
#include "http.h"
#include "url.h"
+#include "util.h"
/*
* list of files for current directory
@@ -153,13 +154,56 @@ build_file_list(struct kreq * r, char *request_dir)
return 0;
}
+const char *const template_keys[] = {"name", "url"};
+
+/*
+ * data required in the template function
+ */
+struct template_data {
+ struct kreq *r;
+ struct file *f;
+};
+
+static int
+template_callback(size_t index, void *arg)
+{
+ struct kreq *r;
+ struct template_data *data;
+
+ if (arg == NULL) {
+ kutil_warn(NULL, NULL, "Invalid data for browse template");
+ return 0;
+ }
+ data = arg;
+ r = data->r;
+ switch (index) {
+ case 0:
+ /* name */
+ K_OK(khttp_puts(r, data->f->name), r);
+ break;
+ case 1:
+ /* url */
+ K_OK(khttp_puts(r, data->f->url), r);
+ break;
+ default:
+ kutil_warnx(r, NULL, "Invalid key index for browse template: %zd", index);
+ return 0;
+ }
+
+ return 1;
+}
+
void
browse(struct kreq * r)
{
- size_t url_len;
+ size_t url_len, template_buf_len;
char current_dir[PATH_MAX];
+ char template_path[PATH_MAX];
+ char *template_buf;
struct file *file;
struct khtmlreq html;
+ struct ktemplate template;
+ struct template_data data;
/* check that the requested URL can be safely processed */
if (!check_request_path(r->path))
@@ -175,6 +219,18 @@ browse(struct kreq * r)
if (build_file_list(r, current_dir) < 0)
http_exit(r, KHTTP_500, "browse: Unable to build file list");
+ /* read template */
+ template_path[0] = '\0';
+ strlcat(template_path, TEMPLATE_DIR, PATH_MAX);
+ url_len = strlcat(template_path, "/browse_file.html", PATH_MAX);
+ if (url_len == 0 || url_len >= PATH_MAX)
+ http_exit(r, KHTTP_404, "browse: Unable to read template");
+
+ template_buf = NULL;
+ if (read_file(template_path, &template_buf, &template_buf_len) < 0
+ || template_buf == NULL)
+ http_exit(r, KHTTP_500, "browse: Unable to read template");
+
/* we have all the data we need, we can start to write output page */
http_open(r, KHTTP_200, r->mime);
@@ -190,17 +246,23 @@ browse(struct kreq * r)
K_OK(khtml_puts(&html, "/"), r);
K_OK(khtml_closeelem(&html, 1), r);
+ /* print file list */
+ template.key = template_keys;
+ template.keysz = 2;
+ template.cb = template_callback;
+ template.arg = &data;
+ data.r = r;
+
K_OK(khtml_elem(&html, KELEM_UL), r);
SLIST_FOREACH(file, &list, files) {
- K_OK(khtml_elem(&html, KELEM_LI), r);
- K_OK(khtml_attr(&html, KELEM_A, KATTR_HREF, file->url, KATTR__MAX),
- r);
- K_OK(khtml_puts(&html, file->name), r);
- K_OK(khtml_closeelem(&html, 2), r);
+ data.f = file;
+ K_OK(khttp_template_buf(r, &template, template_buf,
+ template_buf_len), r);
}
K_OK(khtml_close(&html), r);
- /* free list */
+ /* free list template and list */
+ free(template_buf);
file = NULL;
while (!SLIST_EMPTY(&list)) {
file = SLIST_FIRST(&list);
diff --git a/config.h b/config.h
index c79aedc..3f58258 100644
--- a/config.h
+++ b/config.h
@@ -37,7 +37,7 @@
* files.
*/
#ifndef DATA_DIR
-#define DATA_DIR "/var/www/vault-data"
+#define DATA_DIR "/vault-data"
#endif
/*
@@ -48,4 +48,9 @@
#define LOG_FILE "/var/log/vault.log"
#endif
+/* The directory that contains the HTML template files */
+#ifndef TEMPLATE_DIR
+#define TEMPLATE_DIR "/usr/share/vault/template"
+#endif
+
#endif /* CONFIG_H */
diff --git a/main.c b/main.c
index a9a9c5c..8f2e541 100644
--- a/main.c
+++ b/main.c
@@ -65,7 +65,9 @@ main(void)
kcgi_strerror(parse_err));
/* A bit of security cannot hurt */
- if (-1 == unveil(DATA_DIR, "r") || -1 == unveil(NULL, NULL))
+ if (-1 == unveil(DATA_DIR, "r")
+ || -1 == unveil(TEMPLATE_DIR, "r")
+ || -1 == unveil(NULL, NULL))
http_exit(&r, KHTTP_500, "Unveil failed: %s", strerror(errno));
if (-1 == pledge("stdio rpath wpath cpath", NULL))
http_exit(&r, KHTTP_500, "Pledge failed: %s", strerror(errno));
diff --git a/template/browse_file.html b/template/browse_file.html
new file mode 100755
index 0000000..48834dc
--- /dev/null
+++ b/template/browse_file.html
@@ -0,0 +1 @@
+<li><a href="@@url@@">@@name@@</a></li>
diff --git a/util.c b/util.c
new file mode 100644
index 0000000..54586c4
--- /dev/null
+++ b/util.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "util.h"
+
+int
+read_file(char *path, char **output, size_t * read_size)
+{
+ long file_size;
+ FILE *fp;
+
+ fp = fopen(path, "r");
+ if (fp == NULL)
+ return -1;
+
+ /* get file size */
+ if (fseek(fp, 0L, SEEK_END) != 0)
+ return -1;
+
+ file_size = ftell(fp);
+ if (file_size < 0)
+ return -1;
+
+ /* rewind to file start */
+ if (fseek(fp, 0L, SEEK_SET) != 0)
+ return -1;
+
+ /* create output buffer */
+ *output = malloc(sizeof(char) * (file_size + 1));
+ if (*output == NULL)
+ return -1;
+
+ /* read the file */
+ *read_size = fread(*output, sizeof(char), file_size, fp);
+ if (*read_size == 0 || ferror(fp) != 0) {
+ free(*output);
+ return -1;
+ }
+ /* enforce string termination */
+ (*output)[*read_size] = '\0';
+
+ return 0;
+}
diff --git a/util.h b/util.h
new file mode 100644
index 0000000..056f5a8
--- /dev/null
+++ b/util.h
@@ -0,0 +1,12 @@
+#ifndef UTIL_H
+#define UTIL_H
+
+/*
+ * Reads the file denoted by path into a newly allocated output buffer. Returns
+ * 0 for success, -1 for error. read_size is the size of output buffer (only to
+ * be used in case of success).
+ */
+int
+ read_file(char *path, char **output, size_t * read_size);
+
+#endif /* UTIL_H */