AmendHub

Download:

jcs

/

subtext

/

amendments

/

107

*: Lots of deck chair rearranging

Move things from db files to their respective areas
 
Make username map contain normal username, just do strcasecmp check
during user_find_by_username.

jcs made amendment 107 about 1 year ago
--- db.c Sun May 15 21:48:28 2022 +++ db.c Mon May 23 13:10:11 2022 @@ -19,6 +19,7 @@ #include <time.h> #include "subtext.h" +#include "board.h" #include "bile.h" #include "db.h" #include "user.h" @@ -52,32 +53,9 @@ struct struct_field config_fields[] = { }; size_t nconfig_fields = nitems(config_fields); -struct struct_field board_fields[] = { - { "Board ID", CONFIG_TYPE_LONG, - offsetof(struct board, id), - 1, ULONG_MAX }, - { "Name", CONFIG_TYPE_STRING, - offsetof(struct board, name), - 1, member_size(struct board, name) }, - { "Description", CONFIG_TYPE_STRING, - offsetof(struct board, description), - 0, member_size(struct board, description) }, - { "Restricted Posting", CONFIG_TYPE_BOOLEAN, - offsetof(struct board, restricted_posting), - 0, 0 }, - { "Restricted Viewing", CONFIG_TYPE_BOOLEAN, - offsetof(struct board, restricted_viewing), - 0, 0 }, - { "Days of Retention", CONFIG_TYPE_SHORT, - offsetof(struct board, retention_days), - 0, USHRT_MAX }, -}; -size_t nboard_fields = nitems(board_fields); - struct db * db_init(Str255 file, short vrefnum, struct bile *bile); short db_migrate(struct db *tdb, short is_new); void db_config_load(struct db *tdb); -void db_boards_load(struct db *tdb); struct db * db_open(Str255 file, short vrefnum) @@ -197,7 +175,7 @@ db_init(Str255 path, short vrefnum, struct bile *bile) if (!was_new) { db_config_load(tdb); - db_boards_load(tdb); + db_cache_boards(tdb); } PtoCstr(fullpath); @@ -233,6 +211,7 @@ db_migrate(struct db *tdb, short is_new) { struct user *user; struct bile_object *bob; + struct db *olddb; char *error; char ver; @@ -256,7 +235,11 @@ db_migrate(struct db *tdb, short is_new) user->created_at = Time; user_set_password(user, "p4ssw0rd"); user->is_sysop = DB_TRUE; + /* user_save assumes db is already set */ + olddb = db; + db = tdb; user_save(user); + db = olddb; } else { if (bile_read(tdb->bile, DB_VERS_RTYPE, 1, &ver, 1) != 1) ver = 1; @@ -307,46 +290,82 @@ db_config_load(struct db *tdb) } void -db_boards_load(struct db *tdb) +db_cache_boards(struct db *tdb) { - size_t n; + Str255 db_filename, board_filename; + size_t n, size; struct bile_object *obj; + char *data = NULL; if (tdb->boards) { + for (n = 0; n < tdb->nboards; n++) { + if (tdb->boards[n].bile) + bile_close(tdb->boards[n].bile); + } free(tdb->boards); - tdb->boards = NULL; } + + if (getpath(tdb->bile->vrefnum, tdb->bile->filename, &db_filename, + false) != 0) + panic("getpath failed on %s", PtoCstr(tdb->bile->filename)); + PtoCstr(db_filename); tdb->nboards = bile_count_by_type(tdb->bile, DB_BOARD_RTYPE); if (!tdb->nboards) return; - tdb->boards = xmallocarray(tdb->nboards, sizeof(struct board)); for (n = 0; n < tdb->nboards; n++) { obj = bile_get_nth_of_type(tdb->bile, n, DB_BOARD_RTYPE); if (obj == NULL) break; + + size = bile_read_alloc(tdb->bile, DB_BOARD_RTYPE, obj->id, + &data); + bile_unmarshall_object(tdb->bile, board_object_fields, + nboard_object_fields, data, size, (char *)(&tdb->boards[n])); + free(data); + + snprintf((char *)board_filename, sizeof(board_filename), + "%s:%ld.brd", db_filename, obj->id); + CtoPstr(board_filename); + tdb->boards[n].bile = bile_open(board_filename, tdb->bile->vrefnum); + if (tdb->boards[n].bile != NULL) + continue; - bile_read(tdb->bile, DB_BOARD_RTYPE, obj->id, - (char *)(&tdb->boards[n]), obj->size); + if (ask("Failed to open board bile %s (error %d), recreate it?", + PtoCstr(board_filename), bile_error(NULL)) == false) + exit(0); + + CtoPstr(board_filename); + tdb->boards[n].bile = db_board_create(tdb, &tdb->boards[n]); } } -void +struct bile * db_board_create(struct db *tdb, struct board *board) { Str255 db_filename, board_filename; struct bile *board_bile; + size_t size; + short ret; + char *data; - if (bile_write(tdb->bile, DB_BOARD_RTYPE, board->id, - board, sizeof(struct board)) != sizeof(struct board)) + ret = bile_marshall_object(tdb->bile, board_object_fields, + nboard_object_fields, board, &data, &size); + if (ret != 0 || size == 0) { + warn("db_board_create: failed to marshall object"); + return; + } + + if (bile_write(tdb->bile, DB_BOARD_RTYPE, board->id, data, + size) != size) panic("save of new board failed: %d", bile_error(tdb->bile)); - + free(data); + if (getpath(tdb->bile->vrefnum, tdb->bile->filename, &db_filename, false) != 0) panic("getpath failed on %s", PtoCstr(tdb->bile->filename)); - PtoCstr(db_filename); snprintf((char *)board_filename, sizeof(board_filename), "%s:%ld.brd", @@ -358,6 +377,6 @@ db_board_create(struct db *tdb, struct board *board) if (board_bile == NULL) panic("failed creating new board bile at %s: %d", PtoCstr(board_filename), bile_error(tdb->bile)); - - db_boards_load(tdb); + + return board_bile; } --- db.h Sun May 15 14:54:06 2022 +++ db.h Mon May 23 13:10:23 2022 @@ -41,13 +41,15 @@ #define DB_TEXT_ISSUE_ID 3 #define DB_USERNAME_LENGTH 16 - #define DB_BOARD_NAME_LENGTH 32 #define DB_BOARD_DESCR_LENGTH 100 #define SL_TYPE 'STSL' #define SL_LOG_RTYPE 'SLOG' +#define BOARD_THREAD_RTYPE 'BDTH' +#define BOARD_POST_RTYPE 'BDPS' + #include "subtext.h" #include "settings.h" #include "bile.h" @@ -67,38 +69,6 @@ struct config { extern struct struct_field config_fields[]; extern size_t nconfig_fields; -struct user { - /* keep this first so we can quickly read it during caching */ - char username_key[DB_USERNAME_LENGTH + 1]; - - unsigned long id; - char username[DB_USERNAME_LENGTH + 1]; - char password_hash[SHA256_DIGEST_STRING_LENGTH + 1]; /* 66 */ - char password_salt[SHA256_DIGEST_STRING_LENGTH + 1]; - unsigned long created_at; - unsigned long last_seen_at; - short is_sysop; -}; - -struct board { - unsigned long id; - char name[DB_BOARD_NAME_LENGTH]; - char description[DB_BOARD_DESCR_LENGTH]; - bool restricted_posting; - bool restricted_viewing; - unsigned short retention_days; - unsigned long last_post_at; - unsigned long post_count; -}; - -extern struct struct_field board_fields[]; -extern size_t nboard_fields; - -struct user_map { - unsigned long id; - char username_key[DB_USERNAME_LENGTH + 1]; -}; - struct db { struct bile *bile; short fh; @@ -114,6 +84,7 @@ struct db * db_open(Str255 file, short vrefnum); struct db * db_create(void); void db_close(struct db *tdb); void db_config_save(struct db *tdb); -void db_board_create(struct db *tdb, struct board *board); +void db_cache_boards(struct db *tdb); +struct bile * db_board_create(struct db *tdb, struct board *board); #endif --- mail.c Fri May 20 10:40:14 2022 +++ mail.c Sun May 22 21:56:17 2022 @@ -28,30 +28,31 @@ #include "util.h" struct bile_object_field mail_object_fields[] = { - { offsetof(struct private_message, recipient_user_id), - member_size(struct private_message, recipient_user_id), -1 }, - { offsetof(struct private_message, id), - member_size(struct private_message, id), -1 }, - { offsetof(struct private_message, time), - member_size(struct private_message, time), -1 }, - { offsetof(struct private_message, read), - member_size(struct private_message, read), -1 }, - { offsetof(struct private_message, sender_user_id), - member_size(struct private_message, sender_user_id), -1 }, - { offsetof(struct private_message, subject_size), - member_size(struct private_message, subject_size), -1 }, - { offsetof(struct private_message, subject), - -1, offsetof(struct private_message, subject_size) }, - { offsetof(struct private_message, body_size), - member_size(struct private_message, body_size), -1 }, - { offsetof(struct private_message, body), - -1, offsetof(struct private_message, body_size) }, - { offsetof(struct private_message, parent_message_id), - member_size(struct private_message, parent_message_id), -1 }, + { offsetof(struct mail_message, recipient_user_id), + member_size(struct mail_message, recipient_user_id), -1 }, + { offsetof(struct mail_message, id), + member_size(struct mail_message, id), -1 }, + { offsetof(struct mail_message, time), + member_size(struct mail_message, time), -1 }, + { offsetof(struct mail_message, read), + member_size(struct mail_message, read), -1 }, + { offsetof(struct mail_message, sender_user_id), + member_size(struct mail_message, sender_user_id), -1 }, + { offsetof(struct mail_message, subject_size), + member_size(struct mail_message, subject_size), -1 }, + { offsetof(struct mail_message, subject), + -1, offsetof(struct mail_message, subject_size) }, + { offsetof(struct mail_message, body_size), + member_size(struct mail_message, body_size), -1 }, + { offsetof(struct mail_message, body), + -1, offsetof(struct mail_message, body_size) }, + { offsetof(struct mail_message, parent_message_id), + member_size(struct mail_message, parent_message_id), -1 }, }; +size_t nmail_object_fields = nitems(mail_object_fields); -void mail_free_message_strings(struct private_message *msg); -short mail_save(struct session *s, struct private_message *msg); +void mail_free_message_strings(struct mail_message *msg); +short mail_save(struct session *s, struct mail_message *msg); void mail_read(struct session *s, unsigned long idx); void mail_delete(struct session *s, unsigned long idx); void mail_mark_unread(struct session *s, unsigned long idx); @@ -61,7 +62,7 @@ short mail_get_message_id(struct session *s, size_t nm short initial); void -mail_free_message_strings(struct private_message *msg) +mail_free_message_strings(struct mail_message *msg) { if (msg->subject) { free(msg->subject); @@ -194,7 +195,7 @@ mail_compose(struct session *s, char *initial_to, char char *initial_body) { struct user *to_user = NULL; - struct private_message msg = { 0 }; + struct mail_message msg = { 0 }; char *to_username = NULL, *tmp; char c; @@ -344,8 +345,8 @@ mail_list(struct session *s, bool sent, unsigned long { char time[24]; size_t n, size; - struct private_message msg; - struct user *user; + struct mail_message msg; + struct user_map *user; char *data; *nmsgs = mail_find_for_user_id(s->user->id, mail_ids); @@ -362,11 +363,9 @@ mail_list(struct session *s, bool sent, unsigned long &data); bile_unmarshall_object(db->bile, mail_object_fields, nitems(mail_object_fields), data, size, &msg); - user = user_find(msg.sender_user_id); + user = user_find_username(msg.sender_user_id); + strftime(time, sizeof(time), "%m/%d", localtime(&msg.time)); - strftime(time, sizeof(time), "%Y-%m-%d %H:%M", - localtime(&msg.time)); - session_printf(s, "%s%c [%- 3ld] %s %- 10s {{#}}%- 40s%s\r\n", msg.read ? "" : ansi(s, ANSI_BOLD, ANSI_END), msg.read ? ' ' : 'N', @@ -387,15 +386,15 @@ mail_read(struct session *s, unsigned long id) { char time[32]; size_t size; - struct private_message msg; - struct user *sender, *recipient; + struct mail_message msg; + struct user_map *sender, *recipient; char *data; size = bile_read_alloc(db->bile, DB_MESSAGE_RTYPE, id, &data); bile_unmarshall_object(db->bile, mail_object_fields, nitems(mail_object_fields), data, size, &msg); - sender = user_find(msg.sender_user_id); - recipient = user_find(msg.recipient_user_id); + sender = user_find_username(msg.sender_user_id); + recipient = user_find_username(msg.recipient_user_id); strftime(time, sizeof(time), "%Y-%m-%d %H:%M:%S", localtime(&msg.time)); @@ -447,7 +446,7 @@ delete_done: void mail_mark_unread(struct session *s, unsigned long idx) { - struct private_message msg; + struct mail_message msg; unsigned long *mail_ids; size_t nmsgs, size; char *data; @@ -479,7 +478,7 @@ unread_done: } short -mail_save(struct session *s, struct private_message *msg) +mail_save(struct session *s, struct mail_message *msg) { size_t size; char *data; --- mail.h Fri Feb 18 14:22:59 2022 +++ mail.h Sun May 22 21:24:22 2022 @@ -20,7 +20,7 @@ #include "bile.h" #include "session.h" -struct private_message { +struct mail_message { /* key */ unsigned long recipient_user_id; --- main.c Mon May 9 15:39:21 2022 +++ main.c Mon May 23 13:04:06 2022 @@ -91,8 +91,8 @@ main(void) _atexit(handle_exit); logger = logger_init(); - logger_printf(logger, "[db] Updating user cache"); - user_update_cache_map(); + logger_printf(logger, "[db] Updating username cache"); + user_cache_usernames(); if (db->config.telnet_port) telnet_init(); --- session.h Fri May 20 10:38:07 2022 +++ session.h Mon May 23 11:28:56 2022 @@ -21,6 +21,7 @@ #include "db.h" #include "uthread.h" +#include "user.h" enum session_input_state { SESSION_INPUT_NONE, --- sysop.c Sun May 15 21:42:53 2022 +++ sysop.c Mon May 23 13:00:44 2022 @@ -14,12 +14,13 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <string.h> + #include "subtext.h" +#include "board.h" #include "session.h" #include "sysop.h" -#include <string.h> - void sysop_edit_boards(struct session *s); void @@ -98,12 +99,13 @@ sysop_edit_boards(struct session *s) { 'q', "QqXx", "Return to sysop menu" }, { '?', "?", "List menu options" }, }; + char prompt[30]; struct session_menu_option *dopts = NULL, *opt; struct board *board, *new_board; - size_t n; + struct bile *new_board_bile; + size_t n, size; short ret; - char c; - char prompt[30]; + char c, *data = NULL; bool show_help = true; bool done = false; bool found = false; @@ -144,7 +146,11 @@ sysop_edit_boards(struct session *s) free(board); continue; } - db_board_create(db, new_board); + + new_board_bile = db_board_create(db, new_board); + bile_close(new_board_bile); + db_cache_boards(db); + session_log(s, "Created new board %ld: %s", new_board->id, new_board->name); free(board); @@ -174,10 +180,17 @@ sysop_edit_boards(struct session *s) if (ret != 0) continue; memcpy(&db->boards[n], new_board, sizeof(struct board)); + + ret = bile_marshall_object(db->bile, board_object_fields, + nboard_object_fields, &db->boards[n], &data, &size); + if (ret != 0 || size == 0) + panic("db_board_create: failed to marshall object"); + if (bile_write(db->bile, DB_BOARD_RTYPE, new_board->id, - new_board, sizeof(struct board)) != sizeof(struct board)) - panic("save of board %ld failed: %d", - new_board->id, bile_error(db->bile)); + data, size) != size) + panic("save of board failed: %d", bile_error(db->bile)); + free(data); + session_log(s, "Saved changes to board %ld: %s", new_board->id, new_board->name); free(new_board); --- user.c Sun May 15 22:23:17 2022 +++ user.c Mon May 23 13:19:02 2022 @@ -44,8 +44,9 @@ static char *BANNED_USERNAMES[] = { }; void -user_update_cache_map(void) +user_cache_usernames(void) { + struct user user; struct user_map *muser; struct bile_object *o; size_t nuser, len; @@ -61,13 +62,14 @@ user_update_cache_map(void) muser = &db->user_map[nuser]; muser->id = o->id; - /* the lowercased username should be the first bytes of each rec */ - len = bile_read(db->bile, DB_USER_RTYPE, o->id, - muser->username_key, sizeof(muser->username_key)); - if (len != sizeof(muser->username_key)) + len = bile_read(db->bile, DB_USER_RTYPE, o->id, (char *)&user, + sizeof(user)); + if (len != sizeof(user)) panic("user_update_cache_map: can't read user %lu: %d", o->id, bile_error(db->bile)); - + + strncpy(muser->username, user.username, sizeof(muser->username)); + free(o); nuser++; } @@ -83,18 +85,12 @@ user_save(struct user *user) user->created_at = Time; } - /* update username key */ - memset(user->username_key, 0, sizeof(user->username_key)); - len = strlen(user->username); - for (n = 0; n < len; n++) - user->username_key[n] = tolower(user->username[n]); - len = bile_write(db->bile, DB_USER_RTYPE, user->id, user, sizeof(struct user)); if (len != sizeof(struct user)) panic("user_save: failed to write: %d", bile_error(db->bile)); - user_update_cache_map(); + user_cache_usernames(); } struct user * @@ -121,23 +117,33 @@ user_find_by_username(const char *username) { struct user suser; struct user_map *muser; - char lusername[DB_USERNAME_LENGTH + 1] = { 0 }; short n; size_t len; len = strlen(username); - if (len > sizeof(suser.username_key)) + if (len > sizeof(suser.username)) return NULL; - /* downcase username and find it in the cache map */ - for (n = 0; n < len; n++) - lusername[n] = tolower(username[n]); - for (n = 0; n < db->nusers; n++) { muser = &db->user_map[n]; - if (strcmp(muser->username_key, lusername) == 0) + if (strcasecmp(muser->username, username) == 0) return user_find(muser->id); + } + + return NULL; +} + +struct user_map * +user_find_username(unsigned long id) +{ + struct user_map *muser; + size_t n; + + for (n = 0; n < db->nusers; n++) { + muser = &db->user_map[n]; + if (muser->id == id) + return muser; } return NULL; --- user.h Wed Apr 20 20:24:01 2022 +++ user.h Mon May 23 12:59:50 2022 @@ -24,10 +24,26 @@ #define GUEST_USERNAME "guest" -void user_update_cache_map(void); +struct user { + unsigned long id; + char username[DB_USERNAME_LENGTH + 1]; + char password_hash[SHA256_DIGEST_STRING_LENGTH + 1]; /* 66 */ + char password_salt[SHA256_DIGEST_STRING_LENGTH + 1]; + unsigned long created_at; + unsigned long last_seen_at; + short is_sysop; +}; + +struct user_map { + unsigned long id; + char username[DB_USERNAME_LENGTH + 1]; +}; + +void user_cache_usernames(void); void user_save(struct user *user); struct user * user_find(unsigned long id); struct user * user_find_by_username(const char *username); +struct user_map * user_find_username(unsigned long id); short user_authenticate(struct user *user, const char *password); void user_set_password(struct user *user, const char *password); short user_valid_username(char *username, char **error); --- user_settings.c Sat May 14 21:49:20 2022 +++ user_settings.c Fri May 20 10:42:25 2022 @@ -87,7 +87,7 @@ get_terminal_size: s->terminal_lines); session_flush(s); - tsize = session_field_input(s, 10, 10, NULL, 0); + tsize = session_field_input(s, 10, 10, NULL, false, 0); if (tsize == NULL) return; session_output(s, "\r\n", 2); @@ -132,7 +132,7 @@ user_settings_password(struct session *s) for (;;) { session_output_template(s, "{{B}}New Password:{{/B}} "); session_flush(s); - password = session_field_input(s, 64, 64, NULL, '*'); + password = session_field_input(s, 64, 64, NULL, false, '*'); session_output(s, "\r\n", 2); session_flush(s); @@ -148,7 +148,7 @@ user_settings_password(struct session *s) session_output_template(s, "{{B}}New Password (again):{{/B}} "); session_flush(s); - password_confirm = session_field_input(s, 64, 64, NULL, '*'); + password_confirm = session_field_input(s, 64, 64, NULL, false, '*'); session_output(s, "\r\n", 2); session_flush(s);