r4804 - trunk/varnish-cache/lib/libvarnishapi

phk at varnish-cache.org phk at varnish-cache.org
Mon May 17 17:27:51 CEST 2010


Author: phk
Date: 2010-05-17 17:27:51 +0200 (Mon, 17 May 2010)
New Revision: 4804

Added:
   trunk/varnish-cache/lib/libvarnishapi/vsl.c
   trunk/varnish-cache/lib/libvarnishapi/vsl.h
   trunk/varnish-cache/lib/libvarnishapi/vsl_arg.c
   trunk/varnish-cache/lib/libvarnishapi/vsl_log.c
Removed:
   trunk/varnish-cache/lib/libvarnishapi/shmlog.c
Modified:
   trunk/varnish-cache/lib/libvarnishapi/Makefile.am
Log:
Split shmlog.c into more appropriately named vsl*[.ch] files



Modified: trunk/varnish-cache/lib/libvarnishapi/Makefile.am
===================================================================
--- trunk/varnish-cache/lib/libvarnishapi/Makefile.am	2010-05-17 13:22:53 UTC (rev 4803)
+++ trunk/varnish-cache/lib/libvarnishapi/Makefile.am	2010-05-17 15:27:51 UTC (rev 4804)
@@ -9,7 +9,9 @@
 libvarnishapi_la_SOURCES = \
 	../libvarnish/vin.c \
 	base64.c \
-	shmlog.c
+	vsl.c \
+	vsl_arg.c \
+	vsl_log.c
 
 libvarnishapi_la_CFLAGS = \
 	-DVARNISH_STATE_DIR='"${VARNISH_STATE_DIR}"'

