diff options
-rw-r--r-- | Makefile | 12 | ||||
-rw-r--r-- | cforum.c | 68 | ||||
-rw-r--r-- | front.c | 6 | ||||
-rw-r--r-- | front.t | 11 | ||||
-rwxr-xr-x | maketpl | 55 |
5 files changed, 152 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4bf3230 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +.SUFFIXES: .c .t .tc +LDFLAGS += -lsqlite3 + +cforum: cforum.c front.c front.tc + $(CC) $(CFLAGS) $(LDFLAGS) -o cforum cforum.c + +.t.tc: maketpl + <$< ./maketpl >$@ + +db: + sqlite3 db "CREATE TABLE settings(key UNIQUE, value);" + sqlite3 db "INSERT INTO settings values('name', 'C Forum');"
\ No newline at end of file diff --git a/cforum.c b/cforum.c new file mode 100644 index 0000000..a42a0b3 --- /dev/null +++ b/cforum.c @@ -0,0 +1,68 @@ +#include <sqlite3.h> +#include <stdio.h> +#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 "front.c" + +int +main(int argc, char *argv[]) +{ + char *qs; + sqlite3 *db; + sqlite3_stmt *res; + + /* Retrieve site name from database. */ + if(sqlite3_open("db", &db) != SQLITE_OK){ + warn("%s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + return 1; + } + + if(sqlite3_prepare(db, + "SELECT value FROM settings WHERE key = 'name'", + -1, &res, 0) != SQLITE_OK){ + warn("%s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + return 1; + } + + if(sqlite3_step(res) == SQLITE_ROW) + site.name = strdup(sqlite3_column_text(res, 0)); + + sqlite3_finalize(res); + sqlite3_close(db); + + /* Handle request. */ + qs = getenv("QUERY_STRING"); + if(!qs || !*qs) + front(); + + 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 @@ -0,0 +1,6 @@ +void +front() +{ + printf("Content-Type: text/html\n\n"); + #include "front.tc" +}
\ No newline at end of file @@ -0,0 +1,11 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html;charset=utf-8"> +<title><%= site.name %></title> +</head> +<body> +<h1><%= site.name %></h1> +<% printf("Hello world!"); %> +</body> +</html>
\ No newline at end of file @@ -0,0 +1,55 @@ +#!/usr/bin/env perl + +# `maketpl' translates a template file (.t) to a C program (.tc) +# that prints that template with the desired interpolations. + +use strict; +use warnings; + +my $buf; + +while (<STDIN>) { + if (/(.*)\<%=(.+)%\>(.*)/) { + $buf .= $1; + flsh(); + print qq(printf("%s", $2);\n); + if ($3) { + $buf .= "$3\n"; + } + } elsif (/(.*)\<%/) { + my $code; + $buf .= $1; + flsh(); + if (/\<%(.*)%\>(.*)/) { + $code = $1; + $buf .= $2; + $buf .= "\n"; + } else { + /\<%(.*)/; + $code = $1; + while (<STDIN>) { + if (/(.*)%\>(.*)/) { + $code .= $1; + $buf .= $2; + $buf .= "\n"; + last; + } + $code .= $_; + } + } + print $code; + } else { + $buf .= $_; + } +} + +flsh(); + +sub flsh { + return if not $buf; + $buf =~ s/\\/\\\\/g; + $buf =~ s/"/\\"/g; + $buf =~ s/\n/\\n/g; + print qq(printf("$buf");\n); + $buf = ''; +}
\ No newline at end of file |