aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Ankarström <john@ankarstrom.se>2021-09-18 01:52:04 +0200
committerJohn Ankarström <john@ankarstrom.se>2021-09-18 01:52:04 +0200
commit24bf14f6653ebf1c1ba79b9f212d35417bb6acbf (patch)
tree913a0f1bebf835a1109652b1c61d363972ee9a28
parente25f56cbe86041d4ab19e474e38032fa7e681ac7 (diff)
downloadcforum-24bf14f6653ebf1c1ba79b9f212d35417bb6acbf.tar.gz
Implement attachments
-rw-r--r--Makefile4
-rw-r--r--cforum.c16
-rw-r--r--ctl.c17
-rw-r--r--ctl.h1
-rw-r--r--db.c34
-rw-r--r--db.h11
-rw-r--r--t/front.t11
-rw-r--r--t/front.tc24
-rw-r--r--t/post.t22
-rw-r--r--t/post.tc22
10 files changed, 135 insertions, 27 deletions
diff --git a/Makefile b/Makefile
index ad5701d..5c1e856 100644
--- a/Makefile
+++ b/Makefile
@@ -18,4 +18,6 @@ db:
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.');"
- sqlite3 db "INSERT INTO posts values(1, 1, 1462138896, NULL, 'Re: Hello World!', 'This is the second post!');" \ No newline at end of file
+ sqlite3 db "INSERT INTO posts values(1, 1, 1462138896, NULL, 'Re: Hello World!', 'This is the second post!');"
+ sqlite3 db "CREATE TABLE attachments(post INT NOT NULL, name NOT NULL, description, mime NOT NULL, data BLOB, FOREIGN KEY (post) REFERENCES posts(oid));"
+ sqlite3 db "$$(printf "INSERT INTO attachments values(1, 'example', 'Some example shell code.', 'text/plain', '#!/bin/sh\necho Hello World!');")" \ No newline at end of file
diff --git a/cforum.c b/cforum.c
index 2997ced..dbf320c 100644
--- a/cforum.c
+++ b/cforum.c
@@ -15,7 +15,7 @@ int
main(int argc, char *argv[])
{
char err[MAXERR], *p, *qs, *v;
- int postid, userid;
+ int attachmentid, postid, userid;
sqlite3_stmt *stmt;
/*
@@ -70,15 +70,21 @@ main(int argc, char *argv[])
}
/* Parse query string. */
- postid = userid = 0;
+ attachmentid = postid = userid = 0;
while(p = nextparam(GET, 128)){
v = split(p);
- if(!postid && strcmp(p, "post") == 0) postid = atoi(v);
- else if(!userid && strcmp(p, "user") == 0) userid = atoi(v);
+ if(!attachmentid && strcmp(p, "attachment") == 0)
+ attachmentid = atoi(v);
+ else if(!postid && strcmp(p, "post") == 0)
+ postid = atoi(v);
+ else if(!userid && strcmp(p, "user") == 0)
+ userid = atoi(v);
}
/* Handle request. */
- if(postid)
+ if(attachmentid)
+ showattachment(attachmentid);
+ else if(postid)
showpost(postid);
else if(userid)
showuser(userid);
diff --git a/ctl.c b/ctl.c
index fbc9e63..51809db 100644
--- a/ctl.c
+++ b/ctl.c
@@ -19,6 +19,20 @@ printdate(int timestamp)
}
void
+showattachment(id)
+{
+ struct attachment *attachment;
+
+ if(!(attachment = getattachment(byid("attachments", id), 1))){
+ srverr("Could not retrieve attachment");
+ return;
+ }
+
+ printf("Content-Type: %s\n\n", attachment->mime);
+ printf("%.*s", attachment->bytes, attachment->data);
+}
+
+void
showfront()
{
char *title;
@@ -42,6 +56,7 @@ showpost(int id)
char *title;
struct post *post;
struct user *user;
+ sqlite3_stmt *stmt;
if(!(post = getpost(byid("posts", id), 1))){
srverr("Could not retrieve post");
@@ -53,6 +68,8 @@ showpost(int id)
return;
}
+ stmt = byid("attachments", id);
+
title = site.name;
printf("Content-Type: text/html\n\n");
#include "t/post.tc"
diff --git a/ctl.h b/ctl.h
index 7ac7030..c3797fc 100644
--- a/ctl.h
+++ b/ctl.h
@@ -1,3 +1,4 @@
+void showattachment(int);
void showfront(void);
void showpost(int);
void showuser(int); \ No newline at end of file
diff --git a/db.c b/db.c
index 5de57ec..653065e 100644
--- a/db.c
+++ b/db.c
@@ -24,6 +24,40 @@ byid(char *table, int id)
return stmt;
}
+struct attachment *
+getattachment(sqlite3_stmt *stmt, int final)
+{
+ struct attachment *attachment;
+
+ if(!stmt)
+ goto err;
+
+ if(sqlite3_step(stmt) != SQLITE_ROW)
+ goto err;
+
+ if(!(attachment = malloc(sizeof(struct attachment))))
+ err(1, "malloc");
+
+ attachment->id = sqlite3_column_int(stmt, 0);
+ attachment->post = sqlite3_column_int(stmt, 1);
+ attachment->name = textdup(sqlite3_column_text(stmt, 2));
+ attachment->description = textdup(sqlite3_column_text(stmt, 3));
+ attachment->mime = textdup(sqlite3_column_text(stmt, 4));
+
+ attachment->bytes = sqlite3_column_bytes(stmt, 5);
+ if(!(attachment->data = malloc(attachment->bytes)))
+ err(1, "malloc");
+ memcpy(attachment->data, sqlite3_column_blob(stmt, 5),
+ attachment->bytes);
+
+ if(final) sqlite3_finalize(stmt);
+ return attachment;
+
+err:
+ if(final) sqlite3_finalize(stmt);
+ return NULL;
+}
+
struct post *
getpost(sqlite3_stmt *stmt, int final)
{
diff --git a/db.h b/db.h
index 81a6bcd..9841d9c 100644
--- a/db.h
+++ b/db.h
@@ -2,6 +2,16 @@
sqlite3 *db;
+struct attachment{
+ int id;
+ int post;
+ int bytes;
+ char *name;
+ char *description;
+ char *mime;
+ char *data;
+};
+
struct post{
int id;
int parent;
@@ -20,5 +30,6 @@ struct user{
};
sqlite3_stmt *byid(char *, int);
+struct attachment *getattachment(sqlite3_stmt *, int);
struct post *getpost(sqlite3_stmt *, int);
struct user *getuser(sqlite3_stmt *, int); \ No newline at end of file
diff --git a/t/front.t b/t/front.t
index 86b8fb5..5f59c1c 100644
--- a/t/front.t
+++ b/t/front.t
@@ -1,6 +1,6 @@
<% #include "head.tc" %>
<h1><%= site.name %></h1>
-<p>Thanks for the <%= getenv("REQUEST_METHOD") %> request!</p>
+<h3>Latest posts</h3>
<table border="1">
<%
struct post *post;
@@ -10,12 +10,9 @@
user = getuser(byid("users", post->user), 1);
%>
<tr>
- <td><a href="?user=<% printf("%d", post->user); %>"><%=
- user->name
- %></a></td>
- <td><a href="?post=<% printf("%d", post->id); %>"><%=
- post->subject
- %></a></td>
+ <td><a href="?post=<% printf("%d", post->id); %>"><%= post->subject %></a></td>
+ <td><a href="?user=<% printf("%d", post->user); %>"><%= user->name %></a></td>
+ <td><% printdate(post->created); %></td>
</tr>
<%
}
diff --git a/t/front.tc b/t/front.tc
index f95d8cb..9bed8a1 100644
--- a/t/front.tc
+++ b/t/front.tc
@@ -1,28 +1,24 @@
#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 ");
+printf("</h1>\n<h3>Latest posts</h3>\n<table border=\"1\">\n ");
struct post *post;
struct user *user;
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("\n <tr>\n <td><a href=\"?post=");
printf("%d", post->id);
printf("\">");
-printf("%s",
- post->subject
- );
-printf("</a></td>\n </tr>\n ");
+printf("%s", post->subject );
+printf("</a></td>\n <td><a href=\"?user=");
+printf("%d", post->user);
+printf("\">");
+printf("%s", user->name );
+printf("</a></td>\n <td>");
+printdate(post->created);
+printf("</td>\n </tr>\n ");
}
printf("\n</table>\n");
diff --git a/t/post.t b/t/post.t
index b4d1e52..200e27d 100644
--- a/t/post.t
+++ b/t/post.t
@@ -13,4 +13,26 @@
<pre>
<%= post->text %>
</pre>
+<%
+struct attachment *attachment;
+
+if(attachment = getattachment(stmt, 0)){
+%>
+<h3>Attachments</h3>
+<table border="1">
+ <%
+ do{
+ %>
+ <tr>
+ <td><a href="?attachment=<% printf("%d", attachment->id); %>"><%= attachment->name %></a></td>
+ <td><%= attachment->mime %></td>
+ <td><%= attachment->description %></td>
+ </tr>
+ <%
+ }while(attachment = getattachment(stmt, 0));
+ %>
+</table>
+<%
+}
+%>
<% #include "foot.tc" %> \ No newline at end of file
diff --git a/t/post.tc b/t/post.tc
index 9207de5..89298db 100644
--- a/t/post.tc
+++ b/t/post.tc
@@ -31,4 +31,26 @@ printf("</a>\n");
printf("\n<pre>\n");
printf("%s", post->text );
printf("\n</pre>\n");
+struct attachment *attachment;
+
+if(attachment = getattachment(stmt, 0)){
+
+printf("\n<h3>Attachments</h3>\n<table border=\"1\">\n ");
+ do{
+
+printf("\n <tr>\n <td><a href=\"?attachment=");
+printf("%d", attachment->id);
+printf("\">");
+printf("%s", attachment->name );
+printf("</a></td>\n <td>");
+printf("%s", attachment->mime );
+printf("</td>\n <td>");
+printf("%s", attachment->description );
+printf("</td>\n </tr>\n ");
+ }while(attachment = getattachment(stmt, 0));
+
+printf("\n</table>\n");
+}
+
+printf("\n");
#include "foot.tc"