Пример #1
0
static void
vcc_expr_fmt(struct vsb *d, int ind, const struct expr *e1)
{
	char *p;
	int i;

	for (i = 0; i < ind; i++)
		VSB_cat(d, " ");
	p = VSB_data(e1->vsb);
	while (*p != '\0') {
		if (*p == '\n') {
			VSB_putc(d, '\n');
			if (p[1] != '\0') {
				for (i = 0; i < ind; i++)
					VSB_cat(d, " ");
			}
			p++;
			continue;
		}
		if (*p != '\v') {
			VSB_putc(d, *p);
			p++;
			continue;
		}
		p++;
		switch(*p) {
		case '+': ind += 2; break;
		case '-': ind -= 2; break;
		default:
			assert(__LINE__ == 0);
		}
		p++;
	}
}
Пример #2
0
struct vsb *
vtc_hex_to_bin(struct vtclog *vl, const char *arg)
{
	struct vsb *vsb;
	unsigned sh = 4;
	unsigned c, b = 0;

	vsb = VSB_new_auto();
	AN(vsb);
	for (; *arg != '\0'; arg++) {
		if (vct_issp(*arg) || *arg == '\n')
			continue;
		c = (uint8_t)*arg;
		if (c >= '0' && c <= '9')
			b |= (c - 48U) << sh;
		else if (c >= 'A' && c <= 'F')
			b |= (c - 55U) << sh;
		else if (c >= 'a' && c <= 'f')
			b |= (c - 87U) << sh;
		else
			vtc_fatal(vl,"Illegal hex string");
		sh = 4 - sh;
		if (sh == 4) {
			VSB_putc(vsb, b);
			b = 0;
		}
	}
	if (sh != 4)
		VSB_putc(vsb, b);
	AZ(VSB_finish(vsb));
	return (vsb);
}
Пример #3
0
static void
vxp_quote(const struct vxp *vxp, const char *b, const char *e, int tokoff)
{
	const char *p;
	char c;

	assert(b <= e);
	assert(b >= vxp->b);
	assert(e <= vxp->e);
	for (p = vxp->b; p < vxp->e; p++) {
		if (isspace(*p))
			VSB_putc(vxp->sb, ' ');
		else
			VSB_putc(vxp->sb, *p);
	}
	VSB_putc(vxp->sb, '\n');
	for (p = vxp->b; p < vxp->e; p++) {
		if (p >= b && p < e) {
			if (p - b == tokoff)
				c = '^';
			else
				c = '#';
		} else
			c = '-';
		VSB_putc(vxp->sb, c);
	}
	VSB_putc(vxp->sb, '\n');
}
Пример #4
0
static struct expr *
vcc_expr_edit(enum var_type fmt, const char *p, struct expr *e1,
    struct expr *e2)
{
	struct expr *e;
	int nl = 1;

