2011-12-10 18:40:54 +08:00
|
|
|
#include "cache.h"
|
|
|
|
#include "run-command.h"
|
|
|
|
#include "strbuf.h"
|
|
|
|
#include "prompt.h"
|
2011-12-10 18:41:08 +08:00
|
|
|
#include "compat/terminal.h"
|
2011-12-10 18:40:54 +08:00
|
|
|
|
2011-12-10 18:40:57 +08:00
|
|
|
static char *do_askpass(const char *cmd, const char *prompt)
|
2011-12-10 18:40:54 +08:00
|
|
|
{
|
|
|
|
struct child_process pass;
|
|
|
|
const char *args[3];
|
|
|
|
static struct strbuf buffer = STRBUF_INIT;
|
prompt: fall back to terminal if askpass fails
The current askpass code simply dies if calling an askpass
helper fails. Worse, in some failure modes it doesn't even
print an error (if start_command fails, then it prints its
own error; if reading fails, we print an error; but if the
command exits non-zero, finish_command fails and we print
nothing!).
Let's be more kind to the user by printing an error message
when askpass doesn't work out, and then falling back to the
terminal (which also may fail, of course, but we die already
there with a nice message).
While we're at it, let's clean up the existing error
messages a bit. Now that our prompts are very long and
contain quotes and colons themselves, our error messages are
hard to read.
So the new failure modes look like:
[before, with a terminal]
$ GIT_ASKPASS=false git push
$ echo $?
128
[before, with no terminal, and we must give up]
$ setsid git push
fatal: could not read 'Password for 'https://peff@github.com': ': No such device or address
[after, with a terminal]
$ GIT_ASKPASS=false git push
error: unable to read askpass response from 'false'
Password for 'https://peff@github.com':
[after, with no terminal, and we must give up]
$ GIT_ASKPASS=false setsid git push
error: unable to read askpass response from 'false'
fatal: could not read Password for 'https://peff@github.com': No such device or address
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-04 06:16:02 +08:00
|
|
|
int err = 0;
|
2011-12-10 18:40:54 +08:00
|
|
|
|
2011-12-10 18:40:57 +08:00
|
|
|
args[0] = cmd;
|
2011-12-10 18:40:54 +08:00
|
|
|
args[1] = prompt;
|
|
|
|
args[2] = NULL;
|
|
|
|
|
|
|
|
memset(&pass, 0, sizeof(pass));
|
|
|
|
pass.argv = args;
|
|
|
|
pass.out = -1;
|
|
|
|
|
|
|
|
if (start_command(&pass))
|
prompt: fall back to terminal if askpass fails
The current askpass code simply dies if calling an askpass
helper fails. Worse, in some failure modes it doesn't even
print an error (if start_command fails, then it prints its
own error; if reading fails, we print an error; but if the
command exits non-zero, finish_command fails and we print
nothing!).
Let's be more kind to the user by printing an error message
when askpass doesn't work out, and then falling back to the
terminal (which also may fail, of course, but we die already
there with a nice message).
While we're at it, let's clean up the existing error
messages a bit. Now that our prompts are very long and
contain quotes and colons themselves, our error messages are
hard to read.
So the new failure modes look like:
[before, with a terminal]
$ GIT_ASKPASS=false git push
$ echo $?
128
[before, with no terminal, and we must give up]
$ setsid git push
fatal: could not read 'Password for 'https://peff@github.com': ': No such device or address
[after, with a terminal]
$ GIT_ASKPASS=false git push
error: unable to read askpass response from 'false'
Password for 'https://peff@github.com':
[after, with no terminal, and we must give up]
$ GIT_ASKPASS=false setsid git push
error: unable to read askpass response from 'false'
fatal: could not read Password for 'https://peff@github.com': No such device or address
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-04 06:16:02 +08:00
|
|
|
return NULL;
|
2011-12-10 18:40:54 +08:00
|
|
|
|
|
|
|
if (strbuf_read(&buffer, pass.out, 20) < 0)
|
prompt: fall back to terminal if askpass fails
The current askpass code simply dies if calling an askpass
helper fails. Worse, in some failure modes it doesn't even
print an error (if start_command fails, then it prints its
own error; if reading fails, we print an error; but if the
command exits non-zero, finish_command fails and we print
nothing!).
Let's be more kind to the user by printing an error message
when askpass doesn't work out, and then falling back to the
terminal (which also may fail, of course, but we die already
there with a nice message).
While we're at it, let's clean up the existing error
messages a bit. Now that our prompts are very long and
contain quotes and colons themselves, our error messages are
hard to read.
So the new failure modes look like:
[before, with a terminal]
$ GIT_ASKPASS=false git push
$ echo $?
128
[before, with no terminal, and we must give up]
$ setsid git push
fatal: could not read 'Password for 'https://peff@github.com': ': No such device or address
[after, with a terminal]
$ GIT_ASKPASS=false git push
error: unable to read askpass response from 'false'
Password for 'https://peff@github.com':
[after, with no terminal, and we must give up]
$ GIT_ASKPASS=false setsid git push
error: unable to read askpass response from 'false'
fatal: could not read Password for 'https://peff@github.com': No such device or address
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-04 06:16:02 +08:00
|
|
|
err = 1;
|
2011-12-10 18:40:54 +08:00
|
|
|
|
|
|
|
close(pass.out);
|
|
|
|
|
|
|
|
if (finish_command(&pass))
|
prompt: fall back to terminal if askpass fails
The current askpass code simply dies if calling an askpass
helper fails. Worse, in some failure modes it doesn't even
print an error (if start_command fails, then it prints its
own error; if reading fails, we print an error; but if the
command exits non-zero, finish_command fails and we print
nothing!).
Let's be more kind to the user by printing an error message
when askpass doesn't work out, and then falling back to the
terminal (which also may fail, of course, but we die already
there with a nice message).
While we're at it, let's clean up the existing error
messages a bit. Now that our prompts are very long and
contain quotes and colons themselves, our error messages are
hard to read.
So the new failure modes look like:
[before, with a terminal]
$ GIT_ASKPASS=false git push
$ echo $?
128
[before, with no terminal, and we must give up]
$ setsid git push
fatal: could not read 'Password for 'https://peff@github.com': ': No such device or address
[after, with a terminal]
$ GIT_ASKPASS=false git push
error: unable to read askpass response from 'false'
Password for 'https://peff@github.com':
[after, with no terminal, and we must give up]
$ GIT_ASKPASS=false setsid git push
error: unable to read askpass response from 'false'
fatal: could not read Password for 'https://peff@github.com': No such device or address
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-04 06:16:02 +08:00
|
|
|
err = 1;
|
|
|
|
|
|
|
|
if (err) {
|
|
|
|
error("unable to read askpass response from '%s'", cmd);
|
|
|
|
strbuf_release(&buffer);
|
|
|
|
return NULL;
|
|
|
|
}
|
2011-12-10 18:40:54 +08:00
|
|
|
|
|
|
|
strbuf_setlen(&buffer, strcspn(buffer.buf, "\r\n"));
|
|
|
|
|
2012-02-04 06:14:11 +08:00
|
|
|
return strbuf_detach(&buffer, NULL);
|
2011-12-10 18:40:54 +08:00
|
|
|
}
|
2011-12-10 18:40:57 +08:00
|
|
|
|
|
|
|
char *git_prompt(const char *prompt, int flags)
|
|
|
|
{
|
prompt: fall back to terminal if askpass fails
The current askpass code simply dies if calling an askpass
helper fails. Worse, in some failure modes it doesn't even
print an error (if start_command fails, then it prints its
own error; if reading fails, we print an error; but if the
command exits non-zero, finish_command fails and we print
nothing!).
Let's be more kind to the user by printing an error message
when askpass doesn't work out, and then falling back to the
terminal (which also may fail, of course, but we die already
there with a nice message).
While we're at it, let's clean up the existing error
messages a bit. Now that our prompts are very long and
contain quotes and colons themselves, our error messages are
hard to read.
So the new failure modes look like:
[before, with a terminal]
$ GIT_ASKPASS=false git push
$ echo $?
128
[before, with no terminal, and we must give up]
$ setsid git push
fatal: could not read 'Password for 'https://peff@github.com': ': No such device or address
[after, with a terminal]
$ GIT_ASKPASS=false git push
error: unable to read askpass response from 'false'
Password for 'https://peff@github.com':
[after, with no terminal, and we must give up]
$ GIT_ASKPASS=false setsid git push
error: unable to read askpass response from 'false'
fatal: could not read Password for 'https://peff@github.com': No such device or address
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-04 06:16:02 +08:00
|
|
|
char *r = NULL;
|
2011-12-10 18:40:57 +08:00
|
|
|
|
|
|
|
if (flags & PROMPT_ASKPASS) {
|
|
|
|
const char *askpass;
|
|
|
|
|
|
|
|
askpass = getenv("GIT_ASKPASS");
|
|
|
|
if (!askpass)
|
|
|
|
askpass = askpass_program;
|
|
|
|
if (!askpass)
|
|
|
|
askpass = getenv("SSH_ASKPASS");
|
|
|
|
if (askpass && *askpass)
|
prompt: fall back to terminal if askpass fails
The current askpass code simply dies if calling an askpass
helper fails. Worse, in some failure modes it doesn't even
print an error (if start_command fails, then it prints its
own error; if reading fails, we print an error; but if the
command exits non-zero, finish_command fails and we print
nothing!).
Let's be more kind to the user by printing an error message
when askpass doesn't work out, and then falling back to the
terminal (which also may fail, of course, but we die already
there with a nice message).
While we're at it, let's clean up the existing error
messages a bit. Now that our prompts are very long and
contain quotes and colons themselves, our error messages are
hard to read.
So the new failure modes look like:
[before, with a terminal]
$ GIT_ASKPASS=false git push
$ echo $?
128
[before, with no terminal, and we must give up]
$ setsid git push
fatal: could not read 'Password for 'https://peff@github.com': ': No such device or address
[after, with a terminal]
$ GIT_ASKPASS=false git push
error: unable to read askpass response from 'false'
Password for 'https://peff@github.com':
[after, with no terminal, and we must give up]
$ GIT_ASKPASS=false setsid git push
error: unable to read askpass response from 'false'
fatal: could not read Password for 'https://peff@github.com': No such device or address
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-04 06:16:02 +08:00
|
|
|
r = do_askpass(askpass, prompt);
|
2011-12-10 18:40:57 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!r)
|
prompt: fall back to terminal if askpass fails
The current askpass code simply dies if calling an askpass
helper fails. Worse, in some failure modes it doesn't even
print an error (if start_command fails, then it prints its
own error; if reading fails, we print an error; but if the
command exits non-zero, finish_command fails and we print
nothing!).
Let's be more kind to the user by printing an error message
when askpass doesn't work out, and then falling back to the
terminal (which also may fail, of course, but we die already
there with a nice message).
While we're at it, let's clean up the existing error
messages a bit. Now that our prompts are very long and
contain quotes and colons themselves, our error messages are
hard to read.
So the new failure modes look like:
[before, with a terminal]
$ GIT_ASKPASS=false git push
$ echo $?
128
[before, with no terminal, and we must give up]
$ setsid git push
fatal: could not read 'Password for 'https://peff@github.com': ': No such device or address
[after, with a terminal]
$ GIT_ASKPASS=false git push
error: unable to read askpass response from 'false'
Password for 'https://peff@github.com':
[after, with no terminal, and we must give up]
$ GIT_ASKPASS=false setsid git push
error: unable to read askpass response from 'false'
fatal: could not read Password for 'https://peff@github.com': No such device or address
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-04 06:16:02 +08:00
|
|
|
r = git_terminal_prompt(prompt, flags & PROMPT_ECHO);
|
|
|
|
if (!r) {
|
|
|
|
/* prompts already contain ": " at the end */
|
|
|
|
die("could not read %s%s", prompt, strerror(errno));
|
|
|
|
}
|
2011-12-10 18:40:57 +08:00
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *git_getpass(const char *prompt)
|
|
|
|
{
|
|
|
|
return git_prompt(prompt, PROMPT_ASKPASS);
|
|
|
|
}
|