quark

quark web server
git clone git://git.suckless.org/quark
Log | Files | Refs | LICENSE

commit a94b15814cf5729a377dd23c7961f183c6884b59
parent 9a95d9183c0d4c656d9aca33c2fca2327dc5f3a6
Author: Laslo Hunhold <dev@frign.de>
Date:   Fri, 28 Aug 2020 23:29:54 +0200

Rename resp.{c,h} to data.{c,h}

The methods in data.h only deal with the actual response data, not
the request handling itself, which has been formalized a bit more
in http.h. To avoid confusion, we rename it to data.h.

Signed-off-by: Laslo Hunhold <dev@frign.de>

Diffstat:
MMakefile | 10+++++-----
Adata.c | 137+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rresp.h -> data.h | 0
Mhttp.c | 1-
Mmain.c | 2+-
Dresp.c | 137-------------------------------------------------------------------------------
6 files changed, 143 insertions(+), 144 deletions(-)

diff --git a/Makefile b/Makefile @@ -4,15 +4,15 @@ include config.mk -COMPONENTS = util sock http resp +COMPONENTS = data http sock util all: quark -util.o: util.c util.h config.mk -sock.o: sock.c sock.h util.h config.mk -http.o: http.c http.h util.h http.h resp.h config.h config.mk -resp.o: resp.c resp.h util.h http.h config.mk +data.o: data.c data.h util.h http.h config.mk +http.o: http.c http.h util.h http.h data.h config.h config.mk main.o: main.c util.h sock.h http.h arg.h config.h config.mk +sock.o: sock.c sock.h util.h config.mk +util.o: util.c util.h config.mk quark: $(COMPONENTS:=.o) $(COMPONENTS:=.h) main.o config.mk $(CC) -o $@ $(CPPFLAGS) $(CFLAGS) $(COMPONENTS:=.o) main.o $(LDFLAGS) diff --git a/data.c b/data.c @@ -0,0 +1,137 @@ +/* See LICENSE file for copyright and license details. */ +#include <dirent.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <time.h> +#include <unistd.h> + +#include "http.h" +#include "data.h" +#include "util.h" + +static int +compareent(const struct dirent **d1, const struct dirent **d2) +{ + int v; + + v = ((*d2)->d_type == DT_DIR ? 1 : -1) - + ((*d1)->d_type == DT_DIR ? 1 : -1); + if (v) { + return v; + } + + return strcmp((*d1)->d_name, (*d2)->d_name); +} + +static char * +suffix(int t) +{ + switch (t) { + case DT_FIFO: return "|"; + case DT_DIR: return "/"; + case DT_LNK: return "@"; + case DT_SOCK: return "="; + } + + return ""; +} + +enum status +resp_dir(int fd, const struct response *res) +{ + enum status ret; + struct dirent **e; + size_t i; + int dirlen; + char esc[PATH_MAX /* > NAME_MAX */ * 6]; /* strlen("&...;") <= 6 */ + + /* read directory */ + if ((dirlen = scandir(res->path, &e, NULL, compareent)) < 0) { + return S_FORBIDDEN; + } + + /* listing */ + for (i = 0; i < (size_t)dirlen; i++) { + /* skip hidden files, "." and ".." */ + if (e[i]->d_name[0] == '.') { + continue; + } + + /* entry line */ + html_escape(e[i]->d_name, esc, sizeof(esc)); + if (dprintf(fd, "<br />\n\t\t<a href=\"%s%s\">%s%s</a>", + esc, + (e[i]->d_type == DT_DIR) ? "/" : "", + esc, + suffix(e[i]->d_type)) < 0) { + ret = S_REQUEST_TIMEOUT; + goto cleanup; + } + } + + /* listing footer */ + if (dprintf(fd, "\n\t</body>\n</html>\n") < 0) { + ret = S_REQUEST_TIMEOUT; + goto cleanup; + } + +cleanup: + while (dirlen--) { + free(e[dirlen]); + } + free(e); + + return ret; +} + +enum status +resp_file(int fd, const struct response *res) +{ + FILE *fp; + enum status ret = 0; + ssize_t bread, bwritten; + size_t remaining; + static char buf[BUFSIZ], *p; + + /* open file */ + if (!(fp = fopen(res->path, "r"))) { + ret = S_FORBIDDEN; + goto cleanup; + } + + /* seek to lower bound */ + if (fseek(fp, res->file.lower, SEEK_SET)) { + ret = S_INTERNAL_SERVER_ERROR; + goto cleanup; + } + + /* write data until upper bound is hit */ + remaining = res->file.upper - res->file.lower + 1; + + while ((bread = fread(buf, 1, MIN(sizeof(buf), + remaining), fp))) { + if (bread < 0) { + ret = S_INTERNAL_SERVER_ERROR; + goto cleanup; + } + remaining -= bread; + p = buf; + while (bread > 0) { + bwritten = write(fd, p, bread); + if (bwritten <= 0) { + ret = S_REQUEST_TIMEOUT; + goto cleanup; + } + bread -= bwritten; + p += bwritten; + } + } +cleanup: + if (fp) { + fclose(fp); + } + + return ret; +} diff --git a/resp.h b/data.h diff --git a/http.c b/http.c @@ -18,7 +18,6 @@ #include "config.h" #include "http.h" -#include "resp.h" #include "util.h" const char *req_field_str[] = { diff --git a/main.c b/main.c @@ -16,7 +16,7 @@ #include <time.h> #include <unistd.h> -#include "resp.h" +#include "data.h" #include "http.h" #include "sock.h" #include "util.h" diff --git a/resp.c b/resp.c @@ -1,137 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include <dirent.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/stat.h> -#include <time.h> -#include <unistd.h> - -#include "http.h" -#include "resp.h" -#include "util.h" - -static int -compareent(const struct dirent **d1, const struct dirent **d2) -{ - int v; - - v = ((*d2)->d_type == DT_DIR ? 1 : -1) - - ((*d1)->d_type == DT_DIR ? 1 : -1); - if (v) { - return v; - } - - return strcmp((*d1)->d_name, (*d2)->d_name); -} - -static char * -suffix(int t) -{ - switch (t) { - case DT_FIFO: return "|"; - case DT_DIR: return "/"; - case DT_LNK: return "@"; - case DT_SOCK: return "="; - } - - return ""; -} - -enum status -resp_dir(int fd, const struct response *res) -{ - enum status ret; - struct dirent **e; - size_t i; - int dirlen; - char esc[PATH_MAX /* > NAME_MAX */ * 6]; /* strlen("&...;") <= 6 */ - - /* read directory */ - if ((dirlen = scandir(res->path, &e, NULL, compareent)) < 0) { - return S_FORBIDDEN; - } - - /* listing */ - for (i = 0; i < (size_t)dirlen; i++) { - /* skip hidden files, "." and ".." */ - if (e[i]->d_name[0] == '.') { - continue; - } - - /* entry line */ - html_escape(e[i]->d_name, esc, sizeof(esc)); - if (dprintf(fd, "<br />\n\t\t<a href=\"%s%s\">%s%s</a>", - esc, - (e[i]->d_type == DT_DIR) ? "/" : "", - esc, - suffix(e[i]->d_type)) < 0) { - ret = S_REQUEST_TIMEOUT; - goto cleanup; - } - } - - /* listing footer */ - if (dprintf(fd, "\n\t</body>\n</html>\n") < 0) { - ret = S_REQUEST_TIMEOUT; - goto cleanup; - } - -cleanup: - while (dirlen--) { - free(e[dirlen]); - } - free(e); - - return ret; -} - -enum status -resp_file(int fd, const struct response *res) -{ - FILE *fp; - enum status ret = 0; - ssize_t bread, bwritten; - size_t remaining; - static char buf[BUFSIZ], *p; - - /* open file */ - if (!(fp = fopen(res->path, "r"))) { - ret = S_FORBIDDEN; - goto cleanup; - } - - /* seek to lower bound */ - if (fseek(fp, res->file.lower, SEEK_SET)) { - ret = S_INTERNAL_SERVER_ERROR; - goto cleanup; - } - - /* write data until upper bound is hit */ - remaining = res->file.upper - res->file.lower + 1; - - while ((bread = fread(buf, 1, MIN(sizeof(buf), - remaining), fp))) { - if (bread < 0) { - ret = S_INTERNAL_SERVER_ERROR; - goto cleanup; - } - remaining -= bread; - p = buf; - while (bread > 0) { - bwritten = write(fd, p, bread); - if (bwritten <= 0) { - ret = S_REQUEST_TIMEOUT; - goto cleanup; - } - bread -= bwritten; - p += bwritten; - } - } -cleanup: - if (fp) { - fclose(fp); - } - - return ret; -}