blob: 8935fe4dfb9414f101bf603aaf866ac6a1f6e027 [file] [log] [blame]
Elijah Newren98750582023-03-21 06:26:04 +00001#include "git-compat-util.h"
Calvin Wanb1bda752023-09-29 14:20:51 -07002#include "parse.h"
Elijah Newren32a8f512023-03-21 06:26:03 +00003#include "environment.h"
Jeff Kingd3c58b82011-12-10 05:40:54 -05004#include "run-command.h"
5#include "strbuf.h"
6#include "prompt.h"
Jeff Kinga5090252011-12-10 05:41:08 -05007#include "compat/terminal.h"
Jeff Kingd3c58b82011-12-10 05:40:54 -05008
Jeff King1cb01342011-12-10 05:40:57 -05009static char *do_askpass(const char *cmd, const char *prompt)
Jeff Kingd3c58b82011-12-10 05:40:54 -050010{
René Scharfed3180272014-08-19 21:09:35 +020011 struct child_process pass = CHILD_PROCESS_INIT;
Jeff Kingd3c58b82011-12-10 05:40:54 -050012 static struct strbuf buffer = STRBUF_INIT;
Jeff King84d72732012-02-03 17:16:02 -050013 int err = 0;
Jeff Kingd3c58b82011-12-10 05:40:54 -050014
Ævar Arnfjörð Bjarmason7f146092021-11-25 23:52:21 +010015 strvec_push(&pass.args, cmd);
16 strvec_push(&pass.args, prompt);
Jeff Kingd3c58b82011-12-10 05:40:54 -050017
Jeff Kingd3c58b82011-12-10 05:40:54 -050018 pass.out = -1;
19
20 if (start_command(&pass))
Jeff King84d72732012-02-03 17:16:02 -050021 return NULL;
Jeff Kingd3c58b82011-12-10 05:40:54 -050022
Jeff Kinge1c1a322014-01-01 22:03:30 -050023 strbuf_reset(&buffer);
Jeff Kingd3c58b82011-12-10 05:40:54 -050024 if (strbuf_read(&buffer, pass.out, 20) < 0)
Jeff King84d72732012-02-03 17:16:02 -050025 err = 1;
Jeff Kingd3c58b82011-12-10 05:40:54 -050026
27 close(pass.out);
28
29 if (finish_command(&pass))
Jeff King84d72732012-02-03 17:16:02 -050030 err = 1;
31
32 if (err) {
33 error("unable to read askpass response from '%s'", cmd);
34 strbuf_release(&buffer);
35 return NULL;
36 }
Jeff Kingd3c58b82011-12-10 05:40:54 -050037
38 strbuf_setlen(&buffer, strcspn(buffer.buf, "\r\n"));
39
Jeff Kinge1c1a322014-01-01 22:03:30 -050040 return buffer.buf;
Jeff Kingd3c58b82011-12-10 05:40:54 -050041}
Jeff King1cb01342011-12-10 05:40:57 -050042
43char *git_prompt(const char *prompt, int flags)
44{
Jeff King84d72732012-02-03 17:16:02 -050045 char *r = NULL;
Jeff King1cb01342011-12-10 05:40:57 -050046
47 if (flags & PROMPT_ASKPASS) {
48 const char *askpass;
49
50 askpass = getenv("GIT_ASKPASS");
51 if (!askpass)
52 askpass = askpass_program;
53 if (!askpass)
54 askpass = getenv("SSH_ASKPASS");
55 if (askpass && *askpass)
Jeff King84d72732012-02-03 17:16:02 -050056 r = do_askpass(askpass, prompt);
Jeff King1cb01342011-12-10 05:40:57 -050057 }
58
Jeff King84d72732012-02-03 17:16:02 -050059 if (!r) {
Jeff Kinge652c0e2014-12-03 22:52:29 -050060 const char *err;
61
62 if (git_env_bool("GIT_TERMINAL_PROMPT", 1)) {
63 r = git_terminal_prompt(prompt, flags & PROMPT_ECHO);
64 err = strerror(errno);
65 } else {
66 err = "terminal prompts disabled";
67 }
68 if (!r) {
69 /* prompts already contain ": " at the end */
70 die("could not read %s%s", prompt, err);
71 }
Jeff King84d72732012-02-03 17:16:02 -050072 }
Jeff King1cb01342011-12-10 05:40:57 -050073 return r;
74}
Johannes Schindelin08d383f2020-04-10 11:27:50 +000075
76int git_read_line_interactively(struct strbuf *line)
77{
마누엘1f09aed2020-04-10 11:27:51 +000078 int ret;
Johannes Schindelin08d383f2020-04-10 11:27:50 +000079
마누엘1f09aed2020-04-10 11:27:51 +000080 fflush(stdout);
81 ret = strbuf_getline_lf(line, stdin);
Johannes Schindelin08d383f2020-04-10 11:27:50 +000082 if (ret != EOF)
83 strbuf_trim_trailing_newline(line);
84
85 return ret;
86}