replying and sending email vi WWW

This commit is contained in:
Andrew Pamment 2016-08-19 15:23:04 +10:00
parent 5d47ca787f
commit 439fd48f4a
6 changed files with 479 additions and 12 deletions

3
bbs.h
View File

@ -204,9 +204,12 @@ extern void chomp(char *string);
#if defined(ENABLE_WWW)
extern void www_init();
extern void www_request_completed(void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe);
extern int www_handler(void * cls, struct MHD_Connection * connection, const char * url, const char * method, const char * version, const char * upload_data, size_t * upload_data_size, void ** ptr);
extern char *www_email_summary(struct user_record *user);
extern char *www_email_display(struct user_record *user, int email);
extern int www_send_email(struct user_record *user, char *recipient, char *subject, char *body);
extern char *www_new_email();
#endif
#endif

2
main.c
View File

@ -697,7 +697,7 @@ void server(int port) {
#if defined(ENABLE_WWW)
if (conf.www_server && conf.www_path != NULL) {
www_init();
www_daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, conf.www_port, NULL, NULL, &www_handler, NULL, MHD_OPTION_END);
www_daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, conf.www_port, NULL, NULL, &www_handler, NULL, MHD_OPTION_NOTIFY_COMPLETED, &www_request_completed, NULL, MHD_OPTION_END);
}
#endif

206
www.c
View File

