aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--Makefile1
-rw-r--r--main.c108
-rw-r--r--page.c80
-rw-r--r--page.h2
-rw-r--r--style.c55
-rw-r--r--style.h9
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)
diff --git a/Makefile b/Makefile
index 09f3cb2..ab56da6 100644
--- a/Makefile
+++ b/Makefile
@@ -21,6 +21,7 @@ OBJECTS = \
main.o \
page.o \
server.o \
+ style.o \
wildcard_cmp.o \
all: $(PROJECT)
diff --git a/main.c b/main.c
index 2dee5f6..26cdadc 100644
--- a/main.c
+++ b/main.c
@@ -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)
diff --git a/page.c b/page.c
index eb7ae99..6093d7f 100644
--- a/page.c
+++ b/page.c
@@ -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)
diff --git a/page.h b/page.h
index 748380d..749ebd0 100644
--- a/page.h
+++ b/page.h
@@ -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);
diff --git a/style.c b/style.c
new file mode 100644
index 0000000..07feb44
--- /dev/null
+++ b/style.c
@@ -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;
diff --git a/style.h b/style.h
new file mode 100644
index 0000000..7466ad9
--- /dev/null
+++ b/style.h
@@ -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