First fully featured prototype
This commit is contained in:
parent
2b1da096a6
commit
fc3d99fa82
97
src/main.c
97
src/main.c
@ -7,14 +7,22 @@
|
|||||||
#include "drivers/unix_fs/unix_fs_driver.h"
|
#include "drivers/unix_fs/unix_fs_driver.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#define COMMENTS_PER_PAGE 20
|
#define COMMENTS_PER_PAGE 20
|
||||||
#define MAX_NAME 1024
|
#define MAX_NAME 1024
|
||||||
|
#define MAX_COMMENT_SIZE 4096
|
||||||
|
|
||||||
#define QMENTS_PATH "qments-storage"
|
#define QMENTS_PATH "qments-storage"
|
||||||
#define DRIVER_DATA { QMENTS_PATH }
|
#define DRIVER_DATA { QMENTS_PATH }
|
||||||
#define DRIVER unix_fs_driver
|
#define DRIVER unix_fs_driver
|
||||||
|
|
||||||
|
int
|
||||||
|
page_by_id(int id)
|
||||||
|
{
|
||||||
|
return id / COMMENTS_PER_PAGE + 1;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fct_callback(char character, void *arg)
|
fct_callback(char character, void *arg)
|
||||||
{
|
{
|
||||||
@ -26,15 +34,22 @@ render_comment(const Comment *comment)
|
|||||||
{
|
{
|
||||||
StringBuffer _buffer, *buffer;
|
StringBuffer _buffer, *buffer;
|
||||||
char *retval;
|
char *retval;
|
||||||
|
int rid;
|
||||||
|
|
||||||
buffer = &_buffer;
|
buffer = &_buffer;
|
||||||
sb_init_empty(buffer);
|
sb_init_empty(buffer);
|
||||||
|
|
||||||
fctprintf(fct_callback, buffer, "<div class=\"comment\" id=comment_%d>\n", comment->id);
|
fctprintf(fct_callback, buffer, "<div class=\"comment\" id=\"comment_%d\">\n", comment->id);
|
||||||
|
|
||||||
/* begin header */
|
/* begin header */
|
||||||
fctprintf(fct_callback, buffer, "<div class=\"comment-header\">\n");
|
fctprintf(fct_callback, buffer, "<div class=\"comment-header\">\n");
|
||||||
fctprintf(fct_callback, buffer, "Posted by: %s\n", comment->header->user_displayname);
|
fctprintf(fct_callback, buffer, "Posted by: %s\n", comment->header->user_displayname);
|
||||||
|
|
||||||
|
rid = comment->header->reply_id;
|
||||||
|
if (rid > 0) {
|
||||||
|
fctprintf(fct_callback, buffer, "<a href=\"?page=%d#comment_%d\"> in reply to </a>", page_by_id(rid), rid);
|
||||||
|
}
|
||||||
|
|
||||||
fctprintf(fct_callback, buffer, "</div>\n");
|
fctprintf(fct_callback, buffer, "</div>\n");
|
||||||
/* end header */
|
/* end header */
|
||||||
|
|
||||||
@ -98,9 +113,22 @@ defer:
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
print_submit_form()
|
||||||
|
{
|
||||||
|
fputs("<form action=\"\">\n"
|
||||||
|
"<label>Your name:</label>\n"
|
||||||
|
"<input type=\"text\" name=\"displayname\"><br>\n"
|
||||||
|
"<label>Leave comment: </label><br>\n"
|
||||||
|
"<input type=\"text\" name=\"text\"><br>\n"
|
||||||
|
"<input type=\"submit\" name=\"submit\" value=\"Submit\">\n"
|
||||||
|
"</form>\n", cgiOut);
|
||||||
|
}
|
||||||
|
|
||||||
/* each page stores comments with ids in [P * (page - 1), P * page)
|
/* each page stores comments with ids in [P * (page - 1), P * page)
|
||||||
* if page is not specified, then we'll just print last P comments (for now)
|
* if page is not specified, then we'll just print last P comments (for now)
|
||||||
* TODO: print errors in div
|
* TODO: print errors in div
|
||||||
|
* FIXME: NOW PAGING IS FAULTY, FIX IT
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
print_page()
|
print_page()
|
||||||
@ -147,6 +175,65 @@ print_page()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: restore fields for user no to lose data */
|
||||||
|
int
|
||||||
|
handle_submitted_comment()
|
||||||
|
{
|
||||||
|
char displayname[MAX_NAME], text[MAX_COMMENT_SIZE], *sanitized_text;
|
||||||
|
int rid, retval;
|
||||||
|
cgiFormResultType err;
|
||||||
|
Driver driver = DRIVER;
|
||||||
|
UnixFsDriverData driver_data = DRIVER_DATA;
|
||||||
|
|
||||||
|
err = cgiFormString("text", text, MAX_COMMENT_SIZE);
|
||||||
|
if (err == cgiFormTruncated) {
|
||||||
|
fprintf(cgiOut, "Comment too long (max %d bytes)\n", MAX_COMMENT_SIZE);
|
||||||
|
goto defer;
|
||||||
|
}
|
||||||
|
if (err == cgiFormNotFound) {
|
||||||
|
fprintf(cgiOut, "Comment text not provided\n");
|
||||||
|
goto defer;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = cgiFormString("displayname", displayname, MAX_NAME);
|
||||||
|
if (err == cgiFormTruncated) {
|
||||||
|
fprintf(cgiOut, "Name too long (max %d bytes)\n", MAX_NAME);
|
||||||
|
goto defer;
|
||||||
|
}
|
||||||
|
if (err == cgiFormNotFound) {
|
||||||
|
fprintf(cgiOut, "Name not provided\n");
|
||||||
|
goto defer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contain_special(displayname)) {
|
||||||
|
err = cgiFormTruncated;
|
||||||
|
fprintf(cgiOut, "Name must not contain HTML special characters\n");
|
||||||
|
goto defer;
|
||||||
|
}
|
||||||
|
|
||||||
|
cgiFormInteger("reply-to", &rid, 0);
|
||||||
|
|
||||||
|
sanitized_text = mk_specialchars(text);
|
||||||
|
|
||||||
|
CommentHeader header;
|
||||||
|
time(&header.creation_time);
|
||||||
|
header.reply_id = rid;
|
||||||
|
header.text_length = strlen(sanitized_text);
|
||||||
|
header.user_sid = "anonymous";
|
||||||
|
header.user_displayname = displayname;
|
||||||
|
|
||||||
|
if (driver.leave_comment(&driver_data, &header, sanitized_text) < 0) {
|
||||||
|
fprintf(cgiOut, "Failed to leave your comment\n");
|
||||||
|
} else {
|
||||||
|
fprintf(cgiOut, "Comment successfully left\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
free(sanitized_text);
|
||||||
|
|
||||||
|
defer:
|
||||||
|
return (err == cgiFormSuccess ? 0 : -1);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
cgiMain()
|
cgiMain()
|
||||||
{
|
{
|
||||||
@ -155,12 +242,16 @@ cgiMain()
|
|||||||
fprintf(cgiOut, "<html>\n");
|
fprintf(cgiOut, "<html>\n");
|
||||||
|
|
||||||
fprintf(cgiOut, "<head>\n");
|
fprintf(cgiOut, "<head>\n");
|
||||||
fprintf(cgiOut, "<title> Simple discuss powered by qments\n");
|
fprintf(cgiOut, "<title> Simple discuss powered by qments </title>\n");
|
||||||
fprintf(cgiOut, "</head>\n");
|
fprintf(cgiOut, "</head>\n");
|
||||||
|
|
||||||
fprintf(cgiOut, "<body>\n");
|
fprintf(cgiOut, "<body>\n");
|
||||||
|
|
||||||
|
if (cgiFormSubmitClicked("submit") == cgiFormSuccess) {
|
||||||
|
handle_submitted_comment();
|
||||||
|
}
|
||||||
|
|
||||||
/* print_submit_form(); */
|
print_submit_form();
|
||||||
|
|
||||||
fprintf(cgiOut, "<div class=\"comment-section\">\n");
|
fprintf(cgiOut, "<div class=\"comment-section\">\n");
|
||||||
print_page();
|
print_page();
|
||||||
|
@ -1,7 +1,15 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "string_buffer.h"
|
#include "string_buffer.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
contain_special(const char *s)
|
||||||
|
{
|
||||||
|
return strchr(s, '&') || strchr(s, '"') || strchr(s, '\'') || strchr(s, '<') || strchr(s, '>');
|
||||||
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
mk_specialchars(const char *input)
|
mk_specialchars(const char *input)
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#ifndef UTILS_H
|
#ifndef UTILS_H
|
||||||
#define UTILS_H
|
#define UTILS_H
|
||||||
|
|
||||||
|
int contain_special(const char *s);
|
||||||
|
|
||||||
char *mk_specialchars(const char *input);
|
char *mk_specialchars(const char *input);
|
||||||
|
|
||||||
#endif /* UTILS_H */
|
#endif /* UTILS_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user