jcs
/subtext
/amendments
/317
mail: Move to separate bile database
This should reduce the likelihood of corrupting the main user
database.
jcs made amendment 317 about 1 year ago
--- db.c Wed Feb 22 20:47:37 2023
+++ db.c Thu Feb 23 17:07:31 2023
@@ -108,7 +108,7 @@ struct struct_field config_fields[] = {
size_t nconfig_fields = nitems(config_fields);
struct db * db_init(Str255 file, short vrefnum, struct bile *bile);
-short db_migrate(struct db *tdb, short is_new);
+short db_migrate(struct db *tdb, short is_new, Str255 basepath);
void db_config_load(struct db *tdb);
struct db *
@@ -184,7 +184,7 @@ db_create(void)
struct db *
db_init(Str255 path, short vrefnum, struct bile *bile)
{
- Str255 fullpath;
+ Str255 fullpath, newfullpath;
struct db *tdb;
Handle lastfileh;
short was_new;
@@ -229,7 +229,7 @@ db_init(Str255 path, short vrefnum, struct bile *bile)
tdb = xmalloczero(sizeof(struct db), "db_init db");
tdb->bile = bile;
- if (db_migrate(tdb, was_new) != 0) {
+ if (db_migrate(tdb, was_new, fullpath) != 0) {
bile_close(tdb->bile);
xfree(&tdb);
return NULL;
@@ -241,19 +241,34 @@ db_init(Str255 path, short vrefnum, struct bile *bile)
db_cache_folders(tdb);
}
- PtoCstr(fullpath);
- strlcat((char *)&fullpath, "-sessions", sizeof(fullpath));
- CtoPstr(fullpath);
+ memcpy(newfullpath, fullpath, sizeof(newfullpath));
+ PtoCstr(newfullpath);
+ strlcat((char *)&newfullpath, "-sessions", sizeof(newfullpath));
+ CtoPstr(newfullpath);
- tdb->sessions_bile = bile_open(fullpath, vrefnum);
+ tdb->sessions_bile = bile_open(newfullpath, vrefnum);
if (tdb->sessions_bile == NULL) {
- tdb->sessions_bile = bile_create(fullpath, vrefnum,
+ tdb->sessions_bile = bile_create(newfullpath, vrefnum,
SUBTEXT_CREATOR, SL_TYPE);
if (tdb->sessions_bile == NULL)
- panic("Couldn't create %s: %d", PtoCstr(fullpath),
+ panic("Couldn't create %s: %d", PtoCstr(newfullpath),
bile_error(NULL));
}
+
+ memcpy(newfullpath, fullpath, sizeof(newfullpath));
+ PtoCstr(newfullpath);
+ strlcat((char *)&newfullpath, "-mail", sizeof(newfullpath));
+ CtoPstr(newfullpath);
+ tdb->mail_bile = bile_open(newfullpath, vrefnum);
+ if (tdb->mail_bile == NULL) {
+ tdb->mail_bile = bile_create(newfullpath, vrefnum,
+ SUBTEXT_CREATOR, MAIL_SPOOL_TYPE);
+ if (tdb->mail_bile == NULL)
+ panic("Couldn't create %s: %d", PtoCstr(newfullpath),
+ bile_error(NULL));
+ }
+
return tdb;
}
@@ -270,6 +285,11 @@ db_close(struct db *tdb)
xfree(&tdb->sessions_bile);
}
+ if (tdb->mail_bile != NULL) {
+ bile_close(tdb->mail_bile);
+ xfree(&tdb->mail_bile);
+ }
+
if (tdb->boards) {
for (n = 0; n < tdb->nboards; n++) {
if (tdb->boards[n].bile)
@@ -290,7 +310,7 @@ db_close(struct db *tdb)
}
short
-db_migrate(struct db *tdb, short is_new)
+db_migrate(struct db *tdb, short is_new, Str255 fullpath)
{
struct user *user;
struct db *olddb;
@@ -315,6 +335,8 @@ db_migrate(struct db *tdb, short is_new)
tdb->config.blanker_idle_seconds = (60 * 60);
tdb->config.blanker_runtime_seconds = 30;
tdb->config.session_log_days = 21;
+ tdb->config.binkp_port = 24554;
+ tdb->config.binkp_interval_seconds = (60 * 60 * 3);
db_config_save(tdb);
/* create a default sysop user */
@@ -555,6 +577,49 @@ db_migrate(struct db *tdb, short is_new)
bile_write(tdb->bile, DB_CONFIG_RTYPE, 1, &new_config,
sizeof(new_config));
+ break;
+ }
+ case 13: {
+ /* 13->14, move mail to separate db */
+ Str255 newfullpath;
+ struct bile *mail_bile;
+ struct bile_object *o;
+ size_t n, size, id;
+ char *data;
+
+ memcpy(newfullpath, fullpath, sizeof(newfullpath));
+ PtoCstr(newfullpath);
+ strlcat((char *)&newfullpath, "-mail", sizeof(newfullpath));
+ CtoPstr(newfullpath);
+
+ mail_bile = bile_create(newfullpath, tdb->bile->vrefnum,
+ SUBTEXT_CREATOR, MAIL_SPOOL_TYPE);
+ if (mail_bile == NULL)
+ panic("Couldn't create %s: %d", PtoCstr(newfullpath),
+ bile_error(NULL));
+
+ for (n = 0; (o = bile_get_nth_of_type(tdb->bile, n,
+ MAIL_SPOOL_MESSAGE_RTYPE)); n++) {
+ size = bile_read_alloc(tdb->bile, o->type, o->id,
+ &data);
+ bile_write(mail_bile, o->type, o->id, data, size);
+
+ xfree(&data);
+ xfree(&o);
+ }
+
+ bile_flush(mail_bile, true);
+
+ /* now we can actually delete mail */
+ while ((o = bile_get_nth_of_type(tdb->bile, 0,
+ MAIL_SPOOL_MESSAGE_RTYPE))) {
+ id = o->id;
+ xfree(&o);
+ bile_delete(tdb->bile, MAIL_SPOOL_MESSAGE_RTYPE, id, 0);
+ }
+ bile_write_map(tdb->bile);
+ bile_close(mail_bile);
+
break;
}
}
--- db.h Wed Feb 22 17:54:51 2023
+++ db.h Thu Feb 23 16:34:03 2023
@@ -23,7 +23,7 @@
#define DB_TYPE 'STDB'
-#define DB_CUR_VERS 13
+#define DB_CUR_VERS 14
#define DB_TRUE 0x100
#define DB_FALSE 0x000
@@ -33,7 +33,6 @@
#define DB_BOARD_RTYPE 'BORD'
#define DB_FOLDER_RTYPE 'FOLD'
#define DB_VERS_RTYPE 'VERS'
-#define DB_MESSAGE_RTYPE 'PMSG'
#define DB_MOTD_RTYPE 'MOTD'
#define DB_TEXT_TYPE 'TEXT'
@@ -59,6 +58,9 @@
#define FOLDER_FILENAME_EXT "fld"
#define FOLDER_FILE_RTYPE 'FILE'
+#define MAIL_SPOOL_TYPE 'STMS'
+#define MAIL_SPOOL_MESSAGE_RTYPE 'PMSG'
+
#include "subtext.h"
#include "bile.h"
#include "board.h"
@@ -105,6 +107,7 @@ struct db {
short nboards;
struct folder *folders;
short nfolders;
+ struct bile *mail_bile;
};
struct db * db_open(Str255 file, short vrefnum);
--- mail.c Wed Feb 22 21:51:55 2023
+++ mail.c Thu Feb 23 14:33:34 2023
@@ -416,11 +416,11 @@ mail_list(struct session *s, size_t nmail_ids, unsigne
session_flush(s);
for (n = 0; n < nmail_ids; n++) {
- size = bile_read_alloc(db->bile, DB_MESSAGE_RTYPE, mail_ids[n],
- &data);
+ size = bile_read_alloc(db->mail_bile, MAIL_SPOOL_MESSAGE_RTYPE,
+ mail_ids[n], &data);
if (size == 0)
break;
- bile_unmarshall_object(db->bile, mail_object_fields,
+ bile_unmarshall_object(db->mail_bile, mail_object_fields,
nitems(mail_object_fields), data, size, &msg, sizeof(msg), true,
"mail_list");
xfree(&data);
@@ -465,14 +465,15 @@ mail_read(struct session *s, unsigned long id, short i
bool done = false, show_help = false;
char c;
- size = bile_read_alloc(db->bile, DB_MESSAGE_RTYPE, id, &data);
+ size = bile_read_alloc(db->mail_bile, MAIL_SPOOL_MESSAGE_RTYPE, id,
+ &data);
if (size == 0) {
session_printf(s, "{{B}}Error:{{/B}} Can't find message\r\n");
session_flush(s);
return MAIL_READ_RETURN_DONE;
}
- bile_unmarshall_object(db->bile, mail_object_fields,
+ bile_unmarshall_object(db->mail_bile, mail_object_fields,
nitems(mail_object_fields), data, size, &msg, sizeof(msg), true,
"mail_read");
xfree(&data);
@@ -528,12 +529,13 @@ mail_read(struct session *s, unsigned long id, short i
xfree(&reply_subject);
break;
case 'd':
- if (bile_delete(db->bile, DB_MESSAGE_RTYPE, msg.id,
+ if (bile_delete(db->mail_bile, MAIL_SPOOL_MESSAGE_RTYPE, msg.id,
BILE_DELETE_FLAG_ZERO | BILE_DELETE_FLAG_PURGE) == 0)
session_printf(s, "Deleted message {{B}}%d{{/B}}\r\n", idx);
else
session_printf(s, "Failed deleting message "
- "{{B}}%d{{/B}}! (%d)\r\n", idx, bile_error(db->bile));
+ "{{B}}%d{{/B}}! (%d)\r\n", idx,
+ bile_error(db->mail_bile));
ret = MAIL_READ_RETURN_FIND;
done = true;
break;
@@ -544,7 +546,8 @@ mail_read(struct session *s, unsigned long id, short i
idx);
else
session_printf(s, "Failed updating message "
- "{{B}}%d{{/B}}! (%d)\r\n", idx, bile_error(db->bile));
+ "{{B}}%d{{/B}}! (%d)\r\n", idx,
+ bile_error(db->mail_bile));
ret = MAIL_READ_RETURN_DONE;
done = true;
break;
@@ -575,19 +578,19 @@ mail_save(struct session *s, struct mail_message *msg)
short ret;
if (!msg->id)
- msg->id = bile_next_id(db->bile, DB_MESSAGE_RTYPE);
+ msg->id = bile_next_id(db->mail_bile, MAIL_SPOOL_MESSAGE_RTYPE);
- ret = bile_marshall_object(db->bile, mail_object_fields,
+ ret = bile_marshall_object(db->mail_bile, mail_object_fields,
nitems(mail_object_fields), msg, &data, &size, "mail_save");
if (ret != 0 || size == 0) {
warn("mail_save: failed to marshall object");
return -1;
}
- if (bile_write(db->bile, DB_MESSAGE_RTYPE, msg->id, data,
+ if (bile_write(db->mail_bile, MAIL_SPOOL_MESSAGE_RTYPE, msg->id, data,
size) != size) {
- warn("mail_save: bile_write failed! %d", bile_error(db->bile));
- return bile_error(db->bile);
+ warn("mail_save: bile_write failed! %d", bile_error(db->mail_bile));
+ return bile_error(db->mail_bile);
}
return 0;
@@ -612,19 +615,20 @@ mail_find_ids_for_user(struct user *user, size_t *nmai
*nmail_ids = 0;
nmsgs_for_user = 0;
- for (n = 0; (o = bile_get_nth_of_type(db->bile, n, DB_MESSAGE_RTYPE));
- n++) {
+ for (n = 0; (o = bile_get_nth_of_type(db->mail_bile, n,
+ MAIL_SPOOL_MESSAGE_RTYPE)); n++) {
id = o->id;
- bile_read(db->bile, DB_MESSAGE_RTYPE, id, (char *)&msg_user_id,
- sizeof(msg_user_id));
+ bile_read(db->mail_bile, MAIL_SPOOL_MESSAGE_RTYPE, id,
+ (char *)&msg_user_id, sizeof(msg_user_id));
xfree(&o);
if (msg_user_id != user->id)
continue;
if (only_unread) {
- size = bile_read_alloc(db->bile, DB_MESSAGE_RTYPE, id, &data);
- bile_unmarshall_object(db->bile, mail_object_fields,
+ size = bile_read_alloc(db->mail_bile, MAIL_SPOOL_MESSAGE_RTYPE,
+ id, &data);
+ bile_unmarshall_object(db->mail_bile, mail_object_fields,
nmail_object_fields, data, size, &msg, sizeof(msg), false,
"mail_find_ids_for_user");
xfree(&data);
--- user.c Thu Feb 16 14:33:06 2023
+++ user.c Thu Feb 23 14:26:43 2023
@@ -387,10 +387,11 @@ user_delete(struct user *user)
/* delete the user's mail */
n = 0;
- while ((o = bile_get_nth_of_type(db->bile, n, DB_MESSAGE_RTYPE))) {
+ while ((o = bile_get_nth_of_type(db->mail_bile, n,
+ MAIL_SPOOL_MESSAGE_RTYPE))) {
id = o->id;
- bile_read(db->bile, DB_MESSAGE_RTYPE, id, (char *)&msg_user_id,
- sizeof(msg_user_id));
+ bile_read(db->mail_bile, MAIL_SPOOL_MESSAGE_RTYPE, id,
+ (char *)&msg_user_id, sizeof(msg_user_id));
xfree(&o);
if (msg_user_id != user->id) {
@@ -398,7 +399,7 @@ user_delete(struct user *user)
continue;
}
- bile_delete(db->bile, DB_MESSAGE_RTYPE, id,
+ bile_delete(db->mail_bile, MAIL_SPOOL_MESSAGE_RTYPE, id,
BILE_DELETE_FLAG_ZERO | BILE_DELETE_FLAG_PURGE);
/* don't increase n, the remaining messages will shift down */