aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile7
-rw-r--r--cforum.c74
-rw-r--r--ctl.h1
-rw-r--r--err.c13
-rw-r--r--err.h1
-rw-r--r--front.c10
-rw-r--r--query.c29
-rw-r--r--query.h4
-rw-r--r--site.h3
-rw-r--r--t/err.t2
-rw-r--r--t/err.tc5
-rw-r--r--t/foot.t2
-rw-r--r--t/foot.tc1
-rw-r--r--t/front.t2
-rw-r--r--t/front.tc4
-rw-r--r--t/head.t (renamed from front.t)8
-rw-r--r--t/head.tc3
17 files changed, 126 insertions, 43 deletions
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 <stdlib.h>
#include <string.h>
-#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 <stdio.h>
+
+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 <stdio.h>
+#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/query.c b/query.c
new file mode 100644
index 0000000..09e7578
--- /dev/null
+++ b/query.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#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 @@
+<h1><%= title %></h1>
+<p><%= err %></p> \ 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("<h1>");
+printf("%s", title );
+printf("</h1>\n<p>");
+printf("%s", err );
+printf("</p>\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 @@
+</body>
+</html> \ 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("</body>\n</html>");
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 @@
+<h1><%= site.name %></h1>
+<% 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("<h1>");
+printf("%s", site.name );
+printf("</h1>\n");
+ printf("Hello world!"); printf("\n");
diff --git a/front.t b/t/head.t
index c2c416e..d9da813 100644
--- a/front.t
+++ b/t/head.t
@@ -2,10 +2,6 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
-<title><%= site.name %></title>
+<title><%= title %></title>
</head>
-<body>
-<h1><%= site.name %></h1>
-<% printf("Hello world!"); %>
-</body>
-</html> \ No newline at end of file
+<body> \ 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("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\">\n<title>");
+printf("%s", title );
+printf("</title>\n</head>\n<body>");