<commit_before>/*-
 * Copyright (c) 2006 Verdens Gang AS
 * Copyright (c) 2006 Linpro AS
 * All rights reserved.
 *
 * Author: <NAME> <<EMAIL>>
 *
 * 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 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$
 *
 * Log tailer for Varnish
 */

#include <errno.h>
#include <fcntl.h>
#include <regex.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "compat/vis.h"

#include "vsb.h"

#include "libvarnish.h"
#include "shmlog.h"
#include "varnishapi.h"

static int	bflag, cflag;

/* -------------------------------------------------------------------*/

static int
name2tag(const char *n)
{
	int i;

	for (i = 0; i < 256; i++) {
		if (VSL_tags[i] == NULL)
			continue;
		if (!strcasecmp(n, VSL_tags[i]))
			return (i);
	}
	return (-1);
}

/* Ordering-----------------------------------------------------------*/

static struct vsb	*ob[65536];
static unsigned char	flg[65536];
#define F_INVCL		(1 << 0)
#define F_MATCH		(1 << 1)

static int		match_tag = -1;
static regex_t		match_re;

static void
clean_order(void)
{
	unsigned u;

	for (u = 0; u < 65536; u++) {
		if (ob[u] == NULL)
			continue;
		vsb_finish(ob[u]);
		if (vsb_len(ob[u]) > 1 &&
		    (match_tag == -1 || flg[u] & F_MATCH))
			printf("%s\n", vsb_data(ob[u]));
		flg[u] = 0;
		vsb_clear(ob[u]);
	}
}

static int
h_order(void *priv, enum shmlogtag tag, unsigned fd, unsigned len, unsigned spec, const char *ptr)
{

	(void)priv;

	if (!(spec & (VSL_S_CLIENT|VSL_S_BACKEND))) {
		if (!bflag && !cflag)
			VSL_H_Print(stdout, tag, fd, len, spec, ptr);
		return (0);
	}
	if (ob[fd] == NULL) {
		ob[fd] = vsb_new(NULL, NULL, 0, VSB_AUTOEXTEND);
		assert(ob[fd] != NULL);
	}
	if (tag == match_tag &&
	    !regexec(&match_re, ptr, 0, NULL, 0))
		flg[fd] |= F_MATCH;
	switch (tag) {
	case SLT_VCL_call:
		flg[fd] |= F_INVCL;
		vsb_printf(ob[fd], "%5d %-12s %c %.*s\n",
		    fd, VSL_tags[tag],
		    ((spec & VSL_S_CLIENT) ? 'c' : \
		    (spec & VSL_S_BACKEND) ? 'b' : '-'),
		    len, ptr);
		return (0);
	case SLT_VCL_trace:
	case SLT_VCL_return:
		if (flg[fd] & F_INVCL) {
			vsb_cat(ob[fd], " ");
			vsb_bcat(ob[fd], ptr, len);
			return (0);
		}
		break;
	default:
		break;
	}
	if (flg[fd] & F_INVCL) {
		vsb_cat(ob[fd], "\n");
		flg[fd] &= ~F_INVCL;
	}
	vsb_printf(ob[fd], "%5d %-12s %c %.*s\n",
	    fd, VSL_tags[tag],
	    ((spec & VSL_S_CLIENT) ? 'c' : (spec & VSL_S_BACKEND) ? 'b' : '-'),
	    len, ptr);
	switch (tag) {
	case SLT_ReqEnd:<commit_msg>Try fixing #95 again.  The trick is that if we get a new SLT_VCL_call while the F_INVCL flag is set, we need to insert a newline before the entry for the new VCL_call.<commit_after>/*-
 * Copyright (c) 2006 Verdens Gang AS
 * Copyright (c) 2006 Linpro AS
 * All rights reserved.
 *
 * Author: <NAME> <<EMAIL>>
 *
 * 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 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$
 *
 * Log tailer for Varnish
 */

#include <errno.h>
#include <fcntl.h>
#include <regex.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "compat/vis.h"

#include "vsb.h"

#include "libvarnish.h"
#include "shmlog.h"
#include "varnishapi.h"

static int	bflag, cflag;

/* -------------------------------------------------------------------*/

static int
name2tag(const char *n)
{
	int i;

	for (i = 0; i < 256; i++) {
		if (VSL_tags[i] == NULL)
			continue;
		if (!strcasecmp(n, VSL_tags[i]))
			return (i);
	}
	return (-1);
}

/* Ordering-----------------------------------------------------------*/

static struct vsb	*ob[65536];
static unsigned char	flg[65536];
#define F_INVCL		(1 << 0)
#define F_MATCH		(1 << 1)

static int		match_tag = -1;
static regex_t		match_re;

static void
clean_order(void)
{
	unsigned u;

	for (u = 0; u < 65536; u++) {
		if (ob[u] == NULL)
			continue;
		vsb_finish(ob[u]);
		if (vsb_len(ob[u]) > 1 &&
		    (match_tag == -1 || flg[u] & F_MATCH))
			printf("%s\n", vsb_data(ob[u]));
		flg[u] = 0;
		vsb_clear(ob[u]);
	}
}

static int
h_order(void *priv, enum shmlogtag tag, unsigned fd, unsigned len, unsigned spec, const char *ptr)
{

	(void)priv;

	if (!(spec & (VSL_S_CLIENT|VSL_S_BACKEND))) {
		if (!bflag && !cflag)
			VSL_H_Print(stdout, tag, fd, len, spec, ptr);
		return (0);
	}
	if (ob[fd] == NULL) {
		ob[fd] = vsb_new(NULL, NULL, 0, VSB_AUTOEXTEND);
		assert(ob[fd] != NULL);
	}
	if (tag == match_tag &&
	    !regexec(&match_re, ptr, 0, NULL, 0))
		flg[fd] |= F_MATCH;
	switch (tag) {
	case SLT_VCL_call:
		if (flg[fd] & F_INVCL)
			vsb_cat(ob[fd], "\n");
		else
			flg[fd] |= F_INVCL;
		vsb_printf(ob[fd], "%5d %-12s %c %.*s",
		    fd, VSL_tags[tag],
		    ((spec & VSL_S_CLIENT) ? 'c' : \
		    (spec & VSL_S_BACKEND) ? 'b' : '-'),
		    len, ptr);
		return (0);
	case SLT_VCL_trace:
	case SLT_VCL_return:
		if (flg[fd] & F_INVCL) {
			vsb_cat(ob[fd], " ");
			vsb_bcat(ob[fd], ptr, len);
			return (0);
		}
		break;
	default:
		break;
	}
	if (flg[fd] & F_INVCL) {
		vsb_cat(ob[fd], "\n");
		flg[fd] &= ~F_INVCL;
	}
	vsb_printf(ob[fd], "%5d %-12s %c %.*s\n",
	    fd, VSL_tags[tag],
	    ((spec & VSL_S_CLIENT) ? 'c' : (spec & VSL_S_BACKEND) ? 'b' : '-'),
	    len, ptr);
	switch (tag) {
	case SLT_ReqEnd:
{'fraction_non_alphanumeric': 0.17124457878827704, 'fraction_numerical': 0.013930871336575109, 'mean_word_length': 3.1426238432226454, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1975674', 'n_tokens_mistral': 3072, 'n_tokens_neox': 2781, 'n_words': 889}