How can I quickly test for the presence of an Xserver - xserver

I have a setup such that sometimes I use xterm and sometimes I use putty. The command
xmodmap ~/.Xmodmap
takes longer to run when I am on putty because there is no xserver at DISPLAY.
Without getting into a heated discussion of whether or not my setup is right (because I can't change it), or whether the time difference is significant (no, it's not, but if you don't ask, you'll never learn), is there a way to ping the supposed xserver at DISPLAY to that it comes back instantaneously if there is no xserver there? That way I could set a flag and skip further X client calls, instead of calling xmodmap (or xterm or any other X client) and waiting for the inevitable timeout and 'unable to open display at' message.

xmodmap 1>/dev/null 2>/dev/null
if (($?))
then
## There is no xserver. Do not set any of this up.
return 0 ## return, not exit because this script is meant to be 'dotted in'
fi

Related

Configure TeraTerm to wait for "Enter" key stroke? Or solve PuTTY COM connection error

I am using TeraTerm to send strings over COM port using the Serial connection in TeraTerm. I had tried to use PuTTY but it refuses to connect to the COM port and I am not sure why. It says
Unable to open connection to COM4
Unable to configure serial port
That is neither here nor there, but it does mean that PuTTY like will not be usable for my application.
One thing PuTTY does well, though, is it includes the option for "Local line editing" which means I can make the serial window wait for the "Enter" keystroke before it sends it over COM port. I am looking for a way to make TeraTerm do that as well as right now it sends every character as it is entered into the window.
ie if I type in the word "Test", the window is sending T/r/n, e/r/n, s/r/n, t/r/n as opposed to Test/r/n
If someone could help me solve this in TeraTerm, or help me fix my PuTTY connection, that would be much appreciated as well.
When typing characters into TT, the characters are sent out as you type them, and there is no way to configure it otherwise. If anything is sent with each character, this is configurable, but there is no way to configure TT in such a way to "send nothing" until you type 'enter', as other "terminals" do.
Some devices receive the commands in a buffered way and have a short timeout between the characters, so you are never able to "type" a command in TT. For example, many USB devices which use USB-to-serial internals (like ST development tools and MCUs). This is because the USB sends "frames" with each character you type, and the device expects to receive a "full command" in a frame, if the frame is not a valid command, is discarded.
When you type "test", unless you are lightning fast, four frames will be sent. If that is your case, you have to use another terminal program (there are plenty available). If for any reason you are restricted to TT, then you can use the following trick:
write the command in your favorite editor, like PN2, Notepad++, etc., (or even TT itself in a separate terminal, not connected to your target board) copy it with ctrl+c or whatever, and then switch to TT and press either alt+v or alt+r to send it out without, respective with, a CRLF ending (see the edit menu in TT/VT). The ending can be configured from the setup/terminal menu, and (if enabled in setup/additional_settings/copy_and_paste menu) the mouse's right or mid clicks can be also used.
I usually have a list of commands pre-written, opened in a different window, and instead of typing, the "work" is a sequence of "double click in pn2 window" (to select command), ctrl+c (to copy it), "right click in TT window" (to send it out).

gawk to read last bit of binary data over a pipe without timeout?

