Experimental Subscription
This commit is contained in:
parent
93758c24f2
commit
934763a3c2
3
bbs.h
3
bbs.h
@ -252,6 +252,8 @@ extern int check_user(char *loginname);
|
|||||||
extern struct user_record *new_user();
|
extern struct user_record *new_user();
|
||||||
extern struct user_record *check_user_pass(char *loginname, char *password);
|
extern struct user_record *check_user_pass(char *loginname, char *password);
|
||||||
extern void list_users(struct user_record *user);
|
extern void list_users(struct user_record *user);
|
||||||
|
extern int msgbase_sub_unsub(int conference, int msgbase);
|
||||||
|
extern int msgbase_is_subscribed(int conference, int msgbase);
|
||||||
|
|
||||||
extern void active_nodes();
|
extern void active_nodes();
|
||||||
extern void send_node_msg();
|
extern void send_node_msg();
|
||||||
@ -277,6 +279,7 @@ extern void prev_mail_conf(struct user_record *user);
|
|||||||
extern void next_mail_area(struct user_record *user);
|
extern void next_mail_area(struct user_record *user);
|
||||||
extern void prev_mail_area(struct user_record *user);
|
extern void prev_mail_area(struct user_record *user);
|
||||||
extern void post_message(struct user_record *user);
|
extern void post_message(struct user_record *user);
|
||||||
|
extern void msg_conf_sub_bases();
|
||||||
|
|
||||||
extern void rundoor(struct user_record *user, char *cmd, int stdio, char *codepage);
|
extern void rundoor(struct user_record *user, char *cmd, int stdio, char *codepage);
|
||||||
extern void runexternal(struct user_record *user, char *cmd, int stdio, char **argv, char *cwd, int raw, char *codepage);
|
extern void runexternal(struct user_record *user, char *cmd, int stdio, char **argv, char *cwd, int raw, char *codepage);
|
||||||
|
19
bluewave.c
19
bluewave.c
@ -217,9 +217,24 @@ void bwave_create_packet() {
|
|||||||
FILE *fti_file;
|
FILE *fti_file;
|
||||||
FILE *dat_file;
|
FILE *dat_file;
|
||||||
FILE *inf_file;
|
FILE *inf_file;
|
||||||
|
int tot_areas = 0;
|
||||||
int totmsgs = 0;
|
int totmsgs = 0;
|
||||||
|
|
||||||
|
for (i=0;i<conf.mail_conference_count;i++) {
|
||||||
|
for (j=0;j<conf.mail_conferences[i]->mail_area_count;j++) {
|
||||||
|
if (msgbase_is_subscribed(i, j)) {
|
||||||
|
tot_areas++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tot_areas == 0) {
|
||||||
|
s_printf(get_string(224));
|
||||||
|
s_printf(get_string(6));
|
||||||
|
s_getchar();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
area_count = 0;
|
area_count = 0;
|
||||||
|
|
||||||
memset(&hdr, 0, sizeof(INF_HEADER));
|
memset(&hdr, 0, sizeof(INF_HEADER));
|
||||||
@ -270,7 +285,7 @@ void bwave_create_packet() {
|
|||||||
|
|
||||||
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) {
|
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;
|
lasttot = totmsgs;
|
||||||
totmsgs = bwave_scan_area(i, j, area_count+1, totmsgs, fti_file, mix_file, dat_file, &last_ptr);
|
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);
|
s_printf(get_string(195), conf.mail_conferences[i]->name, conf.mail_conferences[i]->mail_areas[j]->name, totmsgs - lasttot);
|
||||||
|
@ -222,3 +222,8 @@ File exists!\r\n
|
|||||||
\e[0;36mC. \e[1;37mCodepage (\e[1;33m%s\e[1;37m)\r\n
|
\e[0;36mC. \e[1;37mCodepage (\e[1;33m%s\e[1;37m)\r\n
|
||||||
\e[0;36mE. \e[1;37mUse External Editor (\e[1;33m%s\e[1;37m)\r\n
|
\e[0;36mE. \e[1;37mUse External Editor (\e[1;33m%s\e[1;37m)\r\n
|
||||||
\e[1;37mMore? (Y/N/C) \e[0m
|
\e[1;37mMore? (Y/N/C) \e[0m
|
||||||
|
\e[1;31mYou have not subscribed to any areas!\e[0m\r\n
|
||||||
|
\e[1;37mPlease enter an area number to toggle, or hit enter to continue: \e[0m
|
||||||
|
\e[1;30m[\e[1;37m%3d\e[1;30m] [%s\e[1;30m] \e[1;37m%s\e[0m\r\n
|
||||||
|
\e[1;32mSUB\e[0m
|
||||||
|
\e[1;31mUNSUB\e[0m
|
||||||
|
47
mail_menu.c
47
mail_menu.c
@ -2630,3 +2630,50 @@ void mail_scan(struct user_record *user) {
|
|||||||
s_getc();
|
s_getc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void msg_conf_sub_bases() {
|
||||||
|
int i;
|
||||||
|
int lines = 0;
|
||||||
|
char buffer[10];
|
||||||
|
int toggle_area;
|
||||||
|
int done = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
for (i=0;i<conf.mail_conferences[gUser->cur_mail_conf]->mail_area_count;i++) {
|
||||||
|
if (conf.mail_conferences[gUser->cur_mail_conf]->mail_areas[i]->read_sec_level <= gUser->sec_level) {
|
||||||
|
s_printf(get_string(226), i, (msgbase_is_subscribed(gUser->cur_mail_conf, i) ? get_string(227) : get_string(228)), conf.mail_conferences[gUser->cur_mail_conf]->mail_areas[i]->name);
|
||||||
|
lines++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lines == 23) {
|
||||||
|
s_printf(get_string(225));
|
||||||
|
s_readstring(buffer, 9);
|
||||||
|
s_printf("\r\n");
|
||||||
|
if (strlen(buffer) > 0) {
|
||||||
|
toggle_area = atoi(buffer);
|
||||||
|
msgbase_sub_unsub(gUser->cur_mail_conf, i);
|
||||||
|
lines = 0;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lines = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lines > 0) {
|
||||||
|
s_printf(get_string(225));
|
||||||
|
s_readstring(buffer, 9);
|
||||||
|
s_printf("\r\n");
|
||||||
|
if (strlen(buffer) > 0) {
|
||||||
|
toggle_area = atoi(buffer);
|
||||||
|
msgbase_sub_unsub(gUser->cur_mail_conf, i);
|
||||||
|
lines = 0;
|
||||||
|
} else {
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
} while (!done);
|
||||||
|
}
|
||||||
|
6
menus.c
6
menus.c
@ -46,6 +46,7 @@
|
|||||||
#define MENU_LISTMESSAGES 36
|
#define MENU_LISTMESSAGES 36
|
||||||
#define MENU_DOSCRIPT 37
|
#define MENU_DOSCRIPT 37
|
||||||
#define MENU_SENDNODEMSG 38
|
#define MENU_SENDNODEMSG 38
|
||||||
|
#define MENU_SUBUNSUBCONF 39
|
||||||
|
|
||||||
extern struct bbs_config conf;
|
extern struct bbs_config conf;
|
||||||
extern struct user_record *gUser;
|
extern struct user_record *gUser;
|
||||||
@ -187,6 +188,8 @@ int menu_system(char *menufile) {
|
|||||||
menu[menu_items-1]->command = MENU_DOSCRIPT;
|
menu[menu_items-1]->command = MENU_DOSCRIPT;
|
||||||
} else if (strncasecmp(&buffer[8], "SENDNODEMSG", 11) == 0) {
|
} else if (strncasecmp(&buffer[8], "SENDNODEMSG", 11) == 0) {
|
||||||
menu[menu_items-1]->command = MENU_SENDNODEMSG;
|
menu[menu_items-1]->command = MENU_SENDNODEMSG;
|
||||||
|
} else if (strncasecmp(&buffer[8], "SUBUNSUBCONF", 12) == 0) {
|
||||||
|
menu[menu_items-1]->command = MENU_SUBUNSUBCONF;
|
||||||
}
|
}
|
||||||
} else if (strncasecmp(buffer, "SECLEVEL", 8) == 0) {
|
} else if (strncasecmp(buffer, "SECLEVEL", 8) == 0) {
|
||||||
menu[menu_items-1]->seclevel = atoi(&buffer[9]);
|
menu[menu_items-1]->seclevel = atoi(&buffer[9]);
|
||||||
@ -468,6 +471,9 @@ int menu_system(char *menufile) {
|
|||||||
case MENU_SENDNODEMSG:
|
case MENU_SENDNODEMSG:
|
||||||
send_node_msg();
|
send_node_msg();
|
||||||
break;
|
break;
|
||||||
|
case MENU_SUBUNSUBCONF:
|
||||||
|
msg_conf_sub_bases();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -49,3 +49,7 @@ COMMAND BLUEWAVEDOWNLOAD
|
|||||||
|
|
||||||
HOTKEY U
|
HOTKEY U
|
||||||
COMMAND BLUEWAVEUPLOAD
|
COMMAND BLUEWAVEUPLOAD
|
||||||
|
|
||||||
|
HOTKEY S
|
||||||
|
COMMAND SUBUNSUBCONF
|
||||||
|
|
||||||
|
106
users.c
106
users.c
@ -8,6 +8,7 @@
|
|||||||
#include "inih/ini.h"
|
#include "inih/ini.h"
|
||||||
|
|
||||||
extern struct bbs_config conf;
|
extern struct bbs_config conf;
|
||||||
|
extern struct user_record *gUser;
|
||||||
|
|
||||||
char *hash_sha256(char *pass, char *salt) {
|
char *hash_sha256(char *pass, char *salt) {
|
||||||
char *buffer = (char *)malloc(strlen(pass) + strlen(salt) + 1);
|
char *buffer = (char *)malloc(strlen(pass) + strlen(salt) + 1);
|
||||||
@ -93,7 +94,7 @@ int save_user(struct user_record *user) {
|
|||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
sqlite3_busy_timeout(db, 5000);
|
sqlite3_busy_timeout(db, 5000);
|
||||||
rc = sqlite3_prepare_v2(db, update_sql, -1, &res, 0);
|
rc = sqlite3_prepare_v2(db, update_sql, -1, &res, 0);
|
||||||
|
|
||||||
if (rc == SQLITE_OK) {
|
if (rc == SQLITE_OK) {
|
||||||
@ -136,8 +137,101 @@ sqlite3_busy_timeout(db, 5000);
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int msgbase_sub_unsub(int conference, int msgbase) {
|
||||||
|
sqlite3 *db;
|
||||||
|
sqlite3_stmt *res;
|
||||||
|
int rc;
|
||||||
|
char buffer[PATH_MAX];
|
||||||
|
char *create_sql = "CREATE TABLE IF NOT EXISTS msg_subs (conference INTEGER, msgbase INTEGER, uid INTEGER);";
|
||||||
|
char *sub_buf = "INSERT INTO msg_subs (conference, msgbase, uid) VALUES(?, ?, ?)";
|
||||||
|
char *unsub_buf = "DELETE FROM msg_subs WHERE conference=? AND msgbase=? AND uid=?";
|
||||||
|
char *err_msg = 0;
|
||||||
|
int subunsub = 0;
|
||||||
|
|
||||||
|
|
||||||
|
subunsub = msgbase_is_subscribed(conference, msgbase);
|
||||||
|
|
||||||
|
snprintf(buffer, PATH_MAX, "%s/users.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 0;
|
||||||
|
}
|
||||||
|
sqlite3_busy_timeout(db, 5000);
|
||||||
|
rc = sqlite3_exec(db, create_sql, 0, 0, &err_msg);
|
||||||
|
if (rc != SQLITE_OK ) {
|
||||||
|
|
||||||
|
dolog("SQL error: %s", err_msg);
|
||||||
|
|
||||||
|
sqlite3_free(err_msg);
|
||||||
|
sqlite3_close(db);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (subunsub == 1) {
|
||||||
|
rc = sqlite3_prepare_v2(db, unsub_buf, -1, &res, 0);
|
||||||
|
} else {
|
||||||
|
rc = sqlite3_prepare_v2(db, sub_buf, -1, &res, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_bind_int(res, 1, conference);
|
||||||
|
sqlite3_bind_int(res, 2, msgbase);
|
||||||
|
sqlite3_bind_int(res, 3, gUser->id);
|
||||||
|
|
||||||
|
sqlite3_step(res);
|
||||||
|
|
||||||
|
sqlite3_finalize(res);
|
||||||
|
sqlite3_close(db);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int msgbase_is_subscribed(int conference, int msgbase) {
|
||||||
|
sqlite3 *db;
|
||||||
|
sqlite3_stmt *res;
|
||||||
|
int rc;
|
||||||
|
char buffer[PATH_MAX];
|
||||||
|
|
||||||
|
char *sql_buf = "SELECT * FROM msg_subs WHERE conference=? AND msgbase=? AND uid=?";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
snprintf(buffer, PATH_MAX, "%s/users.sq3", conf.bbs_path);
|
||||||
|
if (rc != SQLITE_OK) {
|
||||||
|
dolog("Cannot open database: %s", sqlite3_errmsg(db));
|
||||||
|
sqlite3_close(db);
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
sqlite3_busy_timeout(db, 5000);
|
||||||
|
|
||||||
|
rc = sqlite3_prepare_v2(db, sql_buf, -1, &res, 0);
|
||||||
|
|
||||||
|
if (rc != SQLITE_OK) {
|
||||||
|
sqlite3_close(db);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_bind_int(res, 1, conference);
|
||||||
|
sqlite3_bind_int(res, 2, msgbase);
|
||||||
|
sqlite3_bind_int(res, 3, gUser->id);
|
||||||
|
|
||||||
|
if (sqlite3_step(res) != SQLITE_ROW) {
|
||||||
|
sqlite3_finalize(res);
|
||||||
|
sqlite3_close(db);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
sqlite3_finalize(res);
|
||||||
|
sqlite3_close(db);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int inst_user(struct user_record *user) {
|
int inst_user(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;
|
||||||
@ -169,7 +263,7 @@ int inst_user(struct user_record *user) {
|
|||||||
"lastname, email, location, sec_level, last_on, time_left, cur_mail_conf, cur_mail_area, cur_file_dir, cur_file_sub, times_on, bwavepktno, archiver, protocol, nodemsgs, codepage, exteditor) VALUES(?,?, ?,?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
"lastname, email, location, sec_level, last_on, time_left, cur_mail_conf, cur_mail_area, cur_file_dir, cur_file_sub, times_on, bwavepktno, archiver, protocol, nodemsgs, codepage, exteditor) VALUES(?,?, ?,?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||||
char *err_msg = 0;
|
char *err_msg = 0;
|
||||||
|
|
||||||
sprintf(buffer, "%s/users.sq3", conf.bbs_path);
|
snprintf(buffer, PATH_MAX, "%s/users.sq3", conf.bbs_path);
|
||||||
|
|
||||||
rc = sqlite3_open(buffer, &db);
|
rc = sqlite3_open(buffer, &db);
|
||||||
|
|
||||||
@ -179,7 +273,7 @@ int inst_user(struct user_record *user) {
|
|||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
sqlite3_busy_timeout(db, 5000);
|
sqlite3_busy_timeout(db, 5000);
|
||||||
rc = sqlite3_exec(db, create_sql, 0, 0, &err_msg);
|
rc = sqlite3_exec(db, create_sql, 0, 0, &err_msg);
|
||||||
if (rc != SQLITE_OK ) {
|
if (rc != SQLITE_OK ) {
|
||||||
|
|
||||||
@ -188,7 +282,7 @@ sqlite3_busy_timeout(db, 5000);
|
|||||||
sqlite3_free(err_msg);
|
sqlite3_free(err_msg);
|
||||||
sqlite3_close(db);
|
sqlite3_close(db);
|
||||||
|
|
||||||
return 1;
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = sqlite3_prepare_v2(db, insert_sql, -1, &res, 0);
|
rc = sqlite3_prepare_v2(db, insert_sql, -1, &res, 0);
|
||||||
@ -217,6 +311,8 @@ sqlite3_busy_timeout(db, 5000);
|
|||||||
sqlite3_bind_int(res, 21, user->exteditor);
|
sqlite3_bind_int(res, 21, user->exteditor);
|
||||||
} else {
|
} else {
|
||||||
dolog("Failed to execute statement: %s", sqlite3_errmsg(db));
|
dolog("Failed to execute statement: %s", sqlite3_errmsg(db));
|
||||||
|
sqlite3_close(db);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user