From 24bf14f6653ebf1c1ba79b9f212d35417bb6acbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Ankarstr=C3=B6m?= Date: Sat, 18 Sep 2021 01:52:04 +0200 Subject: Implement attachments --- Makefile | 4 +++- cforum.c | 16 +++++++++++----- ctl.c | 17 +++++++++++++++++ ctl.h | 1 + db.c | 34 ++++++++++++++++++++++++++++++++++ db.h | 11 +++++++++++ t/front.t | 11 ++++------- t/front.tc | 24 ++++++++++-------------- t/post.t | 22 ++++++++++++++++++++++ t/post.tc | 22 ++++++++++++++++++++++ 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 @@ -18,6 +18,20 @@ printdate(int timestamp) printf(buf); } +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() { @@ -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" %>

<%= site.name %>

-

Thanks for the <%= getenv("REQUEST_METHOD") %> request!

+

Latest posts

<% struct post *post; @@ -10,12 +10,9 @@ user = getuser(byid("users", post->user), 1); %> - - + + + <% } 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

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

\n

Thanks for the "); -printf("%s", getenv("REQUEST_METHOD") ); -printf(" request!

\n
user); %>"><%= - user->name - %>id); %>"><%= - post->subject - %>id); %>"><%= post->subject %>user); %>"><%= user->name %><% printdate(post->created); %>
\n "); +printf("\n

Latest posts

\n
\n "); struct post *post; struct user *user; while(post = getpost(stmt, 0)){ user = getuser(byid("users", post->user), 1); -printf("\n \n \n \n \n "); +printf("%s", post->subject ); +printf("\n \n \n \n "); } printf("\n
user); -printf("\">"); -printf("%s", - user->name - ); -printf("\n id); printf("\">"); -printf("%s", - post->subject - ); -printf("
user); +printf("\">"); +printf("%s", user->name ); +printf(""); +printdate(post->created); +printf("
\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 @@
 <%= post->text %>
 
+<% +struct attachment *attachment; + +if(attachment = getattachment(stmt, 0)){ +%> +

Attachments

+ + <% + do{ + %> + + + + + + <% + }while(attachment = getattachment(stmt, 0)); + %> +
id); %>"><%= attachment->name %><%= attachment->mime %><%= attachment->description %>
+<% +} +%> <% #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("\n"); printf("\n
\n");
 printf("%s",  post->text );
 printf("\n
\n"); +struct attachment *attachment; + +if(attachment = getattachment(stmt, 0)){ + +printf("\n

Attachments

\n\n "); + do{ + +printf("\n \n \n \n \n \n "); + }while(attachment = getattachment(stmt, 0)); + +printf("\n
id); +printf("\">"); +printf("%s", attachment->name ); +printf(""); +printf("%s", attachment->mime ); +printf(""); +printf("%s", attachment->description ); +printf("
\n"); +} + +printf("\n"); #include "foot.tc" -- cgit v1.2.3