Deleted: trunk/varnish-cache/lib/libvarnishapi/shmlog.c
===================================================================
--- trunk/varnish-cache/lib/libvarnishapi/shmlog.c	2010-05-17 13:22:53 UTC (rev 4803)
+++ trunk/varnish-cache/lib/libvarnishapi/shmlog.c	2010-05-17 15:27:51 UTC (rev 4804)
@@ -1,663 +0,0 @@
-/*-
- * Copyright (c) 2006 Verdens Gang AS
- * Copyright (c) 2006-2010 Redpill Linpro AS
- * All rights reserved.
- *
- * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "svnid.h"
-SVNID("$Id$")
-
-#include <sys/types.h>
-#include <sys/mman.h>
-
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "shmlog.h"
-#include "vre.h"
-#include "vbm.h"
-#include "miniobj.h"
-#include "varnishapi.h"
-
-/* Parameters */
-#define			SLEEP_USEC	(50*1000)
-#define			TIMEOUT_USEC	(5*1000*1000)
-
-struct VSL_data {
-	unsigned		magic;
-#define VSL_MAGIC		0x6e3bd69b
-
-	struct shmloghead	*head;
-	unsigned char		*logstart;
-	unsigned char		*logend;
-	unsigned char		*ptr;
-
-	/* for -r option */
-	int			r_fd;
-	unsigned		rbuflen;
-	unsigned char		*rbuf;
-
-	unsigned		L_opt;
-	char			*n_opt;
-	int			b_opt;
-	int			c_opt;
-	int			d_opt;
-
-	unsigned		flags;
-#define F_SEEN_IX		(1 << 0)
-#define F_NON_BLOCKING		(1 << 1)
-
-	/*
-	 * These two bitmaps mark fd's as belonging to client or backend
-	 * transactions respectively.
-	 */
-	struct vbitmap		*vbm_client;
-	struct vbitmap		*vbm_backend;
-
-	/*
-	 * Bit map of programatically selected tags, that cannot be suppressed.
-	 * This way programs can make sure they will see certain tags, even
-	 * if the user tries to supress them with -x/-X
-	 */
-	struct vbitmap		*vbm_select;	/* index: tag */
-
-	/* Bit map of tags selected/supressed with -[iIxX] options */
-	struct vbitmap		*vbm_supress;	/* index: tag */
-
-	int			regflags;
-	vre_t			*regincl;
-	vre_t			*regexcl;
-
-	unsigned long		skip;
-	unsigned long		keep;
-
-	int			vsl_fd;
-	struct shmloghead 	*vsl_lh;
-};
-
-#ifndef MAP_HASSEMAPHORE
-#define MAP_HASSEMAPHORE 0 /* XXX Linux */
-#endif
-
-static int vsl_nextlog(struct VSL_data *vd, unsigned char **pp);
-
-/*--------------------------------------------------------------------*/
-
-const char *VSL_tags[256] = {
-#define SLTM(foo)       [SLT_##foo] = #foo,
-#include "shmlog_tags.h"
-#undef SLTM
-};
-
-/*--------------------------------------------------------------------*/
-
-int
-VSL_Open(struct VSL_data *vd)
-{
-	int i;
-	struct shmloghead slh;
-	char *logname;
-
-	if (vd->vsl_lh != NULL)
-		return (0);
-
-	if (vin_n_arg(vd->n_opt, NULL, NULL, &logname)) {
-		fprintf(stderr, "Invalid instance name: %s\n",
-		    strerror(errno));
-		return (1);
-	}
-
-	vd->vsl_fd = open(logname, O_RDONLY);
-	if (vd->vsl_fd < 0) {
-		fprintf(stderr, "Cannot open %s: %s\n",
-		    logname, strerror(errno));
-		return (1);
-	}
-	i = read(vd->vsl_fd, &slh, sizeof slh);
-	if (i != sizeof slh) {
-		fprintf(stderr, "Cannot read %s: %s\n",
-		    logname, strerror(errno));
-		return (1);
-	}
-	if (slh.magic != SHMLOGHEAD_MAGIC) {
-		fprintf(stderr, "Wrong magic number in file %s\n",
-		    logname);
-		return (1);
-	}
-
-	vd->vsl_lh = (void *)mmap(NULL, slh.size + sizeof slh,
-	    PROT_READ, MAP_SHARED|MAP_HASSEMAPHORE, vd->vsl_fd, 0);
-	if (vd->vsl_lh == MAP_FAILED) {
-		fprintf(stderr, "Cannot mmap %s: %s\n",
-		    logname, strerror(errno));
-		return (1);
-	}
-	return (0);
-}
-
-/*--------------------------------------------------------------------*/
-
-struct VSL_data *
-VSL_New(void)
-{
-	struct VSL_data *vd;
-
-	vd = calloc(sizeof *vd, 1);
-	assert(vd != NULL);
-	vd->regflags = 0;
-	vd->magic = VSL_MAGIC;
-	vd->vsl_fd = -1;
-
-	/* XXX: Allocate only if log access */
-	vd->vbm_client = vbit_init(4096);
-	vd->vbm_backend = vbit_init(4096);
-	vd->vbm_supress = vbit_init(256);
-	vd->vbm_select = vbit_init(256);
-
-	vd->r_fd = -1;
-	/* XXX: Allocate only if -r option given ? */
-	vd->rbuflen = SHMLOG_NEXTTAG + 256;
-	vd->rbuf = malloc(vd->rbuflen);
-	assert(vd->rbuf != NULL);
-
-	return (vd);
-}
-
-/*--------------------------------------------------------------------*/
-
-void
-VSL_Delete(struct VSL_data *vd)
-{
-
-	VSL_Close(vd);
-	vbit_destroy(vd->vbm_client);
-	vbit_destroy(vd->vbm_backend);
-	vbit_destroy(vd->vbm_supress);
-	vbit_destroy(vd->vbm_select);
-	free(vd->n_opt);
-	free(vd->rbuf);
-	free(vd);
-}
-
-/*--------------------------------------------------------------------*/
-
-void
-VSL_Select(struct VSL_data *vd, unsigned tag)
-{
-
-	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
-	vbit_set(vd->vbm_select, tag);
-}
-
-/*--------------------------------------------------------------------*/
-
-int
-VSL_OpenLog(struct VSL_data *vd)
-{
-	unsigned char *p;
-
-	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
-	if (vd->r_fd != -1)
-		return (0);
-
-	if (VSL_Open(vd))
-		return (-1);
-
-	vd->head = vd->vsl_lh;
-	vd->logstart = (unsigned char *)vd->vsl_lh + vd->vsl_lh->start;
-	vd->logend = vd->logstart + vd->vsl_lh->size;
-	vd->ptr = vd->logstart;
-
-	if (!vd->d_opt && vd->r_fd == -1) {
-		for (p = vd->ptr; *p != SLT_ENDMARKER; )
-			p += SHMLOG_LEN(p) + SHMLOG_NEXTTAG;
-		vd->ptr = p;
-	}
-	return (0);
-}
-
-/*--------------------------------------------------------------------*/
-
-void
-VSL_NonBlocking(struct VSL_data *vd, int nb)
-{
-	if (nb)
-		vd->flags |= F_NON_BLOCKING;
-	else
-		vd->flags &= ~F_NON_BLOCKING;
-}
-
-/*--------------------------------------------------------------------*/
-
-static int
-vsl_nextlog(struct VSL_data *vd, unsigned char **pp)
-{
-	unsigned char *p;
-	unsigned w, l;
-	int i;
-
-	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
-	if (vd->r_fd != -1) {
-		assert(vd->rbuflen >= SHMLOG_DATA);
-		i = read(vd->r_fd, vd->rbuf, SHMLOG_DATA);
-		if (i != SHMLOG_DATA)
-			return (-1);
-		l = SHMLOG_LEN(vd->rbuf) + SHMLOG_NEXTTAG;
-		if (vd->rbuflen < l) {
-			l += 200;
-			vd->rbuf = realloc(vd->rbuf, l);
-			assert(vd->rbuf != NULL);
-			vd->rbuflen = l;
-		}
-		l = SHMLOG_LEN(vd->rbuf) + 1;
-		i = read(vd->r_fd, vd->rbuf + SHMLOG_DATA, l);
-		if (i != l)
-			return (-1);
-		*pp = vd->rbuf;
-		return (1);
-	}
-
-	p = vd->ptr;
-	for (w = 0; w < TIMEOUT_USEC;) {
-		if (*p == SLT_WRAPMARKER) {
-			p = vd->logstart;
-			continue;
-		}
-		if (*p == SLT_ENDMARKER) {
-			if (vd->flags & F_NON_BLOCKING)
-				return (-1);
-			w += SLEEP_USEC;
-			usleep(SLEEP_USEC);
-			continue;
-		}
-		l = SHMLOG_LEN(p);
-		vd->ptr = p + l + SHMLOG_NEXTTAG;
-		*pp = p;
-		return (1);
-	}
-	vd->ptr = p;
-	return (0);
-}
-
-int
-VSL_NextLog(struct VSL_data *vd, unsigned char **pp)
-{
-	unsigned char *p, t;
-	unsigned u, l;
-	int i;
-
-	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
-	while (1) {
-		i = vsl_nextlog(vd, &p);
-		if (i != 1)
-			return (i);
-		u = SHMLOG_ID(p);
-		l = SHMLOG_LEN(p);
-		switch(p[SHMLOG_TAG]) {
-		case SLT_SessionOpen:
-		case SLT_ReqStart:
-			vbit_set(vd->vbm_client, u);
-			vbit_clr(vd->vbm_backend, u);
-			break;
-		case SLT_BackendOpen:
-		case SLT_BackendXID:
-			vbit_clr(vd->vbm_client, u);
-			vbit_set(vd->vbm_backend, u);
-			break;
-		default:
-			break;
-		}
-		if (vd->skip) {
-			--vd->skip;
-			continue;
-		} else if (vd->keep) {
-			if (--vd->keep == 0)
-				return (-1);
-		}
-		t = p[SHMLOG_TAG];
-		if (vbit_test(vd->vbm_select, t)) {
-			*pp = p;
-			return (1);
-		}
-		if (vbit_test(vd->vbm_supress, t))
-			continue;
-		if (vd->b_opt && !vbit_test(vd->vbm_backend, u))
-			continue;
-		if (vd->c_opt && !vbit_test(vd->vbm_client, u))
-			continue;
-		if (vd->regincl != NULL) {
-			i = VRE_exec(vd->regincl,
-				     (char *)p + SHMLOG_DATA,
-				     SHMLOG_LEN(p) - SHMLOG_DATA, /* Length */
-				     0, 0, NULL, 0);
-			if (i == VRE_ERROR_NOMATCH)
-				continue;
-		}
-		if (vd->regexcl != NULL) {
-			i = VRE_exec(vd->regincl,
-				     (char *)p + SHMLOG_DATA,
-				     SHMLOG_LEN(p) - SHMLOG_DATA, /* Length */
-				     0, 0, NULL, 0);
-			if (i != VRE_ERROR_NOMATCH)
-				continue;
-		}
-		*pp = p;
-		return (1);
-	}
-}
-
-/*--------------------------------------------------------------------*/
-
-int
-VSL_Dispatch(struct VSL_data *vd, vsl_handler *func, void *priv)
-{
-	int i;
-	unsigned u, l, s;
-	unsigned char *p;
-
-	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
-	while (1) {
-		i = VSL_NextLog(vd, &p);
-		if (i <= 0)
-			return (i);
-		u = SHMLOG_ID(p);
-		l = SHMLOG_LEN(p);
-		s = 0;
-		if (vbit_test(vd->vbm_backend, u))
-			s |= VSL_S_BACKEND;
-		if (vbit_test(vd->vbm_client, u))
-			s |= VSL_S_CLIENT;
-		if (func(priv,
-		    p[SHMLOG_TAG], u, l, s, (char *)p + SHMLOG_DATA))
-			return (1);
-	}
-}
-
-/*--------------------------------------------------------------------*/
-
-int
-VSL_H_Print(void *priv, enum shmlogtag tag, unsigned fd, unsigned len,
-    unsigned spec, const char *ptr)
-{
-	FILE *fo = priv;
-	int type;
-
-	assert(fo != NULL);
-
-	type = (spec & VSL_S_CLIENT) ? 'c' :
-	    (spec & VSL_S_BACKEND) ? 'b' : '-';
-
-	if (tag == SLT_Debug) {
-		fprintf(fo, "%5d %-12s %c \"", fd, VSL_tags[tag], type);
-		while (len-- > 0) {
-			if (*ptr >= ' ' && *ptr <= '~')
-				fprintf(fo, "%c", *ptr);
-			else
-				fprintf(fo, "%%%02x", (unsigned char)*ptr);
-			ptr++;
-		}
-		fprintf(fo, "\"\n");
-		return (0);
-	}
-	fprintf(fo, "%5d %-12s %c %.*s\n", fd, VSL_tags[tag], type, len, ptr);
-	return (0);
-}
-
-/*--------------------------------------------------------------------*/
-
-static int
-vsl_r_arg(struct VSL_data *vd, const char *opt)
-{
-
-	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
-	if (!strcmp(opt, "-"))
-		vd->r_fd = STDIN_FILENO;
-	else
-		vd->r_fd = open(opt, O_RDONLY);
-	if (vd->r_fd < 0) {
-		perror(opt);
-		return (-1);
-	}
-	return (1);
-}
-
-/*--------------------------------------------------------------------*/
-
-static int
-vsl_IX_arg(struct VSL_data *vd, const char *opt, int arg)
-{
-	vre_t **rp;
-	const char *error;
-	int erroroffset;
-
-	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
-	if (arg == 'I')
-		rp = &vd->regincl;
-	else
-		rp = &vd->regexcl;
-	if (*rp != NULL) {
-		fprintf(stderr, "Option %c can only be given once", arg);
-		return (-1);
-	}
-	*rp = VRE_compile(opt, vd->regflags, &error, &erroroffset);
-	if (*rp == NULL) {
-		fprintf(stderr, "Illegal regex: %s\n", error);
-		return (-1);
-	}
-	return (1);
-}
-
-/*--------------------------------------------------------------------*/
-
-static int
-vsl_ix_arg(struct VSL_data *vd, const char *opt, int arg)
-{
-	int i, j, l;
-	const char *b, *e, *p, *q;
-
-	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
-	/* If first option is 'i', set all bits for supression */
-	if (arg == 'i' && !(vd->flags & F_SEEN_IX))
-		for (i = 0; i < 256; i++)
-			vbit_set(vd->vbm_supress, i);
-	vd->flags |= F_SEEN_IX;
-
-	for (b = opt; *b; b = e) {
-		while (isspace(*b))
-			b++;
-		e = strchr(b, ',');
-		if (e == NULL)
-			e = strchr(b, '\0');
-		l = e - b;
-		if (*e == ',')
-			e++;
-		while (isspace(b[l - 1]))
-			l--;
-		for (i = 0; i < 256; i++) {
-			if (VSL_tags[i] == NULL)
-				continue;
-			p = VSL_tags[i];
-			q = b;
-			for (j = 0; j < l; j++)
-				if (tolower(*q++) != tolower(*p++))
-					break;
-			if (j != l || *p != '\0')
-				continue;
-
-			if (arg == 'x')
-				vbit_set(vd->vbm_supress, i);
-			else
-				vbit_clr(vd->vbm_supress, i);
-			break;
-		}
-		if (i == 256) {
-			fprintf(stderr,
-			    "Could not match \"%*.*s\" to any tag\n", l, l, b);
-			return (-1);
-		}
-	}
-	return (1);
-}
-
-/*--------------------------------------------------------------------*/
-
-static int
-vsl_s_arg(struct VSL_data *vd, const char *opt)
-{
-	char *end;
-
-	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
-	if (*opt == '\0') {
-		fprintf(stderr, "number required for -s\n");
-		return (-1);
-	}
-	vd->skip = strtoul(opt, &end, 10);
-	if (*end != '\0') {
-		fprintf(stderr, "invalid number for -s\n");
-		return (-1);
-	}
-	return (1);
-}
-/*--------------------------------------------------------------------*/
-
-static int
-vsl_k_arg(struct VSL_data *vd, const char *opt)
-{
-	char *end;
-
-	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
-	if (*opt == '\0') {
-		fprintf(stderr, "number required for -k\n");
-		return (-1);
-	}
-	vd->keep = strtoul(opt, &end, 10);
-	if (*end != '\0') {
-		fprintf(stderr, "invalid number for -k\n");
-		return (-1);
-	}
-	return (1);
-}
-
-/*--------------------------------------------------------------------*/
-
-int
-VSL_Arg(struct VSL_data *vd, int arg, const char *opt)
-{
-
-	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
-	switch (arg) {
-	case 'b': vd->b_opt = !vd->b_opt; return (1);
-	case 'c': vd->c_opt = !vd->c_opt; return (1);
-	case 'd':
-		vd->d_opt = !vd->d_opt;
-		vd->flags |= F_NON_BLOCKING;
-		return (1);
-	case 'i': case 'x': return (vsl_ix_arg(vd, opt, arg));
-	case 'k': return (vsl_k_arg(vd, opt));
-	case 'n':
-		free(vd->n_opt);
-		vd->n_opt = strdup(opt);
-		assert(vd->n_opt != NULL);
-		return (1);
-	case 'r': return (vsl_r_arg(vd, opt));
-	case 's': return (vsl_s_arg(vd, opt));
-	case 'I': case 'X': return (vsl_IX_arg(vd, opt, arg));
-	case 'C': vd->regflags = VRE_CASELESS; return (1);
-	case 'L':
-		vd->L_opt = strtoul(opt, NULL, 0);
-		if (vd->L_opt < 1024 || vd->L_opt > 65000) {
-			fprintf(stderr, "%s\n", VIN_L_MSG);
-			exit (1);
-		}
-		free(vd->n_opt);
-		vd->n_opt = vin_L_arg(vd->L_opt);
-		assert(vd->n_opt != NULL);
-		return (1);
-	default:
-		return (0);
-	}
-}
-
-/*--------------------------------------------------------------------*/
-
-static
-struct shmalloc *
-vsl_find_alloc(struct VSL_data *vd, const char *type, const char *ident)
-{
-	struct shmalloc *sha;
-
-	assert (vd->vsl_lh != NULL);
-	for(sha = &vd->vsl_lh->head; ; sha = SHA_NEXT(sha)) {
-		CHECK_OBJ_NOTNULL(sha, SHMALLOC_MAGIC);
-		if (strcmp(sha->type, type)) 
-			continue;
-		if (ident != NULL && strcmp(sha->ident, ident))
-			continue;
-		return (sha);
-	}
-	return (NULL);
-}
-
-struct varnish_stats *
-VSL_OpenStats(struct VSL_data *vd)
-{
-	struct shmalloc *sha;
-
-	if (VSL_Open(vd))
-		return (NULL);
-	sha = vsl_find_alloc(vd, VSL_STAT_TYPE, "");
-	assert(sha != NULL);
-	return (SHA_PTR(sha));
-}
-
-void
-VSL_Close(struct VSL_data *vd)
-{
-	if (vd->vsl_lh == NULL)
-		return;
-	assert(0 == munmap((void*)vd->vsl_lh,
-	    vd->vsl_lh->size + sizeof *vd->vsl_lh));
-	vd->vsl_lh = NULL;
-	assert(vd->vsl_fd >= 0);
-	assert(0 == close(vd->vsl_fd));
-	vd->vsl_fd = -1;
-}
-
-const char *
-VSL_Name(struct VSL_data *vd)
-{
-
-	return (vd->n_opt);
-}

