Simon Kelley schrieb:
> Dnsmasq 2.52 is now available for download from
> 
[snip]

For those interrested, my regex patch rediffed against 2.52.
Now new and improved, with the powerful conditional compilation formula!

So don't forget to set HAVE_REGEX to you COPTS like:
make COPTS=-DHAVE_REGEX
or unkomment it in config.h

> 
> Cheers,
> 
> Simon.
> 
Greetings
        Jan

[snip]

-- 
"...by all means, do not use a hammer."
(from an IBM dokumentation, ca. 1920)
=== modified file 'Makefile'
--- old/Makefile	2010-01-23 19:48:37 +0000
+++ new/Makefile	2010-01-23 19:49:07 +0000
@@ -32,8 +32,9 @@
 PO = po
 MAN = man
 
-DNSMASQ_CFLAGS=`echo $(COPTS) | ../bld/pkg-wrapper HAVE_DBUS $(PKG_CONFIG) --cflags dbus-1` 
-DNSMASQ_LIBS=  `echo $(COPTS) | ../bld/pkg-wrapper HAVE_DBUS $(PKG_CONFIG) --libs dbus-1` 
+DNSMASQ_CFLAGS=`echo $(COPTS) | ../bld/pkg-wrapper HAVE_DBUS  $(PKG_CONFIG) --cflags dbus-1` 
+DNSMASQ_LIBS=  `echo $(COPTS) | ../bld/pkg-wrapper HAVE_DBUS  $(PKG_CONFIG) --libs dbus-1` 
+DNSMASQ_LIBS +=`echo $(COPTS) | ../bld/pkg-wrapper HAVE_REGEX $(PKG_CONFIG) --libs libpcre`
 SUNOS_LIBS= `if uname | grep SunOS 2>&1 >/dev/null; then echo -lsocket -lnsl -lposix4; fi`
 
 OBJS = cache.o rfc1035.o util.o option.o forward.o network.o \

=== modified file 'src/config.h'
--- old/src/config.h	2010-01-23 19:48:37 +0000
+++ new/src/config.h	2010-01-23 19:49:07 +0000
@@ -147,6 +147,10 @@
    define some methods to allow (re)configuration of the upstream DNS 
    servers via DBus.
 
+HAVE_REGEX
+   Define this if you want to link against lib pcre to get regex
+   support in "address=" matches
+
 NOTES:
    For Linux you should define 
       HAVE_LINUX_NETWORK
@@ -171,6 +175,7 @@
 #define HAVE_SCRIPT
 /* #define HAVE_BROKEN_RTC */
 /* #define HAVE_DBUS */
+/* #define HAVE_REGEX */
 
 /* Allow TFTP to be disabled with COPTS=-DNO_TFTP */
 #ifdef NO_TFTP

=== modified file 'src/dnsmasq.c'
--- old/src/dnsmasq.c	2010-01-23 19:48:37 +0000
+++ new/src/dnsmasq.c	2010-01-23 19:49:08 +0000
@@ -37,6 +37,10 @@
 "no-"
 #endif
 "DBus "
+#ifndef HAVE_REGEX
+"no-"
+#endif
+"regex "
 #ifndef LOCALEDIR
 "no-"
 #endif

=== modified file 'src/dnsmasq.h'
--- old/src/dnsmasq.h	2010-01-23 19:48:37 +0000
+++ new/src/dnsmasq.h	2010-01-23 19:49:08 +0000
@@ -120,6 +120,10 @@
 #include <priv.h>
 #endif
 
+#ifdef HAVE_REGEX
+#  include <pcre.h>
+#endif
+
 /* daemon is function in the C library.... */
 #define daemon dnsmasq_daemon
 
@@ -319,6 +323,7 @@
 #define SERV_MARK            256  /* for mark-and-delete */
 #define SERV_TYPE    (SERV_HAS_DOMAIN | SERV_FOR_NODOTS)
 #define SERV_COUNTED         512  /* workspace for log code */
