EXPERIMENTAL: Bluewave Email Support
This commit is contained in:
parent
76de1e7f4b
commit
1f699ad89f
203
src/bluewave.c
203
src/bluewave.c
@ -4,6 +4,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <sqlite3.h>
|
||||||
#include "bluewave.h"
|
#include "bluewave.h"
|
||||||
#include "jamlib/jam.h"
|
#include "jamlib/jam.h"
|
||||||
#include "bbs.h"
|
#include "bbs.h"
|
||||||
@ -45,6 +46,84 @@ tWORD converts(tWORD s) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int bwave_scan_email(int areano, int totmsgs, FILE *fti_file, FILE *mix_file, FILE *dat_file, int *last_ptr) {
|
||||||
|
sqlite3 *db;
|
||||||
|
sqlite3_stmt *res;
|
||||||
|
int rc;
|
||||||
|
char *sql = "SELECT sender,subject,date,body,id FROM email WHERE recipient LIKE ? AND seen = 0";
|
||||||
|
char buffer[PATH_MAX];
|
||||||
|
MIX_REC mix;
|
||||||
|
FTI_REC fti;
|
||||||
|
long mixptr;
|
||||||
|
struct tm timeStruct;
|
||||||
|
char *month_name[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
|
||||||
|
time_t thetime;
|
||||||
|
char *body;
|
||||||
|
int area_msgs = 0;
|
||||||
|
|
||||||
|
snprintf(buffer, PATH_MAX, "%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);
|
||||||
|
return totmsgs;
|
||||||
|
}
|
||||||
|
sqlite3_busy_timeout(db, 5000);
|
||||||
|
rc = sqlite3_prepare_v2(db, sql, -1, &res, 0);
|
||||||
|
|
||||||
|
if (rc == SQLITE_OK) {
|
||||||
|
sqlite3_bind_text(res, 1, gUser->loginname, -1, 0);
|
||||||
|
} else {
|
||||||
|
dolog("Failed to execute statement: %s", sqlite3_errmsg(db));
|
||||||
|
sqlite3_finalize(res);
|
||||||
|
sqlite3_close(db);
|
||||||
|
return totmsgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
mixptr = ftell(fti_file);
|
||||||
|
|
||||||
|
while (sqlite3_step(res) == SQLITE_ROW) {
|
||||||
|
memset(&fti, 0, sizeof(FTI_REC));
|
||||||
|
strncpy(fti.from, sqlite3_column_text(res, 0), 35);
|
||||||
|
strncpy(fti.to, gUser->loginname, 35);
|
||||||
|
strncpy(fti.subject, sqlite3_column_text(res, 1), 71);
|
||||||
|
thetime = sqlite3_column_int(res, 2);
|
||||||
|
localtime_r((time_t *)&thetime, &timeStruct);
|
||||||
|
|
||||||
|
sprintf(fti.date, "%02d-%s-%04d %02d:%02d", timeStruct.tm_mday, month_name[timeStruct.tm_mon], timeStruct.tm_year + 1900, timeStruct.tm_hour, timeStruct.tm_min);
|
||||||
|
fti.msgnum = converts((tWORD)sqlite3_column_int(res, 4));
|
||||||
|
body = strdup(sqlite3_column_text(res, 3));
|
||||||
|
fti.replyto = 0;
|
||||||
|
fti.replyat = 0;
|
||||||
|
fti.msgptr = convertl(*last_ptr);
|
||||||
|
fti.msglength = convertl(strlen(body));
|
||||||
|
|
||||||
|
*last_ptr += strlen(body);
|
||||||
|
fti.flags |= FTI_MSGLOCAL;
|
||||||
|
fti.flags = converts(fti.flags);
|
||||||
|
fti.orig_zone = 0;
|
||||||
|
fti.orig_net = 0;
|
||||||
|
fti.orig_node = 0;
|
||||||
|
fwrite(body, 1, strlen(body), dat_file);
|
||||||
|
fwrite(&fti, sizeof(FTI_REC), 1, fti_file);
|
||||||
|
free(body);
|
||||||
|
area_msgs++;
|
||||||
|
totmsgs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_finalize(res);
|
||||||
|
sqlite3_close(db);
|
||||||
|
|
||||||
|
memset(&mix, 0, sizeof(MIX_REC));
|
||||||
|
|
||||||
|
snprintf(mix.areanum, 6, "%d", 1);
|
||||||
|
mix.totmsgs = converts(area_msgs);
|
||||||
|
mix.numpers = converts(area_msgs);
|
||||||
|
mix.msghptr = convertl(mixptr);
|
||||||
|
fwrite(&mix, sizeof(MIX_REC), 1, mix_file);
|
||||||
|
|
||||||
|
return totmsgs;
|
||||||
|
}
|
||||||
|
|
||||||
int bwave_scan_area(int confr, int area, int areano, int totmsgs, FILE *fti_file, FILE *mix_file, FILE *dat_file, int *last_ptr) {
|
int bwave_scan_area(int confr, int area, int areano, int totmsgs, FILE *fti_file, FILE *mix_file, FILE *dat_file, int *last_ptr) {
|
||||||
struct msg_headers *msghs = read_message_headers(confr, area, gUser);
|
struct msg_headers *msghs = read_message_headers(confr, area, gUser);
|
||||||
@ -291,6 +370,31 @@ void bwave_create_packet() {
|
|||||||
|
|
||||||
s_printf("\r\n");
|
s_printf("\r\n");
|
||||||
|
|
||||||
|
totmsgs = bwave_scan_email(area_count+1, totmsgs, fti_file, mix_file, dat_file, &last_ptr);
|
||||||
|
s_printf(get_string(195), "Private Email", "Private Email", totmsgs);
|
||||||
|
areas = (INF_AREA_INFO **)malloc(sizeof(INF_AREA_INFO *));
|
||||||
|
|
||||||
|
flags = 0;
|
||||||
|
areas[area_count] = (INF_AREA_INFO *)malloc(sizeof(INF_AREA_INFO));
|
||||||
|
|
||||||
|
memset(areas[area_count], 0, sizeof(INF_AREA_INFO));
|
||||||
|
|
||||||
|
snprintf(areas[area_count]->areanum, 6, "%d", area_count + 1);
|
||||||
|
|
||||||
|
memcpy(areas[area_count]->echotag, "PRIVATE_EMAIL", 13);
|
||||||
|
|
||||||
|
strncpy(areas[area_count]->title, "Private Email", 49);
|
||||||
|
flags |= INF_POST;
|
||||||
|
flags |= INF_NO_PUBLIC;
|
||||||
|
flags |= INF_SCANNING;
|
||||||
|
|
||||||
|
areas[area_count]->area_flags = converts(flags);
|
||||||
|
areas[area_count]->network_type = INF_NET_FIDONET;
|
||||||
|
|
||||||
|
area_count++;
|
||||||
|
|
||||||
|
if (totmsgs < conf.bwave_max_msgs) {
|
||||||
|
|
||||||
for (i=0;i<conf.mail_conference_count;i++) {
|
for (i=0;i<conf.mail_conference_count;i++) {
|
||||||
for (j=0;j<conf.mail_conferences[i]->mail_area_count;j++) {
|
for (j=0;j<conf.mail_conferences[i]->mail_area_count;j++) {
|
||||||
if (conf.mail_conferences[i]->mail_areas[j]->read_sec_level <= gUser->sec_level && conf.mail_conferences[i]->mail_areas[j]->qwkname != NULL && msgbase_is_subscribed(i, j)) {
|
if (conf.mail_conferences[i]->mail_areas[j]->read_sec_level <= gUser->sec_level && conf.mail_conferences[i]->mail_areas[j]->qwkname != NULL && msgbase_is_subscribed(i, j)) {
|
||||||
@ -301,11 +405,8 @@ void bwave_create_packet() {
|
|||||||
// continue;
|
// continue;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
if (area_count == 0) {
|
|
||||||
areas = (INF_AREA_INFO **)malloc(sizeof(INF_AREA_INFO *));
|
|
||||||
} else {
|
|
||||||
areas = (INF_AREA_INFO **)realloc(areas, sizeof(INF_AREA_INFO *) * (area_count + 1));
|
areas = (INF_AREA_INFO **)realloc(areas, sizeof(INF_AREA_INFO *) * (area_count + 1));
|
||||||
}
|
|
||||||
flags = 0;
|
flags = 0;
|
||||||
areas[area_count] = (INF_AREA_INFO *)malloc(sizeof(INF_AREA_INFO));
|
areas[area_count] = (INF_AREA_INFO *)malloc(sizeof(INF_AREA_INFO));
|
||||||
|
|
||||||
@ -352,6 +453,7 @@ void bwave_create_packet() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fclose(dat_file);
|
fclose(dat_file);
|
||||||
fclose(mix_file);
|
fclose(mix_file);
|
||||||
@ -641,6 +743,19 @@ void bwave_upload_reply() {
|
|||||||
int stout;
|
int stout;
|
||||||
int stin;
|
int stin;
|
||||||
int sterr;
|
int sterr;
|
||||||
|
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;
|
||||||
|
|
||||||
msg_count = 0;
|
msg_count = 0;
|
||||||
|
|
||||||
@ -726,6 +841,85 @@ void bwave_upload_reply() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (fread(&upl_rec, sizeof(UPL_REC), 1, upl_file)) {
|
while (fread(&upl_rec, sizeof(UPL_REC), 1, upl_file)) {
|
||||||
|
if (strcmp("PRIVATE_EMAIL", upl_rec.echotag) == 0) {
|
||||||
|
if (msg_attr & UPL_INACTIVE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcasecmp(upl_rec.from, gUser->loginname) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(msgbuffer, 1024, "%s/node%d/bwave/%s", conf.bbs_path, mynode, upl_rec.filename);
|
||||||
|
if (stat(msgbuffer, &s) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
body = (char *)malloc(s.st_size + 1);
|
||||||
|
msg_file = fopen(msgbuffer, "r");
|
||||||
|
if (!msg_file) {
|
||||||
|
free(body);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fread(body, 1, s.st_size, msg_file);
|
||||||
|
fclose(msg_file);
|
||||||
|
|
||||||
|
body[s.st_size] = '\0';
|
||||||
|
|
||||||
|
bpos = 0;
|
||||||
|
for (i=0;i<strlen(body);i++) {
|
||||||
|
if (body[i] != '\n') {
|
||||||
|
body[bpos++] = body[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
body[bpos] = '\0';
|
||||||
|
|
||||||
|
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);
|
||||||
|
free(body);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sqlite3_busy_timeout(db, 5000);
|
||||||
|
|
||||||
|
rc = sqlite3_exec(db, csql, 0, 0, &err_msg);
|
||||||
|
if (rc != SQLITE_OK ) {
|
||||||
|
|
||||||
|
dolog("SQL error: %s", err_msg);
|
||||||
|
|
||||||
|
sqlite3_free(err_msg);
|
||||||
|
sqlite3_close(db);
|
||||||
|
|
||||||
|
free(body);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = sqlite3_prepare_v2(db, isql, -1, &res, 0);
|
||||||
|
|
||||||
|
if (rc == SQLITE_OK) {
|
||||||
|
sqlite3_bind_text(res, 1, gUser->loginname, -1, 0);
|
||||||
|
sqlite3_bind_text(res, 2, upl_rec.to, -1, 0);
|
||||||
|
sqlite3_bind_text(res, 3, upl_rec.subj, -1, 0);
|
||||||
|
sqlite3_bind_text(res, 4, body, -1, 0);
|
||||||
|
sqlite3_bind_int(res, 5, convertl(upl_rec.unix_date));
|
||||||
|
} else {
|
||||||
|
dolog("Failed to execute statement: %s", sqlite3_errmsg(db));
|
||||||
|
sqlite3_finalize(res);
|
||||||
|
sqlite3_close(db);
|
||||||
|
free(body);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sqlite3_step(res);
|
||||||
|
|
||||||
|
sqlite3_finalize(res);
|
||||||
|
sqlite3_close(db);
|
||||||
|
free(body);
|
||||||
|
} else {
|
||||||
// find area
|
// find area
|
||||||
confr = -1;
|
confr = -1;
|
||||||
area = -1;
|
area = -1;
|
||||||
@ -842,6 +1036,7 @@ void bwave_upload_reply() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
snprintf(buffer, 1024, "%s/node%d/bwave/", conf.bbs_path, mynode);
|
snprintf(buffer, 1024, "%s/node%d/bwave/", conf.bbs_path, mynode);
|
||||||
recursive_delete(buffer);
|
recursive_delete(buffer);
|
||||||
|
@ -354,7 +354,7 @@ void show_email(struct user_record *user, int msgno, int email_count, struct ema
|
|||||||
}
|
}
|
||||||
|
|
||||||
void list_emails(struct user_record *user) {
|
void list_emails(struct user_record *user) {
|
||||||
char buffer[256];
|
char buffer[PATH_MAX];
|
||||||
sqlite3 *db;
|
sqlite3 *db;
|
||||||
sqlite3_stmt *res;
|
sqlite3_stmt *res;
|
||||||
int rc;
|
int rc;
|
||||||
@ -370,13 +370,12 @@ void list_emails(struct user_record *user) {
|
|||||||
int i;
|
int i;
|
||||||
char c;
|
char c;
|
||||||
int closed = 0;
|
int closed = 0;
|
||||||
sprintf(buffer, "%s/email.sq3", conf.bbs_path);
|
snprintf(buffer, PATH_MAX, "%s/email.sq3", conf.bbs_path);
|
||||||
|
|
||||||
rc = sqlite3_open(buffer, &db);
|
rc = sqlite3_open(buffer, &db);
|
||||||
if (rc != SQLITE_OK) {
|
if (rc != SQLITE_OK) {
|
||||||
dolog("Cannot open database: %s", sqlite3_errmsg(db));
|
dolog("Cannot open database: %s", sqlite3_errmsg(db));
|
||||||
sqlite3_close(db);
|
sqlite3_close(db);
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
sqlite3_busy_timeout(db, 5000);
|
sqlite3_busy_timeout(db, 5000);
|
||||||
|
Reference in New Issue
Block a user