diff options
| -rw-r--r-- | CMakeLists.txt | 1 | ||||
| -rw-r--r-- | Makefile | 1 | ||||
| -rw-r--r-- | main.c | 108 | ||||
| -rw-r--r-- | page.c | 80 | ||||
| -rw-r--r-- | page.h | 2 | ||||
| -rw-r--r-- | style.c | 55 | ||||
| -rw-r--r-- | style.h | 9 |
7 files changed, 199 insertions, 57 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b4a381..7f0bbaf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,7 @@ add_executable(${PROJECT_NAME} main.c page.c server.c + style.c wildcard_cmp.c ) target_compile_options(${PROJECT_NAME} PRIVATE -Wall) @@ -21,6 +21,7 @@ OBJECTS = \ main.o \ page.o \ server.o \ + style.o \ wildcard_cmp.o \ all: $(PROJECT) @@ -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) @@ -1535,73 +1535,45 @@ int page_bad_request(struct http_response *const r) return 0; } -int page_style(struct http_response *const r) +int page_style(struct http_response *const r, const char *const path) { - static const char body[] = - "body\n" - "{\n" - " font-family: 'Courier New', Courier, monospace;\n" - "}\n" - "td\n" - "{\n" - " font-size: 14px;\n" - "}\n" - "a\n" - "{\n" - " text-decoration: none;\n" - "}\n" - ".userform\n" - "{\n" - " padding: 4px;\n" - "}\n" - ".loginform\n" - "{\n" - " display: grid;\n" - "}\n" - "form, label, table\n" - "{\n" - " margin: auto;\n" - "}\n" - "div\n" - "{\n" - " align-items: center;\n" - " display: grid;\n" - "}\n" - "input, .abutton\n" - "{\n" - " margin: auto;\n" - " border: 1px solid;\n" - " border-radius: 8px;\n" - "}\n" - "header, footer\n" - "{\n" - " display: flex;\n" - " justify-content: center;\n" - " text-decoration: auto;\n" - "}\n" - "table\n" - "{\n" - " max-width: 50%;\n" - "}\n" - "tr:nth-child(even)\n" - "{\n" - " background-color: lightgray;\n" - "}\n"; + FILE *f = NULL; + struct stat sb; + + if (stat(path, &sb)) + { + fprintf(stderr, "%s: stat(2): %s\n", __func__, strerror(errno)); + goto failure; + } + else if (!(f = fopen(path, "rb"))) + { + fprintf(stderr, "%s: fopen(3) %s: %s\n", + __func__, path, strerror(errno)); + goto failure; + } *r = (const struct http_response) { .status = HTTP_STATUS_OK, - .buf.ro = body, - .n = sizeof body - 1 + .f = f, + .n = sb.st_size }; if (http_response_add_header(r, "Content-Type", "text/css")) { fprintf(stderr, "%s: http_response_add_header failed\n", __func__); - return -1; + goto failure; } return 0; + +failure: + + if (f && fclose(f)) + fprintf(stderr, "%s: fclose(3) %s: %s\n", + __func__, path, strerror(errno)); + + return -1; } int page_share(struct http_response *const r, const char *const path) @@ -36,7 +36,7 @@ struct page_rm }; int page_login(struct http_response *r); -int page_style(struct http_response *r); +int page_style(struct http_response *r, const char *path); int page_failed_login(struct http_response *r); int page_forbidden(struct http_response *r); int page_bad_request(struct http_response *r); @@ -0,0 +1,55 @@ +#include "style.h" +#include <stddef.h> + +const char style_default[] = + "body\n" + "{\n" + " font-family: 'Courier New', Courier, monospace;\n" + "}\n" + "td\n" + "{\n" + " font-size: 14px;\n" + "}\n" + "a\n" + "{\n" + " text-decoration: none;\n" + "}\n" + ".userform\n" + "{\n" + " padding: 4px;\n" + "}\n" + ".loginform\n" + "{\n" + " display: grid;\n" + "}\n" + "form, label, table\n" + "{\n" + " margin: auto;\n" + "}\n" + "div\n" + "{\n" + " align-items: center;\n" + " display: grid;\n" + "}\n" + "input, .abutton\n" + "{\n" + " margin: auto;\n" + " border: 1px solid;\n" + " border-radius: 8px;\n" + "}\n" + "header, footer\n" + "{\n" + " display: flex;\n" + " justify-content: center;\n" + " text-decoration: auto;\n" + "}\n" + "table\n" + "{\n" + " max-width: 50%;\n" + "}\n" + "tr:nth-child(even)\n" + "{\n" + " background-color: lightgray;\n" + "}\n"; + +const size_t style_default_len = sizeof style_default - 1; @@ -0,0 +1,9 @@ +#ifndef STYLE_H +#define STYLE_H + +#include <stddef.h> + +extern const char style_default[]; +extern const size_t style_default_len; + +#endif |
