AmendHub

Download:

jcs

/

subtext

/

amendments

/

391

sysop: Use new struct_editor for boards and folders

This allows moving the deletion of them into the edit menu

jcs made amendment 391 about 1 year ago
--- db.c Tue Mar 7 23:11:38 2023 +++ db.c Fri Mar 10 21:15:58 2023 @@ -1011,3 +1011,14 @@ db_folder_create(struct db *tdb, struct folder *folder return folder_bile; } + +void +db_folder_delete(struct db *tdb, struct folder *folder) +{ + if (bile_delete(tdb->bile, DB_FOLDER_RTYPE, folder->id, 0) != 0) { + warn("deletion of folder %ld failed: %d", folder->id, + bile_error(tdb->bile)); + return; + } + bile_close(folder->bile); +} --- db.h Wed Mar 8 17:16:09 2023 +++ db.h Fri Mar 10 20:55:05 2023 @@ -122,12 +122,15 @@ 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_cache_boards(struct db *tdb); struct bile * db_board_create(struct db *tdb, struct board *board, bool delete_first); void db_board_delete(struct db *tdb, struct board *board); + void db_cache_folders(struct db *tdb); struct bile * db_folder_create(struct db *tdb, struct folder *folder, bool delete_first); +void db_folder_delete(struct db *tdb, struct folder *folder); #endif --- sysop.c Tue Mar 7 22:52:43 2023 +++ sysop.c Fri Mar 10 21:29:46 2023 @@ -114,9 +114,9 @@ sysop_edit_settings(struct session *s) if (!s->user || !s->user->is_sysop) return; - ret = struct_editor(s, config_fields, nconfig_fields, &db->config, - sizeof(struct config), (void *)&new_config, "BBS Settings", - "Sysop:Settings"); + ret = struct_editor(s, config_fields, nconfig_fields, NULL, 0, + &db->config, sizeof(struct config), (void *)&new_config, + "BBS Settings", "Sysop:Settings"); if (ret != 0) { session_printf(s, "No changes made\r\n"); return; @@ -137,91 +137,53 @@ void sysop_edit_boards(struct session *s) { static const struct session_menu_option opts[] = { - { 'd', "Dd", "Delete board" }, + { '#', "", "Enter board to edit" }, + { 'l', "Ll", "List boards" }, { 'n', "Nn", "Create new board" }, { 'q', "QqXx", "Return to sysop menu" }, { '?', "?", "List menu options" }, }; + static const struct session_menu_option edit_opts[] = { + { 'd', "Dd", "Delete board" }, + { 'i', "Ii", "Re-index posts" }, + }; char prompt[30]; - struct session_menu_option *dopts = NULL, *opt; struct board *board, *new_board; struct bile *new_board_bile; size_t n, size; - short ret, id, sc; + short bn, ret, id, sc; char c, *data = NULL, *name; - bool show_help = true; - bool done = false; - bool found = false; + bool done, show_list, show_help; - while (!done && !s->ending) { - /* - * Unfortunately we have to do this every iteration because the - * list of boards may change - */ - if (dopts != NULL) - xfree(&dopts); - dopts = xmalloc(sizeof(opts) + - (db->nboards * sizeof(struct session_menu_option))); - if (dopts == NULL) - return; - for (n = 0; n < db->nboards; n++) { - board = &db->boards[n]; - opt = &dopts[n]; - opt->ret = '0' + board->id; - opt->key[0] = '0' + board->id; - opt->key[1] = '\0'; - strlcpy(opt->title, board->name, sizeof(opts[0].title)); - } - memcpy(&dopts[db->nboards], opts, sizeof(opts)); + show_list = true; + show_help = false; + done = false; - c = session_menu(s, "Board Editor", "Sysop:Boards", dopts, - nitems(opts) + db->nboards, show_help, NULL, NULL); - show_help = false; - - switch (c) { - case 'd': - /* TODO: move this to board edit menu */ - session_printf(s, "Board ID to delete: "); + while (!done && !s->ending) { + if (show_list) { + session_printf(s, "{{B}}Boards{{/B}}\r\n"); + session_printf(s, "%s# Name Description%s\r\n", + ansi(s, ANSI_BOLD, ANSI_END), ansi(s, ANSI_RESET, ANSI_END)); session_flush(s); - name = session_field_input(s, 5, 5, "", false, 0); - session_output(s, "\r\n", 2); - session_flush(s); - - if (name == NULL) - break; - id = atoi(name); - xfree(&name); - if (id == 0) - break; - for (n = 0; n < db->nboards; n++) { - board = &db->boards[n]; - if (board->id != id) - continue; + session_printf(s, "%2ld %- 10.10s %s\r\n", + n + 1, + db->boards[n].name, + db->boards[n].description); + } + session_flush(s); - session_printf(s, - "Really delete board %s? [y/N] ", board->name); - session_flush(s); - - sc = session_input_char(s); - if (s->ending) - return; - if (sc != 'Y' && sc != 'y') { - session_output(s, "\r\n", 2); - session_flush(s); - continue; - } - session_printf(s, "%c\r\n", sc == 'Y' ? 'Y' : 'y'); - session_flush(s); + show_list = false; + } - session_logf(s, "Deleting board %ld (%s)!", - board->id, board->name); - - db_board_delete(db, board); - db_cache_boards(db); - break; - } + c = session_menu(s, "Board Editor", "Sysop:Boards", opts, + nitems(opts), show_help, "Board #", &bn); + show_help = false; + + switch (c) { + case 'l': + show_list = true; break; case 'n': board = xmalloczero(sizeof(struct board)); @@ -230,7 +192,7 @@ sysop_edit_boards(struct session *s) board->id = bile_next_id(db->bile, DB_BOARD_RTYPE); board->restricted_posting = false; board->restricted_viewing = false; - ret = struct_editor(s, board_fields, nboard_fields, + ret = struct_editor(s, board_fields, nboard_fields, NULL, 0, board, sizeof(struct board), (void *)&new_board, "New Board", "Sysop:Boards:New"); if (ret != 0) { @@ -251,35 +213,53 @@ sysop_edit_boards(struct session *s) xfree(&board); xfree(&new_board); break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - found = false; - for (n = 0; n < db->nboards; n++) { - board = &db->boards[n]; - if (board->id != c - '0') - continue; - found = true; - snprintf(prompt, sizeof(prompt), "Sysop:Boards:%ld", - board->id); - ret = struct_editor(s, board_fields, nboard_fields, - board, sizeof(struct board), (void *)&new_board, - "Edit Board", prompt); - if (ret != 0) - continue; + case '#': + if (bn < 1 || bn > db->nboards) { + session_printf(s, "Invalid board ID\r\n"); + session_flush(s); + break; + } + + board = &db->boards[bn - 1]; + snprintf(prompt, sizeof(prompt), "Sysop:Boards:%ld", + board->id); +edit_board: + ret = struct_editor(s, board_fields, nboard_fields, edit_opts, + nitems(edit_opts), board, sizeof(struct board), + (void *)&new_board, "Edit Board", prompt); + switch (ret) { + case 'i': + board_index_sorted_post_ids(board, NULL); + goto edit_board; + case 'd': + session_printf(s, + "Really delete board %s? [y/N] ", board->name); + session_flush(s); + + sc = session_input_char(s); + if (s->ending) + return; + if (sc != 'Y' && sc != 'y') { + session_output(s, "\r\n", 2); + session_flush(s); + break; + } + session_printf(s, "%c\r\n", sc == 'Y' ? 'Y' : 'y'); + session_flush(s); + + session_logf(s, "Deleting board %ld (%s)!", + board->id, board->name); + + db_board_delete(db, board); + db_cache_boards(db); + break; + case 0: 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"); + panic("board: failed to marshall object"); if (bile_write(db->bile, DB_BOARD_RTYPE, new_board->id, data, size) != size) @@ -291,10 +271,6 @@ sysop_edit_boards(struct session *s) xfree(&new_board); break; } - if (!found) { - session_printf(s, "Invalid board ID\r\n"); - session_flush(s); - } break; case '?': show_help = true; @@ -310,47 +286,53 @@ void sysop_edit_folders(struct session *s) { static const struct session_menu_option opts[] = { + { '#', "", "Enter folder to edit" }, + { 'l', "Ll", "List folders" }, { 'n', "Nn", "Create new folder" }, { 'q', "QqXx", "Return to sysop menu" }, { '?', "?", "List menu options" }, }; + static const struct session_menu_option edit_opts[] = { + { 'd', "Dd", "Delete folder" }, + }; char prompt[30]; - struct session_menu_option *dopts = NULL, *opt; struct folder *folder, *new_folder; struct bile *new_folder_bile; size_t n, size; - short ret; + short ret, fn, sc; char c, *data = NULL; - bool show_help = true; - bool done = false; - bool found = false; + bool done, show_list, show_help; + show_list = true; + show_help = false; + done = false; + while (!done && !s->ending) { - /* - * Unfortunately we have to do this every iteration because the - * list of folders may change - */ - if (dopts != NULL) - xfree(&dopts); - dopts = xmalloc(sizeof(opts) + - (db->nboards * sizeof(struct session_menu_option))); - if (dopts == NULL) - return; - for (n = 0; n < db->nfolders; n++) { - folder = &db->folders[n]; - opt = &dopts[n]; - opt->ret = '0' + folder->id; - opt->key[0] = '0' + folder->id; - opt->key[1] = '\0'; - strlcpy(opt->title, folder->name, sizeof(opts[0].title)); + if (show_list) { + session_printf(s, "{{B}}Folders{{/B}}\r\n"); + session_printf(s, "%s# Name Description%s\r\n", + ansi(s, ANSI_BOLD, ANSI_END), ansi(s, ANSI_RESET, ANSI_END)); + session_flush(s); + + for (n = 0; n < db->nfolders; n++) { + session_printf(s, "%2ld %- 15.15s %s\r\n", + n + 1, + db->folders[n].name, + db->folders[n].description); + } + session_flush(s); + + show_list = false; } - memcpy(&dopts[db->nfolders], opts, sizeof(opts)); - c = session_menu(s, "Folder Editor", "Sysop:Folders", dopts, - nitems(opts) + db->nfolders, show_help, NULL, NULL); + c = session_menu(s, "Folder Editor", "Sysop:Folders", opts, + nitems(opts), show_help, "Folder #", &fn); show_help = false; switch (c) { + case 'l': + show_list = true; + break; case 'n': folder = xmalloczero(sizeof(struct folder)); if (folder == NULL) @@ -358,7 +340,7 @@ sysop_edit_folders(struct session *s) folder->id = bile_next_id(db->bile, DB_FOLDER_RTYPE); folder->restricted_posting = false; folder->restricted_viewing = false; - ret = struct_editor(s, folder_fields, nfolder_fields, + ret = struct_editor(s, folder_fields, nfolder_fields, NULL, 0, folder, sizeof(struct folder), (void *)&new_folder, "New Folder", "Sysop:Folders:New"); if (ret != 0) { @@ -380,35 +362,50 @@ sysop_edit_folders(struct session *s) xfree(&folder); xfree(&new_folder); break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - found = false; - for (n = 0; n < db->nfolders; n++) { - folder = &db->folders[n]; - if (folder->id != c - '0') - continue; - found = true; - snprintf(prompt, sizeof(prompt), "Sysop:Folders:%ld", - folder->id); - ret = struct_editor(s, folder_fields, nfolder_fields, - folder, sizeof(struct folder), (void *)&new_folder, - "Edit Folder", prompt); - if (ret != 0) - continue; + case '#': + if (fn < 1 || fn > db->nfolders) { + session_printf(s, "Invalid folder ID\r\n"); + session_flush(s); + break; + } + + folder = &db->folders[fn - 1]; + snprintf(prompt, sizeof(prompt), "Sysop:Folders:%ld", + folder->id); +edit_folder: + ret = struct_editor(s, folder_fields, nfolder_fields, + edit_opts, nitems(edit_opts), folder, sizeof(struct folder), + (void *)&new_folder, "Edit Folder", prompt); + switch (ret) { + case 'd': + session_printf(s, + "Really delete folder %s? [y/N] ", folder->name); + session_flush(s); + + sc = session_input_char(s); + if (s->ending) + return; + if (sc != 'Y' && sc != 'y') { + session_output(s, "\r\n", 2); + session_flush(s); + break; + } + session_printf(s, "%c\r\n", sc == 'Y' ? 'Y' : 'y'); + session_flush(s); + + session_logf(s, "Deleting folder %ld (%s)!", + folder->id, folder->name); + + db_folder_delete(db, folder); + db_cache_folders(db); + break; + case 0: memcpy(&db->folders[n], new_folder, sizeof(struct folder)); ret = bile_marshall_object(db->bile, folder_object_fields, nfolder_object_fields, &db->folders[n], &data, &size); if (ret != 0 || size == 0) - panic("db_folder_create: failed to marshall object"); + panic("folder: failed to marshall object"); if (bile_write(db->bile, DB_FOLDER_RTYPE, new_folder->id, data, size) != size) @@ -420,10 +417,6 @@ sysop_edit_folders(struct session *s) new_folder->id, new_folder->name); xfree(&new_folder); break; - } - if (!found) { - session_printf(s, "Invalid folder ID\r\n"); - session_flush(s); } break; case '?':