commit - f65ed01841f4603f861bed55224227501f56372b
commit + 72f653b65247a296f1be344f3c6c1ad981b9fbcf
blob - a5d43108fff381834af1f61b292ec12bbaa49819
blob + 133f513dd3f413b95795711b0a8ccf074973702c
--- gmid.c
+++ gmid.c
dprintf(logfd, "[%s] " fmt "\n", buf, __VA_ARGS__); \
} while (0)
-const char *dir;
+const char *dir, *cgi;
int dirfd, logfd;
-int cgi;
int connected_clients;
void siginfo_handler(int);
+int starts_with(const char*, const char*);
char *url_after_proto(char*);
char *url_start_of_request(char*);
(void)sig;
}
+int
+starts_with(const char *str, const char *prefix)
+{
+ size_t i;
+
+ for (i = 0; prefix[i] != '\0'; ++i)
+ if (str[i] != prefix[i])
+ return 0;
+ return 1;
+}
+
char *
url_after_proto(char *url)
{
char *s;
const char *proto = "gemini";
const char *marker = "://";
- size_t i;
/* a relative URL */
if ((s = strstr(url, marker)) == NULL)
if (s - strlen(proto) != url)
return NULL;
- for (i = 0; proto[i] != '\0'; ++i)
- if (url[i] != proto[i])
- return NULL;
+ if (!starts_with(url, proto))
+ return NULL;
/* a valid gemini:// URL */
return s + strlen(marker);
return 0;
}
- if (cgi && (sb.st_mode & S_IXUSR)) {
+ /* +2 to skip the ./ */
+ if ((sb.st_mode & S_IXUSR) && cgi != NULL && starts_with(fpath+2, cgi)) {
start_cgi(fpath, query, fds, c);
return 0;
}
usage(const char *me)
{
fprintf(stderr,
- "USAGE: %s [-h] [-c cert.pem] [-d docs] [-k key.pem]\n",
+ "USAGE: %s [-h] [-c cert.pem] [-d docs] [-k key.pem] "
+ "[-l logfile] [-x cgi-bin]\n",
me);
}
dir = "docs/";
logfd = 2; /* stderr */
- cgi = 0;
+ cgi = NULL;
- while ((ch = getopt(argc, argv, "c:d:hk:l:x")) != -1) {
+ while ((ch = getopt(argc, argv, "c:d:hk:l:x:")) != -1) {
switch (ch) {
case 'c':
cert = optarg;
break;
case 'x':
- cgi = 1;
+ cgi = optarg;
break;
default:
if ((dirfd = open(dir, O_RDONLY | O_DIRECTORY)) == -1)
err(1, "open: %s", dir);
- if (unveil(dir, cgi ? "rx" : "r") == -1)
- err(1, "unveil");
+ if (cgi != NULL) {
+ if (unveil(dir, "rx") == -1)
+ err(1, "unveil");
+ if (pledge("stdio rpath inet proc exec", NULL) == -1)
+ err(1, "pledge");
+ } else {
+ if (unveil(dir, "r") == -1)
+ err(1, "unveil");
+ if (pledge("stdio rpath inet", NULL) == -1)
+ err(1, "pledge");
+ }
- if (pledge(cgi ? "stdio rpath inet proc exec" : "stdio rpath inet", NULL) == -1)
- err(1, "pledge");
-
loop(ctx, sock);
close(sock);