From: Rene Kita mail@rkta.de

Subject: Add Gemini support

This patch adds Gemini support to w3m. This is still work in progress. Consider

this as alpha stage. INPUT may break with unquoted chars.

The patch should apply to the current master branch of

https://github.com/tats/w3m (commit c8223fed7cc631ad85d8e5665e509e7988bedbab)

also to the releases w3m-0.5.3+git20210102, w3m-0.5.3-git20220429 and

w3m-0.5.3+git20230121.


buffer.c | 9 +

display.c | 3

doc-de/README.func | 1

doc/README.func | 1

file.c | 292 ++++++++++++++++++++++++++++++++++++++++++++++++-

html.h | 1

istream.c | 140 ++++++++++++++++++-----

istream.h | 5

main.c | 152 +++++++++++++++++++++++++

proto.h | 1

rc.c | 5

rc.h | 2

scripts/w3mhelp.cgi.in | 5

url.c | 35 +++++

14 files changed, 613 insertions(+), 39 deletions(-)

--- a/file.c

+++ b/file.c

@@ -30,6 +30,8 @@

#define MAX_INPUT_SIZE 80 /* TODO - max should be screen line length */

+Buffer * loadGeminiBuffer(URLFile *uf, Buffer *volatile newBuf);

static int frame_source = 0;

static int need_number = 0;

@@ -248,7 +250,7 @@ loadSomething(URLFile *f,

    )

buf->type = "text/html";

 else

 return buf;

}