	e = vcc_new_expr();
	while (*p != '\0') {
		if (*p == '\n') {
			if (!nl)
				VSB_putc(e->vsb, *p);
			nl = 1;
			p++;
			continue;
		}
		nl = 0;
		if (*p != '\v') {
			VSB_putc(e->vsb, *p);
			p++;
			continue;
		}
		assert(*p == '\v');
		p++;
		switch(*p) {
		case '+': VSB_cat(e->vsb, "\v+"); break;
		case '-': VSB_cat(e->vsb, "\v-"); break;
		case '1':
		case '2':
			if (*p == '1')
				VSB_cat(e->vsb, VSB_data(e1->vsb));
			else {
				AN(e2);
				VSB_cat(e->vsb, VSB_data(e2->vsb));
			}
			break;
		default:
			assert(__LINE__ == 0);
		}
		p++;
	}
	AZ(VSB_finish(e->vsb));
	if (e1 != NULL)
		e->t1 = e1->t1;
	else if (e2 != NULL)
		e->t1 = e2->t1;
	if (e2 != NULL)
		e->t2 = e2->t1;
	else if (e1 != NULL)
		e->t1 = e1->t1;
	if ((e1 == NULL || e1->constant) && (e2 == NULL || e2->constant))
		e->constant = 1;
	vcc_delete_expr(e1);
	vcc_delete_expr(e2);
	e->fmt = fmt;
	return (e);
}
Пример #5
0
void
vxp_ErrWhere(struct vxp *vxp, const struct token *t, int tokoff)
{

	AN(vxp);
	AN(t);
	vxp_Pos(vxp, vxp->sb, t, tokoff);
	VSB_putc(vxp->sb, '\n');
	vxp_quote(vxp, t->b, t->e, tokoff);
	VSB_putc(vxp->sb, '\n');
	vxp->err = 1;
}
Пример #6
0
static void
ban_parse_http(const struct ban_proto *bp, const char *a1)
{
	int l;

	l = strlen(a1) + 1;
	assert(l <= 127);
	VSB_putc(bp->vsb, (char)l);
	VSB_cat(bp->vsb, a1);
	VSB_putc(bp->vsb, ':');
	VSB_putc(bp->vsb, '\0');
}
Пример #7
0
const char *
BAN_AddTest(struct ban_proto *bp,
    const char *a1, const char *a2, const char *a3)
{
	const struct pvar *pv;
	const char *err;

	CHECK_OBJ_NOTNULL(bp, BAN_PROTO_MAGIC);
	AN(bp->vsb);
	AN(a1);
	AN(a2);
	AN(a3);

	if (bp->err != NULL)
		return (bp->err);

	for (pv = pvars; pv->name != NULL; pv++)
		if (!strncmp(a1, pv->name, strlen(pv->name)))
			break;

	if (pv->name == NULL)
		return (ban_error(bp,
		    "Unknown or unsupported field \"%s\"", a1));

	bp->flags |= pv->flag;

	VSB_putc(bp->vsb, pv->tag);
	if (pv->flag & BANS_FLAG_HTTP)
		ban_parse_http(bp, a1 + strlen(pv->name));

	ban_add_lump(bp, a3, strlen(a3) + 1);
	if (!strcmp(a2, "~")) {
		VSB_putc(bp->vsb, BANS_OPER_MATCH);
		err = ban_parse_regexp(bp, a3);
		if (err)
			return (err);
	} else if (!strcmp(a2, "!~")) {
		VSB_putc(bp->vsb, BANS_OPER_NMATCH);
		err = ban_parse_regexp(bp, a3);
		if (err)
			return (err);
	} else if (!strcmp(a2, "==")) {
		VSB_putc(bp->vsb, BANS_OPER_EQ);
	} else if (!strcmp(a2, "!=")) {
		VSB_putc(bp->vsb, BANS_OPER_NEQ);
	} else {
		return (ban_error(bp,
		    "expected conditional (~, !~, == or !=) got \"%s\"", a2));
	}
	return (NULL);
}
Пример #8
0
static void
mcf_askchild(struct cli *cli, const char * const *av, void *priv)
{
	int i;
	char *q;
	unsigned u;
	struct vsb *vsb;

	(void)priv;
	/*
	 * Command not recognized in master, try cacher if it is
	 * running.
	 */
	if (cli_o <= 0) {
		if (!strcmp(av[1], "help")) {
			if (av[2] == NULL || strcmp(av[2], "-j"))
				VCLI_Out(cli,
				   "No help from child, (not running).\n");
			return;
		}
		VCLI_SetResult(cli, CLIS_UNKNOWN);
		VCLI_Out(cli,
		    "Unknown request in manager process "
		    "(child not running).\n"
		    "Type 'help' for more info.");
		return;
	}
	vsb = VSB_new_auto();
	for (i = 1; av[i] != NULL; i++) {
		VSB_quote(vsb, av[i], strlen(av[i]), 0);
		VSB_putc(vsb, ' ');
	}
	VSB_putc(vsb, '\n');
	AZ(VSB_finish(vsb));
	i = write(cli_o, VSB_data(vsb), VSB_len(vsb));
	if (i != VSB_len(vsb)) {
		VSB_destroy(&vsb);
		VCLI_SetResult(cli, CLIS_COMMS);
		VCLI_Out(cli, "CLI communication error");
		MGT_Child_Cli_Fail();
		return;
	}
	VSB_destroy(&vsb);
	if (VCLI_ReadResult(cli_i, &u, &q, mgt_param.cli_timeout))
		MGT_Child_Cli_Fail();
	VCLI_SetResult(cli, u);
	VCLI_Out(cli, "%s", q);
	free(q);
}
Пример #9
0
//lint -e{818}
void
vtc_log(struct vtclog *vl, int lvl, const char *fmt, ...)
{
	double tx;

	CHECK_OBJ_NOTNULL(vl, VTCLOG_MAGIC);
	tx = VTIM_mono() - t0;
	AZ(pthread_mutex_lock(&vl->mtx));
	vl->act = 1;
	assert(lvl < (int)NLEAD);
	VSB_clear(vl->vsb);
	VSB_printf(vl->vsb, "%s %-4s %4.1f ",
	    lead[lvl < 0 ? 1: lvl], vl->id, tx);
	va_list ap;
	va_start(ap, fmt);
	(void)VSB_vprintf(vl->vsb, fmt, ap);
	va_end(ap);
	VSB_putc(vl->vsb, '\n');
	AZ(VSB_finish(vl->vsb));

	vtc_log_emit(vl, lvl);

	VSB_clear(vl->vsb);
	vl->act = 0;
	AZ(pthread_mutex_unlock(&vl->mtx));
	if (lvl > 0)
		return;
	if (lvl == 0)
		vtc_error = 1;
	if (pthread_self() != vtc_thread)
		pthread_exit(NULL);
}
Пример #10
0
void
vcc_Expr(struct vcc *tl, enum var_type fmt)
{
	struct expr *e;
	struct token *t1;

	assert(fmt != VOID);

	t1 = tl->t;
	vcc_expr0(tl, &e, fmt);
	ERRCHK(tl);
	if (fmt == STRING || fmt == STRING_LIST)
		vcc_expr_tostring(&e, fmt);
	if (!tl->err && fmt != e->fmt)  {
		VSB_printf(tl->sb, "Expression has type %s, expected %s\n",
		    vcc_Type(e->fmt), vcc_Type(fmt));
		tl->err = 1;
	}
	if (!tl->err) {
		if (e->fmt == STRING_LIST) {
			e = vcc_expr_edit(STRING_LIST,
			    "\v+\n\v1,\nvrt_magic_string_end\v-", e, NULL);
		}
		vcc_expr_fmt(tl->fb, tl->indent, e);
		VSB_putc(tl->fb, '\n');
	} else {
		if (t1 != tl->t)
			vcc_ErrWhere2(tl, t1, tl->t);
	}
	vcc_delete_expr(e);
}
Пример #11
0
static void
vbp_bitmap(struct vsb *vsb, char c, uint64_t map, const char *lbl)
{
	int i;
	uint64_t u = (1ULL << 63);

	VSB_printf(vsb, "  ");
	for (i = 0; i < 64; i++) {
		if (map & u)
			VSB_putc(vsb, c);
		else
			VSB_putc(vsb, '-');
		map <<= 1;
	}
	VSB_printf(vsb, " %s\n", lbl);
}
Пример #12
0
run_cc(void *priv)
{
	struct vcc_priv *vp;
	struct vsb *sb;
	int pct;
	char *p;

	VJ_subproc(JAIL_SUBPROC_CC);
	CAST_OBJ_NOTNULL(vp, priv, VCC_PRIV_MAGIC);

	AZ(chdir(vp->dir));

	sb = VSB_new_auto();
	AN(sb);
	for (p = mgt_cc_cmd, pct = 0; *p; ++p) {
		if (pct) {
			switch (*p) {
			case 's':
				VSB_cat(sb, VGC_SRC);
				break;
			case 'o':
				VSB_cat(sb, VGC_LIB);
				break;
			case '%':
				VSB_putc(sb, '%');
				break;
			default:
				VSB_putc(sb, '%');
				VSB_putc(sb, *p);
				break;
			}
			pct = 0;
		} else if (*p == '%') {
			pct = 1;
		} else {
			VSB_putc(sb, *p);
		}
	}
	if (pct)
		VSB_putc(sb, '%');
	AZ(VSB_finish(sb));

	(void)umask(027);
	(void)execl("/bin/sh", "/bin/sh", "-c", VSB_data(sb), (char*)0);
	VSB_destroy(&sb);				// For flexelint
}
Пример #13
0
void
vxp__Expect(struct vxp *vxp, unsigned tok)
{

	if (vxp->t->tok == tok)
		return;
	VSB_printf(vxp->sb, "Expected %s got ", vxp_tnames[tok]);
	vxp_ErrToken(vxp, vxp->t);
	VSB_putc(vxp->sb, ' ');
	vxp_ErrWhere(vxp, vxp->t, -1);
}
Пример #14
0
int
vtc_send_proxy(int fd, int version, const struct suckaddr *sac,
    const struct suckaddr *sas)
{
	struct vsb *vsb;
	char hc[VTCP_ADDRBUFSIZE];
	char pc[VTCP_PORTBUFSIZE];
	char hs[VTCP_ADDRBUFSIZE];
	char ps[VTCP_PORTBUFSIZE];
	int i, len;
	int proto;

	AN(sac);
	AN(sas);

	assert(version == 1 || version == 2);
	vsb = VSB_new_auto();
	AN(vsb);

	proto = VSA_Get_Proto(sas);
	assert(proto == PF_INET6 || proto == PF_INET);

	if (version == 1) {
		VSB_bcat(vsb, vpx1_sig, sizeof(vpx1_sig));
		if (proto == PF_INET6)
			VSB_printf(vsb, " TCP6 ");
		else if (proto == PF_INET)
			VSB_printf(vsb, " TCP4 ");
		VTCP_name(sac, hc, sizeof(hc), pc, sizeof(pc));
		VTCP_name(sas, hs, sizeof(hs), ps, sizeof(ps));
		VSB_printf(vsb, "%s %s %s %s\r\n", hc, hs, pc, ps);
	} else if (version == 2) {
		VSB_bcat(vsb, vpx2_sig, sizeof(vpx2_sig));
		VSB_putc(vsb, 0x21);
		if (proto == PF_INET6) {
			VSB_putc(vsb, 0x21);
			VSB_putc(vsb, 0x00);
			VSB_putc(vsb, 0x24);
		} else if (proto == PF_INET) {
			VSB_putc(vsb, 0x11);
			VSB_putc(vsb, 0x00);
			VSB_putc(vsb, 0x0c);
		}
		vpx_enc_addr(vsb, proto, sac);
		vpx_enc_addr(vsb, proto, sas);
		vpx_enc_port(vsb, sac);
		vpx_enc_port(vsb, sas);
	} else
		WRONG("Wrong proxy version");

	AZ(VSB_finish(vsb));
	len = VSB_len(vsb);
	i = write(fd, VSB_data(vsb), len);
	VSB_delete(vsb);
	return (i != len);
}
Пример #15
0
static void
ban_add_lump(const struct ban_proto *bp, const void *p, uint32_t len)
{
	uint8_t buf[sizeof len];

	buf[0] = 0xff;
	while (VSB_len(bp->vsb) & PALGN)
		VSB_putc(bp->vsb, buf[0]);
	vbe32enc(buf, len);
	VSB_bcat(bp->vsb, buf, sizeof buf);
	VSB_bcat(bp->vsb, p, len);
}
Пример #16
0
void
vtc_fatal(struct vtclog *vl, const char *fmt, ...)
{

	GET_VL(vl);
	va_list ap;
	va_start(ap, fmt);
	vtc_leadinv(vl, 0, fmt, ap);
	VSB_putc(vl->vsb, '\n');
	va_end(ap);
	REL_VL(vl);

	vtc_logfail();
}
Пример #17
0
/*
 * Quote a string
 */