Copied: trunk/varnish-cache/lib/libvarnishapi/vsl.c (from rev 4803, trunk/varnish-cache/lib/libvarnishapi/shmlog.c)
===================================================================
--- trunk/varnish-cache/lib/libvarnishapi/vsl.c	                        (rev 0)
+++ trunk/varnish-cache/lib/libvarnishapi/vsl.c	2010-05-17 15:27:51 UTC (rev 4804)
@@ -0,0 +1,232 @@
+/*-
+ * Copyright (c) 2006 Verdens Gang AS
+ * Copyright (c) 2006-2010 Redpill Linpro AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "svnid.h"
+SVNID("$Id$")
+
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "shmlog.h"
+#include "vre.h"
+#include "vbm.h"
+#include "miniobj.h"
+#include "varnishapi.h"
+
+#include "vsl.h"
+
+#ifndef MAP_HASSEMAPHORE
+#define MAP_HASSEMAPHORE 0 /* XXX Linux */
+#endif
+
+/*--------------------------------------------------------------------*/
+
+struct VSL_data *
+VSL_New(void)
+{
+	struct VSL_data *vd;
+
+	vd = calloc(sizeof *vd, 1);
+	assert(vd != NULL);
+	vd->regflags = 0;
+	vd->magic = VSL_MAGIC;
+	vd->vsl_fd = -1;
+
+	/* XXX: Allocate only if log access */
+	vd->vbm_client = vbit_init(4096);
+	vd->vbm_backend = vbit_init(4096);
+	vd->vbm_supress = vbit_init(256);
+	vd->vbm_select = vbit_init(256);
+
+	vd->r_fd = -1;
+	/* XXX: Allocate only if -r option given ? */
+	vd->rbuflen = SHMLOG_NEXTTAG + 256;
+	vd->rbuf = malloc(vd->rbuflen);
+	assert(vd->rbuf != NULL);
+
+	return (vd);
+}
+
+/*--------------------------------------------------------------------*/
+
+void
+VSL_Delete(struct VSL_data *vd)
+{
+
+	VSL_Close(vd);
+	vbit_destroy(vd->vbm_client);
+	vbit_destroy(vd->vbm_backend);
+	vbit_destroy(vd->vbm_supress);
+	vbit_destroy(vd->vbm_select);
+	free(vd->n_opt);
+	free(vd->rbuf);
+	free(vd);
+}
+
+/*--------------------------------------------------------------------*/
+
+int
+VSL_Open(struct VSL_data *vd)
+{
+	int i;
+	struct shmloghead slh;
+	char *logname;
+
+	if (vd->vsl_lh != NULL)
+		return (0);
+
+	if (vin_n_arg(vd->n_opt, NULL, NULL, &logname)) {
+		fprintf(stderr, "Invalid instance name: %s\n",
+		    strerror(errno));
+		return (1);
+	}
+
+	vd->vsl_fd = open(logname, O_RDONLY);
+	if (vd->vsl_fd < 0) {
+		fprintf(stderr, "Cannot open %s: %s\n",
+		    logname, strerror(errno));
+		return (1);
+	}
+	i = read(vd->vsl_fd, &slh, sizeof slh);
+	if (i != sizeof slh) {
+		fprintf(stderr, "Cannot read %s: %s\n",
+		    logname, strerror(errno));
+		return (1);
+	}
+	if (slh.magic != SHMLOGHEAD_MAGIC) {
+		fprintf(stderr, "Wrong magic number in file %s\n",
+		    logname);
+		return (1);
+	}
+
+	vd->vsl_lh = (void *)mmap(NULL, slh.size + sizeof slh,
+	    PROT_READ, MAP_SHARED|MAP_HASSEMAPHORE, vd->vsl_fd, 0);
+	if (vd->vsl_lh == MAP_FAILED) {
+		fprintf(stderr, "Cannot mmap %s: %s\n",
+		    logname, strerror(errno));
+		return (1);
+	}
+	return (0);
+}
+
+/*--------------------------------------------------------------------*/
+
+void
+VSL_Close(struct VSL_data *vd)
+{
+	if (vd->vsl_lh == NULL)
+		return;
+	assert(0 == munmap((void*)vd->vsl_lh,
+	    vd->vsl_lh->size + sizeof *vd->vsl_lh));
+	vd->vsl_lh = NULL;
+	assert(vd->vsl_fd >= 0);
+	assert(0 == close(vd->vsl_fd));
+	vd->vsl_fd = -1;
+}
+
+/*--------------------------------------------------------------------*/
+
+static struct shmalloc *
+vsl_find_alloc(struct VSL_data *vd, const char *type, const char *ident)
+{
+	struct shmalloc *sha;
+
+	assert (vd->vsl_lh != NULL);
+	for(sha = &vd->vsl_lh->head; ; sha = SHA_NEXT(sha)) {
+		CHECK_OBJ_NOTNULL(sha, SHMALLOC_MAGIC);
+		if (strcmp(sha->type, type)) 
+			continue;
+		if (ident != NULL && strcmp(sha->ident, ident))
+			continue;
+		return (sha);
+	}
+	return (NULL);
+}
+
+/*--------------------------------------------------------------------*/
+
+struct varnish_stats *
+VSL_OpenStats(struct VSL_data *vd)
+{
+	struct shmalloc *sha;
+
+	if (VSL_Open(vd))
+		return (NULL);
+	sha = vsl_find_alloc(vd, VSL_STAT_TYPE, "");
+	assert(sha != NULL);
+	return (SHA_PTR(sha));
+}
+
+/*--------------------------------------------------------------------*/
+
+int
+VSL_OpenLog(struct VSL_data *vd)
+{
+	unsigned char *p;
+
+	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
+	if (vd->r_fd != -1)
+		return (0);
+
+	if (VSL_Open(vd))
+		return (-1);
+
+	vd->head = vd->vsl_lh;
+	vd->logstart = (unsigned char *)vd->vsl_lh + vd->vsl_lh->start;
+	vd->logend = vd->logstart + vd->vsl_lh->size;
+	vd->ptr = vd->logstart;
+
+	if (!vd->d_opt && vd->r_fd == -1) {
+		for (p = vd->ptr; *p != SLT_ENDMARKER; )
+			p += SHMLOG_LEN(p) + SHMLOG_NEXTTAG;
+		vd->ptr = p;
+	}
+	return (0);
+}
+
+/*--------------------------------------------------------------------*/
+
+const char *
+VSL_Name(struct VSL_data *vd)
+{
+
+	return (vd->n_opt);
+}

