diff --git a/doc/cgmnlm.scd b/doc/cgmnlm.scd

index a6e07153e101b487c8706a83777934dd853b5425..dd074f52ed47bcf905ba62b481063f09621e0f3b 100644

--- a/doc/cgmnlm.scd

+++ b/doc/cgmnlm.scd

@@ -22,6 +22,9 @@

*-P*

Disable pagination.

+*-R* _redirs_

+ Sets the maximum number of redirects, negative argument disables limit.

+

*-U*

Disable conservative use of Unicode symbols to render Gemini layout

features.

diff --git a/src/gmnlm.c b/src/gmnlm.c

index 2d8ab2d1e8cd855ab2e5e10e430b4bc982e86452..3ec648629bd1937320448c680e1a93fd7d13e8fe 100644

--- a/src/gmnlm.c

+++ b/src/gmnlm.c

@@ -44,9 +44,13 @@ char *url;

struct history *prev, *next;

};

+#define REDIRS_UNLIMITED -1

+#define REDIRS_ASK -2

+

struct browser {

bool pagination, unicode, alttext, autoopen;

int max_width;

+ int max_redirs;

struct gemini_options opts;

struct gemini_tofu tofu;

enum tofu_action tofu_mode;

@@ -114,7 +118,7 @@

static void

usage(const char *argv_0)

{

- fprintf(stderr, "usage: %s [-PUAT] [-j mode] [-W width] [gemini://...]\n", argv_0);

+ fprintf(stderr, "usage: %s [-PUAT] [-j mode] [-R redirs] [-W width] [gemini://...]\n", argv_0);

}

static void

@@ -434,7 +438,7 @@ {

int nredir = 0;

bool requesting = true;

enum gemini_result res;

-

+

char *scheme;

CURLUcode uc = curl_url_get(browser->url,

CURLUPART_SCHEME, &scheme, 0);

@@ -549,9 +553,40 @@ NULL : &browser->history);

free(new_url);

break;

case GEMINI_STATUS_CLASS_REDIRECT:

- if (++nredir >= 5) {

+ if (browser->max_redirs == REDIRS_ASK) {

+again:

+ fprintf(browser->tty,

+ "The host %s is redirecting to:\n"

+ "%s\n\n"

+ "[f]ollow redirect; [a]bort\n"

+ "=> ", host, resp->meta);

+

+ size_t sz = 0;

+ char *line = NULL;

+ if (getline(&line, &sz, browser->tty) == -1) {

+ free(line);

+ requesting = false;

+ break;

+ }

+ if (line[1] != '\n') {

+ free(line);

+ goto again;

+ }

+

+ char c = line[0];

+ free(line);

+

+ if (c == 'a') {

+ requesting = false;

+ break;

+ } else if (c != 'f') {

+ goto again;

+ }

+ } else if (browser->max_redirs != REDIRS_UNLIMITED

+ && ++nredir >= browser->max_redirs) {

requesting = false;

- fprintf(stderr, "Error: maximum redirects (5) exceeded\n");

+ fprintf(stderr, "Error: maximum redirects (%d) exceeded\n",

+ browser->max_redirs);

break;

}

set_url(browser, resp->meta, NULL);

@@ -1322,10 +1357,11 @@ .unicode = true,

.url = curl_url(),

.tty = fopen("/dev/tty", "w+"),

.meta = NULL,

+ .max_redirs = REDIRS_ASK,

};

int c;

- while ((c = getopt(argc, argv, "hj:PTAUW:")) != -1) {

+ while ((c = getopt(argc, argv, "hj:PR:UW:TA")) != -1) {

switch (c) {

case 'h':

usage(argv[0]);

@@ -1350,6 +1386,10 @@ browser.alttext = true;

break;

case 'P':

browser.pagination = false;

+ break;

+ case 'R':;

+ int mr = strtol(optarg, NULL, 10);

+ browser.max_redirs = mr < 0 ? REDIRS_UNLIMITED : mr;

break;

case 'U':

browser.unicode = false;