dankamongmen / notcurses

blingful character graphics/TUI library. definitely not curses.
https://nick-black.com/dankwiki/index.php/Notcurses
Other
3.58k stars 112 forks source link

provide default when TERM is not defined or terminfo is unavailable #2256

Open j4james opened 3 years ago

j4james commented 3 years ago

Please include the following data:

Steps to reproduce:

  1. Telnet into a remote server that doesn't have yaft installed, and doesn't have the yaft-25color terminfo entry.
  2. Run notcurses-info
  3. Note that it aborts with the following message:
    Gi=1,a=g;interrogate_terminfo:834:Terminfo error 0 for [] (see terminfo(3ncurses))

The bit at the beginning is the result of the Kitty APC query I think, but the rest is coming from here: https://github.com/dankamongmen/notcurses/blob/368d32e337f9da510b7ec5236f0b8e9e6635087a/src/lib/termdesc.c#L833-L837

Technically you can reproduce this on any terminal, just by setting TERM to some random value, but in practice it's most likely to happen on terminals that use something other than xterm-256color (or one of the common variants), and don't have their own terminfo included in the default terminfo database.

I suppose the expected remedy is for users to manually install the appropriate terminfo on any machine they connect to, but that isn't always feasible, so it would be nice if there was some sort of fallback here that still enabled notcurses to run.

j4james commented 3 years ago

Just checked with Kitty, which uses xterm-kitty for its TERM value, and that also fails in a similar way.

dankamongmen commented 3 years ago

I suppose the expected remedy is for users to manually install the appropriate terminfo on any machine they connect to, but that isn't always feasible, so it would be nice if there was some sort of fallback here that still enabled notcurses to run.

i almost feel the reverse: if you're unable to install a correct config, it's on you to select the least-worst incorrect config, and export TERM=that

dankamongmen commented 3 years ago

also, this would admit e.g. misspellings and just fall back to some approximation.

i've considered taking prepare_windows_terminal()'s definitions (on Windows we don't use setupterm()), and always setting them up, or some "ansi" profile. i've also considered building the terminfo definitions directly into Notcurses (though that wouldn't help this particular problem; it's intended for "i have no libterminfo installed"). i've also considered using XTGETTCAP to interrogate the terminal, and thus become independent of terminfo completely. none of these ideas have seemed very wonderful on further reflection (though the third has some merit, where XTGETTCAP is supported anyway).

dankamongmen commented 3 years ago

2144 goes into more detail.

dankamongmen commented 3 years ago

i don't think i like this idea. if we're going to second-guess terminfo, i'd like to just strongly decouple us from terminfo. in what situation would it be impossible to install your own terminfo? i guess where you can't control the environment at all (to set TERMINFO_DIR) or can't write anywhere... i'd maybe be willing to do this when TERM was entirely unset, or set to unknown... but i am very hesitant to just fall back when an explicit terminfo database entry has been specified.

dankamongmen commented 3 years ago

but yeah, this is definitely working as intended unless we can come up with an acceptable alternative.

dankamongmen commented 3 years ago

so, i think i stand by my statement above: if the user has requested a particular terminfo entry by the specification of some TERM variable, but we cannot initialize terminfo with that key, we ought abort.

with that said, i'd be willing to provide a minimal, default configuration for the case of TERM=unknown or no TERM variable. @j4james , would that suffice for the cases you're thinking of, where the user for whatever reason can't install and/or reference a correct terminfo specification?

j4james commented 3 years ago

I can't really complain, because I don't typically use either of the terminals on which I noticed this problem. But note that the user isn't the one setting the TERM variable - it's done by the terminal itself.

And the use-case I had in mind (where you can't install the correct terminfo) is when you're connecting directly to a remote application (built with notcurses) rather than logging into a shell first. But I suppose the application itself could override the TERM variable in that case. And worst case the user can always override the TERM before making the connection.

Anyway, I just wanted to make you aware of the issue, in case you wanted to do something like fallback to a default config rather than aborting.

dankamongmen commented 3 years ago

oh, i was very definitely aware of the situation =]. no i appreciate your input.

And the use-case I had in mind (where you can't install the correct terminfo) is when you're connecting directly to a remote application (built with notcurses) rather than logging into a shell first.

so like ssh -T remote ncapplication? explicitly disabling allocation of a pty for ssh? (that's the only interpretation i have for "connecting directly"). yeah that fails right now. hrmmmm what could i do for that case...,probably treat it as unknown like i'm thinking.

j4james commented 3 years ago

so like ssh -T remote ncapplication?

I was actually thinking something more along the lines of a Telnet BBS, or for telnet gaming (can't find a working example right now, but this is the sort of thing I had in mind: https://milek7.pl/tracehack/). Probably not a common use-case though - just a particular interest of mine.

dankamongmen commented 3 years ago

with telnet you have TERM-TYPE negotiation, and if that fails, NEW-ENVIRON can pass it, right? i'm not sure i'm familiar with exactly what's going on here. in any case, in this setup, would you just be lacking a TERM definition entirely? if so, my suggested scheme ought help.

j4james commented 3 years ago

So when the user starts up their terminal, it's going to set a weird TERM variable like say xterm-kitty (and your average user potentially has no knowledge of that). They then run telnet cool-game.example.com which connects to the game server and passes on that TERM variable in the TERM-TYPE negotiation. The backend (running notcurses) tries to lookup the terminfo, can't find it, and aborts.

If you automatically fall back to unknown instead of aborting, that would probably be the ideal solution. If you require the user to manually set their TERM to unknown or blank before connecting, that is also workable, but your average user probably wouldn't know to do that. If I were writing a notcurses-based server in that state, I'd probably have an inititialisation step that fixed up the TERM variable myself.