Can not connect to an already active screen through system() in c - c

Here is the part of code I have written to stuff 0 to a screen session open in one of my Ubuntu terminal tabs.
char command[60];
strcpy( command, "screen -S 8305.pts-1.MYUb -X stuff $'0'" );
system(command);
It gets compiled fine with only a warning like
ignoring return value of ‘system’,
But when it comes to running I get the message shown below:
No screen session found.
I have tried system() with other shell commands and it works perfectly fine. The command for screen also works fine when you run it in a terminal session not in c code.

Most probably you are running the command as a different user than the user that owns the screen. For example running the binary as sudo.
You can run ps aux to find the user under which your binary is running as.
To make the system command work you should run it as the user who owns the screen.

I think the problem is you are using -S which creates a new named screen, and -X which submits a command to an already running screen session.
You either want:
system( "screen -S 8305.pts-1.MYUb cmd" );
OR
system( "screen -r 8305.pts-1.MYUb -X cmd" );
FYI -- I'm not sure what stuff $0 is suppose to be, and in the context of the code you supplied is not going to work -- but I believe that a different problem then the one you reported.
From man(1) page
-S sessionname
When creating a new session, this option can be used to specify a meaningful name for the session.
And
-X Send the specified command to a running screen session.

Related

How to enable logging in xterm

