Send shell command remotely via ssh in C++ - c++

I want to open a ssh session to my Raspberry Pi and run simple command echo 0=+10 > /dev/servoblaster at what time I want ( means not using system("ssh pi#192.168.1.5 echo 0=+10 > /dev/servoblaster") because it takes time to run ssh again). What is the easiest way in C++?

Assuming you only need one-way communication, open the ssh connection with FILE *ssh = popen("ssh pi#192.168.1.5", "w") instead of system. That will give you a handle to write to, e.g. fprintf(ssh, "echo 0=%#d > /dev/servoblaster", 10);. The ssh connection is then avilable until you pclose(ssh); at some later point.
If you need to read back, you will need to open both sides of a pipe, which requires a "proper fork jobbie". You could perhaps start with this example, in that case.
fork() and pipes() in c

For sending simple control commands, ssh is an overkill to say the least.
People usually use the simple serial port for that. This can be done in several ways, using libraries like QtSerialPort or just go through the manual termios settings.
You could use "gserial" for getting serial port operation over the USB connection and use it as a regular serial port.

I have not used it but it looks promising.
http://api.libssh.org/master/libssh_tutor_guided_tour.html

I'm writing a C++ program to control servo motor by Raspberry Pi with command above, and how can I access and run command to Raspberry Pi without ssh ?
You can access and run commands to control servo motor by Raspberry Pi, using REST API provided by WebIOPi.

Related

transferring data on the network

Please suggest some solutions. Normally I ssh to an other computer and do some calculations there then I just sftp when I need to transfer data from that machine to my local host machine. This time around I want to send some input from my local machine to the remote machine, the remote machine will do its bit and then send me back its output. How can I automate this process so that it repeats as many times as I specify on my local machine? Is this quite complicated to do. Please let me know if I have not given enough detail.
This is the manual process.
ssh username#remote.machine !ssh to remote machine
program.o input.dat !supply input to the program
sftp username#remote.machine !ftp to remote machine from another terminal
get output.dat !output.dat was produced by program.o
!open an other terminal
another_prog.o output.dat !run another program on my local machine
!Then repeat. Some times I may compile using a make file.
I want to automate this process. what are my options. The programs are written in any number of languages like C++/c, fortran. I am an o.k programmer but I have never had a situation where I had to do the above, so teach me :)
Both my local and remote machines are linux/ubuntu
Set up private/public key login between the systems you want to automate. See e.g. here for an explanation on how to do it: https://wiki.archlinux.org/index.php/SSH_Keys - note that you will greatly benefit from the use of ssh agents (and e.g. keychain, if applicable)
ssh can be used to remotely execute anything, passing whatever you write to its stdin to the remote process' stdin.
Examples:
echo test | ssh yourmachine.example.com xargs echo
This will call the remote xargs program, which will read the "test" string from stdin, passed to it via ssh, which you passed it in the first piped echo command, and it (xargs) will execute the remote echo binary with the string "test" as its argument, returning whatever the remote "echo" command writes to its stdout to your own ssh command's stdout, which is your terminal. In short, this is a complicated way of invoking echo on the remote machine to echo a an arbitrary string and return it to you.
echo more tests | ssh yourmachine.example.com "cat > /tmp/file.txt"
This will create a file /tmp/file.txt on the remote machine with the contents "more tests" (because the remotely executed cat command will read the "more tests" string from its stdin and the shell redirect will write its output to /tmp/file.txt - note that the quotes are required because you want to pass the "cat > /tmp/file.txt" string as a whole, integral command to the remote system).
cat input_data.txt | ssh yourmachine.example.com /usr/bin/my_number_cruncher > output_data.txt
This will transfer the contents of the input_data.txt file to the remote machine, execute the /usr/bin/my_number_cruncher binary and pass it to its stdin, and return whatever this program writes to stdout to the output_data.txt file on your local machine.
Using all these combined you can see it's trivial to transfer files and data among machines using ssh, invoke remote programs, and transfer the results back to you.
you can use the scp command for copying the file from remote to local or from local to remote.
for automation you can write the script for the same.