@@ -1702,7 +1704,7 @@ loadGeneralFile(char *path, ParsedURL *v

 URLFile f, *volatile of = NULL;

 ParsedURL pu;

 Buffer *b = NULL;

 char *volatile tpath;

 char *volatile t = "text/plain", *p, *volatile real_type = NULL;

 Buffer *volatile t_buf = NULL;

@@ -2054,6 +2056,166 @@ loadGeneralFile(char *path, ParsedURL *v

 else if (pu.scheme == SCM_DATA) {

t = f.guess_type;

 }

+fail:

 else if (searchHeader) {

searchHeader = SearchHeader = FALSE;

if (t_buf == NULL)

@@ -2232,6 +2394,8 @@ loadGeneralFile(char *path, ParsedURL *v

 if (is_html_type(t))

proc = loadHTMLBuffer;

 else if (is_plain_text_type(t))

proc = loadBuffer;

#ifdef USE_IMAGE

@@ -2486,7 +2650,6 @@ is_boundary(unsigned char *ch1, unsigned

 return 1;

}

static void

set_breakpoint(struct readbuffer *obuf, int tag_length)

{

@@ -7643,6 +7806,130 @@ loadGopherSearch0(URLFile *uf, ParsedURL

}

#endif /* USE_GOPHER */

+Buffer *

+loadGeminiBuffer(URLFile *uf, Buffer *volatile buf)

+{

+}

/*

*/

--- a/html.h

+++ b/html.h

@@ -419,5 +419,6 @@ struct environment {

#ifdef USE_SSL

#define SCM_HTTPS 13

#endif /* USE_SSL */

+#define SCM_GEMINI 14

#endif /* _HTML_H */

--- a/url.c

+++ b/url.c

@@ -75,6 +75,7 @@ static int

#ifdef USE_SSL

 443,			/* https */

#endif /* USE_SSL */

};

struct cmdtable schemetable[] = {

@@ -95,6 +96,7 @@ struct cmdtable schemetable[] = {

#ifdef USE_SSL

 {"https", SCM_HTTPS},

#endif /* USE_SSL */

 {NULL, SCM_UNKNOWN},

};

@@ -235,6 +237,7 @@ DefaultFile(int scheme)

 case SCM_LOCAL_CGI:

 case SCM_FTP:

 case SCM_FTPDIR:

return allocStr("/", -1);

 }

 return NULL;

@@ -256,7 +259,7 @@ free_ssl_ctx(void)

 if (ssl_ctx != NULL)

SSL_CTX_free(ssl_ctx);

 ssl_ctx = NULL;

}

#if SSLEAY_VERSION_NUMBER >= 0x00905100

@@ -1262,6 +1265,7 @@ _parsedURL2Str(ParsedURL *pu, int pass,

"news", "news", "data", "mailto",

#ifdef USE_SSL

"https",

#endif /* USE_SSL */

 };

@@ -1962,6 +1966,35 @@ openURL(char *url, ParsedURL *pu, Parsed

}

break;

#endif /* USE_GOPHER */

#ifdef USE_NNTP

 case SCM_NNTP:

 case SCM_NNTP_GROUP:

--- a/display.c

+++ b/display.c

@@ -382,7 +382,8 @@ displayBuffer(Buffer *buf, int mode)

 if (buf->height == 0)

buf->height = LASTLINE + 1;

 if ((buf->width != INIT_BUFFER_WIDTH &&

|| buf->need_reshape) {

buf->need_reshape = TRUE;

reshapeBuffer(buf);

--- a/buffer.c

+++ b/buffer.c

@@ -18,6 +18,10 @@ extern int do_getch();

char *NullLine = "";

Lineprop NullProp[] = { 0 };

+/* TODO(rkta): header file */

+Buffer * loadGeminiBuffer(URLFile *uf, Buffer *volatile buf);

/*

*/

@@ -507,6 +511,8 @@ reshapeBuffer(Buffer *buf)

{

 URLFile f;

 Buffer sbuf;

#ifdef USE_M17N

 wc_uint8 old_auto_detect = WcOption.auto_detect;

#endif

@@ -517,6 +523,7 @@ reshapeBuffer(Buffer *buf)

 buf->width = INIT_BUFFER_WIDTH;

 if (buf->sourcefile == NULL)

return;

 init_stream(&f, SCM_LOCAL, NULL);

 examineFile(buf->mailcap_source ? buf->mailcap_source : buf->sourcefile,

	&f);

@@ -562,6 +569,8 @@ reshapeBuffer(Buffer *buf)

#endif

 if (is_html_type(buf->type))

loadHTMLBuffer(&f, buf);

 else

loadBuffer(&f, buf);

 UFclose(&f);

--- a/main.c

+++ b/main.c

@@ -406,6 +406,32 @@ die_oom(size_t bytes)

 return NULL;

}

+/* TODO(rkta): header */

+TextList * load_known_hosts(void);

+TextList *

+load_known_hosts(void)

+{

+}

int

main(int argc, char **argv)

{

@@ -908,6 +934,9 @@ main(int argc, char **argv)

 if (UseHistory)

loadHistory(URLHist);

#endif /* not USE_HISTORY */

#ifdef USE_M17N

 /*  if (w3m_dump)

@@ -2557,10 +2586,36 @@ DEFUN(movRW, NEXT_WORD, "Move to the nex

 displayBuffer(Currentbuf, B_NORMAL);

}

+static int

+save_known_hosts(void)

+{

+}

static void

_quitfm(int confirm)

{

 char *ans = "y";

 if (checkDownloadList())

/* FIXME: gettextize? */

@@ -2587,7 +2642,9 @@ _quitfm(int confirm)

 if (UseHistory && SaveURLHist)

saveHistory(URLHist, URLHistSize);

#endif /* USE_HISTORY */

}

/* Quit */

@@ -4786,6 +4843,13 @@ DEFUN(vwSrc, SOURCE VIEW, "Toggle betwee

displayBuffer(Currentbuf, B_NORMAL);

return;

 }

 if (Currentbuf->sourcefile == NULL) {

if (Currentbuf->pagerSource &&

    !strcasecmp(Currentbuf->type, "text/plain")) {

@@ -4864,6 +4928,91 @@ DEFUN(vwSrc, SOURCE VIEW, "Toggle betwee

 displayBuffer(Currentbuf, B_NORMAL);

}

+DEFUN(geminize, GEMINIZE, "Toggle between text/gemini shown or processed")

+{

+#ifdef USE_M17N

+#endif

+#ifdef USE_M17N

+#endif

+#ifdef USE_M17N

+#endif

+}

/* reload */

DEFUN(reload, RELOAD, "Load current document anew")

{

@@ -5089,6 +5238,7 @@ chkURLBuffer(Buffer *buf)

"https?://[a-zA-Z0-9:%\\-\\./_@]*\\[[a-fA-F0-9:][a-fA-F0-9:\\.]*\\][a-zA-Z0-9:%\\-\\./?=~_\\&+@#,\\$;]*",

"ftp://[a-zA-Z0-9:%\\-\\./_@]*\\[[a-fA-F0-9:][a-fA-F0-9:\\.]*\\][a-zA-Z0-9:%\\-\\./=_+@#,\\$]*",

#endif /* INET6 */

NULL

 };

 int i;

--- a/proto.h

+++ b/proto.h

@@ -97,6 +97,7 @@ extern void peekURL(void);

extern void peekIMG(void);

extern void curURL(void);

extern void vwSrc(void);

+extern void geminize(void);

extern void reload(void);

extern void reshape(void);

extern void chkURL(void);

--- a/istream.c

+++ b/istream.c

@@ -1,6 +1,7 @@

/* $Id: istream.c,v 1.27 2010/07/18 13:43:23 htrb Exp $ */

#include "fm.h"

#include "myctype.h"

+#include "rc.h"

#include "istream.h"

#include <signal.h>

#ifdef USE_SSL

@@ -350,15 +351,43 @@ ISeos(InputStream stream)

}

#ifdef USE_SSL

-static Str accept_this_site;

+TextList *known_hosts;

+char *known_hosts_file;

+static Str _accept_this_site;

+static Str

+X509_fingerprint(X509 *x)

+{

+}

void

-ssl_accept_this_site(char *hostname)

+ssl_accept_this_site(char *hostname, X509 *x, int perm)

{

}

static int

@@ -497,6 +526,50 @@ ssl_check_cert_ident(X509 * x, char *hos

 return ret;

}

+/* TODO(rkta): header */

+TextList * load_known_hosts(void);

+/* Return true if the host's cert was manually accepted before */

+static int

+accept_this_site(const char *hostname, X509 *x)

+{

+}

Str

ssl_get_certificate(SSL * ssl, char *hostname)

{

@@ -504,7 +577,7 @@ ssl_get_certificate(SSL * ssl, char *hos

 X509 *x;

 X509_NAME *xn;

 char *p;

 Str s;

 char buf[2048];

 Str amsg = NULL;

@@ -513,10 +586,10 @@ ssl_get_certificate(SSL * ssl, char *hos

 if (ssl == NULL)

return NULL;

 x = SSL_get_peer_certificate(ssl);

 if (x == NULL) {

    ans = "y";

else {

    /* FIXME: gettextize? */

@@ -537,7 +610,7 @@ ssl_get_certificate(SSL * ssl, char *hos

}

if (amsg)

    disp_err_message(amsg->ptr, FALSE);

/* FIXME: gettextize? */

s = amsg ? amsg : Strnew_charp("valid certificate");

return s;

@@ -547,39 +620,46 @@ ssl_get_certificate(SSL * ssl, char *hos

  * The chain length is automatically checked by OpenSSL when we

  * set the verify depth in the ctx.

  */

 if (ssl_verify_server) {

long verr;

if ((verr = SSL_get_verify_result(ssl))

    != X509_V_OK) {

    const char *em = X509_verify_cert_error_string(verr);

	ans = "y";

    else {

	ans = inputAnswer(emsg->ptr);

    }

}

 }

#endif

 emsg = ssl_check_cert_ident(x, hostname);

 if (emsg != NULL) {

    ans = "y";

else {

    Str ep = Strdup(emsg);

@@ -601,10 +681,10 @@ ssl_get_certificate(SSL * ssl, char *hos

    free_ssl_ctx();

    return NULL;

}

 }

 if (amsg)

disp_err_message(amsg->ptr, FALSE);

 /* FIXME: gettextize? */

 s = amsg ? amsg : Strnew_charp("valid certificate");

 Strcat_charp(s, "\n");

--- a/istream.h

+++ b/istream.h

@@ -109,6 +109,9 @@ typedef struct encoded_stream *EncodedSt

typedef union input_stream *InputStream;

+extern TextList *known_hosts;

+extern char *known_hosts_file;

extern InputStream newInputStream(int des);

extern InputStream newFileStream(FILE * f, void (*closep) ());

extern InputStream newStrStream(Str s);

@@ -130,7 +133,7 @@ int ISread_n(InputStream stream, char *d

extern int ISfileno(InputStream stream);

extern int ISeos(InputStream stream);

#ifdef USE_SSL

-extern void ssl_accept_this_site(char *hostname);

+extern void ssl_accept_this_site(char *hostname, X509 *x, int perm);

extern Str ssl_get_certificate(SSL * ssl, char *hostname);

#endif

--- a/rc.c

+++ b/rc.c

@@ -36,6 +36,8 @@ struct rc_search_table {

static struct rc_search_table *RC_search_table;

static int RC_table_size;

+int ssl_known_hosts = 1;

#define P_INT 0

#define P_SHORT 1

#define P_CHARINT 2

@@ -209,6 +211,7 @@ static int OptionEncode = FALSE;

#define CMT_SSL_CA_PATH N_("Path to directory for PEM encoded certificates of CAs")

#define CMT_SSL_CA_FILE N_("File consisting of PEM encoded certificates of CAs")

#define CMT_SSL_CA_DEFAULT N_("Use default locations for PEM encoded certificates of CAs")

+#define CMT_SSL_KNOWN_HOSTS N_("Remember accepted self signed certificates")

#endif /* USE_SSL_VERIFY */

#define CMT_SSL_FORBID_METHOD N_("List of forbidden SSL methods (2: SSLv2, 3: SSLv3, t: TLSv1.0, 5: TLSv1.1, 6: TLSv1.2, 7: TLSv1.3)")

#ifdef SSL_CTX_set_min_proto_version

@@ -647,6 +650,8 @@ struct param_ptr params7[] = {

  NULL},

 {"ssl_ca_default", P_INT, PI_ONOFF, (void *)&ssl_ca_default,

  CMT_SSL_CA_DEFAULT, NULL},

#endif /* USE_SSL_VERIFY */

 {NULL, 0, 0, NULL, NULL, NULL},

};

--- a/rc.h

+++ b/rc.h

@@ -4,4 +4,6 @@

extern void show_params(FILE * fp);

extern int str_to_bool(char *value, int old);

+extern int ssl_known_hosts;

#endif /* RC_H */

--- a/doc-de/README.func

+++ b/doc-de/README.func

@@ -32,6 +32,7 @@ EXIT Sofort beenden

EXTERN Verwende externen Browser zur Anzeige

EXTERN_LINK Verwende externen Browser zur Anzeige des Linkziels

FRAME Wechsle zwischen Kennung und Umsetzung von HTML-Frames

+GEMINIZE Wechsle zwischen text/gemini-Wiedergabe und -Verarbeitung

GOTO Öffne angegebenes Dokument in neuem Puffer

GOTO_HOME Zurück zur Startseite (die Variablen HTTP_HOME oder WWW_HOME spezifiziert wurden)

GOTO_LINE Gehe zur angebenen Zeile

--- a/doc/README.func

+++ b/doc/README.func

@@ -32,6 +32,7 @@ EXIT Quit without confirmation

EXTERN Display using an external browser

EXTERN_LINK Display target using an external browser

FRAME Toggle rendering HTML frames

+GEMINIZE Toggle between text/gemini shown or processed

GOTO Open specified document in a new buffer

GOTO_HOME Return to the homepage (specified HTTP_HOME or WWW_HOME variable)

GOTO_LINE Go to the specified line

--- a/scripts/w3mhelp.cgi.in

+++ b/scripts/w3mhelp.cgi.in

@@ -152,8 +152,9 @@ print "<A HREF="$keymap">$head\

	pipeBuf"));

&show_keymap('Buffer Operations',

&show_keymap('Tab Operations',

     split(" ", "newT closeT nextT prevT tabMn tabR tabL"));

Proxy Information
Original URL
gemini://rkta.srht.site/assets/gemini.patch
Status Code
Success (20)
Meta
text/gemini
Capsule Response Time
167.809802 milliseconds
Gemini-to-HTML Time
9.943585 milliseconds

This content has been proxied by September (ba2dc).