Is it possible to turn on logging feature by default in xterm?
Lets say for example, I have example program in c that give an output in xterm everytime i ran the program from default bash terminal in linux. And I want to save the output that shows in xterm into a file everytime the programs is run.
I'm using centos7_x86_64 fyi
Thanks.
In Windowmaker:
Hold down ctrl + left click in xterm window (on the terminal text), click on "log to file".
A cool thing to do is when you're coding, log the terminal, and then when you cat the Xterm log, you see coding in fast forward. If you wanted you could video it.
Note that there are also other menus in xterm, accessible using Ctrl+Left Click, Ctrl+Middle Click, Ctrl+Right Click.
Log file will be in the directory that you launched Xterm from, and will be in the format: Xterm.log.<hostname>.<date>.<time>.log.
This is a very good question, there's no reason to mark down a question like this.
It can be done in two ways:
Using script:
xterm -e script mylogfile -c "someCommand -i input_file -o output_file -f someArg"
Redirect to a file:
xterm -e 'someCommand --arguments 2>&1> /path/to/mylogfile'
I do essentially this with "terminal-window", mrxvt, "hcm" and "pypty".
terminal-window wraps mrxvt, just filling in some commandline options. mrxvt is a lightweight, multitabbed, nonunicode terminal emulator not dissimilar to xterm.
hcm is a GUI that makes it easy to run a shell (or other command) on a remote host. It can also start an mrxvt with remote ssh's without requiring the GUI if you prefer (using hcm-term).
pypty is a /usr/bin/script reimplementation that is written in Python. It is not significantly different from /usr/bin/script, except it gives a "dated files mode", that allows you to have one file per pseudo terminal per day. So if you leave a shell logged in overnight, you get one file per day - this tends to make it easier to find what you're looking for.
All this combines to give you pseudo terminal logging with great ease. Commands are run on remote hosts, but logged locally. Just start a "fancy terminal-window" (or use hcm-term), and everything you see on the screen plus control characters (but not nonechoed passwords) will be logged under ~/.hcm/logs/<year>/<month>/<day>/* .
Also, if you hit the shell button in the lower right of mrxvt, you get another ssh session into the same remote host, which is also logged locally (to a different file under ~/.hcm/logs/...). When I started making use of that feature, I had no idea how much I would grow to like it.
You can obtain them from http://stromberg.dnsalias.org/~strombrg/hcm/ There's a video there that shows how easy it is to set up and get started with.
BTW, fancy terminal-window sets up $PS0 or "trap DEBUG" to give you command start times and finish times. It's great for post mortems. It does this without replacing any of the usual bash startup files.
I wrote terminal-window, hcm and pypty, but I can't take credit for mrxvt. :)
HTH

Is it possible to override SSH expecting password input from /dev/tty in C

I am developing a piece of software in C that needs to SSH to another machine and run commands as root.
Something that looks like this:
char* GetPasswd(void);
void run(char* apnSshCommand)
{
FILE* lphSshFD = popen(apnSshCommand,"w");
fprintf(lphSshFD,GetPasswd());
fflush(lphSshFD);
fprintf(lphSshFD,"#Command to run in shell");
fflush(lphSshFD);
}
GetPasswd() would be a callback to a gui where the user has typed in the password
I know that the above code is not possible since SSH looks to it's own /dev/tty to provide the password for authentication.
I have read posts such as this that teases an answer using ioctl() and fcntl() but does not provide one. Along with this that shows it is possible from the command line however I have not been able to translate it.
Using expect is NOT an option
Using SSH keys are NOT an option
The SSH C library is NOT an option
Using sshpass is NOT an option
Without these, the only thing that I can think of is starting a new child process and redirect/close file descriptors to control what ssh has access to.
EDIT: These restrictions come from the fact that the system I am working on is extremely old and does not contain tools such as expect, sshpass and the SSH C library as well as being subject to multiple restrictions in regards to when sshkeys can be used
This works for me:
Create a script called pwd.sh that emits the password:
#!/bin/bash
echo -n mypassword
Run ssh in a new session like this:
SSH_ASKPASS=/path/to/pwd.sh DISPLAY= setsid -w ssh root#192.168.1.10 <command>
The effect of setsid is to run ssh detached from the controlling terminal, which is what is needed for it to respect SSH_ASKPASS.
I haven't tried, but I would expect to be able to run this command from C using system().
For the record, I tested this with OpenSSH_7.2p2 on Ubuntu.
I was able to come up with a solution by looking at the source code for sshpass which I found here

running screen command from a c program

Here is the part of code I have written to stuff 0 to a screen session open in one of my Ubuntu terminal tabs.
char command[60];
strcpy( command, "screen -S 8305.pts-1.MYUb -X stuff $'0'" );
system(command);
It gets compiled fine with only a warning like
ignoring return value of ‘system’,
But when it comes to running it does nothing regarding the screen command. Before this, I was getting "No screen session found." error which was fortunately solved by asking about it here.
I have tried system() with other shell commands and it works perfectly fine. The command for screen also works fine when you run it in a terminal session not in c code.

Stty errors with loop, no stty errors without loop

Do not understand why my code works if I take out my loop and variables while manually executing each line. First I thought my variables were wrong, but then I tested my code with the variables but no loop and it worked.
If I put back in the loop (the only thing I'm changing), I get these weird stty errors.
while read p; do
#Send file
scp random_file.txt $p:/me/folder"
#Log in
ssh $p"#myserver.txt"
#List file, extract file, append file
#Code here
#log out
exit
done <usernames.txt
I've googled this error (which is a pretty common error) ad nauseam, but none of the solutions are working. Disabling pseudo-tty allocation nor forcing pseudo-tty allocation work for me. I always get an error, no matter the option
-t -t option
tcgetattr: Inappropriate ioctl for device
-t option
Pseudo-terminal will not be allocated because stdin is not a terminal.
stty: : Invalid argument
-T option
stty: : Invalid argument
So how do I get around these stty errors and why does it stop working when I put it in a loop?
The input redirection with <usernames.txt is replacing the standard input with the file usernames.txt. Hence the terminal is no longer the input, causing these errors. One way around this is to use a file descriptor other than standard input, e.g.:
while read p <&3; do
…
done 3<usernames.txt
Another problem you have is that the commands within the loop are executed locally, not over ssh on the remote machine, so the exit will exit your local shell (after you return from ssh by manually logging out). You can put commands to execute remotely on the ssh command line (see ssh manual, or, e.g., this question), which may eliminate your need to have the terminal as standard input in the first place.
ssh while interactive drops you into a remote shell. ssh while in a script does not do that. The body of your loop after the ssh line is not happening on the remote system when scripted this way. It is happening locally.
If you want to run code on the remote machine in the context of that ssh connection then you need to write it all as the command argument to the ssh command and/or write a script on the remote machine and execute that script as the ssh command argument.

Opening a new terminal window & executing a command

I've been trying to open a new terminal window from my application and execute a command on this second window as specified by the user. I've built some debugging software and I would like to execute the user's program on a separate window so my debugging output doesn't get intermixed with the programs output.
I am using fork() and exec(). The command I am executing is gnome-terminal -e 'the program to be executed'.
I have 2 questions:
Calling gnome-terminal means the user has to be running a gnome graphical environment. Is there a more cross-platform command to use (I am only interested in Linux machines though)?
After the command finishes executing the second terminal also finishes executing and closes. Is there any way to pause it, or just let it continue normal operation by waiting for input?
You probably want something like xterm -hold.
1) gnome-terminal should work reasonably also without the whole gnome environonment, anyway the old plain "xterm" is enough.
2) you can execute a short bash script that launch your program and at the end reads a line:
bash -c 'my program ... ; read a'
(or also 'xterm -e ...')

Resources