I have a program already written in gawk that downloads a lot of small bits of info from the internet. (A media scanner and indexer)
At present it launches wget to get the information. This is fine, but I'd like to simply reuse the connection between invocations. Its possible a run of the program might make between 200-2000 calls to the same api service.
I've just discovered that gawk can do networking and found geturl
However the advice at the bottom of that page is well heeded, I can't find an easy way to read the last line and keep the connection open.
As I'm mostly reading JSON data, I can set RS="}" and exit when body length reaches the expected content-length. This might break with any trailing white space though. I'd like a more robust approach. Does anyone have a nicer way to implement sporadic http requests in awk that keep the connection open. Currently I have the following structure...
con="/inet/tcp/0/host/80";
send_http_request(con);
RS="\r\n";
read_headers();
# now read the body - but do not close the connection...
RS="}"; # for JSON
while ( con |& getline bytes ) {
body = body bytes RS;
if (length(body) >= content_length) break;
print length(body);
}
# Do not close con here - keep open
Its a shame this one little thing seems to be spoiling all the potential here. Also in case anyone asks :) ..
awk was originally chosen for historical reasons - there were not many other language options on this embedded platform at the time.
Gathering up all of the URLs in advance and passing to wget will not be easy.
re-implementing in perl/python etc is not a quick solution.
I've looked at trying to pipe urls to a named pipe and into wget -i - , that doesn't work. Data gets buffered, and unbuffer not available - also I think wget gathers up all the URLS until EOF before processing.
The data is small so lack of compression is not an issue.
The problem with the connection reuse comes from the HTTP 1.0 standard, not gawk. To reuse the connection you must either use HTTP 1.1 or try some other non-standard solutions for HTTP 1.0. Don't forget to add the Host: header in your HTTP/1.1 request, as it is mandatory.
You're right about the lack of robustness when reading the response body. For line oriented protocols this is not an issue. Moreover, even when using HTTP 1.1, if your scripts locks waiting for more data when it shouldn't, the server will, again, close the connection due to inactivity.
As a last resort, you could write your own HTTP retriever in whatever langauage you like which reuses connections (all to the same remote host I presume) and also inserts a special record separator for you. Then, you could control it from the awk script.

stty and sending carriage return

I have a serial device with which I am trying to communicate. This device knows when a complete command has been sent when the command string is terminated with a "\r". Thus, a typical command string might be something like "COMMAND \r".
I'm having trouble configuring stty in such a way that the carriage return gets sent to the device. Currently, the device will not respond to any of my commands, so it's as if the input to the device is still "hanging."
I've written some simple C code where I bypass the terminal and there I can successfully elicit replies from the device, which is the reason why I think that the commands are not being properly terminated in the terminal. I've tried many different permutations of -+onlcr, +icanon, etc to no avail. The baudrate, parity, data bits, start and stop bits are all properly configured, as far as I can tell.
How can I debug this issue?
What is the platform (machine)? What is the OS?
Have you tried to flush the output with
fflush( FILE * FP );
Tried COMMAND\r\n ? What's the device?

Prevent FIFO from closing / reuse closed FIFO

Consider the following scenario:
a FIFO named test is created. In one terminal window (A) I run cat <test and in another (B) cat >test. It is now possible to write in window B and get the output in window A. It is also possible to terminate the process A and relaunch it and still be able to use this setup as suspected. However if you terminate the process in window B, B will (as far as I know) send an EOF through the FIFO to process A and terminate that as well.
In fact, if you run a process that does not terminate on EOF, you'll still not be able to use your FIFO you redirected to the process. Which I think is because this FIFO is considered closed.
Is there anyway to work around this problem?
The reason to why I ran into this problem is because I'd like to send commands to my minecraft server running in a screen session. For example: echo "command" >FIFO_to_server. This is problably possible to do by using screen by itself but I'm not very comfortable with screen I think a solution using only pipes would be a simpler and cleaner one.
A is reading from a file. When it reaches the end of the file, it stops reading. This is normal behavior, even if the file happens to be a fifo. You now have four approaches.
Change the code of the reader to make it keep reading after the end of the file. That's saying the input file is infinite, and reaching the end of the file is just an illusion. Not practical for you, because you'd have to change the minecraft server code.
Apply unix philosophy. You have a writer and a reader who don't agree on protocol, so you interpose a tool that connects them. As it happens, there is such a tool in the unix toolbox: tail -f. tail -f keeps reading from its input file even after it sees the end of the file. Make all your clients talk to the pipe, and connect tail -f to the minecraft server:
tail -n +1 -f client_pipe | minecraft_server &
As mentioned by jilles, use a trick: pipes support multiple writers, and only become closed when the last writer goes away. So make sure there's a client that never goes away.
while true; do sleep 999999999; done >client_pipe &
The problem is that the server is fundamentally designed to handle a single client. To handle multiple clients, you should change to using a socket. Think of sockets as “meta-pipes”: connecting to a socket creates a pipe, and once the client disconnects, that particular pipe is closed, but the server can accept more connections. This is the clean approach, because it also ensures that you won't have mixed up data if two clients happen to connect at the same time (using pipes, their commands could be interspersed). However, it require changing the minecraft server.
Start a process that keeps the fifo open for writing and keeps running indefinitely. This will prevent readers from seeing an end-of-file condition.
From this answer -
On some systems like Linux, <> on a named pipe (FIFO) opens the named pipe without blocking (without waiting for some other process to open the other end), and ensures the pipe structure is left alive. For instance in:
So you could do:
cat <>up_stream >down_stream
# the `cat pipeline keeps running
echo 1 > up_stream
echo 2 > up_stream
echo 3 > up_stream
However, I can't find documentation about this behavior. So this could be implementation detail which is specific to some systems. I tried the above on MacOS and it works.
You can add multiple inputs ino a pipe by adding what you require in brackets with semi-colons in your 'mkfifo yourpipe':
(cat file1; cat file2; ls -l;) > yourpipe