void
VSB_quote(struct vsb *s, const char *p, int len, int how)
{
	const char *q;
	int quote = 0;

	(void)how;	/* For future enhancements */
	if (len == -1)
		len = strlen(p);

	for (q = p; q < p + len; q++) {
		if (!isgraph(*q) || *q == '"' || *q == '\\') {
			quote++;
			break;
		}
	}
	if (!quote) {
		(void)VSB_bcat(s, p, len);
		return;
	}
	(void)VSB_putc(s, '"');
	for (q = p; q < p + len; q++) {
		switch (*q) {
		case ' ':
			(void)VSB_putc(s, *q);
			break;
		case '\\':
		case '"':
			(void)VSB_putc(s, '\\');
			(void)VSB_putc(s, *q);
			break;
		case '\n':
			if (how & VSB_QUOTE_NONL)
				(void)VSB_cat(s, "\n");
			else
				(void)VSB_cat(s, "\\n");
			break;
		case '\r':
			(void)VSB_cat(s, "\\r");
			break;
		case '\t':
			(void)VSB_cat(s, "\\t");
			break;
		default:
			if (isgraph(*q))
				(void)VSB_putc(s, *q);
			else
				(void)VSB_printf(s, "\\%o", *q & 0xff);
			break;
		}
	}
	(void)VSB_putc(s, '"');
}
Пример #18
0
static void
cmd_err_shell(CMD_ARGS)
{
	(void)priv;
	(void)cmd;
	struct vsb *vsb;
	FILE *fp;
	int r, c;

	if (av == NULL)
		return;
	AN(av[1]);
	AN(av[2]);
	AZ(av[3]);
	vsb = VSB_new_auto();
	AN(vsb);
	vtc_dump(vl, 4, "cmd", av[2], -1);
	fp = popen(av[2], "r");
	if (fp == NULL)
		vtc_log(vl, 0, "popen fails: %s", strerror(errno));
	do {
		c = getc(fp);
		if (c != EOF)
			VSB_putc(vsb, c);
	} while (c != EOF);
	r = pclose(fp);
	vtc_log(vl, 4, "Status = %d", WEXITSTATUS(r));
	if (WIFSIGNALED(r))
		vtc_log(vl, 4, "Signal = %d", WTERMSIG(r));
	if (WEXITSTATUS(r) == 0) {
		vtc_log(vl, 0,
		    "expected error from shell");
	}
	AZ(VSB_finish(vsb));
	vtc_dump(vl, 4, "stdout", VSB_data(vsb), VSB_len(vsb));
	if (strstr(VSB_data(vsb), av[1]) == NULL)
		vtc_log(vl, 0,
		    "Did not find expected string: (\"%s\")", av[1]);
	else
		vtc_log(vl, 4,
		    "Found expected string: (\"%s\")", av[1]);
	VSB_delete(vsb);
}
Пример #19
0
void
vtc_log(struct vtclog *vl, int lvl, const char *fmt, ...)
{

	GET_VL(vl);
	va_list ap;
	va_start(ap, fmt);
	if (lvl >= 0) {
		vtc_leadinv(vl, lvl, fmt, ap);
		VSB_putc(vl->vsb, '\n');
	}
	va_end(ap);
	REL_VL(vl);

	if (lvl > 0)
		return;
	if (lvl == 0)
		vtc_logfail();
}
Пример #20
0
static struct expr *
vcc_expr_edit(enum var_type fmt, const char *p, struct expr *e1,
    struct expr *e2)
{
	struct expr *e;
	int nl = 1;

