diff --git a/.gitlab-ci-unix.yml b/.gitlab-ci-unix.yml index dfea88c0011fae4f44d0c1721e93f1c55b1136cf..12787421ec66babc23a2cd52fcdc4c730f82b234 100644 --- a/.gitlab-ci-unix.yml +++ b/.gitlab-ci-unix.yml @@ -46,7 +46,7 @@ spec: script: - cd 3rdp/build - touch depend - - JS_CONFIGURE_ARGS="--cache-file=../../../../../build/smconfig.cache" $[[ inputs.gnu_make ]] $[[ inputs.build_flags ]] $BUILD_ARGS libmozjs + - $[[ inputs.gnu_make ]] $[[ inputs.build_flags ]] $BUILD_ARGS libmozjs - mkdir -p "/tmp/gitlab-runner/$[[ inputs.os ]]-$[[ inputs.platform ]]-${CI_PIPELINE_ID}" - cd ../.. - tar -czf "/tmp/gitlab-runner/$[[ inputs.os ]]-$[[ inputs.platform ]]-${CI_PIPELINE_ID}/spidermonkey.tgz" 3rdp/*.release/mozjs @@ -56,10 +56,6 @@ spec: - if: '"$[[ inputs.no_javascript ]]" == "yes"' when: never - !reference [.rules, rules] - cache: - key: $CI_JOB_NAME - paths: - - 3rdp/build/smconfig.cache* "$[[ inputs.os ]]-$[[ inputs.platform ]] [cryptlib]": extends: diff --git a/exec/load/dd_lightbar_menu.js b/exec/load/dd_lightbar_menu.js index 9a9b04a6c0a5b00e6b6c4074d8e38e9e9564a665..dfa31d3c91ea961756c29663ae749d87d1a14041 100644 --- a/exec/load/dd_lightbar_menu.js +++ b/exec/load/dd_lightbar_menu.js @@ -355,6 +355,19 @@ By default, DDLightbarMenu ignores the isSelectable attribute of items and consi selectable (for efficiency). To enable usage of unselectable items, set the allowUnselectableItems property to true: lbMenu.allowUnselectableItems = true; + + +If the user's terminal doesn't support ANSI, DDLightbarMenu will work in a non-lightbar +mode. When not using a lightbar interface, DDLightbarMenu will automatically use numbered +mode, where the menu will output numbers to the left of the menu items and let the user +type a number to choose an item. +You can also tell DDLightbarMenu to not work in lightbar mode if you want a more traditional +user interface (colors will still be supported) by setting the allowANSI property to false: +lbMenu.allowANSI = false; + +For the traditional/non-lightbar mode, you can customize the prompt text that is used, by +changing the nonANSIPromptText property. For instance: +lbMenu.nonANSIPromptText = "Type a number to choose an item: "; */ "use strict"; @@ -535,6 +548,9 @@ function DDLightbarMenu(pX, pY, pWidth, pHeight) // Whether or not to allow ANSI behavior. Mainly for testing (this should be true). this.allowANSI = true; + // Text to use for the user input prompt for the non-ANSI interface + this.nonANSIPromptText = "\x01n\x01c\x01hY\x01n\x01cour \x01hC\x01n\x01choice\x01h\x01g: \x01c"; + // Member functions this.Add = DDLightbarMenu_Add; this.Remove = DDLightbarMenu_Remove; @@ -2291,27 +2307,62 @@ function DDLightbarMenu_GetVal(pDraw, pSelectedItemIndexes) { // The user's terminal doesn't support ANSI var userAnswerIsValid = false; + var writePromptText = true; do { - console.print("\x01n\x01c\x01hY\x01n\x01cour \x01hC\x01n\x01choice\x01h\x01g: \x01c"); + if (writePromptText) + { + if (typeof(this.nonANSIPromptText) === "string" && console.strlen(this.nonANSIPromptText) > 0) + console.print(this.nonANSIPromptText); + else + console.print("\x01n\x01c\x01hY\x01n\x01cour \x01hC\x01n\x01choice\x01h\x01g: \x01c"); + } + writePromptText = true; // Default value console.attributes = "N"; - var userEnteredItemNum = console.getnum(numItems); - this.lastUserInput = userEnteredItemNum.toString(); - if (!console.aborted && userEnteredItemNum > 0) + var inputMode = K_NOECHO|K_NOSPIN|K_NOCRLF; + var userInput = console.getkey(inputMode); + var userInputUpper = userInput.toUpperCase(); + // Set this.lastUserInput if it's valid + if (console.aborted || userInputUpper == "Q" || userInput == CTRL_C || userInput == KEY_ESC) + { + if (userInputUpper == "Q") + this.lastUserInput = "Q"; + else if (userInput == CTRL_C || userInput == KEY_ESC) + this.lastUserInput = userInput; + else if (console.aborted) + this.lastUserInput = CTRL_C; + userAnswerIsValid = true; + } + else if (this.QuitKeysIncludes(userInput)) { - if (this.ItemIsSelectable(userEnteredItemNum-1)) + this.lastUserInput = userInput; + userAnswerIsValid = true; + } + else if (/[0-9]/.test(userInput)) + { + // Put the user's input back in the input buffer to + // be used for getting the rest of the message number. + console.ungetstr(userInput); + var userEnteredItemNum = console.getnum(numItems); + this.lastUserInput = userEnteredItemNum.toString(); + if (!console.aborted && userEnteredItemNum > 0) + { + if (this.ItemIsSelectable(userEnteredItemNum-1)) + { + var chosenItem = this.GetItem(userEnteredItemNum-1); + if (typeof(chosenItem) === "object" && chosenItem.hasOwnProperty("retval")) + retVal = chosenItem.retval; + userAnswerIsValid = true; + } + } + else { - var chosenItem = this.GetItem(userEnteredItemNum-1); - if (typeof(chosenItem) === "object" && chosenItem.hasOwnProperty("retval")) - retVal = chosenItem.retval; + this.lastUserInput = "Q"; // To signify quitting userAnswerIsValid = true; } } else - { - this.lastUserInput = "Q"; // To signify quitting - userAnswerIsValid = true; - } + writePromptText = false; // Invalid user input } while (!userAnswerIsValid && bbs.online && !js.terminated); } diff --git a/exec/load/portdefs.js b/exec/load/portdefs.js index 1ce9cadfd0707f9824dd3377b44a9d17a5e6391f..37f0abaca847ab6b7d080c35b76ff09edb90bfd4 100644 --- a/exec/load/portdefs.js +++ b/exec/load/portdefs.js @@ -7,7 +7,7 @@ // Mainly used for outgoing connections to URIs without a specified port // Duplicates port numbers for service name aliases are included -// (e.g. both "nttp" and "news") +// (e.g. both "nntp" and "news") var standard_service_port = { "systat": 11, // Active Users diff --git a/exec/tests/crypt/cryptkeyset.js b/exec/tests/crypt/cryptkeyset.js new file mode 100644 index 0000000000000000000000000000000000000000..2eeb6104929e130bc47557edce9e99569d4f6351 --- /dev/null +++ b/exec/tests/crypt/cryptkeyset.js @@ -0,0 +1,3 @@ +var ks = CryptKeyset("tmpkeyset", CryptKeyset.KEYOPT.CREATE); +ks.close(); +file_remove("tmpkeyset"); diff --git a/src/conio/cterm.c b/src/conio/cterm.c index cbf872daa9e65b04137a88cb21eedcb5db4c75f5..9875940932ea53db1147547acf47ee6e485802bb 100644 --- a/src/conio/cterm.c +++ b/src/conio/cterm.c @@ -4724,7 +4724,7 @@ cterm_reset(struct cterminal *cterm) struct cterminal* cterm_init(int height, int width, int xpos, int ypos, int backlines, int backcols, struct vmem_cell *scrollback, int emulation) { - char *revision="$Revision: 1.319 $"; + char *revision="$Revision: 1.320 $"; char *in; char *out; struct cterminal *cterm; diff --git a/src/sbbs3/ssl.c b/src/sbbs3/ssl.c index 0f1645386408f3c9bef3ff1fc37d3899bea74f4f..c7d8075d0fee9060936360642e26e237df29f3d8 100644 --- a/src/sbbs3/ssl.c +++ b/src/sbbs3/ssl.c @@ -310,7 +310,6 @@ static void internal_do_cryptInit(void) if ((ret = cryptInit()) == CRYPT_OK) { cryptAddRandom(NULL, CRYPT_RANDOM_SLOWPOLL); atexit(do_cryptEnd); - cryptlib_initialized = true; cryptInit_error = CRYPT_OK; } else { @@ -319,28 +318,24 @@ static void internal_do_cryptInit(void) ret = cryptGetAttribute(CRYPT_UNUSED, CRYPT_OPTION_INFO_MAJORVERSION, &maj); if (cryptStatusError(ret)) { cryptInit_error = ret; - cryptlib_initialized = false; cryptEnd(); return; } ret = cryptGetAttribute(CRYPT_UNUSED, CRYPT_OPTION_INFO_MINORVERSION, &min); if (cryptStatusError(ret)) { cryptInit_error = ret; - cryptlib_initialized = false; cryptEnd(); return; } ret = cryptGetAttribute(CRYPT_UNUSED, CRYPT_OPTION_INFO_STEPPING, &stp); if (cryptStatusError(ret)) { cryptInit_error = ret; - cryptlib_initialized = false; cryptEnd(); return; } tmp = (maj * 100) + (min * 10) + stp; if (tmp != CRYPTLIB_VERSION) { cryptInit_error = CRYPT_ERROR_INVALID; - cryptlib_initialized = false; cryptEnd(); if (asprintf(&cryptfail, "Incorrect cryptlib version %d (expected %d)", tmp, CRYPTLIB_VERSION) == -1) cryptfail = NULL; @@ -349,12 +344,12 @@ static void internal_do_cryptInit(void) ret = cryptGetAttributeString(CRYPT_UNUSED, CRYPT_OPTION_INFO_PATCHES, patches, &stp); if (cryptStatusError(ret) || stp != 32 || memcmp(patches, CRYPTLIB_PATCHES, 32) != 0) { cryptInit_error = ret; - cryptlib_initialized = false; cryptEnd(); if (asprintf(&cryptfail, "Incorrect cryptlib patch set %.32s (expected %s)", patches, CRYPTLIB_PATCHES) == -1) cryptfail = NULL; return; } + cryptlib_initialized = true; return; } @@ -409,7 +404,7 @@ bool ssl_sync(scfg_t *scfg, int (*lprintf)(int level, const char* fmt, ...)) // Paranoia... keep zero as initial value only. if (cert_epoch == 0) cert_epoch = 1; - pthread_mutex_lock(&ssl_cert_list_mutex); + assert_pthread_mutex_lock(&ssl_cert_list_mutex); while (cert_list) { struct cert_list *old; old = cert_list; @@ -417,7 +412,7 @@ bool ssl_sync(scfg_t *scfg, int (*lprintf)(int level, const char* fmt, ...)) cryptDestroyContext(old->cert); free(old); } - pthread_mutex_unlock(&ssl_cert_list_mutex); + assert_pthread_mutex_unlock(&ssl_cert_list_mutex); if (!rwlock_unlock(&cert_epoch_lock)) { lprintf(LOG_ERR, "Unable to unlock cert_epoch_lock for write at %d", __LINE__); } @@ -471,11 +466,11 @@ static struct cert_list * get_ssl_cert(scfg_t *cfg, int (*lprintf)(int level, co } cert_entry->next = NULL; - pthread_mutex_lock(&get_ssl_cert_mutex); + assert_pthread_mutex_lock(&get_ssl_cert_mutex); /* Get the certificate... first try loading it from a file... */ if (cryptStatusOK(cryptKeysetOpen(&ssl_keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, cert_path, CRYPT_KEYOPT_READONLY))) { if (!DO("getting private key", ssl_keyset, cryptGetPrivateKey(ssl_keyset, &cert_entry->cert, CRYPT_KEYID_NAME, "ssl_cert", cfg->sys_pass))) { - pthread_mutex_unlock(&get_ssl_cert_mutex); + assert_pthread_mutex_unlock(&get_ssl_cert_mutex); free(cert_entry); return NULL; } @@ -483,7 +478,7 @@ static struct cert_list * get_ssl_cert(scfg_t *cfg, int (*lprintf)(int level, co else { /* Couldn't do that... create a new context and use the cert from there... */ if (!DO("creating TLS context", CRYPT_UNUSED, cryptCreateContext(&cert_entry->cert, CRYPT_UNUSED, CRYPT_ALGO_RSA))) { - pthread_mutex_unlock(&get_ssl_cert_mutex); + assert_pthread_mutex_unlock(&get_ssl_cert_mutex); free(cert_entry); return NULL; } @@ -541,7 +536,7 @@ static struct cert_list * get_ssl_cert(scfg_t *cfg, int (*lprintf)(int level, co } cryptKeysetClose(ssl_keyset); - pthread_mutex_unlock(&get_ssl_cert_mutex); + assert_pthread_mutex_unlock(&get_ssl_cert_mutex); if (cert_entry->cert == -1) { free(cert_entry); @@ -559,7 +554,7 @@ failure_return_2: cryptKeysetClose(ssl_keyset); failure_return_1: cryptDestroyContext(cert_entry->cert); - pthread_mutex_unlock(&get_ssl_cert_mutex); + assert_pthread_mutex_unlock(&get_ssl_cert_mutex); cert_path[0] = 0; free(cert_entry); return NULL; @@ -574,10 +569,10 @@ static struct cert_list *get_sess_list_entry(scfg_t *cfg, int (*lprintf)(int lev lprintf(LOG_ERR, "Failed to lock cert_epoch_lock for read at %d", __LINE__); return NULL; } - pthread_mutex_lock(&ssl_cert_list_mutex); + assert_pthread_mutex_lock(&ssl_cert_list_mutex); while (1) { if (cert_list == NULL) { - pthread_mutex_unlock(&ssl_cert_list_mutex); + assert_pthread_mutex_unlock(&ssl_cert_list_mutex); if (!rwlock_rdlock(&cert_epoch_lock)) { lprintf(LOG_ERR, "Failed to unlock cert_epoch_lock for read at %d", __LINE__); } @@ -590,7 +585,7 @@ static struct cert_list *get_sess_list_entry(scfg_t *cfg, int (*lprintf)(int lev cryptDestroyContext(ret->cert); free(ret); } - pthread_mutex_unlock(&ssl_cert_list_mutex); + assert_pthread_mutex_unlock(&ssl_cert_list_mutex); if (!rwlock_rdlock(&cert_epoch_lock)) { lprintf(LOG_ERR, "Failed to unlock cert_epoch_lock for read at %d", __LINE__); } @@ -608,17 +603,17 @@ int add_private_key(scfg_t *cfg, int (*lprintf)(int level, const char* fmt, ...) } ret = cryptSetAttribute(csess, CRYPT_SESSINFO_PRIVATEKEY, sess->cert); if (cryptStatusOK(ret)) { - pthread_mutex_lock(&ssl_sess_list_mutex); + assert_pthread_mutex_lock(&ssl_sess_list_mutex); sess->next = sess_list; sess_list = sess; - pthread_mutex_unlock(&ssl_sess_list_mutex); + assert_pthread_mutex_unlock(&ssl_sess_list_mutex); sess->sess = csess; } else { - pthread_mutex_lock(&ssl_cert_list_mutex); + assert_pthread_mutex_lock(&ssl_cert_list_mutex); sess->next = cert_list; cert_list = sess; - pthread_mutex_unlock(&ssl_cert_list_mutex); + assert_pthread_mutex_unlock(&ssl_cert_list_mutex); } return ret; } @@ -629,7 +624,7 @@ int destroy_session(int (*lprintf)(int level, const char* fmt, ...), CRYPT_SESSI struct cert_list *psess = NULL; int ret = CRYPT_ERROR_NOTFOUND; - pthread_mutex_lock(&ssl_sess_list_mutex); + assert_pthread_mutex_lock(&ssl_sess_list_mutex); sess = sess_list; while (sess != NULL) { if (sess->sess == csess) { @@ -644,7 +639,7 @@ int destroy_session(int (*lprintf)(int level, const char* fmt, ...), CRYPT_SESSI psess = sess; sess = sess->next; } - pthread_mutex_unlock(&ssl_sess_list_mutex); + assert_pthread_mutex_unlock(&ssl_sess_list_mutex); if (sess != NULL) { if (!rwlock_rdlock(&cert_epoch_lock)) { lprintf(LOG_ERR, "Unable to unlock cert_epoch_lock for write at %d", __LINE__); @@ -656,10 +651,10 @@ int destroy_session(int (*lprintf)(int level, const char* fmt, ...), CRYPT_SESSI return CRYPT_ERROR_INTERNAL; } sess->sess = -1; - pthread_mutex_lock(&ssl_cert_list_mutex); + assert_pthread_mutex_lock(&ssl_cert_list_mutex); sess->next = cert_list; cert_list = sess; - pthread_mutex_unlock(&ssl_cert_list_mutex); + assert_pthread_mutex_unlock(&ssl_cert_list_mutex); ret = cryptDestroySession(csess); } else { diff --git a/src/syncterm/CHANGES b/src/syncterm/CHANGES index 6b2afa0ef7be8fef8f61680e4c7937ba728d712a..6c0b1b4505f11b0c7c0aa014ed736ea32b8815c3 100644 --- a/src/syncterm/CHANGES +++ b/src/syncterm/CHANGES @@ -5,6 +5,8 @@ Fix blast-through in Mode 7 high ASCII mosaics Update Prestel/Mode 7 keybindings Don't disable status line for Atari ST modes Fix broken vertical (U+00A6) vs. vertical line (U+007C) +Add custom palette support to list file +Pass control key combinations in BBC Micro mode Version 1.6 ------------