From 38f8e2242353711d5c87c58f3831306934d2e6b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Ankarstr=C3=B6m?= Date: Fri, 17 Sep 2021 11:20:43 +0200 Subject: Compartmentalize --- Makefile | 7 ++++-- cforum.c | 74 +++++++++++++++++++++++++++++++++----------------------------- ctl.h | 1 + err.c | 13 +++++++++++ err.h | 1 + front.c | 10 ++++++++- front.t | 11 ---------- query.c | 29 ++++++++++++++++++++++++ query.h | 4 ++++ site.h | 3 +++ t/err.t | 2 ++ t/err.tc | 5 +++++ t/foot.t | 2 ++ t/foot.tc | 1 + t/front.t | 2 ++ t/front.tc | 4 ++++ t/head.t | 7 ++++++ t/head.tc | 3 +++ 18 files changed, 131 insertions(+), 48 deletions(-) create mode 100644 ctl.h create mode 100644 err.c create mode 100644 err.h delete mode 100644 front.t create mode 100644 query.c create mode 100644 query.h create mode 100644 site.h create mode 100644 t/err.t create mode 100644 t/err.tc create mode 100644 t/foot.t create mode 100644 t/foot.tc create mode 100644 t/front.t create mode 100644 t/front.tc create mode 100644 t/head.t create mode 100644 t/head.tc diff --git a/Makefile b/Makefile index 4bf3230..512b613 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,11 @@ .SUFFIXES: .c .t .tc LDFLAGS += -lsqlite3 -cforum: cforum.c front.c front.tc - $(CC) $(CFLAGS) $(LDFLAGS) -o cforum cforum.c +C = cforum.c err.c front.c query.c +TPL = t/err.tc t/foot.tc t/front.tc t/head.tc + +cforum: $(C) $(TPL) + $(CC) $(CFLAGS) $(LDFLAGS) -o cforum $(C) .t.tc: maketpl <$< ./maketpl >$@ diff --git a/cforum.c b/cforum.c index a42a0b3..7fc738e 100644 --- a/cforum.c +++ b/cforum.c @@ -3,66 +3,72 @@ #include #include -#define warn(...) fprintf(stderr, __VA_ARGS__) -#define die(...) do{ fprintf(stderr, __VA_ARGS__); exit(1); }while(0) -char *query(char *); -struct site { - char *name; -} site; +#include "ctl.h" /* Controllers. */ +#include "err.h" /* HTTP errors. */ +#include "site.h" /* Site settings. Defines global struct site. */ +#include "query.h" /* Query functions. Defines global string qs. */ -#include "front.c" +#define MAXERR 300 int main(int argc, char *argv[]) { - char *qs; + char err[MAXERR], *qs; sqlite3 *db; sqlite3_stmt *res; - /* Retrieve site name from database. */ + /* + * The database is opened or a server error is generated. + * In the rest of the program, the database is always + * assumed to be opened. + */ if(sqlite3_open("db", &db) != SQLITE_OK){ - warn("%s\n", sqlite3_errmsg(db)); + snprintf(err, MAXERR, + "The database could not be opened: %s\n", + sqlite3_errmsg(db)); + srverr(err); sqlite3_close(db); return 1; } + /* + * The site name is retrieved from the database. This early on, + * it is appropriate to die with a server error on failure. + */ if(sqlite3_prepare(db, "SELECT value FROM settings WHERE key = 'name'", -1, &res, 0) != SQLITE_OK){ - warn("%s\n", sqlite3_errmsg(db)); + snprintf(err, MAXERR, + "The site name could not be retrieved: %s\n", + sqlite3_errmsg(db)); + srverr(err); sqlite3_close(db); return 1; } - if(sqlite3_step(res) == SQLITE_ROW) site.name = strdup(sqlite3_column_text(res, 0)); - + else{ + snprintf(err, MAXERR, "The site name is not set.\n"); + srverr(err); + sqlite3_finalize(res); + sqlite3_close(db); + return 1; + } sqlite3_finalize(res); - sqlite3_close(db); + + /* + * The global variable qs is set to the query string, or the + * program dies. From now on, qs is assumed to be set. + */ + setqs(); /* Handle request. */ - qs = getenv("QUERY_STRING"); if(!qs || !*qs) front(); + /* INSERT CONDITIONS HERE */ + else + front(); + sqlite3_close(db); return 0; -} - -char * -query(char *key) -{ - static char *qs; - char *w; - int n; - - if(!qs) qs = getenv("QUERY_STRING"); - if(!qs) die("no QUERY_STRING"); - - for(w = strtok(qs, "&"); w; w = strtok(NULL, "&")){ - n = strcspn(w, "="); - if(strncmp(w, key, n) == 0) - return w + n + (w[n] == '='); - } - - return NULL; } \ No newline at end of file diff --git a/ctl.h b/ctl.h new file mode 100644 index 0000000..144b6dd --- /dev/null +++ b/ctl.h @@ -0,0 +1 @@ +void front(void); \ No newline at end of file diff --git a/err.c b/err.c new file mode 100644 index 0000000..d6f66ad --- /dev/null +++ b/err.c @@ -0,0 +1,13 @@ +#include + +void +srverr(char *err) +{ + char title[] = "500 Internal Server Error"; + + printf("Status: %s\n", title); + printf("Content-Type: text/html\n\n"); + #include "t/head.tc" + #include "t/err.tc" + #include "t/foot.tc" +} \ No newline at end of file diff --git a/err.h b/err.h new file mode 100644 index 0000000..bf218f5 --- /dev/null +++ b/err.h @@ -0,0 +1 @@ +void srverr(char *); \ No newline at end of file diff --git a/front.c b/front.c index 6b8615c..ff6973e 100644 --- a/front.c +++ b/front.c @@ -1,6 +1,14 @@ +#include +#include "site.h" + void front() { + char *title; + + title = site.name; printf("Content-Type: text/html\n\n"); - #include "front.tc" + #include "t/head.tc" + #include "t/front.tc" + #include "t/foot.tc" } \ No newline at end of file diff --git a/front.t b/front.t deleted file mode 100644 index c2c416e..0000000 --- a/front.t +++ /dev/null @@ -1,11 +0,0 @@ - - - - -<%= site.name %> - - -