	AN(e1);
	e = vcc_new_expr();
	while (*p != '\0') {
		if (*p != '\v') {
			if (*p != '\n' || !nl)
				VSB_putc(e->vsb, *p);
			nl = (*p == '\n');
			p++;
			continue;
		}
		assert(*p == '\v');
		switch(*++p) {
		case '+': VSB_cat(e->vsb, "\v+"); break;
		case '-': VSB_cat(e->vsb, "\v-"); break;
		case '1':
			VSB_cat(e->vsb, VSB_data(e1->vsb));
			break;
		case '2':
			AN(e2);
			VSB_cat(e->vsb, VSB_data(e2->vsb));
			break;
		default:
			WRONG("Illegal edit in VCC expression");
		}
		p++;
	}
	AZ(VSB_finish(e->vsb));
	e->t1 = e1->t1;
	e->t2 = e1->t2;
	if (e2 != NULL)
		e->t2 = e2->t2;
	vcc_delete_expr(e1);
	vcc_delete_expr(e2);
	e->fmt = fmt;
	return (e);
}
Пример #21
0
void
VEP_Parse(struct vep_state *vep, const char *p, size_t l)
{
	const char *e;
	struct vep_match *vm;
	int i;

	CHECK_OBJ_NOTNULL(vep, VEP_MAGIC);
	assert(l > 0);

	if (vep->startup) {
		/*
		 * We must force the GZIP header out as a SKIP string,
		 * otherwise an object starting with <esi:include would
		 * have its GZIP header appear after the included object
		 * (e000026.vtc)
		 */
		vep->ver_p = "";
		vep->last_mark = SKIP;
		vep_mark_common(vep, vep->ver_p, VERBATIM);
		vep->startup = 0;
		AZ(vep->hack_p);
		vep->hack_p = p;
	}

	vep->ver_p = p;

	e = p + l;

	while (p < e) {
		AN(vep->state);
		i = e - p;
		if (i > 10)
			i = 10;
		Debug("EP %s %d (%.*s) [%.*s]\n",
		    vep->state,
		    vep->remove,
		    vep->tag_i, vep->tag,
		    i, p);
		assert(p >= vep->ver_p);

		/******************************************************
		 * SECTION A
		 */

		if (vep->state == VEP_START) {
			if (FEATURE(FEATURE_ESI_REMOVE_BOM) && *p == '\xeb') {
				vep->match = vep_match_bom;
				vep->state = VEP_MATCH;
			} else
				vep->state = VEP_BOM;
		} else if (vep->state == VEP_BOM) {
			vep_mark_skip(vep, p);
			if (FEATURE(FEATURE_ESI_DISABLE_XML_CHECK))
				vep->state = VEP_NEXTTAG;
			else
				vep->state = VEP_TESTXML;
		} else if (vep->state == VEP_TESTXML) {
			/*
			 * If the first non-whitespace char is different
			 * from '<' we assume this is not XML.
			 */
			while (p < e && vct_islws(*p))
				p++;
			vep_mark_verbatim(vep, p);
			if (p < e && *p == '<') {
				p++;
				vep->state = VEP_STARTTAG;
			} else if (p < e && *p == '\xeb') {
				VSLb(vep->vc->wrk->vsl, SLT_ESI_xmlerror,
				    "No ESI processing, "
				    "first char not '<' but BOM."
				    " (See feature esi_remove_bom)"
				);
				vep->state = VEP_NOTXML;
			} else if (p < e) {
				VSLb(vep->vc->wrk->vsl, SLT_ESI_xmlerror,
				    "No ESI processing, "
				    "first char not '<'."
				    " (See feature esi_disable_xml_check)"
				);
				vep->state = VEP_NOTXML;
			}
		} else if (vep->state == VEP_NOTXML) {
			/*
			 * This is not recognized as XML, just skip thru
			 * vfp_esi_end() will handle the rest
			 */
			p = e;
			vep_mark_verbatim(vep, p);

		/******************************************************
		 * SECTION B
		 */

		} else if (vep->state == VEP_NOTMYTAG) {
			if (FEATURE(FEATURE_ESI_IGNORE_OTHER_ELEMENTS)) {
				p++;
				vep->state = VEP_NEXTTAG;
			} else {
				vep->tag_i = 0;
				while (p < e) {
					if (*p++ == '>') {
						vep->state = VEP_NEXTTAG;
						break;
					}
				}
			}
			if (p == e && !vep->remove)
				vep_mark_verbatim(vep, p);
		} else if (vep->state == VEP_NEXTTAG) {
			/*
			 * Hunt for start of next tag and keep an eye
			 * out for end of EsiCmt if armed.
			 */
			vep->emptytag = 0;
			vep->attr = NULL;
			vep->dostuff = NULL;
			while (p < e && *p != '<') {
				if (vep->esicmt_p == NULL) {
					p++;
					continue;
				}
				if (*p != *vep->esicmt_p) {
					p++;
					vep->esicmt_p = vep->esicmt;
					continue;
				}
				if (!vep->remove && vep->esicmt_p == vep->esicmt)
					vep_mark_verbatim(vep, p);
				p++;
				if (*++vep->esicmt_p == '\0') {
					vep->esi_found = 1;
					vep->esicmt = NULL;
					vep->esicmt_p = NULL;
					/*
					 * The end of the esicmt
					 * should not be emitted.
					 * But the stuff before should
					 */
					vep_mark_skip(vep, p);
				}
			}
			if (p < e) {
				if (!vep->remove)
					vep_mark_verbatim(vep, p);
				assert(*p == '<');
				p++;
				vep->state = VEP_STARTTAG;
			} else if (vep->esicmt_p == vep->esicmt && !vep->remove)
				vep_mark_verbatim(vep, p);

		/******************************************************
		 * SECTION C
		 */

		} else if (vep->state == VEP_STARTTAG) {
			/* Start of tag, set up match table */
			vep->endtag = 0;
			vep->match = vep_match_starttag;
			vep->state = VEP_MATCH;
		} else if (vep->state == VEP_COMMENT) {
			vep->esicmt_p = vep->esicmt = NULL;
			vep->until_p = vep->until = "-->";
			vep->until_s = VEP_NEXTTAG;
			vep->state = VEP_UNTIL;
		} else if (vep->state == VEP_COMMENTESI) {
			if (vep->remove)
				vep_error(vep,
				    "ESI 1.0 Nested <!--esi"
				    " element in <esi:remove>");
			vep->esicmt_p = vep->esicmt = "-->";
			vep->state = VEP_NEXTTAG;
			vep_mark_skip(vep, p);
		} else if (vep->state == VEP_CDATA) {
			/*
			 * Easy: just look for the end of CDATA
			 */
			vep->until_p = vep->until = "]]>";
			vep->until_s = VEP_NEXTTAG;
			vep->state = VEP_UNTIL;
		} else if (vep->state == VEP_ESIENDTAG) {
			vep->endtag = 1;
			vep->state = VEP_ESITAG;
		} else if (vep->state == VEP_ESITAG) {
			vep->in_esi_tag = 1;
			vep->esi_found = 1;
			vep_mark_skip(vep, p);
			vep->match = vep_match_esi;
			vep->state = VEP_MATCH;
		} else if (vep->state == VEP_ESIINCLUDE) {
			if (vep->remove) {
				vep_error(vep,
				    "ESI 1.0 <esi:include> element"
				    " nested in <esi:remove>");
				vep->state = VEP_TAGERROR;
			} else if (vep->endtag) {
				vep_error(vep,
				    "ESI 1.0 </esi:include> illegal end-tag");
				vep->state = VEP_TAGERROR;
			} else {
				vep->dostuff = vep_do_include;
				vep->state = VEP_INTAG;
				vep->attr = vep_match_attr_include;
			}
		} else if (vep->state == VEP_ESIREMOVE) {
			vep->dostuff = vep_do_remove;
			vep->state = VEP_INTAG;
		} else if (vep->state == VEP_ESICOMMENT) {
			if (vep->remove) {
				vep_error(vep,
				    "ESI 1.0 <esi:comment> element"
				    " nested in <esi:remove>");
				vep->state = VEP_TAGERROR;
			} else if (vep->endtag) {
				vep_error(vep,
				    "ESI 1.0 </esi:comment> illegal end-tag");
				vep->state = VEP_TAGERROR;
			} else {
				vep->dostuff = vep_do_comment;
				vep->state = VEP_INTAG;
			}
		} else if (vep->state == VEP_ESIBOGON) {
			vep_error(vep,
			    "ESI 1.0 <esi:bogus> element");
			vep->state = VEP_TAGERROR;

		/******************************************************
		 * SECTION D
		 */

		} else if (vep->state == VEP_INTAG) {
			vep->tag_i = 0;
			while (p < e && vct_islws(*p) && !vep->emptytag) {
				p++;
				vep->canattr = 1;
			}
			if (p < e && *p == '/' && !vep->emptytag) {
				p++;
				vep->emptytag = 1;
				vep->canattr = 0;
			}
			if (p < e && *p == '>') {
				p++;
				AN(vep->dostuff);
				vep_mark_skip(vep, p);
				vep->dostuff(vep, DO_TAG);
				vep->in_esi_tag = 0;
				vep->state = VEP_NEXTTAG;
			} else if (p < e && vep->emptytag) {
				vep_error(vep,
				    "XML 1.0 '>' does not follow '/' in tag");
				vep->state = VEP_TAGERROR;
			} else if (p < e && vep->canattr &&
			    vct_isxmlnamestart(*p)) {
				vep->state = VEP_ATTR;
			} else if (p < e) {
				vep_error(vep,
				    "XML 1.0 Illegal attribute start char");
				vep->state = VEP_TAGERROR;
			}
		} else if (vep->state == VEP_TAGERROR) {
			while (p < e && *p != '>')
				p++;
			if (p < e) {
				p++;
				vep_mark_skip(vep, p);
				vep->in_esi_tag = 0;
				vep->state = VEP_NEXTTAG;
			}

		/******************************************************
		 * SECTION E
		 */

		} else if (vep->state == VEP_ATTR) {
			AZ(vep->attr_delim);
			if (vep->attr == NULL) {
				p++;
				AZ(vep->attr_vsb);
				vep->state = VEP_SKIPATTR;
			} else {
				vep->match = vep->attr;
				vep->state = VEP_MATCH;
			}
		} else if (vep->state == VEP_SKIPATTR) {
			while (p < e && vct_isxmlname(*p))
				p++;
			if (p < e && *p == '=') {
				p++;
				vep->state = VEP_ATTRDELIM;
			} else if (p < e && *p == '>') {
				vep->state = VEP_INTAG;
			} else if (p < e && *p == '/') {
				vep->state = VEP_INTAG;
			} else if (p < e && vct_issp(*p)) {
				vep->state = VEP_INTAG;
			} else if (p < e) {
				vep_error(vep,
				    "XML 1.0 Illegal attr char");
				vep->state = VEP_TAGERROR;
			}
		} else if (vep->state == VEP_ATTRGETVAL) {
			vep->attr_vsb = VSB_new_auto();
			vep->state = VEP_ATTRDELIM;
		} else if (vep->state == VEP_ATTRDELIM) {
			AZ(vep->attr_delim);
			if (*p == '"' || *p == '\'') {
				vep->attr_delim = *p++;
				vep->state = VEP_ATTRVAL;
			} else if (!vct_issp(*p)) {
				vep->attr_delim = ' ';
				vep->state = VEP_ATTRVAL;
			} else {
				vep_error(vep,
				    "XML 1.0 Illegal attribute delimiter");
				vep->state = VEP_TAGERROR;
			}

		} else if (vep->state == VEP_ATTRVAL) {
			while (p < e && *p != '>' && *p != vep->attr_delim &&
			   (vep->attr_delim != ' ' || !vct_issp(*p))) {
				if (vep->attr_vsb != NULL)
					VSB_putc(vep->attr_vsb, *p);
				p++;
			}
			if (p < e && *p == '>') {
				vep_error(vep,
				    "XML 1.0 Missing end attribute delimiter");
				vep->state = VEP_TAGERROR;
				vep->attr_delim = 0;
				if (vep->attr_vsb != NULL) {
					AZ(VSB_finish(vep->attr_vsb));
					VSB_destroy(&vep->attr_vsb);
				}
			} else if (p < e) {
				vep->attr_delim = 0;
				p++;
				vep->state = VEP_INTAG;
				if (vep->attr_vsb != NULL) {
					AZ(VSB_finish(vep->attr_vsb));
					AN(vep->dostuff);
					vep->dostuff(vep, DO_ATTR);
					vep->attr_vsb = NULL;
				}
			}

		/******************************************************
		 * Utility Section
		 */

		} else if (vep->state == VEP_MATCH) {
			/*
			 * Match against a table
			 */
			vm = vep_match(vep, p, e);
			vep->match_hit = vm;
			if (vm != NULL) {
				if (vm->match != NULL)
					p += strlen(vm->match);
				vep->state = *vm->state;
				vep->match = NULL;
				vep->tag_i = 0;
			} else {
				assert(e - p <= sizeof(vep->tag));
				memcpy(vep->tag, p, e - p);
				vep->tag_i = e - p;
				vep->state = VEP_MATCHBUF;
				p = e;
			}
		} else if (vep->state == VEP_MATCHBUF) {
			/*
			 * Match against a table while split over input
			 * sections.
			 */
			AN(vep->match);
			i = sizeof(vep->tag) - vep->tag_i;
			if (i > e - p)
				i = e - p;
			memcpy(vep->tag + vep->tag_i, p, i);
			vm = vep_match(vep, vep->tag,
			    vep->tag + vep->tag_i + i);
			if (vm == NULL) {
				vep->tag_i += i;
				p += i;
				assert(p == e);
			} else {
				vep->match_hit = vm;
				vep->state = *vm->state;
				if (vm->match != NULL)
					p += strlen(vm->match) - vep->tag_i;
				vep->match = NULL;
				vep->tag_i = 0;
			}
		} else if (vep->state == VEP_UNTIL) {
			/*
			 * Skip until we see magic string
			 */
			while (p < e) {
				if (*p++ != *vep->until_p++) {
					vep->until_p = vep->until;
				} else if (*vep->until_p == '\0') {
					vep->state = vep->until_s;
					break;
				}
			}
			if (p == e && !vep->remove)
				vep_mark_verbatim(vep, p);
		} else {
			Debug("*** Unknown state %s\n", vep->state);
			WRONG("WRONG ESI PARSER STATE");
		}
	}
	/*
	 * We must always mark up the storage we got, try to do so
	 * in the most efficient way, in particular with respect to
	 * minimizing and limiting use of pending.
	 */
	if (p == vep->ver_p)
		;
	else if (vep->in_esi_tag)
		vep_mark_skip(vep, p);
	else if (vep->remove)
		vep_mark_skip(vep, p);
	else
		vep_mark_pending(vep, p);
}
Пример #22
0
/*
 * Quote a string
 */
