[master] 731f514 Add a VFIL facility for searching paths of files.
Poul-Henning Kamp
phk at FreeBSD.org
Fri Jan 8 19:52:21 CET 2016
commit 731f51487b6f17f9d375f3be004fd08a54a7ecce
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Fri Jan 8 18:48:01 2016 +0000
Add a VFIL facility for searching paths of files.
diff --git a/include/vfil.h b/include/vfil.h
index 97484ad..4269fe0 100644
--- a/include/vfil.h
+++ b/include/vfil.h
@@ -28,10 +28,16 @@
*
*/
+struct vfil_path;
+
/* from libvarnish/vfil.c */
int seed_random(void);
char *VFIL_readfile(const char *pfx, const char *fn, ssize_t *sz);
-char *VFIL_readfd(int fd, ssize_t *sz);
int VFIL_nonblocking(int fd);
int VFIL_fsinfo(int fd, unsigned *pbs, uintmax_t *size, uintmax_t *space);
int VFIL_allocate(int fd, off_t size, int insist);
+void VFIL_setpath(struct vfil_path**, const char *path);
+typedef int vfil_path_func_f(void *priv, const char *fn);
+int VFIL_searchpath(const struct vfil_path *, vfil_path_func_f *func,
+ void *priv, char **fn);
+
diff --git a/lib/libvarnish/vfil.c b/lib/libvarnish/vfil.c
index 4b57d01..b6bdc9e 100644
--- a/lib/libvarnish/vfil.c
+++ b/lib/libvarnish/vfil.c
@@ -55,12 +55,16 @@
# include <linux/magic.h>
#endif
-#include "vas.h"
#include "vdef.h"
+
+#include "miniobj.h"
+#include "vas.h"
+#include "vsb.h"
#include "vfil.h"
+#include "vqueue.h"
-char *
-VFIL_readfd(int fd, ssize_t *sz)
+static char *
+vfil_readfd(int fd, ssize_t *sz)
{
struct stat st;
char *f;
@@ -99,7 +103,7 @@ VFIL_readfile(const char *pfx, const char *fn, ssize_t *sz)
fd = open(fn, O_RDONLY);
if (fd < 0)
return (NULL);
- r = VFIL_readfd(fd, sz);
+ r = vfil_readfd(fd, sz);
err = errno;
AZ(close(fd));
errno = err;
@@ -158,7 +162,8 @@ VFIL_fsinfo(int fd, unsigned *pbs, uintmax_t *psize, uintmax_t *pspace)
return (0);
}
-/* Make sure that the file system can accommodate the file of the given
+/*
+ * Make sure that the file system can accommodate the file of the given
* size. Will use fallocate if available. If fallocate is not available
* and insist is true, it will write size zero bytes.
*
@@ -222,3 +227,117 @@ VFIL_allocate(int fd, off_t size, int insist)
assert(lseek(fd, 0, SEEK_SET) == 0);
return (0);
}
+
+struct vfil_dir {
+ unsigned magic;
+#define VFIL_DIR_MAGIC 0x3e214967
+ char *dir;
+ VTAILQ_ENTRY(vfil_dir) list;
+};
+
+struct vfil_path {
+ unsigned magic;
+#define VFIL_PATH_MAGIC 0x92dbcc31
+ char *str;
+ VTAILQ_HEAD(,vfil_dir) paths;
+};
+
+/*
+ * Path searching functions
+ */
+
+void
+VFIL_setpath(struct vfil_path **pp, const char *path)
+{
+ struct vfil_path *vp;
+ struct vfil_dir *vd;
+ char *p, *q;
+
+ AN(pp);
+ AN(path);
+
+ vp = *pp;
+ if (vp == NULL) {
+ ALLOC_OBJ(vp, VFIL_PATH_MAGIC);
+ AN(vp);
+ VTAILQ_INIT(&vp->paths);
+ *pp = vp;
+ }
+ REPLACE(vp->str, path);
+ while (!VTAILQ_EMPTY(&vp->paths)) {
+ vd = VTAILQ_FIRST(&vp->paths);
+ VTAILQ_REMOVE(&vp->paths, vd, list);
+ FREE_OBJ(vd);
+ }
+ for (p = vp->str; p != NULL; p = q) {
+ q = strchr(p, ':');
+ if (q != NULL)
+ *q++ = '\0';
+ ALLOC_OBJ(vd, VFIL_DIR_MAGIC);
+ AN(vd);
+ vd->dir = p;
+ VTAILQ_INSERT_TAIL(&vp->paths, vd, list);
+ }
+}
+
+static int
+vfil_path_openfile(void *priv, const char *fn)
+{
+ char *p, **pp;
+
+ AN(priv);
+ AN(fn);
+ p = VFIL_readfile(NULL, fn, NULL);
+ if (p == NULL)
+ return (1);
+
+ pp = priv;
+ *pp = p;
+ return (0);
+}
+
+int
+VFIL_searchpath(const struct vfil_path *vp, vfil_path_func_f *func, void *priv,
+ char **fnp)
+{
+ struct vsb *vsb;
+ struct vfil_dir *vd;
+ const char *fn;
+ int i, e;
+
+ CHECK_OBJ_NOTNULL(vp, VFIL_PATH_MAGIC);
+ AN(fnp);
+ AN(*fnp);
+ fn = *fnp;
+ *fnp = NULL;
+
+ if (func == NULL) {
+ func = vfil_path_openfile;
+ AN(priv);
+ }
+
+ if (*fn == '/') {
+ i = func(priv, fn);
+ if (i <= 0)
+ REPLACE(*fnp, fn);
+ return (i);
+ }
+ vsb = VSB_new_auto();
+ AN(vsb);
+ VTAILQ_FOREACH(vd, &vp->paths, list) {
+ VSB_clear(vsb);
+ VSB_printf(vsb, "%s/%s", vd->dir, fn);
+ AZ(VSB_finish(vsb));
+ i = func(priv, VSB_data(vsb));
+ if (i <= 0) {
+ e = errno;
+ *fnp = strdup(VSB_data(vsb));
+ AN(*fnp);
+ VSB_delete(vsb);
+ errno = e;
+ return (i);
+ }
+ }
+ VSB_delete(vsb);
+ return (-1);
+}
More information about the varnish-commit
mailing list