aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac18
-rw-r--r--src/variable.c139
-rw-r--r--tests/batchset.at6
3 files changed, 101 insertions, 62 deletions
diff --git a/configure.ac b/configure.ac
index 2fa32f6..f21fcfb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -105,30 +105,12 @@ AC_ARG_WITH([vmoddir],
105 105
106 106
107if test -z "$VMODDIR"; then 107if test -z "$VMODDIR"; then
108 VMODDIR='$(libdir)/varnish/mods' 108 VMODDIR='$(libdir)/varnish/mods'
109fi 109fi
110 110
111###########
112# Check for db.h and libdb
113#
114AC_CHECK_HEADER([db.h],,[AC_MSG_ERROR([Required header file db.h not found])])
115
116AC_CHECK_LIB(db, db_create,
117 [LIBS="$LIBS -ldb"
118 AC_RUN_IFELSE(
119 [AC_LANG_PROGRAM([#include "db.h"],
120 [int v_major, v_minor, v_patch;
121 db_version(&v_major, &v_minor, &v_patch);
122 return !(v_major == DB_VERSION_MAJOR
123 && v_minor == DB_VERSION_MINOR
124 && v_patch == DB_VERSION_PATCH);
125 ])],
126 [],
127 [AC_MSG_ERROR([header file db.h is not the same version as libdb])])])
128
129AC_CONFIG_COMMANDS([status],[ 111AC_CONFIG_COMMANDS([status],[
130delim="-------------------------------------------------------------------" 112delim="-------------------------------------------------------------------"
131echo "" 113echo ""
132echo $delim 114echo $delim
133echo "Building for Varnish version $VARNISHVERSION" 115echo "Building for Varnish version $VARNISHVERSION"
134echo $delim 116echo $delim
diff --git a/src/variable.c b/src/variable.c
index 6403c1a..9442b6b 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -497,13 +497,14 @@ log_error(const char *fmt, ...)
497 497
498#define S(s) ((s) ? (s) : "NULL") 498#define S(s) ((s) ? (s) : "NULL")
499 499
500struct vardef { 500struct vardef {
501 struct vardef *next; 501 struct vardef *next;
502 enum variable_type type; 502 enum variable_type type;
503 char name[1]; 503 char *name;
504 char *repl;
504}; 505};
505 506
506static void 507static void
507vardef_free(struct vardef *v) 508vardef_free(struct vardef *v)
508{ 509{
509 while (v) { 510 while (v) {
@@ -567,12 +568,57 @@ str2duration(const char *str)
567 } 568 }
568 while (*p && isspace(*p)) 569 while (*p && isspace(*p))
569 p++; 570 p++;
570 return *p ? 0 : r; 571 return *p ? 0 : r;
571} 572}
572 573
574char *
575bref_expand(const char *str, const char *input, pcre *re,
576 int ovsize, int *ovector)
577{
578 size_t rlen = 0;
579 char *rbase = NULL;
580 char *rptr;
581 int nm = 2*ovsize/3;
582 const char *p;
583
584 for (p = str; *p; ) {
585 if (*p == '\\' && strchr("123456789", p[1])) {
586 int n = 2*(p[1] - '0');
587 if (n < nm) {
588 rlen += ovector[n+1] - ovector[n];
589 p += 2;
590 continue;
591 }
592 }
593 ++p;
594 ++rlen;
595 }
596 rbase = malloc(rlen + 1);
597 AN(rbase);
598 p = str;
599 rptr = rbase;
600 while (*p) {
601 if (*p == '\\' && strchr("123456789", p[1])) {
602 int n = 2*(p[1] - '0');
603 if (n < nm) {
604 memcpy(rptr, input + ovector[n],
605 ovector[n+1] - ovector[n]);
606 rptr += ovector[n+1] - ovector[n];
607 p += 2;
608 continue;
609 }
610 }
611
612 *rptr++ = *p++;
613 }
614 *rptr = 0;
615
616 return rbase;
617}
618
573VCL_VOID 619VCL_VOID
574vmod_batchset(VARIABLE_CTX ctx, 620vmod_batchset(VARIABLE_CTX ctx,
575 VCL_STRING vars, VCL_STRING rxs, VCL_STRING input) 621 VCL_STRING vars, VCL_STRING rxs, VCL_STRING input)
576{ 622{
577 struct symtab *vt = get_symtab(ctx); 623 struct symtab *vt = get_symtab(ctx);
578 struct vardef *head = NULL, *tail = NULL, *def; 624 struct vardef *head = NULL, *tail = NULL, *def;
@@ -595,56 +641,69 @@ vmod_batchset(VARIABLE_CTX ctx,
595 log_error("variable.batchset: bad arguments: vars=%s, rxs=%s, input=%s", 641 log_error("variable.batchset: bad arguments: vars=%s, rxs=%s, input=%s",
596 S(vars), S(rxs), S(input)); 642 S(vars), S(rxs), S(input));
597 return; 643 return;
598 } 644 }
599 645
600 while (*v) { 646 while (*v) {
601 size_t n = strcspn(v, "="); 647 char const *nameptr = v;
648 size_t n = strcspn(v, ":=,");
649 size_t namelen;
650 char const *replptr;
651 size_t repllen;
652 char rbuf[3];
653 enum variable_type type;
654 int delim;
655
656 namelen = n;
602 657
603 if (!v[n]) { 658 v += n;
604 log_error("variable.batchset: vars argument invalid near %s", 659 delim = *v ? *v++ : 0;
605 v); 660
606 vardef_free(head); 661 if (delim == ':') {
607 return; 662 n = strcspn(v, "=,");
663 type = str2type(v, n);
664 v += n;
665 delim = *v ? *v++ : 0;
666 } else
667 type = variable_string;
668
669 if (delim == '=') {
670 n = strcspn(v, ",");
671 replptr = v;
672 repllen = n;
673 v += n;
674 delim = *v ? *v++ : 0;
675 } else {
676 rbuf[0] = '\\';
677 rbuf[1] = count + '1';
678 rbuf[2] = 0;
679 replptr = rbuf;
680 repllen = 2;
608 } 681 }
609 def = malloc(sizeof(def[0]) + n); 682
683 def = malloc(sizeof(def[0]) + namelen + repllen + 2);
610 def->next = NULL; 684 def->next = NULL;
611 memcpy(def->name, v, n);
612 def->name[n] = 0;
613 if (tail) 685 if (tail)
614 tail->next = def; 686 tail->next = def;
615 else 687 else
616 head = def; 688 head = def;
617 tail = def; 689 tail = def;
618 ++count; 690 ++count;
619 691 def->type = type;
620 v += n + 1; 692 def->name = (char*)(def + 1);
621 if (!*v) { 693 memcpy(def->name, nameptr, namelen);
622 log_error("variable.batchset: no type for %s", def->name); 694 def->name[namelen] = 0;
623 vardef_free(head); 695 def->repl = def->name + namelen + 1;
624 return; 696 memcpy(def->repl, replptr, repllen);
625 } 697 def->repl[repllen] = 0;
626
627 n = strcspn(v, ",");
628 def->type = str2type(v, n);
629 if (def->type == variable_unset) {
630 log_error("variable.batchset: invalid type for %s",
631 def->name);
632 vardef_free(head);
633 return;
634 }
635
636 v += n;
637 if (*v)
638 ++v;
639 } 698 }
640 699
641 re = pcre_compile(rxs, cflags, &error_ptr, &error_offset, NULL); 700 re = pcre_compile(rxs, cflags, &error_ptr, &error_offset, NULL);
642 if (!re) { 701 if (!re) {
643 log_error("variable.batchset: %s: compilation failed near %s: %s", 702 log_error("variable.batchset: %s: compilation failed near %s: %s",
644 rxs, rxs + error_offset, error_ptr); 703 rxs, rxs + error_offset, error_ptr);
645 vardef_free(head); 704 vardef_free(head);
646 return; 705 return;
647 } 706 }
648 707
649 rc = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &n); 708 rc = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &n);
650 if (rc) { 709 if (rc) {
@@ -670,22 +729,14 @@ vmod_batchset(VARIABLE_CTX ctx,
670 else 729 else