Commit Diff


commit - 4ceb570910de41133b2771cff29cbb78f37fea30
commit + 534afd0ddcba7c3d2f8478e89db026010c6190c5
blob - 91b6646cccf967ea82f0fd9f573e8b73c9bf9f7c
blob + 1ed3f58637bba9b00a42e5a77c1eb39db2eca8e5
--- ge.c
+++ ge.c
@@ -53,9 +53,9 @@ load_local_cert(struct vhost *h, const char *hostname,
 	if (access(cert, R_OK) == -1 || access(key, R_OK) == -1)
 		gen_certificate(hostname, cert, key);
 
-	h->cert = cert;
-	h->key = key;
-	h->domain = hostname;
+	strlcpy(h->cert, cert, sizeof(h->cert));
+	strlcpy(h->key, key, sizeof(h->key));
+	strlcpy(h->domain, hostname, sizeof(h->domain));
 }
 
 /* wrapper around dirname(3).  dn must be PATH_MAX+1 at least. */
@@ -256,17 +256,22 @@ main(int argc, char **argv)
 
 	load_local_cert(host, hostname, certs_dir);
 
-	host->domain = "*";
+	strlcpy(host->domain, "*", sizeof(host->domain));
 	loc->auto_index = 1;
-	loc->match = "*";
+	strlcpy(loc->match, "*", sizeof(loc->match));
 
 	if (*argv == NULL) {
 		if (getcwd(path, sizeof(path)) == NULL)
 			fatal("getcwd");
-		loc->dir = path;
-	} else
-		loc->dir = absolutify_path(*argv);
+		strlcpy(loc->dir, path, sizeof(loc->dir));
+	} else {
+		char	*tmp;
 
+		tmp = absolutify_path(*argv);
+		strlcpy(loc->dir, tmp, sizeof(loc->dir));
+		free(tmp);
+	}
+
 	if ((loc->dirfd = open(loc->dir, O_RDONLY|O_DIRECTORY)) == -1)
 		fatal("can't open %s", loc->dir);
 
