C program that connects to remote host and then executes system commands - c

I've looked around online about executing system commands through a c program, but none of them touched on executing the command after connecting to a remote host such as (this connection prompts for a user password):
sprintf(buffer1,"ssh -l %s %s ",userName,hostName);
system((char*)buffer1);
//Nothing below this executes because the connection has been established
sprintf(buffer2,"shasum sfin.exe > t.sha");
system((char*)buffer2);
Once the connection is closed the program then continues to execute, is there a simple way to keep the execution going?

You'll want to use the function popen instead of system.
http://linux.die.net/man/3/popen
It runs a command, returning a file object that you can write to with functions like fprintf, fwrite, etc., and those commands will go through the ssh process to the remote computer.

Related

C : how to to execute remotely a command line programm and interact with it from a server?

I made a simple tcp client in C (in windows I precise), which is controlled by netcat. I would like to be able to run a command line executable (such as Strings for example) remotely, and above all to be able to interact from netcat or my server with this programme.( (in order to perform actions on the remote computer in particular).
What would be the best solution to do that ?
edit : Here is an example : I want to run String programm on the remote computer. To do that, I can simply write "string" in netcat, this command would be interpreted by client, and this client execute strings binary. The output of strings should be displayed on netcat.
I precise that the binary of the programm can be on the remote computer, but it would be great if there is a way to execute it as a "real" remote programm, without need to get the executable on the remote machine.
First of all, your terminology is a bit off. You said you write a tcp client. But it seems you wrote a server. Because this programs should receive incoming tcp connection and request to then send responses.
In order to execute commands, you can use the exec* syscalls.
But then you would need to have the executables available in the machine.
Then you would need to build some for for loop around the tcp read that execute things for each line send, and a bit of setup to ensure that you redirect the output in the tcp connection. See the dupsyscall.
Ultimately, if you do not want to write a full shell-like program, you could just execthe system shell (cmd.exe on windows I think), and redirect all inputs/output to it.

How to know if an SSH connection failed?

I have to run a ssh command in a separate process (so by means of execlp) to connect the running machine to another machine in the same local network. The thing is, I have to establish the hostname entered is valid so the ssh connection succeeds.
Since, execlp replaces the calling process' image on a successful command run (which will be the case with ssh), there is, to the best of knowledge, no way of knowing in the calling process whether the ssh connection was successfully set up.
Hence, the sole solution to this incovenient behavior way I can think up is to assert the given hostname of the machine to connect to is valid. How can/should I about that?
(A valid hostname is simply one that exists and, of course, is reachable, be it an IP adress or an alias)
In order to spare myself all the pipe setting, I use
popen() to run ssh. So yes, if there is no
other way, I might have to go down the less lazy path. …
waitpid() …
You don't have to go down the less lazy path. man popen:
The pclose() function waits for the associated process to terminate
and
returns the exit status of the command as returned by wait4(2).

Running two socket applications within one program

I have two C/C++ socket programs, say server and client, and both communicate to each other through read and write. The entire flow works fine (i.e., communication, read, write) when I run the two programs on two separate terminals in localhost. To avoid manually starting the client program, I use system(exec_cmd_to_run_client_program) in my server program. However, doing so doesn't give me the correct result as that of two separate terminals. I do see server and client running in the job monitor, but the communication in between seems never happens. What could be the problem?
Also I tried using ssh library libssh in the server program to open a new ssh session and send execution command to run the client program. Again I see the same result as system call. Both programs showed up in the job monitor but communication never happens. Did I miss something?

Interpreting commands sent over ssh

Say from a PC, a SSH client will be sending commands (such as custom commands for my program e.g. ("show list of devices")). On my Linux end I want to have a program which will recieve these commands sent over SSH and execute them.
I'm trying to write a c program running on the linux side to interpret the custom commands sent and process them as per my requirements. Any suggestions as to how I would achieve this?
UPDATE:
There are 2 programs here. The 1st program running on a PC1 which gives a command line interface, by which the user can issue commands. The second program is on the Linux end(PC2) which has to receive these commands and process it. Right now I'm thinking on the second program on how to get those commands.
You can do this in at least two different ways:
Execute the C program (say client) through ssh and send commands as arguments. The client parses arguments and does whatever. You need to run the client for each command.
Your C program reads commands from the standard input, so you execute the C program over ssh once, and pipe your commands to ssh.
If your commands are not so frequent then do the 1st one. You can even execute ssh instances in the background and effectively run client commands in parallel. If you have a lot commands in sequence then implement the 2nd way. It will be harder to run them in parallel and relatively harder to parse commands since 1st way will give you each parameter as a different argument. With the second method, it will be much more efficient and faster to process frequent commands since you will not be establishing a connection and forking a process per command.
This is really about communicating with another program, and has very little to do with ssh - since ssh is just the "pipework" - what you need to do is open two pipes (one for stdin, one for stdout) to your application [which happens to be ssh], and write to the stdin pipe, and read from the stdout pipe. If you can do this with a regular (local) program, then all you need to do is add "ssh" to the line you are executing, and you're done.
If you don't understand what this means, look up exec, popen, pipes, etc.
You obviously also need the program at the other end to read from its stdin and write to its stdout. But that's normal command line programming, so I don't see that as a huge problem.

Problem with bin/sh -i in a forked process, error: 'can't access tty, job control turned off'

I'm writing a cgi-bin program for my Sheevaplug (running the default Ubuntu install) that displays a shell in a browser page. It is a single C program that is placed in the cgi-bin folder and viewed in a browser. It automatically launches a daemon and the daemon forks an instance of the shell. The cgi-bin communicates with the daemon via shared memory block, and the daemon communicates with the shell by redirecting its stdin/stdout to the shell's stdout/stdin. When you leave the page it automatically turns off the daemon.
It works if I launch it using "/bin/sh" and I send a whole command line at a time from the browser to it. But using that design it's not interactive.
So I changed it to send a character at a time to "/bin/sh" and added "-i" so the shell runs in interactive mode.
When the shell starts up it displays the error "can't access TTY, job control turned off."
It then displays the '$' when it is ready for input and seems to work, but sending delete characters to it just confuses it and it doesn't properly handle deleting. I'm not really sure if it is in interactive mode or not. When I type 'su root' I get the error "must be run from a terminal'.
Any ideas what I am doing wrong?
PS: When I have it done it will be released under the GPL.
For interactive mode, sh wants to be talking to a terminal or something that emulates one (a pseudo-terminal), not just direct IO pipes. Consider using forkpty to start the process you launch the shell from, and talking to the streams provided by that.

Resources