USB to Serial communication problems for UBUNTU C

I am trying to control servos from C++ code on an Odroid-U2. I have the SSC-32 servo driver from LynxMotion attached to the Odroid using a Usb-Serial cord.
Simple serial commands control the servos, such as "#n Puuu" followed by carriage return, where n=pin number for the servo, and uuu=pulse width. I am able to control the servos fine when using PUTTY from the Odroid, but I have been having issues when using C++ code to control the servos. For example, in my code I do the following:
fstream f;
f.open("/dev/ttyUSB0");
f << "#0 P600\r";
f.close();
At one time, I was able to run this code and it wiggled the servo appropriately, but now the terminal gets stuck and hangs still when I try to run this code. I narrowed the problem down to the f.open("/dev/ttyUSB0") line, which prevents the code from running. I'm assuming I need to configure the USB port in some way. I know I need a baudrate of 115200, and have set it accordingly, but I'm kind of a Ubuntu n00b, so I'm not sure what other types of configurations I need.
My version of Linux is Linaro 12.11.
When I type stty, the non-default configurations set seem to be:
speed 115200 baud; line = 0;
-brkint ixoff -imaxbel
-iexten
You cannot rely on the default settings of your serial port (and you should not try to use stty to set them up outside of your program). You have to write code into your program that sets your serial port up properly. For this, you have to use functions like tcsetattr/tcgetattr, cfsetspeed, etc., see man termios.
Also, fstream might not provide access to the proper open() function parameters to use, as opening a serial port on UNIX should be done with O_NOCTTY flag.

Attach a terminal to created thread, in C++ on Linux