blob - f6d5da65ae49b3adbd17e44da637ca0094c08cf0
blob + 0e7918b31992ce016980ae8d45d477a32e0a9ca8
--- gmid.c
+++ gmid.c
@@ -65,7 +65,7 @@ load_vhosts(void)
 
 	TAILQ_FOREACH(h, &hosts, vhosts) {
 		TAILQ_FOREACH(l, &h->locations, locations) {
-			if (l->dir == NULL)
+			if (*l->dir == '\0')
 				continue;
 			if ((l->dirfd = open(l->dir, O_RDONLY | O_DIRECTORY)) == -1)
 				fatal("open %s for domain %s: %s", l->dir, h->domain,
@@ -132,7 +132,7 @@ make_socket(int port, int family)
 static void
 add_keypair(struct vhost *h)
 {
-	if (h->ocsp == NULL) {
+	if (*h->ocsp == '\0') {
 		if (tls_config_add_keypair_file(tlsconf, h->cert, h->key) == -1)
 			fatal("failed to load the keypair (%s, %s)",
 			    h->cert, h->key);
@@ -170,7 +170,7 @@ setup_tls(void)
 		    h->cert, h->key);
 
 	/* same for OCSP */
-	if (h->ocsp != NULL &&
+	if (*h->ocsp != '\0' &&
 	    tls_config_set_ocsp_staple_file(tlsconf, h->ocsp) == -1)
 		fatal("tls_config_set_ocsp_staple_file failed for (%s)",
 		    h->ocsp);
@@ -216,7 +216,7 @@ free_config(void)
 	struct proxy *p, *tp;
 	struct envlist *e, *te;
 	struct alist *a, *ta;
-	int v, i;
+	int v;
 
 	v = conf.verbose;
 
@@ -229,13 +229,6 @@ free_config(void)
 		TAILQ_FOREACH_SAFE(l, &h->locations, locations, tl) {
 			TAILQ_REMOVE(&h->locations, l, locations);
 
-			free((char*)l->match);
-			free((char*)l->lang);
-			free((char*)l->default_mime);
-			free((char*)l->index);
-			free((char*)l->block_fmt);
-			free((char*)l->dir);
-
 			if (l->dirfd != -1)
 				close(l->dirfd);
 
@@ -244,49 +237,26 @@ free_config(void)
 
 		TAILQ_FOREACH_SAFE(e, &h->params, envs, te) {
 			TAILQ_REMOVE(&h->params, e, envs);
-
-			free(e->name);
-			free(e->value);
 			free(e);
 		}
 
 		TAILQ_FOREACH_SAFE(a, &h->aliases, aliases, ta) {
 			TAILQ_REMOVE(&h->aliases, a, aliases);
-
-			free(a->alias);
 			free(a);
 		}
 
 		TAILQ_FOREACH_SAFE(p, &h->proxies, proxies, tp) {
 			TAILQ_REMOVE(&h->proxies, p, proxies);
-
-			free(p->match_proto);
-			free(p->match_host);
-			free(p->host);
-			free(p->sni);
 			tls_unload_file(p->cert, p->certlen);
 			tls_unload_file(p->key, p->keylen);
 			free(p);
 		}
-
-		free((char*)h->domain);
-		free((char*)h->cert);
-		free((char*)h->key);
-		free((char*)h->ocsp);
 
 		TAILQ_REMOVE(&hosts, h, vhosts);
 		free(h);
 	}
 
-	for (i = 0; i < FCGI_MAX; ++i) {
-		if (fcgi[i].path == NULL)
-			break;
-		free(fcgi[i].path);
-		free(fcgi[i].port);
-
-		fcgi[i].path = NULL;
-		fcgi[i].port = NULL;
-	}
+	memset(fcgi, 0, sizeof(fcgi));
 
 	tls_free(ctx);
 	tls_config_free(tlsconf);
blob - 7be90515e98bc0f9d9eb25cf3b1fe61cc529a5c8
blob + 82d472ac0e0f2abc72a3b1487566e36fb4543993
--- gmid.h
+++ gmid.h
@@ -77,6 +77,9 @@
 #define MEDIATYPE_NAMEMAX	128	/* file name extension */
 #define MEDIATYPE_TYPEMAX	128	/* length of type/subtype */
 
+#define FCGI_NAME_MAX		511
+#define FCGI_VAL_MAX		511
+
 #define FCGI_MAX	32
 #define PROC_MAX	16
 
@@ -98,20 +101,20 @@ struct parser {
 
 struct fcgi {
 	int		 id;
-	char		*path;
-	char		*port;
+	char		 path[PATH_MAX];
+	char		 port[32];
 };
 extern struct fcgi fcgi[FCGI_MAX];
 
 TAILQ_HEAD(proxyhead, proxy);
 struct proxy {
-	char		*match_proto;
-	char		*match_host;
-	const char	*match_port;
+	char		 match_proto[32];
+	char		 match_host[HOST_NAME_MAX + 1];
+	char		 match_port[32];
 
-	char		*host;
-	const char	*port;
-	char		*sni;
+	char		 host[HOST_NAME_MAX + 1];
+	char		 port[32];
+	char		 sni[HOST_NAME_MAX];
 	int		 notls;
 	uint32_t	 protocols;
 	int		 noverifyname;
@@ -126,19 +129,19 @@ struct proxy {
 
 TAILQ_HEAD(lochead, location);
 struct location {
-	const char	*match;
-	const char	*lang;
-	const char	*default_mime;
-	const char	*index;
+	char		 match[128];
+	char		 lang[32];
+	char		 default_mime[MEDIATYPE_TYPEMAX];
+	char		 index[PATH_MAX];
 	int		 auto_index; /* 0 auto, -1 off, 1 on */
 	int		 block_code;
-	const char	*block_fmt;
+	char		 block_fmt[GEMINI_URL_LEN];
 	int		 strip;
 	X509_STORE	*reqca;
 	int		 disable_log;
 	int		 fcgi;
 
-	const char	*dir;
+	char		 dir[PATH_MAX];
 	int		 dirfd;
 
 	TAILQ_ENTRY(location) locations;
@@ -146,23 +149,23 @@ struct location {
 
 TAILQ_HEAD(envhead, envlist);
 struct envlist {
-	char		*name;
-	char		*value;
+	char		 name[FCGI_NAME_MAX];
+	char		 value[FCGI_VAL_MAX];
 	TAILQ_ENTRY(envlist) envs;
 };
 
 TAILQ_HEAD(aliashead, alist);
 struct alist {
-	char		*alias;
+	char		alias[HOST_NAME_MAX + 1];
 	TAILQ_ENTRY(alist) aliases;
 };
 
 extern TAILQ_HEAD(vhosthead, vhost) hosts;
 struct vhost {
-	const char	*domain;
-	const char	*cert;
-	const char	*key;
-	const char	*ocsp;
+	char		 domain[HOST_NAME_MAX + 1];
+	char		 cert[PATH_MAX];
+	char		 key[PATH_MAX];
+	char		 ocsp[PATH_MAX];
 
 	TAILQ_ENTRY(vhost) vhosts;
 
blob - 56f01081f621f518b7300df82677446b08c99a70
blob + c49b5819ea0d7c82674f3dde8a61e30ad3bf17a6
--- parse.y
+++ parse.y
@@ -27,6 +27,7 @@
 
 #include <ctype.h>
 #include <errno.h>
+#include <netdb.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -91,10 +92,9 @@ int		 check_prefork_num(int);
 void		 advance_loc(void);
 void		 advance_proxy(void);
 void		 parsehp(char *, char **, const char **, const char *);
-void		 only_once(const void*, const char*);
-void		 only_oncei(int, const char*);
-int		 fastcgi_conf(char *, char *, char *);
+int		 fastcgi_conf(const char *, const char *, char *);
 void		 add_param(char *, char *);
+int		 getservice(const char *);
 
 static struct vhost		*host;
 static struct location		*loc;
@@ -136,7 +136,7 @@ typedef struct {
 %token	<v.string>	STRING
 %token	<v.number>	NUM
 
-%type	<v.number>	bool
+%type	<v.number>	bool proxy_port
 %type	<v.string>	string numberstring
 
 %%
@@ -242,15 +242,17 @@ vhost		: SERVER string {
 
 			TAILQ_INIT(&host->proxies);
 
-			loc->match = xstrdup("*");
-			host->domain = $2;
+			(void) strlcpy(loc->match, "*", sizeof(loc->match));
+			(void) strlcpy(host->domain, $2, sizeof(host->domain));
 
 			if (strstr($2, "xn--") != NULL) {
 				yywarn("\"%s\" looks like punycode: you "
 				    "should use the decoded hostname", $2);
 			}
+
+			free($2);
 		} '{' optnl servbody '}' {
-			if (host->cert == NULL || host->key == NULL)
+			if (*host->cert == '\0' || *host->key == '\0')
 				yyerror("invalid vhost definition: %s", $2);
 		}
 		| error '}'		{ yyerror("bad server directive"); }
@@ -266,20 +268,24 @@ servopt		: ALIAS string {
 			struct alist *a;
 
 			a = xcalloc(1, sizeof(*a));
-			a->alias = $2;
+			(void) strlcpy(a->alias, $2, sizeof(a->alias));
+			free($2);
 			TAILQ_INSERT_TAIL(&host->aliases, a, aliases);
 		}
 		| CERT string		{
-			only_once(host->cert, "cert");
-			host->cert = ensure_absolute_path($2);
+			ensure_absolute_path($2);
+			(void) strlcpy(host->cert, $2, sizeof(host->cert));
+			free($2);
 		}
 		| KEY string		{
-			only_once(host->key, "key");
-			host->key  = ensure_absolute_path($2);
+			ensure_absolute_path($2);
+			(void) strlcpy(host->key, $2, sizeof(host->key));
+			free($2);
 		}
 		| OCSP string		{
-			only_once(host->ocsp, "ocsp");
-			host->ocsp = ensure_absolute_path($2);
+			ensure_absolute_path($2);
+			(void) strlcpy(host->ocsp, $2, sizeof(host->ocsp));
+			free($2);
 		}
 		| PARAM string '=' string {
 			add_param($2, $4);
@@ -289,7 +295,7 @@ servopt		: ALIAS string {
 
 proxy		: PROXY { advance_proxy(); }
 		  proxy_matches '{' optnl proxy_opts '}' {
-			if (proxy->host == NULL)
+			if (*proxy->host == '\0')
 				yyerror("invalid proxy block: missing `relay-to' option");
 
 			if ((proxy->cert == NULL && proxy->key != NULL) ||
@@ -302,15 +308,24 @@ proxy_matches	: /* empty */
 		| proxy_matches proxy_match
 		;
 
+proxy_port	: /* empty */	{ $$ = 1965; }
+		| PORT STRING {
+			if (($$ = getservice($2)) == -1)
+				yyerror("invalid port number %s", $2);
+			free($2);
+		}
+		| PORT NUM	{ $$ = $2; }
+		;
+
 proxy_match	: PROTO string {
-			only_once(proxy->match_proto, "proxy proto");
-			free(proxy->match_proto);
-			proxy->match_proto = $2;
+			(void) strlcpy(proxy->match_proto, $2, sizeof(proxy->match_proto));
+			free($2);
 		}
-		| FOR_HOST string {
-			only_once(proxy->match_host, "proxy for-host");
-			free(proxy->match_host);
-			parsehp($2, &proxy->match_host, &proxy->match_port, "10965");
+		| FOR_HOST string proxy_port {
+			(void) strlcpy(proxy->match_host, $2, sizeof(proxy->match_host));
+			(void) snprintf(proxy->match_port, sizeof(proxy->match_port),
+			    "%d", $3);
+			free($2);
 		}
 		;
 
@@ -319,7 +334,6 @@ proxy_opts	: /* empty */
 		;
 
 proxy_opt	: CERT string {
-			only_once(proxy->cert, "proxy cert");
 			tls_unload_file(proxy->cert, proxy->certlen);
 			ensure_absolute_path($2);
 			proxy->cert = tls_load_file($2, &proxy->certlen, NULL);
@@ -328,7 +342,6 @@ proxy_opt	: CERT string {
 			free($2);
 		}
 		| KEY string {
-			only_once(proxy->key, "proxy key");
 			tls_unload_file(proxy->key, proxy->keylen);
 			ensure_absolute_path($2);
 			proxy->key = tls_load_file($2, &proxy->keylen, NULL);
@@ -341,22 +354,21 @@ proxy_opt	: CERT string {
 				yyerror("invalid protocols string \"%s\"", $2);
 			free($2);
 		}
-		| RELAY_TO string {
-			only_once(proxy->host, "proxy relay-to");
-			free(proxy->host);
-			parsehp($2, &proxy->host, &proxy->port, "1965");
+		| RELAY_TO string proxy_port {
+			(void) strlcpy(proxy->host, $2, sizeof(proxy->host));
+			(void) snprintf(proxy->port, sizeof(proxy->port),
+			    "%d", $3);
+			free($2);
 		}
 		| REQUIRE CLIENT CA string {
-			only_once(proxy->reqca, "require client ca");
 			ensure_absolute_path($4);
 			if ((proxy->reqca = load_ca($4)) == NULL)
 				yyerror("couldn't load ca cert: %s", $4);
 			free($4);
 		}
 		| SNI string {
-			only_once(proxy->sni, "proxy sni");
-			free(proxy->sni);
-			proxy->sni = $2;
+			(void) strlcpy(proxy->sni, $2, sizeof(proxy->sni));
+			free($2);
 		}
 		| USE_TLS bool {
 			proxy->notls = !$2;
@@ -370,7 +382,8 @@ location	: LOCATION { advance_loc(); } string '{' optn
 			/* drop the starting '/' if any */
 			if (*$3 == '/')
 				memmove($3, $3+1, strlen($3));
-			loc->match = $3;
+			(void) strlcpy(loc->match, $3, sizeof(loc->match));
+			free($3);
 		}
 		| error '}'
 		;
@@ -381,72 +394,75 @@ locopts		: /* empty */
 
 locopt		: AUTO INDEX bool	{ loc->auto_index = $3 ? 1 : -1; }
 		| BLOCK RETURN NUM string {
-			only_once(loc->block_fmt, "block");
-			loc->block_fmt = check_block_fmt($4);
+			check_block_fmt($4);
+			(void) strlcpy(loc->block_fmt, $4, sizeof(loc->block_fmt));
 			loc->block_code = check_block_code($3);
+			free($4);
 		}
 		| BLOCK RETURN NUM {
-			only_once(loc->block_fmt, "block");
-			loc->block_fmt = xstrdup("temporary failure");
+			(void) strlcpy(loc->block_fmt, "temporary failure",
+			    sizeof(loc->block_fmt));
 			loc->block_code = check_block_code($3);
 			if ($3 >= 30 && $3 < 40)
 				yyerror("missing `meta' for block return %d", $3);
 		}
 		| BLOCK {
-			only_once(loc->block_fmt, "block");
-			loc->block_fmt = xstrdup("temporary failure");
+			(void) strlcpy(loc->block_fmt, "temporary failure",
+			    sizeof(loc->block_fmt));
 			loc->block_code = 40;
 		}
 		| DEFAULT TYPE string {
-			only_once(loc->default_mime, "default type");
-			loc->default_mime = $3;
+			(void) strlcpy(loc->default_mime, $3,
+			    sizeof(loc->default_mime));
+			free($3);
 		}
 		| FASTCGI fastcgi
 		| INDEX string {
-			only_once(loc->index, "index");
-			loc->index = $2;
+			(void) strlcpy(loc->index, $2, sizeof(loc->index));
+			free($2);
 		}
 		| LANG string {
-			only_once(loc->lang, "lang");
-			loc->lang = $2;
+			(void) strlcpy(loc->lang, $2,
+			    sizeof(loc->lang));
+			free($2);
 		}
 		| LOG bool	{ loc->disable_log = !$2; }
 		| REQUIRE CLIENT CA string {
-			only_once(loc->reqca, "require client ca");
 			ensure_absolute_path($4);
 			if ((loc->reqca = load_ca($4)) == NULL)
 				yyerror("couldn't load ca cert: %s", $4);
 			free($4);
 		}
 		| ROOT string		{
-			only_once(loc->dir, "root");
-			loc->dir  = ensure_absolute_path($2);
+			(void) strlcpy(loc->dir, $2, sizeof(loc->dir));
+			free($2);
 		}
 		| STRIP NUM		{ loc->strip = check_strip_no($2); }
 		;
 
 fastcgi		: SPAWN string {
-			only_oncei(loc->fcgi, "fastcgi");
 			loc->fcgi = fastcgi_conf(NULL, NULL, $2);
+			free($2);
 		}
 		| string {
-			only_oncei(loc->fcgi, "fastcgi");
 			loc->fcgi = fastcgi_conf($1, NULL, NULL);
+			free($1);
 		}
 		| TCP string PORT NUM {
 			char *c;
 			if (asprintf(&c, "%d", $4) == -1)
 				err(1, "asprintf");
-			only_oncei(loc->fcgi, "fastcgi");
 			loc->fcgi = fastcgi_conf($2, c, NULL);
+			free($2);
 		}
 		| TCP string {
-			only_oncei(loc->fcgi, "fastcgi");
-			loc->fcgi = fastcgi_conf($2, xstrdup("9000"), NULL);
+			loc->fcgi = fastcgi_conf($2, "9000", NULL);
+			free($2);
 		}
 		| TCP string PORT string {
-			only_oncei(loc->fcgi, "fastcgi");
 			loc->fcgi = fastcgi_conf($2, $4, NULL);
+			free($2);
+			free($4);
 		}
 		;
 
@@ -1151,24 +1167,10 @@ parsehp(char *str, char **host, const char **port, con
 	strtonum(*port, 1, UINT16_MAX, &errstr);
 	if (errstr != NULL)
 		yyerror("port is %s: %s", errstr, *port);
-}
-
-void
-only_once(const void *ptr, const char *name)
-{
-	if (ptr != NULL)
-		yyerror("`%s' specified more than once", name);
-}
-
-void
-only_oncei(int i, const char *name)
-{
-	if (i != -1)
-		yyerror("`%s' specified more than once", name);
 }
 
 int
-fastcgi_conf(char *path, char *port, char *prog)
+fastcgi_conf(const char *path, const char *port, char *prog)
 {
 	struct fcgi	*f;
 	int		i;
@@ -1178,20 +1180,17 @@ fastcgi_conf(char *path, char *port, char *prog)
 	for (i = 0; i < FCGI_MAX; ++i) {
 		f = &fcgi[i];
 
-		if (f->path == NULL) {
+		if (*f->path == '\0') {
 			f->id = i;
-			f->path = path;
-			f->port = port;
+			(void) strlcpy(f->path, path, sizeof(f->path));
+			(void) strlcpy(f->port, port, sizeof(f->port));
 			return i;
 		}
 
 		if (!strcmp(f->path, path) &&
-		    ((port == NULL && f->port == NULL) ||
-		     !strcmp(f->port, port))) {
-			free(path);
-			free(port);
+		    ((port == NULL && *f->port == '\0') ||
+		     !strcmp(f->port, port)))
 			return i;
-		}
 	}
 
 	yyerror("too much `fastcgi' rules defined.");
@@ -1205,7 +1204,27 @@ add_param(char *name, char *val)
 	struct envhead *h = &host->params;
 
 	e = xcalloc(1, sizeof(*e));
-	e->name = name;
-	e->value = val;
+	(void) strlcpy(e->name, name, sizeof(e->name));
+	(void) strlcpy(e->value, val, sizeof(e->value));
 	TAILQ_INSERT_TAIL(h, e, envs);
 }
+
+int
+getservice(const char *n)
+{
+	struct servent	*s;
+	const char	*errstr;
+	long long	 llval;
+
+	llval = strtonum(n, 0, UINT16_MAX, &errstr);
+	if (errstr) {
+		s = getservbyname(n, "tcp");
+		if (s == NULL)
+			s = getservbyname(n, "udp");
+		if (s == NULL)
+			return (-1);
+		return (ntohs(s->s_port));
+	}
+
+	return ((unsigned short)llval);
+}
blob - 532517baddf989a7767481f967c199079d78d406
blob + 3c83a325ba92f2549125a474933bb47cfa353419
--- proxy.c
+++ proxy.c
@@ -326,7 +326,7 @@ proxy_setup_tls(struct client *c)
 	if (tls_configure(c->proxyctx, conf) == -1)
 		goto err;
 
-	if ((hn = p->sni) == NULL)
+	if (*(hn = p->sni) == '\0')
 		hn = p->host;
 	if (tls_connect_socket(c->proxyctx, c->pfd, hn) == -1)
 		goto err;
blob - afde8b76618a87bc6807893a54f0c4240e2de0af
blob + 668ef2816d519b2cd8b16e088ec74f9ea853401d
--- regress/lib.sh
+++ regress/lib.sh
@@ -80,7 +80,7 @@ server "localhost.local" {
 	cert "$PWD/cert.pem"
 	key "$PWD/key.pem"
 	proxy {
-		relay-to "localhost:$port"
+		relay-to localhost port $port
 		$1
 	}
 }
blob - 52a161ddc90a8a4446fda741dca4c8fbc1729d7f
blob + f1ca7cba7bea4b3ed467a5dc0caa805e49552584
--- sandbox.c
+++ sandbox.c
@@ -514,7 +514,7 @@ server_landlock(void)
 
 	TAILQ_FOREACH(h, &hosts, vhosts) {
 		TAILQ_FOREACH(l, &h->locations, locations) {
-			if (l->dir == NULL)
+			if (*l->dir == '\0')
 				continue;
 
 			if (landlock_unveil_path(fd, l->dir, perms) == -1)
@@ -608,7 +608,7 @@ sandbox_server_process(int can_open_sockets)
 
 	TAILQ_FOREACH(h, &hosts, vhosts) {
 		TAILQ_FOREACH(l, &h->locations, locations) {
-			if (l->dir == NULL)
+			if (*l->dir == '\0')
 				continue;
 
 			if (unveil(l->dir, "r") == -1)
blob - ebac30e06a4b9df017c6d9c1e2e7d6dc47cae63c
blob + 50b443fc44835c904057f0166f9930cb390c52b0
--- server.c
+++ server.c
@@ -90,13 +90,16 @@ vhost_lang(struct vhost *v, const char *path)
 
 	loc = TAILQ_FIRST(&v->locations);
 	while ((loc = TAILQ_NEXT(loc, locations)) != NULL) {
-		if (loc->lang != NULL) {
+		if (*loc->lang != '\0') {
 			if (matches(loc->match, path))
 				return loc->lang;
 		}
 	}
 
-	return TAILQ_FIRST(&v->locations)->lang;
+	loc = TAILQ_FIRST(&v->locations);
+	if (*loc->lang == '\0')
+		return NULL;
+	return loc->lang;
 }
 
 const char *
@@ -110,14 +113,14 @@ vhost_default_mime(struct vhost *v, const char *path)
 
 	loc = TAILQ_FIRST(&v->locations);
 	while ((loc = TAILQ_NEXT(loc, locations)) != NULL) {
-		if (loc->default_mime != NULL) {
+		if (*loc->default_mime != '\0') {
 			if (matches(loc->match, path))
 				return loc->default_mime;
 		}
 	}
 
 	loc = TAILQ_FIRST(&v->locations);
-	if (loc->default_mime != NULL)
+	if (*loc->default_mime != '\0')
 		return loc->default_mime;
 	return default_mime;
 }
@@ -133,14 +136,14 @@ vhost_index(struct vhost *v, const char *path)
 
 	loc = TAILQ_FIRST(&v->locations);
 	while ((loc = TAILQ_NEXT(loc, locations)) != NULL) {
-		if (loc->index != NULL) {
+		if (*loc->index != '\0') {
 			if (matches(loc->match, path))
 				return loc->index;
 		}
 	}
 
 	loc = TAILQ_FIRST(&v->locations);
-	if (loc->index != NULL)
+	if (*loc->index != '\0')
 		return loc->index;
 	return index;
 }
@@ -536,11 +539,11 @@ matched_proxy(struct client *c)
 	const char	*port;
 
 	TAILQ_FOREACH(p, &c->host->proxies, proxies) {
-		if ((proto = p->match_proto) == NULL)
+		if (*(proto = p->match_proto) == '\0')
 			proto = "gemini";
-		if ((host = p->match_host) == NULL)
+		if (*(host = p->match_host) == '\0')
 			host = "*";
-		if ((port = p->match_port) == NULL)
+		if (*(port = p->match_port) == '\0')
 			port = "*";
 
 		if (matches(proto, c->iri.schema) &&
@@ -719,7 +722,7 @@ apply_fastcgi(struct client *c)
 	log_debug(c, "opening fastcgi connection for (%s,%s)",
 	    f->path, f->port);
 
-	if (f->port != NULL)
+	if (*f->port != '\0')
 		c->pfd = fcgi_open_sock(f);
 	else
 		c->pfd = fcgi_open_conn(f);