How to simulate interaction with console programmatically? - c++

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.

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.

Open the terminal and execute commands via C programming

Does someone know how to open the terminal and execute several commands using a C program ?
I have a program in C and another sets of commands executed by the terminal. I need to combine them into one program in C.
I'm using Ubuntu 10.04.
Thanks!
Your question may be somewhat misleading.
Because you want to run all the terminal commands in the c-code, perhaps you actually have only textual input / output with these commands. If so, you probably do not need the terminal.
I use popen when the output of the (terminal) program is a text stream. It is probably the easiest to use. As an example:
...
const char* cmndStr = "ls -lsa";
FILE* pipe = popen(cmndStr, "r");
...
The popen instruction executes the command in the cmndStr, and any text written to the commands (ls -lsa) standard output, is redirected into the pipe, which is then available for your C program to read in.
popen opens a separate process (but without a terminal to work in, just the pipe)
'Fork' is another way to launch a separate process, with some control over the launched processes' std i/o, but again, I think not a terminal.
On the other hand, if your output is not a simple text stream, maybe you can get by with a output-only dedicated terminal screen to accommodate special output activity. For instance, when I work with ncurses:
I manually open a terminal in the conventional way, and in the terminal
issue the command "tty" to find out the device name, and
issue a "cd" to set the focus to the working dir.
dmoen#C5:~$ tty
/dev/pts/1
dmoen#C5:~$ cd work
dmoen#C5:~/work$
Then I start my program (in a different tty), and let the program know which device I want it to use for the special output (i.e. /dev/pts/1 ) ... I typically use command line parameters to tell my program which pts or extra terminals I want it to use, but environment variables, pipes, in/out redirection, and other choices exist.
I have not tried (lately) to launch a terminal (as suggested by smrt28), except in shell. I believe this will work, but I do not see how the output from the terminal command (ls in the example) would be delivered back to your program. popen trivially delivers a text stream.
A long time ago, I used a device called 'pty' which works like a terminal, but I don't remember how to connect it usefully.
There is a set of 'exec' commands ... see man exec. To connect them back to your program, you will probably work with files, or perhaps redirecting i/o. Too many choices to list here.
And also, maybe you can connect these commands with your c program using shell pipes.
Check "man xterm", parameter -e. Then, in C, you can:
system("xterm -e ls")

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.

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.)

Suppress system("ping") output in C++

I have written a simple program that pings three sites and then reacts to whether they are reachable or not.
My question is: can I suppress system("ping ")'s output? I have written my code in C++ as I know that language the best. Currently the code opens the ping.exe running the system command. If I can prevent the output from showing up while it still pings that would be ideal.
I am eventually going to turn this program in a windows service that is why I would like to suppress both the command line console window as well as suppress the ping output. Thanks.
Try doing system("ping host > nul") (nul is windows equivalent of UNIX /dev/null).
Generally, if you're going to call another program but don't want it to act like std::system, you're going to need a platform-specific function like fork()/exec() on UNIX or CreateProcess() on Windows. These functions give you control over how the other program runs, for instance, that it not show output or not create a console window, etc.
You can use system command like below to suppress the output of ping command.
system("ping 100.100.100.100 > response.dat");
Above command pings IP address 100.100.100.100 and directs the output to a file called response.dat. In response.dat you can see the response of ping command.
Do system( "ping site.com >nul 2>nul" ); and check the value the shell returns.
if the ping succeeds, the shell will return 0, else it will return 1.
I would be more detailed, but Vis Studio is reinstalling itself. :)
There's also a way to hide the console window using the Win API to exec the command, but...
I do not remember the details.
Edit:
I'm still waiting for the MSVS install process, so... :)
Use CreateProcess with the DETACHED_PROCESS flag for the dwCreationFlags parameter to hide the console window.
After you call create process, you'll have to use WaitForSingleObject on the process handle to wait for the ping to complete. The last parameter to CreateProcess should have a pointer to process information that contains the process handle. (Assuming CreateProcess was successful) You have to wait for the command to complete. Once it's complete, you can use the process handle to get the return value, though I'm too time contstrained to tell you how to do that at this point.
When you get over to Windows and call CreateProcess(), be sure to set:
lpStartupInfo->wShowWindow = SW_HIDE;
This will ensure that any windows created by the new process are hidden.
Using the DETACHED_PROCESS flag will prevent the new process from inheriting your application's console, but that does not prevent the new process from creating a new console. Not sure what ping would do, but best to remove all doubt by using SW_HIDE.
You could also use this way, this will return the output in a file and doesn't show up a console windows and freezes the main application which is really usefull.
At first you need to include the Windows header using;
#include <Windows.h>
then send a ping command and write the output into a file like this;
WinExec("ping google.com > file.dat", SW_HIDE);
This will send a ping command to google.com and writes the output to the file 'file.dat' in the directory of your current running program. So you could change file.dat to any file or filepath you want and of course you could change the ping command. The > character means that the output of the command needs to be wrote in the file path behind it.
If you want to show the console window and freeze the application while running the ping command you need to use the following line of code instead of the WindExec() code;
system("ping google.com > file.dat");