diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-07-11 01:20:39 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-07-11 01:49:12 +0200 |
| commit | e79e955d93e24a192c9bf94181294d0797e9fded (patch) | |
| tree | 5c3697710b6aa004bb7e3747f4c8ba98b37d662d /main.c | |
| parent | 4236c7fc3a7c7ef9f79b045cfd99c6575b16f7b1 (diff) | |
| download | slcl-e79e955d93e24a192c9bf94181294d0797e9fded.tar.gz | |
Allow admins to define their own stylesheet
slcl used to provide a hardcoded stylesheet. However, it would be
desirable for some admins to provide a custom stylesheet without having
to rebuild the application.
Now, slcl creates a default stylesheet, namely style.css, into the
target directory, that can be later modified by admins.
While this might contradict the suckless philosophy a bit, hopefully
some admins might find this new feature useful.
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 108 |
1 files changed, 106 insertions, 2 deletions
@@ -6,6 +6,7 @@ #include "hex.h" #include "http.h" #include "page.h" +#include "style.h" #include "wildcard_cmp.h" #include <openssl/err.h> #include <openssl/rand.h> @@ -24,6 +25,8 @@ #include <stdlib.h> #include <string.h> +#define STYLE_PATH "style.css" + struct form { char *key, *value; @@ -59,7 +62,32 @@ static int serve_index(const struct http_payload *const p, static int serve_style(const struct http_payload *const p, struct http_response *const r, void *const user) { - return page_style(r); + int ret = -1; + struct auth *const a = user; + const char *const dir = auth_dir(a); + struct dynstr d; + + dynstr_init(&d); + + if (!dir) + { + fprintf(stderr, "%s: auth_dir failed\n", __func__); + goto end; + } + else if (dynstr_append(&d, "%s/" STYLE_PATH, dir)) + { + fprintf(stderr, "%s: dynstr_append failed\n", __func__); + goto end; + } + else if ((ret = page_style(r, d.str))) + { + fprintf(stderr, "%s: page_style failed\n", __func__); + goto end; + } + +end: + dynstr_free(&d); + return ret; } static char *alloc_form_data(const char *const s, const char **const end) @@ -1796,6 +1824,81 @@ end: return ret; } +static int dump_default_style(const char *const path) +{ + int ret = -1; + FILE *const f = fopen(path, "wb"); + + if (!f) + { + fprintf(stderr, "%s: fopen(3) %s: %s\n", + __func__, path, strerror(errno)); + goto end; + } + else if (!fwrite(style_default, style_default_len, 1, f)) + { + fprintf(stderr, "%s: fwrite(3): %s\n", __func__, strerror(errno)); + goto end; + } + + printf("Dumped default stylesheet into %s\n", path); + ret = 0; + +end: + if (f && fclose(f)) + { + fprintf(stderr, "%s: fclose(3): %s\n", __func__, strerror(errno)); + ret = -1; + } + + return ret; +} + +static int ensure_style(const char *const dir) +{ + int ret = -1; + struct dynstr d; + struct stat sb; + + dynstr_init(&d); + + if (dynstr_append(&d, "%s/" STYLE_PATH, dir)) + { + fprintf(stderr, "%s: dynstr_append user failed\n", __func__); + goto end; + } + else if (stat(d.str, &sb)) + { + switch (errno) + { + case ENOENT: + if (dump_default_style(d.str)) + { + fprintf(stderr, "%s: dump_default_style failed\n", + __func__); + goto end; + } + + break; + + default: + fprintf(stderr, "%s: stat(2): %s\n", __func__, strerror(errno)); + goto end; + } + } + else if (!S_ISREG(sb.st_mode)) + { + fprintf(stderr, "%s: %s not a regular file\n", __func__, d.str); + return -1; + } + + ret = 0; + +end: + dynstr_free(&d); + return ret; +} + int main(int argc, char *argv[]) { int ret = EXIT_FAILURE; @@ -1806,6 +1909,7 @@ int main(int argc, char *argv[]) if (parse_args(argc, argv, &dir, &port, &tmpdir) || init_dirs(dir) + || ensure_style(dir) || !(a = auth_alloc(dir))) goto end; @@ -1819,7 +1923,7 @@ int main(int argc, char *argv[]) if (!(h = handler_alloc(&cfg)) || handler_add(h, "/", HTTP_OP_GET, serve_index, a) || handler_add(h, "/index.html", HTTP_OP_GET, serve_index, a) - || handler_add(h, "/style.css", HTTP_OP_GET, serve_style, NULL) + || handler_add(h, "/style.css", HTTP_OP_GET, serve_style, a) || handler_add(h, "/user/*", HTTP_OP_GET, getnode, a) || handler_add(h, "/login", HTTP_OP_POST, login, a) || handler_add(h, "/logout", HTTP_OP_POST, logout, a) |