void
VSB_quote_pfx(struct vsb *s, const char *pfx, const void *v, int len, int how)
{
	const char *p;
	const char *q;
	int quote = 0;
	int nl = 0;
	const unsigned char *u, *w;

	assert(v != NULL);
	if (len == -1)
		len = strlen(v);

	if (len == 0 && (how & VSB_QUOTE_CSTR)) {
		VSB_printf(s, "%s\"\"", pfx);
		return;
	} else if (len == 0)
		return;

	VSB_cat(s, pfx);

	if (how & VSB_QUOTE_HEX) {
		u = v;
		for (w = u; w < u + len; w++)
			if (*w != 0x00)
				break;
		VSB_printf(s, "0x");
		if (w == u + len && len > 4) {
			VSB_printf(s, "0...0");
		} else {
			for (w = u; w < u + len; w++)
				VSB_printf(s, "%02x", *w);
		}
		return;
	}
	p = v;

	for (q = p; q < p + len; q++) {
		if (!isgraph(*q) || *q == '"' || *q == '\\') {
			quote++;
			break;
		}
	}
	if (!quote && !(how & (VSB_QUOTE_JSON|VSB_QUOTE_CSTR))) {
		(void)VSB_bcat(s, p, len);
		if ((how & (VSB_QUOTE_UNSAFE|VSB_QUOTE_NONL)) &&
		    p[len-1] != '\n')
			(void)VSB_putc(s, '\n');
		return;
	}

	if (how & VSB_QUOTE_CSTR)
		(void)VSB_putc(s, '"');

	for (q = p; q < p + len; q++) {
		if (nl)
			VSB_cat(s, pfx);
		nl = 0;
		switch (*q) {
		case '?':
			if (how & VSB_QUOTE_CSTR)
				(void)VSB_putc(s, '\\');
			(void)VSB_putc(s, *q);
			break;
		case ' ':
			(void)VSB_putc(s, *q);
			break;
		case '\\':
		case '"':
			if (!(how & VSB_QUOTE_UNSAFE))
				(void)VSB_putc(s, '\\');
			(void)VSB_putc(s, *q);
			break;
		case '\n':
			if (how & VSB_QUOTE_CSTR) {
				(void)VSB_printf(s, "\\n\"\n%s\t\"", pfx);
			} else if (how & (VSB_QUOTE_NONL|VSB_QUOTE_UNSAFE)) {
				(void)VSB_printf(s, "\n");
				nl = 1;
			} else {
				(void)VSB_printf(s, "\\n");
			}
			break;
		case '\r':
			(void)VSB_cat(s, "\\r");
			break;
		case '\t':
			(void)VSB_cat(s, "\\t");
			break;
		case '\v':
			(void)VSB_cat(s, "\\v");
			break;
		default:
			/* XXX: Implement VSB_QUOTE_JSON */
			if (isgraph(*q))
				(void)VSB_putc(s, *q);
			else if (how & VSB_QUOTE_ESCHEX)
				(void)VSB_printf(s, "\\x%02x", *q & 0xff);
			else
				(void)VSB_printf(s, "\\%03o", *q & 0xff);
			break;
		}
	}
	if (how & VSB_QUOTE_CSTR)
		(void)VSB_putc(s, '"');
	if ((how & (VSB_QUOTE_NONL|VSB_QUOTE_UNSAFE)) && !nl)
		(void)VSB_putc(s, '\n');
}
Пример #23
0
pan_ic(const char *func, const char *file, int line, const char *cond,
    enum vas_e kind)
{
	const char *q;
	struct req *req;
	struct busyobj *bo;
	struct sigaction sa;
	int err = errno;

