about summary refs log blame commit diff stats
path: root/themes/whiteness
blob: 597c9c83267b9aa310d8132e8db5858f0c7847e3 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14



              









                        












               








                            
[colours]
bkgnd=white
titlebar=blue
statusbar=blue
titlebar.text=white
titlebar.brackets=white
statusbar.text=white
statusbar.brackets=white
statusbar.active=megenta
statusbar.new=red
main.text=black
input.text=black
main.time=black
main.splash=black
online=green
away=cyan
chat=green
dnd=red
xa=cyan
offline=red
typing=yellow
gone=red
error=red
incoming=yellow
roominfo=yellow
me=yellow
them=green
titlebar.unencrypted=red
titlebar.encrypted=white
titlebar.untrusted=yellow
titlebar.trusted=white
otr.started.trusted=green
otr.started.untrusted=yellow
otr.ended=red
otr.trusted=green
otr.untrusted=yellow
} /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/* This file is dedicated to the public domain.
 *
 * FreeBSD libfetch adapter for Chawan local-CGI. Not much more than a
 * proof of concept, as its functionality is very limited:
 * - Only a few HTTP headers are supported: Accept, Referer, User-Agent.
 *   So e.g. cookies do not work.
 * - No HTTP headers are returned at all.
 * - Content-Type is deduced from the extension in a very simplistic manner.
 * - Redirects are respected, but not reported.
 * - See also: BUGS section in fetch(3).
 *
 * Use cases:
 * - You are upset about having to download a huge HTTP library even
 *   though your system already has one that kind of works sometimes.
 * - You are stranded on a desert island with nothing but the Chawan
 *   sources on a FreeBSD system without libcurl.
 * - ???
 */

#include <sys/param.h>
#include <stdio.h>
#include <fetch.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define FDIE(x) \
	do { \
		puts("Content-Type: text/plain\r\n"); \
		puts(x); \
		puts(fetchLastErrString); \
		exit(1); \
	} while (0)

#define DIE(x) \
	do { \
		puts("Content-Type: text/plain\r\n\r\n" x); \
		exit(1); \
	} while (0)

int hasext(const char *path)
{
	const char *p = path, *q;

	while ((q = strchr(p, '/')))
		p = q + 1;
	q = strchr(p, '.');
	return !!q;
}

int main(int argc, char **argv)
{
	struct url *u;
	const char *method, *content_type, *p, *np;
	const char *scheme, *username, *password, *host, *port, *path, *query;
	FILE *f;
	size_t len;
	int n, iport = 0;
	char buf[4096];
	size_t prev_inbuf_len = 0;
	size_t inbuf_len = 65536;
	size_t read_len;
	char *inbuf = malloc(inbuf_len);
	char docbuf[4097];
	int has_file_ext = 0;

	if (!inbuf)
		DIE("out of memory");
	if (!(method = getenv("REQUEST_METHOD")))
		DIE("REQUEST_METHOD was not set");
	scheme = getenv("MAPPED_URI_SCHEME");
	host = getenv("MAPPED_URI_HOST");
	if (!scheme || !host)
		DIE("Scheme or host expected");
	username = getenv("MAPPED_URI_USERNAME");
	password = getenv("MAPPED_URI_PASSWORD");
	port = getenv("MAPPED_URI_PORT");
	if (port)
		iport = atoi(port);
	else if (!strcmp(scheme, "http"))
		iport = 80;
	else if (!strcmp(scheme, "https"))
		iport = 443;
	docbuf[0] = '\0';
	path = getenv("MAPPED_URI_PATH");
	strlcat(docbuf, path && *path ? path : "/", sizeof(docbuf));
	has_file_ext = hasext(docbuf);
	query = getenv("MAPPED_URI_QUERY");
	if (query && *query) {
		strlcat(docbuf, "?", sizeof(docbuf));
		strlcat(docbuf, query, sizeof(docbuf));
	}
	u = fetchMakeURL(scheme, host, iport, docbuf, username, password);
	if (!u)
		DIE("Failed to create URL");
	content_type = getenv("CONTENT_TYPE");
	np = getenv("REQUEST_HEADERS");
	while (np) {
		p = np;
		np = strstr(p, "\r\n");
		if (!strncasecmp(p, "User-Agent: ", strlen("User-Agent: "))) {
			p += strlen("User-Agent: ");
			len = np ? np - p : strlen(p);
			if (len >= sizeof(buf))
				DIE("User agent string too long");
			memcpy(&buf[0], p, len);
			buf[len] = '\0';
			setenv("HTTP_USER_AGENT", buf, 1);
		} else if (!strncasecmp(p, "Accept: ", strlen("Accept: "))) {
			p += strlen("Accept: ");
			len = np ? np - p : strlen(p);
			if (len >= sizeof(buf))
				DIE("Accept string too long");
			memcpy(&buf[0], p, len);
			buf[len] = '\0';
			setenv("HTTP_ACCEPT", buf, 1);
		}
		if (np)
			np += 2; /* skip CRLF */
	}
	if (!isatty(STDIN_FILENO)) {
		read_len = inbuf_len - 1 - prev_inbuf_len;
		while ((n = fread(&inbuf[prev_inbuf_len], 1, read_len,
				stdin) == read_len)) {
			if (inbuf_len >= ((size_t)-1) / 2)
				DIE("out of address space");
			prev_inbuf_len = inbuf_len;
			inbuf_len *= 2;
			inbuf = realloc(inbuf, inbuf_len);
			if (!inbuf)
				DIE("out of memory");
			read_len = inbuf_len - 1 - prev_inbuf_len;
		}
	} else {
		n = 0;
	}
	inbuf[n] = '\0';
	f = fetchReqHTTP(u, method, "", content_type, inbuf);
	if (!f)
		FDIE("Failed to open request");
	/* Hack: print a HTML content type if there is no file extension.
	 * If there is one, just let the buffer take care of detecting it. */
	puts(has_file_ext ? "\n" : "Content-Type: text/html\n\n");
	while ((n = fread(buf, 1, sizeof(buf), f)))
		fwrite(buf, 1, n, stdout);
}