How to send characters in PuTTY serial communication only when pressing enter?

I am trying to use PuTTY to communicate over my computer's serial line. I have configured the correct serial line, baud rate, number of data bits, stop bits, parity, and flow control, and established the connection. When I click OK to open the connection, I am shown a black screen and each of my key presses are sent without being shown on the screen (the window remains black). How do I configure PuTTY so that it only sends my commands or opcodes after I press enter?
I have used PuTTY while at college for Telnet / SSH and it always showed my commands and input them only after I pressed the enter key, so I am a bit confused.
The settings you need are "Local echo" and "Line editing" under the "Terminal" category on the left.
To get the characters to display on the screen as you enter them, set "Local echo" to "Force on".
To get the terminal to not send the command until you press Enter, set "Local line editing" to "Force on".
Explanation:
From the PuTTY User Manual (Found by clicking on the "Help" button in PuTTY):
4.3.8 ‘Local echo’
With local echo disabled, characters you type into the PuTTY window are not echoed in the window by PuTTY. They are simply sent to the server. (The server might choose to echo them back to you; this can't be controlled from the PuTTY control panel.)
Some types of session need local echo, and many do not. In its default mode, PuTTY will automatically attempt to deduce whether or not local echo is appropriate for the session you are working in. If you find it has made the wrong decision, you can use this configuration option to override its choice: you can force local echo to be turned on, or force it to be turned off, instead of relying on the automatic detection.
4.3.9 ‘Local line editing’
Normally, every character you type into the PuTTY window is sent immediately to the server the moment you type it.
If you enable local line editing, this changes. PuTTY will let you edit a whole line at a time locally, and the line will only be sent to the server when you press Return. If you make a mistake, you can use the Backspace key to correct it before you press Return, and the server will never see the mistake.
Since it is hard to edit a line locally without being able to see it, local line editing is mostly used in conjunction with local echo (section 4.3.8). This makes it ideal for use in raw mode or when connecting to MUDs or talkers. (Although some more advanced MUDs do occasionally turn local line editing on and turn local echo off, in order to accept a password from the user.)
Some types of session need local line editing, and many do not. In its default mode, PuTTY will automatically attempt to deduce whether or not local line editing is appropriate for the session you are working in. If you find it has made the wrong decision, you can use this configuration option to override its choice: you can force local line editing to be turned on, or force it to be turned off, instead of relying on the automatic detection.
Putty sometimes makes wrong choices when "Auto" is enabled for these options because it tries to detect the connection configuration. Applied to serial line, this is a bit trickier to do.

Resources