Copied: trunk/varnish-cache/lib/libvarnishapi/vsl.h (from rev 4803, trunk/varnish-cache/lib/libvarnishapi/shmlog.c)
===================================================================
--- trunk/varnish-cache/lib/libvarnishapi/vsl.h	                        (rev 0)
+++ trunk/varnish-cache/lib/libvarnishapi/vsl.h	2010-05-17 15:27:51 UTC (rev 4804)
@@ -0,0 +1,86 @@
+/*-
+ * Copyright (c) 2006 Verdens Gang AS
+ * Copyright (c) 2006-2010 Redpill Linpro AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+/* Parameters */
+#define			SLEEP_USEC	(50*1000)
+#define			TIMEOUT_USEC	(5*1000*1000)
+
+struct VSL_data {
+	unsigned		magic;
+#define VSL_MAGIC		0x6e3bd69b
+
+	struct shmloghead	*head;
+	unsigned char		*logstart;
+	unsigned char		*logend;
+	unsigned char		*ptr;
+
+	/* for -r option */
+	int			r_fd;
+	unsigned		rbuflen;
+	unsigned char		*rbuf;
+
+	unsigned		L_opt;
+	char			*n_opt;
+	int			b_opt;
+	int			c_opt;
+	int			d_opt;
+
+	unsigned		flags;
+#define F_SEEN_IX		(1 << 0)
+#define F_NON_BLOCKING		(1 << 1)
+
+	/*
+	 * These two bitmaps mark fd's as belonging to client or backend
+	 * transactions respectively.
+	 */
+	struct vbitmap		*vbm_client;
+	struct vbitmap		*vbm_backend;
+
+	/*
+	 * Bit map of programatically selected tags, that cannot be suppressed.
+	 * This way programs can make sure they will see certain tags, even
+	 * if the user tries to supress them with -x/-X
+	 */
+	struct vbitmap		*vbm_select;	/* index: tag */
+
+	/* Bit map of tags selected/supressed with -[iIxX] options */
+	struct vbitmap		*vbm_supress;	/* index: tag */
+
+	int			regflags;
+	vre_t			*regincl;
+	vre_t			*regexcl;
+
+	unsigned long		skip;
+	unsigned long		keep;
+
+	int			vsl_fd;
+	struct shmloghead 	*vsl_lh;
+};

