From 3f7fc15c44663bfad8ced3f5a07b6cf7685e10f8 Mon Sep 17 00:00:00 2001 From: Andrew Pamment Date: Tue, 6 Feb 2018 11:41:55 +1000 Subject: [PATCH] Nodelist browser --- STRINGS.CHANGES | 40 +++++++++ dist/ansis/mailmenu.ans | Bin 1422 -> 1556 bytes dist/magicka.strings | 13 ++- dist/menus/mail.mnu | 3 + docs/docs/guide/menus.md | 1 + src/bbs.h | 1 + src/menus.c | 6 ++ src/nodelist.c | 183 ++++++++++++++++++++++++++++++++++++++- 8 files changed, 243 insertions(+), 4 deletions(-) diff --git a/STRINGS.CHANGES b/STRINGS.CHANGES index e225f03..e51abda 100644 --- a/STRINGS.CHANGES +++ b/STRINGS.CHANGES @@ -70,3 +70,43 @@ NEWSTRING: "" LINE 124 MODIFIED OLDSTRING: "\r\nMailing to %d:%d/%d.%d\r\n" NEWSTRING: "\r\nMailing to %d:%d/%d.%d (%s)\r\n" + +LINE 146 MODIFIED +OLDSTRING: "" +NEWSTRING: "\e[1;37;44mNodelist Browser\e[K" + +LINE 147 MODIFIED +OLDSTRING: "" +NEWSTRING: "\e[24;1H\e[1;37;44mUp / Down to Select, Enter to View Details, Q to Quit\e[K" + +LINE 148 MODIFIED +OLDSTRING: "" +NEWSTRING: "\e[%d;1H\e[1;30;40m[\e[1;34;44m%4d\e[1;30;40m] \e[1;37m%-15.15s %s\e[K" + +LINE 262 NEW +OLDSTRING: (NONE) +NEWSTRING: "\e[%d;1H\e[1;30;40m[\e[1;34m%4d\e[1;30;40m] \e[1;37m%-15.15s %s\e[K" + +LINE 263 NEW +OLDSTRING: (NONE) +NEWSTRING: "\e[1;37mNode Details for \e[1;33m%s\r\n" + +LINE 264 NEW +OLDSTRING: (NONE) +NEWSTRING: "\e[1;30m-------------------------------------------------------------------------------\e[0m\r\n" + +LINE 265 NEW +OLDSTRING: (NONE) +NEWSTRING: " \e[1;32mSystem Name : \e[1;37m%s\r\n" + +LINE 266 NEW +OLDSTRING: (NONE) +NEWSTRING: " \e[1;32mSysop Name : \e[1;37m%s\r\n" + +LINE 267 NEW +OLDSTRING: (NONE) +NEWSTRING: " \e[1;32mLocation : \e[1;37m%s\r\n" + +LINE 268 NEW +OLDSTRING: (NONE) +NEWSTRING: "\e[1;30m-------------------------------------------------------------------------------\e[0m\r\n" diff --git a/dist/ansis/mailmenu.ans b/dist/ansis/mailmenu.ans index 53182434bd978793c00be8613cc3dcccc5884cc3..e57a87cfa6fe3f98340fc1bce87e5d4c22702160 100644 GIT binary patch delta 330 zcmeCTj`d2wnH$i*PDj4i;Zn7P-4n*b! zv)SZT%qFZRATuXxvY4|$95XqOMTZBb#n?1AXmTT?$m9 \e[1;37;44mChoose a Text file to view\e[K \e[24;1H\e[1;37;44mUp / Down to Select, Enter to View, Q to Quit\e[K - - - +\e[1;37;44mNodelist Browser\e[K +\e[24;1H\e[1;37;44mUp / Down to Select, Enter to View Details, Q to Quit\e[K +\e[%d;1H\e[1;30;40m[\e[1;34;44m%4d\e[1;30;40m] \e[1;37m%-15.15s %s\e[K \r\nSorry, there are no text files to display\r\n \e[2J\e[1;1H\e[1;32mYour Settings\r\n \e[1;30m-------------------------------------------------------------------------------\e[0m\r\n @@ -259,3 +259,10 @@ File exists!\r\n \e[1;33mSorry this BBS does not have the webserver enabled.\e[0m\r\n \e[%d;1H\e[1;30;40m[\e[1;34;44m%4d\e[1;30;40m]\e[1;32m*\e[1;37m%s\e[K \e[%d;1H\e[1;30;40m[\e[1;34m%4d\e[1;30;40m]\e[1;32m*\e[1;37m%s\e[K +\e[%d;1H\e[1;30;40m[\e[1;34m%4d\e[1;30;40m] \e[1;37m%-15.15s %s\e[K +\e[1;37mNode Details for \e[1;33m%s\r\n +\e[1;30m-------------------------------------------------------------------------------\e[0m\r\n + \e[1;32mSystem Name : \e[1;37m%s\r\n + \e[1;32mSysop Name : \e[1;37m%s\r\n + \e[1;32mLocation : \e[1;37m%s\r\n +\e[1;30m-------------------------------------------------------------------------------\e[0m\r\n diff --git a/dist/menus/mail.mnu b/dist/menus/mail.mnu index 9b3e29b..bf9bd41 100644 --- a/dist/menus/mail.mnu +++ b/dist/menus/mail.mnu @@ -58,3 +58,6 @@ COMMAND RESETMSGPTRS HOTKEY X COMMAND RESETALLMSGPTRS + +HOTKEY N +COMMAND NLBROWSER diff --git a/docs/docs/guide/menus.md b/docs/docs/guide/menus.md index a7b6d04..66b7096 100644 --- a/docs/docs/guide/menus.md +++ b/docs/docs/guide/menus.md @@ -128,3 +128,4 @@ Finally, an optional SECLEVEL command indicates the required security level for **GENWWWURLS** Generate and show WWW urls for the tagged files for web download. +**NLBROWSER** Browse the nodelist for the current conference. \ No newline at end of file diff --git a/src/bbs.h b/src/bbs.h index 92789e7..92a6538 100644 --- a/src/bbs.h +++ b/src/bbs.h @@ -369,4 +369,5 @@ extern char *www_decode_hash(char *hash); extern int menu_system(char *menufile); extern char *nl_get_bbsname(struct fido_addr *addr, char *domain); +extern void nl_browser(); #endif diff --git a/src/menus.c b/src/menus.c index 2cae1b3..1fac33b 100644 --- a/src/menus.c +++ b/src/menus.c @@ -55,6 +55,7 @@ #define MENU_DISPTXTFILE 45 #define MENU_DISPTXTFILEPAUSE 46 #define MENU_GENWWWURLS 47 +#define MENU_NLBROWSER 48 extern struct bbs_config conf; extern struct user_record *gUser; @@ -216,6 +217,8 @@ int menu_system(char *menufile) { menu[menu_items-1]->command = MENU_DISPTXTFILEPAUSE; } else if (strncasecmp(&buffer[8], "GENWWWURLS", 10) == 0) { menu[menu_items-1]->command = MENU_GENWWWURLS; + } else if (strncasecmp(&buffer[8], "NLBROWSER", 9) == 0) { + menu[menu_items-1]->command = MENU_NLBROWSER; } } else if (strncasecmp(buffer, "SECLEVEL", 8) == 0) { menu[menu_items-1]->seclevel = atoi(&buffer[9]); @@ -556,6 +559,9 @@ int menu_system(char *menufile) { case MENU_GENWWWURLS: genurls(); break; + case MENU_NLBROWSER: + nl_browser(); + break; default: break; } diff --git a/src/nodelist.c b/src/nodelist.c index 5994a29..15b0bf0 100644 --- a/src/nodelist.c +++ b/src/nodelist.c @@ -4,6 +4,7 @@ #include "bbs.h" extern struct bbs_config conf; +extern struct user_record *gUser; char *nl_get_bbsname(struct fido_addr *addr, char *domain) { sqlite3 *db; @@ -27,7 +28,7 @@ char *nl_get_bbsname(struct fido_addr *addr, char *domain) { if (rc != SQLITE_OK) { sqlite3_close(db); - return 0; + return strdup("Unknown"); } if (addr->point == 0) { @@ -50,4 +51,184 @@ char *nl_get_bbsname(struct fido_addr *addr, char *domain) { sqlite3_finalize(res); sqlite3_close(db); return ret; +} + +struct nl_temp { + char *address; + char *location; + char *sysop; + char *bbsname; +}; + +void nl_browser() { + int entry_count = 0; + struct nl_temp **entries; + sqlite3 *db; + sqlite3_stmt *res; + int rc; + char buffer[PATH_MAX]; + char *ret; + char *sql_buf = "SELECT nodeno,location,sysop,bbsname FROM nodelist WHERE domain=?"; + int i; + int redraw = 1; + int start = 0; + int selected = 0; + char c; + + // load nodelist + snprintf(buffer, PATH_MAX, "%s/nodelists.sq3", conf.bbs_path); + + rc = sqlite3_open(buffer, &db); + + if (rc != SQLITE_OK) { + dolog("Cannot open database: %s", sqlite3_errmsg(db)); + return; + } + sqlite3_busy_timeout(db, 5000); + + rc = sqlite3_prepare_v2(db, sql_buf, -1, &res, 0); + + if (rc != SQLITE_OK) { + sqlite3_close(db); + return; + } + + sqlite3_bind_text(res, 1, conf.mail_conferences[gUser->cur_mail_conf]->domain, -1, 0); + + while (sqlite3_step(res) == SQLITE_ROW) { + if (entry_count == 0) { + entries = (struct nl_temp **)malloc(sizeof(struct nl_temp *)); + } else { + entries = (struct nl_temp **)realloc(entries, sizeof(struct nl_temp *) * (entry_count + 1)); + } + entries[entry_count] = (struct nl_temp *)malloc(sizeof(struct nl_temp)); + + entries[entry_count]->address = strdup(sqlite3_column_text(res, 0)); + entries[entry_count]->location = strdup(sqlite3_column_text(res, 1)); + entries[entry_count]->sysop = strdup(sqlite3_column_text(res, 2)); + entries[entry_count]->bbsname = strdup(sqlite3_column_text(res, 3)); + entry_count++; + } + sqlite3_finalize(res); + sqlite3_close(db); + + while (1) { + if (redraw) { + s_printf("\e[2J\e[1;1H"); + s_printf(get_string(145)); + s_printf(get_string(146)); + for (i=start;iaddress, entries[i]->bbsname); + } else { + s_printf(get_string(262), i - start + 2, i, entries[i]->address, entries[i]->bbsname); + } + } + s_printf("\e[%d;5H", selected - start + 2); + redraw = 0; + } + c = s_getchar(); + if (tolower(c) == 'q') { + break; + } else if (c == 27) { + c = s_getchar(); + if (c == 91) { + c = s_getchar(); + if (c == 66) { + // down + if (selected + 1 >= start + 22) { + start += 22; + if (start >= entry_count) { + start = entry_count - 22; + } + redraw = 1; + } + selected++; + if (selected >= entry_count) { + selected = entry_count - 1; + } else { + if (!redraw) { + s_printf(get_string(262), selected - start + 1, selected - 1, entries[selected - 1]->address, entries[selected - 1]->bbsname); + s_printf(get_string(147), selected - start + 2, selected, entries[selected]->address, entries[selected]->bbsname); + s_printf("\e[%d;5H", selected - start + 2); + } + } + } else if (c == 65) { + // up + if (selected - 1 < start) { + start -= 22; + if (start < 0) { + start = 0; + } + redraw = 1; + } + selected--; + if (selected < 0) { + selected = 0; + } else { + if (!redraw) { + s_printf(get_string(147), selected - start + 2, selected, entries[selected]->address, entries[selected]->bbsname); + s_printf(get_string(262), selected - start + 3, selected + 1, entries[selected + 1]->address, entries[selected + 1]->bbsname); + s_printf("\e[%d;5H", selected - start + 2); + } + } + } else if (c == 75) { + // END KEY + selected = entry_count - 1; + start = entry_count - 22; + if (start < 0) { + start = 0; + } + redraw = 1; + } else if (c == 72) { + // HOME KEY + selected = 0; + start = 0; + redraw = 1; + } else if (c == 86 || c == '5') { + if (c == '5') { + s_getchar(); + } + // PAGE UP + selected = selected - 22; + if (selected < 0) { + selected = 0; + } + start = selected; + redraw = 1; + } else if (c == 85 || c == '6') { + if (c == '6') { + s_getchar(); + } + // PAGE DOWN + selected = selected + 22; + if (selected >= entry_count) { + selected = entry_count -1; + } + start = selected; + redraw = 1; + } + } + } else if (c == 13) { + s_printf("\e[2J\e[1;1H"); + s_printf(get_string(262), entries[selected]->address); + s_printf(get_string(263)); + s_printf(get_string(264), entries[selected]->bbsname); + s_printf(get_string(265), entries[selected]->sysop); + s_printf(get_string(266), entries[selected]->location); + s_printf(get_string(267)); + s_printf(get_string(185)); + s_getc(); + s_printf("\r\n"); + redraw = 1; + } + } + for (i=0;iaddress); + free(entries[i]->bbsname); + free(entries[i]->sysop); + free(entries[i]->location); + free(entries[i]); + } + free(entries); } \ No newline at end of file