This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
magicka/src/bluewave.c

1110 lines
30 KiB
C
Raw Normal View History

2016-12-06 07:06:28 +00:00
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <termios.h>
#include <fcntl.h>
2018-01-07 22:54:03 +00:00
#include <sqlite3.h>
#include <sys/wait.h>
2016-12-06 07:06:28 +00:00
#include "bluewave.h"
#include "jamlib/jam.h"
#include "bbs.h"
2018-05-22 11:02:22 +00:00
#include "libuuid/uuid.h"
2016-12-06 07:06:28 +00:00
extern struct bbs_config conf;
extern struct user_record *gUser;
extern int mynode;
extern char upload_filename[1024];
extern int sshBBS;
2016-12-11 12:14:36 +00:00
extern int bbs_stdin;
extern int bbs_stdout;
extern int bbs_stderr;
2016-12-06 07:06:28 +00:00
tLONG convertl(tLONG l) {
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
unsigned char result_bytes[4];
unsigned int result;
result_bytes[0] = (unsigned char)((l >> 24) & 0xFF);
result_bytes[1] = (unsigned char)((l >> 16) & 0xFF);
result_bytes[2] = (unsigned char)((l >> 8) & 0xFF);
result_bytes[3] = (unsigned char)(l & 0xFF);
2016-12-06 07:06:28 +00:00
memcpy(&result, result_bytes, 4);
return result;
#else
return l;
#endif
}
tWORD converts(tWORD s) {
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
unsigned char result_bytes[2];
unsigned short result;
result_bytes[0] = (unsigned char)((s >> 8) & 0xFF);
result_bytes[1] = (unsigned char)(s & 0xFF);
2016-12-06 07:06:28 +00:00
memcpy(&result, result_bytes, 4);
return result;
#else
return s;
#endif
}
2018-01-07 22:54:03 +00:00
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 *sqlseen = "UPDATE email SET seen = 1 WHERE recipient LIKE ?";
2018-01-07 22:54:03 +00:00
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);
2018-01-07 22:54:03 +00:00
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);
2018-01-07 22:54:03 +00:00
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);
2018-01-07 22:54:03 +00:00
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++;
2018-01-07 22:54:03 +00:00
}
sqlite3_finalize(res);
2018-01-07 23:59:20 +00:00
rc = sqlite3_prepare_v2(db, sqlseen, -1, &res, 0);
if (rc == SQLITE_OK) {
sqlite3_bind_text(res, 1, gUser->loginname, -1, 0);
sqlite3_step(res);
}
2018-01-07 22:54:03 +00:00
sqlite3_finalize(res);
sqlite3_close(db);
memset(&mix, 0, sizeof(MIX_REC));
2018-01-07 22:54:03 +00:00
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);
2018-01-07 22:54:03 +00:00
return totmsgs;
}
2016-12-06 07:06:28 +00:00
int bwave_scan_area(int confr, int area, int areano, int totmsgs, FILE *fti_file, FILE *mix_file, FILE *dat_file, int *last_ptr) {
2018-02-18 03:51:39 +00:00
struct msg_headers *msghs = read_message_headers(confr, area, gUser, 0);
2016-12-06 07:06:28 +00:00
int all_unread = 1;
s_JamBase *jb;
s_JamLastRead jlr;
int i;
int k;
MIX_REC mix;
int area_msgs;
int personal_msgs;
long mixptr;
FTI_REC fti;
struct fido_addr *fido;
char *body;
struct tm timeStruct;
char realname[66];
2016-12-06 07:06:28 +00:00
char *month_name[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
snprintf(realname, 65, "%s %s", gUser->firstname, gUser->lastname);
2016-12-06 07:06:28 +00:00
if (msghs == NULL) {
return totmsgs;
}
2016-12-06 07:06:28 +00:00
jb = open_jam_base(conf.mail_conferences[confr]->mail_areas[area]->path);
if (!jb) {
dolog("Error opening JAM base.. %s", conf.mail_conferences[confr]->mail_areas[area]->path);
2016-12-06 23:24:15 +00:00
if (msghs != NULL) {
free_message_headers(msghs);
}
2016-12-06 07:06:28 +00:00
return totmsgs;
} else {
all_unread = 0;
if (JAM_ReadLastRead(jb, gUser->id, &jlr) == JAM_NO_USER) {
jlr.LastReadMsg = 0;
jlr.HighReadMsg = 0;
2017-10-11 11:01:13 +00:00
jlr.UserCRC = JAM_Crc32(gUser->loginname, strlen(gUser->loginname));
jlr.UserID = gUser->id;
2016-12-06 07:06:28 +00:00
all_unread = 1;
2017-09-21 06:16:12 +00:00
} else if (jlr.LastReadMsg == 0 && jlr.HighReadMsg == 0) {
2017-09-21 11:45:24 +00:00
all_unread = 1;
2016-12-06 07:06:28 +00:00
}
}
2016-12-06 07:06:28 +00:00
if (all_unread == 0) {
k = jlr.HighReadMsg;
for (i = 0; i < msghs->msg_count; i++) {
2016-12-06 07:06:28 +00:00
if (msghs->msgs[i]->msg_h->MsgNum == k) {
break;
}
}
i += 1;
2016-12-06 07:06:28 +00:00
} else {
i = 0;
}
2016-12-06 07:06:28 +00:00
mixptr = ftell(fti_file);
area_msgs = 0;
personal_msgs = 0;
for (k = i; k < msghs->msg_count; k++) {
2016-12-06 07:06:28 +00:00
if (totmsgs == conf.bwave_max_msgs) {
break;
}
2016-12-11 12:14:36 +00:00
if (msghs->msgs[k]->to != NULL) {
if (strcasecmp(msghs->msgs[k]->to, gUser->loginname) == 0 || strncasecmp(msghs->msgs[k]->to, realname, 42) == 0) {
2016-12-11 12:14:36 +00:00
personal_msgs++;
}
2016-12-06 07:06:28 +00:00
}
2016-12-06 07:06:28 +00:00
memset(&fti, 0, sizeof(FTI_REC));
2016-12-11 12:14:36 +00:00
if (msghs->msgs[k]->from != NULL) {
strncpy(fti.from, msghs->msgs[k]->from, 35);
} else {
sprintf(fti.from, "(Missing From)");
}
if (msghs->msgs[k]->to != NULL) {
strncpy(fti.to, msghs->msgs[k]->to, 35);
} else {
sprintf(fti.to, "(Missing To)");
}
2016-12-11 12:14:36 +00:00
if (msghs->msgs[k]->subject != NULL) {
strncpy(fti.subject, msghs->msgs[k]->subject, 71);
} else {
sprintf(fti.subject, "(Missing Subject)");
}
2016-12-06 07:06:28 +00:00
localtime_r((time_t *)&msghs->msgs[k]->msg_h->DateWritten, &timeStruct);
2016-12-06 07:06:28 +00:00
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)msghs->msgs[k]->msg_h->MsgNum);
fti.replyto = 0;
fti.replyat = 0;
fti.msgptr = convertl(*last_ptr);
2016-12-06 07:06:28 +00:00
fti.msglength = convertl(msghs->msgs[k]->msg_h->TxtLen);
*last_ptr += msghs->msgs[k]->msg_h->TxtLen;
if (msghs->msgs[k]->msg_h->Attribute & JAM_MSG_LOCAL) {
2016-12-06 07:06:28 +00:00
fti.flags |= FTI_MSGLOCAL;
}
2016-12-06 07:06:28 +00:00
fti.flags = converts(fti.flags);
2016-12-06 07:06:28 +00:00
fido = parse_fido_addr(msghs->msgs[k]->oaddress);
if (fido != NULL) {
fti.orig_zone = converts(fido->zone);
fti.orig_net = converts(fido->net);
fti.orig_node = converts(fido->node);
free(fido);
} else {
fti.orig_zone = 0;
fti.orig_net = 0;
fti.orig_node = 0;
}
// write msg data
body = (char *)malloz(msghs->msgs[k]->msg_h->TxtLen);
JAM_ReadMsgText(jb, msghs->msgs[k]->msg_h->TxtOffset, msghs->msgs[k]->msg_h->TxtLen, body);
2016-12-06 07:06:28 +00:00
fwrite(body, 1, msghs->msgs[k]->msg_h->TxtLen, dat_file);
fwrite(&fti, sizeof(FTI_REC), 1, fti_file);
2016-12-06 07:06:28 +00:00
free(body);
jlr.LastReadMsg = msghs->msgs[k]->msg_h->MsgNum;
if (jlr.HighReadMsg < msghs->msgs[k]->msg_h->MsgNum) {
jlr.HighReadMsg = msghs->msgs[k]->msg_h->MsgNum;
}
2016-12-06 07:06:28 +00:00
JAM_WriteLastRead(jb, gUser->id, &jlr);
2016-12-06 07:06:28 +00:00
area_msgs++;
totmsgs++;
}
2017-09-21 11:45:24 +00:00
//if (area_msgs) {
memset(&mix, 0, sizeof(MIX_REC));
snprintf(mix.areanum, 6, "%d", areano);
mix.totmsgs = converts(area_msgs);
mix.numpers = converts(personal_msgs);
mix.msghptr = convertl(mixptr);
fwrite(&mix, sizeof(MIX_REC), 1, mix_file);
2017-09-21 11:45:24 +00:00
//}
2016-12-06 07:06:28 +00:00
JAM_CloseMB(jb);
2018-02-10 06:01:30 +00:00
free(jb);
2016-12-06 07:06:28 +00:00
free_message_headers(msghs);
return totmsgs;
}
void bwave_create_packet() {
char buffer[1024];
char archive[1024];
INF_HEADER hdr;
struct ptr_vector areas;
INF_AREA_INFO *area = NULL;
2016-12-06 07:06:28 +00:00
int i;
int j;
int area_count;
tWORD flags;
int lasttot;
int bpos;
int last_ptr = 0;
2016-12-11 12:14:36 +00:00
int stout;
int stin;
int sterr;
char *weekday[] = {"SU", "MO", "TU", "WE", "TH", "FR", "SA"};
struct stat s;
2016-12-06 07:06:28 +00:00
struct termios oldit;
struct termios oldot;
struct tm time_tm;
time_t thetime;
2016-12-06 07:06:28 +00:00
FILE *mix_file;
FILE *fti_file;
FILE *dat_file;
FILE *inf_file;
2017-09-21 00:21:51 +00:00
int tot_areas = 0;
2016-12-06 07:06:28 +00:00
int totmsgs = 0;
2018-02-09 09:35:14 +00:00
int ret;
char **args, *arg;
2018-06-20 09:31:35 +00:00
char *cmd;
pid_t pid;
2018-02-09 09:35:14 +00:00
init_ptr_vector(&areas);
for (i = 0; i < conf.mail_conference_count; i++) {
for (j = 0; j < conf.mail_conferences[i]->mail_area_count; j++) {
2017-09-21 00:21:51 +00:00
if (msgbase_is_subscribed(i, j)) {
tot_areas++;
}
}
}
2017-09-21 00:21:51 +00:00
if (tot_areas == 0) {
s_printf(get_string(224));
s_printf(get_string(6));
s_getchar();
return;
}
2016-12-06 07:06:28 +00:00
area_count = 0;
2016-12-06 07:06:28 +00:00
memset(&hdr, 0, sizeof(INF_HEADER));
2016-12-06 07:06:28 +00:00
hdr.ver = PACKET_LEVEL;
strncpy(hdr.loginname, gUser->loginname, 42);
//strncpy(hdr.aliasname, gUser->loginname, 42);
snprintf(hdr.aliasname, 42, "%s %s", gUser->firstname, gUser->lastname);
2016-12-06 07:06:28 +00:00
hdr.zone = converts(conf.main_aka->zone);
hdr.node = converts(conf.main_aka->node);
hdr.net = converts(conf.main_aka->net);
hdr.point = converts(conf.main_aka->point);
strncpy(hdr.sysop, conf.sysop_name, 40);
2016-12-06 07:06:28 +00:00
strncpy(hdr.systemname, conf.bbs_name, 64);
hdr.inf_header_len = converts(sizeof(INF_HEADER));
hdr.inf_areainfo_len = converts(sizeof(INF_AREA_INFO));
hdr.mix_structlen = converts(sizeof(MIX_REC));
hdr.fti_structlen = converts(sizeof(FTI_REC));
hdr.uses_upl_file = 1;
hdr.from_to_len = 35;
hdr.subject_len = 71;
memcpy(hdr.packet_id, conf.bwave_name, strlen(conf.bwave_name));
2016-12-06 23:24:15 +00:00
snprintf(buffer, 1024, "%s/node%d", conf.bbs_path, mynode);
if (stat(buffer, &s) != 0) {
mkdir(buffer, 0755);
}
snprintf(buffer, 1024, "%s/node%d/bwave/", conf.bbs_path, mynode);
if (stat(buffer, &s) == 0) {
recursive_delete(buffer);
}
mkdir(buffer, 0755);
snprintf(buffer, 1024, "%s/node%d/bwave/%s.FTI", conf.bbs_path, mynode, conf.bwave_name);
fti_file = fopen(buffer, "wb");
snprintf(buffer, 1024, "%s/node%d/bwave/%s.MIX", conf.bbs_path, mynode, conf.bwave_name);
mix_file = fopen(buffer, "wb");
snprintf(buffer, 1024, "%s/node%d/bwave/%s.DAT", conf.bbs_path, mynode, conf.bwave_name);
dat_file = fopen(buffer, "wb");
2016-12-06 07:06:28 +00:00
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);
2018-01-07 22:54:03 +00:00
flags = 0;
area = (INF_AREA_INFO *)malloz(sizeof(INF_AREA_INFO));
2018-01-07 22:54:03 +00:00
snprintf(area->areanum, 6, "%d", area_count + 1);
memcpy(area->echotag, "PRIVATE_EMAIL", 13);
strncpy(area->title, "Private Email", 49);
2018-01-07 22:54:03 +00:00
flags |= INF_POST;
flags |= INF_NO_PUBLIC;
flags |= INF_SCANNING;
area->area_flags = converts(flags);
area->network_type = INF_NET_FIDONET;
ptr_vector_append(&areas, area);
2018-01-07 22:54:03 +00:00
area_count++;
2016-12-06 07:06:28 +00:00
2018-01-07 22:54:03 +00:00
if (totmsgs < conf.bwave_max_msgs) {
for (i = 0; i < conf.mail_conference_count; i++) {
for (j = 0; j < conf.mail_conferences[i]->mail_area_count; j++) {
2018-01-07 22:54:03 +00:00
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)) {
lasttot = totmsgs;
totmsgs = bwave_scan_area(i, j, area_count + 1, totmsgs, fti_file, mix_file, dat_file, &last_ptr);
s_printf(get_string(195), conf.mail_conferences[i]->name, conf.mail_conferences[i]->mail_areas[j]->name, totmsgs - lasttot);
2018-01-07 22:54:03 +00:00
//if (lasttot == totmsgs) {
// continue;
//}
2018-01-07 22:54:03 +00:00
flags = 0;
area = (INF_AREA_INFO *)malloz(sizeof(INF_AREA_INFO));
snprintf(area->areanum, 6, "%d", area_count + 1);
memcpy(area->echotag, conf.mail_conferences[i]->mail_areas[j]->qwkname, strlen(conf.mail_conferences[i]->mail_areas[j]->qwkname));
strncpy(area->title, conf.mail_conferences[i]->mail_areas[j]->name, 49);
2018-01-07 22:54:03 +00:00
if (conf.mail_conferences[i]->mail_areas[j]->write_sec_level <= gUser->sec_level) {
flags |= INF_POST;
}
2018-01-07 22:54:03 +00:00
if (conf.mail_conferences[i]->mail_areas[j]->type == TYPE_NETMAIL_AREA) {
flags |= INF_NO_PUBLIC;
flags |= INF_NETMAIL;
flags |= INF_ECHO;
}
2018-01-07 22:54:03 +00:00
if (conf.mail_conferences[i]->mail_areas[j]->type == TYPE_ECHOMAIL_AREA || conf.mail_conferences[i]->mail_areas[j]->type == TYPE_NEWSGROUP_AREA) {
flags |= INF_NO_PRIVATE;
flags |= INF_ECHO;
}
2018-01-07 22:54:03 +00:00
if (conf.mail_conferences[i]->mail_areas[j]->type == TYPE_LOCAL_AREA) {
flags |= INF_NO_PRIVATE;
}
2018-01-07 22:54:03 +00:00
flags |= INF_SCANNING;
area->area_flags = converts(flags);
area->network_type = INF_NET_FIDONET;
2018-01-07 22:54:03 +00:00
ptr_vector_append(&areas, area);
2018-01-07 22:54:03 +00:00
area_count++;
if (totmsgs == conf.bwave_max_msgs) {
break;
}
2016-12-06 07:06:28 +00:00
}
}
2018-01-07 22:54:03 +00:00
if (totmsgs == conf.bwave_max_msgs) {
break;
}
2016-12-06 07:06:28 +00:00
}
}
2018-01-07 22:54:03 +00:00
2016-12-06 07:06:28 +00:00
fclose(dat_file);
fclose(mix_file);
fclose(fti_file);
snprintf(buffer, 1024, "%s/node%d/bwave/%s.INF", conf.bbs_path, mynode, conf.bwave_name);
inf_file = fopen(buffer, "wb");
2016-12-06 07:06:28 +00:00
fwrite(&hdr, sizeof(INF_HEADER), 1, inf_file);
for (i = 0; i < area_count; i++) {
fwrite(ptr_vector_get(&areas, i), sizeof(INF_AREA_INFO), 1, inf_file);
2016-12-06 07:06:28 +00:00
}
2016-12-06 07:06:28 +00:00
fclose(inf_file);
More use of ptr_vector; avoid unnecessary copies. Recast more code in terms of the ptr_vector abstraction. The mail_menu.c code also made a lot of unnecessary copies of strings. For example, there was this code sequence: for (i = z; i < lines - 1; i++) { free(content[i]); content[i] = strdup(content[i + 1]); } free(content[i]); lines--; content = (char **)realloc(content, sizeof(char *) * lines); Here, `content` represents an array of lines of text. This code is removing an element from somewhere in that array (possibly in the middle), and then shifting the remaining elements over one position. But observe the calls to `free` and `strdup` in the loop body: the content is already dynamically allocated. We free whatever was in the selected position, and then make *another copy* of the data in the next position to put into the now-available slot in the array: repeat for the remainder of the array's elements. Instead, we could change this code to just shift things down: free(content[z]); for (i = z; i < (lines - 1); ++i) content[i] = content[i + 1]; --lines; ncontent = realloc(content, sizeof(char *) * lines); assert(ncontent == NULL); content = ncontent; However, the ptr_vector abstraction provides us a function, `ptr_vector_del` that deletes an element from the array and returns the pointer, so we can rewrite this as simply: free(ptr_vector_del(&content, z)); No additional malloc()/free() required, which means less pressure on the memory allocator and less copying of data. Signed-off-by: Dan Cross <patchdev@fat-dragon.org>
2018-10-10 17:50:37 +00:00
ptr_vector_apply(&areas, free);
destroy_ptr_vector(&areas);
2016-12-06 07:06:28 +00:00
if (totmsgs > 0) {
// create archive
bpos = 0;
if (gUser->bwavestyle) {
thetime = time(NULL);
localtime_r(&thetime, &time_tm);
if (gUser->bwavepktno / 10 != time_tm.tm_wday) {
gUser->bwavepktno = time_tm.tm_wday * 10;
}
snprintf(archive, 1024, "%s/node%d/%s.%s%d", conf.bbs_path, mynode, conf.bwave_name, weekday[time_tm.tm_wday], gUser->bwavepktno % 10);
} else {
snprintf(archive, 1024, "%s/node%d/%s.%03d", conf.bbs_path, mynode, conf.bwave_name, gUser->bwavepktno);
}
for (i = 0; i < strlen(conf.archivers[gUser->defarchiver - 1]->pack); i++) {
if (conf.archivers[gUser->defarchiver - 1]->pack[i] == '*') {
2016-12-06 07:06:28 +00:00
i++;
if (conf.archivers[gUser->defarchiver - 1]->pack[i] == 'a') {
2016-12-06 07:06:28 +00:00
sprintf(&buffer[bpos], "%s", archive);
bpos = strlen(buffer);
} else if (conf.archivers[gUser->defarchiver - 1]->pack[i] == 'f') {
sprintf(&buffer[bpos], "%s/node%d/bwave/%s.INF %s/node%d/bwave/%s.MIX %s/node%d/bwave/%s.FTI %s/node%d/bwave/%s.DAT", conf.bbs_path, mynode, conf.bwave_name, conf.bbs_path, mynode, conf.bwave_name, conf.bbs_path, mynode, conf.bwave_name, conf.bbs_path, mynode, conf.bwave_name);
2016-12-06 07:06:28 +00:00
bpos = strlen(buffer);
} else if (conf.archivers[gUser->defarchiver - 1]->pack[i] == '*') {
2016-12-06 07:06:28 +00:00
buffer[bpos++] = '*';
buffer[bpos] = '\0';
}
} else {
buffer[bpos++] = conf.archivers[gUser->defarchiver - 1]->pack[i];
2016-12-06 07:06:28 +00:00
buffer[bpos] = '\0';
}
}
2016-12-11 12:14:36 +00:00
if (sshBBS) {
stout = dup(STDOUT_FILENO);
stin = dup(STDIN_FILENO);
sterr = dup(STDERR_FILENO);
2016-12-11 12:14:36 +00:00
dup2(bbs_stdout, STDOUT_FILENO);
dup2(bbs_stderr, STDERR_FILENO);
dup2(bbs_stdin, STDIN_FILENO);
}
args = split_on_space(buffer, NULL);
cmd = args[0];
2018-06-20 09:31:35 +00:00
pid = fork();
if (pid == 0) {
execvp(cmd, args);
exit(0);
} else if (pid > 0) {
waitpid(pid, &ret, 0);
} else {
ret = -1;
}
free(args);
2016-12-11 12:14:36 +00:00
if (sshBBS) {
2016-12-11 12:14:36 +00:00
dup2(stout, STDOUT_FILENO);
dup2(sterr, STDERR_FILENO);
2016-12-11 12:14:36 +00:00
dup2(stin, STDIN_FILENO);
2016-12-11 12:14:36 +00:00
close(stin);
close(stout);
close(sterr);
}
2016-12-06 07:06:28 +00:00
2018-02-09 09:35:14 +00:00
if (ret != -1 && ret >> 8 != 127) {
do_download(gUser, archive);
} else {
s_printf(get_string(274));
}
snprintf(buffer, 1024, "%s/node%d/bwave", conf.bbs_path, mynode);
recursive_delete(buffer);
2016-12-06 07:06:28 +00:00
unlink(archive);
gUser->bwavepktno++;
if (gUser->bwavepktno > 999) {
gUser->bwavepktno = 0;
}
2016-12-06 07:06:28 +00:00
save_user(gUser);
}
2016-12-06 07:06:28 +00:00
s_printf(get_string(6));
s_getc();
}
int bwave_add_message(int confr, int area, unsigned int dwritten, char *to, char *subject, struct fido_addr *destaddr, char *msg) {
s_JamBase *jb;
s_JamMsgHeader jmh;
s_JamSubPacket *jsp;
2016-12-06 07:06:28 +00:00
s_JamSubfield jsf;
int z;
char buffer[256];
2018-05-22 11:02:22 +00:00
uuid_t magi_msgid;
2016-12-06 07:06:28 +00:00
jb = open_jam_base(conf.mail_conferences[confr]->mail_areas[area]->path);
if (!jb) {
dolog("Error opening JAM base.. %s", conf.mail_conferences[confr]->mail_areas[area]->path);
return 1;
}
JAM_ClearMsgHeader(&jmh);
2016-12-06 07:06:28 +00:00
jmh.DateWritten = dwritten;
jmh.Attribute |= JAM_MSG_LOCAL;
2016-12-06 07:06:28 +00:00
if (conf.mail_conferences[confr]->realnames == 0) {
strlcpy(buffer, gUser->loginname, sizeof buffer);
2016-12-06 07:06:28 +00:00
} else {
snprintf(buffer, sizeof buffer, "%s %s", gUser->firstname, gUser->lastname);
2016-12-06 07:06:28 +00:00
}
jsp = JAM_NewSubPacket();
jsf.LoID = JAMSFLD_SENDERNAME;
jsf.HiID = 0;
2016-12-06 07:06:28 +00:00
jsf.DatLen = strlen(buffer);
jsf.Buffer = (char *)buffer;
JAM_PutSubfield(jsp, &jsf);
if (conf.mail_conferences[confr]->mail_areas[area]->type == TYPE_NEWSGROUP_AREA) {
sprintf(buffer, "ALL");
jsf.LoID = JAMSFLD_RECVRNAME;
jsf.HiID = 0;
jsf.DatLen = strlen(buffer);
jsf.Buffer = (char *)buffer;
JAM_PutSubfield(jsp, &jsf);
} else {
jsf.LoID = JAMSFLD_RECVRNAME;
jsf.HiID = 0;
jsf.DatLen = strlen(to);
jsf.Buffer = (char *)to;
JAM_PutSubfield(jsp, &jsf);
}
2016-12-06 07:06:28 +00:00
jsf.LoID = JAMSFLD_SUBJECT;
jsf.HiID = 0;
2016-12-06 07:06:28 +00:00
jsf.DatLen = strlen(subject);
jsf.Buffer = (char *)subject;
JAM_PutSubfield(jsp, &jsf);
if (conf.mail_conferences[confr]->mail_areas[area]->type == TYPE_ECHOMAIL_AREA || conf.mail_conferences[confr]->mail_areas[area]->type == TYPE_NEWSGROUP_AREA) {
jmh.Attribute |= JAM_MSG_TYPEECHO;
2016-12-06 07:06:28 +00:00
2018-05-22 11:02:22 +00:00
if (conf.mail_conferences[confr]->nettype == NETWORK_FIDO) {
if (conf.mail_conferences[confr]->fidoaddr->point) {
sprintf(buffer, "%d:%d/%d.%d", conf.mail_conferences[confr]->fidoaddr->zone,
conf.mail_conferences[confr]->fidoaddr->net,
conf.mail_conferences[confr]->fidoaddr->node,
conf.mail_conferences[confr]->fidoaddr->point);
2018-05-22 11:02:22 +00:00
} else {
sprintf(buffer, "%d:%d/%d", conf.mail_conferences[confr]->fidoaddr->zone,
conf.mail_conferences[confr]->fidoaddr->net,
conf.mail_conferences[confr]->fidoaddr->node);
2018-05-22 11:02:22 +00:00
}
jsf.LoID = JAMSFLD_OADDRESS;
jsf.HiID = 0;
2018-05-22 11:02:22 +00:00
jsf.DatLen = strlen(buffer);
jsf.Buffer = (char *)buffer;
JAM_PutSubfield(jsp, &jsf);
2016-12-06 07:06:28 +00:00
2018-05-22 11:02:22 +00:00
sprintf(buffer, "%d:%d/%d.%d %08lx", conf.mail_conferences[confr]->fidoaddr->zone,
conf.mail_conferences[confr]->fidoaddr->net,
conf.mail_conferences[confr]->fidoaddr->node,
conf.mail_conferences[confr]->fidoaddr->point,
generate_msgid());
2016-12-06 07:06:28 +00:00
jsf.LoID = JAMSFLD_MSGID;
jsf.HiID = 0;
2018-05-22 11:02:22 +00:00
jsf.DatLen = strlen(buffer);
jsf.Buffer = (char *)buffer;
JAM_PutSubfield(jsp, &jsf);
jmh.MsgIdCRC = JAM_Crc32(buffer, strlen(buffer));
} else if (conf.mail_conferences[confr]->nettype == NETWORK_MAGI) {
sprintf(buffer, "%d", conf.mail_conferences[confr]->maginode);
jsf.LoID = JAMSFLD_OADDRESS;
jsf.HiID = 0;
2018-05-22 11:02:22 +00:00
jsf.DatLen = strlen(buffer);
jsf.Buffer = (char *)buffer;
JAM_PutSubfield(jsp, &jsf);
uuid_generate(magi_msgid);
uuid_unparse_lower(magi_msgid, buffer);
jsf.LoID = JAMSFLD_MSGID;
jsf.HiID = 0;
2018-05-22 11:02:22 +00:00
jsf.DatLen = strlen(buffer);
jsf.Buffer = (char *)buffer;
JAM_PutSubfield(jsp, &jsf);
jmh.MsgIdCRC = JAM_Crc32(buffer, strlen(buffer));
2018-06-24 00:28:18 +00:00
} else if (conf.mail_conferences[confr]->nettype == NETWORK_QWK) {
jsf.LoID = JAMSFLD_OADDRESS;
jsf.HiID = 0;
2018-06-24 00:28:18 +00:00
jsf.DatLen = strlen(conf.bwave_name);
jsf.Buffer = (char *)conf.bwave_name;
JAM_PutSubfield(jsp, &jsf);
2018-05-22 11:02:22 +00:00
}
} else if (conf.mail_conferences[confr]->mail_areas[area]->type == TYPE_NETMAIL_AREA && conf.mail_conferences[confr]->nettype == NETWORK_FIDO) {
jmh.Attribute |= JAM_MSG_TYPENET;
jmh.Attribute |= JAM_MSG_PRIVATE;
2016-12-06 07:06:28 +00:00
if (conf.mail_conferences[confr]->fidoaddr->point) {
sprintf(buffer, "%d:%d/%d.%d", conf.mail_conferences[confr]->fidoaddr->zone,
conf.mail_conferences[confr]->fidoaddr->net,
conf.mail_conferences[confr]->fidoaddr->node,
conf.mail_conferences[confr]->fidoaddr->point);
2016-12-06 07:06:28 +00:00
} else {
sprintf(buffer, "%d:%d/%d", conf.mail_conferences[confr]->fidoaddr->zone,
conf.mail_conferences[confr]->fidoaddr->net,
conf.mail_conferences[confr]->fidoaddr->node);
2016-12-06 07:06:28 +00:00
}
jsf.LoID = JAMSFLD_OADDRESS;
jsf.HiID = 0;
2016-12-06 07:06:28 +00:00
jsf.DatLen = strlen(buffer);
jsf.Buffer = (char *)buffer;
JAM_PutSubfield(jsp, &jsf);
if (destaddr != NULL) {
if (destaddr->point) {
sprintf(buffer, "%d:%d/%d.%d", destaddr->zone,
destaddr->net,
destaddr->node,
destaddr->point);
2016-12-06 07:06:28 +00:00
} else {
sprintf(buffer, "%d:%d/%d", destaddr->zone,
destaddr->net,
destaddr->node);
2016-12-06 07:06:28 +00:00
}
jsf.LoID = JAMSFLD_DADDRESS;
jsf.HiID = 0;
2016-12-06 07:06:28 +00:00
jsf.DatLen = strlen(buffer);
jsf.Buffer = (char *)buffer;
JAM_PutSubfield(jsp, &jsf);
}
sprintf(buffer, "%d:%d/%d.%d %08lx", conf.mail_conferences[confr]->fidoaddr->zone,
conf.mail_conferences[confr]->fidoaddr->net,
conf.mail_conferences[confr]->fidoaddr->node,
conf.mail_conferences[confr]->fidoaddr->point,
generate_msgid());
2016-12-06 07:06:28 +00:00
jsf.LoID = JAMSFLD_MSGID;
jsf.HiID = 0;
2016-12-06 07:06:28 +00:00
jsf.DatLen = strlen(buffer);
jsf.Buffer = (char *)buffer;
JAM_PutSubfield(jsp, &jsf);
jmh.MsgIdCRC = JAM_Crc32(buffer, strlen(buffer));
}
while (1) {
z = JAM_LockMB(jb, 100);
if (z == 0) {
break;
} else if (z == JAM_LOCK_FAILED) {
sleep(1);
} else {
dolog("Failed to lock msg base!");
2018-02-10 06:01:30 +00:00
JAM_CloseMB(jb);
free(jb);
2016-12-06 07:06:28 +00:00
return 1;
}
}
if (JAM_AddMessage(jb, &jmh, jsp, (char *)msg, strlen(msg))) {
dolog("Failed to add message");
JAM_UnlockMB(jb);
2016-12-06 07:06:28 +00:00
JAM_DelSubPacket(jsp);
JAM_CloseMB(jb);
2018-02-10 06:01:30 +00:00
free(jb);
2016-12-06 07:06:28 +00:00
return -1;
} else {
JAM_UnlockMB(jb);
JAM_DelSubPacket(jsp);
JAM_CloseMB(jb);
2018-02-10 06:01:30 +00:00
free(jb);
2016-12-06 07:06:28 +00:00
}
return 0;
}
void bwave_upload_reply() {
char buffer[1024];
char msgbuffer[1024];
char originlinebuffer[256];
int i;
int bpos;
UPL_HEADER upl_hdr;
UPL_REC upl_rec;
int j;
int confr;
int area;
tWORD msg_attr;
struct fido_addr addr;
stralloc sa = EMPTY_STRALLOC;
2016-12-06 07:06:28 +00:00
char *body;
char *tagline;
struct stat s;
2016-12-06 07:06:28 +00:00
int echomail = 0;
int netmail = 0;
FILE *upl_file;
FILE *msg_file;
int sem_fd;
int msg_count;
2016-12-11 12:14:36 +00:00
int stout;
int stin;
int sterr;
2018-01-07 22:54:03 +00:00
sqlite3 *db;
sqlite3_stmt *res;
int rc;
2018-01-07 22:54:03 +00:00
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);";
2018-01-07 22:54:03 +00:00
char *isql = "INSERT INTO email (sender, recipient, subject, body, date, seen) VALUES(?, ?, ?, ?, ?, 0)";
char *err_msg = 0;
char **args, *arg;
2018-06-20 09:31:35 +00:00
char *cmd;
pid_t pid;
int ret;
msg_count = 0;
2016-12-06 23:24:15 +00:00
snprintf(buffer, 1024, "%s/node%d", conf.bbs_path, mynode);
if (stat(buffer, &s) != 0) {
mkdir(buffer, 0755);
}
snprintf(buffer, 1024, "%s/node%d/bwave/", conf.bbs_path, mynode);
if (stat(buffer, &s) == 0) {
recursive_delete(buffer);
}
mkdir(buffer, 0755);
if (!do_upload(gUser, buffer)) {
s_printf(get_string(211));
recursive_delete(buffer);
return;
}
2016-12-06 07:06:28 +00:00
bpos = 0;
for (i = 0; i < strlen(conf.archivers[gUser->defarchiver - 1]->unpack); i++) {
if (conf.archivers[gUser->defarchiver - 1]->unpack[i] == '*') {
2016-12-06 07:06:28 +00:00
i++;
if (conf.archivers[gUser->defarchiver - 1]->unpack[i] == 'a') {
2016-12-06 07:06:28 +00:00
sprintf(&buffer[bpos], "%s", upload_filename);
bpos = strlen(buffer);
} else if (conf.archivers[gUser->defarchiver - 1]->unpack[i] == 'd') {
sprintf(&buffer[bpos], "%s/node%d/bwave/", conf.bbs_path, mynode);
bpos = strlen(buffer);
} else if (conf.archivers[gUser->defarchiver - 1]->unpack[i] == '*') {
2016-12-06 07:06:28 +00:00
buffer[bpos++] = '*';
buffer[bpos] = '\0';
}
} else {
buffer[bpos++] = conf.archivers[gUser->defarchiver - 1]->unpack[i];
2016-12-06 07:06:28 +00:00
buffer[bpos] = '\0';
}
}
2016-12-11 12:14:36 +00:00
if (sshBBS) {
stout = dup(STDOUT_FILENO);
stin = dup(STDIN_FILENO);
sterr = dup(STDERR_FILENO);
2016-12-11 12:14:36 +00:00
dup2(bbs_stdout, STDOUT_FILENO);
dup2(bbs_stderr, STDERR_FILENO);
dup2(bbs_stdin, STDIN_FILENO);
}
args = split_on_space(buffer, NULL);
cmd = args[0];
2018-06-20 09:31:35 +00:00
pid = fork();
if (pid == 0) {
execvp(cmd, args);
exit(0);
} else if (pid > 0) {
waitpid(pid, &ret, 0);
} else {
ret = -1;
}
free(args);
2016-12-11 12:14:36 +00:00
if (sshBBS) {
2016-12-11 12:14:36 +00:00
dup2(stout, STDOUT_FILENO);
dup2(sterr, STDERR_FILENO);
2016-12-11 12:14:36 +00:00
dup2(stin, STDIN_FILENO);
2016-12-11 12:14:36 +00:00
close(stin);
close(stout);
close(sterr);
}
2016-12-06 07:06:28 +00:00
unlink(upload_filename);
snprintf(buffer, 1024, "%s/node%d/bwave/%s.UPL", conf.bbs_path, mynode, conf.bwave_name);
2016-12-06 07:06:28 +00:00
upl_file = fopen(buffer, "r");
2016-12-06 07:06:28 +00:00
if (!upl_file) {
snprintf(buffer, 1024, "%s/node%d/bwave/%s.upl", conf.bbs_path, mynode, conf.bwave_name);
2016-12-06 07:06:28 +00:00
upl_file = fopen(buffer, "r");
if (!upl_file) {
s_printf(get_string(196));
return;
}
}
2016-12-06 07:06:28 +00:00
if (!fread(&upl_hdr, sizeof(UPL_HEADER), 1, upl_file)) {
s_printf(get_string(196));
fclose(upl_file);
return;
2016-12-06 07:06:28 +00:00
}
2016-12-06 07:06:28 +00:00
while (fread(&upl_rec, sizeof(UPL_REC), 1, upl_file)) {
2018-01-07 22:54:03 +00:00
if (strcmp("PRIVATE_EMAIL", upl_rec.echotag) == 0) {
if (msg_attr & UPL_INACTIVE) {
continue;
}
2018-01-07 22:54:03 +00:00
if (strcasecmp(upl_rec.from, gUser->loginname) != 0) {
continue;
}
snprintf(msgbuffer, 1024, "%s/node%d/bwave/%s", conf.bbs_path, mynode, upl_rec.filename);
body = file2str(msgbuffer);
if (body == NULL) {
2018-01-07 22:54:03 +00:00
continue;
2016-12-06 07:06:28 +00:00
}
2018-01-07 22:54:03 +00:00
bpos = 0;
for (i = 0; i < strlen(body); i++) {
2018-01-07 22:54:03 +00:00
if (body[i] != '\n') {
body[bpos++] = body[i];
}
2016-12-06 07:06:28 +00:00
}
2018-01-07 22:54:03 +00:00
body[bpos] = '\0';
sprintf(buffer, "%s/email.sq3", conf.bbs_path);
rc = sqlite3_open(buffer, &db);
2018-01-07 22:54:03 +00:00
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) {
2018-01-07 22:54:03 +00:00
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);
msg_count++;
2018-01-07 22:54:03 +00:00
} else {
// find area
confr = -1;
area = -1;
for (i = 0; i < conf.mail_conference_count; i++) {
for (j = 0; j < conf.mail_conferences[i]->mail_area_count; j++) {
2018-01-07 22:54:03 +00:00
if (strcmp(conf.mail_conferences[i]->mail_areas[j]->qwkname, upl_rec.echotag) == 0) {
confr = i;
area = j;
break;
}
2016-12-06 07:06:28 +00:00
}
2018-01-07 22:54:03 +00:00
if (confr != -1) {
break;
2016-12-06 07:06:28 +00:00
}
2018-01-07 22:54:03 +00:00
}
2018-01-07 22:54:03 +00:00
if (confr != -1 && area != -1) {
// import message
if (conf.mail_conferences[confr]->mail_areas[area]->write_sec_level <= gUser->sec_level) {
msg_attr = converts(upl_rec.msg_attr);
2018-01-07 22:54:03 +00:00
if (msg_attr & UPL_INACTIVE) {
2016-12-06 07:06:28 +00:00
continue;
}
2018-01-07 22:54:03 +00:00
if (strcasecmp(upl_rec.from, gUser->loginname) != 0) {
2016-12-06 07:06:28 +00:00
continue;
}
2018-01-07 22:54:03 +00:00
addr.zone = 0;
addr.net = 0;
addr.node = 0;
addr.zone = 0;
2018-01-07 22:54:03 +00:00
if (conf.mail_conferences[confr]->mail_areas[area]->type == TYPE_NETMAIL_AREA) {
if (!(msg_attr & UPL_NETMAIL)) {
continue;
}
addr.zone = converts(upl_rec.destzone);
addr.net = converts(upl_rec.destnet);
addr.node = converts(upl_rec.destnode);
addr.zone = converts(upl_rec.destpoint);
netmail = 1;
} else if (conf.mail_conferences[confr]->mail_areas[area]->type == TYPE_ECHOMAIL_AREA || conf.mail_conferences[confr]->mail_areas[area]->type == TYPE_NEWSGROUP_AREA) {
if (msg_attr & UPL_PRIVATE) {
continue;
}
echomail = 1;
} else { // Local area
if (msg_attr & UPL_PRIVATE) {
continue;
}
2018-01-07 22:54:03 +00:00
}
2018-01-07 22:54:03 +00:00
snprintf(msgbuffer, 1024, "%s/node%d/bwave/%s", conf.bbs_path, mynode, upl_rec.filename);
2018-01-07 22:54:03 +00:00
if (conf.mail_conferences[confr]->tagline != NULL) {
tagline = conf.mail_conferences[confr]->tagline;
2016-12-06 07:06:28 +00:00
} else {
2018-01-07 22:54:03 +00:00
tagline = conf.default_tagline;
}
2018-01-07 22:54:03 +00:00
if (conf.mail_conferences[confr]->nettype == NETWORK_FIDO) {
if (conf.mail_conferences[confr]->fidoaddr->point == 0) {
snprintf(originlinebuffer, 256, "\r--- %s\r * Origin: %s (%d:%d/%d)\r", upl_hdr.reader_tear, tagline, conf.mail_conferences[confr]->fidoaddr->zone,
conf.mail_conferences[confr]->fidoaddr->net,
conf.mail_conferences[confr]->fidoaddr->node);
2018-01-07 22:54:03 +00:00
} else {
2018-01-07 22:54:03 +00:00
snprintf(originlinebuffer, 256, "\r--- %s\r * Origin: %s (%d:%d/%d.%d)\r", upl_hdr.reader_tear, tagline, conf.mail_conferences[confr]->fidoaddr->zone,
conf.mail_conferences[confr]->fidoaddr->net,
conf.mail_conferences[confr]->fidoaddr->node,
conf.mail_conferences[confr]->fidoaddr->point);
2018-01-07 22:54:03 +00:00
}
2018-05-22 11:02:22 +00:00
} else if (conf.mail_conferences[confr]->nettype == NETWORK_MAGI) {
snprintf(originlinebuffer, 256, "\r--- %s\r * Origin: %s (@%d)\r", upl_hdr.reader_tear, tagline, conf.mail_conferences[confr]->maginode);
2018-06-24 00:28:18 +00:00
} else if (conf.mail_conferences[confr]->nettype == NETWORK_QWK) {
snprintf(originlinebuffer, 256, "\r--- $s\r * Origin: %s (%s)\r", upl_hdr.reader_tear, tagline, conf.bwave_name);
2018-01-07 22:54:03 +00:00
} else {
2018-05-22 11:02:22 +00:00
snprintf(originlinebuffer, 256, "\r");
2016-12-06 07:06:28 +00:00
}
sa = file2stralloc(msgbuffer);
if (sa.s == NULL) {
2018-01-07 22:54:03 +00:00
continue;
2016-12-06 07:06:28 +00:00
}
stralloc_cats(&sa, originlinebuffer);
stralloc_0(&sa);
body = sa.s;
char *p, *s;
for (p = s = body; *p != '\0'; ++p) {
if (*p != '\n')
*s++ = *p;
2018-01-07 22:54:03 +00:00
}
*s = '\0';
2018-01-07 22:54:03 +00:00
if (bwave_add_message(confr, area, convertl(upl_rec.unix_date), upl_rec.to, upl_rec.subj, &addr, body) != 0) {
// failed to add message
s_printf(get_string(197));
} else {
msg_count++;
}
2018-01-07 22:54:03 +00:00
free(body);
2016-12-06 07:06:28 +00:00
}
}
}
}
2018-01-07 22:54:03 +00:00
snprintf(buffer, 1024, "%s/node%d/bwave/", conf.bbs_path, mynode);
recursive_delete(buffer);
if (netmail == 1) {
if (conf.netmail_sem != NULL) {
sem_fd = open(conf.netmail_sem, O_RDWR | O_CREAT | O_TRUNC, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
close(sem_fd);
}
}
if (echomail == 1) {
if (conf.echomail_sem != NULL) {
sem_fd = open(conf.echomail_sem, O_RDWR | O_CREAT | O_TRUNC, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
close(sem_fd);
}
}
2016-12-06 07:06:28 +00:00
s_printf("\r\n");
if (msg_count > 0) {
s_printf(get_string(204), msg_count);
}
2016-12-06 07:06:28 +00:00
s_printf(get_string(6));
s_getc();
}