@ -8,6 +8,11 @@
#include <b64/cdecode.h>
#include "bbs.h"
#define GET 1
#define POST 2
#define POSTBUFFERSIZE 8192
extern struct bbs_config conf;
struct mime_type {
@ -18,6 +23,91 @@ struct mime_type {
static struct mime_type **mime_types;
static int mime_types_count;
struct connection_info_s {
int connection_type;
struct user_record *user;
char *url;
char **keys;
char **values;
int count;
struct MHD_PostProcessor *pp;
};
void www_request_completed(void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe) {
struct connection_info_s *con_info = *con_cls;
int i;
if (con_info == NULL) {
return;
}
if (con_info->connection_type == POST) {
if (con_info->count > 0) {
for (i=0;i<con_info->count;i++) {
free(con_info->values[i]);
free(con_info->keys[i]);
}
free(con_info->values);
free(con_info->keys);
}
if (con_info->user != NULL) {
free(con_info->user->loginname);
free(con_info->user->password);
free(con_info->user->firstname);
free(con_info->user->lastname);
free(con_info->user->email);
free(con_info->user->location);
free(con_info->user->sec_info);
free(con_info->user);
}
MHD_destroy_post_processor(con_info->pp);
}
free(con_info->url);
free(con_info);
}
static int iterate_post (void *coninfo_cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size) {
struct connection_info_s *con_info = coninfo_cls;
int i;
if (con_info != NULL) {
if (con_info->connection_type == POST) {
for (i=0;i<con_info->count;i++) {
if (strcmp(con_info->keys[i], key) == 0) {
con_info->values[i] = (char *)realloc(con_info->values[i], strlen(con_info->values[i] + size + 1));
strcat(con_info->values[i], data);
return MHD_YES;
}
}
if (con_info->count == 0) {
con_info->keys = (char **)malloc(sizeof(char *));
con_info->values = (char **)malloc(sizeof(char *));
} else {
con_info->keys = (char **)realloc(con_info->keys, sizeof(char *) * (con_info->count + 1));
con_info->values = (char **)realloc(con_info->values, sizeof(char *) * (con_info->count + 1));
}
con_info->keys[con_info->count] = strdup(key);
con_info->values[con_info->count] = strdup(data);;
con_info->count++;
if (strcmp(con_info->url, "/email/") == 0 || strcmp(con_info->url, "/email") == 0) {
if (con_info->count == 3) {
return MHD_NO;
}
}
return MHD_YES;
} else {
return MHD_NO;
}
}
return MHD_NO;
}
void www_init() {
FILE *fptr;
char buffer[4096];
@ -278,16 +368,39 @@ int www_handler(void * cls, struct MHD_Connection * connection, const char * url
int fno;
const char *url_ = url;
struct user_record *user;
char *subj, *to, *body;
struct connection_info_s *con_inf;
static int apointer;
if (&apointer != *ptr) {
*ptr = &apointer;
return MHD_YES;
if (strcmp(method, "GET") == 0) {
if (*ptr == NULL) {
con_inf = (struct connection_info_s *)malloc(sizeof(struct connection_info_s));
if (!con_inf) {
return MHD_NO;
}
con_inf->connection_type = GET;
con_inf->user = NULL;
con_inf->count = 0;
con_inf->url = strdup(url);
*ptr = con_inf;
return MHD_YES;
}
} else if (strcmp(method, "POST") == 0) {
if (*ptr == NULL) {
con_inf = (struct connection_info_s *)malloc(sizeof(struct connection_info_s));
if (!con_inf) {
return MHD_NO;
}
con_inf->connection_type = POST;
con_inf->user = NULL;
con_inf->count = 0;
con_inf->url = strdup(url);
*ptr = con_inf;
return MHD_YES;
}
}
*ptr = NULL;
con_inf = *ptr;
snprintf(buffer, 4096, "%s/header.tpl", conf.www_path);
@ -402,6 +515,24 @@ int www_handler(void * cls, struct MHD_Connection * connection, const char * url
}
whole_page = (char *)malloc(strlen(header) + strlen(page) + strlen(footer) + 1);
sprintf(whole_page, "%s%s%s", header, page, footer);
} else if(strcasecmp(url, "/email/new") == 0) {
user = www_auth_ok(connection, url_);
if (user == NULL) {
www_401(header, footer, connection);
free(header);
free(footer);
return MHD_YES;
}
page = www_new_email();
if (page == NULL) {
free(header);
free(footer);
return MHD_NO;
}
whole_page = (char *)malloc(strlen(header) + strlen(page) + strlen(footer) + 1);
sprintf(whole_page, "%s%s%s", header, page, footer);
} else if (strncasecmp(url, "/email/", 7) == 0) {
user = www_auth_ok(connection, url_);
@ -478,9 +609,64 @@ int www_handler(void * cls, struct MHD_Connection * connection, const char * url
return MHD_YES;
}
} else if (strcmp(method, "POST") == 0) {
free(header);
free(footer);
return MHD_NO;
if (strcasecmp(url, "/email/") == 0 || strcasecmp(url, "/email") == 0) {
con_inf->user = www_auth_ok(connection, url_);
user = www_auth_ok(connection, url_);
if (user == NULL) {
www_401(header, footer, connection);
free(header);
free(footer);
return MHD_YES;
}
con_inf->pp = MHD_create_post_processor(connection, POSTBUFFERSIZE, iterate_post, (void*) con_inf);
if (*upload_data_size != 0) {
MHD_post_process (con_inf->pp, upload_data, *upload_data_size);
*upload_data_size = 0;
return MHD_YES;
}
subj = NULL;
to = NULL;
body = NULL;
for (i=0;i<con_inf->count;i++) {
if (strcmp(con_inf->keys[i], "recipient") == 0) {
to = con_inf->values[i];
} else if (strcmp(con_inf->keys[i], "subject") == 0) {
subj = con_inf->values[i];
} else if (strcmp(con_inf->keys[i], "body") == 0) {
body = con_inf->values[i];
}
}
if (!www_send_email(con_inf->user, to, subj, body)) {
page = (char *)malloc(50);
if (page == NULL) {
free(header);
free(footer);
return MHD_NO;
}
sprintf(page, "<h1>Error Sending Email (Check User Exists?)</h1>");
} else {
page = (char *)malloc(21);
if (page == NULL) {
free(header);
free(footer);
return MHD_NO;
}
sprintf(page, "<h1>Email Sent!</h1>");
}
whole_page = (char *)malloc(strlen(header) + strlen(page) + strlen(footer) + 1);
sprintf(whole_page, "%s%s%s", header, page, footer);
} else {
free(header);
free(footer);
return MHD_NO;
}
}
response = MHD_create_response_from_buffer (strlen (whole_page), (void*) whole_page, MHD_RESPMEM_PERSISTENT);

View File

@ -7,5 +7,11 @@
<div class="header">
<img src="/static/header.png" alt="Magicka BBS" />
</div>
<div class="menu">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/email/">Email</a></li>
</ul>
</div>
<hr />

View File

@ -66,3 +66,45 @@
.email-view-date {
color: #222;
}
.menu ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333333;
}
.menu li {
float: left;
}
.menu li a {
display: block;
color: white;
text-align: center;
padding: 16px;
text-decoration: none;
}
.menu li a:hover {
background-color: #111111;
}
.email-reply-form {
margin-left: 20px;
}
.button {
padding-bottom:10px;
}
.button a {
width: auto;
padding: 5px;
color: white;
background-color: #333;
text-decoration: none;
}
.button a:hover {
background-color: #111111;
}

View File

@ -4,12 +4,163 @@
#include <sqlite3.h>
#include <time.h>
#include <stdlib.h>
#include <sys/utsname.h>
#include "bbs.h"
extern struct bbs_config conf;
int www_send_email(struct user_record *user, char *recipient, char *subject, char *ibody) {
char buffer[256];
sqlite3 *db;
sqlite3_stmt *res;
int rc;
char *csql = "CREATE TABLE IF NOT EXISTS email ("
"id INTEGER PRIMARY KEY,"
"sender TEXT COLLATE NOCASE,"
"recipient TEXT COLLATE NOCASE,"
"subject TEXT,"
"body TEXT,"
"date INTEGER,"
"seen INTEGER);";
char *isql = "INSERT INTO email (sender, recipient, subject, body, date, seen) VALUES(?, ?, ?, ?, ?, 0)";
char *err_msg = 0;
char *body;
struct utsname name;
int i;
int pos;
if (check_user(recipient)) {
return 0;
}
uname(&name);
snprintf(buffer, 256, "\r--- MagickaBBS v%d.%d%s (%s/%s)\r * Origin: %s \r", VERSION_MAJOR, VERSION_MINOR, VERSION_STR, name.sysname, name.machine, conf.default_tagline);
body = (char *)malloc(strlen(ibody) + strlen(buffer) + 1);
memset(body, 0, strlen(ibody) + strlen(buffer) + 1);
pos = 0;
for (i = 0;i<strlen(ibody);i++) {
if (ibody[i] != '\n') {
body[pos] = ibody[i];
pos++;
}
}
strcat(body, buffer);
sprintf(buffer, "%s/email.sq3", conf.bbs_path);
rc = sqlite3_open(buffer, &db);
if (rc != SQLITE_OK) {
sqlite3_close(db);
return 0;
}
rc = sqlite3_exec(db, csql, 0, 0, &err_msg);
if (rc != SQLITE_OK ) {
sqlite3_free(err_msg);
sqlite3_close(db);
return 0;
}
rc = sqlite3_prepare_v2(db, isql, -1, &res, 0);
if (rc == SQLITE_OK) {
sqlite3_bind_text(res, 1, user->loginname, -1, 0);
sqlite3_bind_text(res, 2, recipient, -1, 0);
sqlite3_bind_text(res, 3, subject, -1, 0);
sqlite3_bind_text(res, 4, body, -1, 0);
sqlite3_bind_int(res, 5, time(NULL));
} else {
sqlite3_finalize(res);
sqlite3_close(db);
return 0;
}
sqlite3_step(res);
sqlite3_finalize(res);
sqlite3_close(db);
return 1;
}
char *www_new_email() {
char *page;
int max_len;
int len;
char buffer[4096];
page = (char *)malloc(4096);
max_len = 4096;
len = 0;
memset(page, 0, 4096);
sprintf(buffer, "<div class=\"content-header\"><h2>New Email</h2></div>\n");
if (len + strlen(buffer) > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
}
strcat(page, buffer);
len += strlen(buffer);
sprintf(buffer, "<form action=\"/email/\" method=\"POST\">\n");
if (len + strlen(buffer) > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
}
strcat(page, buffer);
len += strlen(buffer);
sprintf(buffer, "<input type=\"text\" name=\"recipient\" /><br />\n");
if (len + strlen(buffer) > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
}
strcat(page, buffer);
len += strlen(buffer);
sprintf(buffer, "<input type=\"text\" name=\"subject\" /><br />\n");
if (len + strlen(buffer) > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
}
strcat(page, buffer);
len += strlen(buffer);
sprintf(buffer, "<textarea name=\"body\" rows=25 cols=80></textarea>\n<br />");
if (len + strlen(buffer) > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
}
strcat(page, buffer);
len += strlen(buffer);
sprintf(buffer, "<input type=\"submit\" name=\"submit\" value=\"Send\" />\n<br />");
if (len + strlen(buffer) > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
}
strcat(page, buffer);
len += strlen(buffer);
sprintf(buffer, "</form>\n");
if (len + strlen(buffer) > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
}
strcat(page, buffer);
len += strlen(buffer);
return page;
}
char *www_email_display(struct user_record *user, int email) {
char *page;
int max_len;
@ -141,7 +292,77 @@ char *www_email_display(struct user_record *user, int email) {
len += strlen(buffer);
}
sprintf(buffer, "<div class=\"email-reply-form\">\n");
if (len + strlen(buffer) > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
}
strcat(page, buffer);
len += strlen(buffer);
sprintf(buffer, "<h3>Reply</h3>\n");
if (len + strlen(buffer) > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
}
strcat(page, buffer);
len += strlen(buffer);
sprintf(buffer, "<form action=\"/email/\" method=\"POST\">\n");
if (len + strlen(buffer) > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
}
strcat(page, buffer);
len += strlen(buffer);
sprintf(buffer, "<input type=\"hidden\" name=\"recipient\" value=\"%s\" />\n", from);
if (len + strlen(buffer) > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
}
strcat(page, buffer);
len += strlen(buffer);
sprintf(buffer, "<input type=\"text\" name=\"subject\" value=\"RE: %s\" /><br />\n", subject);
if (len + strlen(buffer) > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
}
strcat(page, buffer);
len += strlen(buffer);
sprintf(buffer, "<textarea name=\"body\" rows=25 cols=80></textarea>\n<br />");
if (len + strlen(buffer) > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
}
strcat(page, buffer);
len += strlen(buffer);
sprintf(buffer, "<input type=\"submit\" name=\"submit\" value=\"Reply\" />\n<br />");
if (len + strlen(buffer) > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
}
strcat(page, buffer);
len += strlen(buffer);
sprintf(buffer, "</form>\n");
if (len + strlen(buffer) > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
}
strcat(page, buffer);
len += strlen(buffer);
sprintf(buffer, "</div>\n");
if (len + strlen(buffer) > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
}
strcat(page, buffer);
len += strlen(buffer);
free(from);
free(body);
@ -215,6 +436,15 @@ char *www_email_summary(struct user_record *user) {
}
strcat(page, buffer);
len += strlen(buffer);
sprintf(buffer, "<div class=\"button\"><a href=\"/email/new\">New Email</a></div>\n");
if (len + strlen(buffer) > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
}
strcat(page, buffer);
len += strlen(buffer);
sprintf(buffer, "%s/email.sq3", conf.bbs_path);
rc = sqlite3_open(buffer, &db);