X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/agedu/blobdiff_plain/cfe942fb3391ae80e816272d7baa45be30e5e7ec..56cae6e16d22dfba1aafe91dc3465a684d808124:/httpd.c diff --git a/httpd.c b/httpd.c index e71fef7..bbe82ab 100644 --- a/httpd.c +++ b/httpd.c @@ -2,25 +2,8 @@ * httpd.c: implementation of httpd.h. */ -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "malloc.h" +#include "agedu.h" +#include "alloc.h" #include "html.h" #include "httpd.h" @@ -66,7 +49,7 @@ static char *http_error(char *code, char *errmsg, char *extraheader, { return dupfmt("HTTP/1.1 %s %s\r\n" "Date: %D\r\n" - "Server: agedu\r\n" + "Server: " PNAME "\r\n" "Connection: close\r\n" "%s" "Content-Type: text/html; charset=US-ASCII\r\n" @@ -87,7 +70,7 @@ static char *http_success(char *mimetype, int stuff_cr, char *document) return dupfmt("HTTP/1.1 200 OK\r\n" "Date: %D\r\n" "Expires: %D\r\n" - "Server: agedu\r\n" + "Server: " PNAME "\r\n" "Connection: close\r\n" "Content-Type: %s\r\n" "\r\n" @@ -186,7 +169,7 @@ char *got_data(struct connctx *ctx, char *data, int length, /* Restore the request to the way we received it. */ *z2 = c2; *z1 = c1; - text = dupfmt("agedu received the HTTP request" + text = dupfmt("" PNAME " received the HTTP request" " \"%h\", which contains no URL.", line); ret = http_error("400", "Bad request", NULL, text); @@ -277,10 +260,10 @@ char *got_data(struct connctx *ctx, char *data, int length, } if (!magic_access && !auth_correct) { - if (auth_string && !auth_provided) { + if (auth_string) { ret = http_error("401", "Unauthorized", - "WWW-Authenticate: Basic realm=\"agedu\"\r\n", - "Please authenticate to view these pages."); + "WWW-Authenticate: Basic realm=\""PNAME"\"\r", + "\nYou must authenticate to view these pages."); } else { ret = http_error("403", "Forbidden", NULL, "This is a restricted-access set of pages."); @@ -420,7 +403,7 @@ static void base64_encode_atom(unsigned char *data, int n, char *out) void run_httpd(const void *t, int authmask, const struct httpd_config *dcfg, const struct html_config *incfg) { - int fd; + int fd, ret; int authtype; char *authstring = NULL; unsigned long ipaddr; @@ -449,12 +432,24 @@ void run_httpd(const void *t, int authmask, const struct httpd_config *dcfg, ipaddr += (1 + rand() % 255); addr.sin_addr.s_addr = htonl(ipaddr); addr.sin_port = htons(0); + } else { addr.sin_addr.s_addr = inet_addr(dcfg->address); - addr.sin_port = dcfg->port ? htons(dcfg->port) : 80; + addr.sin_port = dcfg->port ? htons(dcfg->port) : 0; } addrlen = sizeof(addr); - if (bind(fd, (struct sockaddr *)&addr, addrlen) < 0) { + ret = bind(fd, (const struct sockaddr *)&addr, addrlen); + if (ret < 0 && errno == EADDRNOTAVAIL && !dcfg->address) { + /* + * Some systems don't like us binding to random weird + * localhost-space addresses. Try again with the official + * INADDR_LOOPBACK. + */ + addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + addr.sin_port = htons(0); + ret = bind(fd, (const struct sockaddr *)&addr, addrlen); + } + if (ret < 0) { fprintf(stderr, "bind: %s\n", strerror(errno)); exit(1); } @@ -487,7 +482,7 @@ void run_httpd(const void *t, int authmask, const struct httpd_config *dcfg, if (dcfg->basicauthdata) { userpass = dcfg->basicauthdata; } else { - sprintf(username, "agedu"); + strcpy(username, PNAME); rname = "/dev/urandom"; fd = open(rname, O_RDONLY); if (fd < 0) { @@ -551,16 +546,16 @@ void run_httpd(const void *t, int authmask, const struct httpd_config *dcfg, if (authmask != HTTPD_AUTH_NONE) printf("Web server is unauthenticated\n"); } else { - fprintf(stderr, "agedu: authentication method not supported\n"); + fprintf(stderr, PNAME ": authentication method not supported\n"); exit(1); } - if (!dcfg->address) { - if (ntohs(addr.sin_port) == 80) { - printf("URL: http://%s/\n", inet_ntoa(addr.sin_addr)); - } else { - printf("URL: http://%s:%d/\n", - inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); - } + if (ntohs(addr.sin_addr.s_addr) == INADDR_ANY) { + printf("Server port: %d\n", ntohs(addr.sin_port)); + } else if (ntohs(addr.sin_port) == 80) { + printf("URL: http://%s/\n", inet_ntoa(addr.sin_addr)); + } else { + printf("URL: http://%s:%d/\n", + inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); } /* @@ -580,7 +575,9 @@ void run_httpd(const void *t, int authmask, const struct httpd_config *dcfg, */ while (1) { fd_set rfds, wfds; - int i, j, maxfd, ret; + int i, j; + SELECT_TYPE_ARG1 maxfd; + int ret; #define FD_SET_MAX(fd, set, max) \ do { FD_SET((fd),(set)); (max) = ((max)<=(fd)?(fd)+1:(max)); } while(0) @@ -604,6 +601,8 @@ void run_httpd(const void *t, int authmask, const struct httpd_config *dcfg, switch (fds[i].type) { case FD_CLIENT: + FD_SET_MAX(fds[i].fd, &rfds, maxfd); + break; case FD_LISTENER: FD_SET_MAX(fds[i].fd, &rfds, maxfd); break; @@ -629,7 +628,9 @@ void run_httpd(const void *t, int authmask, const struct httpd_config *dcfg, } nfds = i; - ret = select(maxfd, &rfds, &wfds, NULL, NULL); + ret = select(maxfd, SELECT_TYPE_ARG234 &rfds, + SELECT_TYPE_ARG234 &wfds, SELECT_TYPE_ARG234 NULL, + SELECT_TYPE_ARG5 NULL); if (ret <= 0) { if (ret < 0 && (errno != EINTR)) { fprintf(stderr, "select: %s", strerror(errno));