	AZ(pthread_mutex_lock(&panicstr_mtx)); /* Won't be released,
						  we're going to die
						  anyway */

	/*
	 * should we trigger a SIGSEGV while handling a panic, our sigsegv
	 * handler would hide the panic, so we need to reset the handler to
	 * default
	 */
	memset(&sa, 0, sizeof sa);
	sa.sa_handler = SIG_DFL;
	(void)sigaction(SIGSEGV, &sa, NULL);
	/* Set SIGABRT back to default so the final abort() has the
	   desired effect */
	(void)sigaction(SIGABRT, &sa, NULL);

	switch(kind) {
	case VAS_WRONG:
		VSB_printf(pan_vsb,
		    "Wrong turn at %s:%d:\n%s\n", file, line, cond);
		break;
	case VAS_VCL:
		VSB_printf(pan_vsb,
		    "Panic from VCL:\n  %s\n", cond);
		break;
	case VAS_MISSING:
		VSB_printf(pan_vsb,
		    "Missing errorhandling code in %s(), %s line %d:\n"
		    "  Condition(%s) not true.",
		    func, file, line, cond);
		break;
	case VAS_INCOMPLETE:
		VSB_printf(pan_vsb,
		    "Incomplete code in %s(), %s line %d:\n",
		    func, file, line);
		break;
	default:
	case VAS_ASSERT:
		VSB_printf(pan_vsb,
		    "Assert error in %s(), %s line %d:\n"
		    "  Condition(%s) not true.\n",
		    func, file, line, cond);
		break;
	}
	if (err)
		VSB_printf(pan_vsb, "errno = %d (%s)\n", err, strerror(err));

	q = THR_GetName();
	if (q != NULL)
		VSB_printf(pan_vsb, "thread = (%s)\n", q);

	VSB_printf(pan_vsb, "version = %s\n", VCS_version);
	VSB_printf(pan_vsb, "ident = %s,%s\n",
	    VSB_data(vident) + 1, Waiter_GetName());

	pan_backtrace(pan_vsb);

	if (!FEATURE(FEATURE_SHORT_PANIC)) {
		req = THR_GetRequest();
		if (req != NULL) {
			pan_req(pan_vsb, req);
			VSL_Flush(req->vsl, 0);
		}
		bo = THR_GetBusyobj();
		if (bo != NULL) {
			pan_busyobj(pan_vsb, bo);
			VSL_Flush(bo->vsl, 0);
		}
	}
	VSB_printf(pan_vsb, "\n");
	VSB_putc(pan_vsb, '\0');	/* NUL termination */

	if (FEATURE(FEATURE_NO_COREDUMP))
		exit(4);
	else
		abort();
}