commit d53c210ecbb69f6e6fb6b2a389ada9c2dee3cb88
parent da3d3735a9b8e35407874e61cb6288999a2271c9
Author: Jacob R. Edwards <jacob@jacobedwards.org>
Date: Sat, 23 Mar 2024 20:31:04 -0700
Add content fragments
This provides an interface for using fragments of content (i.e.
HTML) from files in your CGI program. It's meant for lengthy static
content that would be annoying to produce using khtml functions.
Diffstat:
4 files changed, 59 insertions(+), 3 deletions(-)
diff --git a/Makefile b/Makefile
@@ -3,10 +3,12 @@ cc = ${CC}
cflags = ${CFLAGS} -O0 -Wall -Wextra -I/usr/local/include
lddflags = ${LDDFLAGS} -static -L/usr/local/lib -lkcgi -lkcgihtml -lz -lsqlbox -lsqlite3 -lm -lpthread
prefix = /var/www/htdocs/${name}.primus.lan
+datadir = /var/www/tmp
pages = pages/index.c pages/login.c pages/logout.c \
pages/account.c pages/main.c pages/export.c pages/archive.c
-hdrsrc = page.c html.c user.c stmt.c key.c times.c menu.c pages/util.c pages/common.c
+hdrsrc = page.c html.c user.c stmt.c key.c times.c menu.c frag.c \
+ pages/util.c pages/common.c
src = ${hdrsrc} ${pages}
hdr = ${hdrsrc:.c=.h} util.h pages/util.h pages/pages.h
obj = ${src:.c=.o}
@@ -29,6 +31,7 @@ install: ${name}
cp scripts/* ${prefix}/scripts
mkdir -p ${prefix}/css
cp css/* ${prefix}/css
+ cp -r frags ${datadir}
# Otherwise 'Text file is busy'
pkill kfcgi || true
@@ -36,9 +39,10 @@ install: ${name}
kfcgi -n 1 -N 1 -u www -U www -- /htdocs/timekeeper.primus.lan/timekeeper
uninstall:
- rm -f ${prefix}/${name}
- rm -rf ${prefix}/scripts
rm -rf ${prefix}/css
+ rm -rf ${prefix}/scripts
+ rm -rf ${datadir}/frags
+ rm -f ${prefix}/${name}
.PHONY: clean install uninstall
.SUFFIX: .c .o
diff --git a/config.h b/config.h
@@ -0,0 +1 @@
+#define DataDir "/tmp"
diff --git a/frag.c b/frag.c
@@ -0,0 +1,50 @@
+#include <assert.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <kcgi.h>
+#include <kcgihtml.h>
+
+#include "page.h"
+#include "user.h"
+#include "config.h"
+
+int
+frag(struct pagedata *pd, char *name)
+{
+ int fd;
+ int len;
+ char buf[4096];
+ char path[PATH_MAX];
+ int errprint;
+
+ assert(!strchr(name, '/'));
+
+ errprint = snprintf(path, sizeof(path), DataDir "/frags/%s", name);
+ if (errprint < 0 || (unsigned int)errprint >= sizeof(path))
+ return 1;
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0) {
+ kutil_warn(&pd->req, pd->user ? pd->user->name : NULL, "%s: %s",
+ path, strerror(errno));
+ return 1;
+ }
+
+ while ((len = read(fd, buf, sizeof(buf))) > 0) {
+ if (khttp_write(&pd->req, buf, len) != KCGI_OK)
+ return 1;
+ }
+
+ if (close(fd) || len < 0)
+ return 1;
+ return 0;
+}
diff --git a/frag.h b/frag.h
@@ -0,0 +1 @@
+int frag(struct pagedata *pd, char *name);