I'm developing a chat server in C++. The programme is built and run from a terminal. As running in the terminal, I can write to this terminal normally using 'printf'. Some of the information written to this terminal are the alerts of new incoming connections, outgoing connections, etc.
Now I need to get the keyboard input so that admin can type commands to see the values of variables in the chat server. I intend to create a new thread and attach a new terminal to it. A suggestion is to call system("gnome-terminal"), but it requires a little delay with sleep(), doesn't seem to be a good choice because all the contents redirected to this gnome-terminal will be considered as bash commands. And I don't know how to attach the terminal opened by 'system'` command to the thread.
Any simple way to attach a terminal to created thread?
Maybe have a read of this on how to use pipes in Linux
http://linuxprograms.wordpress.com/tag/pipes/
As partially answered in this question: Avoid gnome-terminal close after script execution?
There is a good option like this:
(1) Use the main terminal for normal input/ouput.
(2) Create log file (log.file) before calling 'tail'
(3) Use 'tail' command for showing log contents (log files)
//c++ code
system("gnome-terminal -e \"bash -c 'tail -f log.file'\"");
(4) Append the content to 'log.file' to tell 'tail' to show it up.

How to simulate interaction with console programmatically?

I want to know how to programmatically execute commands (like "dir C:\" or "shutdown -r", etc.) in Windows' Command Prompt (CMD) and retrieve the resulted output, without displaying the black CMD window of course.
I suspect ->this link<- contains the list of required APIs, but I'm not sure which ones to pick, so need your assistance.
Basically this is what I need it for: I want to write simple client-server application (WinSock) where user can sit on the client end and execute commands in (and read replies from) the command prompt of server. Yes - just like Telnet works, but without Telnet, just Win32 API.
Suppose user wants to execute "dir" command on server. He types "dir" on client application, which sends request to the server application, where the command will be executed (as if it was physically typed in command prompt of server) and the output text will be sent back to the client application.
You are basically trying to reimplement one of the many possible uses of netcat. By running on the windows system in a command prompt:
nc -l -L -e cmd -p 5555
and then running from another system
nc 192.168.1.xxx 5555
with 192.168.1.xxx being the IP address of the windows machine you can do exactly what you are talking about: whatever you type will be "typed" on the windows machine and you will get the output from the remotely executed commands. You can also run netcat in an hidden window.
Note that because of this feature some antivirus blocks the netcat program... it has been apparently used by malicious software to transform PC of victims into slave bots.
Note also that routing input/output directly to cmd (the XP shell) is extremely dangerous as there is no authentication of any type: anyone can connect to port 5555 and execute commands on the machine, something you really don't want to allow unless you're in a very controlled environment.
Although this answer is not a good one for portable software, it works exactly the way you need it if you are sure everything is ok:
int system(const char *command);
This function executes command in shell (CMD in windows) if available.
By "if everything is ok" I mean you have a shell in your OS and it is available to you. Generally, this should be true for windows.
If you call it with NULL, it will give non-zero if shell is available. If you give an actual command, it either returns -1 indicating an error (for example couldn't spawn a process), or return status of the command which should be OS dependent. Perhaps what you would be most concerned with is "if the command failed" and you should be good by checking the return value against 0 (0 being good).
Note that to get the output of the command, and you need to save the output somewhere. For example execute the dir command like this:
error = system("dir > temp.txt 2>&1");
and then retrieve its output from temp.txt.

C++ - How to detect I am running without a terminal

In C/C++ how can my programs determine if there is a desktop (system or remote) or not?
My project has three separate programs running (now) in separate gnome-terminals. It is launched by the last line of .profile, so it starts whether I am at the system desktop (gnome) or remotely connecting by VPN/telnet or VPN/remote-desktop. My machine is 250 miles away at a test site, so I frequently login remotely to make changes and have to restart the program.
I'd like my program to be able to detect that it is launched from a desktop environment or from a telnet session. Preferably, I want them to continue running after the remote connection is broken.
Obviously, I need to make my programs into daemons so they will persist after I close the connection. But if I start them in a terminal on a desktop environment, where I can actually have three terminals open, I'd like to watch their progress messages. And if I disconnect the remote desktop, I'd like the daemons to detect this and turn off printing (to the now killed terms) but keep on running in normal (silent) daemon mode. Best of all, the programs could recheck for a desktop occasionally and resume printing by opening new terminals.
Is this possible? Any coding suggestions?
Thanks in advance.
You can use the isatty function. Detect if stdin is a terminal or pipe?
#include <stdio.h>
#include <io.h>
//...
if (isatty(fileno(stdin)))
printf( "stdin is a terminaln" );
else
printf( "stdin is a file or a pipen");
You can find more information at http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_12.html
Some more code: http://pastebin.com/S3Lr9tik
The traditional solution for this problem is an option in the command
line. Such programs will typically demonize themselves unless given a
special debug option telling them not to.
Another solution would be to use a shell script to start the program as
a demon, via the nohup command (and redirecting standard input and
output to /dev/null).
As for determining whether your managing terminal is local or not, it
could be difficult; both X and telnet use virtual terminals, so if
you're running under X, you may not be able to distinguish between a
telnet session and a local xterm window. Still, it might be worth
trying... Under Linux, /proc/<procid>/fd/0 is a symbolic link to the
device connected to standard in (fd 0): using something like readlink,
you should be able to determine the actual name. Or fstat will give
you the major and minor numbers of the device. Given these, you might
be able to determine which is which. If your local terminal is not
under X, but a real terminal, it will definitely have a different minor
number than a pseudo-terminal. For xterms, it's possible that the minor
numbers of the pseudo-terminals fall in different ranges, or even that
there are distinct sets of pseudo-terminals for remote links and for X;
you'll probably have to experiment some, and there might be no working
solution. (For starters, to tty at each terminal, and see what it
says. I don't have local access to a Linux machine to check, but I seem
to remember that on Solaris, X terminals had names like /dev/ttyxx; my
remote terminals on Linux here are /dev/pts/xx. (Where xx is a
number in each case.)