Copied: trunk/varnish-cache/lib/libvarnishapi/vsl_arg.c (from rev 4803, trunk/varnish-cache/lib/libvarnishapi/shmlog.c)
===================================================================
--- trunk/varnish-cache/lib/libvarnishapi/vsl_arg.c	                        (rev 0)
+++ trunk/varnish-cache/lib/libvarnishapi/vsl_arg.c	2010-05-17 15:27:51 UTC (rev 4804)
@@ -0,0 +1,233 @@
+/*-
+ * Copyright (c) 2006 Verdens Gang AS
+ * Copyright (c) 2006-2010 Redpill Linpro AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "svnid.h"
+SVNID("$Id$")
+
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "shmlog.h"
+#include "vre.h"
+#include "vbm.h"
+#include "miniobj.h"
+#include "varnishapi.h"
+
+#include "vsl.h"
+
+#ifndef MAP_HASSEMAPHORE
+#define MAP_HASSEMAPHORE 0 /* XXX Linux */
+#endif
+
+/*--------------------------------------------------------------------*/
+
+static int
+vsl_r_arg(struct VSL_data *vd, const char *opt)
+{
+
+	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
+	if (!strcmp(opt, "-"))
+		vd->r_fd = STDIN_FILENO;
+	else
+		vd->r_fd = open(opt, O_RDONLY);
+	if (vd->r_fd < 0) {
+		perror(opt);
+		return (-1);
+	}
+	return (1);
+}
+
+/*--------------------------------------------------------------------*/
+
+static int
+vsl_IX_arg(struct VSL_data *vd, const char *opt, int arg)
+{
+	vre_t **rp;
+	const char *error;
+	int erroroffset;
+
+	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
+	if (arg == 'I')
+		rp = &vd->regincl;
+	else
+		rp = &vd->regexcl;
+	if (*rp != NULL) {
+		fprintf(stderr, "Option %c can only be given once", arg);
+		return (-1);
+	}
+	*rp = VRE_compile(opt, vd->regflags, &error, &erroroffset);
+	if (*rp == NULL) {
+		fprintf(stderr, "Illegal regex: %s\n", error);
+		return (-1);
+	}
+	return (1);
+}
+
+/*--------------------------------------------------------------------*/
+
+static int
+vsl_ix_arg(struct VSL_data *vd, const char *opt, int arg)
+{
+	int i, j, l;
+	const char *b, *e, *p, *q;
+
+	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
+	/* If first option is 'i', set all bits for supression */
+	if (arg == 'i' && !(vd->flags & F_SEEN_IX))
+		for (i = 0; i < 256; i++)
+			vbit_set(vd->vbm_supress, i);
+	vd->flags |= F_SEEN_IX;
+
+	for (b = opt; *b; b = e) {
+		while (isspace(*b))
+			b++;
+		e = strchr(b, ',');
+		if (e == NULL)
+			e = strchr(b, '\0');
+		l = e - b;
+		if (*e == ',')
+			e++;
+		while (isspace(b[l - 1]))
+			l--;
+		for (i = 0; i < 256; i++) {
+			if (VSL_tags[i] == NULL)
+				continue;
+			p = VSL_tags[i];
+			q = b;
+			for (j = 0; j < l; j++)
+				if (tolower(*q++) != tolower(*p++))
+					break;
+			if (j != l || *p != '\0')
+				continue;
+
+			if (arg == 'x')
+				vbit_set(vd->vbm_supress, i);
+			else
+				vbit_clr(vd->vbm_supress, i);
+			break;
+		}
+		if (i == 256) {
+			fprintf(stderr,
+			    "Could not match \"%*.*s\" to any tag\n", l, l, b);
+			return (-1);
+		}
+	}
+	return (1);
+}
+
+/*--------------------------------------------------------------------*/
+
+static int
+vsl_s_arg(struct VSL_data *vd, const char *opt)
+{
+	char *end;
+
+	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
+	if (*opt == '\0') {
+		fprintf(stderr, "number required for -s\n");
+		return (-1);
+	}
+	vd->skip = strtoul(opt, &end, 10);
+	if (*end != '\0') {
+		fprintf(stderr, "invalid number for -s\n");
+		return (-1);
+	}
+	return (1);
+}
+/*--------------------------------------------------------------------*/
+
+static int
+vsl_k_arg(struct VSL_data *vd, const char *opt)
+{
+	char *end;
+
+	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
+	if (*opt == '\0') {
+		fprintf(stderr, "number required for -k\n");
+		return (-1);
+	}
+	vd->keep = strtoul(opt, &end, 10);
+	if (*end != '\0') {
+		fprintf(stderr, "invalid number for -k\n");
+		return (-1);
+	}
+	return (1);
+}
+
+/*--------------------------------------------------------------------*/
+
+int
+VSL_Arg(struct VSL_data *vd, int arg, const char *opt)
+{
+
+	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
+	switch (arg) {
+	case 'b': vd->b_opt = !vd->b_opt; return (1);
+	case 'c': vd->c_opt = !vd->c_opt; return (1);
+	case 'd':
+		vd->d_opt = !vd->d_opt;
+		vd->flags |= F_NON_BLOCKING;
+		return (1);
+	case 'i': case 'x': return (vsl_ix_arg(vd, opt, arg));
+	case 'k': return (vsl_k_arg(vd, opt));
+	case 'n':
+		free(vd->n_opt);
+		vd->n_opt = strdup(opt);
+		assert(vd->n_opt != NULL);
+		return (1);
+	case 'r': return (vsl_r_arg(vd, opt));
+	case 's': return (vsl_s_arg(vd, opt));
+	case 'I': case 'X': return (vsl_IX_arg(vd, opt, arg));
+	case 'C': vd->regflags = VRE_CASELESS; return (1);
+	case 'L':
+		vd->L_opt = strtoul(opt, NULL, 0);
+		if (vd->L_opt < 1024 || vd->L_opt > 65000) {
+			fprintf(stderr, "%s\n", VIN_L_MSG);
+			exit (1);
+		}
+		free(vd->n_opt);
+		vd->n_opt = vin_L_arg(vd->L_opt);
+		assert(vd->n_opt != NULL);
+		return (1);
+	default:
+		return (0);
+	}
+}

