Search code examples
cgitcommand-promptexpect

How to respond to any command line prompts in C


I'm trying to automate the process of doing

git add .
git commit -m "some message"
git push origin master

In C.

I've already done a bash script with Expect

#!/bin/bash

HOME="/home/prxvvy"
filename="$HOME/Documents/github_creds.txt"

username=`awk 'NR==1' $filename`
password=`awk 'NR==3' $filename`

echo "Enter a message for commit:"
read message
expect <<EOS
spawn git add .
expect
spawn git commit -m "$message"
expect
spawn git push origin master
expect "Username for 'https://github.com':"
send "$username\r"
expect "Password for 'https://$username@github.com':"
send "$password\r"
expect eof
EOS

So how would I "send" the requested data when the "Username for 'https://github.com':" prompt comes up, with C?

PS: I don't want to use any git api or something as I did in the bash script


Solution

  • Answer #1: you can't. The problem here has nothing to do with Git per se. Programs that read passwords from humans make sure they're not talking to other programs, by making sure they're using the human /dev/tty interface. So your program can't push a password into another program.

    Answer #2: you can, but you must re-implement expect. The expect program tricks other programs into thinking they are talking to a human. This is fairly complicated and involves opening a "pseudo tty" from the control side, initializing it properly on the dependent side, and doing any OS-level operations required to make it become the /dev/tty that other programs will get when they open it. Then, having done all this song and dance (some of which is available in some libraries via openpty or similar), you can then run a program. You then must implement the rest of expect to read data coming through the control side of the pty pair, interpret it to figure out what the program is doing, and feed it data.

    (Note that if all you want to do is run git push without having to enter a password, Git can invoke authentication methods that do this. Git does not have its own built in authentication: it relies on credential helpers when using https and ssh's credentialing and authentication systems when using ssh. So if you're using https:// for your URL, you want to configure a credential helper to do the job, and if you're using ssh:// for your URL, you want to configure ssh. You said that's not what you're interested in, though.)