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 '?':