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;