+#define SERV_IS_REGEX       1024  /* server entry is a regex */
 
 struct serverfd {
   int fd;
@@ -337,6 +342,10 @@
   char interface[IF_NAMESIZE+1];
   struct serverfd *sfd; 
   char *domain; /* set if this server only handles a domain. */ 
+#ifdef HAVE_REGEX
+  pcre *regex;
+  pcre_extra *pextra;
+#endif
   int flags, tcpfd;
   unsigned int queries, failed_queries;
   struct server *next; 

=== modified file 'src/forward.c'
--- old/src/forward.c	2010-01-23 19:48:37 +0000
+++ new/src/forward.c	2010-01-23 19:49:08 +0000
@@ -149,12 +149,38 @@
       }
     else if (serv->flags & SERV_HAS_DOMAIN)
       {
-	unsigned int domainlen = strlen(serv->domain);
-	char *matchstart = qdomain + namelen - domainlen;
-	if (namelen >= domainlen &&
-	    hostname_isequal(matchstart, serv->domain) &&
-	    domainlen >= matchlen &&
-	    (domainlen == 0 || namelen == domainlen || *(serv->domain) == '.' || *(matchstart-1) == '.' ))
+	unsigned int domainlen = matchlen;
+	int serverhit = 0;
+
+#ifdef HAVE_REGEX
+	if (serv->flags & SERV_IS_REGEX)
+	  {
+	    int captcount = 0;
+	    if (pcre_fullinfo(serv->regex, serv->pextra, PCRE_INFO_CAPTURECOUNT, &captcount) == 0)
+	      {
+		/* C99 dyn-array, or alloca must be used */
+		int ovect[(captcount + 1) * 3];
+		if (pcre_exec(serv->regex, serv->pextra, qdomain, namelen, 0, 0, ovect, (captcount + 1) * 3) > 0)
+		  {
+		    domainlen = (unsigned int) (ovect[1] - ovect[0]);
+		    if (domainlen >= matchlen)
+		      serverhit = 1;
+		  }
+	      }
+	  }
+	else
+#endif
+	  {
+	    domainlen = strlen(serv->domain);
+	    char *matchstart = qdomain + namelen - domainlen;
+	    if (namelen >= domainlen &&
+	        hostname_isequal(matchstart, serv->domain) &&
+	        domainlen >= matchlen &&
+	        (domainlen == 0 || namelen == domainlen || *(serv->domain) == '.' || *(matchstart-1) == '.' ))
+	       serverhit = 1;
+	  }
+
+	if (serverhit)
 	  {
 	    unsigned short sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6;
 	    *type = SERV_HAS_DOMAIN;

=== modified file 'src/network.c'
--- old/src/network.c	2010-01-23 19:48:37 +0000
+++ new/src/network.c	2010-01-23 19:49:08 +0000
@@ -741,7 +741,7 @@
 	  char *s1, *s2;
 	  if (!(new->flags & SERV_HAS_DOMAIN))
 	    s1 = _("unqualified"), s2 = _("names");
-	  else if (strlen(new->domain) == 0)
+	  else if (new->domain && strlen(new->domain) == 0)
 	    s1 = _("default"), s2 = "";
 	  else
 	    s1 = _("domain"), s2 = new->domain;

=== modified file 'src/option.c'
--- old/src/option.c	2010-01-23 19:48:37 +0000
+++ new/src/option.c	2010-01-23 19:49:08 +0000
@@ -1405,10 +1405,16 @@
 	    arg++;
 	    while ((end = split_chr(arg, '/')))
 	      {
-		char *domain = NULL;
+		char *domain = NULL, *regex = NULL;
+		char *real_end = arg + strlen(arg);
 		/* # matches everything and becomes a zero length domain string */
 		if (strcmp(arg, "#") == 0)
 		  domain = "";
+		else if (*arg == ':' && *(real_end - 1) == ':')
+		  {
+		     *(real_end - 1) = '\0';
+		     regex = arg + 1;
+		  }
 		else if (strlen (arg) != 0 && !(domain = canonicalise_opt(arg)))
 		  option = '?';
 		serv = opt_malloc(sizeof(struct server));
@@ -1416,7 +1422,28 @@
 		serv->next = newlist;
 		newlist = serv;
 		serv->domain = domain;
-		serv->flags = domain ? SERV_HAS_DOMAIN : SERV_FOR_NODOTS;
+		serv->flags = domain || regex ? SERV_HAS_DOMAIN : SERV_FOR_NODOTS;
+		if (regex)
+		  {
+#ifdef HAVE_REGEX
+		    const char *error;
+		    int erroff;
+		    serv->regex = pcre_compile(regex, 0, &error, &erroff, NULL);
+
+		    if (!serv->regex)
+		      {
+			 option = '?';
+			 problem = (char *) error;
+			 break;
+		      }
+		    serv->flags |= SERV_IS_REGEX;
+		    serv->pextra = pcre_study(serv->regex, 0, &error);
+#else
+		    option = '?';
+		    problem = "Using a regex while server was configured without regex support!";
+		    break;
+#endif
+		  }
 		arg = end;
 	      }
 	    if (!newlist)

Reply via email to