From 8bd085270d705e19cbb8eeadb953ca58e39a9d80 Mon Sep 17 00:00:00 2001 From: Andrew Pamment Date: Fri, 2 Dec 2016 17:43:28 +1000 Subject: [PATCH] Redid the email system to be more like the new mail system --- email.c | 465 +++++++++++++++++++++++++++++++++--------------- magicka.strings | 8 +- mail_menu.c | 4 +- 3 files changed, 328 insertions(+), 149 deletions(-) diff --git a/email.c b/email.c index 7241c0f..d217b7c 100644 --- a/email.c +++ b/email.c @@ -8,6 +8,15 @@ extern struct bbs_config conf; +struct email_msg { + int id; + char *from; + char *subject; + int seen; + time_t date; + char *body; +}; + void send_email(struct user_record *user) { char buffer[256]; sqlite3 *db; @@ -100,19 +109,18 @@ void send_email(struct user_record *user) { free(recipient); } -void show_email(struct user_record *user, int msgno) { - char buffer[256]; - sqlite3 *db; - sqlite3_stmt *res; - int rc; - char *sql = "SELECT id,sender,subject,body,date FROM email WHERE recipient LIKE ? LIMIT ?, 1"; - char *dsql = "DELETE FROM email WHERE id=?"; - char *isql = "INSERT INTO email (sender, recipient, subject, body, date, seen) VALUES(?, ?, ?, ?, ?, 0)"; - char *ssql = "UPDATE email SET seen=1 WHERE id=?"; +void show_email(struct user_record *user, int msgno, int email_count, struct email_msg **emails) { + char buffer[256]; + sqlite3 *db; + sqlite3_stmt *res; + int rc; + char *dsql = "DELETE FROM email WHERE id=?"; + char *isql = "INSERT INTO email (sender, recipient, subject, body, date, seen) VALUES(?, ?, ?, ?, ?, 0)"; + char *ssql = "UPDATE email SET seen=1 WHERE id=?"; + int id; char *sender; char *subject; - char *body; time_t date; struct tm msg_date; int z; @@ -120,39 +128,19 @@ void show_email(struct user_record *user, int msgno) { char c; char *replybody; int chars; + int start_line; + int msg_line_count; + char **msg_lines; + int i, j; + int position; + int should_break; + int quit = 0; - sprintf(buffer, "%s/email.sq3", conf.bbs_path); + while (!quit) { - rc = sqlite3_open(buffer, &db); - if (rc != SQLITE_OK) { - dolog("Cannot open database: %s", sqlite3_errmsg(db)); - sqlite3_close(db); - - exit(1); - } - rc = sqlite3_prepare_v2(db, sql, -1, &res, 0); - - if (rc == SQLITE_OK) { - sqlite3_bind_text(res, 1, user->loginname, -1, 0); - sqlite3_bind_int(res, 2, msgno); - } else { - dolog("Failed to execute statement: %s", sqlite3_errmsg(db)); - sqlite3_finalize(res); - sqlite3_close(db); - s_printf("\r\nNo such email\r\n"); - return; - } - if (sqlite3_step(res) == SQLITE_ROW) { - id = sqlite3_column_int(res, 0); - sender = strdup((char *)sqlite3_column_text(res, 1)); - subject = strdup((char *)sqlite3_column_text(res, 2)); - body = strdup((char *)sqlite3_column_text(res, 3)); - date = (time_t)sqlite3_column_int(res, 4); - - - s_printf(get_string(57), sender); - s_printf(get_string(58), subject); - localtime_r(&date, &msg_date); + s_printf(get_string(57), emails[msgno]->from); + s_printf(get_string(58), emails[msgno]->subject); + localtime_r(&emails[msgno]->date, &msg_date); sprintf(buffer, "%s", asctime(&msg_date)); buffer[strlen(buffer) - 1] = '\0'; s_printf(get_string(59), buffer); @@ -160,30 +148,111 @@ void show_email(struct user_record *user, int msgno) { lines = 0; chars = 0; + + + msg_line_count = 0; + start_line = 0; + + // count the number of lines... + for (z=0;zbody);z++) { + if (emails[msgno]->body[z] == '\r' || chars == 79) { + if (msg_line_count == 0) { + msg_lines = (char **)malloc(sizeof(char *)); + } else { + msg_lines = (char **)realloc(msg_lines, sizeof(char *) * (msg_line_count + 1)); + } + + msg_lines[msg_line_count] = (char *)malloc(sizeof(char) * (z - start_line + 1)); + + if (z == start_line) { + msg_lines[msg_line_count][0] = '\0'; + } else { + strncpy(msg_lines[msg_line_count], &emails[msgno]->body[start_line], z - start_line); + msg_lines[msg_line_count][z-start_line] = '\0'; + } + msg_line_count++; + if (emails[msgno]->body[z] == '\r') { + start_line = z + 1; + } else { + start_line = z; + } + chars = 0; + } else { + chars ++; + } + } + + lines = 0; + + position = 0; + should_break = 0; + + while (!should_break) { + s_printf("\e[5;1H\e[0J"); + for (z=position;z= 17) { + break; + } + } + s_printf(get_string(187)); + s_printf(get_string(191)); + c = s_getc(); + + if (tolower(c) == 'r') { + should_break = 1; + } else if (tolower(c) == 'q') { + should_break = 1; + quit = 1; + } else if (tolower(c) == 'd') { + should_break = 1; + } else if (c == '\e') { + c = s_getc(); + if (c == 91) { + c = s_getc(); + if (c == 65) { + position--; + if (position < 0) { + position = 0; + } + } else if (c == 66) { + position++; + if (position + 17 > msg_line_count) { + position--; + } + } else if (c == 67) { + c = ' '; + should_break = 1; + } else if (c == 68) { + c = 'b'; + should_break = 1; + } + } + } + } - for (z=0;zid); } else { dolog("Failed to execute statement: %s", sqlite3_errmsg(db)); sqlite3_finalize(res); @@ -192,27 +261,37 @@ void show_email(struct user_record *user, int msgno) { } sqlite3_step(res); - s_printf(get_string(61)); - c = s_getc(); + sqlite3_finalize(res); + sqlite3_close(db); + + if (tolower(c) == 'r') { - if (subject != NULL) { - if (strncasecmp(buffer, "RE:", 3) != 0) { - snprintf(buffer, 256, "RE: %s", subject); + if (emails[msgno]->subject != NULL) { + if (strncasecmp(emails[msgno]->subject, "RE:", 3) != 0) { + snprintf(buffer, 256, "RE: %s", emails[msgno]->subject); } else { - snprintf(buffer, 256, "%s", subject); + snprintf(buffer, 256, "%s", emails[msgno]->subject); } - free(subject); } subject = (char *)malloc(strlen(buffer) + 1); strcpy(subject, buffer); - replybody = external_editor(user, user->loginname, sender, body, sender, subject, 1); + replybody = external_editor(user, user->loginname, emails[msgno]->from, emails[msgno]->body, emails[msgno]->from, subject, 1); if (replybody != NULL) { + sprintf(buffer, "%s/email.sq3", conf.bbs_path); + + rc = sqlite3_open(buffer, &db); + if (rc != SQLITE_OK) { + dolog("Cannot open database: %s", sqlite3_errmsg(db)); + sqlite3_close(db); + + exit(1); + } 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, sender, -1, 0); + sqlite3_bind_text(res, 2, emails[msgno]->from, -1, 0); sqlite3_bind_text(res, 3, subject, -1, 0); sqlite3_bind_text(res, 4, replybody, -1, 0); sqlite3_bind_int(res, 5, time(NULL)); @@ -220,61 +299,73 @@ void show_email(struct user_record *user, int msgno) { dolog("Failed to execute statement: %s", sqlite3_errmsg(db)); sqlite3_finalize(res); sqlite3_close(db); - s_printf("\r\nNo such email\r\n"); + free(replybody); + free(subject); return; } sqlite3_step(res); sqlite3_finalize(res); + sqlite3_close(db); free(replybody); } - free(sender); free(subject); - free(body); - sqlite3_close(db); } else if (tolower(c) == 'd') { - free(sender); - free(subject); - free(body); + sprintf(buffer, "%s/email.sq3", conf.bbs_path); + rc = sqlite3_open(buffer, &db); + if (rc != SQLITE_OK) { + dolog("Cannot open database: %s", sqlite3_errmsg(db)); + sqlite3_close(db); + + exit(1); + } rc = sqlite3_prepare_v2(db, dsql, -1, &res, 0); if (rc == SQLITE_OK) { - sqlite3_bind_int(res, 1, id); + sqlite3_bind_int(res, 1, emails[msgno]->id); } else { dolog("Failed to execute statement: %s", sqlite3_errmsg(db)); sqlite3_finalize(res); sqlite3_close(db); - s_printf("\r\nNo such email\r\n"); return; } sqlite3_step(res); - + sqlite3_finalize(res); sqlite3_close(db); + quit = 1; + } else if (tolower(c) == ' ') { + msgno ++; + if (msgno == email_count) { + quit = 1; + } + } else if (tolower(c) == 'b') { + msgno--; + if (msgno < 0) { + quit = 1; + } } - - } else { - dolog("Failed"); - sqlite3_finalize(res); - sqlite3_close(db); - } + } } void list_emails(struct user_record *user) { char buffer[256]; sqlite3 *db; - sqlite3_stmt *res; - int rc; - char *sql = "SELECT sender,subject,seen,date FROM email WHERE recipient LIKE ?"; - char *subject; - char *from; - time_t date; - int seen; - int msgid; + sqlite3_stmt *res; + int rc; + char *sql = "SELECT sender,subject,seen,date,body,id FROM email WHERE recipient LIKE ?"; + struct email_msg **emails; + int email_count; + int msgid; int msgtoread; struct tm msg_date; - + int redraw; + int start; + int position; + int i; + char c; + int closed = 0; sprintf(buffer, "%s/email.sq3", conf.bbs_path); rc = sqlite3_open(buffer, &db); @@ -282,71 +373,155 @@ void list_emails(struct user_record *user) { dolog("Cannot open database: %s", sqlite3_errmsg(db)); sqlite3_close(db); - exit(1); - } - rc = sqlite3_prepare_v2(db, sql, -1, &res, 0); + exit(1); + } + rc = sqlite3_prepare_v2(db, sql, -1, &res, 0); - if (rc == SQLITE_OK) { - sqlite3_bind_text(res, 1, user->loginname, -1, 0); - } else { - dolog("Failed to execute statement: %s", sqlite3_errmsg(db)); + if (rc == SQLITE_OK) { + sqlite3_bind_text(res, 1, user->loginname, -1, 0); + } else { + dolog("Failed to execute statement: %s", sqlite3_errmsg(db)); sqlite3_finalize(res); sqlite3_close(db); s_printf(get_string(62)); return; - } + } msgid = 0; s_printf(get_string(63)); - while (sqlite3_step(res) == SQLITE_ROW) { - from = strdup((char *)sqlite3_column_text(res, 0)); - subject = strdup((char *)sqlite3_column_text(res, 1)); - seen = sqlite3_column_int(res, 2); - date = (time_t)sqlite3_column_int(res, 3); - localtime_r(&date, &msg_date); - if (seen == 0) { - s_printf(get_string(64), msgid + 1, subject, from, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); + email_count = 0; + while (sqlite3_step(res) == SQLITE_ROW) { + if (email_count == 0) { + emails = (struct email_msg **)malloc(sizeof(struct email_msg *)); } else { - s_printf(get_string(65), msgid + 1, subject, from, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); - } - free(from); - free(subject); - - if (msgid % 22 == 0 && msgid != 0) { - s_printf(get_string(66)); - s_readstring(buffer, 5); - if (strlen(buffer) > 0) { - if (tolower(buffer[0]) == 'q') { - sqlite3_finalize(res); - sqlite3_close(db); - return; - } else { - msgtoread = atoi(buffer) - 1; - sqlite3_finalize(res); - sqlite3_close(db); - show_email(user, msgtoread); - return; - } - } - s_printf(get_string(63)); - } - msgid++; - } - if (msgid == 0) { - s_printf(get_string(62)); - } else { - s_printf(get_string(67)); - s_readstring(buffer, 5); - if (strlen(buffer) > 0) { - msgtoread = atoi(buffer) - 1; - sqlite3_finalize(res); - sqlite3_close(db); - show_email(user, msgtoread); - return; + emails = (struct email_msg **)realloc(emails, sizeof(struct email_msg *) * (email_count + 1)); } + + emails[email_count] = (struct email_msg *)malloc(sizeof(struct email_msg)); + + emails[email_count]->from = strdup((char *)sqlite3_column_text(res, 0)); + emails[email_count]->subject = strdup((char *)sqlite3_column_text(res, 1)); + emails[email_count]->seen = sqlite3_column_int(res, 2); + emails[email_count]->date = (time_t)sqlite3_column_int(res, 3); + emails[email_count]->body = strdup((char *)sqlite3_column_text(res, 4)); + emails[email_count]->id = sqlite3_column_int(res, 5); + email_count++; } + sqlite3_finalize(res); sqlite3_close(db); + + if (email_count == 0) { + s_printf(get_string(194)); + return; + } + + redraw = 1; + start = 0; + position = 0; + while (!closed) { + if (redraw) { + s_printf(get_string(126)); + for (i=start;idate, &msg_date); + if (i == position) { + if (!emails[i]->seen) { + s_printf(get_string(192), i + 1, emails[i]->subject, emails[i]->from,msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); + } else { + s_printf(get_string(193), i + 1, emails[i]->subject, emails[i]->from,msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); + } + } else { + if (!emails[i]->seen) { + s_printf(get_string(64), i + 1, emails[i]->subject, emails[i]->from,msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); + } else { + s_printf(get_string(65), i + 1, emails[i]->subject, emails[i]->from,msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); + } + } + } + s_printf(get_string(190)); + redraw = 0; + } + c = s_getc(); + if (tolower(c) == 'q') { + closed = 1; + } else if (c == 27) { + c = s_getc(); + if (c == 91) { + c = s_getc(); + if (c == 66) { + // down + position++; + if (position >= start + 22) { + start += 22; + if (start >= email_count) { + start = email_count - 22; + } + redraw = 1; + } + if (position == email_count) { + position--; + } else if (!redraw) { + s_printf("\e[%d;1H", position - start + 1); + localtime_r((time_t *)&emails[position-1]->date, &msg_date); + if (!emails[position - 1]->seen) { + s_printf(get_string(64), position, emails[position-1]->subject, emails[position-1]->from, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); + } else { + s_printf(get_string(65), position, emails[position-1]->subject, emails[position-1]->from, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); + } + s_printf("\e[%d;1H", position - start + 2); + localtime_r((time_t *)&emails[position]->date, &msg_date); + if (!emails[position]->seen) { + s_printf(get_string(192), position + 1, emails[position]->subject, emails[position]->from, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); + } else { + s_printf(get_string(193), position + 1, emails[position]->subject, emails[position]->from, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); + } + } + } else if (c == 65) { + // up + position--; + if (position < start) { + start -=22; + if (start < 0) { + start = 0; + } + redraw = 1; + } + if (position <= 0) { + start = 0; + position = 0; + redraw = 1; + } else if (!redraw) { + s_printf("\e[%d;1H", position - start + 3); + localtime_r((time_t *)&emails[position + 1]->date, &msg_date); + if (!emails[position + 1]->seen) { + s_printf(get_string(64), position + 2, emails[position + 1]->subject, emails[position + 1]->from, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); + } else { + s_printf(get_string(65), position + 2, emails[position + 1]->subject, emails[position + 1]->from, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); + } + s_printf("\e[%d;1H", position - start + 2); + localtime_r((time_t *)&emails[position]->date, &msg_date); + if (!emails[position]->seen) { + s_printf(get_string(192), position + 1, emails[position]->subject, emails[position]->from, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); + } else { + s_printf(get_string(193), position + 1, emails[position]->subject, emails[position]->from, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); + } + + } + } + } + } else if (c == 13) { + closed = 1; + show_email(user, position, email_count, emails); + } + } + + for (i=0;ifrom); + free(emails[i]->subject); + free(emails[i]->body); + free(emails[i]); + } + free(emails); } diff --git a/magicka.strings b/magicka.strings index 64c0e37..56f179e 100644 --- a/magicka.strings +++ b/magicka.strings @@ -62,8 +62,8 @@ Non-STDIO door support on SSH is currently broken...\r\n \e[1;37mPress \e[1;36mR\e[1;37m to reply, \e[1;36mD\e[1;37m to delete \e[1;36mEnter\e[1;37m to quit...\e[0m\r\n \r\nYou have no email\r\n \e[2J\e[1;37;44m[MSG#] Subject From Date \r\n\e[0m -\e[1;30m[\e[1;34m%4d\e[1;30m]\e[1;32m*\e[1;37m%-39.39s \e[1;32m%-16.16s \e[1;35m%02d:%02d %02d-%02d-%02d\e[0m\r\n -\e[1;30m[\e[1;34m%4d\e[1;30m] \e[1;37m%-39.39s \e[1;32m%-16.16s \e[1;35m%02d:%02d %02d-%02d-%02d\e[0m\r\n +\e[1;30m[\e[1;34m%4d\e[1;30m]\e[1;32m*\e[1;37m%-39.39s \e[1;32m%-16.16s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n +\e[1;30m[\e[1;34m%4d\e[1;30m] \e[1;37m%-39.39s \e[1;32m%-16.16s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n \e[1;37mEnter \e[1;36m# \e[1;37mto read, \e[1;36mQ \e[1;37mto quit or \e[1;36mEnter\e[1;37m to continue\e[0m\r\n \e[1;37mEnter \e[1;36m# \e[1;37mto read, or \e[1;36mEnter\e[1;37m to quit\e[0m\r\n \r\nNo files in this area!\r\n @@ -189,3 +189,7 @@ Is this Correct? (Y/N) \e[1;30m[\e[1;34;44m%4d\e[1;30;40m]\e[1;32m*\e[1;37m%-25.25s \e[1;32m%-15.15s \e[1;33m%-15.15s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n \e[1;30m[\e[1;34;44m%4d\e[1;30;40m] \e[1;37m%-25.25s \e[1;32m%-15.15s \e[1;33m%-15.15s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n \e[24;1H\e[1;37;44mUp/Down to Scroll, Enter to read, Q to quit\e[K\e[0m +\e[24;1H\e[1;32mUp / Down \e[1;37mto Scroll, \e[1;32mLeft / Right \e[1;37mto Change Message, \e[1;32mR \e[1;37mreply, \e[1;32mD \e[1;37mDelete, \e[1;32mQ \e[1;37mquit\e[K\e[0m +\e[1;30m[\e[1;34;44m%4d\e[1;30;40m]\e[1;32m*\e[1;37m%-39.39s \e[1;32m%-16.16s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n +\e[1;30m[\e[1;34;44m%4d\e[1;30;40m] \e[1;37m%-39.39s \e[1;32m%-16.16s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n +\e[1;31mYou have no email!\e[0m diff --git a/mail_menu.c b/mail_menu.c index 16bd72e..2793766 100644 --- a/mail_menu.c +++ b/mail_menu.c @@ -919,9 +919,9 @@ void read_message(struct user_record *user, struct msg_headers *msghs, int mailn s_printf(get_string(186)); c = s_getc(); - if (c == 'r') { + if (tolower(c) == 'r') { should_break = 1; - } else if (c == 'q') { + } else if (tolower(c) == 'q') { should_break = 1; } else if (c == '\e') { c = s_getc();