aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--cforum.c4
-rw-r--r--ctl.c20
-rw-r--r--db.c82
-rw-r--r--db.h5
-rwxr-xr-xmktpl/mktplbin23988 -> 23988 bytes
-rw-r--r--mktpl/mktpl.c2
-rw-r--r--mktpl/mktpl.lex2
-rw-r--r--t/err.t4
-rw-r--r--t/err.tc6
-rw-r--r--t/front.t24
-rw-r--r--t/front.tc34
-rw-r--r--t/post.t13
-rw-r--r--t/post.tc19
-rw-r--r--t/user.t4
-rw-r--r--t/user.tc6
16 files changed, 142 insertions, 86 deletions
diff --git a/Makefile b/Makefile
index f6fdc96..37472bd 100644
--- a/Makefile
+++ b/Makefile
@@ -16,4 +16,5 @@ db:
sqlite3 db "CREATE TABLE users(name, full, hash NOT NULL, PRIMARY KEY (name));"
sqlite3 db "INSERT INTO users values('john', 'John Ankarström', '123');"
sqlite3 db "CREATE TABLE posts(parent INT, user INT NOT NULL, created INT NOT NULL, edited INT, subject NOT NULL, text NOT NULL, FOREIGN KEY (user) REFERENCES users(oid));"
- sqlite3 db "INSERT INTO posts values(NULL, 1, 1462137896, NULL, 'Hello World!', 'This is the first post.');" \ No newline at end of file
+ sqlite3 db "INSERT INTO posts values(NULL, 1, 1462137896, NULL, 'Hello World!', 'This is the first post.');"
+ sqlite3 db "INSERT INTO posts values(1, 1, 1462138896, NULL, 'Re: Hello World!', 'This is the second post!');" \ No newline at end of file
diff --git a/cforum.c b/cforum.c
index 19dee61..2997ced 100644
--- a/cforum.c
+++ b/cforum.c
@@ -73,8 +73,8 @@ main(int argc, char *argv[])
postid = userid = 0;
while(p = nextparam(GET, 128)){
v = split(p);
- if(strcmp(p, "post") == 0) postid = atoi(v);
- else if(strcmp(p, "user") == 0) userid = atoi(v);
+ if(!postid && strcmp(p, "post") == 0) postid = atoi(v);
+ else if(!userid && strcmp(p, "user") == 0) userid = atoi(v);
}
/* Handle request. */
diff --git a/ctl.c b/ctl.c
index 773e4f6..fbc9e63 100644
--- a/ctl.c
+++ b/ctl.c
@@ -22,12 +22,18 @@ void
showfront()
{
char *title;
+ sqlite3_stmt *stmt;
+
+ if(sqlite3_prepare(db,
+ "SELECT oid, * from posts ORDER BY created DESC",
+ -1, &stmt, 0) != SQLITE_OK){
+ srverr("Could not retrieve posts");
+ return;
+ }
title = site.name;
printf("Content-Type: text/html\n\n");
- #include "t/head.tc"
#include "t/front.tc"
- #include "t/foot.tc"
}
void
@@ -37,21 +43,19 @@ showpost(int id)
struct post *post;
struct user *user;
- if(!(post = getpost(id))){
+ if(!(post = getpost(byid("posts", id), 1))){
srverr("Could not retrieve post");
return;
}
- if(!(user = getuser(post->user))){
+ if(!(user = getuser(byid("users", post->user), 1))){
srverr("Could not retrieve post author");
return;
}
title = site.name;
printf("Content-Type: text/html\n\n");
- #include "t/head.tc"
#include "t/post.tc"
- #include "t/foot.tc"
}
void
@@ -60,15 +64,13 @@ showuser(int id)
char s[128], *title;
struct user *user;
- if(!(user = getuser(id))){
+ if(!(user = getuser(byid("users", id), 1))){
srverr("Could not retrieve user");
return;
}
title = site.name;
printf("Content-Type: text/html\n\n");
- #include "t/head.tc"
#include "t/user.tc"
- #include "t/foot.tc"
free(user);
} \ No newline at end of file
diff --git a/db.c b/db.c
index c6ddab2..5de57ec 100644
--- a/db.c
+++ b/db.c
@@ -1,76 +1,88 @@
#include <err.h>
#include <stdlib.h>
+#include <stdio.h>
#include <string.h>
#include <sqlite3.h>
#include "db.h"
+static char * textdup(const unsigned char *);
+
sqlite3_stmt *
-byid(int id, char *sql)
+byid(char *table, int id)
{
+ char sql[100];
sqlite3_stmt *stmt;
+ snprintf(sql, 100, "SELECT oid, * FROM %s WHERE oid = ?", table);
+
if(sqlite3_prepare(db, sql, -1, &stmt, 0) != SQLITE_OK)
return NULL;
-
+
if(sqlite3_bind_int(stmt, 1, id) != SQLITE_OK)
return NULL;
- if(sqlite3_step(stmt) != SQLITE_ROW)
- return NULL;
-
return stmt;
}
-char *
-textdup(const unsigned char *s)
-{
- return s? strdup((char *)s): NULL;
-}
-
struct post *
-getpost(int id)
+getpost(sqlite3_stmt *stmt, int final)
{
- sqlite3_stmt *stmt;
struct post *post;
- if(!(stmt = byid(id, "SELECT parent, user, created, edited, subject, text FROM posts WHERE oid = ?"))){
- sqlite3_finalize(stmt);
- return NULL;
- }
+ if(!stmt)
+ goto err;
+
+ if(sqlite3_step(stmt) != SQLITE_ROW)
+ goto err;
if(!(post = malloc(sizeof(struct post))))
err(1, "malloc");
- post->parent = sqlite3_column_int(stmt, 0);
- post->user = sqlite3_column_int(stmt, 1);
- post->created = sqlite3_column_int(stmt, 2);
- post->edited = sqlite3_column_int(stmt, 3);
- post->subject = textdup(sqlite3_column_text(stmt, 4));
- post->text = textdup(sqlite3_column_text(stmt, 5));
+ post->id = sqlite3_column_int(stmt, 0);
+ post->parent = sqlite3_column_int(stmt, 1);
+ post->user = sqlite3_column_int(stmt, 2);
+ post->created = sqlite3_column_int(stmt, 3);
+ post->edited = sqlite3_column_int(stmt, 4);
+ post->subject = textdup(sqlite3_column_text(stmt, 5));
+ post->text = textdup(sqlite3_column_text(stmt, 6));
- sqlite3_finalize(stmt);
+ if(final) sqlite3_finalize(stmt);
return post;
+
+err:
+ if(final) sqlite3_finalize(stmt);
+ return NULL;
}
struct user *
-getuser(int id)
+getuser(sqlite3_stmt *stmt, int final)
{
- sqlite3_stmt *stmt;
struct user *user;
- if(!(stmt = byid(id, "SELECT name, full, hash FROM users WHERE oid = ?"))){
- sqlite3_finalize(stmt);
- return NULL;
- }
+ if(!stmt)
+ goto err;
+
+ if(sqlite3_step(stmt) != SQLITE_ROW)
+ goto err;
if(!(user = malloc(sizeof(struct user))))
err(1, "malloc");
- user->id = id;
- user->name = textdup(sqlite3_column_text(stmt, 0));
- user->full = textdup(sqlite3_column_text(stmt, 1));
- user->hash = textdup(sqlite3_column_text(stmt, 2));
+ user->id = sqlite3_column_int(stmt, 0);
+ user->name = textdup(sqlite3_column_text(stmt, 1));
+ user->full = textdup(sqlite3_column_text(stmt, 2));
+ user->hash = textdup(sqlite3_column_text(stmt, 3));
- sqlite3_finalize(stmt);
+ if(final) sqlite3_finalize(stmt);
return user;
+
+err:
+ if(final) sqlite3_finalize(stmt);
+ return NULL;
+}
+
+char *
+textdup(const unsigned char *s)
+{
+ return s? strdup((char *)s): NULL;
} \ No newline at end of file
diff --git a/db.h b/db.h
index a70e156..81a6bcd 100644
--- a/db.h
+++ b/db.h
@@ -19,5 +19,6 @@ struct user{
char *hash;
};
-struct post *getpost(int);
-struct user *getuser(int); \ No newline at end of file
+sqlite3_stmt *byid(char *, int);
+struct post *getpost(sqlite3_stmt *, int);
+struct user *getuser(sqlite3_stmt *, int); \ No newline at end of file
diff --git a/mktpl/mktpl b/mktpl/mktpl
index 092441e..415d645 100755
--- a/mktpl/mktpl
+++ b/mktpl/mktpl
Binary files differ
diff --git a/mktpl/mktpl.c b/mktpl/mktpl.c
index 2ebc343..e806bef 100644
--- a/mktpl/mktpl.c
+++ b/mktpl/mktpl.c
@@ -1594,6 +1594,8 @@ text()
{
int i;
+ if(!len) return;
+
printf("printf(\"");
for(i = 0; i < len; i++){
if(buf[i] == '\\') printf("\\\\");
diff --git a/mktpl/mktpl.lex b/mktpl/mktpl.lex
index 56ce93f..1940f02 100644
--- a/mktpl/mktpl.lex
+++ b/mktpl/mktpl.lex
@@ -66,6 +66,8 @@ text()
{
int i;
+ if(!len) return;
+
printf("printf(\"");
for(i = 0; i < len; i++){
if(buf[i] == '\\') printf("\\\\");
diff --git a/t/err.t b/t/err.t
index 437effc..9a4aa61 100644
--- a/t/err.t
+++ b/t/err.t
@@ -1,2 +1,4 @@
+<% #include "head.tc" %>
<h1><%= title %></h1>
-<p><%= err %></p> \ No newline at end of file
+<p><%= err %></p>
+<% #include "foot.tc" %> \ No newline at end of file
diff --git a/t/err.tc b/t/err.tc
index c4369a9..c066a5a 100644
--- a/t/err.tc
+++ b/t/err.tc
@@ -1,5 +1,7 @@
-printf("<h1>");
+#include "head.tc"
+printf("\n<h1>");
printf("%s", title );
printf("</h1>\n<p>");
printf("%s", err );
-printf("</p>");
+printf("</p>\n");
+#include "foot.tc"
diff --git a/t/front.t b/t/front.t
index a9badb0..86b8fb5 100644
--- a/t/front.t
+++ b/t/front.t
@@ -1,20 +1,24 @@
+<% #include "head.tc" %>
<h1><%= site.name %></h1>
<p>Thanks for the <%= getenv("REQUEST_METHOD") %> request!</p>
<table border="1">
- <tr style="font-weight: bold;">
- <td style="width: 60px;">Key</td>
- <td style="width: 140px;">Value</td>
- </tr>
<%
- char *p, *v;
- while(p = nextparam(GET, 512)){
- v = split(p);
+ struct post *post;
+ struct user *user;
+
+ while(post = getpost(stmt, 0)){
+ user = getuser(byid("users", post->user), 1);
%>
<tr>
- <td><%= p %></td>
- <td><%= v %></td>
+ <td><a href="?user=<% printf("%d", post->user); %>"><%=
+ user->name
+ %></a></td>
+ <td><a href="?post=<% printf("%d", post->id); %>"><%=
+ post->subject
+ %></a></td>
</tr>
<%
}
%>
-</table> \ No newline at end of file
+</table>
+<% #include "foot.tc" %> \ No newline at end of file
diff --git a/t/front.tc b/t/front.tc
index d7afb7b..f95d8cb 100644
--- a/t/front.tc
+++ b/t/front.tc
@@ -1,17 +1,29 @@
-printf("<h1>");
+#include "head.tc"
+printf("\n<h1>");
printf("%s", site.name );
printf("</h1>\n<p>Thanks for the ");
printf("%s", getenv("REQUEST_METHOD") );
-printf(" request!</p>\n<table border=\"1\">\n <tr style=\"font-weight: bold;\">\n <td style=\"width: 60px;\">Key</td>\n <td style=\"width: 140px;\">Value</td>\n </tr>\n ");
- char *p, *v;
- while(p = nextparam(GET, 512)){
- v = split(p);
+printf(" request!</p>\n<table border=\"1\">\n ");
+ struct post *post;
+ struct user *user;
-printf("\n <tr>\n <td>");
-printf("%s", p );
-printf("</td>\n <td>");
-printf("%s", v );
-printf("</td>\n </tr>\n ");
+ while(post = getpost(stmt, 0)){
+ user = getuser(byid("users", post->user), 1);
+
+printf("\n <tr>\n <td><a href=\"?user=");
+printf("%d", post->user);
+printf("\">");
+printf("%s",
+ user->name
+ );
+printf("</a></td>\n <td><a href=\"?post=");
+printf("%d", post->id);
+printf("\">");
+printf("%s",
+ post->subject
+ );
+printf("</a></td>\n </tr>\n ");
}
-printf("\n</table>");
+printf("\n</table>\n");
+#include "foot.tc"
diff --git a/t/post.t b/t/post.t
index 83529d7..b4d1e52 100644
--- a/t/post.t
+++ b/t/post.t
@@ -1,13 +1,16 @@
+<% #include "head.tc" %>
<h1>Post <% printf("%d", id); %>: <%= post->subject %></h1>
-<p>From: <%= user->full? user->full: "" %> <%
-if(user->full) printf("&lt;");
-%><a href="?user=<% printf("%d", user->id); %>"><%= user->name %></a><%
-if(user->full) printf("&gt;"); %>
+<p>From: <%= user->full? user->full: "" %>
+<% if(user->full) printf("&lt;"); %><a href="?user=<% printf("%d", user->id); %>"><%= user->name %></a><% if(user->full) printf("&gt;"); %>
<br>Date: <% printdate(post->created); %>
<% if(post->edited){
printf("<br>Edited: ");
printdate(post->edited);
} %>
+<% if(post->parent){ %>
+<br>In Reply To: <a href="?post=<% printf("%d", post->parent); %>"><% printf("%d", post->parent); %></a>
+<% } %>
<pre>
<%= post->text %>
-</pre> \ No newline at end of file
+</pre>
+<% #include "foot.tc" %> \ No newline at end of file
diff --git a/t/post.tc b/t/post.tc
index 732f0a7..9207de5 100644
--- a/t/post.tc
+++ b/t/post.tc
@@ -1,12 +1,12 @@
-printf("<h1>Post ");
+#include "head.tc"
+printf("\n<h1>Post ");
printf("%d", id);
printf(": ");
printf("%s", post->subject );
printf("</h1>\n<p>From: ");
printf("%s", user->full? user->full: "" );
-printf(" ");
-if(user->full) printf("&lt;");
-
+printf("\n");
+if(user->full) printf("&lt;");
printf("<a href=\"?user=");
printf("%d", user->id);
printf("\">");
@@ -20,6 +20,15 @@ if(post->edited){
printf("<br>Edited: ");
printdate(post->edited);
}
+printf("\n");
+if(post->parent){
+printf("\n<br>In Reply To: <a href=\"?post=");
+printf("%d", post->parent);
+printf("\">");
+printf("%d", post->parent);
+printf("</a>\n");
+}
printf("\n<pre>\n");
printf("%s", post->text );
-printf("\n</pre>");
+printf("\n</pre>\n");
+#include "foot.tc"
diff --git a/t/user.t b/t/user.t
index 9a0fd49..af7c8cd 100644
--- a/t/user.t
+++ b/t/user.t
@@ -1 +1,3 @@
-<h1>User <% printf("%d", id); %>: <%= user->name %></h1> \ No newline at end of file
+<% #include "head.tc" %>
+<h1>User <% printf("%d", id); %>: <%= user->name %></h1>
+<% #include "foot.tc" %> \ No newline at end of file
diff --git a/t/user.tc b/t/user.tc
index 3d92e16..3527acb 100644
--- a/t/user.tc
+++ b/t/user.tc
@@ -1,5 +1,7 @@
-printf("<h1>User ");
+#include "head.tc"
+printf("\n<h1>User ");
printf("%d", id);
printf(": ");
printf("%s", user->name );
-printf("</h1>");
+printf("</h1>\n");
+#include "foot.tc"