<%= site.name %>

-<% printf("Hello world!"); %> - - \ No newline at end of file diff --git a/query.c b/query.c new file mode 100644 index 0000000..09e7578 --- /dev/null +++ b/query.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include "query.h" + +void +setqs() +{ + qs = getenv("QUERY_STRING"); + if(!qs){ + fprintf(stderr, "no QUERY_STRING\n"); + exit(1); + } +} + +char * +query(char *key) +{ + char *w; + int n; + + for(w = strtok(qs, "&"); w; w = strtok(NULL, "&")){ + n = strcspn(w, "="); + if(strncmp(w, key, n) == 0) + return w + n + (w[n] == '='); + } + + return NULL; +} \ No newline at end of file diff --git a/query.h b/query.h new file mode 100644 index 0000000..81662a8 --- /dev/null +++ b/query.h @@ -0,0 +1,4 @@ +char *qs; + +void setqs(void); +char *query(char *); \ No newline at end of file diff --git a/site.h b/site.h new file mode 100644 index 0000000..e5dba32 --- /dev/null +++ b/site.h @@ -0,0 +1,3 @@ +struct site { + char *name; +} site; \ No newline at end of file diff --git a/t/err.t b/t/err.t new file mode 100644 index 0000000..437effc --- /dev/null +++ b/t/err.t @@ -0,0 +1,2 @@ +

<%= title %>

+

<%= err %>

\ No newline at end of file diff --git a/t/err.tc b/t/err.tc new file mode 100644 index 0000000..f6d48ab --- /dev/null +++ b/t/err.tc @@ -0,0 +1,5 @@ +printf("

"); +printf("%s", title ); +printf("

\n

"); +printf("%s", err ); +printf("

\n"); diff --git a/t/foot.t b/t/foot.t new file mode 100644 index 0000000..691287b --- /dev/null +++ b/t/foot.t @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/t/foot.tc b/t/foot.tc new file mode 100644 index 0000000..927824c --- /dev/null +++ b/t/foot.tc @@ -0,0 +1 @@ +printf("\n"); diff --git a/t/front.t b/t/front.t new file mode 100644 index 0000000..ed6fbf8 --- /dev/null +++ b/t/front.t @@ -0,0 +1,2 @@ +

<%= site.name %>

+<% printf("Hello world!"); %> \ No newline at end of file diff --git a/t/front.tc b/t/front.tc new file mode 100644 index 0000000..0d7aec3 --- /dev/null +++ b/t/front.tc @@ -0,0 +1,4 @@ +printf("

"); +printf("%s", site.name ); +printf("

\n"); + printf("Hello world!"); printf("\n"); diff --git a/t/head.t b/t/head.t new file mode 100644 index 0000000..d9da813 --- /dev/null +++ b/t/head.t @@ -0,0 +1,7 @@ + + + + +<%= title %> + + \ No newline at end of file diff --git a/t/head.tc b/t/head.tc new file mode 100644 index 0000000..c19b483 --- /dev/null +++ b/t/head.tc @@ -0,0 +1,3 @@ +printf("\n\n\n\n"); +printf("%s", title ); +printf("\n\n"); -- cgit v1.2.3