commit 211b8c3dd36a950132efa5ba4e2f0172a42bb6bc
parent 1808e6cd1880d3c08abb0ddfa19044afada925dd
Author: Drew DeVault <sir@cmpwn.com>
Date: Sun, 20 Sep 2020 19:40:42 -0400
gmnlm: Implement input responses
Diffstat:
M | src/gmnlm.c | | | 46 | +++++++++++++++++++++++++++++++++++++++++++++- |
1 file changed, 45 insertions(+), 1 deletion(-)
diff --git a/src/gmnlm.c b/src/gmnlm.c
@@ -192,6 +192,40 @@ display_response(struct browser *browser, struct gemini_response *resp)
}
static char *
+get_input(const struct gemini_response *resp, FILE *source)
+{
+ int r = 0;
+ struct termios attrs;
+ bool tty = fileno(source) != -1 && isatty(fileno(source));
+ char *input = NULL;
+ if (tty) {
+ fprintf(stderr, "%s: ", resp->meta);
+ if (resp->status == GEMINI_STATUS_SENSITIVE_INPUT) {
+ r = tcgetattr(fileno(source), &attrs);
+ struct termios new_attrs;
+ r = tcgetattr(fileno(source), &new_attrs);
+ if (r != -1) {
+ new_attrs.c_lflag &= ~ECHO;
+ tcsetattr(fileno(source), TCSANOW, &new_attrs);
+ }
+ }
+ }
+ size_t s = 0;
+ ssize_t n = getline(&input, &s, source);
+ if (n == -1) {
+ fprintf(stderr, "Error reading input: %s\n",
+ feof(source) ? "EOF" : strerror(ferror(source)));
+ return NULL;
+ }
+ input[n - 1] = '\0'; // Drop LF
+ if (tty && resp->status == GEMINI_STATUS_SENSITIVE_INPUT && r != -1) {
+ attrs.c_lflag &= ~ECHO;
+ tcsetattr(fileno(source), TCSANOW, &attrs);
+ }
+ return input;
+}
+
+static char *
do_requests(struct browser *browser, struct gemini_response *resp)
{
char *plain_url;
@@ -210,9 +244,19 @@ do_requests(struct browser *browser, struct gemini_response *resp)
break;
}
+ char *input;
switch (gemini_response_class(resp->status)) {
case GEMINI_STATUS_CLASS_INPUT:
- assert(0); // TODO
+ input = get_input(resp, browser->tty);
+ if (!input) {
+ requesting = false;
+ break;
+ }
+
+ char *new_url = gemini_input_url(plain_url, input);
+ assert(new_url);
+ set_url(browser, new_url, NULL);
+ break;
case GEMINI_STATUS_CLASS_REDIRECT:
if (++nredir >= 5) {
requesting = false;