replying and sending email vi WWW
This commit is contained in:
parent
5d47ca787f
commit
439fd48f4a
3
bbs.h
3
bbs.h
@ -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
2
main.c
@ -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
206
www.c
@ -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);
|
||||
|
||||
|
@ -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 />
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
232
www_email.c
232
www_email.c
@ -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);
|
||||
|
Reference in New Issue
Block a user