From 439fd48f4a553ad1e8f3681a285a7dc5ea86560b Mon Sep 17 00:00:00 2001 From: Andrew Pamment Date: Fri, 19 Aug 2016 15:23:04 +1000 Subject: [PATCH] replying and sending email vi WWW --- bbs.h | 3 + main.c | 2 +- www.c | 206 ++++++++++++++++++++++++++++++++++++-- www/header.tpl | 6 ++ www/static/style.css | 42 ++++++++ www_email.c | 232 ++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 479 insertions(+), 12 deletions(-) diff --git a/bbs.h b/bbs.h index 1a471bf..adb9eea 100644 --- a/bbs.h +++ b/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 diff --git a/main.c b/main.c index 210f7f5..f80ee29 100644 --- a/main.c +++ b/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 diff --git a/www.c b/www.c index c58af22..48d8fb5 100644 --- a/www.c +++ b/www.c @@ -8,6 +8,11 @@ #include #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;icount;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;icount;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); @@ -403,6 +516,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;icount;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, "

Error Sending Email (Check User Exists?)

"); + } else { + page = (char *)malloc(21); + if (page == NULL) { + free(header); + free(footer); + return MHD_NO; + } + sprintf(page, "

Email Sent!

"); + } + 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); diff --git a/www/header.tpl b/www/header.tpl index ec7efc2..c0ecae2 100644 --- a/www/header.tpl +++ b/www/header.tpl @@ -7,5 +7,11 @@
Magicka BBS
+
diff --git a/www/static/style.css b/www/static/style.css index deab0e8..25ff4ae 100644 --- a/www/static/style.css +++ b/www/static/style.css @@ -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; +} diff --git a/www_email.c b/www_email.c index 782737f..f5dc0aa 100644 --- a/www_email.c +++ b/www_email.c @@ -4,12 +4,163 @@ #include #include #include - +#include #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;iloginname, -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, "

New Email

\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, "
\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, "
\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, "
\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, "\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, "\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, "
\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, "
\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, "

Reply

\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, "
\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, "\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, "
\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, "\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, "\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, "
\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, "
\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, "\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);