Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to render a remote ncurses console?

I wanna write a remote console, working like a telnet server. User is able to use telnet to log into the server, then write some commands to do some works.

A good example for this is the console of router os. What I'm confusing right now is, I can accept user's input, do someting then print some texts back, but I wanna use ncurses to make the console has more features(such as "cmd auto-complete", syntax color...), so how can I do that? Because the console is in user side, if the server calls ncurses APIs it'll just change stuffs on server...

Maybe this is a stupid question but I'm really newbie on this. Any suggestions are appreciated.

like image 875
Mark Zhang Avatar asked May 05 '13 07:05

Mark Zhang


2 Answers

This is more difficult than you might think.

You need to understand how terminals work - they use special control sequences for e.g. moving the cursor or color output. This is described by a terminfo file which is terminal-specific. Ncurses translates API calls (e.g. move cursor to a certain position) to such control sequences using terminfo.

Since the terminal (nowadays xterm, gnome-terminal, screen, tmux, etc) is on the client side, you have to pass the type of terminal from the client to the server. That's why e.g. ssh passes this information from the ssh client to the server (try echo $TERM in your ssh session - it might be 'linux' if you are logged in via the console, or 'xterm', if you are using X and an xterm). Also, you better have the respective terminfo available on the server.

Another piece of the puzzle is pseudo terminals. As nowadays relatively few people use serial terminals, their semantics are emulated so that applications and libraries (e.g. curses and its friends) originally developed for serial consoles keep working. This is achieved via pseudo terminals - these are like pipes, a master and a slave device communicates, anything written on one side comes out on the other side. For a login process, getty, for example, can just use one side of a pty device and think it's a serial line - your server program must handle the other side of the pty, sending everything it gets from the pty to your client via the network.

Terminal emulators also use ptys, type tty into your terminal, and you'll get something like /dev/pts/9 if you're using a terminal emulator. On the other side of the pty it's usually your shell, communicating with your terminal emulator via the pty.

Your client program can more or less just use standard input and standard output. If your terminal information is correct, the rest will be handled by your terminal emulator, just pass anything you receive from your server program to stdout, and send anything you read from stdin to your server program.

Hopefully I haven't left out any important detail. Good luck!

like image 57
ldx Avatar answered Oct 29 '22 09:10

ldx


It is possible to have ncurses operate on streams other than stdin and stdout. Call newterm() before initscr() to set the input and output file handles for ncurses.

But you will need to know what sort of terminal is on the remote end of the connection (ssh and telnet both have mechanisms for communicating this to the server) and you will also want a fall back to a non-ncurses interface in case the remote end is not a supported terminal type (or if you can't determine the terminal type).

like image 39
Craig Avatar answered Oct 29 '22 09:10

Craig