Copied: trunk/varnish-cache/lib/libvarnishapi/vsl_log.c (from rev 4803, trunk/varnish-cache/lib/libvarnishapi/shmlog.c)
===================================================================
--- trunk/varnish-cache/lib/libvarnishapi/vsl_log.c	                        (rev 0)
+++ trunk/varnish-cache/lib/libvarnishapi/vsl_log.c	2010-05-17 15:27:51 UTC (rev 4804)
@@ -0,0 +1,266 @@
+/*-
+ * Copyright (c) 2006 Verdens Gang AS
+ * Copyright (c) 2006-2010 Redpill Linpro AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "svnid.h"
+SVNID("$Id$")
+
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "shmlog.h"
+#include "vre.h"
+#include "vbm.h"
+#include "miniobj.h"
+#include "varnishapi.h"
+
+#include "vsl.h"
+
+#ifndef MAP_HASSEMAPHORE
+#define MAP_HASSEMAPHORE 0 /* XXX Linux */
+#endif
+
+static int vsl_nextlog(struct VSL_data *vd, unsigned char **pp);
+
+/*--------------------------------------------------------------------*/
+
+const char *VSL_tags[256] = {
+#define SLTM(foo)       [SLT_##foo] = #foo,
+#include "shmlog_tags.h"
+#undef SLTM
+};
+
+/*--------------------------------------------------------------------*/
+
+void
+VSL_Select(struct VSL_data *vd, unsigned tag)
+{
+
+	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
+	vbit_set(vd->vbm_select, tag);
+}
+
+
+/*--------------------------------------------------------------------*/
+
+void
+VSL_NonBlocking(struct VSL_data *vd, int nb)
+{
+	if (nb)
+		vd->flags |= F_NON_BLOCKING;
+	else
+		vd->flags &= ~F_NON_BLOCKING;
+}
+
+/*--------------------------------------------------------------------*/
+
+static int
+vsl_nextlog(struct VSL_data *vd, unsigned char **pp)
+{
+	unsigned char *p;
+	unsigned w, l;
+	int i;
+
+	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
+	if (vd->r_fd != -1) {
+		assert(vd->rbuflen >= SHMLOG_DATA);
+		i = read(vd->r_fd, vd->rbuf, SHMLOG_DATA);
+		if (i != SHMLOG_DATA)
+			return (-1);
+		l = SHMLOG_LEN(vd->rbuf) + SHMLOG_NEXTTAG;
+		if (vd->rbuflen < l) {
+			l += 200;
+			vd->rbuf = realloc(vd->rbuf, l);
+			assert(vd->rbuf != NULL);
+			vd->rbuflen = l;
+		}
+		l = SHMLOG_LEN(vd->rbuf) + 1;
+		i = read(vd->r_fd, vd->rbuf + SHMLOG_DATA, l);
+		if (i != l)
+			return (-1);
+		*pp = vd->rbuf;
+		return (1);
+	}
+
+	p = vd->ptr;
+	for (w = 0; w < TIMEOUT_USEC;) {
+		if (*p == SLT_WRAPMARKER) {
+			p = vd->logstart;
+			continue;
+		}
+		if (*p == SLT_ENDMARKER) {
+			if (vd->flags & F_NON_BLOCKING)
+				return (-1);
+			w += SLEEP_USEC;
+			usleep(SLEEP_USEC);
+			continue;
+		}
+		l = SHMLOG_LEN(p);
+		vd->ptr = p + l + SHMLOG_NEXTTAG;
+		*pp = p;
+		return (1);
+	}
+	vd->ptr = p;
+	return (0);
+}
+
+int
+VSL_NextLog(struct VSL_data *vd, unsigned char **pp)
+{
+	unsigned char *p, t;
+	unsigned u, l;
+	int i;
+
+	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
+	while (1) {
+		i = vsl_nextlog(vd, &p);
+		if (i != 1)
+			return (i);
+		u = SHMLOG_ID(p);
+		l = SHMLOG_LEN(p);
+		switch(p[SHMLOG_TAG]) {
+		case SLT_SessionOpen:
+		case SLT_ReqStart:
+			vbit_set(vd->vbm_client, u);
+			vbit_clr(vd->vbm_backend, u);
+			break;
+		case SLT_BackendOpen:
+		case SLT_BackendXID:
+			vbit_clr(vd->vbm_client, u);
+			vbit_set(vd->vbm_backend, u);
+			break;
+		default:
+			break;
+		}
+		if (vd->skip) {
+			--vd->skip;
+			continue;
+		} else if (vd->keep) {
+			if (--vd->keep == 0)
+				return (-1);
+		}
+		t = p[SHMLOG_TAG];
+		if (vbit_test(vd->vbm_select, t)) {
+			*pp = p;
+			return (1);
+		}
+		if (vbit_test(vd->vbm_supress, t))
+			continue;
+		if (vd->b_opt && !vbit_test(vd->vbm_backend, u))
+			continue;
+		if (vd->c_opt && !vbit_test(vd->vbm_client, u))
+			continue;
+		if (vd->regincl != NULL) {
+			i = VRE_exec(vd->regincl,
+				     (char *)p + SHMLOG_DATA,
+				     SHMLOG_LEN(p) - SHMLOG_DATA, /* Length */
+				     0, 0, NULL, 0);
+			if (i == VRE_ERROR_NOMATCH)
+				continue;
+		}
+		if (vd->regexcl != NULL) {
+			i = VRE_exec(vd->regincl,
+				     (char *)p + SHMLOG_DATA,
+				     SHMLOG_LEN(p) - SHMLOG_DATA, /* Length */
+				     0, 0, NULL, 0);
+			if (i != VRE_ERROR_NOMATCH)
+				continue;
+		}
+		*pp = p;
+		return (1);
+	}
+}
+
+/*--------------------------------------------------------------------*/
+
+int
+VSL_Dispatch(struct VSL_data *vd, vsl_handler *func, void *priv)
+{
+	int i;
+	unsigned u, l, s;
+	unsigned char *p;
+
+	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
+	while (1) {
+		i = VSL_NextLog(vd, &p);
+		if (i <= 0)
+			return (i);
+		u = SHMLOG_ID(p);
+		l = SHMLOG_LEN(p);
+		s = 0;
+		if (vbit_test(vd->vbm_backend, u))
+			s |= VSL_S_BACKEND;
+		if (vbit_test(vd->vbm_client, u))
+			s |= VSL_S_CLIENT;
+		if (func(priv,
+		    p[SHMLOG_TAG], u, l, s, (char *)p + SHMLOG_DATA))
+			return (1);
+	}
+}
+
+/*--------------------------------------------------------------------*/
+
+int
+VSL_H_Print(void *priv, enum shmlogtag tag, unsigned fd, unsigned len,
+    unsigned spec, const char *ptr)
+{
+	FILE *fo = priv;
+	int type;
+
+	assert(fo != NULL);
+
+	type = (spec & VSL_S_CLIENT) ? 'c' :
+	    (spec & VSL_S_BACKEND) ? 'b' : '-';
+
+	if (tag == SLT_Debug) {
+		fprintf(fo, "%5d %-12s %c \"", fd, VSL_tags[tag], type);
+		while (len-- > 0) {
+			if (*ptr >= ' ' && *ptr <= '~')
+				fprintf(fo, "%c", *ptr);
+			else
+				fprintf(fo, "%%%02x", (unsigned char)*ptr);
+			ptr++;
+		}
+		fprintf(fo, "\"\n");
+		return (0);
+	}
+	fprintf(fo, "%5d %-12s %c %.*s\n", fd, VSL_tags[tag], type, len, ptr);
+	return (0);
+}




More information about the varnish-commit mailing list