varnish-cache/lib/libvcc/vcc_var.c
1
/*-
2
 * Copyright (c) 2006 Verdens Gang AS
3
 * Copyright (c) 2006-2011 Varnish Software AS
4
 * All rights reserved.
5
 *
6
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 */
29
30
#include "config.h"
31
32
#include <stdlib.h>
33
#include <string.h>
34
35
#include "vcc_compile.h"
36
37
/*--------------------------------------------------------------------*/
38
39
void v_matchproto_(sym_wildcard_t)
40 9718
vcc_Var_Wildcard(struct vcc *tl, struct symbol *parent,
41
    const char *b, const char *e)
42
{
43
        struct symbol *sym;
44
        struct var *v;
45
        const struct var *vh;
46
        struct vsb *vsb;
47
        unsigned len;
48
49 9718
        vh = parent->wildcard_priv;
50 9718
        assert(vh->fmt == HEADER);
51
52 9718
        if (b + 127 <= e) {
53 1
                VSB_printf(tl->sb, "HTTP header (%.20s..) is too long.\n", b);
54 1
                VSB_cat(tl->sb, "\nAt: ");
55 1
                vcc_ErrWhere(tl, tl->t);
56 9719
                return;
57
        }
58
59 9717
        v = TlAlloc(tl, sizeof *v);
60 9717
        AN(v);
61 9717
        v->r_methods = vh->r_methods;
62 9717
        v->w_methods = vh->w_methods;
63 9717
        v->fmt = vh->fmt;
64
65
        /* Create a C-name version of the header name */
66 9717
        vsb = VSB_new_auto();
67 9717
        AN(vsb);
68 9717
        VSB_printf(vsb, "&VGC_%s_", vh->rname);
69 9717
        VCC_PrintCName(vsb, b, e);
70 9717
        AZ(VSB_finish(vsb));
71
72
        /* Create the static identifier */
73 9717
        len = (unsigned)(e - b);
74 9717
        Fh(tl, 0, "static const struct gethdr_s %s =\n", VSB_data(vsb) + 1);
75 9717
        Fh(tl, 0, "    { %s, \"\\%03o%.*s:\"};\n",
76
            vh->rname, len + 1, len, b);
77
78
        /* Create the symbol r/l values */
79 9717
        v->rname = TlDup(tl, VSB_data(vsb));
80 9717
        VSB_clear(vsb);
81 9717
        VSB_printf(vsb, "VRT_SetHdr(ctx, %s,", v->rname);
82 9717
        AZ(VSB_finish(vsb));
83 9717
        v->lname = TlDup(tl, VSB_data(vsb));
84 9717
        VSB_destroy(&vsb);
85
86 9717
        sym = VCC_Symbol(tl, parent, b, e, SYM_VAR, 1);
87 9717
        AN(sym);
88 9717
        sym->fmt = v->fmt;
89 9717
        sym->eval = vcc_Eval_Var;
90 9717
        sym->r_methods = v->r_methods;
91 9717
        sym->w_methods = v->w_methods;
92 9717
        sym->lname = v->lname;
93 9717
        REPLACE(sym->rname, v->rname);
94
}
95
96
/*--------------------------------------------------------------------*/
97
98
const struct symbol *
99 8604
vcc_FindVar(struct vcc *tl, const struct token *t, int wr_access,
100
    const char *use)
101
{
102
        const struct symbol *sym;
103
104 8604
        sym = VCC_SymbolTok(tl, NULL, t, SYM_VAR, 0);
105 8604
        if (tl->err)
106 1
                return (NULL);
107 8603
        if (sym != NULL) {
108 8602
                if (wr_access && sym->w_methods == 0) {
109 5
                        VSB_printf(tl->sb, "Variable ");
110 5
                        vcc_ErrToken(tl, t);
111 5
                        VSB_printf(tl->sb, " is read only.");
112 5
                        VSB_cat(tl->sb, "\nAt: ");
113 5
                        vcc_ErrWhere(tl, t);
114 5
                        return (NULL);
115 8597
                } else if (wr_access) {
116 8597
                        vcc_AddUses(tl, t, sym->w_methods, use);
117 0
                } else if (sym->r_methods == 0) {
118 0
                        VSB_printf(tl->sb, "Variable ");
119 0
                        vcc_ErrToken(tl, t);
120 0
                        VSB_printf(tl->sb, " is write only.");
121 0
                        VSB_cat(tl->sb, "\nAt: ");
122 0
                        vcc_ErrWhere(tl, t);
123 0
                        return (NULL);
124
                } else {
125 0
                        vcc_AddUses(tl, t, sym->r_methods, use);
126
                }
127 8597
                return (sym);
128
        }
129 1
        VSB_printf(tl->sb, "Unknown variable ");
130 1
        vcc_ErrToken(tl, t);
131 1
        VSB_cat(tl->sb, "\nAt: ");
132 1
        vcc_ErrWhere(tl, t);
133 1
        return (NULL);
134
}