Merge "Run clang-format with netd's .clang-format file."
am: 2295ec5d3a

Change-Id: I25bcc68c089cd26b457f288129f35ac374219e89
diff --git a/src/.clang-format b/src/.clang-format
new file mode 100644
index 0000000..39ee5dd
--- /dev/null
+++ b/src/.clang-format
@@ -0,0 +1,15 @@
+# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
+#
+BasedOnStyle: Google
+AccessModifierOffset: -2
+AllowShortFunctionsOnASingleLine: Inline
+BreakBeforeTernaryOperators: true
+ColumnLimit: 100
+CommentPragmas: NOLINT:.*
+DerivePointerAlignment: false
+IndentWidth: 4
+PointerAlignment: Left
+SpaceAfterCStyleCast: true
+TabWidth: 4
+UseTab: Never
+PenaltyExcessCharacter: 32
diff --git a/src/cache.c b/src/cache.c
index 6c0f225..91bfa2d 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -4,12 +4,12 @@
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; version 2 dated June, 1991, or
    (at your option) version 3 dated 29 June, 2007.
- 
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-     
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
@@ -18,319 +18,254 @@
 
 static struct crec *cache_head = NULL, *cache_tail = NULL, **hash_table = NULL;
 #ifdef HAVE_DHCP
-static struct crec *dhcp_spare = NULL;
+static struct crec* dhcp_spare = NULL;
 #endif
-static struct crec *new_chain = NULL;
+static struct crec* new_chain = NULL;
 static int cache_inserted = 0, cache_live_freed = 0, insert_error;
-static union bigname *big_free = NULL;
+static union bigname* big_free = NULL;
 static int bignames_left, hash_size;
 static int uid = 0;
-static char *addrbuff = NULL;
+static char* addrbuff = NULL;
 
 /* type->string mapping: this is also used by the name-hash function as a mixing table. */
 static const struct {
-  unsigned int type;
-  const char * const name;
-} typestr[] = {
-  { 1,   "A" },
-  { 2,   "NS" },
-  { 5,   "CNAME" },
-  { 6,   "SOA" },
-  { 10,  "NULL" },
-  { 11,  "WKS" },
-  { 12,  "PTR" },
-  { 13,  "HINFO" },	
-  { 15,  "MX" },
-  { 16,  "TXT" },
-  { 22,  "NSAP" },
-  { 23,  "NSAP_PTR" },
-  { 24,  "SIG" },
-  { 25,  "KEY" },
-  { 28,  "AAAA" },
-  { 33,  "SRV" },
-  { 35,  "NAPTR" },
-  { 36,  "KX" },
-  { 37,  "CERT" },
-  { 38,  "A6" },
-  { 39,  "DNAME" },
-  { 41,  "OPT" },
-  { 48,  "DNSKEY" },
-  { 249, "TKEY" },
-  { 250, "TSIG" },
-  { 251, "IXFR" },
-  { 252, "AXFR" },
-  { 253, "MAILB" },
-  { 254, "MAILA" },
-  { 255, "ANY" }
-};
+    unsigned int type;
+    const char* const name;
+} typestr[] = {{1, "A"},      {2, "NS"},        {5, "CNAME"},   {6, "SOA"},     {10, "NULL"},
+               {11, "WKS"},   {12, "PTR"},      {13, "HINFO"},  {15, "MX"},     {16, "TXT"},
+               {22, "NSAP"},  {23, "NSAP_PTR"}, {24, "SIG"},    {25, "KEY"},    {28, "AAAA"},
+               {33, "SRV"},   {35, "NAPTR"},    {36, "KX"},     {37, "CERT"},   {38, "A6"},
+               {39, "DNAME"}, {41, "OPT"},      {48, "DNSKEY"}, {249, "TKEY"},  {250, "TSIG"},
+               {251, "IXFR"}, {252, "AXFR"},    {253, "MAILB"}, {254, "MAILA"}, {255, "ANY"}};
 
-static void cache_free(struct crec *crecp);
-static void cache_unlink(struct crec *crecp);
-static void cache_link(struct crec *crecp);
+static void cache_free(struct crec* crecp);
+static void cache_unlink(struct crec* crecp);
+static void cache_link(struct crec* crecp);
 static void rehash(int size);
-static void cache_hash(struct crec *crecp);
+static void cache_hash(struct crec* crecp);
 
-void cache_init(void)
-{
-  struct crec *crecp;
-  int i;
+void cache_init(void) {
+    struct crec* crecp;
+    int i;
 
-  if (daemon->options & OPT_LOG)
-    addrbuff = safe_malloc(ADDRSTRLEN);
-  
-  bignames_left = daemon->cachesize/10;
-  
-  if (daemon->cachesize > 0)
-    {
-      crecp = safe_malloc(daemon->cachesize*sizeof(struct crec));
-      
-      for (i=0; i < daemon->cachesize; i++, crecp++)
-	{
-	  cache_link(crecp);
-	  crecp->flags = 0;
-	  crecp->uid = uid++;
-	}
+    if (daemon->options & OPT_LOG) addrbuff = safe_malloc(ADDRSTRLEN);
+
+    bignames_left = daemon->cachesize / 10;
+
+    if (daemon->cachesize > 0) {
+        crecp = safe_malloc(daemon->cachesize * sizeof(struct crec));
+
+        for (i = 0; i < daemon->cachesize; i++, crecp++) {
+            cache_link(crecp);
+            crecp->flags = 0;
+            crecp->uid = uid++;
+        }
     }
-  
-  /* create initial hash table*/
-  rehash(daemon->cachesize);
+
+    /* create initial hash table*/
+    rehash(daemon->cachesize);
 }
 
 /* In most cases, we create the hash table once here by calling this with (hash_table == NULL)
    but if the hosts file(s) are big (some people have 50000 ad-block entries), the table
    will be much too small, so the hosts reading code calls rehash every 1000 addresses, to
    expand the table. */
-static void rehash(int size)
-{
-  struct crec **new, **old, *p, *tmp;
-  int i, new_size, old_size;
+static void rehash(int size) {
+    struct crec** new, **old, *p, *tmp;
+    int i, new_size, old_size;
 
-  /* hash_size is a power of two. */
-  for (new_size = 64; new_size < size/10; new_size = new_size << 1);
-  
-  /* must succeed in getting first instance, failure later is non-fatal */
-  if (!hash_table)
-    new = safe_malloc(new_size * sizeof(struct crec *));
-  else if (new_size <= hash_size || !(new = whine_malloc(new_size * sizeof(struct crec *))))
-    return;
+    /* hash_size is a power of two. */
+    for (new_size = 64; new_size < size / 10; new_size = new_size << 1)
+        ;
 
-  for(i = 0; i < new_size; i++)
-    new[i] = NULL;
+    /* must succeed in getting first instance, failure later is non-fatal */
+    if (!hash_table)
+        new = safe_malloc(new_size * sizeof(struct crec*));
+    else if (new_size <= hash_size || !(new = whine_malloc(new_size * sizeof(struct crec*))))
+        return;
 
-  old = hash_table;
-  old_size = hash_size;
-  hash_table = new;
-  hash_size = new_size;
-  
-  if (old)
-    {
-      for (i = 0; i < old_size; i++)
-	for (p = old[i]; p ; p = tmp)
-	  {
-	    tmp = p->hash_next;
-	    cache_hash(p);
-	  }
-      free(old);
+    for (i = 0; i < new_size; i++) new[i] = NULL;
+
+    old = hash_table;
+    old_size = hash_size;
+    hash_table = new;
+    hash_size = new_size;
+
+    if (old) {
+        for (i = 0; i < old_size; i++)
+            for (p = old[i]; p; p = tmp) {
+                tmp = p->hash_next;
+                cache_hash(p);
+            }
+        free(old);
     }
 }
-  
-static struct crec **hash_bucket(char *name)
-{
-  unsigned int c, val = 017465; /* Barker code - minimum self-correlation in cyclic shift */
-  const unsigned char *mix_tab = (const unsigned char*)typestr; 
 
-  while((c = (unsigned char) *name++))
-    {
-      /* don't use tolower and friends here - they may be messed up by LOCALE */
-      if (c >= 'A' && c <= 'Z')
-	c += 'a' - 'A';
-      val = ((val << 7) | (val >> (32 - 7))) + (mix_tab[(val + c) & 0x3F] ^ c);
-    } 
-  
-  /* hash_size is a power of two */
-  return hash_table + ((val ^ (val >> 16)) & (hash_size - 1));
+static struct crec** hash_bucket(char* name) {
+    unsigned int c, val = 017465; /* Barker code - minimum self-correlation in cyclic shift */
+    const unsigned char* mix_tab = (const unsigned char*) typestr;
+
+    while ((c = (unsigned char) *name++)) {
+        /* don't use tolower and friends here - they may be messed up by LOCALE */
+        if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
+        val = ((val << 7) | (val >> (32 - 7))) + (mix_tab[(val + c) & 0x3F] ^ c);
+    }
+
+    /* hash_size is a power of two */
+    return hash_table + ((val ^ (val >> 16)) & (hash_size - 1));
 }
 
-static void cache_hash(struct crec *crecp)
-{
-  /* maintain an invariant that all entries with F_REVERSE set
-     are at the start of the hash-chain  and all non-reverse
-     immortal entries are at the end of the hash-chain.
-     This allows reverse searches and garbage collection to be optimised */
+static void cache_hash(struct crec* crecp) {
+    /* maintain an invariant that all entries with F_REVERSE set
+       are at the start of the hash-chain  and all non-reverse
+       immortal entries are at the end of the hash-chain.
+       This allows reverse searches and garbage collection to be optimised */
 
-  struct crec **up = hash_bucket(cache_get_name(crecp));
+    struct crec** up = hash_bucket(cache_get_name(crecp));
 
-  if (!(crecp->flags & F_REVERSE))
-    {
-      while (*up && ((*up)->flags & F_REVERSE))
-	up = &((*up)->hash_next); 
-      
-      if (crecp->flags & F_IMMORTAL)
-	while (*up && !((*up)->flags & F_IMMORTAL))
-	  up = &((*up)->hash_next);
+    if (!(crecp->flags & F_REVERSE)) {
+        while (*up && ((*up)->flags & F_REVERSE)) up = &((*up)->hash_next);
+
+        if (crecp->flags & F_IMMORTAL)
+            while (*up && !((*up)->flags & F_IMMORTAL)) up = &((*up)->hash_next);
     }
-  crecp->hash_next = *up;
-  *up = crecp;
+    crecp->hash_next = *up;
+    *up = crecp;
 }
- 
-static void cache_free(struct crec *crecp)
-{
-  crecp->flags &= ~F_FORWARD;
-  crecp->flags &= ~F_REVERSE;
-  crecp->uid = uid++; /* invalidate CNAMES pointing to this. */
-  
-  if (cache_tail)
-    cache_tail->next = crecp;
-  else
-    cache_head = crecp;
-  crecp->prev = cache_tail;
-  crecp->next = NULL;
-  cache_tail = crecp;
-  
-  /* retrieve big name for further use. */
-  if (crecp->flags & F_BIGNAME)
-    {
-      crecp->name.bname->next = big_free;
-      big_free = crecp->name.bname;
-      crecp->flags &= ~F_BIGNAME;
+
+static void cache_free(struct crec* crecp) {
+    crecp->flags &= ~F_FORWARD;
+    crecp->flags &= ~F_REVERSE;
+    crecp->uid = uid++; /* invalidate CNAMES pointing to this. */
+
+    if (cache_tail)
+        cache_tail->next = crecp;
+    else
+        cache_head = crecp;
+    crecp->prev = cache_tail;
+    crecp->next = NULL;
+    cache_tail = crecp;
+
+    /* retrieve big name for further use. */
+    if (crecp->flags & F_BIGNAME) {
+        crecp->name.bname->next = big_free;
+        big_free = crecp->name.bname;
+        crecp->flags &= ~F_BIGNAME;
     }
-}    
+}
 
 /* insert a new cache entry at the head of the list (youngest entry) */
-static void cache_link(struct crec *crecp)
-{
-  if (cache_head) /* check needed for init code */
-    cache_head->prev = crecp;
-  crecp->next = cache_head;
-  crecp->prev = NULL;
-  cache_head = crecp;
-  if (!cache_tail)
-    cache_tail = crecp;
+static void cache_link(struct crec* crecp) {
+    if (cache_head) /* check needed for init code */
+        cache_head->prev = crecp;
+    crecp->next = cache_head;
+    crecp->prev = NULL;
+    cache_head = crecp;
+    if (!cache_tail) cache_tail = crecp;
 }
 
-/* remove an arbitrary cache entry for promotion */ 
-static void cache_unlink (struct crec *crecp)
-{
-  if (crecp->prev)
-    crecp->prev->next = crecp->next;
-  else
-    cache_head = crecp->next;
+/* remove an arbitrary cache entry for promotion */
+static void cache_unlink(struct crec* crecp) {
+    if (crecp->prev)
+        crecp->prev->next = crecp->next;
+    else
+        cache_head = crecp->next;
 
-  if (crecp->next)
-    crecp->next->prev = crecp->prev;
-  else
-    cache_tail = crecp->prev;
+    if (crecp->next)
+        crecp->next->prev = crecp->prev;
+    else
+        cache_tail = crecp->prev;
 }
 
-char *cache_get_name(struct crec *crecp)
-{
-  if (crecp->flags & F_BIGNAME)
-    return crecp->name.bname->name;
-  else if (crecp->flags & (F_DHCP | F_CONFIG)) 
-    return crecp->name.namep;
-  
-  return crecp->name.sname;
+char* cache_get_name(struct crec* crecp) {
+    if (crecp->flags & F_BIGNAME)
+        return crecp->name.bname->name;
+    else if (crecp->flags & (F_DHCP | F_CONFIG))
+        return crecp->name.namep;
+
+    return crecp->name.sname;
 }
 
-static int is_outdated_cname_pointer(struct crec *crecp)
-{
-  if (!(crecp->flags & F_CNAME))
-    return 0;
-  
-  if (crecp->addr.cname.cache && crecp->addr.cname.uid == crecp->addr.cname.cache->uid)
-    return 0;
-  
-  return 1;
+static int is_outdated_cname_pointer(struct crec* crecp) {
+    if (!(crecp->flags & F_CNAME)) return 0;
+
+    if (crecp->addr.cname.cache && crecp->addr.cname.uid == crecp->addr.cname.cache->uid) return 0;
+
+    return 1;
 }
 
-static int is_expired(time_t now, struct crec *crecp)
-{
-  if (crecp->flags & F_IMMORTAL)
-    return 0;
+static int is_expired(time_t now, struct crec* crecp) {
+    if (crecp->flags & F_IMMORTAL) return 0;
 
-  if (difftime(now, crecp->ttd) < 0)
-    return 0;
-  
-  return 1;
+    if (difftime(now, crecp->ttd) < 0) return 0;
+
+    return 1;
 }
 
-static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsigned short flags)
-{
-  /* Scan and remove old entries.
-     If (flags & F_FORWARD) then remove any forward entries for name and any expired
-     entries but only in the same hash bucket as name.
-     If (flags & F_REVERSE) then remove any reverse entries for addr and any expired
-     entries in the whole cache.
-     If (flags == 0) remove any expired entries in the whole cache. 
+static int cache_scan_free(char* name, struct all_addr* addr, time_t now, unsigned short flags) {
+    /* Scan and remove old entries.
+       If (flags & F_FORWARD) then remove any forward entries for name and any expired
+       entries but only in the same hash bucket as name.
+       If (flags & F_REVERSE) then remove any reverse entries for addr and any expired
+       entries in the whole cache.
+       If (flags == 0) remove any expired entries in the whole cache.
 
-     In the flags & F_FORWARD case, the return code is valid, and returns zero if the
-     name exists in the cache as a HOSTS or DHCP entry (these are never deleted)
+       In the flags & F_FORWARD case, the return code is valid, and returns zero if the
+       name exists in the cache as a HOSTS or DHCP entry (these are never deleted)
 
-     We take advantage of the fact that hash chains have stuff in the order <reverse>,<other>,<immortal>
-     so that when we hit an entry which isn't reverse and is immortal, we're done. */
- 
-  struct crec *crecp, **up;
-  
-  if (flags & F_FORWARD)
-    {
-      for (up = hash_bucket(name), crecp = *up; crecp; crecp = crecp->hash_next)
-	if (is_expired(now, crecp) || is_outdated_cname_pointer(crecp))
-	  { 
-	    *up = crecp->hash_next;
-	    if (!(crecp->flags & (F_HOSTS | F_DHCP)))
-	      {
-		cache_unlink(crecp);
-		cache_free(crecp);
-	      }
-	  } 
-	else if ((crecp->flags & F_FORWARD) && 
-		 ((flags & crecp->flags & (F_IPV4 | F_IPV6)) || ((crecp->flags | flags) & F_CNAME)) &&
-		 hostname_isequal(cache_get_name(crecp), name))
-	  {
-	    if (crecp->flags & (F_HOSTS | F_DHCP))
-	      return 0;
-	    *up = crecp->hash_next;
-	    cache_unlink(crecp);
-	    cache_free(crecp);
-	  }
-	else
-	  up = &crecp->hash_next;
-    }
-  else
-    {
-      int i;
+       We take advantage of the fact that hash chains have stuff in the order
+       <reverse>,<other>,<immortal> so that when we hit an entry which isn't reverse and is
+       immortal, we're done. */
+
+    struct crec *crecp, **up;
+
+    if (flags & F_FORWARD) {
+        for (up = hash_bucket(name), crecp = *up; crecp; crecp = crecp->hash_next)
+            if (is_expired(now, crecp) || is_outdated_cname_pointer(crecp)) {
+                *up = crecp->hash_next;
+                if (!(crecp->flags & (F_HOSTS | F_DHCP))) {
+                    cache_unlink(crecp);
+                    cache_free(crecp);
+                }
+            } else if ((crecp->flags & F_FORWARD) &&
+                       ((flags & crecp->flags & (F_IPV4 | F_IPV6)) ||
+                        ((crecp->flags | flags) & F_CNAME)) &&
+                       hostname_isequal(cache_get_name(crecp), name)) {
+                if (crecp->flags & (F_HOSTS | F_DHCP)) return 0;
+                *up = crecp->hash_next;
+                cache_unlink(crecp);
+                cache_free(crecp);
+            } else
+                up = &crecp->hash_next;
+    } else {
+        int i;
 #ifdef HAVE_IPV6
-      int addrlen = (flags & F_IPV6) ? IN6ADDRSZ : INADDRSZ;
+        int addrlen = (flags & F_IPV6) ? IN6ADDRSZ : INADDRSZ;
 #else
-      int addrlen = INADDRSZ;
-#endif 
-      for (i = 0; i < hash_size; i++)
-	for (crecp = hash_table[i], up = &hash_table[i]; 
-	     crecp && ((crecp->flags & F_REVERSE) || !(crecp->flags & F_IMMORTAL));
-	     crecp = crecp->hash_next)
-	  if (is_expired(now, crecp))
-	    {
-	      *up = crecp->hash_next;
-	      if (!(crecp->flags & (F_HOSTS | F_DHCP)))
-		{ 
-		  cache_unlink(crecp);
-		  cache_free(crecp);
-		}
-	    }
-	  else if (!(crecp->flags & (F_HOSTS | F_DHCP)) &&
-		   (flags & crecp->flags & F_REVERSE) && 
-		   (flags & crecp->flags & (F_IPV4 | F_IPV6)) &&
-		   memcmp(&crecp->addr.addr, addr, addrlen) == 0)
-	    {
-	      *up = crecp->hash_next;
-	      cache_unlink(crecp);
-	      cache_free(crecp);
-	    }
-	  else
-	    up = &crecp->hash_next;
+        int addrlen = INADDRSZ;
+#endif
+        for (i = 0; i < hash_size; i++)
+            for (crecp = hash_table[i], up = &hash_table[i];
+                 crecp && ((crecp->flags & F_REVERSE) || !(crecp->flags & F_IMMORTAL));
+                 crecp = crecp->hash_next)
+                if (is_expired(now, crecp)) {
+                    *up = crecp->hash_next;
+                    if (!(crecp->flags & (F_HOSTS | F_DHCP))) {
+                        cache_unlink(crecp);
+                        cache_free(crecp);
+                    }
+                } else if (!(crecp->flags & (F_HOSTS | F_DHCP)) &&
+                           (flags & crecp->flags & F_REVERSE) &&
+                           (flags & crecp->flags & (F_IPV4 | F_IPV6)) &&
+                           memcmp(&crecp->addr.addr, addr, addrlen) == 0) {
+                    *up = crecp->hash_next;
+                    cache_unlink(crecp);
+                    cache_free(crecp);
+                } else
+                    up = &crecp->hash_next;
     }
-  
-  return 1;
+
+    return 1;
 }
 
 /* Note: The normal calling sequence is
@@ -338,981 +273,822 @@
    cache_insert * n
    cache_end_insert
 
-   but an abort can cause the cache_end_insert to be missed 
+   but an abort can cause the cache_end_insert to be missed
    in which can the next cache_start_insert cleans things up. */
 
-void cache_start_insert(void)
-{
-  /* Free any entries which didn't get committed during the last
-     insert due to error.
-  */
-  while (new_chain)
-    {
-      struct crec *tmp = new_chain->next;
-      cache_free(new_chain);
-      new_chain = tmp;
+void cache_start_insert(void) {
+    /* Free any entries which didn't get committed during the last
+       insert due to error.
+    */
+    while (new_chain) {
+        struct crec* tmp = new_chain->next;
+        cache_free(new_chain);
+        new_chain = tmp;
     }
-  new_chain = NULL;
-  insert_error = 0;
+    new_chain = NULL;
+    insert_error = 0;
 }
- 
-struct crec *cache_insert(char *name, struct all_addr *addr, 
-			  time_t now,  unsigned long ttl, unsigned short flags)
-{
-  struct crec *new;
-  union bigname *big_name = NULL;
-  int freed_all = flags & F_REVERSE;
-  int free_avail = 0;
 
-  log_query(flags | F_UPSTREAM, name, addr, NULL);
+struct crec* cache_insert(char* name, struct all_addr* addr, time_t now, unsigned long ttl,
+                          unsigned short flags) {
+    struct crec* new;
+    union bigname* big_name = NULL;
+    int freed_all = flags & F_REVERSE;
+    int free_avail = 0;
 
-  /* CONFIG bit means something else when stored in cache entries */
-  flags &= ~F_CONFIG;
+    log_query(flags | F_UPSTREAM, name, addr, NULL);
 
-  /* if previous insertion failed give up now. */
-  if (insert_error)
-    return NULL;
+    /* CONFIG bit means something else when stored in cache entries */
+    flags &= ~F_CONFIG;
 
-  /* First remove any expired entries and entries for the name/address we
-     are currently inserting. Fail is we attempt to delete a name from
-     /etc/hosts or DHCP. */
-  if (!cache_scan_free(name, addr, now, flags))
-    {
-      insert_error = 1;
-      return NULL;
-    }
-  
-  /* Now get a cache entry from the end of the LRU list */
-  while (1) {
-    if (!(new = cache_tail)) /* no entries left - cache is too small, bail */
-      {
-	insert_error = 1;
-	return NULL;
-      }
-    
-    /* End of LRU list is still in use: if we didn't scan all the hash
-       chains for expired entries do that now. If we already tried that
-       then it's time to start spilling things. */
-    
-    if (new->flags & (F_FORWARD | F_REVERSE))
-      { 
-	/* If free_avail set, we believe that an entry has been freed.
-	   Bugs have been known to make this not true, resulting in
-	   a tight loop here. If that happens, abandon the
-	   insert. Once in this state, all inserts will probably fail. */
-	if (free_avail)
-	  {
-	    insert_error = 1;
-	    return NULL;
-	  }
-		
-	if (freed_all)
-	  {
-	    free_avail = 1; /* Must be free space now. */
-	    cache_scan_free(cache_get_name(new), &new->addr.addr, now, new->flags);
-	    cache_live_freed++;
-	  }
-	else
-	  {
-	    cache_scan_free(NULL, NULL, now, 0);
-	    freed_all = 1;
-	  }
-	continue;
-      }
- 
-    /* Check if we need to and can allocate extra memory for a long name.
-       If that fails, give up now. */
-    if (name && (strlen(name) > SMALLDNAME-1))
-      {
-	if (big_free)
-	  { 
-	    big_name = big_free;
-	    big_free = big_free->next;
-	  }
-	else if (!bignames_left ||
-		 !(big_name = (union bigname *)whine_malloc(sizeof(union bigname))))
-	  {
-	    insert_error = 1;
-	    return NULL;
-	  }
-	else
-	  bignames_left--;
-	
-      }
+    /* if previous insertion failed give up now. */
+    if (insert_error) return NULL;
 
-    /* Got the rest: finally grab entry. */
-    cache_unlink(new);
-    break;
-  }
-  
-  new->flags = flags;
-  if (big_name)
-    {
-      new->name.bname = big_name;
-      new->flags |= F_BIGNAME;
+    /* First remove any expired entries and entries for the name/address we
+       are currently inserting. Fail is we attempt to delete a name from
+       /etc/hosts or DHCP. */
+    if (!cache_scan_free(name, addr, now, flags)) {
+        insert_error = 1;
+        return NULL;
     }
 
-  if (name)
-    strcpy(cache_get_name(new), name);
-  else
-    *cache_get_name(new) = 0;
+    /* Now get a cache entry from the end of the LRU list */
+    while (1) {
+        if (!(new = cache_tail)) /* no entries left - cache is too small, bail */
+        {
+            insert_error = 1;
+            return NULL;
+        }
 
-  if (addr)
-    new->addr.addr = *addr;
-  else
-    new->addr.cname.cache = NULL;
-  
-  new->ttd = now + (time_t)ttl;
-  new->next = new_chain;
-  new_chain = new;
+        /* End of LRU list is still in use: if we didn't scan all the hash
+           chains for expired entries do that now. If we already tried that
+           then it's time to start spilling things. */
 
-  return new;
+        if (new->flags&(F_FORWARD | F_REVERSE)) {
+            /* If free_avail set, we believe that an entry has been freed.
+               Bugs have been known to make this not true, resulting in
+               a tight loop here. If that happens, abandon the
+               insert. Once in this state, all inserts will probably fail. */
+            if (free_avail) {
+                insert_error = 1;
+                return NULL;
+            }
+
+            if (freed_all) {
+                free_avail = 1; /* Must be free space now. */
+                cache_scan_free(cache_get_name(new), &new->addr.addr, now, new->flags);
+                cache_live_freed++;
+            } else {
+                cache_scan_free(NULL, NULL, now, 0);
+                freed_all = 1;
+            }
+            continue;
+        }
+
+        /* Check if we need to and can allocate extra memory for a long name.
+           If that fails, give up now. */
+        if (name && (strlen(name) > SMALLDNAME - 1)) {
+            if (big_free) {
+                big_name = big_free;
+                big_free = big_free->next;
+            } else if (!bignames_left ||
+                       !(big_name = (union bigname*) whine_malloc(sizeof(union bigname)))) {
+                insert_error = 1;
+                return NULL;
+            } else
+                bignames_left--;
+        }
+
+        /* Got the rest: finally grab entry. */
+        cache_unlink(new);
+        break;
+    }
+
+    new->flags = flags;
+    if (big_name) {
+        new->name.bname = big_name;
+        new->flags |= F_BIGNAME;
+    }
+
+    if (name)
+        strcpy(cache_get_name(new), name);
+    else
+        *cache_get_name(new) = 0;
+
+    if (addr)
+        new->addr.addr = *addr;
+    else
+        new->addr.cname.cache = NULL;
+
+    new->ttd = now + (time_t) ttl;
+    new->next = new_chain;
+    new_chain = new;
+
+    return new;
 }
 
 /* after end of insertion, commit the new entries */
-void cache_end_insert(void)
-{
-  if (insert_error)
-    return;
-  
-  while (new_chain)
-    { 
-      struct crec *tmp = new_chain->next;
-      /* drop CNAMEs which didn't find a target. */
-      if (is_outdated_cname_pointer(new_chain))
-	cache_free(new_chain);
-      else
-	{
-	  cache_hash(new_chain);
-	  cache_link(new_chain);
-	  cache_inserted++;
-	}
-      new_chain = tmp;
+void cache_end_insert(void) {
+    if (insert_error) return;
+
+    while (new_chain) {
+        struct crec* tmp = new_chain->next;
+        /* drop CNAMEs which didn't find a target. */
+        if (is_outdated_cname_pointer(new_chain))
+            cache_free(new_chain);
+        else {
+            cache_hash(new_chain);
+            cache_link(new_chain);
+            cache_inserted++;
+        }
+        new_chain = tmp;
     }
-  new_chain = NULL;
+    new_chain = NULL;
 }
 
-struct crec *cache_find_by_name(struct crec *crecp, char *name, time_t now, unsigned short prot)
-{
-  struct crec *ans;
+struct crec* cache_find_by_name(struct crec* crecp, char* name, time_t now, unsigned short prot) {
+    struct crec* ans;
 
-  if (crecp) /* iterating */
-    ans = crecp->next;
-  else
-    {
-      /* first search, look for relevant entries and push to top of list
-	 also free anything which has expired */
-      struct crec *next, **up, **insert = NULL, **chainp = &ans;
-      int ins_flags = 0;
-      
-      for (up = hash_bucket(name), crecp = *up; crecp; crecp = next)
-	{
-	  next = crecp->hash_next;
-	  
-	  if (!is_expired(now, crecp) && !is_outdated_cname_pointer(crecp))
-	    {
-	      if ((crecp->flags & F_FORWARD) && 
-		  (crecp->flags & prot) &&
-		  hostname_isequal(cache_get_name(crecp), name))
-		{
-		  if (crecp->flags & (F_HOSTS | F_DHCP))
-		    {
-		      *chainp = crecp;
-		      chainp = &crecp->next;
-		    }
-		  else
-		    {
-		      cache_unlink(crecp);
-		      cache_link(crecp);
-		    }
-	      	      
-		  /* Move all but the first entry up the hash chain
-		     this implements round-robin. 
-		     Make sure that re-ordering doesn't break the hash-chain
-		     order invariants. 
-		  */
-		  if (insert && (crecp->flags & (F_REVERSE | F_IMMORTAL)) == ins_flags)
-		    {
-		      *up = crecp->hash_next;
-		      crecp->hash_next = *insert;
-		      *insert = crecp;
-		      insert = &crecp->hash_next;
-		    }
-		  else
-		    {
-		      if (!insert)
-			{
-			  insert = up;
-			  ins_flags = crecp->flags & (F_REVERSE | F_IMMORTAL);
-			}
-		      up = &crecp->hash_next; 
-		    }
-		}
-	      else
-		/* case : not expired, incorrect entry. */
-		up = &crecp->hash_next; 
-	    }
-	  else
-	    {
-	      /* expired entry, free it */
-	      *up = crecp->hash_next;
-	      if (!(crecp->flags & (F_HOSTS | F_DHCP)))
-		{ 
-		  cache_unlink(crecp);
-		  cache_free(crecp);
-		}
-	    }
-	}
-	  
-      *chainp = cache_head;
+    if (crecp) /* iterating */
+        ans = crecp->next;
+    else {
+        /* first search, look for relevant entries and push to top of list
+       also free anything which has expired */
+        struct crec *next, **up, **insert = NULL, **chainp = &ans;
+        int ins_flags = 0;
+
+        for (up = hash_bucket(name), crecp = *up; crecp; crecp = next) {
+            next = crecp->hash_next;
+
+            if (!is_expired(now, crecp) && !is_outdated_cname_pointer(crecp)) {
+                if ((crecp->flags & F_FORWARD) && (crecp->flags & prot) &&
+                    hostname_isequal(cache_get_name(crecp), name)) {
+                    if (crecp->flags & (F_HOSTS | F_DHCP)) {
+                        *chainp = crecp;
+                        chainp = &crecp->next;
+                    } else {
+                        cache_unlink(crecp);
+                        cache_link(crecp);
+                    }
+
+                    /* Move all but the first entry up the hash chain
+                       this implements round-robin.
+                       Make sure that re-ordering doesn't break the hash-chain
+                       order invariants.
+                    */
+                    if (insert && (crecp->flags & (F_REVERSE | F_IMMORTAL)) == ins_flags) {
+                        *up = crecp->hash_next;
+                        crecp->hash_next = *insert;
+                        *insert = crecp;
+                        insert = &crecp->hash_next;
+                    } else {
+                        if (!insert) {
+                            insert = up;
+                            ins_flags = crecp->flags & (F_REVERSE | F_IMMORTAL);
+                        }
+                        up = &crecp->hash_next;
+                    }
+                } else
+                    /* case : not expired, incorrect entry. */
+                    up = &crecp->hash_next;
+            } else {
+                /* expired entry, free it */
+                *up = crecp->hash_next;
+                if (!(crecp->flags & (F_HOSTS | F_DHCP))) {
+                    cache_unlink(crecp);
+                    cache_free(crecp);
+                }
+            }
+        }
+
+        *chainp = cache_head;
     }
 
-  if (ans && 
-      (ans->flags & F_FORWARD) &&
-      (ans->flags & prot) &&
-      hostname_isequal(cache_get_name(ans), name))
-    return ans;
-  
-  return NULL;
+    if (ans && (ans->flags & F_FORWARD) && (ans->flags & prot) &&
+        hostname_isequal(cache_get_name(ans), name))
+        return ans;
+
+    return NULL;
 }
 
-struct crec *cache_find_by_addr(struct crec *crecp, struct all_addr *addr, 
-				time_t now, unsigned short prot)
-{
-  struct crec *ans;
+struct crec* cache_find_by_addr(struct crec* crecp, struct all_addr* addr, time_t now,
+                                unsigned short prot) {
+    struct crec* ans;
 #ifdef HAVE_IPV6
-  int addrlen = (prot == F_IPV6) ? IN6ADDRSZ : INADDRSZ;
+    int addrlen = (prot == F_IPV6) ? IN6ADDRSZ : INADDRSZ;
 #else
-  int addrlen = INADDRSZ;
+    int addrlen = INADDRSZ;
 #endif
-  
-  if (crecp) /* iterating */
-    ans = crecp->next;
-  else
-    {  
-      /* first search, look for relevant entries and push to top of list
-	 also free anything which has expired. All the reverse entries are at the
-	 start of the hash chain, so we can give up when we find the first 
-	 non-REVERSE one.  */
-       int i;
-       struct crec **up, **chainp = &ans;
-       
-       for (i=0; i<hash_size; i++)
-	 for (crecp = hash_table[i], up = &hash_table[i]; 
-	      crecp && (crecp->flags & F_REVERSE);
-	      crecp = crecp->hash_next)
-	   if (!is_expired(now, crecp))
-	     {      
-	       if ((crecp->flags & prot) &&
-		   memcmp(&crecp->addr.addr, addr, addrlen) == 0)
-		 {	    
-		   if (crecp->flags & (F_HOSTS | F_DHCP))
-		     {
-		       *chainp = crecp;
-		       chainp = &crecp->next;
-		     }
-		   else
-		     {
-		       cache_unlink(crecp);
-		       cache_link(crecp);
-		     }
-		 }
-	       up = &crecp->hash_next;
-	     }
-	   else
-	     {
-	       *up = crecp->hash_next;
-	       if (!(crecp->flags & (F_HOSTS | F_DHCP)))
-		 {
-		   cache_unlink(crecp);
-		   cache_free(crecp);
-		 }
-	     }
-       
-       *chainp = cache_head;
+
+    if (crecp) /* iterating */
+        ans = crecp->next;
+    else {
+        /* first search, look for relevant entries and push to top of list
+       also free anything which has expired. All the reverse entries are at the
+       start of the hash chain, so we can give up when we find the first
+       non-REVERSE one.  */
+        int i;
+        struct crec **up, **chainp = &ans;
+
+        for (i = 0; i < hash_size; i++)
+            for (crecp = hash_table[i], up = &hash_table[i]; crecp && (crecp->flags & F_REVERSE);
+                 crecp = crecp->hash_next)
+                if (!is_expired(now, crecp)) {
+                    if ((crecp->flags & prot) && memcmp(&crecp->addr.addr, addr, addrlen) == 0) {
+                        if (crecp->flags & (F_HOSTS | F_DHCP)) {
+                            *chainp = crecp;
+                            chainp = &crecp->next;
+                        } else {
+                            cache_unlink(crecp);
+                            cache_link(crecp);
+                        }
+                    }
+                    up = &crecp->hash_next;
+                } else {
+                    *up = crecp->hash_next;
+                    if (!(crecp->flags & (F_HOSTS | F_DHCP))) {
+                        cache_unlink(crecp);
+                        cache_free(crecp);
+                    }
+                }
+
+        *chainp = cache_head;
     }
-  
-  if (ans && 
-      (ans->flags & F_REVERSE) &&
-      (ans->flags & prot) &&
-      memcmp(&ans->addr.addr, addr, addrlen) == 0)
-    return ans;
-  
-  return NULL;
+
+    if (ans && (ans->flags & F_REVERSE) && (ans->flags & prot) &&
+        memcmp(&ans->addr.addr, addr, addrlen) == 0)
+        return ans;
+
+    return NULL;
 }
 
-static void add_hosts_entry(struct crec *cache, struct all_addr *addr, int addrlen, 
-			    unsigned short flags, int index, int addr_dup)
-{
-  struct crec *lookup = cache_find_by_name(NULL, cache->name.sname, 0, flags & (F_IPV4 | F_IPV6));
-  int i, nameexists = 0;
-  struct cname *a;
+static void add_hosts_entry(struct crec* cache, struct all_addr* addr, int addrlen,
+                            unsigned short flags, int index, int addr_dup) {
+    struct crec* lookup = cache_find_by_name(NULL, cache->name.sname, 0, flags & (F_IPV4 | F_IPV6));
+    int i, nameexists = 0;
+    struct cname* a;
 
-  /* Remove duplicates in hosts files. */
-  if (lookup && (lookup->flags & F_HOSTS))
-    {
-      nameexists = 1;
-      if (memcmp(&lookup->addr.addr, addr, addrlen) == 0)
-	{
-	  free(cache);
-	  return;
-	}
+    /* Remove duplicates in hosts files. */
+    if (lookup && (lookup->flags & F_HOSTS)) {
+        nameexists = 1;
+        if (memcmp(&lookup->addr.addr, addr, addrlen) == 0) {
+            free(cache);
+            return;
+        }
     }
-  
-  /* Ensure there is only one address -> name mapping (first one trumps) 
-     We do this by steam here, first we see if the address is the same as
-     the last one we saw, which eliminates most in the case of an ad-block 
-     file with thousands of entries for the same address.
-     Then we search and bail at the first matching address that came from
-     a HOSTS file. Since the first host entry gets reverse, we know 
-     then that it must exist without searching exhaustively for it. */
-  
-  if (addr_dup)
-    flags &= ~F_REVERSE;
-  else
-    for (i=0; i<hash_size; i++)
-      {
-	for (lookup = hash_table[i]; lookup; lookup = lookup->hash_next)
-	  if ((lookup->flags & F_HOSTS) && 
-	      (lookup->flags & flags & (F_IPV4 | F_IPV6)) &&
-	      memcmp(&lookup->addr.addr, addr, addrlen) == 0)
-	    {
-	      flags &= ~F_REVERSE;
-	      break;
-	    }
-	if (lookup)
-	  break;
-      }
-  
-  cache->flags = flags;
-  cache->uid = index;
-  memcpy(&cache->addr.addr, addr, addrlen);
-  cache_hash(cache);
-  
-  /* don't need to do alias stuff for second and subsequent addresses. */
-  if (!nameexists)
-    for (a = daemon->cnames; a; a = a->next)
-      if (hostname_isequal(cache->name.sname, a->target) &&
-	  (lookup = whine_malloc(sizeof(struct crec))))
-	{
-	  lookup->flags = F_FORWARD | F_IMMORTAL | F_CONFIG | F_HOSTS | F_CNAME;
-	  lookup->name.namep = a->alias;
-	  lookup->addr.cname.cache = cache;
-	  lookup->addr.cname.uid = index;
-	  cache_hash(lookup);
-	}
+
+    /* Ensure there is only one address -> name mapping (first one trumps)
+       We do this by steam here, first we see if the address is the same as
+       the last one we saw, which eliminates most in the case of an ad-block
+       file with thousands of entries for the same address.
+       Then we search and bail at the first matching address that came from
+       a HOSTS file. Since the first host entry gets reverse, we know
+       then that it must exist without searching exhaustively for it. */
+
+    if (addr_dup)
+        flags &= ~F_REVERSE;
+    else
+        for (i = 0; i < hash_size; i++) {
+            for (lookup = hash_table[i]; lookup; lookup = lookup->hash_next)
+                if ((lookup->flags & F_HOSTS) && (lookup->flags & flags & (F_IPV4 | F_IPV6)) &&
+                    memcmp(&lookup->addr.addr, addr, addrlen) == 0) {
+                    flags &= ~F_REVERSE;
+                    break;
+                }
+            if (lookup) break;
+        }
+
+    cache->flags = flags;
+    cache->uid = index;
+    memcpy(&cache->addr.addr, addr, addrlen);
+    cache_hash(cache);
+
+    /* don't need to do alias stuff for second and subsequent addresses. */
+    if (!nameexists)
+        for (a = daemon->cnames; a; a = a->next)
+            if (hostname_isequal(cache->name.sname, a->target) &&
+                (lookup = whine_malloc(sizeof(struct crec)))) {
+                lookup->flags = F_FORWARD | F_IMMORTAL | F_CONFIG | F_HOSTS | F_CNAME;
+                lookup->name.namep = a->alias;
+                lookup->addr.cname.cache = cache;
+                lookup->addr.cname.uid = index;
+                cache_hash(lookup);
+            }
 }
 
-static int eatspace(FILE *f)
-{
-  int c, nl = 0;
+static int eatspace(FILE* f) {
+    int c, nl = 0;
 
-  while (1)
-    {
-      if ((c = getc(f)) == '#')
-	while (c != '\n' && c != EOF)
-	  c = getc(f);
-      
-      if (c == EOF)
-	return 1;
+    while (1) {
+        if ((c = getc(f)) == '#')
+            while (c != '\n' && c != EOF) c = getc(f);
 
-      if (!isspace(c))
-	{
-	  ungetc(c, f);
-	  return nl;
-	}
+        if (c == EOF) return 1;
 
-      if (c == '\n')
-	nl = 1;
-    }
-}
-	 
-static int gettok(FILE *f, char *token)
-{
-  int c, count = 0;
- 
-  while (1)
-    {
-      if ((c = getc(f)) == EOF)
-	return (count == 0) ? EOF : 1;
+        if (!isspace(c)) {
+            ungetc(c, f);
+            return nl;
+        }
 
-      if (isspace(c) || c == '#')
-	{
-	  ungetc(c, f);
-	  return eatspace(f);
-	}
-      
-      if (count < (MAXDNAME - 1))
-	{
-	  token[count++] = c;
-	  token[count] = 0;
-	}
+        if (c == '\n') nl = 1;
     }
 }
 
-static int read_hostsfile(char *filename, int index, int cache_size)
-{  
-  FILE *f = fopen(filename, "r");
-  char *token = daemon->namebuff, *domain_suffix = NULL;
-  int addr_count = 0, name_count = cache_size, lineno = 0;
-  unsigned short flags = 0, saved_flags = 0;
-  struct all_addr addr, saved_addr;
-  int atnl, addrlen = 0, addr_dup;
+static int gettok(FILE* f, char* token) {
+    int c, count = 0;
 
-  if (!f)
-    {
-      my_syslog(LOG_ERR, _("failed to load names from %s: %s"), filename, strerror(errno));
-      return 0;
+    while (1) {
+        if ((c = getc(f)) == EOF) return (count == 0) ? EOF : 1;
+
+        if (isspace(c) || c == '#') {
+            ungetc(c, f);
+            return eatspace(f);
+        }
+
+        if (count < (MAXDNAME - 1)) {
+            token[count++] = c;
+            token[count] = 0;
+        }
     }
-  
-  eatspace(f);
-  
-  while ((atnl = gettok(f, token)) != EOF)
-    {
-      addr_dup = 0;
-      lineno++;
-      
-#ifdef HAVE_IPV6      
-      if (inet_pton(AF_INET, token, &addr) > 0)
-	{
-	  flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV4;
-	  addrlen = INADDRSZ;
-	  domain_suffix = get_domain(addr.addr.addr4);
-	}
-      else if (inet_pton(AF_INET6, token, &addr) > 0)
-	{
-	  flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV6;
-	  addrlen = IN6ADDRSZ;
-	  domain_suffix = daemon->domain_suffix;
-	}
-#else 
-      if ((addr.addr.addr4.s_addr = inet_addr(token)) != (in_addr_t) -1)
-	{
-	  flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV4;
-	  addrlen = INADDRSZ;
-	  domain_suffix = get_domain(addr.addr.addr4);
-	}
+}
+
+static int read_hostsfile(char* filename, int index, int cache_size) {
+    FILE* f = fopen(filename, "r");
+    char *token = daemon->namebuff, *domain_suffix = NULL;
+    int addr_count = 0, name_count = cache_size, lineno = 0;
+    unsigned short flags = 0, saved_flags = 0;
+    struct all_addr addr, saved_addr;
+    int atnl, addrlen = 0, addr_dup;
+
+    if (!f) {
+        my_syslog(LOG_ERR, _("failed to load names from %s: %s"), filename, strerror(errno));
+        return 0;
+    }
+
+    eatspace(f);
+
+    while ((atnl = gettok(f, token)) != EOF) {
+        addr_dup = 0;
+        lineno++;
+
+#ifdef HAVE_IPV6
+        if (inet_pton(AF_INET, token, &addr) > 0) {
+            flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV4;
+            addrlen = INADDRSZ;
+            domain_suffix = get_domain(addr.addr.addr4);
+        } else if (inet_pton(AF_INET6, token, &addr) > 0) {
+            flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV6;
+            addrlen = IN6ADDRSZ;
+            domain_suffix = daemon->domain_suffix;
+        }
+#else
+        if ((addr.addr.addr4.s_addr = inet_addr(token)) != (in_addr_t) -1) {
+            flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV4;
+            addrlen = INADDRSZ;
+            domain_suffix = get_domain(addr.addr.addr4);
+        }
 #endif
-      else
-	{
-	  my_syslog(LOG_ERR, _("bad address at %s line %d"), filename, lineno); 
-	  while (atnl == 0)
-	    atnl = gettok(f, token);
-	  continue;
-	}
-      
-      if (saved_flags == flags && memcmp(&addr, &saved_addr, addrlen) == 0)
-	addr_dup = 1;
-      else
-	{
-	  saved_flags = flags;
-	  saved_addr = addr;
-	}
-      
-      addr_count++;
-      
-      /* rehash every 1000 names. */
-      if ((name_count - cache_size) > 1000)
-	{
-	  rehash(name_count);
-	  cache_size = name_count;
-	} 
-      
-      while (atnl == 0)
-	{
-	  struct crec *cache;
-	  int fqdn, nomem;
-	  char *canon;
-	  
-	  if ((atnl = gettok(f, token)) == EOF)
-	    break;
+        else {
+            my_syslog(LOG_ERR, _("bad address at %s line %d"), filename, lineno);
+            while (atnl == 0) atnl = gettok(f, token);
+            continue;
+        }
 
-	  fqdn = !!strchr(token, '.');
+        if (saved_flags == flags && memcmp(&addr, &saved_addr, addrlen) == 0)
+            addr_dup = 1;
+        else {
+            saved_flags = flags;
+            saved_addr = addr;
+        }
 
-	  if ((canon = canonicalise(token, &nomem)))
-	    {
-	      /* If set, add a version of the name with a default domain appended */
-	      if ((daemon->options & OPT_EXPAND) && domain_suffix && !fqdn && 
-		  (cache = whine_malloc(sizeof(struct crec) + 
-					strlen(canon)+2+strlen(domain_suffix)-SMALLDNAME)))
-		{
-		  strcpy(cache->name.sname, canon);
-		  strcat(cache->name.sname, ".");
-		  strcat(cache->name.sname, domain_suffix);
-		  add_hosts_entry(cache, &addr, addrlen, flags, index, addr_dup);
-		  addr_dup = 1;
-		  name_count++;
-		}
-	      if ((cache = whine_malloc(sizeof(struct crec) + strlen(canon)+1-SMALLDNAME)))
-		{
-		  strcpy(cache->name.sname, canon);
-		  add_hosts_entry(cache, &addr, addrlen, flags, index, addr_dup);
-		  name_count++;
-		}
-	      free(canon);
-	      
-	    }
-	  else if (!nomem)
-	    my_syslog(LOG_ERR, _("bad name at %s line %d"), filename, lineno); 
-	}
-    } 
+        addr_count++;
 
-  fclose(f);
-  rehash(name_count);
-  
-  my_syslog(LOG_INFO, _("read %s - %d addresses"), filename, addr_count);
-  
-  return name_count;
+        /* rehash every 1000 names. */
+        if ((name_count - cache_size) > 1000) {
+            rehash(name_count);
+            cache_size = name_count;
+        }
+
+        while (atnl == 0) {
+            struct crec* cache;
+            int fqdn, nomem;
+            char* canon;
+
+            if ((atnl = gettok(f, token)) == EOF) break;
+
+            fqdn = !!strchr(token, '.');
+
+            if ((canon = canonicalise(token, &nomem))) {
+                /* If set, add a version of the name with a default domain appended */
+                if ((daemon->options & OPT_EXPAND) && domain_suffix && !fqdn &&
+                    (cache = whine_malloc(sizeof(struct crec) + strlen(canon) + 2 +
+                                          strlen(domain_suffix) - SMALLDNAME))) {
+                    strcpy(cache->name.sname, canon);
+                    strcat(cache->name.sname, ".");
+                    strcat(cache->name.sname, domain_suffix);
+                    add_hosts_entry(cache, &addr, addrlen, flags, index, addr_dup);
+                    addr_dup = 1;
+                    name_count++;
+                }
+                if ((cache = whine_malloc(sizeof(struct crec) + strlen(canon) + 1 - SMALLDNAME))) {
+                    strcpy(cache->name.sname, canon);
+                    add_hosts_entry(cache, &addr, addrlen, flags, index, addr_dup);
+                    name_count++;
+                }
+                free(canon);
+
+            } else if (!nomem)
+                my_syslog(LOG_ERR, _("bad name at %s line %d"), filename, lineno);
+        }
+    }
+
+    fclose(f);
+    rehash(name_count);
+
+    my_syslog(LOG_INFO, _("read %s - %d addresses"), filename, addr_count);
+
+    return name_count;
 }
-	    
-void cache_reload(void)
-{
-  struct crec *cache, **up, *tmp;
-  int i, total_size = daemon->cachesize;
-  struct hostsfile *ah;
 
-  cache_inserted = cache_live_freed = 0;
-  
-  for (i=0; i<hash_size; i++)
-    for (cache = hash_table[i], up = &hash_table[i]; cache; cache = tmp)
-      {
-	tmp = cache->hash_next;
-	if (cache->flags & F_HOSTS)
-	  {
-	    *up = cache->hash_next;
-	    free(cache);
-	  }
-	else if (!(cache->flags & F_DHCP))
-	  {
-	    *up = cache->hash_next;
-	    if (cache->flags & F_BIGNAME)
-	      {
-		cache->name.bname->next = big_free;
-		big_free = cache->name.bname;
-	      }
-	    cache->flags = 0;
-	  }
-	else
-	  up = &cache->hash_next;
-      }
-  
-  if ((daemon->options & OPT_NO_HOSTS) && !daemon->addn_hosts)
-    {
-      if (daemon->cachesize > 0)
-	my_syslog(LOG_INFO, _("cleared cache"));
-      return;
+void cache_reload(void) {
+    struct crec *cache, **up, *tmp;
+    int i, total_size = daemon->cachesize;
+    struct hostsfile* ah;
+
+    cache_inserted = cache_live_freed = 0;
+
+    for (i = 0; i < hash_size; i++)
+        for (cache = hash_table[i], up = &hash_table[i]; cache; cache = tmp) {
+            tmp = cache->hash_next;
+            if (cache->flags & F_HOSTS) {
+                *up = cache->hash_next;
+                free(cache);
+            } else if (!(cache->flags & F_DHCP)) {
+                *up = cache->hash_next;
+                if (cache->flags & F_BIGNAME) {
+                    cache->name.bname->next = big_free;
+                    big_free = cache->name.bname;
+                }
+                cache->flags = 0;
+            } else
+                up = &cache->hash_next;
+        }
+
+    if ((daemon->options & OPT_NO_HOSTS) && !daemon->addn_hosts) {
+        if (daemon->cachesize > 0) my_syslog(LOG_INFO, _("cleared cache"));
+        return;
     }
 
-  if (!(daemon->options & OPT_NO_HOSTS))
-    total_size = read_hostsfile(HOSTSFILE, 0, total_size);
-  
-  for (i = 0, ah = daemon->addn_hosts; ah; ah = ah->next)
-    {
-      if (i <= ah->index)
-	i = ah->index + 1;
+    if (!(daemon->options & OPT_NO_HOSTS)) total_size = read_hostsfile(HOSTSFILE, 0, total_size);
 
-      if (ah->flags & AH_DIR)
-	ah->flags |= AH_INACTIVE;
-      else
-	ah->flags &= ~AH_INACTIVE;
+    for (i = 0, ah = daemon->addn_hosts; ah; ah = ah->next) {
+        if (i <= ah->index) i = ah->index + 1;
+
+        if (ah->flags & AH_DIR)
+            ah->flags |= AH_INACTIVE;
+        else
+            ah->flags &= ~AH_INACTIVE;
     }
 
-  for (ah = daemon->addn_hosts; ah; ah = ah->next)
-    if (!(ah->flags & AH_INACTIVE))
-      {
-	struct stat buf;
-	if (stat(ah->fname, &buf) != -1 && S_ISDIR(buf.st_mode))
-	  {
-	    DIR *dir_stream;
-	    struct dirent *ent;
-	    
-	    /* don't read this as a file */
-	    ah->flags |= AH_INACTIVE;
-	    
-	    if (!(dir_stream = opendir(ah->fname)))
-	      my_syslog(LOG_ERR, _("cannot access directory %s: %s"), 
-			ah->fname, strerror(errno));
-	    else
-	      {
-		while ((ent = readdir(dir_stream)))
-		  {
-		    size_t lendir = strlen(ah->fname);
-		    size_t lenfile = strlen(ent->d_name);
-		    struct hostsfile *ah1;
-		    char *path;
-		    
-		    /* ignore emacs backups and dotfiles */
-		    if (lenfile == 0 || 
-			ent->d_name[lenfile - 1] == '~' ||
-			(ent->d_name[0] == '#' && ent->d_name[lenfile - 1] == '#') ||
-			ent->d_name[0] == '.')
-		      continue;
-		    
-		    /* see if we have an existing record.
-		       dir is ah->fname 
-		       file is ent->d_name
-		       path to match is ah1->fname */
+    for (ah = daemon->addn_hosts; ah; ah = ah->next)
+        if (!(ah->flags & AH_INACTIVE)) {
+            struct stat buf;
+            if (stat(ah->fname, &buf) != -1 && S_ISDIR(buf.st_mode)) {
+                DIR* dir_stream;
+                struct dirent* ent;
 
-		    for (ah1 = daemon->addn_hosts; ah1; ah1 = ah1->next)
-		      {
-			if (lendir < strlen(ah1->fname) &&
-			    strstr(ah1->fname, ah->fname) == ah1->fname &&
-			    ah1->fname[lendir] == '/' &&
-			    strcmp(ah1->fname + lendir + 1, ent->d_name) == 0)
-			  {
-			    ah1->flags &= ~AH_INACTIVE;
-			    break;
-			  }
-		      }
-		    
-		    /* make new record */
-		    if (!ah1)
-		      {
-			if (!(ah1 = whine_malloc(sizeof(struct hostsfile))))
-			  continue;
-			
-			if (!(path = whine_malloc(lendir + lenfile + 2)))
-			  {
-			    free(ah1);
-			    continue;
-			  }
-		      	
-			strcpy(path, ah->fname);
-			strcat(path, "/");
-			strcat(path, ent->d_name);
-			ah1->fname = path;
-			ah1->index = i++;
-			ah1->flags = AH_DIR;
-			ah1->next = daemon->addn_hosts;
-			daemon->addn_hosts = ah1;
-		      }
-		    
-		    /* inactivate record if not regular file */
-		    if ((ah1->flags & AH_DIR) && stat(ah1->fname, &buf) != -1 && !S_ISREG(buf.st_mode))
-		      ah1->flags |= AH_INACTIVE; 
+                /* don't read this as a file */
+                ah->flags |= AH_INACTIVE;
 
-		  }
-		closedir(dir_stream);
-	      }
-	  }
-      }
-	    
-  for (ah = daemon->addn_hosts; ah; ah = ah->next)
-    if (!(ah->flags & AH_INACTIVE))
-      total_size = read_hostsfile(ah->fname, ah->index, total_size);
-} 
+                if (!(dir_stream = opendir(ah->fname)))
+                    my_syslog(LOG_ERR, _("cannot access directory %s: %s"), ah->fname,
+                              strerror(errno));
+                else {
+                    while ((ent = readdir(dir_stream))) {
+                        size_t lendir = strlen(ah->fname);
+                        size_t lenfile = strlen(ent->d_name);
+                        struct hostsfile* ah1;
+                        char* path;
 
-char *get_domain(struct in_addr addr)
-{
-  struct cond_domain *c;
+                        /* ignore emacs backups and dotfiles */
+                        if (lenfile == 0 || ent->d_name[lenfile - 1] == '~' ||
+                            (ent->d_name[0] == '#' && ent->d_name[lenfile - 1] == '#') ||
+                            ent->d_name[0] == '.')
+                            continue;
 
-  for (c = daemon->cond_domain; c; c = c->next)
-    if (ntohl(addr.s_addr) >= ntohl(c->start.s_addr) &&
-        ntohl(addr.s_addr) <= ntohl(c->end.s_addr))
-      return c->domain;
+                        /* see if we have an existing record.
+                           dir is ah->fname
+                           file is ent->d_name
+                           path to match is ah1->fname */
 
-  return daemon->domain_suffix;
+                        for (ah1 = daemon->addn_hosts; ah1; ah1 = ah1->next) {
+                            if (lendir < strlen(ah1->fname) &&
+                                strstr(ah1->fname, ah->fname) == ah1->fname &&
+                                ah1->fname[lendir] == '/' &&
+                                strcmp(ah1->fname + lendir + 1, ent->d_name) == 0) {
+                                ah1->flags &= ~AH_INACTIVE;
+                                break;
+                            }
+                        }
+
+                        /* make new record */
+                        if (!ah1) {
+                            if (!(ah1 = whine_malloc(sizeof(struct hostsfile)))) continue;
+
+                            if (!(path = whine_malloc(lendir + lenfile + 2))) {
+                                free(ah1);
+                                continue;
+                            }
+
+                            strcpy(path, ah->fname);
+                            strcat(path, "/");
+                            strcat(path, ent->d_name);
+                            ah1->fname = path;
+                            ah1->index = i++;
+                            ah1->flags = AH_DIR;
+                            ah1->next = daemon->addn_hosts;
+                            daemon->addn_hosts = ah1;
+                        }
+
+                        /* inactivate record if not regular file */
+                        if ((ah1->flags & AH_DIR) && stat(ah1->fname, &buf) != -1 &&
+                            !S_ISREG(buf.st_mode))
+                            ah1->flags |= AH_INACTIVE;
+                    }
+                    closedir(dir_stream);
+                }
+            }
+        }
+
+    for (ah = daemon->addn_hosts; ah; ah = ah->next)
+        if (!(ah->flags & AH_INACTIVE))
+            total_size = read_hostsfile(ah->fname, ah->index, total_size);
+}
+
+char* get_domain(struct in_addr addr) {
+    struct cond_domain* c;
+
+    for (c = daemon->cond_domain; c; c = c->next)
+        if (ntohl(addr.s_addr) >= ntohl(c->start.s_addr) &&
+            ntohl(addr.s_addr) <= ntohl(c->end.s_addr))
+            return c->domain;
+
+    return daemon->domain_suffix;
 }
 
 #ifdef HAVE_DHCP
-void cache_unhash_dhcp(void)
-{
-  struct crec *cache, **up;
-  int i;
+void cache_unhash_dhcp(void) {
+    struct crec *cache, **up;
+    int i;
 
-  for (i=0; i<hash_size; i++)
-    for (cache = hash_table[i], up = &hash_table[i]; cache; cache = cache->hash_next)
-      if (cache->flags & F_DHCP)
-	{
-	  *up = cache->hash_next;
-	  cache->next = dhcp_spare;
-	  dhcp_spare = cache;
-	}
-      else
-	up = &cache->hash_next;
+    for (i = 0; i < hash_size; i++)
+        for (cache = hash_table[i], up = &hash_table[i]; cache; cache = cache->hash_next)
+            if (cache->flags & F_DHCP) {
+                *up = cache->hash_next;
+                cache->next = dhcp_spare;
+                dhcp_spare = cache;
+            } else
+                up = &cache->hash_next;
 }
 
-void cache_add_dhcp_entry(char *host_name, 
-			  struct in_addr *host_address, time_t ttd) 
-{
-  struct crec *crec = NULL, *aliasc;
-  unsigned short flags =  F_DHCP | F_FORWARD | F_IPV4 | F_REVERSE;
-  int in_hosts = 0;
-  struct cname *a;
-  
-  while ((crec = cache_find_by_name(crec, host_name, 0, F_IPV4 | F_CNAME)))
-    {
-      /* check all addresses associated with name */
-      if (crec->flags & F_HOSTS)
-	{
-	  if (crec->addr.addr.addr.addr4.s_addr != host_address->s_addr)
-	    {
-	      strcpy(daemon->namebuff, inet_ntoa(crec->addr.addr.addr.addr4));
-	      my_syslog(LOG_WARNING, 
-			_("not giving name %s to the DHCP lease of %s because "
-			  "the name exists in %s with address %s"), 
-			host_name, inet_ntoa(*host_address),
-			record_source(crec->uid), daemon->namebuff);
-	      return;
-	    }
-	  else
-	    /* if in hosts, don't need DHCP record */
-	    in_hosts = 1;
-	}
-      else if (!(crec->flags & F_DHCP))
-	{
-	  cache_scan_free(host_name, NULL, 0, crec->flags & (F_IPV4 | F_CNAME | F_FORWARD));
-	  /* scan_free deletes all addresses associated with name */
-	  break;
-	}
+void cache_add_dhcp_entry(char* host_name, struct in_addr* host_address, time_t ttd) {
+    struct crec *crec = NULL, *aliasc;
+    unsigned short flags = F_DHCP | F_FORWARD | F_IPV4 | F_REVERSE;
+    int in_hosts = 0;
+    struct cname* a;
+
+    while ((crec = cache_find_by_name(crec, host_name, 0, F_IPV4 | F_CNAME))) {
+        /* check all addresses associated with name */
+        if (crec->flags & F_HOSTS) {
+            if (crec->addr.addr.addr.addr4.s_addr != host_address->s_addr) {
+                strcpy(daemon->namebuff, inet_ntoa(crec->addr.addr.addr.addr4));
+                my_syslog(LOG_WARNING,
+                          _("not giving name %s to the DHCP lease of %s because "
+                            "the name exists in %s with address %s"),
+                          host_name, inet_ntoa(*host_address), record_source(crec->uid),
+                          daemon->namebuff);
+                return;
+            } else
+                /* if in hosts, don't need DHCP record */
+                in_hosts = 1;
+        } else if (!(crec->flags & F_DHCP)) {
+            cache_scan_free(host_name, NULL, 0, crec->flags & (F_IPV4 | F_CNAME | F_FORWARD));
+            /* scan_free deletes all addresses associated with name */
+            break;
+        }
     }
-  
-   if (in_hosts)
-    return;
 
-   if ((crec = cache_find_by_addr(NULL, (struct all_addr *)host_address, 0, F_IPV4)))
-     {
-       if (crec->flags & F_NEG)
-	 cache_scan_free(NULL, (struct all_addr *)host_address, 0, F_IPV4 | F_REVERSE);
-       else
-	 /* avoid multiple reverse mappings */
-	 flags &= ~F_REVERSE;
-     }
-   
-   if ((crec = dhcp_spare))
-    dhcp_spare = dhcp_spare->next;
-  else /* need new one */
-    crec = whine_malloc(sizeof(struct crec));
-  
-  if (crec) /* malloc may fail */
+    if (in_hosts) return;
+
+    if ((crec = cache_find_by_addr(NULL, (struct all_addr*) host_address, 0, F_IPV4))) {
+        if (crec->flags & F_NEG)
+            cache_scan_free(NULL, (struct all_addr*) host_address, 0, F_IPV4 | F_REVERSE);
+        else
+            /* avoid multiple reverse mappings */
+            flags &= ~F_REVERSE;
+    }
+
+    if ((crec = dhcp_spare))
+        dhcp_spare = dhcp_spare->next;
+    else /* need new one */
+        crec = whine_malloc(sizeof(struct crec));
+
+    if (crec) /* malloc may fail */
     {
-      crec->flags = flags;
-      if (ttd == 0)
-	crec->flags |= F_IMMORTAL;
-      else
-	crec->ttd = ttd;
-      crec->addr.addr.addr.addr4 = *host_address;
-      crec->name.namep = host_name;
-      crec->uid = uid++;
-      cache_hash(crec);
+        crec->flags = flags;
+        if (ttd == 0)
+            crec->flags |= F_IMMORTAL;
+        else
+            crec->ttd = ttd;
+        crec->addr.addr.addr.addr4 = *host_address;
+        crec->name.namep = host_name;
+        crec->uid = uid++;
+        cache_hash(crec);
 
-      for (a = daemon->cnames; a; a = a->next)
-	if (hostname_isequal(host_name, a->target))
-	  {
-	    if ((aliasc = dhcp_spare))
-	      dhcp_spare = dhcp_spare->next;
-	    else /* need new one */
-	      aliasc = whine_malloc(sizeof(struct crec));
-	    
-	    if (aliasc)
-	      {
-		aliasc->flags = F_FORWARD | F_CONFIG | F_DHCP | F_CNAME;
-		if (ttd == 0)
-		  aliasc->flags |= F_IMMORTAL;
-		else
-		  aliasc->ttd = ttd;
-		aliasc->name.namep = a->alias;
-		aliasc->addr.cname.cache = crec;
-		aliasc->addr.cname.uid = crec->uid;
-		cache_hash(aliasc);
-	      }
-	  }
+        for (a = daemon->cnames; a; a = a->next)
+            if (hostname_isequal(host_name, a->target)) {
+                if ((aliasc = dhcp_spare))
+                    dhcp_spare = dhcp_spare->next;
+                else /* need new one */
+                    aliasc = whine_malloc(sizeof(struct crec));
+
+                if (aliasc) {
+                    aliasc->flags = F_FORWARD | F_CONFIG | F_DHCP | F_CNAME;
+                    if (ttd == 0)
+                        aliasc->flags |= F_IMMORTAL;
+                    else
+                        aliasc->ttd = ttd;
+                    aliasc->name.namep = a->alias;
+                    aliasc->addr.cname.cache = crec;
+                    aliasc->addr.cname.uid = crec->uid;
+                    cache_hash(aliasc);
+                }
+            }
     }
 }
 #endif
 
+void dump_cache(time_t now) {
+    struct server *serv, *serv1;
 
-void dump_cache(time_t now)
-{
-  struct server *serv, *serv1;
+    my_syslog(LOG_INFO, _("time %lu"), (unsigned long) now);
+    my_syslog(LOG_INFO, _("cache size %d, %d/%d cache insertions re-used unexpired cache entries."),
+              daemon->cachesize, cache_live_freed, cache_inserted);
+    my_syslog(LOG_INFO, _("queries forwarded %u, queries answered locally %u"),
+              daemon->queries_forwarded, daemon->local_answer);
 
-  my_syslog(LOG_INFO, _("time %lu"), (unsigned long)now);
-  my_syslog(LOG_INFO, _("cache size %d, %d/%d cache insertions re-used unexpired cache entries."), 
-	    daemon->cachesize, cache_live_freed, cache_inserted);
-  my_syslog(LOG_INFO, _("queries forwarded %u, queries answered locally %u"), 
-	    daemon->queries_forwarded, daemon->local_answer);
+    if (!addrbuff && !(addrbuff = whine_malloc(ADDRSTRLEN))) return;
 
-  if (!addrbuff && !(addrbuff = whine_malloc(ADDRSTRLEN)))
-    return;
+    /* sum counts from different records for same server */
+    for (serv = daemon->servers; serv; serv = serv->next) serv->flags &= ~SERV_COUNTED;
 
-  /* sum counts from different records for same server */
-  for (serv = daemon->servers; serv; serv = serv->next)
-    serv->flags &= ~SERV_COUNTED;
-  
-  for (serv = daemon->servers; serv; serv = serv->next)
-    if (!(serv->flags & (SERV_NO_ADDR | SERV_LITERAL_ADDRESS | SERV_COUNTED)))
-      {
-	int port;
-	unsigned int queries = 0, failed_queries = 0;
-	for (serv1 = serv; serv1; serv1 = serv1->next)
-	  if (!(serv1->flags & (SERV_NO_ADDR | SERV_LITERAL_ADDRESS | SERV_COUNTED)) && sockaddr_isequal(&serv->addr, &serv1->addr))
-	    {
-	      serv1->flags |= SERV_COUNTED;
-	      queries += serv1->queries;
-	      failed_queries += serv1->failed_queries;
-	    }
-	port = prettyprint_addr(&serv->addr, addrbuff);
-	my_syslog(LOG_INFO, _("server %s#%d: queries sent %u, retried or failed %u"), addrbuff, port, queries, failed_queries);
-      }
-  
-  if ((daemon->options & (OPT_DEBUG | OPT_LOG)))
-    {
-      struct crec *cache ;
-      int i;
-      my_syslog(LOG_DEBUG, "Host                                     Address                        Flags     Expires");
-    
-      for (i=0; i<hash_size; i++)
-	for (cache = hash_table[i]; cache; cache = cache->hash_next)
-	  {
-	    char *a, *p = daemon->namebuff;
-	    p += sprintf(p, "%-40.40s ", cache_get_name(cache));
-	    if ((cache->flags & F_NEG) && (cache->flags & F_FORWARD))
-	      a = ""; 
-	    else if (cache->flags & F_CNAME) 
-	      {
-		a = "";
-		if (!is_outdated_cname_pointer(cache))
-		  a = cache_get_name(cache->addr.cname.cache);
-	      }
+    for (serv = daemon->servers; serv; serv = serv->next)
+        if (!(serv->flags & (SERV_NO_ADDR | SERV_LITERAL_ADDRESS | SERV_COUNTED))) {
+            int port;
+            unsigned int queries = 0, failed_queries = 0;
+            for (serv1 = serv; serv1; serv1 = serv1->next)
+                if (!(serv1->flags & (SERV_NO_ADDR | SERV_LITERAL_ADDRESS | SERV_COUNTED)) &&
+                    sockaddr_isequal(&serv->addr, &serv1->addr)) {
+                    serv1->flags |= SERV_COUNTED;
+                    queries += serv1->queries;
+                    failed_queries += serv1->failed_queries;
+                }
+            port = prettyprint_addr(&serv->addr, addrbuff);
+            my_syslog(LOG_INFO, _("server %s#%d: queries sent %u, retried or failed %u"), addrbuff,
+                      port, queries, failed_queries);
+        }
+
+    if ((daemon->options & (OPT_DEBUG | OPT_LOG))) {
+        struct crec* cache;
+        int i;
+        my_syslog(LOG_DEBUG,
+                  "Host                                     Address                        Flags   "
+                  "  Expires");
+
+        for (i = 0; i < hash_size; i++)
+            for (cache = hash_table[i]; cache; cache = cache->hash_next) {
+                char *a, *p = daemon->namebuff;
+                p += sprintf(p, "%-40.40s ", cache_get_name(cache));
+                if ((cache->flags & F_NEG) && (cache->flags & F_FORWARD))
+                    a = "";
+                else if (cache->flags & F_CNAME) {
+                    a = "";
+                    if (!is_outdated_cname_pointer(cache))
+                        a = cache_get_name(cache->addr.cname.cache);
+                }
 #ifdef HAVE_IPV6
-	    else 
-	      { 
-		a = addrbuff;
-		if (cache->flags & F_IPV4)
-		  inet_ntop(AF_INET, &cache->addr.addr, addrbuff, ADDRSTRLEN);
-		else if (cache->flags & F_IPV6)
-		  inet_ntop(AF_INET6, &cache->addr.addr, addrbuff, ADDRSTRLEN);
-	      }
+                else {
+                    a = addrbuff;
+                    if (cache->flags & F_IPV4)
+                        inet_ntop(AF_INET, &cache->addr.addr, addrbuff, ADDRSTRLEN);
+                    else if (cache->flags & F_IPV6)
+                        inet_ntop(AF_INET6, &cache->addr.addr, addrbuff, ADDRSTRLEN);
+                }
 #else
-            else 
-	      a = inet_ntoa(cache->addr.addr.addr.addr4);
+                else
+                    a = inet_ntoa(cache->addr.addr.addr.addr4);
 #endif
-	    p += sprintf(p, "%-30.30s %s%s%s%s%s%s%s%s%s%s  ", a, 
-			 cache->flags & F_IPV4 ? "4" : "",
-			 cache->flags & F_IPV6 ? "6" : "",
-			 cache->flags & F_CNAME ? "C" : "",
-			 cache->flags & F_FORWARD ? "F" : " ",
-			 cache->flags & F_REVERSE ? "R" : " ",
-			 cache->flags & F_IMMORTAL ? "I" : " ",
-			 cache->flags & F_DHCP ? "D" : " ",
-			 cache->flags & F_NEG ? "N" : " ",
-			 cache->flags & F_NXDOMAIN ? "X" : " ",
-			 cache->flags & F_HOSTS ? "H" : " ");
+                p += sprintf(
+                    p, "%-30.30s %s%s%s%s%s%s%s%s%s%s  ", a, cache->flags & F_IPV4 ? "4" : "",
+                    cache->flags & F_IPV6 ? "6" : "", cache->flags & F_CNAME ? "C" : "",
+                    cache->flags & F_FORWARD ? "F" : " ", cache->flags & F_REVERSE ? "R" : " ",
+                    cache->flags & F_IMMORTAL ? "I" : " ", cache->flags & F_DHCP ? "D" : " ",
+                    cache->flags & F_NEG ? "N" : " ", cache->flags & F_NXDOMAIN ? "X" : " ",
+                    cache->flags & F_HOSTS ? "H" : " ");
 #ifdef HAVE_BROKEN_RTC
-	    p += sprintf(p, "%lu", cache->flags & F_IMMORTAL ? 0: (unsigned long)(cache->ttd - now));
+                p += sprintf(p, "%lu",
+                             cache->flags & F_IMMORTAL ? 0 : (unsigned long) (cache->ttd - now));
 #else
-	    p += sprintf(p, "%s", cache->flags & F_IMMORTAL ? "\n" : ctime(&(cache->ttd)));
-	    /* ctime includes trailing \n - eat it */
-	    *(p-1) = 0;
+                p += sprintf(p, "%s", cache->flags & F_IMMORTAL ? "\n" : ctime(&(cache->ttd)));
+                /* ctime includes trailing \n - eat it */
+                *(p - 1) = 0;
 #endif
-	    my_syslog(LOG_DEBUG, daemon->namebuff);
-	  }
+                my_syslog(LOG_DEBUG, daemon->namebuff);
+            }
     }
 }
 
-char *record_source(int index)
-{
-  struct hostsfile *ah;
+char* record_source(int index) {
+    struct hostsfile* ah;
 
-  if (index == 0)
-    return HOSTSFILE;
+    if (index == 0) return HOSTSFILE;
 
-  for (ah = daemon->addn_hosts; ah; ah = ah->next)
-    if (ah->index == index)
-      return ah->fname;
-  
-  return "<unknown>";
+    for (ah = daemon->addn_hosts; ah; ah = ah->next)
+        if (ah->index == index) return ah->fname;
+
+    return "<unknown>";
 }
 
-void querystr(char *str, unsigned short type)
-{
-  unsigned int i;
-  
-  sprintf(str, "query[type=%d]", type); 
-  for (i = 0; i < (sizeof(typestr)/sizeof(typestr[0])); i++)
-    if (typestr[i].type == type)
-      sprintf(str,"query[%s]", typestr[i].name);
+void querystr(char* str, unsigned short type) {
+    unsigned int i;
+
+    sprintf(str, "query[type=%d]", type);
+    for (i = 0; i < (sizeof(typestr) / sizeof(typestr[0])); i++)
+        if (typestr[i].type == type) sprintf(str, "query[%s]", typestr[i].name);
 }
 
-void log_query(unsigned short flags, char *name, struct all_addr *addr, char *arg)
-{
-  char *source, *dest = addrbuff;
-  char *verb = "is";
-  
-  if (!(daemon->options & OPT_LOG))
-    return;
+void log_query(unsigned short flags, char* name, struct all_addr* addr, char* arg) {
+    char *source, *dest = addrbuff;
+    char* verb = "is";
 
-  if (addr)
-    {
+    if (!(daemon->options & OPT_LOG)) return;
+
+    if (addr) {
 #ifdef HAVE_IPV6
-      /* TODO: support scoped addresses. struct all_addr doesn't store scope IDs. */
-      inet_ntop(flags & F_IPV4 ? AF_INET : AF_INET6,
-		addr, addrbuff, ADDRSTRLEN);
+        /* TODO: support scoped addresses. struct all_addr doesn't store scope IDs. */
+        inet_ntop(flags & F_IPV4 ? AF_INET : AF_INET6, addr, addrbuff, ADDRSTRLEN);
 #else
-      strncpy(addrbuff, inet_ntoa(addr->addr.addr4), ADDRSTRLEN);  
+        strncpy(addrbuff, inet_ntoa(addr->addr.addr4), ADDRSTRLEN);
 #endif
     }
 
-  if (flags & F_REVERSE)
-    {
-      dest = name;
-      name = addrbuff;
+    if (flags & F_REVERSE) {
+        dest = name;
+        name = addrbuff;
     }
-  
-  if (flags & F_NEG)
-    {
-      if (flags & F_NXDOMAIN)
-	{
-	  if (flags & F_IPV4)
-	    dest = "NXDOMAIN-IPv4";
-	  else if (flags & F_IPV6)
-	    dest = "NXDOMAIN-IPv6";
-	  else
-	    dest = "NXDOMAIN";
-	}
-      else
-	{      
-	  if (flags & F_IPV4)
-	    dest = "NODATA-IPv4";
-	  else if (flags & F_IPV6)
-	    dest = "NODATA-IPv6";
-	  else
-	    dest = "NODATA";
-	}
-    }
-  else if (flags & F_CNAME)
-    {
-      /* nasty abuse of NXDOMAIN and CNAME flags */
-      if (flags & F_NXDOMAIN)
-	dest = arg;
-      else
-	dest = "<CNAME>";
-    }
-    
-  if (flags & F_CONFIG)
-    source = "config";
-  else if (flags & F_DHCP)
-    source = "DHCP";
-  else if (flags & F_HOSTS)
-    source = arg;
-  else if (flags & F_UPSTREAM)
-    source = "reply";
-  else if (flags & F_SERVER)
-    {
-      source = "forwarded";
-      verb = "to";
-    }
-  else if (flags & F_QUERY)
-    {
-      source = arg;
-      verb = "from";
-    }
-  else
-    source = "cached";
-  
-  if (strlen(name) == 0)
-    name = ".";
 
-  my_syslog(LOG_DEBUG, "%s %s %s %s", source, name, verb, dest);
+    if (flags & F_NEG) {
+        if (flags & F_NXDOMAIN) {
+            if (flags & F_IPV4)
+                dest = "NXDOMAIN-IPv4";
+            else if (flags & F_IPV6)
+                dest = "NXDOMAIN-IPv6";
+            else
+                dest = "NXDOMAIN";
+        } else {
+            if (flags & F_IPV4)
+                dest = "NODATA-IPv4";
+            else if (flags & F_IPV6)
+                dest = "NODATA-IPv6";
+            else
+                dest = "NODATA";
+        }
+    } else if (flags & F_CNAME) {
+        /* nasty abuse of NXDOMAIN and CNAME flags */
+        if (flags & F_NXDOMAIN)
+            dest = arg;
+        else
+            dest = "<CNAME>";
+    }
+
+    if (flags & F_CONFIG)
+        source = "config";
+    else if (flags & F_DHCP)
+        source = "DHCP";
+    else if (flags & F_HOSTS)
+        source = arg;
+    else if (flags & F_UPSTREAM)
+        source = "reply";
+    else if (flags & F_SERVER) {
+        source = "forwarded";
+        verb = "to";
+    } else if (flags & F_QUERY) {
+        source = arg;
+        verb = "from";
+    } else
+        source = "cached";
+
+    if (strlen(name) == 0) name = ".";
+
+    my_syslog(LOG_DEBUG, "%s %s %s %s", source, name, verb, dest);
 }
-
diff --git a/src/config.h b/src/config.h
index 1491f14..05d74ae 100644
--- a/src/config.h
+++ b/src/config.h
@@ -16,48 +16,48 @@
 
 #define VERSION "2.51"
 
-#define FTABSIZ 150 /* max number of outstanding requests (default) */
-#define MAX_PROCS 20 /* max no children for TCP requests */
-#define CHILD_LIFETIME 150 /* secs 'till terminated (RFC1035 suggests > 120s) */
-#define EDNS_PKTSZ 1280 /* default max EDNS.0 UDP packet from RFC2671 */
-#define TIMEOUT 10 /* drop UDP queries after TIMEOUT seconds */
-#define FORWARD_TEST 50 /* try all servers every 50 queries */
-#define FORWARD_TIME 10 /* or 10 seconds */
-#define RANDOM_SOCKS 64 /* max simultaneous random ports */
-#define LEASE_RETRY 60 /* on error, retry writing leasefile after LEASE_RETRY seconds */
-#define CACHESIZ 150 /* default cache size */
-#define MAXLEASES 150 /* maximum number of DHCP leases */
-#define PING_WAIT 3 /* wait for ping address-in-use test */
-#define PING_CACHE_TIME 30 /* Ping test assumed to be valid this long. */
-#define DECLINE_BACKOFF 600 /* disable DECLINEd static addresses for this long */
+#define FTABSIZ 150           /* max number of outstanding requests (default) */
+#define MAX_PROCS 20          /* max no children for TCP requests */
+#define CHILD_LIFETIME 150    /* secs 'till terminated (RFC1035 suggests > 120s) */
+#define EDNS_PKTSZ 1280       /* default max EDNS.0 UDP packet from RFC2671 */
+#define TIMEOUT 10            /* drop UDP queries after TIMEOUT seconds */
+#define FORWARD_TEST 50       /* try all servers every 50 queries */
+#define FORWARD_TIME 10       /* or 10 seconds */
+#define RANDOM_SOCKS 64       /* max simultaneous random ports */
+#define LEASE_RETRY 60        /* on error, retry writing leasefile after LEASE_RETRY seconds */
+#define CACHESIZ 150          /* default cache size */
+#define MAXLEASES 150         /* maximum number of DHCP leases */
+#define PING_WAIT 3           /* wait for ping address-in-use test */
+#define PING_CACHE_TIME 30    /* Ping test assumed to be valid this long. */
+#define DECLINE_BACKOFF 600   /* disable DECLINEd static addresses for this long */
 #define DHCP_PACKET_MAX 16384 /* hard limit on DHCP packet size */
-#define SMALLDNAME 40 /* most domain names are smaller than this */
+#define SMALLDNAME 40         /* most domain names are smaller than this */
 #define HOSTSFILE "/etc/hosts"
 #ifdef __uClinux__
-#  define RESOLVFILE "/etc/config/resolv.conf"
+#define RESOLVFILE "/etc/config/resolv.conf"
 #else
-#  define RESOLVFILE "/etc/resolv.conf"
+#define RESOLVFILE "/etc/resolv.conf"
 #endif
 #define RUNFILE "/var/run/dnsmasq.pid"
 
 #ifndef LEASEFILE
-#   if defined(__FreeBSD__) || defined (__OpenBSD__) || defined(__DragonFly__) || defined(__NetBSD__)
-#      define LEASEFILE "/var/db/dnsmasq.leases"
-#   elif defined(__sun__) || defined (__sun)
-#      define LEASEFILE "/var/cache/dnsmasq.leases"
-#   elif defined(__ANDROID__)
-#      define LEASEFILE "/data/misc/dhcp/dnsmasq.leases"
-#   else
-#      define LEASEFILE "/var/lib/misc/dnsmasq.leases"
-#   endif
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__NetBSD__)
+#define LEASEFILE "/var/db/dnsmasq.leases"
+#elif defined(__sun__) || defined(__sun)
+#define LEASEFILE "/var/cache/dnsmasq.leases"
+#elif defined(__ANDROID__)
+#define LEASEFILE "/data/misc/dhcp/dnsmasq.leases"
+#else
+#define LEASEFILE "/var/lib/misc/dnsmasq.leases"
+#endif
 #endif
 
 #ifndef CONFFILE
-#   if defined(__FreeBSD__)
-#      define CONFFILE "/usr/local/etc/dnsmasq.conf"
-#   else
-#      define CONFFILE "/etc/dnsmasq.conf"
-#   endif
+#if defined(__FreeBSD__)
+#define CONFFILE "/usr/local/etc/dnsmasq.conf"
+#else
+#define CONFFILE "/etc/dnsmasq.conf"
+#endif
 #endif
 
 #define DEFLEASE 3600 /* default lease time, 1 hour */
@@ -74,29 +74,28 @@
 /* A small collection of RR-types which are missing on some platforms */
 
 #ifndef T_SIG
-#  define T_SIG 24
+#define T_SIG 24
 #endif
 
 #ifndef T_SRV
-#  define T_SRV 33
+#define T_SRV 33
 #endif
 
 #ifndef T_OPT
-#  define T_OPT 41
+#define T_OPT 41
 #endif
 
 #ifndef T_TKEY
-#  define T_TKEY 249
+#define T_TKEY 249
 #endif
 
 #ifndef T_TSIG
-#  define T_TSIG 250
+#define T_TSIG 250
 #endif
 
-
-/* Follows system specific switches. If you run on a 
-   new system, you may want to edit these. 
-   May replace this with Autoconf one day. 
+/* Follows system specific switches. If you run on a
+   new system, you may want to edit these.
+   May replace this with Autoconf one day.
 
 HAVE_LINUX_NETWORK
 HAVE_BSD_NETWORK
@@ -109,9 +108,9 @@
    for timing, and keep lease lengths rather than expiry times
    in its leases file. This also make dnsmasq "flash disk friendly".
    Normally, dnsmasq tries very hard to keep the on-disk leases file
-   up-to-date: rewriting it after every renewal.  When HAVE_BROKEN_RTC 
-   is in effect, the lease file is only written when a new lease is 
-   created, or an old one destroyed. (Because those are the only times 
+   up-to-date: rewriting it after every renewal.  When HAVE_BROKEN_RTC
+   is in effect, the lease file is only written when a new lease is
+   created, or an old one destroyed. (Because those are the only times
    it changes.) This vastly reduces the number of file writes, and makes
    it viable to keep the lease file on a flash filesystem.
    NOTE: when enabling or disabling this, be sure to delete any old
@@ -124,30 +123,30 @@
    define this to get the ability to call scripts on lease-change
 
 HAVE_GETOPT_LONG
-   define this if you have GNU libc or GNU getopt. 
+   define this if you have GNU libc or GNU getopt.
 
 HAVE_ARC4RANDOM
    define this if you have arc4random() to get better security from DNS spoofs
-   by using really random ids (OpenBSD) 
+   by using really random ids (OpenBSD)
 
 HAVE_SOCKADDR_SA_LEN
-   define this if struct sockaddr has sa_len field (*BSD) 
+   define this if struct sockaddr has sa_len field (*BSD)
 
 NOTES:
-   For Linux you should define 
+   For Linux you should define
       HAVE_LINUX_NETWORK
       HAVE_GETOPT_LONG
-  you should NOT define 
+  you should NOT define
       HAVE_ARC4RANDOM
       HAVE_SOCKADDR_SA_LEN
 
-   For *BSD systems you should define 
+   For *BSD systems you should define
      HAVE_BSD_NETWORK
      HAVE_SOCKADDR_SA_LEN
-   and you MAY define  
+   and you MAY define
      HAVE_ARC4RANDOM - OpenBSD and FreeBSD and NetBSD version 2.0 or later
-     HAVE_GETOPT_LONG - NetBSD, later FreeBSD 
-                       (FreeBSD and OpenBSD only if you link GNU getopt) 
+     HAVE_GETOPT_LONG - NetBSD, later FreeBSD
+                       (FreeBSD and OpenBSD only if you link GNU getopt)
 
 */
 
@@ -166,8 +165,6 @@
 #undef HAVE_SCRIPT
 #endif
 
-
-
 /* platform dependent options. */
 
 /* Must preceed __linux__ since uClinux defines __linux__ too. */
@@ -177,7 +174,7 @@
 #undef HAVE_ARC4RANDOM
 #undef HAVE_SOCKADDR_SA_LEN
 /* Never use fork() on uClinux. Note that this is subtly different from the
-   --keep-in-foreground option, since it also  suppresses forking new 
+   --keep-in-foreground option, since it also  suppresses forking new
    processes for TCP connections and disables the call-a-script on leasechange
    system. It's intended for use on MMU-less kernels. */
 #define NO_FORK
@@ -185,18 +182,18 @@
 #elif defined(__UCLIBC__)
 #define HAVE_LINUX_NETWORK
 #if defined(__UCLIBC_HAS_GNU_GETOPT__) || \
-   ((__UCLIBC_MAJOR__==0) && (__UCLIBC_MINOR__==9) && (__UCLIBC_SUBLEVEL__<21))
-#    define HAVE_GETOPT_LONG
+    ((__UCLIBC_MAJOR__ == 0) && (__UCLIBC_MINOR__ == 9) && (__UCLIBC_SUBLEVEL__ < 21))
+#define HAVE_GETOPT_LONG
 #endif
 #undef HAVE_ARC4RANDOM
 #undef HAVE_SOCKADDR_SA_LEN
 #if !defined(__ARCH_HAS_MMU__) && !defined(__UCLIBC_HAS_MMU__)
-#  define NO_FORK
+#define NO_FORK
 #endif
 #if defined(__UCLIBC_HAS_IPV6__)
-#  ifndef IPV6_V6ONLY
-#    define IPV6_V6ONLY 26
-#  endif
+#ifndef IPV6_V6ONLY
+#define IPV6_V6ONLY 26
+#endif
 #endif
 
 /* This is for glibc 2.x */
@@ -206,17 +203,15 @@
 #undef HAVE_ARC4RANDOM
 #undef HAVE_SOCKADDR_SA_LEN
 
-#elif defined(__FreeBSD__) || \
-      defined(__OpenBSD__) || \
-      defined(__DragonFly__) || \
-      defined (__FreeBSD_kernel__)
+#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || \
+    defined(__FreeBSD_kernel__)
 #define HAVE_BSD_NETWORK
 /* Later verions of FreeBSD have getopt_long() */
 #if defined(optional_argument) && defined(required_argument)
-#   define HAVE_GETOPT_LONG
+#define HAVE_GETOPT_LONG
 #endif
-#if !defined (__FreeBSD_kernel__)
-#   define HAVE_ARC4RANDOM
+#if !defined(__FreeBSD_kernel__)
+#define HAVE_ARC4RANDOM
 #endif
 #define HAVE_SOCKADDR_SA_LEN
 
@@ -227,7 +222,7 @@
 #define HAVE_SOCKADDR_SA_LEN
 /* Define before sys/socket.h is included so we get socklen_t */
 #define _BSD_SOCKLEN_T_
- 
+
 #elif defined(__NetBSD__)
 #define HAVE_BSD_NETWORK
 #define HAVE_GETOPT_LONG
@@ -241,8 +236,8 @@
 #undef HAVE_SOCKADDR_SA_LEN
 #define _XPG4_2
 #define __EXTENSIONS__
-#define ETHER_ADDR_LEN 6 
- 
+#define ETHER_ADDR_LEN 6
+
 #endif
 
 /* Decide if we're going to support IPv6 */
@@ -251,23 +246,22 @@
    headers don't have ntop and pton either */
 
 #if defined(INET6_ADDRSTRLEN) && defined(IPV6_V6ONLY) && !defined(NO_IPV6)
-#  define HAVE_IPV6
-#  define ADDRSTRLEN INET6_ADDRSTRLEN
-#  if defined(SOL_IPV6)
-#    define IPV6_LEVEL SOL_IPV6
-#  else
-#    define IPV6_LEVEL IPPROTO_IPV6
-#  endif
-#elif defined(INET_ADDRSTRLEN)
-#  undef HAVE_IPV6
-#  define ADDRSTRLEN INET_ADDRSTRLEN
+#define HAVE_IPV6
+#define ADDRSTRLEN INET6_ADDRSTRLEN
+#if defined(SOL_IPV6)
+#define IPV6_LEVEL SOL_IPV6
 #else
-#  undef HAVE_IPV6
-#  define ADDRSTRLEN 16 /* 4*3 + 3 dots + NULL */
+#define IPV6_LEVEL IPPROTO_IPV6
+#endif
+#elif defined(INET_ADDRSTRLEN)
+#undef HAVE_IPV6
+#define ADDRSTRLEN INET_ADDRSTRLEN
+#else
+#undef HAVE_IPV6
+#define ADDRSTRLEN 16 /* 4*3 + 3 dots + NULL */
 #endif
 
 /* Can't do scripts without fork */
 #ifdef NOFORK
-#  undef HAVE_SCRIPT
+#undef HAVE_SCRIPT
 #endif
-
diff --git a/src/dhcp.c b/src/dhcp.c
index 82075fd..e5c47b2 100644
--- a/src/dhcp.c
+++ b/src/dhcp.c
@@ -4,12 +4,12 @@
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; version 2 dated June, 1991, or
    (at your option) version 3 dated 29 June, 2007.
- 
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-     
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
@@ -19,755 +19,656 @@
 #ifdef HAVE_DHCP
 
 struct iface_param {
-  struct in_addr relay, primary;
-  struct dhcp_context *current;
-  int ind;
+    struct in_addr relay, primary;
+    struct dhcp_context* current;
+    int ind;
 };
 
-static int complete_context(struct in_addr local, int if_index, 
-			    struct in_addr netmask, struct in_addr broadcast, void *vparam);
+static int complete_context(struct in_addr local, int if_index, struct in_addr netmask,
+                            struct in_addr broadcast, void* vparam);
 
-void dhcp_init(void)
-{
-  int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
-  struct sockaddr_in saddr;
-  int oneopt = 1;
+void dhcp_init(void) {
+    int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+    struct sockaddr_in saddr;
+    int oneopt = 1;
 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
-  int mtu = IP_PMTUDISC_DONT;
+    int mtu = IP_PMTUDISC_DONT;
 #endif
 
-  if (fd == -1)
-    die (_("cannot create DHCP socket: %s"), NULL, EC_BADNET);
-  
-  if (!fix_fd(fd) ||
+    if (fd == -1) die(_("cannot create DHCP socket: %s"), NULL, EC_BADNET);
+
+    if (!fix_fd(fd) ||
 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
-      setsockopt(fd, SOL_IP, IP_MTU_DISCOVER, &mtu, sizeof(mtu)) == -1 ||
+        setsockopt(fd, SOL_IP, IP_MTU_DISCOVER, &mtu, sizeof(mtu)) == -1 ||
 #endif
 #if defined(HAVE_LINUX_NETWORK)
-      setsockopt(fd, SOL_IP, IP_PKTINFO, &oneopt, sizeof(oneopt)) == -1 ||
+        setsockopt(fd, SOL_IP, IP_PKTINFO, &oneopt, sizeof(oneopt)) == -1 ||
 #else
-      setsockopt(fd, IPPROTO_IP, IP_RECVIF, &oneopt, sizeof(oneopt)) == -1 ||
+        setsockopt(fd, IPPROTO_IP, IP_RECVIF, &oneopt, sizeof(oneopt)) == -1 ||
 #endif
-      setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &oneopt, sizeof(oneopt)) == -1)  
-    die(_("failed to set options on DHCP socket: %s"), NULL, EC_BADNET);
-  
-  /* When bind-interfaces is set, there might be more than one dnmsasq
-     instance binding port 67. That's OK if they serve different networks.
-     Need to set REUSEADDR to make this posible, or REUSEPORT on *BSD. */
-  if (daemon->options & OPT_NOWILD)
-    {
-#ifdef SO_REUSEPORT
-      int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, sizeof(oneopt));
-#else
-      int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &oneopt, sizeof(oneopt));
-#endif
-      if (rc == -1)
-	die(_("failed to set SO_REUSE{ADDR|PORT} on DHCP socket: %s"), NULL, EC_BADNET);
-    }
-  
-  memset(&saddr, 0, sizeof(saddr));
-  saddr.sin_family = AF_INET;
-  saddr.sin_port = htons(daemon->dhcp_server_port);
-  saddr.sin_addr.s_addr = INADDR_ANY;
+        setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &oneopt, sizeof(oneopt)) == -1)
+        die(_("failed to set options on DHCP socket: %s"), NULL, EC_BADNET);
 
-  if (bind(fd, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in)))
-    die(_("failed to bind DHCP server socket: %s"), NULL, EC_BADNET);
+    /* When bind-interfaces is set, there might be more than one dnmsasq
+       instance binding port 67. That's OK if they serve different networks.
+       Need to set REUSEADDR to make this posible, or REUSEPORT on *BSD. */
+    if (daemon->options & OPT_NOWILD) {
+#ifdef SO_REUSEPORT
+        int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, sizeof(oneopt));
+#else
+        int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &oneopt, sizeof(oneopt));
+#endif
+        if (rc == -1)
+            die(_("failed to set SO_REUSE{ADDR|PORT} on DHCP socket: %s"), NULL, EC_BADNET);
+    }
+
+    memset(&saddr, 0, sizeof(saddr));
+    saddr.sin_family = AF_INET;
+    saddr.sin_port = htons(daemon->dhcp_server_port);
+    saddr.sin_addr.s_addr = INADDR_ANY;
+
+    if (bind(fd, (struct sockaddr*) &saddr, sizeof(struct sockaddr_in)))
+        die(_("failed to bind DHCP server socket: %s"), NULL, EC_BADNET);
 
 #ifdef __ANDROID__
-  if (setsockopt(fd, SOL_SOCKET, SO_MARK, &daemon->listen_mark, sizeof(daemon->listen_mark)) == -1)
-    die(_("failed to set DHCP socket mark: %s"), NULL, EC_BADNET);
+    if (setsockopt(fd, SOL_SOCKET, SO_MARK, &daemon->listen_mark, sizeof(daemon->listen_mark)) == -1)
+        die(_("failed to set DHCP socket mark: %s"), NULL, EC_BADNET);
 #endif /* __ANDROID__ */
 
-  daemon->dhcpfd = fd;
+    daemon->dhcpfd = fd;
 
-  check_dhcp_hosts(1);
+    check_dhcp_hosts(1);
 
-  daemon->dhcp_packet.iov_len = sizeof(struct dhcp_packet);
-  daemon->dhcp_packet.iov_base = safe_malloc(daemon->dhcp_packet.iov_len);
+    daemon->dhcp_packet.iov_len = sizeof(struct dhcp_packet);
+    daemon->dhcp_packet.iov_base = safe_malloc(daemon->dhcp_packet.iov_len);
 }
-  
-void dhcp_packet(time_t now)
-{
-  struct dhcp_packet *mess;
-  struct dhcp_context *context;
-  struct iname *tmp;
-  struct ifreq ifr;
-  struct msghdr msg;
-  struct sockaddr_in dest;
-  struct cmsghdr *cmptr;
-  struct iovec iov;
-  ssize_t sz; 
-  int iface_index = 0, unicast_dest = 0, is_inform = 0;
-  struct in_addr iface_addr, *addrp = NULL;
-  struct iface_param parm;
 
-  union {
-    struct cmsghdr align; /* this ensures alignment */
+void dhcp_packet(time_t now) {
+    struct dhcp_packet* mess;
+    struct dhcp_context* context;
+    struct iname* tmp;
+    struct ifreq ifr;
+    struct msghdr msg;
+    struct sockaddr_in dest;
+    struct cmsghdr* cmptr;
+    struct iovec iov;
+    ssize_t sz;
+    int iface_index = 0, unicast_dest = 0, is_inform = 0;
+    struct in_addr iface_addr, *addrp = NULL;
+    struct iface_param parm;
+
+    union {
+        struct cmsghdr align; /* this ensures alignment */
 #if defined(HAVE_LINUX_NETWORK)
-    char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
+        char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
 #endif
-  } control_u;
-  
-  msg.msg_control = NULL;
-  msg.msg_controllen = 0;
-  msg.msg_name = NULL;
-  msg.msg_namelen = 0;
-  msg.msg_iov = &daemon->dhcp_packet;
-  msg.msg_iovlen = 1;
-  
-  while (1)
-    {
-      msg.msg_flags = 0;
-      while ((sz = recvmsg(daemon->dhcpfd, &msg, MSG_PEEK | MSG_TRUNC)) == -1 && errno == EINTR);
-      
-      if (sz == -1)
-	return;
-      
-      if (!(msg.msg_flags & MSG_TRUNC))
-	break;
+    } control_u;
 
-      /* Very new Linux kernels return the actual size needed, 
-	 older ones always return truncated size */
-      if ((size_t)sz == daemon->dhcp_packet.iov_len)
-	{
-	  if (!expand_buf(&daemon->dhcp_packet, sz + 100))
-	    return;
-	}
-      else
-	{
-	  expand_buf(&daemon->dhcp_packet, sz);
-	  break;
-	}
+    msg.msg_control = NULL;
+    msg.msg_controllen = 0;
+    msg.msg_name = NULL;
+    msg.msg_namelen = 0;
+    msg.msg_iov = &daemon->dhcp_packet;
+    msg.msg_iovlen = 1;
+
+    while (1) {
+        msg.msg_flags = 0;
+        while ((sz = recvmsg(daemon->dhcpfd, &msg, MSG_PEEK | MSG_TRUNC)) == -1 && errno == EINTR)
+            ;
+
+        if (sz == -1) return;
+
+        if (!(msg.msg_flags & MSG_TRUNC)) break;
+
+        /* Very new Linux kernels return the actual size needed,
+       older ones always return truncated size */
+        if ((size_t) sz == daemon->dhcp_packet.iov_len) {
+            if (!expand_buf(&daemon->dhcp_packet, sz + 100)) return;
+        } else {
+            expand_buf(&daemon->dhcp_packet, sz);
+            break;
+        }
     }
-  
-  /* expand_buf may have moved buffer */
-  mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base;
-  msg.msg_controllen = sizeof(control_u);
-  msg.msg_control = control_u.control;
-  msg.msg_flags = 0;
-  msg.msg_name = &dest;
-  msg.msg_namelen = sizeof(dest);
 
-  while ((sz = recvmsg(daemon->dhcpfd, &msg, 0)) == -1 && errno == EINTR);
+    /* expand_buf may have moved buffer */
+    mess = (struct dhcp_packet*) daemon->dhcp_packet.iov_base;
+    msg.msg_controllen = sizeof(control_u);
+    msg.msg_control = control_u.control;
+    msg.msg_flags = 0;
+    msg.msg_name = &dest;
+    msg.msg_namelen = sizeof(dest);
 
-  if ((msg.msg_flags & MSG_TRUNC) || sz < (ssize_t)(sizeof(*mess) - sizeof(mess->options)))
-    return;
+    while ((sz = recvmsg(daemon->dhcpfd, &msg, 0)) == -1 && errno == EINTR)
+        ;
 
-#if defined (HAVE_LINUX_NETWORK)
-  if (msg.msg_controllen >= sizeof(struct cmsghdr))
-    for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
-      if (cmptr->cmsg_level == SOL_IP && cmptr->cmsg_type == IP_PKTINFO)
-	{
-	  iface_index = ((struct in_pktinfo *)CMSG_DATA(cmptr))->ipi_ifindex;
-	  if (((struct in_pktinfo *)CMSG_DATA(cmptr))->ipi_addr.s_addr != INADDR_BROADCAST)
-	    unicast_dest = 1;
-	}
+    if ((msg.msg_flags & MSG_TRUNC) || sz < (ssize_t)(sizeof(*mess) - sizeof(mess->options)))
+        return;
+
+#if defined(HAVE_LINUX_NETWORK)
+    if (msg.msg_controllen >= sizeof(struct cmsghdr))
+        for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
+            if (cmptr->cmsg_level == SOL_IP && cmptr->cmsg_type == IP_PKTINFO) {
+                iface_index = ((struct in_pktinfo*) CMSG_DATA(cmptr))->ipi_ifindex;
+                if (((struct in_pktinfo*) CMSG_DATA(cmptr))->ipi_addr.s_addr != INADDR_BROADCAST)
+                    unicast_dest = 1;
+            }
 #endif
 
-  if (!indextoname(daemon->dhcpfd, iface_index, ifr.ifr_name))
-    return;
+    if (!indextoname(daemon->dhcpfd, iface_index, ifr.ifr_name)) return;
 
 #ifdef MSG_BCAST
-  /* OpenBSD tells us when a packet was broadcast */
-  if (!(msg.msg_flags & MSG_BCAST))
-    unicast_dest = 1;
+    /* OpenBSD tells us when a packet was broadcast */
+    if (!(msg.msg_flags & MSG_BCAST)) unicast_dest = 1;
 #endif
 
-  ifr.ifr_addr.sa_family = AF_INET;
-  if (ioctl(daemon->dhcpfd, SIOCGIFADDR, &ifr) != -1 )
-    {
-      addrp = &iface_addr;
-      iface_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
+    ifr.ifr_addr.sa_family = AF_INET;
+    if (ioctl(daemon->dhcpfd, SIOCGIFADDR, &ifr) != -1) {
+        addrp = &iface_addr;
+        iface_addr = ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr;
     }
 
-  if (!iface_check(AF_INET, (struct all_addr *)addrp, ifr.ifr_name, &iface_index))
-    return;
-  
-  for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
-    if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
-      return;
-  
-  /* interface may have been changed by alias in iface_check */
-  if (!addrp)
-    {
-      if (ioctl(daemon->dhcpfd, SIOCGIFADDR, &ifr) == -1)
-	{
-	  my_syslog(MS_DHCP | LOG_WARNING, _("DHCP packet received on %s which has no address"), ifr.ifr_name);
-	  return;
-	}
-      else
-	iface_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
-    }
-  
-  /* unlinked contexts are marked by context->current == context */
-  for (context = daemon->dhcp; context; context = context->next)
-    context->current = context;
-  
-  parm.relay = mess->giaddr;
-  parm.primary = iface_addr;
-  parm.current = NULL;
-  parm.ind = iface_index;
+    if (!iface_check(AF_INET, (struct all_addr*) addrp, ifr.ifr_name, &iface_index)) return;
 
-  if (!iface_enumerate(&parm, complete_context, NULL))
-    return;
-  lease_prune(NULL, now); /* lose any expired leases */
-  iov.iov_len = dhcp_reply(parm.current, ifr.ifr_name, iface_index, (size_t)sz, 
-			   now, unicast_dest, &is_inform);
-  lease_update_file(now);
-  lease_update_dns();
-    
-  if (iov.iov_len == 0)
-    return;
-  
-  msg.msg_name = &dest;
-  msg.msg_namelen = sizeof(dest);
-  msg.msg_control = NULL;
-  msg.msg_controllen = 0;
-  msg.msg_iov = &iov;
-  iov.iov_base = daemon->dhcp_packet.iov_base;
-  
-  /* packet buffer may have moved */
-  mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base;
+    for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
+        if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0)) return;
 
-  if (mess->giaddr.s_addr)
-    {
-      /* Send to BOOTP relay  */
-      dest.sin_port = htons(daemon->dhcp_server_port);
-      dest.sin_addr = mess->giaddr; 
+    /* interface may have been changed by alias in iface_check */
+    if (!addrp) {
+        if (ioctl(daemon->dhcpfd, SIOCGIFADDR, &ifr) == -1) {
+            my_syslog(MS_DHCP | LOG_WARNING, _("DHCP packet received on %s which has no address"),
+                      ifr.ifr_name);
+            return;
+        } else
+            iface_addr = ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr;
     }
-  else if (mess->ciaddr.s_addr)
-    {
-      /* If the client's idea of its own address tallys with
-	 the source address in the request packet, we believe the
-	 source port too, and send back to that.  If we're replying 
-	 to a DHCPINFORM, trust the source address always. */
-      if ((!is_inform && dest.sin_addr.s_addr != mess->ciaddr.s_addr) ||
-	  dest.sin_port == 0 || dest.sin_addr.s_addr == 0)
-	{
-	  dest.sin_port = htons(daemon->dhcp_client_port); 
-	  dest.sin_addr = mess->ciaddr;
-	}
-    } 
+
+    /* unlinked contexts are marked by context->current == context */
+    for (context = daemon->dhcp; context; context = context->next) context->current = context;
+
+    parm.relay = mess->giaddr;
+    parm.primary = iface_addr;
+    parm.current = NULL;
+    parm.ind = iface_index;
+
+    if (!iface_enumerate(&parm, complete_context, NULL)) return;
+    lease_prune(NULL, now); /* lose any expired leases */
+    iov.iov_len = dhcp_reply(parm.current, ifr.ifr_name, iface_index, (size_t) sz, now,
+                             unicast_dest, &is_inform);
+    lease_update_file(now);
+    lease_update_dns();
+
+    if (iov.iov_len == 0) return;
+
+    msg.msg_name = &dest;
+    msg.msg_namelen = sizeof(dest);
+    msg.msg_control = NULL;
+    msg.msg_controllen = 0;
+    msg.msg_iov = &iov;
+    iov.iov_base = daemon->dhcp_packet.iov_base;
+
+    /* packet buffer may have moved */
+    mess = (struct dhcp_packet*) daemon->dhcp_packet.iov_base;
+
+    if (mess->giaddr.s_addr) {
+        /* Send to BOOTP relay  */
+        dest.sin_port = htons(daemon->dhcp_server_port);
+        dest.sin_addr = mess->giaddr;
+    } else if (mess->ciaddr.s_addr) {
+        /* If the client's idea of its own address tallys with
+       the source address in the request packet, we believe the
+       source port too, and send back to that.  If we're replying
+       to a DHCPINFORM, trust the source address always. */
+        if ((!is_inform && dest.sin_addr.s_addr != mess->ciaddr.s_addr) || dest.sin_port == 0 ||
+            dest.sin_addr.s_addr == 0) {
+            dest.sin_port = htons(daemon->dhcp_client_port);
+            dest.sin_addr = mess->ciaddr;
+        }
+    }
 #if defined(HAVE_LINUX_NETWORK)
-  else if ((ntohs(mess->flags) & 0x8000) || mess->hlen == 0 ||
-	   mess->hlen > sizeof(ifr.ifr_addr.sa_data) || mess->htype == 0)
-    {
-      /* broadcast to 255.255.255.255 (or mac address invalid) */
-      struct in_pktinfo *pkt;
-      msg.msg_control = control_u.control;
-      msg.msg_controllen = sizeof(control_u);
-      cmptr = CMSG_FIRSTHDR(&msg);
-      pkt = (struct in_pktinfo *)CMSG_DATA(cmptr);
-      pkt->ipi_ifindex = iface_index;
-      pkt->ipi_spec_dst.s_addr = 0;
-      msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
-      cmptr->cmsg_level = SOL_IP;
-      cmptr->cmsg_type = IP_PKTINFO;  
-      dest.sin_addr.s_addr = INADDR_BROADCAST;
-      dest.sin_port = htons(daemon->dhcp_client_port);
-    }
-  else
-    {
-      /* unicast to unconfigured client. Inject mac address direct into ARP cache. 
-	 struct sockaddr limits size to 14 bytes. */
-      struct arpreq req;
-      dest.sin_addr = mess->yiaddr;
-      dest.sin_port = htons(daemon->dhcp_client_port);
-      *((struct sockaddr_in *)&req.arp_pa) = dest;
-      req.arp_ha.sa_family = mess->htype;
-      memcpy(req.arp_ha.sa_data, mess->chaddr, mess->hlen);
-      strncpy(req.arp_dev, ifr.ifr_name, 16);
-      req.arp_flags = ATF_COM;
-      ioctl(daemon->dhcpfd, SIOCSARP, &req);
+    else if ((ntohs(mess->flags) & 0x8000) || mess->hlen == 0 ||
+             mess->hlen > sizeof(ifr.ifr_addr.sa_data) || mess->htype == 0) {
+        /* broadcast to 255.255.255.255 (or mac address invalid) */
+        struct in_pktinfo* pkt;
+        msg.msg_control = control_u.control;
+        msg.msg_controllen = sizeof(control_u);
+        cmptr = CMSG_FIRSTHDR(&msg);
+        pkt = (struct in_pktinfo*) CMSG_DATA(cmptr);
+        pkt->ipi_ifindex = iface_index;
+        pkt->ipi_spec_dst.s_addr = 0;
+        msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
+        cmptr->cmsg_level = SOL_IP;
+        cmptr->cmsg_type = IP_PKTINFO;
+        dest.sin_addr.s_addr = INADDR_BROADCAST;
+        dest.sin_port = htons(daemon->dhcp_client_port);
+    } else {
+        /* unicast to unconfigured client. Inject mac address direct into ARP cache.
+       struct sockaddr limits size to 14 bytes. */
+        struct arpreq req;
+        dest.sin_addr = mess->yiaddr;
+        dest.sin_port = htons(daemon->dhcp_client_port);
+        *((struct sockaddr_in*) &req.arp_pa) = dest;
+        req.arp_ha.sa_family = mess->htype;
+        memcpy(req.arp_ha.sa_data, mess->chaddr, mess->hlen);
+        strncpy(req.arp_dev, ifr.ifr_name, 16);
+        req.arp_flags = ATF_COM;
+        ioctl(daemon->dhcpfd, SIOCSARP, &req);
     }
 #endif
 
-  while(sendmsg(daemon->dhcpfd, &msg, 0) == -1 && retry_send());
+    while (sendmsg(daemon->dhcpfd, &msg, 0) == -1 && retry_send())
+        ;
 }
- 
-/* This is a complex routine: it gets called with each (address,netmask,broadcast) triple 
+
+/* This is a complex routine: it gets called with each (address,netmask,broadcast) triple
    of each interface (and any relay address) and does the  following things:
 
    1) Discards stuff for interfaces other than the one on which a DHCP packet just arrived.
    2) Fills in any netmask and broadcast addresses which have not been explicitly configured.
    3) Fills in local (this host) and router (this host or relay) addresses.
-   4) Links contexts which are valid for hosts directly connected to the arrival interface on ->current.
+   4) Links contexts which are valid for hosts directly connected to the arrival interface on
+   ->current.
 
-   Note that the current chain may be superceded later for configured hosts or those coming via gateways. */
+   Note that the current chain may be superceded later for configured hosts or those coming via
+   gateways. */
 
-static int complete_context(struct in_addr local, int if_index, 
-			    struct in_addr netmask, struct in_addr broadcast, void *vparam)
-{
-  struct dhcp_context *context;
-  struct iface_param *param = vparam;
-  
-  for (context = daemon->dhcp; context; context = context->next)
-    {
-      if (!(context->flags & CONTEXT_NETMASK) &&
-	  (is_same_net(local, context->start, netmask) ||
-	   is_same_net(local, context->end, netmask)))
-      { 
-	if (context->netmask.s_addr != netmask.s_addr &&
-	    !(is_same_net(local, context->start, netmask) &&
-	      is_same_net(local, context->end, netmask)))
-	  {
-	    strcpy(daemon->dhcp_buff, inet_ntoa(context->start));
-	    strcpy(daemon->dhcp_buff2, inet_ntoa(context->end));
-	    my_syslog(MS_DHCP | LOG_WARNING, _("DHCP range %s -- %s is not consistent with netmask %s"),
-		      daemon->dhcp_buff, daemon->dhcp_buff2, inet_ntoa(netmask));
-	  }	
- 	context->netmask = netmask;
-      }
-      
-      if (context->netmask.s_addr)
-	{
-	  if (is_same_net(local, context->start, context->netmask) &&
-	      is_same_net(local, context->end, context->netmask))
-	    {
-	      /* link it onto the current chain if we've not seen it before */
-	      if (if_index == param->ind && context->current == context)
-		{
-		  context->router = local;
-		  context->local = local;
-		  context->current = param->current;
-		  param->current = context;
-		}
-	      
-	      if (!(context->flags & CONTEXT_BRDCAST))
-		{
-		  if (is_same_net(broadcast, context->start, context->netmask))
-		    context->broadcast = broadcast;
-		  else 
-		    context->broadcast.s_addr  = context->start.s_addr | ~context->netmask.s_addr;
-		}
-	    }	
-	  else if (param->relay.s_addr && is_same_net(param->relay, context->start, context->netmask))
-	    {
-	      context->router = param->relay;
-	      context->local = param->primary;
-	      /* fill in missing broadcast addresses for relayed ranges */
-	      if (!(context->flags & CONTEXT_BRDCAST))
-		context->broadcast.s_addr  = context->start.s_addr | ~context->netmask.s_addr;
-	    }
+static int complete_context(struct in_addr local, int if_index, struct in_addr netmask,
+                            struct in_addr broadcast, void* vparam) {
+    struct dhcp_context* context;
+    struct iface_param* param = vparam;
 
-	}
+    for (context = daemon->dhcp; context; context = context->next) {
+        if (!(context->flags & CONTEXT_NETMASK) && (is_same_net(local, context->start, netmask) ||
+                                                    is_same_net(local, context->end, netmask))) {
+            if (context->netmask.s_addr != netmask.s_addr &&
+                !(is_same_net(local, context->start, netmask) &&
+                  is_same_net(local, context->end, netmask))) {
+                strcpy(daemon->dhcp_buff, inet_ntoa(context->start));
+                strcpy(daemon->dhcp_buff2, inet_ntoa(context->end));
+                my_syslog(MS_DHCP | LOG_WARNING,
+                          _("DHCP range %s -- %s is not consistent with netmask %s"),
+                          daemon->dhcp_buff, daemon->dhcp_buff2, inet_ntoa(netmask));
+            }
+            context->netmask = netmask;
+        }
+
+        if (context->netmask.s_addr) {
+            if (is_same_net(local, context->start, context->netmask) &&
+                is_same_net(local, context->end, context->netmask)) {
+                /* link it onto the current chain if we've not seen it before */
+                if (if_index == param->ind && context->current == context) {
+                    context->router = local;
+                    context->local = local;
+                    context->current = param->current;
+                    param->current = context;
+                }
+
+                if (!(context->flags & CONTEXT_BRDCAST)) {
+                    if (is_same_net(broadcast, context->start, context->netmask))
+                        context->broadcast = broadcast;
+                    else
+                        context->broadcast.s_addr = context->start.s_addr | ~context->netmask.s_addr;
+                }
+            } else if (param->relay.s_addr &&
+                       is_same_net(param->relay, context->start, context->netmask)) {
+                context->router = param->relay;
+                context->local = param->primary;
+                /* fill in missing broadcast addresses for relayed ranges */
+                if (!(context->flags & CONTEXT_BRDCAST))
+                    context->broadcast.s_addr = context->start.s_addr | ~context->netmask.s_addr;
+            }
+        }
     }
 
-  return 1;
-}
-	  
-struct dhcp_context *address_available(struct dhcp_context *context, 
-				       struct in_addr taddr,
-				       struct dhcp_netid *netids)
-{
-  /* Check is an address is OK for this network, check all
-     possible ranges. Make sure that the address isn't in use
-     by the server itself. */
-  
-  unsigned int start, end, addr = ntohl(taddr.s_addr);
-  struct dhcp_context *tmp;
-
-  for (tmp = context; tmp; tmp = tmp->current)
-    if (taddr.s_addr == context->router.s_addr)
-      return NULL;
-  
-  for (tmp = context; tmp; tmp = tmp->current)
-    {
-      start = ntohl(tmp->start.s_addr);
-      end = ntohl(tmp->end.s_addr);
-
-      if (!(tmp->flags & CONTEXT_STATIC) &&
-	  addr >= start &&
-	  addr <= end &&
-	  match_netid(tmp->filter, netids, 1))
-	return tmp;
-    }
-
-  return NULL;
-}
-
-struct dhcp_context *narrow_context(struct dhcp_context *context, 
-				    struct in_addr taddr,
-				    struct dhcp_netid *netids)
-{
-  /* We start of with a set of possible contexts, all on the current physical interface.
-     These are chained on ->current.
-     Here we have an address, and return the actual context correponding to that
-     address. Note that none may fit, if the address came a dhcp-host and is outside
-     any dhcp-range. In that case we return a static range if possible, or failing that,
-     any context on the correct subnet. (If there's more than one, this is a dodgy 
-     configuration: maybe there should be a warning.) */
-  
-  struct dhcp_context *tmp;
-
-  if (!(tmp = address_available(context, taddr, netids)))
-    {
-      for (tmp = context; tmp; tmp = tmp->current)
-	if (is_same_net(taddr, tmp->start, tmp->netmask) && 
-	    (tmp->flags & CONTEXT_STATIC))
-	  break;
-      
-      if (!tmp)
-	for (tmp = context; tmp; tmp = tmp->current)
-	  if (is_same_net(taddr, tmp->start, tmp->netmask))
-	    break;
-    }
-  
-  /* Only one context allowed now */
-  if (tmp)
-    tmp->current = NULL;
-  
-  return tmp;
-}
-
-struct dhcp_config *config_find_by_address(struct dhcp_config *configs, struct in_addr addr)
-{
-  struct dhcp_config *config;
-  
-  for (config = configs; config; config = config->next)
-    if ((config->flags & CONFIG_ADDR) && config->addr.s_addr == addr.s_addr)
-      return config;
-
-  return NULL;
-}
-
-/* Is every member of check matched by a member of pool? 
-   If tagnotneeded, untagged is OK */
-int match_netid(struct dhcp_netid *check, struct dhcp_netid *pool, int tagnotneeded)
-{
-  struct dhcp_netid *tmp1;
-  
-  if (!check && !tagnotneeded)
-    return 0;
-
-  for (; check; check = check->next)
-    {
-      if (check->net[0] != '#')
-	{
-	  for (tmp1 = pool; tmp1; tmp1 = tmp1->next)
-	    if (strcmp(check->net, tmp1->net) == 0)
-	      break;
-	  if (!tmp1)
-	    return 0;
-	}
-      else
-	for (tmp1 = pool; tmp1; tmp1 = tmp1->next)
-	  if (strcmp((check->net)+1, tmp1->net) == 0)
-	    return 0;
-    }
-  return 1;
-}
-
-int address_allocate(struct dhcp_context *context,
-		     struct in_addr *addrp, unsigned char *hwaddr, int hw_len, 
-		     struct dhcp_netid *netids, time_t now)   
-{
-  /* Find a free address: exclude anything in use and anything allocated to
-     a particular hwaddr/clientid/hostname in our configuration.
-     Try to return from contexts which match netids first. */
-
-  struct in_addr start, addr;
-  struct dhcp_context *c, *d;
-  int i, pass;
-  unsigned int j; 
-
-  /* hash hwaddr */
-  for (j = 0, i = 0; i < hw_len; i++)
-    j += hwaddr[i] + (hwaddr[i] << 8) + (hwaddr[i] << 16);
-  
-  for (pass = 0; pass <= 1; pass++)
-    for (c = context; c; c = c->current)
-      if (c->flags & CONTEXT_STATIC)
-	continue;
-      else if (!match_netid(c->filter, netids, pass))
-	continue;
-      else
-	{
-	  /* pick a seed based on hwaddr then iterate until we find a free address. */
-	  start.s_addr = addr.s_addr = 
-	    htonl(ntohl(c->start.s_addr) + 
-		  ((j + c->addr_epoch) % (1 + ntohl(c->end.s_addr) - ntohl(c->start.s_addr))));
-	  
-	  do {
-	    /* eliminate addresses in use by the server. */
-	    for (d = context; d; d = d->current)
-	      if (addr.s_addr == d->router.s_addr)
-		break;
-
-	    /* Addresses which end in .255 and .0 are broken in Windows even when using 
-	       supernetting. ie dhcp-range=192.168.0.1,192.168.1.254,255,255,254.0
-	       then 192.168.0.255 is a valid IP address, but not for Windows as it's
-	       in the class C range. See  KB281579. We therefore don't allocate these 
-	       addresses to avoid hard-to-diagnose problems. Thanks Bill. */	    
-	    if (!d &&
-		!lease_find_by_addr(addr) && 
-		!config_find_by_address(daemon->dhcp_conf, addr) &&
-		(!IN_CLASSC(ntohl(addr.s_addr)) || 
-		 ((ntohl(addr.s_addr) & 0xff) != 0xff && ((ntohl(addr.s_addr) & 0xff) != 0x0))))
-	      {
-		struct ping_result *r, *victim = NULL;
-		int count, max = (int)(0.6 * (((float)PING_CACHE_TIME)/
-					      ((float)PING_WAIT)));
-		
-		*addrp = addr;
-
-		if (daemon->options & OPT_NO_PING)
-		  return 1;
-		
-		/* check if we failed to ping addr sometime in the last
-		   PING_CACHE_TIME seconds. If so, assume the same situation still exists.
-		   This avoids problems when a stupid client bangs
-		   on us repeatedly. As a final check, if we did more
-		   than 60% of the possible ping checks in the last 
-		   PING_CACHE_TIME, we are in high-load mode, so don't do any more. */
-		for (count = 0, r = daemon->ping_results; r; r = r->next)
-		  if (difftime(now, r->time) >  (float)PING_CACHE_TIME)
-		    victim = r; /* old record */
-		  else if (++count == max || r->addr.s_addr == addr.s_addr)
-		    return 1;
-		    
-		if (icmp_ping(addr))
-		  /* address in use: perturb address selection so that we are
-		     less likely to try this address again. */
-		  c->addr_epoch++;
-		else
-		  {
-		    /* at this point victim may hold an expired record */
-		    if (!victim)
-		      {
-			if ((victim = whine_malloc(sizeof(struct ping_result))))
-			  {
-			    victim->next = daemon->ping_results;
-			    daemon->ping_results = victim;
-			  }
-		      }
-		    
-		    /* record that this address is OK for 30s 
-		       without more ping checks */
-		    if (victim)
-		      {
-			victim->addr = addr;
-			victim->time = now;
-		      }
-		    return 1;
-		  }
-	      }
-
-	    addr.s_addr = htonl(ntohl(addr.s_addr) + 1);
-	    
-	    if (addr.s_addr == htonl(ntohl(c->end.s_addr) + 1))
-	      addr = c->start;
-	    
-	  } while (addr.s_addr != start.s_addr);
-	}
-  return 0;
-}
-
-static int is_addr_in_context(struct dhcp_context *context, struct dhcp_config *config)
-{
-  if (!context) /* called via find_config() from lease_update_from_configs() */
-    return 1; 
-  if (!(config->flags & CONFIG_ADDR))
     return 1;
-  for (; context; context = context->current)
-    if (is_same_net(config->addr, context->start, context->netmask))
-      return 1;
-  
-  return 0;
 }
 
-int config_has_mac(struct dhcp_config *config, unsigned char *hwaddr, int len, int type)
-{
-  struct hwaddr_config *conf_addr;
-  
-  for (conf_addr = config->hwaddr; conf_addr; conf_addr = conf_addr->next)
-    if (conf_addr->wildcard_mask == 0 &&
-	conf_addr->hwaddr_len == len &&
-	(conf_addr->hwaddr_type == type || conf_addr->hwaddr_type == 0) &&
-	memcmp(conf_addr->hwaddr, hwaddr, len) == 0)
-      return 1;
-  
-  return 0;
+struct dhcp_context* address_available(struct dhcp_context* context, struct in_addr taddr,
+                                       struct dhcp_netid* netids) {
+    /* Check is an address is OK for this network, check all
+       possible ranges. Make sure that the address isn't in use
+       by the server itself. */
+
+    unsigned int start, end, addr = ntohl(taddr.s_addr);
+    struct dhcp_context* tmp;
+
+    for (tmp = context; tmp; tmp = tmp->current)
+        if (taddr.s_addr == context->router.s_addr) return NULL;
+
+    for (tmp = context; tmp; tmp = tmp->current) {
+        start = ntohl(tmp->start.s_addr);
+        end = ntohl(tmp->end.s_addr);
+
+        if (!(tmp->flags & CONTEXT_STATIC) && addr >= start && addr <= end &&
+            match_netid(tmp->filter, netids, 1))
+            return tmp;
+    }
+
+    return NULL;
 }
 
-struct dhcp_config *find_config(struct dhcp_config *configs,
-				struct dhcp_context *context,
-				unsigned char *clid, int clid_len,
-				unsigned char *hwaddr, int hw_len, 
-				int hw_type, char *hostname)
-{
-  int count, new;
-  struct dhcp_config *config, *candidate; 
-  struct hwaddr_config *conf_addr;
+struct dhcp_context* narrow_context(struct dhcp_context* context, struct in_addr taddr,
+                                    struct dhcp_netid* netids) {
+    /* We start of with a set of possible contexts, all on the current physical interface.
+       These are chained on ->current.
+       Here we have an address, and return the actual context correponding to that
+       address. Note that none may fit, if the address came a dhcp-host and is outside
+       any dhcp-range. In that case we return a static range if possible, or failing that,
+       any context on the correct subnet. (If there's more than one, this is a dodgy
+       configuration: maybe there should be a warning.) */
 
-  if (clid)
+    struct dhcp_context* tmp;
+
+    if (!(tmp = address_available(context, taddr, netids))) {
+        for (tmp = context; tmp; tmp = tmp->current)
+            if (is_same_net(taddr, tmp->start, tmp->netmask) && (tmp->flags & CONTEXT_STATIC))
+                break;
+
+        if (!tmp)
+            for (tmp = context; tmp; tmp = tmp->current)
+                if (is_same_net(taddr, tmp->start, tmp->netmask)) break;
+    }
+
+    /* Only one context allowed now */
+    if (tmp) tmp->current = NULL;
+
+    return tmp;
+}
+
+struct dhcp_config* config_find_by_address(struct dhcp_config* configs, struct in_addr addr) {
+    struct dhcp_config* config;
+
     for (config = configs; config; config = config->next)
-      if (config->flags & CONFIG_CLID)
-	{
-	  if (config->clid_len == clid_len && 
-	      memcmp(config->clid, clid, clid_len) == 0 &&
-	      is_addr_in_context(context, config))
-	    return config;
-	  
-	  /* dhcpcd prefixes ASCII client IDs by zero which is wrong, but we try and
-	     cope with that here */
-	  if (*clid == 0 && config->clid_len == clid_len-1  &&
-	      memcmp(config->clid, clid+1, clid_len-1) == 0 &&
-	      is_addr_in_context(context, config))
-	    return config;
-	}
-  
+        if ((config->flags & CONFIG_ADDR) && config->addr.s_addr == addr.s_addr) return config;
 
-  for (config = configs; config; config = config->next)
-    if (config_has_mac(config, hwaddr, hw_len, hw_type) &&
-	is_addr_in_context(context, config))
-      return config;
-  
-  if (hostname && context)
-    for (config = configs; config; config = config->next)
-      if ((config->flags & CONFIG_NAME) && 
-	  hostname_isequal(config->hostname, hostname) &&
-	  is_addr_in_context(context, config))
-	return config;
-
-  /* use match with fewest wildcast octets */
-  for (candidate = NULL, count = 0, config = configs; config; config = config->next)
-    if (is_addr_in_context(context, config))
-      for (conf_addr = config->hwaddr; conf_addr; conf_addr = conf_addr->next)
-	if (conf_addr->wildcard_mask != 0 &&
-	    conf_addr->hwaddr_len == hw_len &&	
-	    (conf_addr->hwaddr_type == hw_type || conf_addr->hwaddr_type == 0) &&
-	    (new = memcmp_masked(conf_addr->hwaddr, hwaddr, hw_len, conf_addr->wildcard_mask)) > count)
-	  {
-	    count = new;
-	    candidate = config;
-	  }
-
-  return candidate;
+    return NULL;
 }
 
-void check_dhcp_hosts(int fatal)
-{
-  /* If the same IP appears in more than one host config, then DISCOVER
-     for one of the hosts will get the address, but REQUEST will be NAKed,
-     since the address is reserved by the other one -> protocol loop. 
-     Also check that FQDNs match the domain we are using. */
-  
-  struct dhcp_config *configs, *cp;
- 
-  for (configs = daemon->dhcp_conf; configs; configs = configs->next)
-    {
-      char *domain;
+/* Is every member of check matched by a member of pool?
+   If tagnotneeded, untagged is OK */
+int match_netid(struct dhcp_netid* check, struct dhcp_netid* pool, int tagnotneeded) {
+    struct dhcp_netid* tmp1;
 
-      if ((configs->flags & DHOPT_BANK) || fatal)
-       {
-	 for (cp = configs->next; cp; cp = cp->next)
-	   if ((configs->flags & cp->flags & CONFIG_ADDR) && configs->addr.s_addr == cp->addr.s_addr)
-	     {
-	       if (fatal)
-		 die(_("duplicate IP address %s in dhcp-config directive."), 
-		     inet_ntoa(cp->addr), EC_BADCONF);
-	       else
-		 my_syslog(MS_DHCP | LOG_ERR, _("duplicate IP address %s in %s."), 
-			   inet_ntoa(cp->addr), daemon->dhcp_hosts_file);
-	       configs->flags &= ~CONFIG_ADDR;
-	     }
-	 
-	 /* split off domain part */
-	 if ((configs->flags & CONFIG_NAME) && (domain = strip_hostname(configs->hostname)))
-	   configs->domain = domain;
-       }
+    if (!check && !tagnotneeded) return 0;
+
+    for (; check; check = check->next) {
+        if (check->net[0] != '#') {
+            for (tmp1 = pool; tmp1; tmp1 = tmp1->next)
+                if (strcmp(check->net, tmp1->net) == 0) break;
+            if (!tmp1) return 0;
+        } else
+            for (tmp1 = pool; tmp1; tmp1 = tmp1->next)
+                if (strcmp((check->net) + 1, tmp1->net) == 0) return 0;
+    }
+    return 1;
+}
+
+int address_allocate(struct dhcp_context* context, struct in_addr* addrp, unsigned char* hwaddr,
+                     int hw_len, struct dhcp_netid* netids, time_t now) {
+    /* Find a free address: exclude anything in use and anything allocated to
+       a particular hwaddr/clientid/hostname in our configuration.
+       Try to return from contexts which match netids first. */
+
+    struct in_addr start, addr;
+    struct dhcp_context *c, *d;
+    int i, pass;
+    unsigned int j;
+
+    /* hash hwaddr */
+    for (j = 0, i = 0; i < hw_len; i++) j += hwaddr[i] + (hwaddr[i] << 8) + (hwaddr[i] << 16);
+
+    for (pass = 0; pass <= 1; pass++)
+        for (c = context; c; c = c->current)
+            if (c->flags & CONTEXT_STATIC)
+                continue;
+            else if (!match_netid(c->filter, netids, pass))
+                continue;
+            else {
+                /* pick a seed based on hwaddr then iterate until we find a free address. */
+                start.s_addr = addr.s_addr = htonl(
+                    ntohl(c->start.s_addr) +
+                    ((j + c->addr_epoch) % (1 + ntohl(c->end.s_addr) - ntohl(c->start.s_addr))));
+
+                do {
+                    /* eliminate addresses in use by the server. */
+                    for (d = context; d; d = d->current)
+                        if (addr.s_addr == d->router.s_addr) break;
+
+                    /* Addresses which end in .255 and .0 are broken in Windows even when using
+                       supernetting. ie dhcp-range=192.168.0.1,192.168.1.254,255,255,254.0
+                       then 192.168.0.255 is a valid IP address, but not for Windows as it's
+                       in the class C range. See  KB281579. We therefore don't allocate these
+                       addresses to avoid hard-to-diagnose problems. Thanks Bill. */
+                    if (!d && !lease_find_by_addr(addr) &&
+                        !config_find_by_address(daemon->dhcp_conf, addr) &&
+                        (!IN_CLASSC(ntohl(addr.s_addr)) || ((ntohl(addr.s_addr) & 0xff) != 0xff &&
+                                                            ((ntohl(addr.s_addr) & 0xff) != 0x0)))) {
+                        struct ping_result *r, *victim = NULL;
+                        int count,
+                            max = (int) (0.6 * (((float) PING_CACHE_TIME) / ((float) PING_WAIT)));
+
+                        *addrp = addr;
+
+                        if (daemon->options & OPT_NO_PING) return 1;
+
+                        /* check if we failed to ping addr sometime in the last
+                           PING_CACHE_TIME seconds. If so, assume the same situation still exists.
+                           This avoids problems when a stupid client bangs
+                           on us repeatedly. As a final check, if we did more
+                           than 60% of the possible ping checks in the last
+                           PING_CACHE_TIME, we are in high-load mode, so don't do any more. */
+                        for (count = 0, r = daemon->ping_results; r; r = r->next)
+                            if (difftime(now, r->time) > (float) PING_CACHE_TIME)
+                                victim = r; /* old record */
+                            else if (++count == max || r->addr.s_addr == addr.s_addr)
+                                return 1;
+
+                        if (icmp_ping(addr))
+                            /* address in use: perturb address selection so that we are
+                               less likely to try this address again. */
+                            c->addr_epoch++;
+                        else {
+                            /* at this point victim may hold an expired record */
+                            if (!victim) {
+                                if ((victim = whine_malloc(sizeof(struct ping_result)))) {
+                                    victim->next = daemon->ping_results;
+                                    daemon->ping_results = victim;
+                                }
+                            }
+
+                            /* record that this address is OK for 30s
+                               without more ping checks */
+                            if (victim) {
+                                victim->addr = addr;
+                                victim->time = now;
+                            }
+                            return 1;
+                        }
+                    }
+
+                    addr.s_addr = htonl(ntohl(addr.s_addr) + 1);
+
+                    if (addr.s_addr == htonl(ntohl(c->end.s_addr) + 1)) addr = c->start;
+
+                } while (addr.s_addr != start.s_addr);
+            }
+    return 0;
+}
+
+static int is_addr_in_context(struct dhcp_context* context, struct dhcp_config* config) {
+    if (!context) /* called via find_config() from lease_update_from_configs() */
+        return 1;
+    if (!(config->flags & CONFIG_ADDR)) return 1;
+    for (; context; context = context->current)
+        if (is_same_net(config->addr, context->start, context->netmask)) return 1;
+
+    return 0;
+}
+
+int config_has_mac(struct dhcp_config* config, unsigned char* hwaddr, int len, int type) {
+    struct hwaddr_config* conf_addr;
+
+    for (conf_addr = config->hwaddr; conf_addr; conf_addr = conf_addr->next)
+        if (conf_addr->wildcard_mask == 0 && conf_addr->hwaddr_len == len &&
+            (conf_addr->hwaddr_type == type || conf_addr->hwaddr_type == 0) &&
+            memcmp(conf_addr->hwaddr, hwaddr, len) == 0)
+            return 1;
+
+    return 0;
+}
+
+struct dhcp_config* find_config(struct dhcp_config* configs, struct dhcp_context* context,
+                                unsigned char* clid, int clid_len, unsigned char* hwaddr,
+                                int hw_len, int hw_type, char* hostname) {
+    int count, new;
+    struct dhcp_config *config, *candidate;
+    struct hwaddr_config* conf_addr;
+
+    if (clid)
+        for (config = configs; config; config = config->next)
+            if (config->flags & CONFIG_CLID) {
+                if (config->clid_len == clid_len && memcmp(config->clid, clid, clid_len) == 0 &&
+                    is_addr_in_context(context, config))
+                    return config;
+
+                /* dhcpcd prefixes ASCII client IDs by zero which is wrong, but we try and
+                   cope with that here */
+                if (*clid == 0 && config->clid_len == clid_len - 1 &&
+                    memcmp(config->clid, clid + 1, clid_len - 1) == 0 &&
+                    is_addr_in_context(context, config))
+                    return config;
+            }
+
+    for (config = configs; config; config = config->next)
+        if (config_has_mac(config, hwaddr, hw_len, hw_type) && is_addr_in_context(context, config))
+            return config;
+
+    if (hostname && context)
+        for (config = configs; config; config = config->next)
+            if ((config->flags & CONFIG_NAME) && hostname_isequal(config->hostname, hostname) &&
+                is_addr_in_context(context, config))
+                return config;
+
+    /* use match with fewest wildcast octets */
+    for (candidate = NULL, count = 0, config = configs; config; config = config->next)
+        if (is_addr_in_context(context, config))
+            for (conf_addr = config->hwaddr; conf_addr; conf_addr = conf_addr->next)
+                if (conf_addr->wildcard_mask != 0 && conf_addr->hwaddr_len == hw_len &&
+                    (conf_addr->hwaddr_type == hw_type || conf_addr->hwaddr_type == 0) &&
+                    (new = memcmp_masked(conf_addr->hwaddr, hwaddr, hw_len,
+                                         conf_addr->wildcard_mask)) > count) {
+                    count = new;
+                    candidate = config;
+                }
+
+    return candidate;
+}
+
+void check_dhcp_hosts(int fatal) {
+    /* If the same IP appears in more than one host config, then DISCOVER
+       for one of the hosts will get the address, but REQUEST will be NAKed,
+       since the address is reserved by the other one -> protocol loop.
+       Also check that FQDNs match the domain we are using. */
+
+    struct dhcp_config *configs, *cp;
+
+    for (configs = daemon->dhcp_conf; configs; configs = configs->next) {
+        char* domain;
+
+        if ((configs->flags & DHOPT_BANK) || fatal) {
+            for (cp = configs->next; cp; cp = cp->next)
+                if ((configs->flags & cp->flags & CONFIG_ADDR) &&
+                    configs->addr.s_addr == cp->addr.s_addr) {
+                    if (fatal)
+                        die(_("duplicate IP address %s in dhcp-config directive."),
+                            inet_ntoa(cp->addr), EC_BADCONF);
+                    else
+                        my_syslog(MS_DHCP | LOG_ERR, _("duplicate IP address %s in %s."),
+                                  inet_ntoa(cp->addr), daemon->dhcp_hosts_file);
+                    configs->flags &= ~CONFIG_ADDR;
+                }
+
+            /* split off domain part */
+            if ((configs->flags & CONFIG_NAME) && (domain = strip_hostname(configs->hostname)))
+                configs->domain = domain;
+        }
     }
 }
 
-void dhcp_update_configs(struct dhcp_config *configs)
-{
-  /* Some people like to keep all static IP addresses in /etc/hosts.
-     This goes through /etc/hosts and sets static addresses for any DHCP config
-     records which don't have an address and whose name matches. 
-     We take care to maintain the invariant that any IP address can appear
-     in at most one dhcp-host. Since /etc/hosts can be re-read by SIGHUP, 
-     restore the status-quo ante first. */
-  
-  struct dhcp_config *config;
-  struct crec *crec;
+void dhcp_update_configs(struct dhcp_config* configs) {
+    /* Some people like to keep all static IP addresses in /etc/hosts.
+       This goes through /etc/hosts and sets static addresses for any DHCP config
+       records which don't have an address and whose name matches.
+       We take care to maintain the invariant that any IP address can appear
+       in at most one dhcp-host. Since /etc/hosts can be re-read by SIGHUP,
+       restore the status-quo ante first. */
 
-  for (config = configs; config; config = config->next)
-    if (config->flags & CONFIG_ADDR_HOSTS)
-      config->flags &= ~(CONFIG_ADDR | CONFIG_ADDR_HOSTS);
-  
-  
-  if (daemon->port != 0)
+    struct dhcp_config* config;
+    struct crec* crec;
+
     for (config = configs; config; config = config->next)
-      if (!(config->flags & CONFIG_ADDR) &&
-	  (config->flags & CONFIG_NAME) && 
-	  (crec = cache_find_by_name(NULL, config->hostname, 0, F_IPV4)) &&
-	  (crec->flags & F_HOSTS))
-	{
-	  if (cache_find_by_name(crec, config->hostname, 0, F_IPV4))
-	    {
-	      /* use primary (first) address */
-	      while (crec && !(crec->flags & F_REVERSE))
-		crec = cache_find_by_name(crec, config->hostname, 0, F_IPV4);
-	      if (!crec)
-		continue; /* should be never */
-	      my_syslog(MS_DHCP | LOG_WARNING, _("%s has more than one address in hostsfile, using %s for DHCP"), 
-			config->hostname, inet_ntoa(crec->addr.addr.addr.addr4));
-	    }
+        if (config->flags & CONFIG_ADDR_HOSTS) config->flags &= ~(CONFIG_ADDR | CONFIG_ADDR_HOSTS);
 
-	  if (config_find_by_address(configs, crec->addr.addr.addr.addr4))
-	    my_syslog(MS_DHCP | LOG_WARNING, _("duplicate IP address %s (%s) in dhcp-config directive"), 
-		      inet_ntoa(crec->addr.addr.addr.addr4), config->hostname);
-	  else 
-	    {
-	      config->addr = crec->addr.addr.addr.addr4;
-	      config->flags |= CONFIG_ADDR | CONFIG_ADDR_HOSTS;
-	    }
-	}
+    if (daemon->port != 0)
+        for (config = configs; config; config = config->next)
+            if (!(config->flags & CONFIG_ADDR) && (config->flags & CONFIG_NAME) &&
+                (crec = cache_find_by_name(NULL, config->hostname, 0, F_IPV4)) &&
+                (crec->flags & F_HOSTS)) {
+                if (cache_find_by_name(crec, config->hostname, 0, F_IPV4)) {
+                    /* use primary (first) address */
+                    while (crec && !(crec->flags & F_REVERSE))
+                        crec = cache_find_by_name(crec, config->hostname, 0, F_IPV4);
+                    if (!crec) continue; /* should be never */
+                    my_syslog(MS_DHCP | LOG_WARNING,
+                              _("%s has more than one address in hostsfile, using %s for DHCP"),
+                              config->hostname, inet_ntoa(crec->addr.addr.addr.addr4));
+                }
+
+                if (config_find_by_address(configs, crec->addr.addr.addr.addr4))
+                    my_syslog(MS_DHCP | LOG_WARNING,
+                              _("duplicate IP address %s (%s) in dhcp-config directive"),
+                              inet_ntoa(crec->addr.addr.addr.addr4), config->hostname);
+                else {
+                    config->addr = crec->addr.addr.addr.addr4;
+                    config->flags |= CONFIG_ADDR | CONFIG_ADDR_HOSTS;
+                }
+            }
 }
 
 /* If we've not found a hostname any other way, try and see if there's one in /etc/hosts
    for this address. If it has a domain part, that must match the set domain and
    it gets stripped. The set of legal domain names is bigger than the set of legal hostnames
    so check here that the domain name is legal as a hostname. */
-char *host_from_dns(struct in_addr addr)
-{
-  struct crec *lookup;
-  char *hostname = NULL;
-  char *d1, *d2;
+char* host_from_dns(struct in_addr addr) {
+    struct crec* lookup;
+    char* hostname = NULL;
+    char *d1, *d2;
 
-  if (daemon->port == 0)
-    return NULL; /* DNS disabled. */
-  
-  lookup = cache_find_by_addr(NULL, (struct all_addr *)&addr, 0, F_IPV4);
-  if (lookup && (lookup->flags & F_HOSTS))
-    {
-      hostname = daemon->dhcp_buff;
-      strncpy(hostname, cache_get_name(lookup), 256);
-      hostname[255] = 0;
-      d1 = strip_hostname(hostname);
-      d2 = get_domain(addr);
-      if (!legal_hostname(hostname) || (d1 && (!d2 || !hostname_isequal(d1, d2))))
-	hostname = NULL;
+    if (daemon->port == 0) return NULL; /* DNS disabled. */
+
+    lookup = cache_find_by_addr(NULL, (struct all_addr*) &addr, 0, F_IPV4);
+    if (lookup && (lookup->flags & F_HOSTS)) {
+        hostname = daemon->dhcp_buff;
+        strncpy(hostname, cache_get_name(lookup), 256);
+        hostname[255] = 0;
+        d1 = strip_hostname(hostname);
+        d2 = get_domain(addr);
+        if (!legal_hostname(hostname) || (d1 && (!d2 || !hostname_isequal(d1, d2))))
+            hostname = NULL;
     }
-  
-  return hostname;
+
+    return hostname;
 }
 
 /* return domain or NULL if none. */
-char *strip_hostname(char *hostname)
-{
-  char *dot = strchr(hostname, '.');
- 
-  if (!dot)
+char* strip_hostname(char* hostname) {
+    char* dot = strchr(hostname, '.');
+
+    if (!dot) return NULL;
+
+    *dot = 0; /* truncate */
+    if (strlen(dot + 1) != 0) return dot + 1;
+
     return NULL;
-  
-  *dot = 0; /* truncate */
-  if (strlen(dot+1) != 0)
-    return dot+1;
-  
-  return NULL;
 }
 
 #endif
-
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index 947b481..27ad864 100644
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -34,51 +34,48 @@
 #error Should HAVE_LINUX_NETWORK
 #endif
 
+struct daemon* daemon;
 
-struct daemon *daemon;
-
-static char *compile_opts = 
+static char* compile_opts =
 #ifndef HAVE_IPV6
-"no-"
+    "no-"
 #endif
-"IPv6 "
+    "IPv6 "
 #ifndef HAVE_GETOPT_LONG
-"no-"
+    "no-"
 #endif
-"GNU-getopt "
+    "GNU-getopt "
 #ifdef HAVE_BROKEN_RTC
-"no-RTC "
+    "no-RTC "
 #endif
 #ifdef NO_FORK
-"no-MMU "
+    "no-MMU "
 #endif
 #ifndef LOCALEDIR
-"no-"
+    "no-"
 #endif
-"I18N "
+    "I18N "
 #ifndef HAVE_DHCP
-"no-"
+    "no-"
 #endif
-"DHCP "
+    "DHCP "
 #if defined(HAVE_DHCP) && !defined(HAVE_SCRIPT)
-"no-scripts"
+    "no-scripts"
 #endif
-"";
-
-
+    "";
 
 static volatile pid_t pid = 0;
 static volatile int pipewrite;
 
-static int set_dns_listeners(time_t now, fd_set *set, int *maxfdp);
-static void check_dns_listeners(fd_set *set, time_t now);
+static int set_dns_listeners(time_t now, fd_set* set, int* maxfdp);
+static void check_dns_listeners(fd_set* set, time_t now);
 static void sig_handler(int sig);
 static void async_event(int pipe, time_t now);
-static void fatal_event(struct event_desc *ev);
+static void fatal_event(struct event_desc* ev);
 static void poll_resolv(void);
 #ifdef __ANDROID__
-static int set_android_listeners(fd_set *set, int *maxfdp);
-static int check_android_listeners(fd_set *set);
+static int set_android_listeners(fd_set* set, int* maxfdp);
+static int check_android_listeners(fd_set* set);
 #endif
 
 void setupSignalHandling() {
@@ -117,508 +114,451 @@
             if (errno == EACCES) continue;  // Lessen the log spam.
             my_syslog(LOG_ERR, "fstat(%d) error: %d/%s", i, errno, strerror(errno));
         } else {
-            my_syslog(LOG_ERR, "Closing inherited file descriptor %d (%u:%u)",
-                      i, stat_buf.st_dev, stat_buf.st_ino);
+            my_syslog(LOG_ERR, "Closing inherited file descriptor %d (%u:%u)", i, stat_buf.st_dev,
+                      stat_buf.st_ino);
         }
         close(i);
     }
 }
 
-int main (int argc, char **argv)
-{
-  int bind_fallback = 0;
-  time_t now;
-  struct iname *if_tmp;
-  int piperead, pipefd[2], err_pipe[2];
-  struct passwd *ent_pw = NULL;
+int main(int argc, char** argv) {
+    int bind_fallback = 0;
+    time_t now;
+    struct iname* if_tmp;
+    int piperead, pipefd[2], err_pipe[2];
+    struct passwd* ent_pw = NULL;
 #if defined(HAVE_DHCP) && defined(HAVE_SCRIPT)
-  uid_t script_uid = 0;
-  gid_t script_gid = 0;
+    uid_t script_uid = 0;
+    gid_t script_gid = 0;
 #endif
-  struct group *gp = NULL;
-  long i, max_fd = sysconf(_SC_OPEN_MAX);
-  char *baduser = NULL;
-  int log_err;
+    struct group* gp = NULL;
+    long i, max_fd = sysconf(_SC_OPEN_MAX);
+    char* baduser = NULL;
+    int log_err;
 #if defined(HAVE_LINUX_NETWORK)
-  cap_user_header_t hdr = NULL;
-  cap_user_data_t data = NULL;
-#endif 
+    cap_user_header_t hdr = NULL;
+    cap_user_data_t data = NULL;
+#endif
 
 #ifdef LOCALEDIR
-  setlocale(LC_ALL, "");
-  bindtextdomain("dnsmasq", LOCALEDIR); 
-  textdomain("dnsmasq");
+    setlocale(LC_ALL, "");
+    bindtextdomain("dnsmasq", LOCALEDIR);
+    textdomain("dnsmasq");
 #endif
 
-  setupSignalHandling();
+    setupSignalHandling();
 
-  umask(022); /* known umask, create leases and pid files as 0644 */
+    umask(022); /* known umask, create leases and pid files as 0644 */
 
-  read_opts(argc, argv, compile_opts);
-    
-  if (daemon->edns_pktsz < PACKETSZ)
-    daemon->edns_pktsz = PACKETSZ;
-  daemon->packet_buff_sz = daemon->edns_pktsz > DNSMASQ_PACKETSZ ? 
-    daemon->edns_pktsz : DNSMASQ_PACKETSZ;
-  daemon->packet = safe_malloc(daemon->packet_buff_sz);
+    read_opts(argc, argv, compile_opts);
+
+    if (daemon->edns_pktsz < PACKETSZ) daemon->edns_pktsz = PACKETSZ;
+    daemon->packet_buff_sz =
+        daemon->edns_pktsz > DNSMASQ_PACKETSZ ? daemon->edns_pktsz : DNSMASQ_PACKETSZ;
+    daemon->packet = safe_malloc(daemon->packet_buff_sz);
 
 #ifdef HAVE_DHCP
-  if (!daemon->lease_file)
-    {
-      if (daemon->dhcp)
-	daemon->lease_file = LEASEFILE;
+    if (!daemon->lease_file) {
+        if (daemon->dhcp) daemon->lease_file = LEASEFILE;
     }
 #endif
 
-  closeUnwantedFileDescriptors();
+    closeUnwantedFileDescriptors();
 
 #ifdef HAVE_LINUX_NETWORK
-  netlink_init();
-#elif !(defined(IP_RECVDSTADDR) && \
-	defined(IP_RECVIF) && \
-	defined(IP_SENDSRCADDR))
-  if (!(daemon->options & OPT_NOWILD))
-    {
-      bind_fallback = 1;
-      daemon->options |= OPT_NOWILD;
+    netlink_init();
+#elif !(defined(IP_RECVDSTADDR) && defined(IP_RECVIF) && defined(IP_SENDSRCADDR))
+    if (!(daemon->options & OPT_NOWILD)) {
+        bind_fallback = 1;
+        daemon->options |= OPT_NOWILD;
     }
 #endif
 
-  rand_init();
+    rand_init();
 
-  now = dnsmasq_time();
+    now = dnsmasq_time();
 
 #ifdef HAVE_DHCP
-  if (daemon->dhcp)
-    {
-      /* Note that order matters here, we must call lease_init before
-	 creating any file descriptors which shouldn't be leaked
-	 to the lease-script init process. */
-      lease_init(now);
-      dhcp_init();
+    if (daemon->dhcp) {
+        /* Note that order matters here, we must call lease_init before
+       creating any file descriptors which shouldn't be leaked
+       to the lease-script init process. */
+        lease_init(now);
+        dhcp_init();
     }
 #endif
 
-  if (!enumerate_interfaces())
-    die(_("failed to find list of interfaces: %s"), NULL, EC_MISC);
-    
-  if (daemon->options & OPT_NOWILD) 
-    {
-      daemon->listeners = create_bound_listeners();
+    if (!enumerate_interfaces()) die(_("failed to find list of interfaces: %s"), NULL, EC_MISC);
 
-      for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
-	if (if_tmp->name && !if_tmp->used)
-	  die(_("unknown interface %s"), if_tmp->name, EC_BADNET);
-  
-      for (if_tmp = daemon->if_addrs; if_tmp; if_tmp = if_tmp->next)
-	if (!if_tmp->used)
-	  {
-	    prettyprint_addr(&if_tmp->addr, daemon->namebuff);
-	    die(_("no interface with address %s"), daemon->namebuff, EC_BADNET);
-	  }
-    }
-  else if ((daemon->port != 0 || (daemon->options & OPT_TFTP)) &&
-	   !(daemon->listeners = create_wildcard_listeners()))
-    die(_("failed to create listening socket: %s"), NULL, EC_BADNET);
-  
-  if (daemon->port != 0)
-    cache_init();
- 
-  if (daemon->port != 0)
-    pre_allocate_sfds();
+    if (daemon->options & OPT_NOWILD) {
+        daemon->listeners = create_bound_listeners();
+
+        for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
+            if (if_tmp->name && !if_tmp->used)
+                die(_("unknown interface %s"), if_tmp->name, EC_BADNET);
+
+        for (if_tmp = daemon->if_addrs; if_tmp; if_tmp = if_tmp->next)
+            if (!if_tmp->used) {
+                prettyprint_addr(&if_tmp->addr, daemon->namebuff);
+                die(_("no interface with address %s"), daemon->namebuff, EC_BADNET);
+            }
+    } else if ((daemon->port != 0 || (daemon->options & OPT_TFTP)) &&
+               !(daemon->listeners = create_wildcard_listeners()))
+        die(_("failed to create listening socket: %s"), NULL, EC_BADNET);
+
+    if (daemon->port != 0) cache_init();
+
+    if (daemon->port != 0) pre_allocate_sfds();
 
 #if defined(HAVE_DHCP) && defined(HAVE_SCRIPT)
-  /* Note getpwnam returns static storage */
-  if (daemon->dhcp && daemon->lease_change_command && daemon->scriptuser)
-    {
-      if ((ent_pw = getpwnam(daemon->scriptuser)))
-	{
-	  script_uid = ent_pw->pw_uid;
-	  script_gid = ent_pw->pw_gid;
-	 }
-      else
-	baduser = daemon->scriptuser;
+    /* Note getpwnam returns static storage */
+    if (daemon->dhcp && daemon->lease_change_command && daemon->scriptuser) {
+        if ((ent_pw = getpwnam(daemon->scriptuser))) {
+            script_uid = ent_pw->pw_uid;
+            script_gid = ent_pw->pw_gid;
+        } else
+            baduser = daemon->scriptuser;
     }
 #endif
-  
-  if (daemon->username && !(ent_pw = getpwnam(daemon->username)))
-    baduser = daemon->username;
-  else if (daemon->groupname && !(gp = getgrnam(daemon->groupname)))
-    baduser = daemon->groupname;
 
-  if (baduser)
-    die(_("unknown user or group: %s"), baduser, EC_BADCONF);
-   
-  /* implement group defaults, "dip" if available, or group associated with uid */
-  if (!daemon->group_set && !gp)
-    {
-      if (!(gp = getgrnam(CHGRP)) && ent_pw)
-	gp = getgrgid(ent_pw->pw_gid);
-      
-      /* for error message */
-      if (gp)
-	daemon->groupname = gp->gr_name; 
+    if (daemon->username && !(ent_pw = getpwnam(daemon->username)))
+        baduser = daemon->username;
+    else if (daemon->groupname && !(gp = getgrnam(daemon->groupname)))
+        baduser = daemon->groupname;
+
+    if (baduser) die(_("unknown user or group: %s"), baduser, EC_BADCONF);
+
+    /* implement group defaults, "dip" if available, or group associated with uid */
+    if (!daemon->group_set && !gp) {
+        if (!(gp = getgrnam(CHGRP)) && ent_pw) gp = getgrgid(ent_pw->pw_gid);
+
+        /* for error message */
+        if (gp) daemon->groupname = gp->gr_name;
     }
 
 #if defined(HAVE_LINUX_NETWORK)
-  /* determine capability API version here, while we can still
-     call safe_malloc */
-  if (ent_pw && ent_pw->pw_uid != 0)
-    {
-      int capsize = 1; /* for header version 1 */
-      hdr = safe_malloc(sizeof(*hdr));
+    /* determine capability API version here, while we can still
+       call safe_malloc */
+    if (ent_pw && ent_pw->pw_uid != 0) {
+        int capsize = 1; /* for header version 1 */
+        hdr = safe_malloc(sizeof(*hdr));
 
-      /* find version supported by kernel */
-      memset(hdr, 0, sizeof(*hdr));
-      capget(hdr, NULL);
-      
-      if (hdr->version != LINUX_CAPABILITY_VERSION_1)
-	{
-	  /* if unknown version, use largest supported version (3) */
-	  if (hdr->version != LINUX_CAPABILITY_VERSION_2)
-	    hdr->version = LINUX_CAPABILITY_VERSION_3;
-	  capsize = 2;
-	}
-      
-      data = safe_malloc(sizeof(*data) * capsize);
-      memset(data, 0, sizeof(*data) * capsize);
+        /* find version supported by kernel */
+        memset(hdr, 0, sizeof(*hdr));
+        capget(hdr, NULL);
+
+        if (hdr->version != LINUX_CAPABILITY_VERSION_1) {
+            /* if unknown version, use largest supported version (3) */
+            if (hdr->version != LINUX_CAPABILITY_VERSION_2)
+                hdr->version = LINUX_CAPABILITY_VERSION_3;
+            capsize = 2;
+        }
+
+        data = safe_malloc(sizeof(*data) * capsize);
+        memset(data, 0, sizeof(*data) * capsize);
     }
 #endif
 
-  /* Use a pipe to carry signals and other events back to the event loop 
-     in a race-free manner and another to carry errors to daemon-invoking process */
-  safe_pipe(pipefd, 1);
-  
-  piperead = pipefd[0];
-  pipewrite = pipefd[1];
-  /* prime the pipe to load stuff first time. */
-  send_event(pipewrite, EVENT_RELOAD, 0); 
+    /* Use a pipe to carry signals and other events back to the event loop
+       in a race-free manner and another to carry errors to daemon-invoking process */
+    safe_pipe(pipefd, 1);
 
-  err_pipe[1] = -1;
-  
-  if (!(daemon->options & OPT_DEBUG))   
-    {
+    piperead = pipefd[0];
+    pipewrite = pipefd[1];
+    /* prime the pipe to load stuff first time. */
+    send_event(pipewrite, EVENT_RELOAD, 0);
+
+    err_pipe[1] = -1;
+
+    if (!(daemon->options & OPT_DEBUG)) {
 #ifndef __ANDROID__
-      int nullfd;
+        int nullfd;
 #endif
 
-      /* The following code "daemonizes" the process. 
-	 See Stevens section 12.4 */
-      
-      if (chdir("/") != 0)
-	die(_("cannot chdir to filesystem root: %s"), NULL, EC_MISC); 
+        /* The following code "daemonizes" the process.
+       See Stevens section 12.4 */
 
-#ifndef NO_FORK      
-      if (!(daemon->options & OPT_NO_FORK))
-	{
-	  pid_t pid;
-	  
-	  /* pipe to carry errors back to original process.
-	     When startup is complete we close this and the process terminates. */
-	  safe_pipe(err_pipe, 0);
-	  
-	  if ((pid = fork()) == -1)
-	    /* fd == -1 since we've not forked, never returns. */
-	    send_event(-1, EVENT_FORK_ERR, errno);
-	   
-	  if (pid != 0)
-	    {
-	      struct event_desc ev;
-	      
-	      /* close our copy of write-end */
-	      close(err_pipe[1]);
-	      
-	      /* check for errors after the fork */
-	      if (read_write(err_pipe[0], (unsigned char *)&ev, sizeof(ev), 1))
-		fatal_event(&ev);
-	      
-	      _exit(EC_GOOD);
-	    } 
-	  
-	  close(err_pipe[0]);
+        if (chdir("/") != 0) die(_("cannot chdir to filesystem root: %s"), NULL, EC_MISC);
 
-	  /* NO calls to die() from here on. */
-	  
-	  setsid();
-	 
-	  if ((pid = fork()) == -1)
-	    send_event(err_pipe[1], EVENT_FORK_ERR, errno);
-	 
-	  if (pid != 0)
-	    _exit(0);
-	}
+#ifndef NO_FORK
+        if (!(daemon->options & OPT_NO_FORK)) {
+            pid_t pid;
+
+            /* pipe to carry errors back to original process.
+               When startup is complete we close this and the process terminates. */
+            safe_pipe(err_pipe, 0);
+
+            if ((pid = fork()) == -1) /* fd == -1 since we've not forked, never returns. */
+                send_event(-1, EVENT_FORK_ERR, errno);
+
+            if (pid != 0) {
+                struct event_desc ev;
+
+                /* close our copy of write-end */
+                close(err_pipe[1]);
+
+                /* check for errors after the fork */
+                if (read_write(err_pipe[0], (unsigned char*) &ev, sizeof(ev), 1)) fatal_event(&ev);
+
+                _exit(EC_GOOD);
+            }
+
+            close(err_pipe[0]);
+
+            /* NO calls to die() from here on. */
+
+            setsid();
+
+            if ((pid = fork()) == -1) send_event(err_pipe[1], EVENT_FORK_ERR, errno);
+
+            if (pid != 0) _exit(0);
+        }
 #endif
-            
-      /* write pidfile _after_ forking ! */
-      if (daemon->runfile)
-	{
-	  FILE *pidfile;
-	  
-	  /* only complain if started as root */
-	  if ((pidfile = fopen(daemon->runfile, "w")))
-	    {
-	      fprintf(pidfile, "%d\n", (int) getpid());
-	      fclose(pidfile);
-	    }
-	  else if (getuid() == 0)
-	    {
-	      send_event(err_pipe[1], EVENT_PIDFILE, errno);
-	      _exit(0);
-	    }
-	}
+
+        /* write pidfile _after_ forking ! */
+        if (daemon->runfile) {
+            FILE* pidfile;
+
+            /* only complain if started as root */
+            if ((pidfile = fopen(daemon->runfile, "w"))) {
+                fprintf(pidfile, "%d\n", (int) getpid());
+                fclose(pidfile);
+            } else if (getuid() == 0) {
+                send_event(err_pipe[1], EVENT_PIDFILE, errno);
+                _exit(0);
+            }
+        }
 
 #ifndef __ANDROID__
-      /* open  stdout etc to /dev/null */
-      nullfd = open("/dev/null", O_RDWR);
-      dup2(nullfd, STDOUT_FILENO);
-      dup2(nullfd, STDERR_FILENO);
-      dup2(nullfd, STDIN_FILENO);
-      close(nullfd);
+        /* open  stdout etc to /dev/null */
+        nullfd = open("/dev/null", O_RDWR);
+        dup2(nullfd, STDOUT_FILENO);
+        dup2(nullfd, STDERR_FILENO);
+        dup2(nullfd, STDIN_FILENO);
+        close(nullfd);
 #endif
     }
-  
-   log_err = log_start(ent_pw, err_pipe[1]); 
-   
-   /* if we are to run scripts, we need to fork a helper before dropping root. */
-  daemon->helperfd = -1;
-#if defined(HAVE_DHCP) && defined(HAVE_SCRIPT) 
-  if (daemon->dhcp && daemon->lease_change_command)
-    daemon->helperfd = create_helper(pipewrite, err_pipe[1], script_uid, script_gid, max_fd);
+
+    log_err = log_start(ent_pw, err_pipe[1]);
+
+    /* if we are to run scripts, we need to fork a helper before dropping root. */
+    daemon->helperfd = -1;
+#if defined(HAVE_DHCP) && defined(HAVE_SCRIPT)
+    if (daemon->dhcp && daemon->lease_change_command)
+        daemon->helperfd = create_helper(pipewrite, err_pipe[1], script_uid, script_gid, max_fd);
 #endif
 
-  if (!(daemon->options & OPT_DEBUG) && getuid() == 0)   
-    {
-      int bad_capabilities = 0;
-      gid_t dummy;
-      
-      /* remove all supplimentary groups */
-      if (gp && 
-	  (setgroups(0, &dummy) == -1 ||
-	   setgid(gp->gr_gid) == -1))
-	{
-	  send_event(err_pipe[1], EVENT_GROUP_ERR, errno);
-	  _exit(0);
-	}
-  
-      if (ent_pw && ent_pw->pw_uid != 0)
-	{     
+    if (!(daemon->options & OPT_DEBUG) && getuid() == 0) {
+        int bad_capabilities = 0;
+        gid_t dummy;
+
+        /* remove all supplimentary groups */
+        if (gp && (setgroups(0, &dummy) == -1 || setgid(gp->gr_gid) == -1)) {
+            send_event(err_pipe[1], EVENT_GROUP_ERR, errno);
+            _exit(0);
+        }
+
+        if (ent_pw && ent_pw->pw_uid != 0) {
 #if defined(HAVE_LINUX_NETWORK)
-	  /* On linux, we keep CAP_NETADMIN (for ARP-injection) and
-	     CAP_NET_RAW (for icmp) if we're doing dhcp */
-	  data->effective = data->permitted = data->inheritable =
+            /* On linux, we keep CAP_NETADMIN (for ARP-injection) and
+               CAP_NET_RAW (for icmp) if we're doing dhcp */
+            data->effective = data->permitted = data->inheritable =
 #ifdef __ANDROID__
-	    (1 << CAP_NET_BIND_SERVICE) |
+                (1 << CAP_NET_BIND_SERVICE) |
 #endif
-	    (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW) | (1 << CAP_SETUID);
-	  
-	  /* Tell kernel to not clear capabilities when dropping root */
-	  if (capset(hdr, data) == -1 || prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1)
-	    bad_capabilities = errno;
+                (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW) | (1 << CAP_SETUID);
+
+            /* Tell kernel to not clear capabilities when dropping root */
+            if (capset(hdr, data) == -1 || prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1)
+                bad_capabilities = errno;
 
 #endif
 
-	  if (bad_capabilities != 0)
-	    {
-	      send_event(err_pipe[1], EVENT_CAP_ERR, bad_capabilities);
-	      _exit(0);
-	    }
-	  
-	  /* finally drop root */
-	  if (setuid(ent_pw->pw_uid) == -1)
-	    {
-	      send_event(err_pipe[1], EVENT_USER_ERR, errno);
-	      _exit(0);
-	    }     
+            if (bad_capabilities != 0) {
+                send_event(err_pipe[1], EVENT_CAP_ERR, bad_capabilities);
+                _exit(0);
+            }
+
+            /* finally drop root */
+            if (setuid(ent_pw->pw_uid) == -1) {
+                send_event(err_pipe[1], EVENT_USER_ERR, errno);
+                _exit(0);
+            }
 
 #ifdef HAVE_LINUX_NETWORK
-	  data->effective = data->permitted = 
+            data->effective = data->permitted =
 #ifdef __ANDROID__
-	    (1 << CAP_NET_BIND_SERVICE) |
+                (1 << CAP_NET_BIND_SERVICE) |
 #endif
-	    (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW);
-	  data->inheritable = 0;
-	  
-	  /* lose the setuid and setgid capbilities */
-	  if (capset(hdr, data) == -1)
-	    {
-	      send_event(err_pipe[1], EVENT_CAP_ERR, errno);
-	      _exit(0);
-	    }
+                (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW);
+            data->inheritable = 0;
+
+            /* lose the setuid and setgid capbilities */
+            if (capset(hdr, data) == -1) {
+                send_event(err_pipe[1], EVENT_CAP_ERR, errno);
+                _exit(0);
+            }
 #endif
-	  
-	}
+        }
     }
-  
+
 #ifdef HAVE_LINUX_NETWORK
-  if (daemon->options & OPT_DEBUG) 
-    prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
+    if (daemon->options & OPT_DEBUG) prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
 #endif
 
-  if (daemon->port == 0)
-    my_syslog(LOG_INFO, _("started, version %s DNS disabled"), VERSION);
-  else if (daemon->cachesize != 0)
-    my_syslog(LOG_INFO, _("started, version %s cachesize %d"), VERSION, daemon->cachesize);
-  else
-    my_syslog(LOG_INFO, _("started, version %s cache disabled"), VERSION);
-  
-  my_syslog(LOG_INFO, _("compile time options: %s"), compile_opts);
+    if (daemon->port == 0)
+        my_syslog(LOG_INFO, _("started, version %s DNS disabled"), VERSION);
+    else if (daemon->cachesize != 0)
+        my_syslog(LOG_INFO, _("started, version %s cachesize %d"), VERSION, daemon->cachesize);
+    else
+        my_syslog(LOG_INFO, _("started, version %s cache disabled"), VERSION);
 
-  if (log_err != 0)
-    my_syslog(LOG_WARNING, _("warning: failed to change owner of %s: %s"), 
-	      daemon->log_file, strerror(log_err));
+    my_syslog(LOG_INFO, _("compile time options: %s"), compile_opts);
 
-  if (bind_fallback)
-    my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
-  
-  if (!(daemon->options & OPT_NOWILD)) 
-    for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
-      if (if_tmp->name && !if_tmp->used)
-	my_syslog(LOG_WARNING, _("warning: interface %s does not currently exist"), if_tmp->name);
-   
-  if (daemon->port != 0 && (daemon->options & OPT_NO_RESOLV))
-    {
-      if (daemon->resolv_files && !daemon->resolv_files->is_default)
-	my_syslog(LOG_WARNING, _("warning: ignoring resolv-file flag because no-resolv is set"));
-      daemon->resolv_files = NULL;
-      if (!daemon->servers)
-	my_syslog(LOG_WARNING, _("warning: no upstream servers configured"));
-    } 
+    if (log_err != 0)
+        my_syslog(LOG_WARNING, _("warning: failed to change owner of %s: %s"), daemon->log_file,
+                  strerror(log_err));
 
-  if (daemon->max_logs != 0)
-    my_syslog(LOG_INFO, _("asynchronous logging enabled, queue limit is %d messages"), daemon->max_logs);
+    if (bind_fallback)
+        my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
+
+    if (!(daemon->options & OPT_NOWILD))
+        for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
+            if (if_tmp->name && !if_tmp->used)
+                my_syslog(LOG_WARNING, _("warning: interface %s does not currently exist"),
+                          if_tmp->name);
+
+    if (daemon->port != 0 && (daemon->options & OPT_NO_RESOLV)) {
+        if (daemon->resolv_files && !daemon->resolv_files->is_default)
+            my_syslog(LOG_WARNING,
+                      _("warning: ignoring resolv-file flag because no-resolv is set"));
+        daemon->resolv_files = NULL;
+        if (!daemon->servers) my_syslog(LOG_WARNING, _("warning: no upstream servers configured"));
+    }
+
+    if (daemon->max_logs != 0)
+        my_syslog(LOG_INFO, _("asynchronous logging enabled, queue limit is %d messages"),
+                  daemon->max_logs);
 
 #ifdef HAVE_DHCP
-  if (daemon->dhcp)
-    {
-      struct dhcp_context *dhcp_tmp;
-      
-      for (dhcp_tmp = daemon->dhcp; dhcp_tmp; dhcp_tmp = dhcp_tmp->next)
-	{
-	  prettyprint_time(daemon->dhcp_buff2, dhcp_tmp->lease_time);
-	  strcpy(daemon->dhcp_buff, inet_ntoa(dhcp_tmp->start));
-	  my_syslog(MS_DHCP | LOG_INFO, 
-		    (dhcp_tmp->flags & CONTEXT_STATIC) ? 
-		    _("DHCP, static leases only on %.0s%s, lease time %s") :
-		    (dhcp_tmp->flags & CONTEXT_PROXY) ?
-		    _("DHCP, proxy on subnet %.0s%s%.0s") :
-		    _("DHCP, IP range %s -- %s, lease time %s"),
-		    daemon->dhcp_buff, inet_ntoa(dhcp_tmp->end), daemon->dhcp_buff2);
-	}
+    if (daemon->dhcp) {
+        struct dhcp_context* dhcp_tmp;
+
+        for (dhcp_tmp = daemon->dhcp; dhcp_tmp; dhcp_tmp = dhcp_tmp->next) {
+            prettyprint_time(daemon->dhcp_buff2, dhcp_tmp->lease_time);
+            strcpy(daemon->dhcp_buff, inet_ntoa(dhcp_tmp->start));
+            my_syslog(MS_DHCP | LOG_INFO,
+                      (dhcp_tmp->flags & CONTEXT_STATIC)
+                          ? _("DHCP, static leases only on %.0s%s, lease time %s")
+                          : (dhcp_tmp->flags & CONTEXT_PROXY)
+                                ? _("DHCP, proxy on subnet %.0s%s%.0s")
+                                : _("DHCP, IP range %s -- %s, lease time %s"),
+                      daemon->dhcp_buff, inet_ntoa(dhcp_tmp->end), daemon->dhcp_buff2);
+        }
     }
 #endif
 
-  /* finished start-up - release original process */
-  if (err_pipe[1] != -1)
-    close(err_pipe[1]);
-  
-  if (daemon->port != 0)
-    check_servers();
-  
-  pid = getpid();
-  
-  while (1)
-    {
-      int maxfd = -1;
-      struct timeval t, *tp = NULL;
-      fd_set rset, wset, eset;
-      
-      FD_ZERO(&rset);
-      FD_ZERO(&wset);
-      FD_ZERO(&eset);
-      
-      /* if we are out of resources, find how long we have to wait
-	 for some to come free, we'll loop around then and restart
-	 listening for queries */
-      if ((t.tv_sec = set_dns_listeners(now, &rset, &maxfd)) != 0)
-	{
-	  t.tv_usec = 0;
-	  tp = &t;
-	}
+    /* finished start-up - release original process */
+    if (err_pipe[1] != -1) close(err_pipe[1]);
+
+    if (daemon->port != 0) check_servers();
+
+    pid = getpid();
+
+    while (1) {
+        int maxfd = -1;
+        struct timeval t, *tp = NULL;
+        fd_set rset, wset, eset;
+
+        FD_ZERO(&rset);
+        FD_ZERO(&wset);
+        FD_ZERO(&eset);
+
+        /* if we are out of resources, find how long we have to wait
+       for some to come free, we'll loop around then and restart
+       listening for queries */
+        if ((t.tv_sec = set_dns_listeners(now, &rset, &maxfd)) != 0) {
+            t.tv_usec = 0;
+            tp = &t;
+        }
 #ifdef __ANDROID__
-      set_android_listeners(&rset, &maxfd);
+        set_android_listeners(&rset, &maxfd);
 #endif
 
 #ifdef HAVE_DHCP
-      if (daemon->dhcp)
-	{
-	  FD_SET(daemon->dhcpfd, &rset);
-	  bump_maxfd(daemon->dhcpfd, &maxfd);
-	}
+        if (daemon->dhcp) {
+            FD_SET(daemon->dhcpfd, &rset);
+            bump_maxfd(daemon->dhcpfd, &maxfd);
+        }
 #endif
 
 #ifdef HAVE_LINUX_NETWORK
-      FD_SET(daemon->netlinkfd, &rset);
-      bump_maxfd(daemon->netlinkfd, &maxfd);
+        FD_SET(daemon->netlinkfd, &rset);
+        bump_maxfd(daemon->netlinkfd, &maxfd);
 #endif
-      
-      FD_SET(piperead, &rset);
-      bump_maxfd(piperead, &maxfd);
+
+        FD_SET(piperead, &rset);
+        bump_maxfd(piperead, &maxfd);
 
 #ifdef HAVE_DHCP
-#  ifdef HAVE_SCRIPT
-      while (helper_buf_empty() && do_script_run(now));
+#ifdef HAVE_SCRIPT
+        while (helper_buf_empty() && do_script_run(now))
+            ;
 
-      if (!helper_buf_empty())
-	{
-	  FD_SET(daemon->helperfd, &wset);
-	  bump_maxfd(daemon->helperfd, &maxfd);
-	}
-#  else
-      /* need this for other side-effects */
-      while (do_script_run(now));
-#  endif
+        if (!helper_buf_empty()) {
+            FD_SET(daemon->helperfd, &wset);
+            bump_maxfd(daemon->helperfd, &maxfd);
+        }
+#else
+        /* need this for other side-effects */
+        while (do_script_run(now))
+            ;
 #endif
-   
-      /* must do this just before select(), when we know no
-	 more calls to my_syslog() can occur */
-      set_log_writer(&wset, &maxfd);
-      
-      if (select(maxfd+1, &rset, &wset, &eset, tp) < 0)
-	{
-	  /* otherwise undefined after error */
-	  FD_ZERO(&rset); FD_ZERO(&wset); FD_ZERO(&eset);
-	}
+#endif
 
-      now = dnsmasq_time();
+        /* must do this just before select(), when we know no
+       more calls to my_syslog() can occur */
+        set_log_writer(&wset, &maxfd);
 
-      check_log_writer(&wset);
+        if (select(maxfd + 1, &rset, &wset, &eset, tp) < 0) {
+            /* otherwise undefined after error */
+            FD_ZERO(&rset);
+            FD_ZERO(&wset);
+            FD_ZERO(&eset);
+        }
 
-      /* Check for changes to resolv files once per second max. */
-      /* Don't go silent for long periods if the clock goes backwards. */
-      if (daemon->last_resolv == 0 || 
-	  difftime(now, daemon->last_resolv) > 1.0 || 
-	  difftime(now, daemon->last_resolv) < -1.0)
-	{
-	  daemon->last_resolv = now;
+        now = dnsmasq_time();
 
-	  if (daemon->port != 0 && !(daemon->options & OPT_NO_POLL))
-	    poll_resolv();
-	}
-      
-      if (FD_ISSET(piperead, &rset))
-	async_event(piperead, now);
-      
+        check_log_writer(&wset);
+
+        /* Check for changes to resolv files once per second max. */
+        /* Don't go silent for long periods if the clock goes backwards. */
+        if (daemon->last_resolv == 0 || difftime(now, daemon->last_resolv) > 1.0 ||
+            difftime(now, daemon->last_resolv) < -1.0) {
+            daemon->last_resolv = now;
+
+            if (daemon->port != 0 && !(daemon->options & OPT_NO_POLL)) poll_resolv();
+        }
+
+        if (FD_ISSET(piperead, &rset)) async_event(piperead, now);
+
 #ifdef HAVE_LINUX_NETWORK
-      if (FD_ISSET(daemon->netlinkfd, &rset))
-	netlink_multicast();
+        if (FD_ISSET(daemon->netlinkfd, &rset)) netlink_multicast();
 #endif
 
 #ifdef __ANDROID__
-      check_android_listeners(&rset);
+        check_android_listeners(&rset);
 #endif
-      
-      check_dns_listeners(&rset, now);
+
+        check_dns_listeners(&rset, now);
 
 #ifdef HAVE_DHCP
-      if (daemon->dhcp && FD_ISSET(daemon->dhcpfd, &rset))
-	dhcp_packet(now);
+        if (daemon->dhcp && FD_ISSET(daemon->dhcpfd, &rset)) dhcp_packet(now);
 
-#  ifdef HAVE_SCRIPT
-      if (daemon->helperfd != -1 && FD_ISSET(daemon->helperfd, &wset))
-	helper_write();
-#  endif
+#ifdef HAVE_SCRIPT
+        if (daemon->helperfd != -1 && FD_ISSET(daemon->helperfd, &wset)) helper_write();
 #endif
-
+#endif
     }
 }
 
@@ -635,230 +575,207 @@
         const int errsave = errno;
         int event;
 
-        if (sig == SIGHUP) event = EVENT_RELOAD;
-        else if (sig == SIGCHLD) event = EVENT_CHILD;
-        else if (sig == SIGALRM) event = EVENT_ALARM;
-        else if (sig == SIGTERM) event = EVENT_TERM;
-        else if (sig == SIGUSR1) event = EVENT_DUMP;
-        else if (sig == SIGUSR2) event = EVENT_REOPEN;
-        else return;
+        if (sig == SIGHUP)
+            event = EVENT_RELOAD;
+        else if (sig == SIGCHLD)
+            event = EVENT_CHILD;
+        else if (sig == SIGALRM)
+            event = EVENT_ALARM;
+        else if (sig == SIGTERM)
+            event = EVENT_TERM;
+        else if (sig == SIGUSR1)
+            event = EVENT_DUMP;
+        else if (sig == SIGUSR2)
+            event = EVENT_REOPEN;
+        else
+            return;
 
         send_event(pipewrite, event, 0);
         errno = errsave;
     }
 }
 
-void send_event(int fd, int event, int data)
-{
-  struct event_desc ev;
-  
-  ev.event = event;
-  ev.data = data;
-  
-  /* error pipe, debug mode. */
-  if (fd == -1)
-    fatal_event(&ev);
-  else
-    /* pipe is non-blocking and struct event_desc is smaller than
-       PIPE_BUF, so this either fails or writes everything */
-    while (write(fd, &ev, sizeof(ev)) == -1 && errno == EINTR);
-}
+void send_event(int fd, int event, int data) {
+    struct event_desc ev;
 
-static void fatal_event(struct event_desc *ev)
-{
-  errno = ev->data;
-  
-  switch (ev->event)
-    {
-    case EVENT_DIE:
-      exit(0);
+    ev.event = event;
+    ev.data = data;
 
-    case EVENT_FORK_ERR:
-      die(_("cannot fork into background: %s"), NULL, EC_MISC);
-  
-    case EVENT_PIPE_ERR:
-      die(_("failed to create helper: %s"), NULL, EC_MISC);
-  
-    case EVENT_CAP_ERR:
-      die(_("setting capabilities failed: %s"), NULL, EC_MISC);
-
-    case EVENT_USER_ERR:
-    case EVENT_HUSER_ERR:
-      die(_("failed to change user-id to %s: %s"), 
-	  ev->event == EVENT_USER_ERR ? daemon->username : daemon->scriptuser,
-	  EC_MISC);
-
-    case EVENT_GROUP_ERR:
-      die(_("failed to change group-id to %s: %s"), daemon->groupname, EC_MISC);
-      
-    case EVENT_PIDFILE:
-      die(_("failed to open pidfile %s: %s"), daemon->runfile, EC_FILE);
-
-    case EVENT_LOG_ERR:
-      die(_("cannot open %s: %s"), daemon->log_file ? daemon->log_file : "log", EC_FILE);
-    }
-}	
-      
-static void async_event(int pipe, time_t now)
-{
-  pid_t p;
-  struct event_desc ev;
-  int i;
-
-  if (read_write(pipe, (unsigned char *)&ev, sizeof(ev), 1))
-    switch (ev.event)
-      {
-      case EVENT_RELOAD:
-	clear_cache_and_reload(now);
-	if (daemon->port != 0 && daemon->resolv_files && (daemon->options & OPT_NO_POLL))
-	  {
-	    reload_servers(daemon->resolv_files->name);
-	    check_servers();
-	  }
-#ifdef HAVE_DHCP
-	rerun_scripts();
-#endif
-	break;
-	
-      case EVENT_DUMP:
-	if (daemon->port != 0)
-	  dump_cache(now);
-	break;
-	
-      case EVENT_ALARM:
-#ifdef HAVE_DHCP
-	if (daemon->dhcp)
-	  {
-	    lease_prune(NULL, now);
-	    lease_update_file(now);
-	  }
-#endif
-	break;
-		
-      case EVENT_CHILD:
-	/* See Stevens 5.10 */
-	while ((p = waitpid(-1, NULL, WNOHANG)) != 0)
-	  if (p == -1)
-	    {
-	      if (errno != EINTR)
-		break;
-	    }      
-	  else 
-	    for (i = 0 ; i < MAX_PROCS; i++)
-	      if (daemon->tcp_pids[i] == p)
-		daemon->tcp_pids[i] = 0;
-	break;
-	
-      case EVENT_KILLED:
-	my_syslog(LOG_WARNING, _("child process killed by signal %d"), ev.data);
-	break;
-
-      case EVENT_EXITED:
-	my_syslog(LOG_WARNING, _("child process exited with status %d"), ev.data);
-	break;
-
-      case EVENT_EXEC_ERR:
-	my_syslog(LOG_ERR, _("failed to execute %s: %s"), 
-		  daemon->lease_change_command, strerror(ev.data));
-	break;
-
-	/* necessary for fatal errors in helper */
-      case EVENT_HUSER_ERR:
-      case EVENT_DIE:
-	fatal_event(&ev);
-	break;
-
-      case EVENT_REOPEN:
-	/* Note: this may leave TCP-handling processes with the old file still open.
-	   Since any such process will die in CHILD_LIFETIME or probably much sooner,
-	   we leave them logging to the old file. */
-	if (daemon->log_file != NULL)
-	  log_reopen(daemon->log_file);
-	break;
-	
-      case EVENT_TERM:
-	/* Knock all our children on the head. */
-	for (i = 0; i < MAX_PROCS; i++)
-	  if (daemon->tcp_pids[i] != 0)
-	    kill(daemon->tcp_pids[i], SIGALRM);
-	
-#if defined(HAVE_DHCP) && defined(HAVE_SCRIPT)
-	/* handle pending lease transitions */
-	if (daemon->helperfd != -1)
-	  {
-	    /* block in writes until all done */
-	    if ((i = fcntl(daemon->helperfd, F_GETFL)) != -1)
-	      fcntl(daemon->helperfd, F_SETFL, i & ~O_NONBLOCK); 
-	    do {
-	      helper_write();
-	    } while (!helper_buf_empty() || do_script_run(now));
-	    close(daemon->helperfd);
-	  }
-#endif
-	
-	if (daemon->lease_stream)
-	  fclose(daemon->lease_stream);
-
-	if (daemon->runfile)
-	  unlink(daemon->runfile);
-	
-	my_syslog(LOG_INFO, _("exiting on receipt of SIGTERM"));
-	flush_log();
-	exit(EC_GOOD);
-      }
-}
-
-static void poll_resolv()
-{
-  struct resolvc *res, *latest;
-  struct stat statbuf;
-  time_t last_change = 0;
-  /* There may be more than one possible file. 
-     Go through and find the one which changed _last_.
-     Warn of any which can't be read. */
-  for (latest = NULL, res = daemon->resolv_files; res; res = res->next)
-    if (stat(res->name, &statbuf) == -1)
-      {
-	if (!res->logged)
-	  my_syslog(LOG_WARNING, _("failed to access %s: %s"), res->name, strerror(errno));
-	res->logged = 1;
-      }
+    /* error pipe, debug mode. */
+    if (fd == -1)
+        fatal_event(&ev);
     else
-      {
-	res->logged = 0;
-	if (statbuf.st_mtime != res->mtime)
-	  {
-	    res->mtime = statbuf.st_mtime;
-	    if (difftime(statbuf.st_mtime, last_change) > 0.0)
-	      {
-		last_change = statbuf.st_mtime;
-		latest = res;
-	      }
-	  }
-      }
-  
-  if (latest)
-    {
-      static int warned = 0;
-      if (reload_servers(latest->name))
-	{
-	  my_syslog(LOG_INFO, _("reading %s"), latest->name);
-	  warned = 0;
-	  check_servers();
-	  if (daemon->options & OPT_RELOAD)
-	    cache_reload();
-	}
-      else 
-	{
-	  latest->mtime = 0;
-	  if (!warned)
-	    {
-	      my_syslog(LOG_WARNING, _("no servers found in %s, will retry"), latest->name);
-	      warned = 1;
-	    }
-	}
+        /* pipe is non-blocking and struct event_desc is smaller than
+           PIPE_BUF, so this either fails or writes everything */
+        while (write(fd, &ev, sizeof(ev)) == -1 && errno == EINTR)
+            ;
+}
+
+static void fatal_event(struct event_desc* ev) {
+    errno = ev->data;
+
+    switch (ev->event) {
+        case EVENT_DIE:
+            exit(0);
+
+        case EVENT_FORK_ERR:
+            die(_("cannot fork into background: %s"), NULL, EC_MISC);
+
+        case EVENT_PIPE_ERR:
+            die(_("failed to create helper: %s"), NULL, EC_MISC);
+
+        case EVENT_CAP_ERR:
+            die(_("setting capabilities failed: %s"), NULL, EC_MISC);
+
+        case EVENT_USER_ERR:
+        case EVENT_HUSER_ERR:
+            die(_("failed to change user-id to %s: %s"),
+                ev->event == EVENT_USER_ERR ? daemon->username : daemon->scriptuser, EC_MISC);
+
+        case EVENT_GROUP_ERR:
+            die(_("failed to change group-id to %s: %s"), daemon->groupname, EC_MISC);
+
+        case EVENT_PIDFILE:
+            die(_("failed to open pidfile %s: %s"), daemon->runfile, EC_FILE);
+
+        case EVENT_LOG_ERR:
+            die(_("cannot open %s: %s"), daemon->log_file ? daemon->log_file : "log", EC_FILE);
     }
-}       
+}
+
+static void async_event(int pipe, time_t now) {
+    pid_t p;
+    struct event_desc ev;
+    int i;
+
+    if (read_write(pipe, (unsigned char*) &ev, sizeof(ev), 1)) switch (ev.event) {
+            case EVENT_RELOAD:
+                clear_cache_and_reload(now);
+                if (daemon->port != 0 && daemon->resolv_files && (daemon->options & OPT_NO_POLL)) {
+                    reload_servers(daemon->resolv_files->name);
+                    check_servers();
+                }
+#ifdef HAVE_DHCP
+                rerun_scripts();
+#endif
+                break;
+
+            case EVENT_DUMP:
+                if (daemon->port != 0) dump_cache(now);
+                break;
+
+            case EVENT_ALARM:
+#ifdef HAVE_DHCP
+                if (daemon->dhcp) {
+                    lease_prune(NULL, now);
+                    lease_update_file(now);
+                }
+#endif
+                break;
+
+            case EVENT_CHILD:
+                /* See Stevens 5.10 */
+                while ((p = waitpid(-1, NULL, WNOHANG)) != 0)
+                    if (p == -1) {
+                        if (errno != EINTR) break;
+                    } else
+                        for (i = 0; i < MAX_PROCS; i++)
+                            if (daemon->tcp_pids[i] == p) daemon->tcp_pids[i] = 0;
+                break;
+
+            case EVENT_KILLED:
+                my_syslog(LOG_WARNING, _("child process killed by signal %d"), ev.data);
+                break;
+
+            case EVENT_EXITED:
+                my_syslog(LOG_WARNING, _("child process exited with status %d"), ev.data);
+                break;
+
+            case EVENT_EXEC_ERR:
+                my_syslog(LOG_ERR, _("failed to execute %s: %s"), daemon->lease_change_command,
+                          strerror(ev.data));
+                break;
+
+                /* necessary for fatal errors in helper */
+            case EVENT_HUSER_ERR:
+            case EVENT_DIE:
+                fatal_event(&ev);
+                break;
+
+            case EVENT_REOPEN:
+                /* Note: this may leave TCP-handling processes with the old file still open.
+                   Since any such process will die in CHILD_LIFETIME or probably much sooner,
+                   we leave them logging to the old file. */
+                if (daemon->log_file != NULL) log_reopen(daemon->log_file);
+                break;
+
+            case EVENT_TERM:
+                /* Knock all our children on the head. */
+                for (i = 0; i < MAX_PROCS; i++)
+                    if (daemon->tcp_pids[i] != 0) kill(daemon->tcp_pids[i], SIGALRM);
+
+#if defined(HAVE_DHCP) && defined(HAVE_SCRIPT)
+                /* handle pending lease transitions */
+                if (daemon->helperfd != -1) {
+                    /* block in writes until all done */
+                    if ((i = fcntl(daemon->helperfd, F_GETFL)) != -1)
+                        fcntl(daemon->helperfd, F_SETFL, i & ~O_NONBLOCK);
+                    do {
+                        helper_write();
+                    } while (!helper_buf_empty() || do_script_run(now));
+                    close(daemon->helperfd);
+                }
+#endif
+
+                if (daemon->lease_stream) fclose(daemon->lease_stream);
+
+                if (daemon->runfile) unlink(daemon->runfile);
+
+                my_syslog(LOG_INFO, _("exiting on receipt of SIGTERM"));
+                flush_log();
+                exit(EC_GOOD);
+        }
+}
+
+static void poll_resolv() {
+    struct resolvc *res, *latest;
+    struct stat statbuf;
+    time_t last_change = 0;
+    /* There may be more than one possible file.
+       Go through and find the one which changed _last_.
+       Warn of any which can't be read. */
+    for (latest = NULL, res = daemon->resolv_files; res; res = res->next)
+        if (stat(res->name, &statbuf) == -1) {
+            if (!res->logged)
+                my_syslog(LOG_WARNING, _("failed to access %s: %s"), res->name, strerror(errno));
+            res->logged = 1;
+        } else {
+            res->logged = 0;
+            if (statbuf.st_mtime != res->mtime) {
+                res->mtime = statbuf.st_mtime;
+                if (difftime(statbuf.st_mtime, last_change) > 0.0) {
+                    last_change = statbuf.st_mtime;
+                    latest = res;
+                }
+            }
+        }
+
+    if (latest) {
+        static int warned = 0;
+        if (reload_servers(latest->name)) {
+            my_syslog(LOG_INFO, _("reading %s"), latest->name);
+            warned = 0;
+            check_servers();
+            if (daemon->options & OPT_RELOAD) cache_reload();
+        } else {
+            latest->mtime = 0;
+            if (!warned) {
+                my_syslog(LOG_WARNING, _("no servers found in %s, will retry"), latest->name);
+                warned = 1;
+            }
+        }
+    }
+}
 
 void clear_cache_and_reload(time_t now) {
     if (daemon->port != 0) cache_reload();
@@ -877,28 +794,28 @@
 
 #ifdef __ANDROID__
 
-static int set_android_listeners(fd_set *set, int *maxfdp) {
+static int set_android_listeners(fd_set* set, int* maxfdp) {
     FD_SET(STDIN_FILENO, set);
     bump_maxfd(STDIN_FILENO, maxfdp);
     return 0;
 }
 
-static int check_android_listeners(fd_set *set) {
+static int check_android_listeners(fd_set* set) {
     int retcode = 0;
     if (FD_ISSET(STDIN_FILENO, set)) {
         char buffer[1024];
         int rc;
         int consumed = 0;
 
-        if ((rc = read(STDIN_FILENO, buffer, sizeof(buffer) -1)) < 0) {
+        if ((rc = read(STDIN_FILENO, buffer, sizeof(buffer) - 1)) < 0) {
             my_syslog(LOG_ERR, _("Error reading from stdin (%s)"), strerror(errno));
             return -1;
         }
         buffer[rc] = '\0';
-        while(consumed < rc) {
-            char *cmd;
-            char *current_cmd = &buffer[consumed];
-            char *params = current_cmd;
+        while (consumed < rc) {
+            char* cmd;
+            char* current_cmd = &buffer[consumed];
+            char* params = current_cmd;
             int len = strlen(current_cmd);
 
             cmd = strsep(&params, "|");
@@ -918,8 +835,8 @@
                     retcode = -1;
                 }
             } else {
-                 my_syslog(LOG_ERR, _("Unknown cmd '%s'"), cmd);
-                 retcode = -1;
+                my_syslog(LOG_ERR, _("Unknown cmd '%s'"), cmd);
+                retcode = -1;
             }
             consumed += len + 1;
         }
@@ -928,294 +845,258 @@
 }
 #endif
 
-static int set_dns_listeners(time_t now, fd_set *set, int *maxfdp)
-{
-  struct serverfd *serverfdp;
-  struct listener *listener;
-  int wait = 0, i;
+static int set_dns_listeners(time_t now, fd_set* set, int* maxfdp) {
+    struct serverfd* serverfdp;
+    struct listener* listener;
+    int wait = 0, i;
 
-  /* will we be able to get memory? */
-  if (daemon->port != 0)
-    get_new_frec(now, &wait);
-  
-  for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
-    {
-      FD_SET(serverfdp->fd, set);
-      bump_maxfd(serverfdp->fd, maxfdp);
+    /* will we be able to get memory? */
+    if (daemon->port != 0) get_new_frec(now, &wait);
+
+    for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next) {
+        FD_SET(serverfdp->fd, set);
+        bump_maxfd(serverfdp->fd, maxfdp);
     }
 
-  if (daemon->port != 0 && !daemon->osport)
-    for (i = 0; i < RANDOM_SOCKS; i++)
-      if (daemon->randomsocks[i].refcount != 0)
-	{
-	  FD_SET(daemon->randomsocks[i].fd, set);
-	  bump_maxfd(daemon->randomsocks[i].fd, maxfdp);
-	}
-  
-  for (listener = daemon->listeners; listener; listener = listener->next)
-    {
-      /* only listen for queries if we have resources */
-      if (listener->fd != -1 && wait == 0)
-	{
-	  FD_SET(listener->fd, set);
-	  bump_maxfd(listener->fd, maxfdp);
-	}
+    if (daemon->port != 0 && !daemon->osport)
+        for (i = 0; i < RANDOM_SOCKS; i++)
+            if (daemon->randomsocks[i].refcount != 0) {
+                FD_SET(daemon->randomsocks[i].fd, set);
+                bump_maxfd(daemon->randomsocks[i].fd, maxfdp);
+            }
 
-      /* death of a child goes through the select loop, so
-	 we don't need to explicitly arrange to wake up here */
-      if  (listener->tcpfd != -1)
-	for (i = 0; i < MAX_PROCS; i++)
-	  if (daemon->tcp_pids[i] == 0)
-	    {
-	      FD_SET(listener->tcpfd, set);
-	      bump_maxfd(listener->tcpfd, maxfdp);
-	      break;
-	    }
+    for (listener = daemon->listeners; listener; listener = listener->next) {
+        /* only listen for queries if we have resources */
+        if (listener->fd != -1 && wait == 0) {
+            FD_SET(listener->fd, set);
+            bump_maxfd(listener->fd, maxfdp);
+        }
+
+        /* death of a child goes through the select loop, so
+       we don't need to explicitly arrange to wake up here */
+        if (listener->tcpfd != -1)
+            for (i = 0; i < MAX_PROCS; i++)
+                if (daemon->tcp_pids[i] == 0) {
+                    FD_SET(listener->tcpfd, set);
+                    bump_maxfd(listener->tcpfd, maxfdp);
+                    break;
+                }
     }
-  
-  return wait;
+
+    return wait;
 }
 
-static void check_dns_listeners(fd_set *set, time_t now)
-{
-  struct serverfd *serverfdp;
-  struct listener *listener;
-  int i;
+static void check_dns_listeners(fd_set* set, time_t now) {
+    struct serverfd* serverfdp;
+    struct listener* listener;
+    int i;
 
-  for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
-    if (FD_ISSET(serverfdp->fd, set))
-      reply_query(serverfdp->fd, serverfdp->source_addr.sa.sa_family, now);
-  
-  if (daemon->port != 0 && !daemon->osport)
-    for (i = 0; i < RANDOM_SOCKS; i++)
-      if (daemon->randomsocks[i].refcount != 0 && 
-	  FD_ISSET(daemon->randomsocks[i].fd, set))
-	reply_query(daemon->randomsocks[i].fd, daemon->randomsocks[i].family, now);
-  
-  for (listener = daemon->listeners; listener; listener = listener->next)
-    {
-      if (listener->fd != -1 && FD_ISSET(listener->fd, set))
-	receive_query(listener, now); 
+    for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
+        if (FD_ISSET(serverfdp->fd, set))
+            reply_query(serverfdp->fd, serverfdp->source_addr.sa.sa_family, now);
 
-      if (listener->tcpfd != -1 && FD_ISSET(listener->tcpfd, set))
-	{
-	  int confd;
-	  struct irec *iface = NULL;
-	  pid_t p;
-	  
-	  while((confd = accept(listener->tcpfd, NULL, NULL)) == -1 && errno == EINTR);
-	  
-	  if (confd == -1)
-	    continue;
-	  
-	  if (daemon->options & OPT_NOWILD)
-	    iface = listener->iface;
-	  else
-	    {
-	      union mysockaddr tcp_addr;
-	      socklen_t tcp_len = sizeof(union mysockaddr);
-	      /* Check for allowed interfaces when binding the wildcard address:
-		 we do this by looking for an interface with the same address as 
-		 the local address of the TCP connection, then looking to see if that's
-		 an allowed interface. As a side effect, we get the netmask of the
-		 interface too, for localisation. */
-	      
-	      /* interface may be new since startup */
-	      if (enumerate_interfaces() &&
-		  getsockname(confd, (struct sockaddr *)&tcp_addr, &tcp_len) != -1)
-		for (iface = daemon->interfaces; iface; iface = iface->next)
-		  if (sockaddr_isequal(&iface->addr, &tcp_addr))
-		    break;
-	    }
-	  
-	  if (!iface)
-	    {
-	      shutdown(confd, SHUT_RDWR);
-	      close(confd);
-	    }
+    if (daemon->port != 0 && !daemon->osport)
+        for (i = 0; i < RANDOM_SOCKS; i++)
+            if (daemon->randomsocks[i].refcount != 0 && FD_ISSET(daemon->randomsocks[i].fd, set))
+                reply_query(daemon->randomsocks[i].fd, daemon->randomsocks[i].family, now);
+
+    for (listener = daemon->listeners; listener; listener = listener->next) {
+        if (listener->fd != -1 && FD_ISSET(listener->fd, set)) receive_query(listener, now);
+
+        if (listener->tcpfd != -1 && FD_ISSET(listener->tcpfd, set)) {
+            int confd;
+            struct irec* iface = NULL;
+            pid_t p;
+
+            while ((confd = accept(listener->tcpfd, NULL, NULL)) == -1 && errno == EINTR)
+                ;
+
+            if (confd == -1) continue;
+
+            if (daemon->options & OPT_NOWILD)
+                iface = listener->iface;
+            else {
+                union mysockaddr tcp_addr;
+                socklen_t tcp_len = sizeof(union mysockaddr);
+                /* Check for allowed interfaces when binding the wildcard address:
+               we do this by looking for an interface with the same address as
+               the local address of the TCP connection, then looking to see if that's
+               an allowed interface. As a side effect, we get the netmask of the
+               interface too, for localisation. */
+
+                /* interface may be new since startup */
+                if (enumerate_interfaces() &&
+                    getsockname(confd, (struct sockaddr*) &tcp_addr, &tcp_len) != -1)
+                    for (iface = daemon->interfaces; iface; iface = iface->next)
+                        if (sockaddr_isequal(&iface->addr, &tcp_addr)) break;
+            }
+
+            if (!iface) {
+                shutdown(confd, SHUT_RDWR);
+                close(confd);
+            }
 #ifndef NO_FORK
-	  else if (!(daemon->options & OPT_DEBUG) && (p = fork()) != 0)
-	    {
-	      if (p != -1)
-		{
-		  int i;
-		  for (i = 0; i < MAX_PROCS; i++)
-		    if (daemon->tcp_pids[i] == 0)
-		      {
-			daemon->tcp_pids[i] = p;
-			break;
-		      }
-		}
-	      close(confd);
-	    }
+            else if (!(daemon->options & OPT_DEBUG) && (p = fork()) != 0) {
+                if (p != -1) {
+                    int i;
+                    for (i = 0; i < MAX_PROCS; i++)
+                        if (daemon->tcp_pids[i] == 0) {
+                            daemon->tcp_pids[i] = p;
+                            break;
+                        }
+                }
+                close(confd);
+            }
 #endif
-	  else
-	    {
-	      unsigned char *buff;
-	      struct server *s; 
-	      int flags;
-	      struct in_addr dst_addr_4;
-	      
-	      dst_addr_4.s_addr = 0;
-	      
-	       /* Arrange for SIGALARM after CHILD_LIFETIME seconds to
-		  terminate the process. */
-	      if (!(daemon->options & OPT_DEBUG))
-		alarm(CHILD_LIFETIME);
-	      
-	      /* start with no upstream connections. */
-	      for (s = daemon->servers; s; s = s->next)
-		 s->tcpfd = -1; 
-	      
-	      /* The connected socket inherits non-blocking
-		 attribute from the listening socket. 
-		 Reset that here. */
-	      if ((flags = fcntl(confd, F_GETFL, 0)) != -1)
-		fcntl(confd, F_SETFL, flags & ~O_NONBLOCK);
-	      
-	      if (listener->family == AF_INET)
-		dst_addr_4 = iface->addr.in.sin_addr;
-	      
-	      buff = tcp_request(confd, now, dst_addr_4, iface->netmask);
-	       
-	      shutdown(confd, SHUT_RDWR);
-	      close(confd);
-	      
-	      if (buff)
-		free(buff);
-	      
-	      for (s = daemon->servers; s; s = s->next)
-		if (s->tcpfd != -1)
-		  {
-		    shutdown(s->tcpfd, SHUT_RDWR);
-		    close(s->tcpfd);
-		  }
-#ifndef NO_FORK		   
-	      if (!(daemon->options & OPT_DEBUG))
-		{
-		  flush_log();
-		  _exit(0);
-		}
+            else {
+                unsigned char* buff;
+                struct server* s;
+                int flags;
+                struct in_addr dst_addr_4;
+
+                dst_addr_4.s_addr = 0;
+
+                /* Arrange for SIGALARM after CHILD_LIFETIME seconds to
+               terminate the process. */
+                if (!(daemon->options & OPT_DEBUG)) alarm(CHILD_LIFETIME);
+
+                /* start with no upstream connections. */
+                for (s = daemon->servers; s; s = s->next) s->tcpfd = -1;
+
+                /* The connected socket inherits non-blocking
+               attribute from the listening socket.
+               Reset that here. */
+                if ((flags = fcntl(confd, F_GETFL, 0)) != -1)
+                    fcntl(confd, F_SETFL, flags & ~O_NONBLOCK);
+
+                if (listener->family == AF_INET) dst_addr_4 = iface->addr.in.sin_addr;
+
+                buff = tcp_request(confd, now, dst_addr_4, iface->netmask);
+
+                shutdown(confd, SHUT_RDWR);
+                close(confd);
+
+                if (buff) free(buff);
+
+                for (s = daemon->servers; s; s = s->next)
+                    if (s->tcpfd != -1) {
+                        shutdown(s->tcpfd, SHUT_RDWR);
+                        close(s->tcpfd);
+                    }
+#ifndef NO_FORK
+                if (!(daemon->options & OPT_DEBUG)) {
+                    flush_log();
+                    _exit(0);
+                }
 #endif
-	    }
-	}
+            }
+        }
     }
 }
 
 #ifdef HAVE_DHCP
-int make_icmp_sock(void)
-{
-  int fd;
-  int zeroopt = 0;
+int make_icmp_sock(void) {
+    int fd;
+    int zeroopt = 0;
 
-  if ((fd = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP)) != -1)
-    {
-      if (!fix_fd(fd) ||
-	  setsockopt(fd, SOL_SOCKET, SO_DONTROUTE, &zeroopt, sizeof(zeroopt)) == -1)
-	{
-	  close(fd);
-	  fd = -1;
-	}
+    if ((fd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) != -1) {
+        if (!fix_fd(fd) ||
+            setsockopt(fd, SOL_SOCKET, SO_DONTROUTE, &zeroopt, sizeof(zeroopt)) == -1) {
+            close(fd);
+            fd = -1;
+        }
     }
 
-  return fd;
+    return fd;
 }
 
-int icmp_ping(struct in_addr addr)
-{
-  /* Try and get an ICMP echo from a machine. */
+int icmp_ping(struct in_addr addr) {
+    /* Try and get an ICMP echo from a machine. */
 
-  /* Note that whilst in the three second wait, we check for 
-     (and service) events on the DNS sockets, (so doing that
-     better not use any resources our caller has in use...)
-     but we remain deaf to signals or further DHCP packets. */
+    /* Note that whilst in the three second wait, we check for
+       (and service) events on the DNS sockets, (so doing that
+       better not use any resources our caller has in use...)
+       but we remain deaf to signals or further DHCP packets. */
 
-  int fd;
-  struct sockaddr_in saddr;
-  struct { 
-    struct ip ip;
-    struct icmp icmp;
-  } packet;
-  unsigned short id = rand16();
-  unsigned int i, j;
-  int gotreply = 0;
-  time_t start, now;
+    int fd;
+    struct sockaddr_in saddr;
+    struct {
+        struct ip ip;
+        struct icmp icmp;
+    } packet;
+    unsigned short id = rand16();
+    unsigned int i, j;
+    int gotreply = 0;
+    time_t start, now;
 
 #if defined(HAVE_LINUX_NETWORK)
-  if ((fd = make_icmp_sock()) == -1)
-    return 0;
+    if ((fd = make_icmp_sock()) == -1) return 0;
 #else
-  int opt = 2000;
-  fd = daemon->dhcp_icmp_fd;
-  setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
+    int opt = 2000;
+    fd = daemon->dhcp_icmp_fd;
+    setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
 #endif
 
-  saddr.sin_family = AF_INET;
-  saddr.sin_port = 0;
-  saddr.sin_addr = addr;
+    saddr.sin_family = AF_INET;
+    saddr.sin_port = 0;
+    saddr.sin_addr = addr;
 
-  memset(&packet.icmp, 0, sizeof(packet.icmp));
-  packet.icmp.icmp_type = ICMP_ECHO;
-  packet.icmp.icmp_id = id;
-  for (j = 0, i = 0; i < sizeof(struct icmp) / 2; i++)
-    j += ((u16 *)&packet.icmp)[i];
-  while (j>>16)
-    j = (j & 0xffff) + (j >> 16);  
-  packet.icmp.icmp_cksum = (j == 0xffff) ? j : ~j;
-  
-  while (sendto(fd, (char *)&packet.icmp, sizeof(struct icmp), 0, 
-		(struct sockaddr *)&saddr, sizeof(saddr)) == -1 &&
-	 retry_send());
-  
-  for (now = start = dnsmasq_time(); 
-       difftime(now, start) < (float)PING_WAIT;)
-    {
-      struct timeval tv;
-      fd_set rset, wset;
-      struct sockaddr_in faddr;
-      int maxfd = fd; 
-      socklen_t len = sizeof(faddr);
-      
-      tv.tv_usec = 250000;
-      tv.tv_sec = 0; 
-      
-      FD_ZERO(&rset);
-      FD_ZERO(&wset);
-      FD_SET(fd, &rset);
-      set_dns_listeners(now, &rset, &maxfd);
-      set_log_writer(&wset, &maxfd);
+    memset(&packet.icmp, 0, sizeof(packet.icmp));
+    packet.icmp.icmp_type = ICMP_ECHO;
+    packet.icmp.icmp_id = id;
+    for (j = 0, i = 0; i < sizeof(struct icmp) / 2; i++) j += ((u16*) &packet.icmp)[i];
+    while (j >> 16) j = (j & 0xffff) + (j >> 16);
+    packet.icmp.icmp_cksum = (j == 0xffff) ? j : ~j;
 
-      if (select(maxfd+1, &rset, &wset, NULL, &tv) < 0)
-	{
-	  FD_ZERO(&rset);
-	  FD_ZERO(&wset);
-	}
+    while (sendto(fd, (char*) &packet.icmp, sizeof(struct icmp), 0, (struct sockaddr*) &saddr,
+                  sizeof(saddr)) == -1 &&
+           retry_send())
+        ;
 
-      now = dnsmasq_time();
+    for (now = start = dnsmasq_time(); difftime(now, start) < (float) PING_WAIT;) {
+        struct timeval tv;
+        fd_set rset, wset;
+        struct sockaddr_in faddr;
+        int maxfd = fd;
+        socklen_t len = sizeof(faddr);
 
-      check_log_writer(&wset);
-      check_dns_listeners(&rset, now);
+        tv.tv_usec = 250000;
+        tv.tv_sec = 0;
 
-      if (FD_ISSET(fd, &rset) &&
-	  recvfrom(fd, &packet, sizeof(packet), 0,
-		   (struct sockaddr *)&faddr, &len) == sizeof(packet) &&
-	  saddr.sin_addr.s_addr == faddr.sin_addr.s_addr &&
-	  packet.icmp.icmp_type == ICMP_ECHOREPLY &&
-	  packet.icmp.icmp_seq == 0 &&
-	  packet.icmp.icmp_id == id)
-	{
-	  gotreply = 1;
-	  break;
-	}
+        FD_ZERO(&rset);
+        FD_ZERO(&wset);
+        FD_SET(fd, &rset);
+        set_dns_listeners(now, &rset, &maxfd);
+        set_log_writer(&wset, &maxfd);
+
+        if (select(maxfd + 1, &rset, &wset, NULL, &tv) < 0) {
+            FD_ZERO(&rset);
+            FD_ZERO(&wset);
+        }
+
+        now = dnsmasq_time();
+
+        check_log_writer(&wset);
+        check_dns_listeners(&rset, now);
+
+        if (FD_ISSET(fd, &rset) &&
+            recvfrom(fd, &packet, sizeof(packet), 0, (struct sockaddr*) &faddr, &len) ==
+                sizeof(packet) &&
+            saddr.sin_addr.s_addr == faddr.sin_addr.s_addr &&
+            packet.icmp.icmp_type == ICMP_ECHOREPLY && packet.icmp.icmp_seq == 0 &&
+            packet.icmp.icmp_id == id) {
+            gotreply = 1;
+            break;
+        }
     }
-  
+
 #if defined(HAVE_LINUX_NETWORK)
-  close(fd);
+    close(fd);
 #else
-  opt = 1;
-  setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
+    opt = 1;
+    setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
 #endif
 
-  return gotreply;
+    return gotreply;
 }
 #endif
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 99b683c..2c5f964 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -1,49 +1,49 @@
 /* dnsmasq is Copyright (c) 2000-2009 Simon Kelley
- 
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; version 2 dated June, 1991, or
    (at your option) version 3 dated 29 June, 2007.
- 
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-     
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#define COPYRIGHT "Copyright (C) 2000-2009 Simon Kelley" 
+#define COPYRIGHT "Copyright (C) 2000-2009 Simon Kelley"
 
 #ifndef NO_LARGEFILE
 /* Ensure we can use files >2GB (log files may grow this big) */
-#  define _LARGEFILE_SOURCE 1
-#  define _FILE_OFFSET_BITS 64
+#define _LARGEFILE_SOURCE 1
+#define _FILE_OFFSET_BITS 64
 #endif
 
 /* Get linux C library versions. */
 #ifdef __linux__
-#  ifndef __ANDROID__
-#      define _GNU_SOURCE
-#  endif
-#  include <features.h> 
+#ifndef __ANDROID__
+#define _GNU_SOURCE
+#endif
+#include <features.h>
 #endif
 
 /* get these before config.h  for IPv6 stuff... */
-#include <sys/types.h> 
-#include <sys/socket.h>
 #include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/types.h>
 
 #ifdef __APPLE__
-#  include <nameser.h>
-#  include <arpa/nameser_compat.h>
+#include <arpa/nameser_compat.h>
+#include <nameser.h>
 #else
-#  ifdef __ANDROID__
-#    include "nameser.h"
-#  else
-#    include <arpa/nameser.h>
-#  endif
+#ifdef __ANDROID__
+#include "nameser.h"
+#else
+#include <arpa/nameser.h>
+#endif
 #endif
 
 /* and this. */
@@ -53,60 +53,61 @@
 
 #define gettext_noop(S) (S)
 #ifndef LOCALEDIR
-#  define _(S) (S)
+#define _(S) (S)
 #else
-#  include <libintl.h>
-#  include <locale.h>   
-#  define _(S) gettext(S)
+#include <libintl.h>
+#include <locale.h>
+#define _(S) gettext(S)
 #endif
 
 #include <arpa/inet.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/select.h>
-#include <sys/wait.h>
-#include <sys/time.h>
-#include <sys/un.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <grp.h>
 #include <limits.h>
 #include <net/if.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <signal.h>
-#include <stddef.h>
-#include <time.h>
-#include <errno.h>
 #include <pwd.h>
-#include <grp.h>
+#include <signal.h>
 #include <stdarg.h>
-#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__sun__) || defined (__sun) || defined (__ANDROID__)
-#  include <netinet/if_ether.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/select.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/un.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__sun__) || defined(__sun) || \
+    defined(__ANDROID__)
+#include <netinet/if_ether.h>
 #else
-#  include <net/ethernet.h>
+#include <net/ethernet.h>
 #endif
+#include <dirent.h>
 #include <net/if_arp.h>
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
 #include <netinet/ip_icmp.h>
 #include <sys/uio.h>
 #include <syslog.h>
-#include <dirent.h>
 #ifndef HAVE_LINUX_NETWORK
-#  include <net/if_dl.h>
+#include <net/if_dl.h>
 #endif
 
 #if defined(HAVE_LINUX_NETWORK)
 #include <linux/capability.h>
-/* There doesn't seem to be a universally-available 
+/* There doesn't seem to be a universally-available
    userpace header for these. */
 extern int capset(cap_user_header_t header, cap_user_data_t data);
 extern int capget(cap_user_header_t header, cap_user_data_t data);
-#define LINUX_CAPABILITY_VERSION_1  0x19980330
-#define LINUX_CAPABILITY_VERSION_2  0x20071026
-#define LINUX_CAPABILITY_VERSION_3  0x20080522
+#define LINUX_CAPABILITY_VERSION_1 0x19980330
+#define LINUX_CAPABILITY_VERSION_2 0x20071026
+#define LINUX_CAPABILITY_VERSION_3 0x20080522
 
 #include <sys/prctl.h>
 #endif
@@ -116,667 +117,653 @@
 
 /* Async event queue */
 struct event_desc {
-  int event, data;
+    int event, data;
 };
 
-#define EVENT_RELOAD    1
-#define EVENT_DUMP      2
-#define EVENT_ALARM     3
-#define EVENT_TERM      4
-#define EVENT_CHILD     5
-#define EVENT_REOPEN    6
-#define EVENT_EXITED    7
-#define EVENT_KILLED    8
-#define EVENT_EXEC_ERR  9
-#define EVENT_PIPE_ERR  10
-#define EVENT_USER_ERR  11
-#define EVENT_CAP_ERR   12
-#define EVENT_PIDFILE   13
+#define EVENT_RELOAD 1
+#define EVENT_DUMP 2
+#define EVENT_ALARM 3
+#define EVENT_TERM 4
+#define EVENT_CHILD 5
+#define EVENT_REOPEN 6
+#define EVENT_EXITED 7
+#define EVENT_KILLED 8
+#define EVENT_EXEC_ERR 9
+#define EVENT_PIPE_ERR 10
+#define EVENT_USER_ERR 11
+#define EVENT_CAP_ERR 12
+#define EVENT_PIDFILE 13
 #define EVENT_HUSER_ERR 14
 #define EVENT_GROUP_ERR 15
-#define EVENT_DIE       16
-#define EVENT_LOG_ERR   17
-#define EVENT_FORK_ERR  18
+#define EVENT_DIE 16
+#define EVENT_LOG_ERR 17
+#define EVENT_FORK_ERR 18
 
 /* Exit codes. */
-#define EC_GOOD        0
-#define EC_BADCONF     1
-#define EC_BADNET      2
-#define EC_FILE        3
-#define EC_NOMEM       4
-#define EC_MISC        5
+#define EC_GOOD 0
+#define EC_BADCONF 1
+#define EC_BADNET 2
+#define EC_FILE 3
+#define EC_NOMEM 4
+#define EC_MISC 5
 #define EC_INIT_OFFSET 10
 
-/* Min buffer size: we check after adding each record, so there must be 
+/* Min buffer size: we check after adding each record, so there must be
    memory for the largest packet, and the largest record so the
    min for DNS is PACKETSZ+MAXDNAME+RRFIXEDSZ which is < 1000.
    This might be increased is EDNS packet size if greater than the minimum.
 */
-#define DNSMASQ_PACKETSZ PACKETSZ+MAXDNAME+RRFIXEDSZ
+#define DNSMASQ_PACKETSZ PACKETSZ + MAXDNAME + RRFIXEDSZ
 
-#define OPT_BOGUSPRIV      (1u<<0)
-#define OPT_FILTER         (1u<<1)
-#define OPT_LOG            (1u<<2)
-#define OPT_SELFMX         (1u<<3)
-#define OPT_NO_HOSTS       (1u<<4)
-#define OPT_NO_POLL        (1u<<5)
-#define OPT_DEBUG          (1u<<6)
-#define OPT_ORDER          (1u<<7)
-#define OPT_NO_RESOLV      (1u<<8)
-#define OPT_EXPAND         (1u<<9)
-#define OPT_LOCALMX        (1u<<10)
-#define OPT_NO_NEG         (1u<<11)
-#define OPT_NODOTS_LOCAL   (1u<<12)
-#define OPT_NOWILD         (1u<<13)
-#define OPT_RESOLV_DOMAIN  (1u<<15)
-#define OPT_NO_FORK        (1u<<16)
-#define OPT_AUTHORITATIVE  (1u<<17)
-#define OPT_LOCALISE       (1u<<18)
-#define OPT_DBUS           (1u<<19)
-#define OPT_DHCP_FQDN      (1u<<20)
-#define OPT_NO_PING        (1u<<21)
-#define OPT_LEASE_RO       (1u<<22)
-#define OPT_ALL_SERVERS    (1u<<23)
-#define OPT_RELOAD         (1u<<24)
-#define OPT_TFTP           (1u<<25)
-#define OPT_TFTP_SECURE    (1u<<26)
-#define OPT_TFTP_NOBLOCK   (1u<<27)
-#define OPT_LOG_OPTS       (1u<<28)
-#define OPT_TFTP_APREF     (1u<<29)
-#define OPT_NO_OVERRIDE    (1u<<30)
-#define OPT_NO_REBIND      (1u<<31)
+#define OPT_BOGUSPRIV (1u << 0)
+#define OPT_FILTER (1u << 1)
+#define OPT_LOG (1u << 2)
+#define OPT_SELFMX (1u << 3)
+#define OPT_NO_HOSTS (1u << 4)
+#define OPT_NO_POLL (1u << 5)
+#define OPT_DEBUG (1u << 6)
+#define OPT_ORDER (1u << 7)
+#define OPT_NO_RESOLV (1u << 8)
+#define OPT_EXPAND (1u << 9)
+#define OPT_LOCALMX (1u << 10)
+#define OPT_NO_NEG (1u << 11)
+#define OPT_NODOTS_LOCAL (1u << 12)
+#define OPT_NOWILD (1u << 13)
+#define OPT_RESOLV_DOMAIN (1u << 15)
+#define OPT_NO_FORK (1u << 16)
+#define OPT_AUTHORITATIVE (1u << 17)
+#define OPT_LOCALISE (1u << 18)
+#define OPT_DBUS (1u << 19)
+#define OPT_DHCP_FQDN (1u << 20)
+#define OPT_NO_PING (1u << 21)
+#define OPT_LEASE_RO (1u << 22)
+#define OPT_ALL_SERVERS (1u << 23)
+#define OPT_RELOAD (1u << 24)
+#define OPT_TFTP (1u << 25)
+#define OPT_TFTP_SECURE (1u << 26)
+#define OPT_TFTP_NOBLOCK (1u << 27)
+#define OPT_LOG_OPTS (1u << 28)
+#define OPT_TFTP_APREF (1u << 29)
+#define OPT_NO_OVERRIDE (1u << 30)
+#define OPT_NO_REBIND (1u << 31)
 
-/* extra flags for my_syslog, we use a couple of facilities since they are known 
+/* extra flags for my_syslog, we use a couple of facilities since they are known
    not to occupy the same bits as priorities, no matter how syslog.h is set up. */
 #define MS_TFTP LOG_USER
-#define MS_DHCP LOG_DAEMON 
+#define MS_DHCP LOG_DAEMON
 
 struct all_addr {
-  union {
-    struct in_addr addr4;
+    union {
+        struct in_addr addr4;
 #ifdef HAVE_IPV6
-    struct in6_addr addr6;
+        struct in6_addr addr6;
 #endif
-  } addr;
+    } addr;
 };
 
 struct bogus_addr {
-  struct in_addr addr;
-  struct bogus_addr *next;
+    struct in_addr addr;
+    struct bogus_addr* next;
 };
 
 /* dns doctor param */
 struct doctor {
-  struct in_addr in, end, out, mask;
-  struct doctor *next;
+    struct in_addr in, end, out, mask;
+    struct doctor* next;
 };
 
 struct mx_srv_record {
-  char *name, *target;
-  int issrv, srvport, priority, weight;
-  unsigned int offset;
-  struct mx_srv_record *next;
+    char *name, *target;
+    int issrv, srvport, priority, weight;
+    unsigned int offset;
+    struct mx_srv_record* next;
 };
 
 struct naptr {
-  char *name, *replace, *regexp, *services, *flags;
-  unsigned int order, pref;
-  struct naptr *next;
+    char *name, *replace, *regexp, *services, *flags;
+    unsigned int order, pref;
+    struct naptr* next;
 };
 
 struct txt_record {
-  char *name, *txt;
-  unsigned short class, len;
-  struct txt_record *next;
+    char *name, *txt;
+    unsigned short class, len;
+    struct txt_record* next;
 };
 
 struct ptr_record {
-  char *name, *ptr;
-  struct ptr_record *next;
+    char *name, *ptr;
+    struct ptr_record* next;
 };
 
 struct cname {
-  char *alias, *target;
-  struct cname *next;
+    char *alias, *target;
+    struct cname* next;
 };
 
 struct interface_name {
-  char *name; /* domain name */
-  char *intr; /* interface name */
-  struct interface_name *next;
+    char* name; /* domain name */
+    char* intr; /* interface name */
+    struct interface_name* next;
 };
 
 union bigname {
-  char name[MAXDNAME];
-  union bigname *next; /* freelist */
+    char name[MAXDNAME];
+    union bigname* next; /* freelist */
 };
 
-struct crec { 
-  struct crec *next, *prev, *hash_next;
-  time_t ttd; /* time to die */
-  int uid; 
-  union {
-    struct all_addr addr;
-    struct {
-      struct crec *cache;
-      int uid;
-    } cname;
-  } addr;
-  unsigned short flags;
-  union {
-    char sname[SMALLDNAME];
-    union bigname *bname;
-    char *namep;
-  } name;
+struct crec {
+    struct crec *next, *prev, *hash_next;
+    time_t ttd; /* time to die */
+    int uid;
+    union {
+        struct all_addr addr;
+        struct {
+            struct crec* cache;
+            int uid;
+        } cname;
+    } addr;
+    unsigned short flags;
+    union {
+        char sname[SMALLDNAME];
+        union bigname* bname;
+        char* namep;
+    } name;
 };
 
-#define F_IMMORTAL  1
-#define F_CONFIG    2
-#define F_REVERSE   4
-#define F_FORWARD   8
-#define F_DHCP      16 
-#define F_NEG       32       
-#define F_HOSTS     64
-#define F_IPV4      128
-#define F_IPV6      256
-#define F_BIGNAME   512
-#define F_UPSTREAM  1024
-#define F_SERVER    2048
-#define F_NXDOMAIN  4096
-#define F_QUERY     8192
-#define F_CNAME     16384
-#define F_NOERR     32768
+#define F_IMMORTAL 1
+#define F_CONFIG 2
+#define F_REVERSE 4
+#define F_FORWARD 8
+#define F_DHCP 16
+#define F_NEG 32
+#define F_HOSTS 64
+#define F_IPV4 128
+#define F_IPV6 256
+#define F_BIGNAME 512
+#define F_UPSTREAM 1024
+#define F_SERVER 2048
+#define F_NXDOMAIN 4096
+#define F_QUERY 8192
+#define F_CNAME 16384
+#define F_NOERR 32768
 
 /* struct sockaddr is not large enough to hold any address,
    and specifically not big enough to hold an IPv6 address.
    Blech. Roll our own. */
 union mysockaddr {
-  struct sockaddr sa;
-  struct sockaddr_in in;
+    struct sockaddr sa;
+    struct sockaddr_in in;
 #if defined(HAVE_IPV6)
-  struct sockaddr_in6 in6;
+    struct sockaddr_in6 in6;
 #endif
 };
 
-#define SERV_FROM_RESOLV       1  /* 1 for servers from resolv, 0 for command line. */
-#define SERV_NO_ADDR           2  /* no server, this domain is local only */
-#define SERV_LITERAL_ADDRESS   4  /* addr is the answer, not the server */ 
-#define SERV_HAS_DOMAIN        8  /* server for one domain only */
-#define SERV_HAS_SOURCE       16  /* source address defined */
-#define SERV_FOR_NODOTS       32  /* server for names with no domain part only */
-#define SERV_WARNED_RECURSIVE 64  /* avoid warning spam */
-#define SERV_FROM_DBUS       128  /* 1 if source is DBus */
-#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_FROM_RESOLV 1       /* 1 for servers from resolv, 0 for command line. */
+#define SERV_NO_ADDR 2           /* no server, this domain is local only */
+#define SERV_LITERAL_ADDRESS 4   /* addr is the answer, not the server */
+#define SERV_HAS_DOMAIN 8        /* server for one domain only */
+#define SERV_HAS_SOURCE 16       /* source address defined */
+#define SERV_FOR_NODOTS 32       /* server for names with no domain part only */
+#define SERV_WARNED_RECURSIVE 64 /* avoid warning spam */
+#define SERV_FROM_DBUS 128       /* 1 if source is DBus */
+#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 */
 
 struct serverfd {
-  int fd;
-  union mysockaddr source_addr;
-  char interface[IF_NAMESIZE+1];
-  struct serverfd *next;
-  uint32_t mark;
+    int fd;
+    union mysockaddr source_addr;
+    char interface[IF_NAMESIZE + 1];
+    struct serverfd* next;
+    uint32_t mark;
 };
 
 struct randfd {
-  int fd;
-  unsigned short refcount, family;
+    int fd;
+    unsigned short refcount, family;
 };
-  
+
 struct server {
-  union mysockaddr addr, source_addr;
-  char interface[IF_NAMESIZE+1];
-  struct serverfd *sfd; 
-  char *domain; /* set if this server only handles a domain. */ 
-  int flags, tcpfd;
-  unsigned int queries, failed_queries;
-  uint32_t mark;
-  struct server *next; 
+    union mysockaddr addr, source_addr;
+    char interface[IF_NAMESIZE + 1];
+    struct serverfd* sfd;
+    char* domain; /* set if this server only handles a domain. */
+    int flags, tcpfd;
+    unsigned int queries, failed_queries;
+    uint32_t mark;
+    struct server* next;
 };
 
 struct irec {
-  union mysockaddr addr;
-  struct in_addr netmask; /* only valid for IPv4 */
-  int dhcp_ok, mtu;
-  struct irec *next;
+    union mysockaddr addr;
+    struct in_addr netmask; /* only valid for IPv4 */
+    int dhcp_ok, mtu;
+    struct irec* next;
 };
 
 struct listener {
-  int fd, tcpfd, family;
-  struct irec *iface; /* only valid for non-wildcard */
-  struct listener *next;
+    int fd, tcpfd, family;
+    struct irec* iface; /* only valid for non-wildcard */
+    struct listener* next;
 };
 
 /* interface and address parms from command line. */
 struct iname {
-  char *name;
-  union mysockaddr addr;
-  int isloop, used;
-  struct iname *next;
+    char* name;
+    union mysockaddr addr;
+    int isloop, used;
+    struct iname* next;
 };
 
 /* resolv-file parms from command-line */
 struct resolvc {
-  struct resolvc *next;
-  int is_default, logged;
-  time_t mtime;
-  char *name;
+    struct resolvc* next;
+    int is_default, logged;
+    time_t mtime;
+    char* name;
 };
 
 /* adn-hosts parms from command-line */
-#define AH_DIR      1
+#define AH_DIR 1
 #define AH_INACTIVE 2
 struct hostsfile {
-  struct hostsfile *next;
-  int flags;
-  char *fname;
-  int index; /* matches to cache entries for logging */
+    struct hostsfile* next;
+    int flags;
+    char* fname;
+    int index; /* matches to cache entries for logging */
 };
 
 struct frec {
-  union mysockaddr source;
-  struct all_addr dest;
-  struct server *sentto; /* NULL means free */
-  struct randfd *rfd4;
+    union mysockaddr source;
+    struct all_addr dest;
+    struct server* sentto; /* NULL means free */
+    struct randfd* rfd4;
 #ifdef HAVE_IPV6
-  struct randfd *rfd6;
+    struct randfd* rfd6;
 #endif
-  unsigned int iface;
-  unsigned short orig_id, new_id;
-  int fd, forwardall;
-  unsigned int crc;
-  time_t time;
-  struct frec *next;
+    unsigned int iface;
+    unsigned short orig_id, new_id;
+    int fd, forwardall;
+    unsigned int crc;
+    time_t time;
+    struct frec* next;
 };
 
 /* actions in the daemon->helper RPC */
-#define ACTION_DEL           1
-#define ACTION_OLD_HOSTNAME  2
-#define ACTION_OLD           3
-#define ACTION_ADD           4
+#define ACTION_DEL 1
+#define ACTION_OLD_HOSTNAME 2
+#define ACTION_OLD 3
+#define ACTION_ADD 4
 
 #define DHCP_CHADDR_MAX 16
 
 struct dhcp_lease {
-  int clid_len;          /* length of client identifier */
-  unsigned char *clid;   /* clientid */
-  char *hostname, *fqdn; /* name from client-hostname option or config */
-  char *old_hostname;    /* hostname before it moved to another lease */
-  char auth_name;        /* hostname came from config, not from client */
-  char new;              /* newly created */
-  char changed;          /* modified */
-  char aux_changed;      /* CLID or expiry changed */
-  time_t expires;        /* lease expiry */
+    int clid_len;          /* length of client identifier */
+    unsigned char* clid;   /* clientid */
+    char *hostname, *fqdn; /* name from client-hostname option or config */
+    char* old_hostname;    /* hostname before it moved to another lease */
+    char auth_name;        /* hostname came from config, not from client */
+    char new;              /* newly created */
+    char changed;          /* modified */
+    char aux_changed;      /* CLID or expiry changed */
+    time_t expires;        /* lease expiry */
 #ifdef HAVE_BROKEN_RTC
-  unsigned int length;
+    unsigned int length;
 #endif
-  int hwaddr_len, hwaddr_type;
-  unsigned char hwaddr[DHCP_CHADDR_MAX]; 
-  struct in_addr addr, override, giaddr;
-  unsigned char *vendorclass, *userclass, *supplied_hostname;
-  unsigned int vendorclass_len, userclass_len, supplied_hostname_len;
-  int last_interface;
-  struct dhcp_lease *next;
+    int hwaddr_len, hwaddr_type;
+    unsigned char hwaddr[DHCP_CHADDR_MAX];
+    struct in_addr addr, override, giaddr;
+    unsigned char *vendorclass, *userclass, *supplied_hostname;
+    unsigned int vendorclass_len, userclass_len, supplied_hostname_len;
+    int last_interface;
+    struct dhcp_lease* next;
 };
 
 struct dhcp_netid {
-  char *net;
-  struct dhcp_netid *next;
+    char* net;
+    struct dhcp_netid* next;
 };
 
 struct dhcp_netid_list {
-  struct dhcp_netid *list;
-  struct dhcp_netid_list *next;
+    struct dhcp_netid* list;
+    struct dhcp_netid_list* next;
 };
 
 struct hwaddr_config {
-  int hwaddr_len, hwaddr_type;
-  unsigned char hwaddr[DHCP_CHADDR_MAX];
-  unsigned int wildcard_mask;
-  struct hwaddr_config *next;
+    int hwaddr_len, hwaddr_type;
+    unsigned char hwaddr[DHCP_CHADDR_MAX];
+    unsigned int wildcard_mask;
+    struct hwaddr_config* next;
 };
 
 struct dhcp_config {
-  unsigned int flags;
-  int clid_len;          /* length of client identifier */
-  unsigned char *clid;   /* clientid */
-  char *hostname, *domain;
-  struct dhcp_netid netid;
-  struct in_addr addr;
-  time_t decline_time;
-  unsigned int lease_time;
-  struct hwaddr_config *hwaddr;
-  struct dhcp_config *next;
+    unsigned int flags;
+    int clid_len;        /* length of client identifier */
+    unsigned char* clid; /* clientid */
+    char *hostname, *domain;
+    struct dhcp_netid netid;
+    struct in_addr addr;
+    time_t decline_time;
+    unsigned int lease_time;
+    struct hwaddr_config* hwaddr;
+    struct dhcp_config* next;
 };
 
-#define CONFIG_DISABLE           1
-#define CONFIG_CLID              2
-#define CONFIG_TIME              8
-#define CONFIG_NAME             16
-#define CONFIG_ADDR             32
-#define CONFIG_NETID            64
-#define CONFIG_NOCLID          128
-#define CONFIG_ADDR_HOSTS      512    /* address added by from /etc/hosts */
-#define CONFIG_DECLINED       1024    /* address declined by client */
-#define CONFIG_BANK           2048    /* from dhcp hosts file */
+#define CONFIG_DISABLE 1
+#define CONFIG_CLID 2
+#define CONFIG_TIME 8
+#define CONFIG_NAME 16
+#define CONFIG_ADDR 32
+#define CONFIG_NETID 64
+#define CONFIG_NOCLID 128
+#define CONFIG_ADDR_HOSTS 512 /* address added by from /etc/hosts */
+#define CONFIG_DECLINED 1024  /* address declined by client */
+#define CONFIG_BANK 2048      /* from dhcp hosts file */
 
 struct dhcp_opt {
-  int opt, len, flags;
-  union {
-    int encap;
-    unsigned int wildcard_mask;
-    unsigned char *vendor_class;
-  } u;
-  unsigned char *val;
-  struct dhcp_netid *netid;
-  struct dhcp_opt *next;
+    int opt, len, flags;
+    union {
+        int encap;
+        unsigned int wildcard_mask;
+        unsigned char* vendor_class;
+    } u;
+    unsigned char* val;
+    struct dhcp_netid* netid;
+    struct dhcp_opt* next;
 };
 
-#define DHOPT_ADDR               1
-#define DHOPT_STRING             2
-#define DHOPT_ENCAPSULATE        4
-#define DHOPT_ENCAP_MATCH        8
-#define DHOPT_FORCE             16
-#define DHOPT_BANK              32
-#define DHOPT_ENCAP_DONE        64
-#define DHOPT_MATCH            128
-#define DHOPT_VENDOR           256
-#define DHOPT_HEX              512
-#define DHOPT_VENDOR_MATCH    1024
+#define DHOPT_ADDR 1
+#define DHOPT_STRING 2
+#define DHOPT_ENCAPSULATE 4
+#define DHOPT_ENCAP_MATCH 8
+#define DHOPT_FORCE 16
+#define DHOPT_BANK 32
+#define DHOPT_ENCAP_DONE 64
+#define DHOPT_MATCH 128
+#define DHOPT_VENDOR 256
+#define DHOPT_HEX 512
+#define DHOPT_VENDOR_MATCH 1024
 
 struct dhcp_boot {
-  char *file, *sname;
-  struct in_addr next_server;
-  struct dhcp_netid *netid;
-  struct dhcp_boot *next;
+    char *file, *sname;
+    struct in_addr next_server;
+    struct dhcp_netid* netid;
+    struct dhcp_boot* next;
 };
 
 struct pxe_service {
-  unsigned short CSA, type; 
-  char *menu, *basename;
-  struct in_addr server;
-  struct dhcp_netid *netid;
-  struct pxe_service *next;
+    unsigned short CSA, type;
+    char *menu, *basename;
+    struct in_addr server;
+    struct dhcp_netid* netid;
+    struct pxe_service* next;
 };
 
-#define MATCH_VENDOR     1
-#define MATCH_USER       2
-#define MATCH_CIRCUIT    3
-#define MATCH_REMOTE     4
+#define MATCH_VENDOR 1
+#define MATCH_USER 2
+#define MATCH_CIRCUIT 3
+#define MATCH_REMOTE 4
 #define MATCH_SUBSCRIBER 5
 
 /* vendorclass, userclass, remote-id or cicuit-id */
 struct dhcp_vendor {
-  int len, match_type, option;
-  char *data;
-  struct dhcp_netid netid;
-  struct dhcp_vendor *next;
+    int len, match_type, option;
+    char* data;
+    struct dhcp_netid netid;
+    struct dhcp_vendor* next;
 };
 
 struct dhcp_mac {
-  unsigned int mask;
-  int hwaddr_len, hwaddr_type;
-  unsigned char hwaddr[DHCP_CHADDR_MAX];
-  struct dhcp_netid netid;
-  struct dhcp_mac *next;
+    unsigned int mask;
+    int hwaddr_len, hwaddr_type;
+    unsigned char hwaddr[DHCP_CHADDR_MAX];
+    struct dhcp_netid netid;
+    struct dhcp_mac* next;
 };
 
 struct dhcp_bridge {
-  char iface[IF_NAMESIZE];
-  struct dhcp_bridge *alias, *next;
+    char iface[IF_NAMESIZE];
+    struct dhcp_bridge *alias, *next;
 };
 
 struct cond_domain {
-  char *domain;
-  struct in_addr start, end;
-  struct cond_domain *next;
+    char* domain;
+    struct in_addr start, end;
+    struct cond_domain* next;
 };
 
 struct dhcp_context {
-  unsigned int lease_time, addr_epoch;
-  struct in_addr netmask, broadcast;
-  struct in_addr local, router;
-  struct in_addr start, end; /* range of available addresses */
-  int flags;
-  struct dhcp_netid netid, *filter;
-  struct dhcp_context *next, *current;
+    unsigned int lease_time, addr_epoch;
+    struct in_addr netmask, broadcast;
+    struct in_addr local, router;
+    struct in_addr start, end; /* range of available addresses */
+    int flags;
+    struct dhcp_netid netid, *filter;
+    struct dhcp_context *next, *current;
 };
 
-#define CONTEXT_STATIC    1
-#define CONTEXT_NETMASK   2
-#define CONTEXT_BRDCAST   4
-#define CONTEXT_PROXY     8
-
+#define CONTEXT_STATIC 1
+#define CONTEXT_NETMASK 2
+#define CONTEXT_BRDCAST 4
+#define CONTEXT_PROXY 8
 
 typedef unsigned char u8;
 typedef unsigned short u16;
 typedef unsigned int u32;
 
-
 struct dhcp_packet {
-  u8 op, htype, hlen, hops;
-  u32 xid;
-  u16 secs, flags;
-  struct in_addr ciaddr, yiaddr, siaddr, giaddr;
-  u8 chaddr[DHCP_CHADDR_MAX], sname[64], file[128];
-  u8 options[312];
+    u8 op, htype, hlen, hops;
+    u32 xid;
+    u16 secs, flags;
+    struct in_addr ciaddr, yiaddr, siaddr, giaddr;
+    u8 chaddr[DHCP_CHADDR_MAX], sname[64], file[128];
+    u8 options[312];
 };
 
 struct ping_result {
-  struct in_addr addr;
-  time_t time;
-  struct ping_result *next;
+    struct in_addr addr;
+    time_t time;
+    struct ping_result* next;
 };
 
 extern struct daemon {
-  /* datastuctures representing the command-line and 
-     config file arguments. All set (including defaults)
-     in option.c */
+    /* datastuctures representing the command-line and
+       config file arguments. All set (including defaults)
+       in option.c */
 
-  unsigned int options;
-  struct resolvc default_resolv, *resolv_files;
-  time_t last_resolv;
-  struct mx_srv_record *mxnames;
-  struct naptr *naptr;
-  struct txt_record *txt;
-  struct ptr_record *ptr;
-  struct cname *cnames;
-  struct interface_name *int_names;
-  char *mxtarget;
-  char *lease_file; 
-  char *username, *groupname, *scriptuser;
-  int group_set, osport;
-  char *domain_suffix;
-  struct cond_domain *cond_domain;
-  char *runfile; 
-  char *lease_change_command;
-  struct iname *if_names, *if_addrs, *if_except, *dhcp_except;
-  struct bogus_addr *bogus_addr;
-  struct server *servers;
-  int log_fac; /* log facility */
-  char *log_file; /* optional log file */
-  int max_logs;  /* queue limit */
-  int cachesize, ftabsize;
-  int port, query_port, min_port;
-  unsigned long local_ttl, neg_ttl;
-  struct hostsfile *addn_hosts;
-  struct dhcp_context *dhcp;
-  struct dhcp_config *dhcp_conf;
-  struct dhcp_opt *dhcp_opts, *dhcp_match;
-  struct dhcp_vendor *dhcp_vendors;
-  struct dhcp_mac *dhcp_macs;
-  struct dhcp_boot *boot_config;
-  struct pxe_service *pxe_services;
-  int enable_pxe;
-  struct dhcp_netid_list *dhcp_ignore, *dhcp_ignore_names, *force_broadcast, *bootp_dynamic;
-  char *dhcp_hosts_file, *dhcp_opts_file;
-  int dhcp_max;
-  int dhcp_server_port, dhcp_client_port;
-  unsigned int min_leasetime;
-  struct doctor *doctors;
-  unsigned short edns_pktsz;
-  uint32_t listen_mark;
+    unsigned int options;
+    struct resolvc default_resolv, *resolv_files;
+    time_t last_resolv;
+    struct mx_srv_record* mxnames;
+    struct naptr* naptr;
+    struct txt_record* txt;
+    struct ptr_record* ptr;
+    struct cname* cnames;
+    struct interface_name* int_names;
+    char* mxtarget;
+    char* lease_file;
+    char *username, *groupname, *scriptuser;
+    int group_set, osport;
+    char* domain_suffix;
+    struct cond_domain* cond_domain;
+    char* runfile;
+    char* lease_change_command;
+    struct iname *if_names, *if_addrs, *if_except, *dhcp_except;
+    struct bogus_addr* bogus_addr;
+    struct server* servers;
+    int log_fac;    /* log facility */
+    char* log_file; /* optional log file */
+    int max_logs;   /* queue limit */
+    int cachesize, ftabsize;
+    int port, query_port, min_port;
+    unsigned long local_ttl, neg_ttl;
+    struct hostsfile* addn_hosts;
+    struct dhcp_context* dhcp;
+    struct dhcp_config* dhcp_conf;
+    struct dhcp_opt *dhcp_opts, *dhcp_match;
+    struct dhcp_vendor* dhcp_vendors;
+    struct dhcp_mac* dhcp_macs;
+    struct dhcp_boot* boot_config;
+    struct pxe_service* pxe_services;
+    int enable_pxe;
+    struct dhcp_netid_list *dhcp_ignore, *dhcp_ignore_names, *force_broadcast, *bootp_dynamic;
+    char *dhcp_hosts_file, *dhcp_opts_file;
+    int dhcp_max;
+    int dhcp_server_port, dhcp_client_port;
+    unsigned int min_leasetime;
+    struct doctor* doctors;
+    unsigned short edns_pktsz;
+    uint32_t listen_mark;
 
-  /* globally used stuff for DNS */
-  char *packet; /* packet buffer */
-  int packet_buff_sz; /* size of above */
-  char *namebuff; /* MAXDNAME size buffer */
-  unsigned int local_answer, queries_forwarded;
-  struct frec *frec_list;
-  struct serverfd *sfds;
-  struct irec *interfaces;
-  struct listener *listeners;
-  struct server *last_server;
-  time_t forwardtime;
-  int forwardcount;
-  struct server *srv_save; /* Used for resend on DoD */
-  size_t packet_len;       /*      "        "        */
-  struct randfd *rfd_save; /*      "        "        */
-  pid_t tcp_pids[MAX_PROCS];
-  struct randfd randomsocks[RANDOM_SOCKS];
+    /* globally used stuff for DNS */
+    char* packet;       /* packet buffer */
+    int packet_buff_sz; /* size of above */
+    char* namebuff;     /* MAXDNAME size buffer */
+    unsigned int local_answer, queries_forwarded;
+    struct frec* frec_list;
+    struct serverfd* sfds;
+    struct irec* interfaces;
+    struct listener* listeners;
+    struct server* last_server;
+    time_t forwardtime;
+    int forwardcount;
+    struct server* srv_save; /* Used for resend on DoD */
+    size_t packet_len;       /*      "        "        */
+    struct randfd* rfd_save; /*      "        "        */
+    pid_t tcp_pids[MAX_PROCS];
+    struct randfd randomsocks[RANDOM_SOCKS];
 
-  /* DHCP state */
-  int dhcpfd, helperfd; 
-  int netlinkfd;
-  struct iovec dhcp_packet;
-  char *dhcp_buff, *dhcp_buff2;
-  struct ping_result *ping_results;
-  FILE *lease_stream;
-  struct dhcp_bridge *bridges;
+    /* DHCP state */
+    int dhcpfd, helperfd;
+    int netlinkfd;
+    struct iovec dhcp_packet;
+    char *dhcp_buff, *dhcp_buff2;
+    struct ping_result* ping_results;
+    FILE* lease_stream;
+    struct dhcp_bridge* bridges;
 
-} *daemon;
+} * daemon;
 
 /* cache.c */
 void cache_init(void);
-void log_query(unsigned short flags, char *name, struct all_addr *addr, char *arg); 
-char *record_source(int index);
-void querystr(char *str, unsigned short type);
-struct crec *cache_find_by_addr(struct crec *crecp,
-				struct all_addr *addr, time_t now, 
-				unsigned short prot);
-struct crec *cache_find_by_name(struct crec *crecp, 
-				char *name, time_t now, unsigned short  prot);
+void log_query(unsigned short flags, char* name, struct all_addr* addr, char* arg);
+char* record_source(int index);
+void querystr(char* str, unsigned short type);
+struct crec* cache_find_by_addr(struct crec* crecp, struct all_addr* addr, time_t now,
+                                unsigned short prot);
+struct crec* cache_find_by_name(struct crec* crecp, char* name, time_t now, unsigned short prot);
 void cache_end_insert(void);
 void cache_start_insert(void);
-struct crec *cache_insert(char *name, struct all_addr *addr,
-			  time_t now, unsigned long ttl, unsigned short flags);
+struct crec* cache_insert(char* name, struct all_addr* addr, time_t now, unsigned long ttl,
+                          unsigned short flags);
 void cache_reload(void);
-void cache_add_dhcp_entry(char *host_name, struct in_addr *host_address, time_t ttd);
+void cache_add_dhcp_entry(char* host_name, struct in_addr* host_address, time_t ttd);
 void cache_unhash_dhcp(void);
 void dump_cache(time_t now);
-char *cache_get_name(struct crec *crecp);
-char *get_domain(struct in_addr addr);
+char* cache_get_name(struct crec* crecp);
+char* get_domain(struct in_addr addr);
 
 /* rfc1035.c */
-unsigned short extract_request(HEADER *header, size_t qlen, 
-			       char *name, unsigned short *typep);
-size_t setup_reply(HEADER *header, size_t  qlen,
-		   struct all_addr *addrp, unsigned short flags,
-		   unsigned long local_ttl);
-int extract_addresses(HEADER *header, size_t qlen, char *namebuff, time_t now);
-size_t answer_request(HEADER *header, char *limit, size_t qlen,  
-		   struct in_addr local_addr, struct in_addr local_netmask, time_t now);
-int check_for_bogus_wildcard(HEADER *header, size_t qlen, char *name, 
-			     struct bogus_addr *addr, time_t now);
-unsigned char *find_pseudoheader(HEADER *header, size_t plen,
-				 size_t *len, unsigned char **p, int *is_sign);
-int check_for_local_domain(char *name, time_t now);
-unsigned int questions_crc(HEADER *header, size_t plen, char *buff);
-size_t resize_packet(HEADER *header, size_t plen, 
-		  unsigned char *pheader, size_t hlen);
+unsigned short extract_request(HEADER* header, size_t qlen, char* name, unsigned short* typep);
+size_t setup_reply(HEADER* header, size_t qlen, struct all_addr* addrp, unsigned short flags,
+                   unsigned long local_ttl);
+int extract_addresses(HEADER* header, size_t qlen, char* namebuff, time_t now);
+size_t answer_request(HEADER* header, char* limit, size_t qlen, struct in_addr local_addr,
+                      struct in_addr local_netmask, time_t now);
+int check_for_bogus_wildcard(HEADER* header, size_t qlen, char* name, struct bogus_addr* addr,
+                             time_t now);
+unsigned char* find_pseudoheader(HEADER* header, size_t plen, size_t* len, unsigned char** p,
+                                 int* is_sign);
+int check_for_local_domain(char* name, time_t now);
+unsigned int questions_crc(HEADER* header, size_t plen, char* buff);
+size_t resize_packet(HEADER* header, size_t plen, unsigned char* pheader, size_t hlen);
 
 /* util.c */
 void rand_init(void);
 unsigned short rand16(void);
-int legal_hostname(char *c);
-char *canonicalise(char *s, int *nomem);
-unsigned char *do_rfc1035_name(unsigned char *p, char *sval);
-void *safe_malloc(size_t size);
-void safe_pipe(int *fd, int read_noblock);
-void *whine_malloc(size_t size);
-int sa_len(union mysockaddr *addr);
-int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2);
-int hostname_isequal(char *a, char *b);
+int legal_hostname(char* c);
+char* canonicalise(char* s, int* nomem);
+unsigned char* do_rfc1035_name(unsigned char* p, char* sval);
+void* safe_malloc(size_t size);
+void safe_pipe(int* fd, int read_noblock);
+void* whine_malloc(size_t size);
+int sa_len(union mysockaddr* addr);
+int sockaddr_isequal(union mysockaddr* s1, union mysockaddr* s2);
+int hostname_isequal(char* a, char* b);
 time_t dnsmasq_time(void);
 int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask);
 int retry_send(void);
-int parse_addr(int family, const char *addrstr, union mysockaddr *addr);
-void prettyprint_time(char *buf, unsigned int t);
-int prettyprint_addr(const union mysockaddr *addr, char *buf);
-int parse_hex(char *in, unsigned char *out, int maxlen, 
-	      unsigned int *wildcard_mask, int *mac_type);
-int memcmp_masked(unsigned char *a, unsigned char *b, int len, 
-		  unsigned int mask);
-int expand_buf(struct iovec *iov, size_t size);
-char *print_mac(char *buff, unsigned char *mac, int len);
-void bump_maxfd(int fd, int *max);
-int read_write(int fd, unsigned char *packet, int size, int rw);
+int parse_addr(int family, const char* addrstr, union mysockaddr* addr);
+void prettyprint_time(char* buf, unsigned int t);
+int prettyprint_addr(const union mysockaddr* addr, char* buf);
+int parse_hex(char* in, unsigned char* out, int maxlen, unsigned int* wildcard_mask, int* mac_type);
+int memcmp_masked(unsigned char* a, unsigned char* b, int len, unsigned int mask);
+int expand_buf(struct iovec* iov, size_t size);
+char* print_mac(char* buff, unsigned char* mac, int len);
+void bump_maxfd(int fd, int* max);
+int read_write(int fd, unsigned char* packet, int size, int rw);
 
 /* log.c */
-void die(char *message, char *arg1, int exit_code);
-int log_start(struct passwd *ent_pw, int errfd);
-int log_reopen(char *log_file);
-void my_syslog(int priority, const char *format, ...);
-void set_log_writer(fd_set *set, int *maxfdp);
-void check_log_writer(fd_set *set);
+void die(char* message, char* arg1, int exit_code);
+int log_start(struct passwd* ent_pw, int errfd);
+int log_reopen(char* log_file);
+void my_syslog(int priority, const char* format, ...);
+void set_log_writer(fd_set* set, int* maxfdp);
+void check_log_writer(fd_set* set);
 void flush_log(void);
 
 /* option.c */
-void read_opts (int argc, char **argv, char *compile_opts);
-char *option_string(unsigned char opt, int *is_ip, int *is_name);
+void read_opts(int argc, char** argv, char* compile_opts);
+char* option_string(unsigned char opt, int* is_ip, int* is_name);
 void reread_dhcp(void);
 
 /* forward.c */
 void reply_query(int fd, int family, time_t now);
-void receive_query(struct listener *listen, time_t now);
-unsigned char *tcp_request(int confd, time_t now,
-			   struct in_addr local_addr, struct in_addr netmask);
-void server_gone(struct server *server);
-struct frec *get_new_frec(time_t now, int *wait);
+void receive_query(struct listener* listen, time_t now);
+unsigned char* tcp_request(int confd, time_t now, struct in_addr local_addr, struct in_addr netmask);
+void server_gone(struct server* server);
+struct frec* get_new_frec(time_t now, int* wait);
 
 /* network.c */
-int indextoname(int fd, int index, char *name);
-int local_bind(int fd, union mysockaddr *addr, char *intname, uint32_t mark, int is_tcp);
+int indextoname(int fd, int index, char* name);
+int local_bind(int fd, union mysockaddr* addr, char* intname, uint32_t mark, int is_tcp);
 int random_sock(int family);
 void pre_allocate_sfds(void);
-int reload_servers(char *fname);
+int reload_servers(char* fname);
 #ifdef __ANDROID__
-int set_servers(const char *servers);
-void set_interfaces(const char *interfaces);
+int set_servers(const char* servers);
+void set_interfaces(const char* interfaces);
 #endif
 void check_servers(void);
 int enumerate_interfaces();
-struct listener *create_wildcard_listeners(void);
-struct listener *create_bound_listeners(void);
-int iface_check(int family, struct all_addr *addr, char *name, int *indexp);
+struct listener* create_wildcard_listeners(void);
+struct listener* create_bound_listeners(void);
+int iface_check(int family, struct all_addr* addr, char* name, int* indexp);
 int fix_fd(int fd);
-struct in_addr get_ifaddr(char *intr);
+struct in_addr get_ifaddr(char* intr);
 
 /* dhcp.c */
 #ifdef HAVE_DHCP
 void dhcp_init(void);
 void dhcp_packet(time_t now);
-struct dhcp_context *address_available(struct dhcp_context *context, 
-				       struct in_addr addr,
-				       struct dhcp_netid *netids);
-struct dhcp_context *narrow_context(struct dhcp_context *context, 
-				    struct in_addr taddr,
-				    struct dhcp_netid *netids);
-int match_netid(struct dhcp_netid *check, struct dhcp_netid *pool, int negonly);int address_allocate(struct dhcp_context *context,
-		     struct in_addr *addrp, unsigned char *hwaddr, int hw_len,
-		     struct dhcp_netid *netids, time_t now);
-int config_has_mac(struct dhcp_config *config, unsigned char *hwaddr, int len, int type);
-struct dhcp_config *find_config(struct dhcp_config *configs,
-				struct dhcp_context *context,
-				unsigned char *clid, int clid_len,
-				unsigned char *hwaddr, int hw_len, 
-				int hw_type, char *hostname);
-void dhcp_update_configs(struct dhcp_config *configs);
+struct dhcp_context* address_available(struct dhcp_context* context, struct in_addr addr,
+                                       struct dhcp_netid* netids);
+struct dhcp_context* narrow_context(struct dhcp_context* context, struct in_addr taddr,
+                                    struct dhcp_netid* netids);
+int match_netid(struct dhcp_netid* check, struct dhcp_netid* pool, int negonly);
+int address_allocate(struct dhcp_context* context, struct in_addr* addrp, unsigned char* hwaddr,
+                     int hw_len, struct dhcp_netid* netids, time_t now);
+int config_has_mac(struct dhcp_config* config, unsigned char* hwaddr, int len, int type);
+struct dhcp_config* find_config(struct dhcp_config* configs, struct dhcp_context* context,
+                                unsigned char* clid, int clid_len, unsigned char* hwaddr,
+                                int hw_len, int hw_type, char* hostname);
+void dhcp_update_configs(struct dhcp_config* configs);
 void check_dhcp_hosts(int fatal);
-struct dhcp_config *config_find_by_address(struct dhcp_config *configs, struct in_addr addr);
-char *strip_hostname(char *hostname);
-char *host_from_dns(struct in_addr addr);
-char *get_domain(struct in_addr addr);
+struct dhcp_config* config_find_by_address(struct dhcp_config* configs, struct in_addr addr);
+char* strip_hostname(char* hostname);
+char* host_from_dns(struct in_addr addr);
+char* get_domain(struct in_addr addr);
 #endif
 
 /* lease.c */
@@ -784,16 +771,16 @@
 void lease_update_file(time_t now);
 void lease_update_dns();
 void lease_init(time_t now);
-struct dhcp_lease *lease_allocate(struct in_addr addr);
-void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
-		      unsigned char *clid, int hw_len, int hw_type, int clid_len);
-void lease_set_hostname(struct dhcp_lease *lease, char *name, int auth);
-void lease_set_expires(struct dhcp_lease *lease, unsigned int len, time_t now);
-void lease_set_interface(struct dhcp_lease *lease, int interface);
-struct dhcp_lease *lease_find_by_client(unsigned char *hwaddr, int hw_len, int hw_type,  
-					unsigned char *clid, int clid_len);
-struct dhcp_lease *lease_find_by_addr(struct in_addr addr);
-void lease_prune(struct dhcp_lease *target, time_t now);
+struct dhcp_lease* lease_allocate(struct in_addr addr);
+void lease_set_hwaddr(struct dhcp_lease* lease, unsigned char* hwaddr, unsigned char* clid,
+                      int hw_len, int hw_type, int clid_len);
+void lease_set_hostname(struct dhcp_lease* lease, char* name, int auth);
+void lease_set_expires(struct dhcp_lease* lease, unsigned int len, time_t now);
+void lease_set_interface(struct dhcp_lease* lease, int interface);
+struct dhcp_lease* lease_find_by_client(unsigned char* hwaddr, int hw_len, int hw_type,
+                                        unsigned char* clid, int clid_len);
+struct dhcp_lease* lease_find_by_addr(struct in_addr addr);
+void lease_prune(struct dhcp_lease* target, time_t now);
 void lease_update_from_configs(void);
 int do_script_run(time_t now);
 void rerun_scripts(void);
@@ -801,10 +788,10 @@
 
 /* rfc2131.c */
 #ifdef HAVE_DHCP
-size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
-		  size_t sz, time_t now, int unicast_dest, int *is_inform);
-unsigned char *extended_hwaddr(int hwtype, int hwlen, unsigned char *hwaddr, 
-			       int clid_len, unsigned char *clid, int *len_out);
+size_t dhcp_reply(struct dhcp_context* context, char* iface_name, int int_index, size_t sz,
+                  time_t now, int unicast_dest, int* is_inform);
+unsigned char* extended_hwaddr(int hwtype, int hwlen, unsigned char* hwaddr, int clid_len,
+                               unsigned char* clid, int* len_out);
 #endif
 
 /* dnsmasq.c */
@@ -822,13 +809,12 @@
 #endif
 
 /* bpf.c or netlink.c */
-int iface_enumerate(void *parm, int (*ipv4_callback)(), int (*ipv6_callback)());
+int iface_enumerate(void* parm, int (*ipv4_callback)(), int (*ipv6_callback)());
 
 /* helper.c */
 #if defined(HAVE_DHCP) && !defined(NO_FORK)
 int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd);
 void helper_write(void);
-void queue_script(int action, struct dhcp_lease *lease, 
-		  char *hostname, time_t now);
+void queue_script(int action, struct dhcp_lease* lease, char* hostname, time_t now);
 int helper_buf_empty(void);
 #endif
diff --git a/src/forward.c b/src/forward.c
index 4937fc0..9010a01 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -4,959 +4,834 @@
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; version 2 dated June, 1991, or
    (at your option) version 3 dated 29 June, 2007.
- 
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-     
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "dnsmasq.h"
 
-static struct frec *lookup_frec(unsigned short id, unsigned int crc);
-static struct frec *lookup_frec_by_sender(unsigned short id,
-					  union mysockaddr *addr,
-					  unsigned int crc);
+static struct frec* lookup_frec(unsigned short id, unsigned int crc);
+static struct frec* lookup_frec_by_sender(unsigned short id, union mysockaddr* addr,
+                                          unsigned int crc);
 static unsigned short get_id(int force, unsigned short force_id, unsigned int crc);
-static void free_frec(struct frec *f);
-static struct randfd *allocate_rfd(int family);
+static void free_frec(struct frec* f);
+static struct randfd* allocate_rfd(int family);
 
-/* Send a UDP packet with its source address set as "source" 
+/* Send a UDP packet with its source address set as "source"
    unless nowild is true, when we just send it with the kernel default */
-static void send_from(int fd, int nowild, char *packet, size_t len, 
-		      union mysockaddr *to, struct all_addr *source,
-		      unsigned int iface)
-{
-  struct msghdr msg;
-  struct iovec iov[1]; 
-  union {
-    struct cmsghdr align; /* this ensures alignment */
+static void send_from(int fd, int nowild, char* packet, size_t len, union mysockaddr* to,
+                      struct all_addr* source, unsigned int iface) {
+    struct msghdr msg;
+    struct iovec iov[1];
+    union {
+        struct cmsghdr align; /* this ensures alignment */
 #if defined(HAVE_LINUX_NETWORK)
-    char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
+        char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
 #elif defined(IP_SENDSRCADDR)
-    char control[CMSG_SPACE(sizeof(struct in_addr))];
+        char control[CMSG_SPACE(sizeof(struct in_addr))];
 #endif
 #ifdef HAVE_IPV6
-    char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
+        char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
 #endif
-  } control_u;
-  
-  iov[0].iov_base = packet;
-  iov[0].iov_len = len;
+    } control_u;
 
-  msg.msg_control = NULL;
-  msg.msg_controllen = 0;
-  msg.msg_flags = 0;
-  msg.msg_name = to;
-  msg.msg_namelen = sa_len(to);
-  msg.msg_iov = iov;
-  msg.msg_iovlen = 1;
-  
-  if (!nowild)
-    {
-      struct cmsghdr *cmptr;
-      msg.msg_control = &control_u;
-      msg.msg_controllen = sizeof(control_u);
-      cmptr = CMSG_FIRSTHDR(&msg);
+    iov[0].iov_base = packet;
+    iov[0].iov_len = len;
 
-      if (to->sa.sa_family == AF_INET)
-	{
+    msg.msg_control = NULL;
+    msg.msg_controllen = 0;
+    msg.msg_flags = 0;
+    msg.msg_name = to;
+    msg.msg_namelen = sa_len(to);
+    msg.msg_iov = iov;
+    msg.msg_iovlen = 1;
+
+    if (!nowild) {
+        struct cmsghdr* cmptr;
+        msg.msg_control = &control_u;
+        msg.msg_controllen = sizeof(control_u);
+        cmptr = CMSG_FIRSTHDR(&msg);
+
+        if (to->sa.sa_family == AF_INET) {
 #if defined(HAVE_LINUX_NETWORK)
-	  struct in_pktinfo *pkt = (struct in_pktinfo *)CMSG_DATA(cmptr);
-	  pkt->ipi_ifindex = 0;
-	  pkt->ipi_spec_dst = source->addr.addr4;
-	  msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
-	  cmptr->cmsg_level = SOL_IP;
-	  cmptr->cmsg_type = IP_PKTINFO;
+            struct in_pktinfo* pkt = (struct in_pktinfo*) CMSG_DATA(cmptr);
+            pkt->ipi_ifindex = 0;
+            pkt->ipi_spec_dst = source->addr.addr4;
+            msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
+            cmptr->cmsg_level = SOL_IP;
+            cmptr->cmsg_type = IP_PKTINFO;
 #elif defined(IP_SENDSRCADDR)
-	  struct in_addr *a = (struct in_addr *)CMSG_DATA(cmptr);
-	  *a = source->addr.addr4;
-	  msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
-	  cmptr->cmsg_level = IPPROTO_IP;
-	  cmptr->cmsg_type = IP_SENDSRCADDR;
+            struct in_addr* a = (struct in_addr*) CMSG_DATA(cmptr);
+            *a = source->addr.addr4;
+            msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
+            cmptr->cmsg_level = IPPROTO_IP;
+            cmptr->cmsg_type = IP_SENDSRCADDR;
 #endif
-	}
-      else
+        } else
 #ifdef HAVE_IPV6
-	{
-	  struct in6_pktinfo *pkt = (struct in6_pktinfo *)CMSG_DATA(cmptr);
-	  pkt->ipi6_ifindex = iface; /* Need iface for IPv6 to handle link-local addrs */
-	  pkt->ipi6_addr = source->addr.addr6;
-	  msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
-	  cmptr->cmsg_type = IPV6_PKTINFO;
-	  cmptr->cmsg_level = IPV6_LEVEL;
-	}
+        {
+            struct in6_pktinfo* pkt = (struct in6_pktinfo*) CMSG_DATA(cmptr);
+            pkt->ipi6_ifindex = iface; /* Need iface for IPv6 to handle link-local addrs */
+            pkt->ipi6_addr = source->addr.addr6;
+            msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
+            cmptr->cmsg_type = IPV6_PKTINFO;
+            cmptr->cmsg_level = IPV6_LEVEL;
+        }
 #else
-      iface = 0; /* eliminate warning */
+            iface = 0; /* eliminate warning */
 #endif
     }
-  
- retry:
-  if (sendmsg(fd, &msg, 0) == -1)
-    {
-      /* certain Linux kernels seem to object to setting the source address in the IPv6 stack
-	 by returning EINVAL from sendmsg. In that case, try again without setting the
-	 source address, since it will nearly alway be correct anyway.  IPv6 stinks. */
-      if (errno == EINVAL && msg.msg_controllen)
-	{
-	  msg.msg_controllen = 0;
-	  goto retry;
-	}
-      if (retry_send())
-	goto retry;
+
+retry:
+    if (sendmsg(fd, &msg, 0) == -1) {
+        /* certain Linux kernels seem to object to setting the source address in the IPv6 stack
+       by returning EINVAL from sendmsg. In that case, try again without setting the
+       source address, since it will nearly alway be correct anyway.  IPv6 stinks. */
+        if (errno == EINVAL && msg.msg_controllen) {
+            msg.msg_controllen = 0;
+            goto retry;
+        }
+        if (retry_send()) goto retry;
     }
 }
-          
-static unsigned short search_servers(time_t now, struct all_addr **addrpp, 
-				     unsigned short qtype, char *qdomain, int *type, char **domain)
-			      
+
+static unsigned short search_servers(time_t now, struct all_addr** addrpp, unsigned short qtype,
+                                     char* qdomain, int* type, char** domain)
+
 {
-  /* If the query ends in the domain in one of our servers, set
-     domain to point to that name. We find the largest match to allow both
-     domain.org and sub.domain.org to exist. */
-  
-  unsigned int namelen = strlen(qdomain);
-  unsigned int matchlen = 0;
-  struct server *serv;
-  unsigned short flags = 0;
-  
-  for (serv = daemon->servers; serv; serv=serv->next)
-    /* domain matches take priority over NODOTS matches */
-    if ((serv->flags & SERV_FOR_NODOTS) && *type != SERV_HAS_DOMAIN && !strchr(qdomain, '.') && namelen != 0)
-      {
-	unsigned short sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6; 
-	*type = SERV_FOR_NODOTS;
-	if (serv->flags & SERV_NO_ADDR)
-	  flags = F_NXDOMAIN;
-	else if (serv->flags & SERV_LITERAL_ADDRESS) 
-	  { 
-	    if (sflag & qtype)
-	      {
-		flags = sflag;
-		if (serv->addr.sa.sa_family == AF_INET) 
-		  *addrpp = (struct all_addr *)&serv->addr.in.sin_addr;
+    /* If the query ends in the domain in one of our servers, set
+       domain to point to that name. We find the largest match to allow both
+       domain.org and sub.domain.org to exist. */
+
+    unsigned int namelen = strlen(qdomain);
+    unsigned int matchlen = 0;
+    struct server* serv;
+    unsigned short flags = 0;
+
+    for (serv = daemon->servers; serv; serv = serv->next)
+        /* domain matches take priority over NODOTS matches */
+        if ((serv->flags & SERV_FOR_NODOTS) && *type != SERV_HAS_DOMAIN && !strchr(qdomain, '.') &&
+            namelen != 0) {
+            unsigned short sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6;
+            *type = SERV_FOR_NODOTS;
+            if (serv->flags & SERV_NO_ADDR)
+                flags = F_NXDOMAIN;
+            else if (serv->flags & SERV_LITERAL_ADDRESS) {
+                if (sflag & qtype) {
+                    flags = sflag;
+                    if (serv->addr.sa.sa_family == AF_INET)
+                        *addrpp = (struct all_addr*) &serv->addr.in.sin_addr;
 #ifdef HAVE_IPV6
-		else
-		  *addrpp = (struct all_addr *)&serv->addr.in6.sin6_addr;
-#endif 
-	      }
-	    else if (!flags || (flags & F_NXDOMAIN))
-	      flags = F_NOERR;
-	  } 
-      }
-    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 short sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6;
-	    *type = SERV_HAS_DOMAIN;
-	    *domain = serv->domain;
-	    matchlen = domainlen;
-	    if (serv->flags & SERV_NO_ADDR)
-	      flags = F_NXDOMAIN;
-	    else if (serv->flags & SERV_LITERAL_ADDRESS)
-	      {
-		if (sflag & qtype)
-		  {
-		    flags = sflag;
-		    if (serv->addr.sa.sa_family == AF_INET) 
-		      *addrpp = (struct all_addr *)&serv->addr.in.sin_addr;
-#ifdef HAVE_IPV6
-		    else
-		      *addrpp = (struct all_addr *)&serv->addr.in6.sin6_addr;
+                    else
+                        *addrpp = (struct all_addr*) &serv->addr.in6.sin6_addr;
 #endif
-		  }
-		else if (!flags || (flags & F_NXDOMAIN))
-		  flags = F_NOERR;
-	      }
-	  } 
-      }
+                } else if (!flags || (flags & F_NXDOMAIN))
+                    flags = F_NOERR;
+            }
+        } 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 short sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6;
+                *type = SERV_HAS_DOMAIN;
+                *domain = serv->domain;
+                matchlen = domainlen;
+                if (serv->flags & SERV_NO_ADDR)
+                    flags = F_NXDOMAIN;
+                else if (serv->flags & SERV_LITERAL_ADDRESS) {
+                    if (sflag & qtype) {
+                        flags = sflag;
+                        if (serv->addr.sa.sa_family == AF_INET)
+                            *addrpp = (struct all_addr*) &serv->addr.in.sin_addr;
+#ifdef HAVE_IPV6
+                        else
+                            *addrpp = (struct all_addr*) &serv->addr.in6.sin6_addr;
+#endif
+                    } else if (!flags || (flags & F_NXDOMAIN))
+                        flags = F_NOERR;
+                }
+            }
+        }
 
-  if (flags == 0 && !(qtype & F_BIGNAME) && 
-      (daemon->options & OPT_NODOTS_LOCAL) && !strchr(qdomain, '.') && namelen != 0)
-    /* don't forward simple names, make exception for NS queries and empty name. */
-    flags = F_NXDOMAIN;
-    
-  if (flags == F_NXDOMAIN && check_for_local_domain(qdomain, now))
-    flags = F_NOERR;
+    if (flags == 0 && !(qtype & F_BIGNAME) && (daemon->options & OPT_NODOTS_LOCAL) &&
+        !strchr(qdomain, '.') && namelen != 0)
+        /* don't forward simple names, make exception for NS queries and empty name. */
+        flags = F_NXDOMAIN;
 
-  if (flags)
-    {
-      int logflags = 0;
-      
-      if (flags == F_NXDOMAIN || flags == F_NOERR)
-	logflags = F_NEG | qtype;
-  
-      log_query(logflags | flags | F_CONFIG | F_FORWARD, qdomain, *addrpp, NULL);
+    if (flags == F_NXDOMAIN && check_for_local_domain(qdomain, now)) flags = F_NOERR;
+
+    if (flags) {
+        int logflags = 0;
+
+        if (flags == F_NXDOMAIN || flags == F_NOERR) logflags = F_NEG | qtype;
+
+        log_query(logflags | flags | F_CONFIG | F_FORWARD, qdomain, *addrpp, NULL);
     }
 
-  return  flags;
+    return flags;
 }
 
-static int forward_query(int udpfd, union mysockaddr *udpaddr,
-			 struct all_addr *dst_addr, unsigned int dst_iface,
-			 HEADER *header, size_t plen, time_t now, struct frec *forward)
-{
-  char *domain = NULL;
-  int type = 0;
-  struct all_addr *addrp = NULL;
-  unsigned int crc = questions_crc(header, plen, daemon->namebuff);
-  unsigned short flags = 0;
-  unsigned short gotname = extract_request(header, plen, daemon->namebuff, NULL);
-  struct server *start = NULL;
-    
-  /* may be no servers available. */
-  if (!daemon->servers)
-    forward = NULL;
-  else if (forward || (forward = lookup_frec_by_sender(ntohs(header->id), udpaddr, crc)))
-    {
-      /* retry on existing query, send to all available servers  */
-      domain = forward->sentto->domain;
-      forward->sentto->failed_queries++;
-      if (!(daemon->options & OPT_ORDER))
-	{
-	  forward->forwardall = 1;
-	  daemon->last_server = NULL;
-	}
-      type = forward->sentto->flags & SERV_TYPE;
-      if (!(start = forward->sentto->next))
-	start = daemon->servers; /* at end of list, recycle */
-      header->id = htons(forward->new_id);
-    }
-  else 
-    {
-      if (gotname)
-	flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain);
-      
-      if (!flags && !(forward = get_new_frec(now, NULL)))
-	/* table full - server failure. */
-	flags = F_NEG;
-      
-      if (forward)
-	{
-	  /* force unchanging id for signed packets */
-	  int is_sign;
-	  find_pseudoheader(header, plen, NULL, NULL, &is_sign);
-	  
-	  forward->source = *udpaddr;
-	  forward->dest = *dst_addr;
-	  forward->iface = dst_iface;
-	  forward->orig_id = ntohs(header->id);
-	  forward->new_id = get_id(is_sign, forward->orig_id, crc);
-	  forward->fd = udpfd;
-	  forward->crc = crc;
-	  forward->forwardall = 0;
-	  header->id = htons(forward->new_id);
+static int forward_query(int udpfd, union mysockaddr* udpaddr, struct all_addr* dst_addr,
+                         unsigned int dst_iface, HEADER* header, size_t plen, time_t now,
+                         struct frec* forward) {
+    char* domain = NULL;
+    int type = 0;
+    struct all_addr* addrp = NULL;
+    unsigned int crc = questions_crc(header, plen, daemon->namebuff);
+    unsigned short flags = 0;
+    unsigned short gotname = extract_request(header, plen, daemon->namebuff, NULL);
+    struct server* start = NULL;
 
-	  /* In strict_order mode, or when using domain specific servers
-	     always try servers in the order specified in resolv.conf,
-	     otherwise, use the one last known to work. */
-	  
-	  if (type != 0  || (daemon->options & OPT_ORDER))
-	    start = daemon->servers;
-	  else if (!(start = daemon->last_server) ||
-		   daemon->forwardcount++ > FORWARD_TEST ||
-		   difftime(now, daemon->forwardtime) > FORWARD_TIME)
-	    {
-	      start = daemon->servers;
-	      forward->forwardall = 1;
-	      daemon->forwardcount = 0;
-	      daemon->forwardtime = now;
-	    }
-	}
+    /* may be no servers available. */
+    if (!daemon->servers)
+        forward = NULL;
+    else if (forward || (forward = lookup_frec_by_sender(ntohs(header->id), udpaddr, crc))) {
+        /* retry on existing query, send to all available servers  */
+        domain = forward->sentto->domain;
+        forward->sentto->failed_queries++;
+        if (!(daemon->options & OPT_ORDER)) {
+            forward->forwardall = 1;
+            daemon->last_server = NULL;
+        }
+        type = forward->sentto->flags & SERV_TYPE;
+        if (!(start = forward->sentto->next)) start = daemon->servers; /* at end of list, recycle */
+        header->id = htons(forward->new_id);
+    } else {
+        if (gotname) flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain);
+
+        if (!flags && !(forward = get_new_frec(now, NULL))) /* table full - server failure. */
+            flags = F_NEG;
+
+        if (forward) {
+            /* force unchanging id for signed packets */
+            int is_sign;
+            find_pseudoheader(header, plen, NULL, NULL, &is_sign);
+
+            forward->source = *udpaddr;
+            forward->dest = *dst_addr;
+            forward->iface = dst_iface;
+            forward->orig_id = ntohs(header->id);
+            forward->new_id = get_id(is_sign, forward->orig_id, crc);
+            forward->fd = udpfd;
+            forward->crc = crc;
+            forward->forwardall = 0;
+            header->id = htons(forward->new_id);
+
+            /* In strict_order mode, or when using domain specific servers
+               always try servers in the order specified in resolv.conf,
+               otherwise, use the one last known to work. */
+
+            if (type != 0 || (daemon->options & OPT_ORDER))
+                start = daemon->servers;
+            else if (!(start = daemon->last_server) || daemon->forwardcount++ > FORWARD_TEST ||
+                     difftime(now, daemon->forwardtime) > FORWARD_TIME) {
+                start = daemon->servers;
+                forward->forwardall = 1;
+                daemon->forwardcount = 0;
+                daemon->forwardtime = now;
+            }
+        }
     }
 
-  /* check for send errors here (no route to host) 
-     if we fail to send to all nameservers, send back an error
-     packet straight away (helps modem users when offline)  */
-  
-  if (!flags && forward)
-    {
-      struct server *firstsentto = start;
-      int forwarded = 0;
+    /* check for send errors here (no route to host)
+       if we fail to send to all nameservers, send back an error
+       packet straight away (helps modem users when offline)  */
 
-      while (1)
-	{ 
-	  /* only send to servers dealing with our domain.
-	     domain may be NULL, in which case server->domain 
-	     must be NULL also. */
-	  
-	  if (type == (start->flags & SERV_TYPE) &&
-	      (type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
-	      !(start->flags & SERV_LITERAL_ADDRESS))
-	    {
-	      int fd;
+    if (!flags && forward) {
+        struct server* firstsentto = start;
+        int forwarded = 0;
 
-	      /* find server socket to use, may need to get random one. */
-	      if (start->sfd)
-		fd = start->sfd->fd;
-	      else 
-		{
+        while (1) {
+            /* only send to servers dealing with our domain.
+               domain may be NULL, in which case server->domain
+               must be NULL also. */
+
+            if (type == (start->flags & SERV_TYPE) &&
+                (type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
+                !(start->flags & SERV_LITERAL_ADDRESS)) {
+                int fd;
+
+                /* find server socket to use, may need to get random one. */
+                if (start->sfd)
+                    fd = start->sfd->fd;
+                else {
 #ifdef HAVE_IPV6
-		  if (start->addr.sa.sa_family == AF_INET6)
-		    {
-		      if (!forward->rfd6 &&
-			  !(forward->rfd6 = allocate_rfd(AF_INET6)))
-			break;
-		      daemon->rfd_save = forward->rfd6;
-		      fd = forward->rfd6->fd;
-		    }
-		  else
+                    if (start->addr.sa.sa_family == AF_INET6) {
+                        if (!forward->rfd6 && !(forward->rfd6 = allocate_rfd(AF_INET6))) break;
+                        daemon->rfd_save = forward->rfd6;
+                        fd = forward->rfd6->fd;
+                    } else
 #endif
-		    {
-		      if (!forward->rfd4 &&
-			  !(forward->rfd4 = allocate_rfd(AF_INET)))
-			break;
-		      daemon->rfd_save = forward->rfd4;
-		      fd = forward->rfd4->fd;
-		    }
+                    {
+                        if (!forward->rfd4 && !(forward->rfd4 = allocate_rfd(AF_INET))) break;
+                        daemon->rfd_save = forward->rfd4;
+                        fd = forward->rfd4->fd;
+                    }
 
 #ifdef ANDROID
-		  // Mark the socket so it goes out on the correct network. Note
-		  // that we never clear the mark, only re-set it the next time we
-		  // allocate a new random fd. This is because we buffer DNS
-		  // queries (in daemon->srv_save, daemon->packet_len) and socket
-		  // file descriptors (in daemon->rfd_save) with the expectation of
-		  // being able to use them again.
-		  //
-		  // Server fds are marked separately in allocate_sfd.
-		  setsockopt(fd, SOL_SOCKET, SO_MARK, &start->mark, sizeof(start->mark));
+                    // Mark the socket so it goes out on the correct network. Note
+                    // that we never clear the mark, only re-set it the next time we
+                    // allocate a new random fd. This is because we buffer DNS
+                    // queries (in daemon->srv_save, daemon->packet_len) and socket
+                    // file descriptors (in daemon->rfd_save) with the expectation of
+                    // being able to use them again.
+                    //
+                    // Server fds are marked separately in allocate_sfd.
+                    setsockopt(fd, SOL_SOCKET, SO_MARK, &start->mark, sizeof(start->mark));
 #endif
-		}
+                }
 
-	      if (sendto(fd, (char *)header, plen, 0,
-			 &start->addr.sa,
-			 sa_len(&start->addr)) == -1)
-		{
-		  if (retry_send())
-		    continue;
-		}
-	      else
-		{
-		  /* Keep info in case we want to re-send this packet */
-		  daemon->srv_save = start;
-		  daemon->packet_len = plen;
-		  
-		  if (!gotname)
-		    strcpy(daemon->namebuff, "query");
-		  if (start->addr.sa.sa_family == AF_INET)
-		    log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff, 
-			      (struct all_addr *)&start->addr.in.sin_addr, NULL); 
+                if (sendto(fd, (char*) header, plen, 0, &start->addr.sa, sa_len(&start->addr)) ==
+                    -1) {
+                    if (retry_send()) continue;
+                } else {
+                    /* Keep info in case we want to re-send this packet */
+                    daemon->srv_save = start;
+                    daemon->packet_len = plen;
+
+                    if (!gotname) strcpy(daemon->namebuff, "query");
+                    if (start->addr.sa.sa_family == AF_INET)
+                        log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff,
+                                  (struct all_addr*) &start->addr.in.sin_addr, NULL);
 #ifdef HAVE_IPV6
-		  else
-		    log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff, 
-			      (struct all_addr *)&start->addr.in6.sin6_addr, NULL);
-#endif 
-		  start->queries++;
-		  forwarded = 1;
-		  forward->sentto = start;
-		  if (!forward->forwardall) 
-		    break;
-		  forward->forwardall++;
-		}
-	    } 
-	  
-	  if (!(start = start->next))
- 	    start = daemon->servers;
-	  
-	  if (start == firstsentto)
-	    break;
-	}
-      
-      if (forwarded)
-	return 1;
-      
-      /* could not send on, prepare to return */ 
-      header->id = htons(forward->orig_id);
-      free_frec(forward); /* cancel */
-    }	  
-  
-  /* could not send on, return empty answer or address if known for whole domain */
-  if (udpfd != -1)
-    {
-      plen = setup_reply(header, plen, addrp, flags, daemon->local_ttl);
-      send_from(udpfd, daemon->options & OPT_NOWILD, (char *)header, plen, udpaddr, dst_addr, dst_iface);
+                    else
+                        log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff,
+                                  (struct all_addr*) &start->addr.in6.sin6_addr, NULL);
+#endif
+                    start->queries++;
+                    forwarded = 1;
+                    forward->sentto = start;
+                    if (!forward->forwardall) break;
+                    forward->forwardall++;
+                }
+            }
+
+            if (!(start = start->next)) start = daemon->servers;
+
+            if (start == firstsentto) break;
+        }
+
+        if (forwarded) return 1;
+
+        /* could not send on, prepare to return */
+        header->id = htons(forward->orig_id);
+        free_frec(forward); /* cancel */
     }
 
-  return 0;
+    /* could not send on, return empty answer or address if known for whole domain */
+    if (udpfd != -1) {
+        plen = setup_reply(header, plen, addrp, flags, daemon->local_ttl);
+        send_from(udpfd, daemon->options & OPT_NOWILD, (char*) header, plen, udpaddr, dst_addr,
+                  dst_iface);
+    }
+
+    return 0;
 }
 
-static size_t process_reply(HEADER *header, time_t now, 
-			    struct server *server, size_t n)
-{
-  unsigned char *pheader, *sizep;
-  int munged = 0, is_sign;
-  size_t plen; 
+static size_t process_reply(HEADER* header, time_t now, struct server* server, size_t n) {
+    unsigned char *pheader, *sizep;
+    int munged = 0, is_sign;
+    size_t plen;
 
-  /* If upstream is advertising a larger UDP packet size
-     than we allow, trim it so that we don't get overlarge
-     requests for the client. We can't do this for signed packets. */
+    /* If upstream is advertising a larger UDP packet size
+       than we allow, trim it so that we don't get overlarge
+       requests for the client. We can't do this for signed packets. */
 
-  if ((pheader = find_pseudoheader(header, n, &plen, &sizep, &is_sign)) && !is_sign)
-    {
-      unsigned short udpsz;
-      unsigned char *psave = sizep;
-      
-      GETSHORT(udpsz, sizep);
-      if (udpsz > daemon->edns_pktsz)
-	PUTSHORT(daemon->edns_pktsz, psave);
+    if ((pheader = find_pseudoheader(header, n, &plen, &sizep, &is_sign)) && !is_sign) {
+        unsigned short udpsz;
+        unsigned char* psave = sizep;
+
+        GETSHORT(udpsz, sizep);
+        if (udpsz > daemon->edns_pktsz) PUTSHORT(daemon->edns_pktsz, psave);
     }
 
-  if (header->opcode != QUERY || (header->rcode != NOERROR && header->rcode != NXDOMAIN))
-    return n;
-  
-  /* Complain loudly if the upstream server is non-recursive. */
-  if (!header->ra && header->rcode == NOERROR && ntohs(header->ancount) == 0 &&
-      server && !(server->flags & SERV_WARNED_RECURSIVE))
-    {
-      prettyprint_addr(&server->addr, daemon->namebuff);
-      my_syslog(LOG_WARNING, _("nameserver %s refused to do a recursive query"), daemon->namebuff);
-      if (!(daemon->options & OPT_LOG))
-	server->flags |= SERV_WARNED_RECURSIVE;
-    }  
-    
-  if (daemon->bogus_addr && header->rcode != NXDOMAIN &&
-      check_for_bogus_wildcard(header, n, daemon->namebuff, daemon->bogus_addr, now))
-    {
-      munged = 1;
-      header->rcode = NXDOMAIN;
-      header->aa = 0;
+    if (header->opcode != QUERY || (header->rcode != NOERROR && header->rcode != NXDOMAIN))
+        return n;
+
+    /* Complain loudly if the upstream server is non-recursive. */
+    if (!header->ra && header->rcode == NOERROR && ntohs(header->ancount) == 0 && server &&
+        !(server->flags & SERV_WARNED_RECURSIVE)) {
+        prettyprint_addr(&server->addr, daemon->namebuff);
+        my_syslog(LOG_WARNING, _("nameserver %s refused to do a recursive query"), daemon->namebuff);
+        if (!(daemon->options & OPT_LOG)) server->flags |= SERV_WARNED_RECURSIVE;
     }
-  else 
-    {
-      if (header->rcode == NXDOMAIN && 
-	  extract_request(header, n, daemon->namebuff, NULL) &&
-	  check_for_local_domain(daemon->namebuff, now))
-	{
-	  /* if we forwarded a query for a locally known name (because it was for 
-	     an unknown type) and the answer is NXDOMAIN, convert that to NODATA,
-	     since we know that the domain exists, even if upstream doesn't */
-	  munged = 1;
-	  header->aa = 1;
-	  header->rcode = NOERROR;
-	}
-      
-      if (extract_addresses(header, n, daemon->namebuff, now))
-	{
-	  my_syslog(LOG_WARNING, _("possible DNS-rebind attack detected"));
-	  munged = 1;
-	}
+
+    if (daemon->bogus_addr && header->rcode != NXDOMAIN &&
+        check_for_bogus_wildcard(header, n, daemon->namebuff, daemon->bogus_addr, now)) {
+        munged = 1;
+        header->rcode = NXDOMAIN;
+        header->aa = 0;
+    } else {
+        if (header->rcode == NXDOMAIN && extract_request(header, n, daemon->namebuff, NULL) &&
+            check_for_local_domain(daemon->namebuff, now)) {
+            /* if we forwarded a query for a locally known name (because it was for
+               an unknown type) and the answer is NXDOMAIN, convert that to NODATA,
+               since we know that the domain exists, even if upstream doesn't */
+            munged = 1;
+            header->aa = 1;
+            header->rcode = NOERROR;
+        }
+
+        if (extract_addresses(header, n, daemon->namebuff, now)) {
+            my_syslog(LOG_WARNING, _("possible DNS-rebind attack detected"));
+            munged = 1;
+        }
     }
-  
-  /* do this after extract_addresses. Ensure NODATA reply and remove
-     nameserver info. */
-  
-  if (munged)
-    {
-      header->ancount = htons(0);
-      header->nscount = htons(0);
-      header->arcount = htons(0);
+
+    /* do this after extract_addresses. Ensure NODATA reply and remove
+       nameserver info. */
+
+    if (munged) {
+        header->ancount = htons(0);
+        header->nscount = htons(0);
+        header->arcount = htons(0);
     }
-  
-  /* the bogus-nxdomain stuff, doctor and NXDOMAIN->NODATA munging can all elide
-     sections of the packet. Find the new length here and put back pseudoheader
-     if it was removed. */
-  return resize_packet(header, n, pheader, plen);
+
+    /* the bogus-nxdomain stuff, doctor and NXDOMAIN->NODATA munging can all elide
+       sections of the packet. Find the new length here and put back pseudoheader
+       if it was removed. */
+    return resize_packet(header, n, pheader, plen);
 }
 
 /* sets new last_server */
-void reply_query(int fd, int family, time_t now)
-{
-  /* packet from peer server, extract data for cache, and send to
-     original requester */
-  HEADER *header;
-  union mysockaddr serveraddr;
-  struct frec *forward;
-  socklen_t addrlen = sizeof(serveraddr);
-  ssize_t n = recvfrom(fd, daemon->packet, daemon->edns_pktsz, 0, &serveraddr.sa, &addrlen);
-  size_t nn;
-  struct server *server;
-  
-  /* packet buffer overwritten */
-  daemon->srv_save = NULL;
-  
-  /* Determine the address of the server replying  so that we can mark that as good */
-  serveraddr.sa.sa_family = family;
+void reply_query(int fd, int family, time_t now) {
+    /* packet from peer server, extract data for cache, and send to
+       original requester */
+    HEADER* header;
+    union mysockaddr serveraddr;
+    struct frec* forward;
+    socklen_t addrlen = sizeof(serveraddr);
+    ssize_t n = recvfrom(fd, daemon->packet, daemon->edns_pktsz, 0, &serveraddr.sa, &addrlen);
+    size_t nn;
+    struct server* server;
+
+    /* packet buffer overwritten */
+    daemon->srv_save = NULL;
+
+    /* Determine the address of the server replying  so that we can mark that as good */
+    serveraddr.sa.sa_family = family;
 #ifdef HAVE_IPV6
-  if (serveraddr.sa.sa_family == AF_INET6)
-    serveraddr.in6.sin6_flowinfo = 0;
+    if (serveraddr.sa.sa_family == AF_INET6) serveraddr.in6.sin6_flowinfo = 0;
 #endif
-  
-  /* spoof check: answer must come from known server, */
-  for (server = daemon->servers; server; server = server->next)
-    if (!(server->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)) &&
-	sockaddr_isequal(&server->addr, &serveraddr))
-      break;
-   
-  header = (HEADER *)daemon->packet;
-  
-  if (!server ||
-      n < (int)sizeof(HEADER) || !header->qr ||
-      !(forward = lookup_frec(ntohs(header->id), questions_crc(header, n, daemon->namebuff))))
-    return;
-   
-  server = forward->sentto;
-  
-  if ((header->rcode == SERVFAIL || header->rcode == REFUSED) &&
-      !(daemon->options & OPT_ORDER) &&
-      forward->forwardall == 0)
+
+    /* spoof check: answer must come from known server, */
+    for (server = daemon->servers; server; server = server->next)
+        if (!(server->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)) &&
+            sockaddr_isequal(&server->addr, &serveraddr))
+            break;
+
+    header = (HEADER*) daemon->packet;
+
+    if (!server || n < (int) sizeof(HEADER) || !header->qr ||
+        !(forward = lookup_frec(ntohs(header->id), questions_crc(header, n, daemon->namebuff))))
+        return;
+
+    server = forward->sentto;
+
+    if ((header->rcode == SERVFAIL || header->rcode == REFUSED) && !(daemon->options & OPT_ORDER) &&
+        forward->forwardall == 0)
     /* for broken servers, attempt to send to another one. */
     {
-      unsigned char *pheader;
-      size_t plen;
-      int is_sign;
-      
-      /* recreate query from reply */
-      pheader = find_pseudoheader(header, (size_t)n, &plen, NULL, &is_sign);
-      if (!is_sign)
-	{
-	  header->ancount = htons(0);
-	  header->nscount = htons(0);
-	  header->arcount = htons(0);
-	  if ((nn = resize_packet(header, (size_t)n, pheader, plen)))
-	    {
-	      header->qr = 0;
-	      header->tc = 0;
-	      forward_query(-1, NULL, NULL, 0, header, nn, now, forward);
-	      return;
-	    }
-	}
-    }   
-  
-  if ((forward->sentto->flags & SERV_TYPE) == 0)
-    {
-      if (header->rcode == SERVFAIL || header->rcode == REFUSED)
-	server = NULL;
-      else
-	{
-	  struct server *last_server;
-	  
-	  /* find good server by address if possible, otherwise assume the last one we sent to */ 
-	  for (last_server = daemon->servers; last_server; last_server = last_server->next)
-	    if (!(last_server->flags & (SERV_LITERAL_ADDRESS | SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_NO_ADDR)) &&
-		sockaddr_isequal(&last_server->addr, &serveraddr))
-	      {
-		server = last_server;
-		break;
-	      }
-	} 
-      if (!(daemon->options & OPT_ALL_SERVERS))
-	daemon->last_server = server;
+        unsigned char* pheader;
+        size_t plen;
+        int is_sign;
+
+        /* recreate query from reply */
+        pheader = find_pseudoheader(header, (size_t) n, &plen, NULL, &is_sign);
+        if (!is_sign) {
+            header->ancount = htons(0);
+            header->nscount = htons(0);
+            header->arcount = htons(0);
+            if ((nn = resize_packet(header, (size_t) n, pheader, plen))) {
+                header->qr = 0;
+                header->tc = 0;
+                forward_query(-1, NULL, NULL, 0, header, nn, now, forward);
+                return;
+            }
+        }
     }
-  
-  /* If the answer is an error, keep the forward record in place in case
-     we get a good reply from another server. Kill it when we've
-     had replies from all to avoid filling the forwarding table when
-     everything is broken */
-  if (forward->forwardall == 0 || --forward->forwardall == 1 || 
-      (header->rcode != REFUSED && header->rcode != SERVFAIL))
-    {
-      if ((nn = process_reply(header, now, server, (size_t)n)))
-	{
-	  header->id = htons(forward->orig_id);
-	  header->ra = 1; /* recursion if available */
-	  send_from(forward->fd, daemon->options & OPT_NOWILD, daemon->packet, nn, 
-		    &forward->source, &forward->dest, forward->iface);
-	}
-      free_frec(forward); /* cancel */
+
+    if ((forward->sentto->flags & SERV_TYPE) == 0) {
+        if (header->rcode == SERVFAIL || header->rcode == REFUSED)
+            server = NULL;
+        else {
+            struct server* last_server;
+
+            /* find good server by address if possible, otherwise assume the last one we sent to */
+            for (last_server = daemon->servers; last_server; last_server = last_server->next)
+                if (!(last_server->flags &
+                      (SERV_LITERAL_ADDRESS | SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_NO_ADDR)) &&
+                    sockaddr_isequal(&last_server->addr, &serveraddr)) {
+                    server = last_server;
+                    break;
+                }
+        }
+        if (!(daemon->options & OPT_ALL_SERVERS)) daemon->last_server = server;
+    }
+
+    /* If the answer is an error, keep the forward record in place in case
+       we get a good reply from another server. Kill it when we've
+       had replies from all to avoid filling the forwarding table when
+       everything is broken */
+    if (forward->forwardall == 0 || --forward->forwardall == 1 ||
+        (header->rcode != REFUSED && header->rcode != SERVFAIL)) {
+        if ((nn = process_reply(header, now, server, (size_t) n))) {
+            header->id = htons(forward->orig_id);
+            header->ra = 1; /* recursion if available */
+            send_from(forward->fd, daemon->options & OPT_NOWILD, daemon->packet, nn,
+                      &forward->source, &forward->dest, forward->iface);
+        }
+        free_frec(forward); /* cancel */
     }
 }
 
-
-void receive_query(struct listener *listen, time_t now)
-{
-  HEADER *header = (HEADER *)daemon->packet;
-  union mysockaddr source_addr;
-  unsigned short type;
-  struct all_addr dst_addr;
-  struct in_addr netmask, dst_addr_4;
-  size_t m;
-  ssize_t n;
-  int if_index = 0;
-  struct iovec iov[1];
-  struct msghdr msg;
-  struct cmsghdr *cmptr;
-  union {
-    struct cmsghdr align; /* this ensures alignment */
+void receive_query(struct listener* listen, time_t now) {
+    HEADER* header = (HEADER*) daemon->packet;
+    union mysockaddr source_addr;
+    unsigned short type;
+    struct all_addr dst_addr;
+    struct in_addr netmask, dst_addr_4;
+    size_t m;
+    ssize_t n;
+    int if_index = 0;
+    struct iovec iov[1];
+    struct msghdr msg;
+    struct cmsghdr* cmptr;
+    union {
+        struct cmsghdr align; /* this ensures alignment */
 #ifdef HAVE_IPV6
-    char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
+        char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
 #endif
 #if defined(HAVE_LINUX_NETWORK)
-    char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
+        char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
 #elif defined(IP_RECVDSTADDR)
-    char control[CMSG_SPACE(sizeof(struct in_addr)) +
-		 CMSG_SPACE(sizeof(struct sockaddr_dl))];
+        char control[CMSG_SPACE(sizeof(struct in_addr)) + CMSG_SPACE(sizeof(struct sockaddr_dl))];
 #endif
-  } control_u;
-  
-  /* packet buffer overwritten */
-  daemon->srv_save = NULL;
-  
-  if (listen->family == AF_INET && (daemon->options & OPT_NOWILD))
-    {
-      dst_addr_4 = listen->iface->addr.in.sin_addr;
-      netmask = listen->iface->netmask;
-    }
-  else
-    {
-      dst_addr_4.s_addr = 0;
-      netmask.s_addr = 0;
+    } control_u;
+
+    /* packet buffer overwritten */
+    daemon->srv_save = NULL;
+
+    if (listen->family == AF_INET && (daemon->options & OPT_NOWILD)) {
+        dst_addr_4 = listen->iface->addr.in.sin_addr;
+        netmask = listen->iface->netmask;
+    } else {
+        dst_addr_4.s_addr = 0;
+        netmask.s_addr = 0;
     }
 
-  iov[0].iov_base = daemon->packet;
-  iov[0].iov_len = daemon->edns_pktsz;
-    
-  msg.msg_control = control_u.control;
-  msg.msg_controllen = sizeof(control_u);
-  msg.msg_flags = 0;
-  msg.msg_name = &source_addr;
-  msg.msg_namelen = sizeof(source_addr);
-  msg.msg_iov = iov;
-  msg.msg_iovlen = 1;
-  
-  if ((n = recvmsg(listen->fd, &msg, 0)) == -1)
-    return;
-  
-  if (n < (int)sizeof(HEADER) || 
-      (msg.msg_flags & MSG_TRUNC) ||
-      header->qr)
-    return;
-  
-  source_addr.sa.sa_family = listen->family;
+    iov[0].iov_base = daemon->packet;
+    iov[0].iov_len = daemon->edns_pktsz;
+
+    msg.msg_control = control_u.control;
+    msg.msg_controllen = sizeof(control_u);
+    msg.msg_flags = 0;
+    msg.msg_name = &source_addr;
+    msg.msg_namelen = sizeof(source_addr);
+    msg.msg_iov = iov;
+    msg.msg_iovlen = 1;
+
+    if ((n = recvmsg(listen->fd, &msg, 0)) == -1) return;
+
+    if (n < (int) sizeof(HEADER) || (msg.msg_flags & MSG_TRUNC) || header->qr) return;
+
+    source_addr.sa.sa_family = listen->family;
 #ifdef HAVE_IPV6
-  if (listen->family == AF_INET6)
-    source_addr.in6.sin6_flowinfo = 0;
+    if (listen->family == AF_INET6) source_addr.in6.sin6_flowinfo = 0;
 #endif
-  
-  if (!(daemon->options & OPT_NOWILD))
-    {
-      struct ifreq ifr;
 
-      if (msg.msg_controllen < sizeof(struct cmsghdr))
-	return;
+    if (!(daemon->options & OPT_NOWILD)) {
+        struct ifreq ifr;
+
+        if (msg.msg_controllen < sizeof(struct cmsghdr)) return;
 
 #if defined(HAVE_LINUX_NETWORK)
-      if (listen->family == AF_INET)
-	for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
-	  if (cmptr->cmsg_level == SOL_IP && cmptr->cmsg_type == IP_PKTINFO)
-	    {
-	      dst_addr_4 = dst_addr.addr.addr4 = ((struct in_pktinfo *)CMSG_DATA(cmptr))->ipi_spec_dst;
-	      if_index = ((struct in_pktinfo *)CMSG_DATA(cmptr))->ipi_ifindex;
-	    }
+        if (listen->family == AF_INET)
+            for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
+                if (cmptr->cmsg_level == SOL_IP && cmptr->cmsg_type == IP_PKTINFO) {
+                    dst_addr_4 = dst_addr.addr.addr4 =
+                        ((struct in_pktinfo*) CMSG_DATA(cmptr))->ipi_spec_dst;
+                    if_index = ((struct in_pktinfo*) CMSG_DATA(cmptr))->ipi_ifindex;
+                }
 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
-      if (listen->family == AF_INET)
-	{
-	  for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
-	    if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR)
-	      dst_addr_4 = dst_addr.addr.addr4 = *((struct in_addr *)CMSG_DATA(cmptr));
-	    else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
-	      if_index = ((struct sockaddr_dl *)CMSG_DATA(cmptr))->sdl_index;
-	}
+        if (listen->family == AF_INET) {
+            for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
+                if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR)
+                    dst_addr_4 = dst_addr.addr.addr4 = *((struct in_addr*) CMSG_DATA(cmptr));
+                else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
+                    if_index = ((struct sockaddr_dl*) CMSG_DATA(cmptr))->sdl_index;
+        }
 #endif
-      
+
 #ifdef HAVE_IPV6
-      if (listen->family == AF_INET6)
-	{
-	  for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
-	    if (cmptr->cmsg_level == IPV6_LEVEL && cmptr->cmsg_type == IPV6_PKTINFO)
-	      {
-		dst_addr.addr.addr6 = ((struct in6_pktinfo *)CMSG_DATA(cmptr))->ipi6_addr;
-		if_index =((struct in6_pktinfo *)CMSG_DATA(cmptr))->ipi6_ifindex;
-	      }
-	}
+        if (listen->family == AF_INET6) {
+            for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
+                if (cmptr->cmsg_level == IPV6_LEVEL && cmptr->cmsg_type == IPV6_PKTINFO) {
+                    dst_addr.addr.addr6 = ((struct in6_pktinfo*) CMSG_DATA(cmptr))->ipi6_addr;
+                    if_index = ((struct in6_pktinfo*) CMSG_DATA(cmptr))->ipi6_ifindex;
+                }
+        }
 #endif
-      
-      /* enforce available interface configuration */
-      
-      if (!indextoname(listen->fd, if_index, ifr.ifr_name) ||
-	  !iface_check(listen->family, &dst_addr, ifr.ifr_name, &if_index))
-	return;
-      
-      if (listen->family == AF_INET &&
-	  (daemon->options & OPT_LOCALISE) &&
-	  ioctl(listen->fd, SIOCGIFNETMASK, &ifr) == -1)
-	return;
-      
-      netmask = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
+
+        /* enforce available interface configuration */
+
+        if (!indextoname(listen->fd, if_index, ifr.ifr_name) ||
+            !iface_check(listen->family, &dst_addr, ifr.ifr_name, &if_index))
+            return;
+
+        if (listen->family == AF_INET && (daemon->options & OPT_LOCALISE) &&
+            ioctl(listen->fd, SIOCGIFNETMASK, &ifr) == -1)
+            return;
+
+        netmask = ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr;
     }
-  
-  if (extract_request(header, (size_t)n, daemon->namebuff, &type))
-    {
-      char types[20];
 
-      querystr(types, type);
+    if (extract_request(header, (size_t) n, daemon->namebuff, &type)) {
+        char types[20];
 
-      if (listen->family == AF_INET) 
-	log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff, 
-		  (struct all_addr *)&source_addr.in.sin_addr, types);
+        querystr(types, type);
+
+        if (listen->family == AF_INET)
+            log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff,
+                      (struct all_addr*) &source_addr.in.sin_addr, types);
 #ifdef HAVE_IPV6
-      else
-	log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff, 
-		  (struct all_addr *)&source_addr.in6.sin6_addr, types);
+        else
+            log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff,
+                      (struct all_addr*) &source_addr.in6.sin6_addr, types);
 #endif
     }
 
-  m = answer_request (header, ((char *) header) + PACKETSZ, (size_t)n, 
-		      dst_addr_4, netmask, now);
-  if (m >= 1)
-    {
-      send_from(listen->fd, daemon->options & OPT_NOWILD, (char *)header, 
-		m, &source_addr, &dst_addr, if_index);
-      daemon->local_answer++;
-    }
-  else if (forward_query(listen->fd, &source_addr, &dst_addr, if_index,
-			 header, (size_t)n, now, NULL))
-    daemon->queries_forwarded++;
-  else
-    daemon->local_answer++;
+    m = answer_request(header, ((char*) header) + PACKETSZ, (size_t) n, dst_addr_4, netmask, now);
+    if (m >= 1) {
+        send_from(listen->fd, daemon->options & OPT_NOWILD, (char*) header, m, &source_addr,
+                  &dst_addr, if_index);
+        daemon->local_answer++;
+    } else if (forward_query(listen->fd, &source_addr, &dst_addr, if_index, header, (size_t) n, now,
+                             NULL))
+        daemon->queries_forwarded++;
+    else
+        daemon->local_answer++;
 }
 
 /* The daemon forks before calling this: it should deal with one connection,
    blocking as neccessary, and then return. Note, need to be a bit careful
    about resources for debug mode, when the fork is suppressed: that's
    done by the caller. */
-unsigned char *tcp_request(int confd, time_t now,
-			   struct in_addr local_addr, struct in_addr netmask)
-{
-  int size = 0;
-  size_t m;
-  unsigned short qtype, gotname;
-  unsigned char c1, c2;
-  /* Max TCP packet + slop */
-  unsigned char *packet = whine_malloc(65536 + MAXDNAME + RRFIXEDSZ);
-  HEADER *header;
-  struct server *last_server;
-  
-  while (1)
-    {
-      if (!packet ||
-	  !read_write(confd, &c1, 1, 1) || !read_write(confd, &c2, 1, 1) ||
-	  !(size = c1 << 8 | c2) ||
-	  !read_write(confd, packet, size, 1))
-       	return packet; 
-  
-      if (size < (int)sizeof(HEADER))
-	continue;
-      
-      header = (HEADER *)packet;
-      
-      if ((gotname = extract_request(header, (unsigned int)size, daemon->namebuff, &qtype)))
-	{
-	  union mysockaddr peer_addr;
-	  socklen_t peer_len = sizeof(union mysockaddr);
-	  
-	  if (getpeername(confd, (struct sockaddr *)&peer_addr, &peer_len) != -1)
-	    {
-	      char types[20];
+unsigned char* tcp_request(int confd, time_t now, struct in_addr local_addr,
+                           struct in_addr netmask) {
+    int size = 0;
+    size_t m;
+    unsigned short qtype, gotname;
+    unsigned char c1, c2;
+    /* Max TCP packet + slop */
+    unsigned char* packet = whine_malloc(65536 + MAXDNAME + RRFIXEDSZ);
+    HEADER* header;
+    struct server* last_server;
 
-	      querystr(types, qtype);
+    while (1) {
+        if (!packet || !read_write(confd, &c1, 1, 1) || !read_write(confd, &c2, 1, 1) ||
+            !(size = c1 << 8 | c2) || !read_write(confd, packet, size, 1))
+            return packet;
 
-	      if (peer_addr.sa.sa_family == AF_INET) 
-		log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff, 
-			  (struct all_addr *)&peer_addr.in.sin_addr, types);
+        if (size < (int) sizeof(HEADER)) continue;
+
+        header = (HEADER*) packet;
+
+        if ((gotname = extract_request(header, (unsigned int) size, daemon->namebuff, &qtype))) {
+            union mysockaddr peer_addr;
+            socklen_t peer_len = sizeof(union mysockaddr);
+
+            if (getpeername(confd, (struct sockaddr*) &peer_addr, &peer_len) != -1) {
+                char types[20];
+
+                querystr(types, qtype);
+
+                if (peer_addr.sa.sa_family == AF_INET)
+                    log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff,
+                              (struct all_addr*) &peer_addr.in.sin_addr, types);
 #ifdef HAVE_IPV6
-	      else
-		log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff, 
-			  (struct all_addr *)&peer_addr.in6.sin6_addr, types);
+                else
+                    log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff,
+                              (struct all_addr*) &peer_addr.in6.sin6_addr, types);
 #endif
-	    }
-	}
-      
-      /* m > 0 if answered from cache */
-      m = answer_request(header, ((char *) header) + 65536, (unsigned int)size, 
-			 local_addr, netmask, now);
+            }
+        }
 
-      /* Do this by steam now we're not in the select() loop */
-      check_log_writer(NULL); 
-      
-      if (m == 0)
-	{
-	  unsigned short flags = 0;
-	  struct all_addr *addrp = NULL;
-	  int type = 0;
-	  char *domain = NULL;
-	  
-	  if (gotname)
-	    flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain);
-	  
-	  if (type != 0  || (daemon->options & OPT_ORDER) || !daemon->last_server)
-	    last_server = daemon->servers;
-	  else
-	    last_server = daemon->last_server;
-      
-	  if (!flags && last_server)
-	    {
-	      struct server *firstsendto = NULL;
-	      unsigned int crc = questions_crc(header, (unsigned int)size, daemon->namebuff);
+        /* m > 0 if answered from cache */
+        m = answer_request(header, ((char*) header) + 65536, (unsigned int) size, local_addr,
+                           netmask, now);
 
-	      /* Loop round available servers until we succeed in connecting to one.
-	         Note that this code subtley ensures that consecutive queries on this connection
-	         which can go to the same server, do so. */
-	      while (1) 
-		{
-		  if (!firstsendto)
-		    firstsendto = last_server;
-		  else
-		    {
-		      if (!(last_server = last_server->next))
-			last_server = daemon->servers;
-		      
-		      if (last_server == firstsendto)
-			break;
-		    }
-	      
-		  /* server for wrong domain */
-		  if (type != (last_server->flags & SERV_TYPE) ||
-		      (type == SERV_HAS_DOMAIN && !hostname_isequal(domain, last_server->domain)))
-		    continue;
-		  
-		  if ((last_server->tcpfd == -1) &&
-		      (last_server->tcpfd = socket(last_server->addr.sa.sa_family, SOCK_STREAM, 0)) != -1 &&
-		      (!local_bind(last_server->tcpfd, &last_server->source_addr,
-				   last_server->interface, last_server->mark, 1) ||
-		       connect(last_server->tcpfd, &last_server->addr.sa, sa_len(&last_server->addr)) == -1))
-		    {
-		      close(last_server->tcpfd);
-		      last_server->tcpfd = -1;
-		    }
-		  
-		  if (last_server->tcpfd == -1)	
-		    continue;
+        /* Do this by steam now we're not in the select() loop */
+        check_log_writer(NULL);
 
-		  c1 = size >> 8;
-		  c2 = size;
-		  
-		  if (!read_write(last_server->tcpfd, &c1, 1, 0) ||
-		      !read_write(last_server->tcpfd, &c2, 1, 0) ||
-		      !read_write(last_server->tcpfd, packet, size, 0) ||
-		      !read_write(last_server->tcpfd, &c1, 1, 1) ||
-		      !read_write(last_server->tcpfd, &c2, 1, 1))
-		    {
-		      close(last_server->tcpfd);
-		      last_server->tcpfd = -1;
-		      continue;
-		    } 
-		  
-		  m = (c1 << 8) | c2;
-		  if (!read_write(last_server->tcpfd, packet, m, 1))
-		    return packet;
-		  
-		  if (!gotname)
-		    strcpy(daemon->namebuff, "query");
-		  if (last_server->addr.sa.sa_family == AF_INET)
-		    log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff, 
-			      (struct all_addr *)&last_server->addr.in.sin_addr, NULL); 
+        if (m == 0) {
+            unsigned short flags = 0;
+            struct all_addr* addrp = NULL;
+            int type = 0;
+            char* domain = NULL;
+
+            if (gotname)
+                flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain);
+
+            if (type != 0 || (daemon->options & OPT_ORDER) || !daemon->last_server)
+                last_server = daemon->servers;
+            else
+                last_server = daemon->last_server;
+
+            if (!flags && last_server) {
+                struct server* firstsendto = NULL;
+                unsigned int crc = questions_crc(header, (unsigned int) size, daemon->namebuff);
+
+                /* Loop round available servers until we succeed in connecting to one.
+                   Note that this code subtley ensures that consecutive queries on this connection
+                   which can go to the same server, do so. */
+                while (1) {
+                    if (!firstsendto)
+                        firstsendto = last_server;
+                    else {
+                        if (!(last_server = last_server->next)) last_server = daemon->servers;
+
+                        if (last_server == firstsendto) break;
+                    }
+
+                    /* server for wrong domain */
+                    if (type != (last_server->flags & SERV_TYPE) ||
+                        (type == SERV_HAS_DOMAIN && !hostname_isequal(domain, last_server->domain)))
+                        continue;
+
+                    if ((last_server->tcpfd == -1) &&
+                        (last_server->tcpfd =
+                             socket(last_server->addr.sa.sa_family, SOCK_STREAM, 0)) != -1 &&
+                        (!local_bind(last_server->tcpfd, &last_server->source_addr,
+                                     last_server->interface, last_server->mark, 1) ||
+                         connect(last_server->tcpfd, &last_server->addr.sa,
+                                 sa_len(&last_server->addr)) == -1)) {
+                        close(last_server->tcpfd);
+                        last_server->tcpfd = -1;
+                    }
+
+                    if (last_server->tcpfd == -1) continue;
+
+                    c1 = size >> 8;
+                    c2 = size;
+
+                    if (!read_write(last_server->tcpfd, &c1, 1, 0) ||
+                        !read_write(last_server->tcpfd, &c2, 1, 0) ||
+                        !read_write(last_server->tcpfd, packet, size, 0) ||
+                        !read_write(last_server->tcpfd, &c1, 1, 1) ||
+                        !read_write(last_server->tcpfd, &c2, 1, 1)) {
+                        close(last_server->tcpfd);
+                        last_server->tcpfd = -1;
+                        continue;
+                    }
+
+                    m = (c1 << 8) | c2;
+                    if (!read_write(last_server->tcpfd, packet, m, 1)) return packet;
+
+                    if (!gotname) strcpy(daemon->namebuff, "query");
+                    if (last_server->addr.sa.sa_family == AF_INET)
+                        log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff,
+                                  (struct all_addr*) &last_server->addr.in.sin_addr, NULL);
 #ifdef HAVE_IPV6
-		  else
-		    log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff, 
-			      (struct all_addr *)&last_server->addr.in6.sin6_addr, NULL);
-#endif 
-		  
-		  /* There's no point in updating the cache, since this process will exit and
-		     lose the information after a few queries. We make this call for the alias and 
-		     bogus-nxdomain side-effects. */
-		  /* If the crc of the question section doesn't match the crc we sent, then
-		     someone might be attempting to insert bogus values into the cache by 
-		     sending replies containing questions and bogus answers. */
-		  if (crc == questions_crc(header, (unsigned int)m, daemon->namebuff))
-		    m = process_reply(header, now, last_server, (unsigned int)m);
-		  
-		  break;
-		}
-	    }
-	  
-	  /* In case of local answer or no connections made. */
-	  if (m == 0)
-	    m = setup_reply(header, (unsigned int)size, addrp, flags, daemon->local_ttl);
-	}
-
-      check_log_writer(NULL);
-      
-      c1 = m>>8;
-      c2 = m;
-      if (!read_write(confd, &c1, 1, 0) ||
-	  !read_write(confd, &c2, 1, 0) || 
-	  !read_write(confd, packet, m, 0))
-	return packet;
-    }
-}
-
-static struct frec *allocate_frec(time_t now)
-{
-  struct frec *f;
-  
-  if ((f = (struct frec *)whine_malloc(sizeof(struct frec))))
-    {
-      f->next = daemon->frec_list;
-      f->time = now;
-      f->sentto = NULL;
-      f->rfd4 = NULL;
-#ifdef HAVE_IPV6
-      f->rfd6 = NULL;
+                    else
+                        log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff,
+                                  (struct all_addr*) &last_server->addr.in6.sin6_addr, NULL);
 #endif
-      daemon->frec_list = f;
-    }
 
-  return f;
+                    /* There's no point in updating the cache, since this process will exit and
+                       lose the information after a few queries. We make this call for the alias and
+                       bogus-nxdomain side-effects. */
+                    /* If the crc of the question section doesn't match the crc we sent, then
+                       someone might be attempting to insert bogus values into the cache by
+                       sending replies containing questions and bogus answers. */
+                    if (crc == questions_crc(header, (unsigned int) m, daemon->namebuff))
+                        m = process_reply(header, now, last_server, (unsigned int) m);
+
+                    break;
+                }
+            }
+
+            /* In case of local answer or no connections made. */
+            if (m == 0)
+                m = setup_reply(header, (unsigned int) size, addrp, flags, daemon->local_ttl);
+        }
+
+        check_log_writer(NULL);
+
+        c1 = m >> 8;
+        c2 = m;
+        if (!read_write(confd, &c1, 1, 0) || !read_write(confd, &c2, 1, 0) ||
+            !read_write(confd, packet, m, 0))
+            return packet;
+    }
 }
 
-static struct randfd *allocate_rfd(int family)
-{
-  static int finger = 0;
-  int i;
+static struct frec* allocate_frec(time_t now) {
+    struct frec* f;
 
-  /* limit the number of sockets we have open to avoid starvation of 
-     (eg) TFTP. Once we have a reasonable number, randomness should be OK */
-
-  for (i = 0; i < RANDOM_SOCKS; i++)
-    if (daemon->randomsocks[i].refcount == 0)
-      {
-	if ((daemon->randomsocks[i].fd = random_sock(family)) == -1)
-	  break;
-      
-	daemon->randomsocks[i].refcount = 1;
-	daemon->randomsocks[i].family = family;
-	return &daemon->randomsocks[i];
-      }
-
-  /* No free ones or cannot get new socket, grab an existing one */
-  for (i = 0; i < RANDOM_SOCKS; i++)
-    {
-      int j = (i+finger) % RANDOM_SOCKS;
-      if (daemon->randomsocks[j].refcount != 0 &&
-	  daemon->randomsocks[j].family == family && 
-	  daemon->randomsocks[j].refcount != 0xffff)
-	{
-	  finger = j;
-	  daemon->randomsocks[j].refcount++;
-	  return &daemon->randomsocks[j];
-	}
-    }
-
-  return NULL; /* doom */
-}
-
-static void free_frec(struct frec *f)
-{
-  if (f->rfd4 && --(f->rfd4->refcount) == 0)
-    close(f->rfd4->fd);
-    
-  f->rfd4 = NULL;
-  f->sentto = NULL;
-  
+    if ((f = (struct frec*) whine_malloc(sizeof(struct frec)))) {
+        f->next = daemon->frec_list;
+        f->time = now;
+        f->sentto = NULL;
+        f->rfd4 = NULL;
 #ifdef HAVE_IPV6
-  if (f->rfd6 && --(f->rfd6->refcount) == 0)
-    close(f->rfd6->fd);
-    
-  f->rfd6 = NULL;
+        f->rfd6 = NULL;
+#endif
+        daemon->frec_list = f;
+    }
+
+    return f;
+}
+
+static struct randfd* allocate_rfd(int family) {
+    static int finger = 0;
+    int i;
+
+    /* limit the number of sockets we have open to avoid starvation of
+       (eg) TFTP. Once we have a reasonable number, randomness should be OK */
+
+    for (i = 0; i < RANDOM_SOCKS; i++)
+        if (daemon->randomsocks[i].refcount == 0) {
+            if ((daemon->randomsocks[i].fd = random_sock(family)) == -1) break;
+
+            daemon->randomsocks[i].refcount = 1;
+            daemon->randomsocks[i].family = family;
+            return &daemon->randomsocks[i];
+        }
+
+    /* No free ones or cannot get new socket, grab an existing one */
+    for (i = 0; i < RANDOM_SOCKS; i++) {
+        int j = (i + finger) % RANDOM_SOCKS;
+        if (daemon->randomsocks[j].refcount != 0 && daemon->randomsocks[j].family == family &&
+            daemon->randomsocks[j].refcount != 0xffff) {
+            finger = j;
+            daemon->randomsocks[j].refcount++;
+            return &daemon->randomsocks[j];
+        }
+    }
+
+    return NULL; /* doom */
+}
+
+static void free_frec(struct frec* f) {
+    if (f->rfd4 && --(f->rfd4->refcount) == 0) close(f->rfd4->fd);
+
+    f->rfd4 = NULL;
+    f->sentto = NULL;
+
+#ifdef HAVE_IPV6
+    if (f->rfd6 && --(f->rfd6->refcount) == 0) close(f->rfd6->fd);
+
+    f->rfd6 = NULL;
 #endif
 }
 
@@ -964,137 +839,105 @@
    else return *wait zero if one available, or *wait is delay to
    when the oldest in-use record will expire. Impose an absolute
    limit of 4*TIMEOUT before we wipe things (for random sockets) */
-struct frec *get_new_frec(time_t now, int *wait)
-{
-  struct frec *f, *oldest, *target;
-  int count;
-  
-  if (wait)
-    *wait = 0;
+struct frec* get_new_frec(time_t now, int* wait) {
+    struct frec *f, *oldest, *target;
+    int count;
 
-  for (f = daemon->frec_list, oldest = NULL, target =  NULL, count = 0; f; f = f->next, count++)
-    if (!f->sentto)
-      target = f;
-    else 
-      {
-	if (difftime(now, f->time) >= 4*TIMEOUT)
-	  {
-	    free_frec(f);
-	    target = f;
-	  }
-	
-	if (!oldest || difftime(f->time, oldest->time) <= 0)
-	  oldest = f;
-      }
+    if (wait) *wait = 0;
 
-  if (target)
-    {
-      target->time = now;
-      return target;
+    for (f = daemon->frec_list, oldest = NULL, target = NULL, count = 0; f; f = f->next, count++)
+        if (!f->sentto)
+            target = f;
+        else {
+            if (difftime(now, f->time) >= 4 * TIMEOUT) {
+                free_frec(f);
+                target = f;
+            }
+
+            if (!oldest || difftime(f->time, oldest->time) <= 0) oldest = f;
+        }
+
+    if (target) {
+        target->time = now;
+        return target;
     }
-  
-  /* can't find empty one, use oldest if there is one
-     and it's older than timeout */
-  if (oldest && ((int)difftime(now, oldest->time)) >= TIMEOUT)
-    { 
-      /* keep stuff for twice timeout if we can by allocating a new
-	 record instead */
-      if (difftime(now, oldest->time) < 2*TIMEOUT && 
-	  count <= daemon->ftabsize &&
-	  (f = allocate_frec(now)))
-	return f;
 
-      if (!wait)
-	{
-	  free_frec(oldest);
-	  oldest->time = now;
-	}
-      return oldest;
-    }
-  
-  /* none available, calculate time 'till oldest record expires */
-  if (count > daemon->ftabsize)
-    {
-      if (oldest && wait)
-	*wait = oldest->time + (time_t)TIMEOUT - now;
-      return NULL;
-    }
-  
-  if (!(f = allocate_frec(now)) && wait)
-    /* wait one second on malloc failure */
-    *wait = 1;
+    /* can't find empty one, use oldest if there is one
+       and it's older than timeout */
+    if (oldest && ((int) difftime(now, oldest->time)) >= TIMEOUT) {
+        /* keep stuff for twice timeout if we can by allocating a new
+       record instead */
+        if (difftime(now, oldest->time) < 2 * TIMEOUT && count <= daemon->ftabsize &&
+            (f = allocate_frec(now)))
+            return f;
 
-  return f; /* OK if malloc fails and this is NULL */
+        if (!wait) {
+            free_frec(oldest);
+            oldest->time = now;
+        }
+        return oldest;
+    }
+
+    /* none available, calculate time 'till oldest record expires */
+    if (count > daemon->ftabsize) {
+        if (oldest && wait) *wait = oldest->time + (time_t) TIMEOUT - now;
+        return NULL;
+    }
+
+    if (!(f = allocate_frec(now)) && wait) /* wait one second on malloc failure */
+        *wait = 1;
+
+    return f; /* OK if malloc fails and this is NULL */
 }
- 
+
 /* crc is all-ones if not known. */
-static struct frec *lookup_frec(unsigned short id, unsigned int crc)
-{
-  struct frec *f;
+static struct frec* lookup_frec(unsigned short id, unsigned int crc) {
+    struct frec* f;
 
-  for(f = daemon->frec_list; f; f = f->next)
-    if (f->sentto && f->new_id == id && 
-	(f->crc == crc || crc == 0xffffffff))
-      return f;
-      
-  return NULL;
+    for (f = daemon->frec_list; f; f = f->next)
+        if (f->sentto && f->new_id == id && (f->crc == crc || crc == 0xffffffff)) return f;
+
+    return NULL;
 }
 
-static struct frec *lookup_frec_by_sender(unsigned short id,
-					  union mysockaddr *addr,
-					  unsigned int crc)
-{
-  struct frec *f;
-  
-  for(f = daemon->frec_list; f; f = f->next)
-    if (f->sentto &&
-	f->orig_id == id && 
-	f->crc == crc &&
-	sockaddr_isequal(&f->source, addr))
-      return f;
-   
-  return NULL;
+static struct frec* lookup_frec_by_sender(unsigned short id, union mysockaddr* addr,
+                                          unsigned int crc) {
+    struct frec* f;
+
+    for (f = daemon->frec_list; f; f = f->next)
+        if (f->sentto && f->orig_id == id && f->crc == crc && sockaddr_isequal(&f->source, addr))
+            return f;
+
+    return NULL;
 }
 
 /* A server record is going away, remove references to it */
-void server_gone(struct server *server)
-{
-  struct frec *f;
-  
-  for (f = daemon->frec_list; f; f = f->next)
-    if (f->sentto && f->sentto == server)
-      free_frec(f);
-  
-  if (daemon->last_server == server)
-    daemon->last_server = NULL;
+void server_gone(struct server* server) {
+    struct frec* f;
 
-  if (daemon->srv_save == server)
-    daemon->srv_save = NULL;
+    for (f = daemon->frec_list; f; f = f->next)
+        if (f->sentto && f->sentto == server) free_frec(f);
+
+    if (daemon->last_server == server) daemon->last_server = NULL;
+
+    if (daemon->srv_save == server) daemon->srv_save = NULL;
 }
 
 /* return unique random ids.
    For signed packets we can't change the ID without breaking the
    signing, so we keep the same one. In this case force is set, and this
    routine degenerates into killing any conflicting forward record. */
-static unsigned short get_id(int force, unsigned short force_id, unsigned int crc)
-{
-  unsigned short ret = 0;
-  
-  if (force)
-    {
-      struct frec *f = lookup_frec(force_id, crc);
-      if (f)
-	free_frec(f); /* free */
-      ret = force_id;
-    }
-  else do 
-    ret = rand16();
-  while (lookup_frec(ret, crc));
-  
-  return ret;
+static unsigned short get_id(int force, unsigned short force_id, unsigned int crc) {
+    unsigned short ret = 0;
+
+    if (force) {
+        struct frec* f = lookup_frec(force_id, crc);
+        if (f) free_frec(f); /* free */
+        ret = force_id;
+    } else
+        do
+            ret = rand16();
+        while (lookup_frec(ret, crc));
+
+    return ret;
 }
-
-
-
-
-
diff --git a/src/helper.c b/src/helper.c
index b992e78..eb6614a 100644
--- a/src/helper.c
+++ b/src/helper.c
@@ -4,425 +4,357 @@
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; version 2 dated June, 1991, or
    (at your option) version 3 dated 29 June, 2007.
- 
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-     
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "dnsmasq.h"
 
-/* This file has code to fork a helper process which recieves data via a pipe 
+/* This file has code to fork a helper process which recieves data via a pipe
    shared with the main process and which is responsible for calling a script when
    DHCP leases change.
 
-   The helper process is forked before the main process drops root, so it retains root 
-   privs to pass on to the script. For this reason it tries to be paranoid about 
+   The helper process is forked before the main process drops root, so it retains root
+   privs to pass on to the script. For this reason it tries to be paranoid about
    data received from the main process, in case that has been compromised. We don't
    want the helper to give an attacker root. In particular, the script to be run is
-   not settable via the pipe, once the fork has taken place it is not alterable by the 
+   not settable via the pipe, once the fork has taken place it is not alterable by the
    main process.
 */
 
 #if defined(HAVE_DHCP) && defined(HAVE_SCRIPT)
 
-static void my_setenv(const char *name, const char *value, int *error);
+static void my_setenv(const char* name, const char* value, int* error);
 
-struct script_data
-{
-  unsigned char action, hwaddr_len, hwaddr_type;
-  unsigned char clid_len, hostname_len, uclass_len, vclass_len, shost_len;
-  struct in_addr addr, giaddr;
-  unsigned int remaining_time;
+struct script_data {
+    unsigned char action, hwaddr_len, hwaddr_type;
+    unsigned char clid_len, hostname_len, uclass_len, vclass_len, shost_len;
+    struct in_addr addr, giaddr;
+    unsigned int remaining_time;
 #ifdef HAVE_BROKEN_RTC
-  unsigned int length;
+    unsigned int length;
 #else
-  time_t expires;
+    time_t expires;
 #endif
-  unsigned char hwaddr[DHCP_CHADDR_MAX];
-  char interface[IF_NAMESIZE];
+    unsigned char hwaddr[DHCP_CHADDR_MAX];
+    char interface[IF_NAMESIZE];
 };
 
-static struct script_data *buf = NULL;
+static struct script_data* buf = NULL;
 static size_t bytes_in_buf = 0, buf_size = 0;
 
-int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
-{
-  pid_t pid;
-  int i, pipefd[2];
-  struct sigaction sigact;
+int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd) {
+    pid_t pid;
+    int i, pipefd[2];
+    struct sigaction sigact;
 
-  /* create the pipe through which the main program sends us commands,
-     then fork our process. */
-  if (pipe(pipefd) == -1 || !fix_fd(pipefd[1]) || (pid = fork()) == -1)
-    {
-      send_event(err_fd, EVENT_PIPE_ERR, errno);
-      _exit(0);
+    /* create the pipe through which the main program sends us commands,
+       then fork our process. */
+    if (pipe(pipefd) == -1 || !fix_fd(pipefd[1]) || (pid = fork()) == -1) {
+        send_event(err_fd, EVENT_PIPE_ERR, errno);
+        _exit(0);
     }
 
-  if (pid != 0)
-    {
-      close(pipefd[0]); /* close reader side */
-      return pipefd[1];
+    if (pid != 0) {
+        close(pipefd[0]); /* close reader side */
+        return pipefd[1];
     }
 
-  /* ignore SIGTERM, so that we can clean up when the main process gets hit
-     and SIGALRM so that we can use sleep() */
-  sigact.sa_handler = SIG_IGN;
-  sigact.sa_flags = 0;
-  sigemptyset(&sigact.sa_mask);
-  sigaction(SIGTERM, &sigact, NULL);
-  sigaction(SIGALRM, &sigact, NULL);
+    /* ignore SIGTERM, so that we can clean up when the main process gets hit
+       and SIGALRM so that we can use sleep() */
+    sigact.sa_handler = SIG_IGN;
+    sigact.sa_flags = 0;
+    sigemptyset(&sigact.sa_mask);
+    sigaction(SIGTERM, &sigact, NULL);
+    sigaction(SIGALRM, &sigact, NULL);
 
-  if (!(daemon->options & OPT_DEBUG) && uid != 0)
-    {
-      gid_t dummy;
-      if (setgroups(0, &dummy) == -1 || 
-	  setgid(gid) == -1 || 
-	  setuid(uid) == -1)
-	{
-	  if (daemon->options & OPT_NO_FORK)
-	    /* send error to daemon process if no-fork */
-	    send_event(event_fd, EVENT_HUSER_ERR, errno);
-	  else
-	    {
-	      /* kill daemon */
-	      send_event(event_fd, EVENT_DIE, 0);
-	      /* return error */
-	      send_event(err_fd, EVENT_HUSER_ERR, errno);
-	    }
-	  _exit(0);
-	}
-    }
-
-  /* close all the sockets etc, we don't need them here. This closes err_fd, so that
-     main process can return. */
-  for (max_fd--; max_fd >= 0; max_fd--)
-    if (max_fd != STDOUT_FILENO && max_fd != STDERR_FILENO && 
-	max_fd != STDIN_FILENO && max_fd != pipefd[0] && max_fd != event_fd)
-      close(max_fd);
-  
-  /* loop here */
-  while(1)
-    {
-      struct script_data data;
-      char *p, *action_str, *hostname = NULL;
-      unsigned char *buf = (unsigned char *)daemon->namebuff;
-      int err = 0;
-
-      /* we read zero bytes when pipe closed: this is our signal to exit */ 
-      if (!read_write(pipefd[0], (unsigned char *)&data, sizeof(data), 1))
-	_exit(0);
-      
-      if (data.action == ACTION_DEL)
-	action_str = "del";
-      else if (data.action == ACTION_ADD)
-	action_str = "add";
-      else if (data.action == ACTION_OLD || data.action == ACTION_OLD_HOSTNAME)
-	action_str = "old";
-      else
-	continue;
-	
-      /* stringify MAC into dhcp_buff */
-      p = daemon->dhcp_buff;
-      if (data.hwaddr_type != ARPHRD_ETHER || data.hwaddr_len == 0) 
-        p += sprintf(p, "%.2x-", data.hwaddr_type);
-      for (i = 0; (i < data.hwaddr_len) && (i < DHCP_CHADDR_MAX); i++)
-        {
-          p += sprintf(p, "%.2x", data.hwaddr[i]);
-          if (i != data.hwaddr_len - 1)
-            p += sprintf(p, ":");
+    if (!(daemon->options & OPT_DEBUG) && uid != 0) {
+        gid_t dummy;
+        if (setgroups(0, &dummy) == -1 || setgid(gid) == -1 || setuid(uid) == -1) {
+            if (daemon->options & OPT_NO_FORK) /* send error to daemon process if no-fork */
+                send_event(event_fd, EVENT_HUSER_ERR, errno);
+            else {
+                /* kill daemon */
+                send_event(event_fd, EVENT_DIE, 0);
+                /* return error */
+                send_event(err_fd, EVENT_HUSER_ERR, errno);
+            }
+            _exit(0);
         }
-      
-      /* and CLID into packet */
-      if (!read_write(pipefd[0], buf, data.clid_len, 1))
-	continue;
-      for (p = daemon->packet, i = 0; i < data.clid_len; i++)
-	{
-	  p += sprintf(p, "%.2x", buf[i]);
-	  if (i != data.clid_len - 1) 
-	    p += sprintf(p, ":");
-	}
-      
-      /* and expiry or length into dhcp_buff2 */
+    }
+
+    /* close all the sockets etc, we don't need them here. This closes err_fd, so that
+       main process can return. */
+    for (max_fd--; max_fd >= 0; max_fd--)
+        if (max_fd != STDOUT_FILENO && max_fd != STDERR_FILENO && max_fd != STDIN_FILENO &&
+            max_fd != pipefd[0] && max_fd != event_fd)
+            close(max_fd);
+
+    /* loop here */
+    while (1) {
+        struct script_data data;
+        char *p, *action_str, *hostname = NULL;
+        unsigned char* buf = (unsigned char*) daemon->namebuff;
+        int err = 0;
+
+        /* we read zero bytes when pipe closed: this is our signal to exit */
+        if (!read_write(pipefd[0], (unsigned char*) &data, sizeof(data), 1)) _exit(0);
+
+        if (data.action == ACTION_DEL)
+            action_str = "del";
+        else if (data.action == ACTION_ADD)
+            action_str = "add";
+        else if (data.action == ACTION_OLD || data.action == ACTION_OLD_HOSTNAME)
+            action_str = "old";
+        else
+            continue;
+
+        /* stringify MAC into dhcp_buff */
+        p = daemon->dhcp_buff;
+        if (data.hwaddr_type != ARPHRD_ETHER || data.hwaddr_len == 0)
+            p += sprintf(p, "%.2x-", data.hwaddr_type);
+        for (i = 0; (i < data.hwaddr_len) && (i < DHCP_CHADDR_MAX); i++) {
+            p += sprintf(p, "%.2x", data.hwaddr[i]);
+            if (i != data.hwaddr_len - 1) p += sprintf(p, ":");
+        }
+
+        /* and CLID into packet */
+        if (!read_write(pipefd[0], buf, data.clid_len, 1)) continue;
+        for (p = daemon->packet, i = 0; i < data.clid_len; i++) {
+            p += sprintf(p, "%.2x", buf[i]);
+            if (i != data.clid_len - 1) p += sprintf(p, ":");
+        }
+
+        /* and expiry or length into dhcp_buff2 */
 #ifdef HAVE_BROKEN_RTC
-      sprintf(daemon->dhcp_buff2, "%u ", data.length);
+        sprintf(daemon->dhcp_buff2, "%u ", data.length);
 #else
-      sprintf(daemon->dhcp_buff2, "%lu ", (unsigned long)data.expires);
+        sprintf(daemon->dhcp_buff2, "%lu ", (unsigned long) data.expires);
 #endif
-      
-      if (!read_write(pipefd[0], buf, 
-		      data.hostname_len + data.uclass_len + data.vclass_len + data.shost_len, 1))
-	continue;
-      
-      /* possible fork errors are all temporary resource problems */
-      while ((pid = fork()) == -1 && (errno == EAGAIN || errno == ENOMEM))
-	sleep(2);
-      
-      if (pid == -1)
-	continue;
-	  
-      /* wait for child to complete */
-      if (pid != 0)
-	{
-	  /* reap our children's children, if necessary */
-	  while (1)
-	    {
-	      int status;
-	      pid_t rc = wait(&status);
-	      
-	      if (rc == pid)
-		{
-		  /* On error send event back to main process for logging */
-		  if (WIFSIGNALED(status))
-		    send_event(event_fd, EVENT_KILLED, WTERMSIG(status));
-		  else if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
-		    send_event(event_fd, EVENT_EXITED, WEXITSTATUS(status));
-		  break;
-		}
-	      
-	      if (rc == -1 && errno != EINTR)
-		break;
-	    }
-	  
-	  continue;
-	}
-      
-      if (data.clid_len != 0)
-	my_setenv("DNSMASQ_CLIENT_ID", daemon->packet, &err);
 
-      if (strlen(data.interface) != 0)
-	my_setenv("DNSMASQ_INTERFACE", data.interface, &err);
-            
+        if (!read_write(pipefd[0], buf,
+                        data.hostname_len + data.uclass_len + data.vclass_len + data.shost_len, 1))
+            continue;
+
+        /* possible fork errors are all temporary resource problems */
+        while ((pid = fork()) == -1 && (errno == EAGAIN || errno == ENOMEM)) sleep(2);
+
+        if (pid == -1) continue;
+
+        /* wait for child to complete */
+        if (pid != 0) {
+            /* reap our children's children, if necessary */
+            while (1) {
+                int status;
+                pid_t rc = wait(&status);
+
+                if (rc == pid) {
+                    /* On error send event back to main process for logging */
+                    if (WIFSIGNALED(status))
+                        send_event(event_fd, EVENT_KILLED, WTERMSIG(status));
+                    else if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
+                        send_event(event_fd, EVENT_EXITED, WEXITSTATUS(status));
+                    break;
+                }
+
+                if (rc == -1 && errno != EINTR) break;
+            }
+
+            continue;
+        }
+
+        if (data.clid_len != 0) my_setenv("DNSMASQ_CLIENT_ID", daemon->packet, &err);
+
+        if (strlen(data.interface) != 0) my_setenv("DNSMASQ_INTERFACE", data.interface, &err);
+
 #ifdef HAVE_BROKEN_RTC
-      my_setenv("DNSMASQ_LEASE_LENGTH", daemon->dhcp_buff2, &err);
+        my_setenv("DNSMASQ_LEASE_LENGTH", daemon->dhcp_buff2, &err);
 #else
-      my_setenv("DNSMASQ_LEASE_EXPIRES", daemon->dhcp_buff2, &err); 
+        my_setenv("DNSMASQ_LEASE_EXPIRES", daemon->dhcp_buff2, &err);
 #endif
-      
-      if (data.vclass_len != 0)
-	{
-	  buf[data.vclass_len - 1] = 0; /* don't trust zero-term */
-	  /* cannot have = chars in env - truncate if found . */
-	  if ((p = strchr((char *)buf, '=')))
-	    *p = 0;
-	  my_setenv("DNSMASQ_VENDOR_CLASS", (char *)buf, &err);
-	  buf += data.vclass_len;
-	}
-      
-      if (data.uclass_len != 0)
-	{
-	  unsigned char *end = buf + data.uclass_len;
-	  buf[data.uclass_len - 1] = 0; /* don't trust zero-term */
-	  
-	  for (i = 0; buf < end;)
-	    {
-	      size_t len = strlen((char *)buf) + 1;
-	      if ((p = strchr((char *)buf, '=')))
-		*p = 0;
-	      if (strlen((char *)buf) != 0)
-		{
-		  sprintf(daemon->dhcp_buff2, "DNSMASQ_USER_CLASS%i", i++);
-		  my_setenv(daemon->dhcp_buff2, (char *)buf, &err);
-		}
-	      buf += len;
-	    }
-	}
-      
-      if (data.shost_len != 0)
-	{
-	  buf[data.shost_len - 1] = 0; /* don't trust zero-term */
-	  /* cannot have = chars in env - truncate if found . */
-	  if ((p = strchr((char *)buf, '=')))
-	    *p = 0;
-	  my_setenv("DNSMASQ_SUPPLIED_HOSTNAME", (char *)buf, &err);
-	  buf += data.shost_len;
-	}
 
-      if (data.giaddr.s_addr != 0)
-	my_setenv("DNSMASQ_RELAY_ADDRESS", inet_ntoa(data.giaddr), &err); 
+        if (data.vclass_len != 0) {
+            buf[data.vclass_len - 1] = 0; /* don't trust zero-term */
+            /* cannot have = chars in env - truncate if found . */
+            if ((p = strchr((char*) buf, '='))) *p = 0;
+            my_setenv("DNSMASQ_VENDOR_CLASS", (char*) buf, &err);
+            buf += data.vclass_len;
+        }
 
-      sprintf(daemon->dhcp_buff2, "%u ", data.remaining_time);
-      my_setenv("DNSMASQ_TIME_REMAINING", daemon->dhcp_buff2, &err);
-      
-      if (data.hostname_len != 0)
-	{
-	  char *dot;
-	  hostname = (char *)buf;
-	  hostname[data.hostname_len - 1] = 0;
-	  if (!legal_hostname(hostname))
-	    hostname = NULL;
-	  else if ((dot = strchr(hostname, '.')))
-	    {
-	      my_setenv("DNSMASQ_DOMAIN", dot+1, &err);
-	      *dot = 0;
-	    }
-	}
-      
-      if (data.action == ACTION_OLD_HOSTNAME && hostname)
-	{
-	  my_setenv("DNSMASQ_OLD_HOSTNAME", hostname, &err);
-	  hostname = NULL;
-	}
+        if (data.uclass_len != 0) {
+            unsigned char* end = buf + data.uclass_len;
+            buf[data.uclass_len - 1] = 0; /* don't trust zero-term */
 
-      /* we need to have the event_fd around if exec fails */
-      if ((i = fcntl(event_fd, F_GETFD)) != -1)
-	fcntl(event_fd, F_SETFD, i | FD_CLOEXEC);
-      close(pipefd[0]);
+            for (i = 0; buf < end;) {
+                size_t len = strlen((char*) buf) + 1;
+                if ((p = strchr((char*) buf, '='))) *p = 0;
+                if (strlen((char*) buf) != 0) {
+                    sprintf(daemon->dhcp_buff2, "DNSMASQ_USER_CLASS%i", i++);
+                    my_setenv(daemon->dhcp_buff2, (char*) buf, &err);
+                }
+                buf += len;
+            }
+        }
 
-      p =  strrchr(daemon->lease_change_command, '/');
-      if (err == 0)
-	{
-	  execl(daemon->lease_change_command, 
-		p ? p+1 : daemon->lease_change_command,
-		action_str, daemon->dhcp_buff, inet_ntoa(data.addr), hostname, (char*)NULL);
-	  err = errno;
-	}
-      /* failed, send event so the main process logs the problem */
-      send_event(event_fd, EVENT_EXEC_ERR, err);
-      _exit(0); 
+        if (data.shost_len != 0) {
+            buf[data.shost_len - 1] = 0; /* don't trust zero-term */
+            /* cannot have = chars in env - truncate if found . */
+            if ((p = strchr((char*) buf, '='))) *p = 0;
+            my_setenv("DNSMASQ_SUPPLIED_HOSTNAME", (char*) buf, &err);
+            buf += data.shost_len;
+        }
+
+        if (data.giaddr.s_addr != 0)
+            my_setenv("DNSMASQ_RELAY_ADDRESS", inet_ntoa(data.giaddr), &err);
+
+        sprintf(daemon->dhcp_buff2, "%u ", data.remaining_time);
+        my_setenv("DNSMASQ_TIME_REMAINING", daemon->dhcp_buff2, &err);
+
+        if (data.hostname_len != 0) {
+            char* dot;
+            hostname = (char*) buf;
+            hostname[data.hostname_len - 1] = 0;
+            if (!legal_hostname(hostname))
+                hostname = NULL;
+            else if ((dot = strchr(hostname, '.'))) {
+                my_setenv("DNSMASQ_DOMAIN", dot + 1, &err);
+                *dot = 0;
+            }
+        }
+
+        if (data.action == ACTION_OLD_HOSTNAME && hostname) {
+            my_setenv("DNSMASQ_OLD_HOSTNAME", hostname, &err);
+            hostname = NULL;
+        }
+
+        /* we need to have the event_fd around if exec fails */
+        if ((i = fcntl(event_fd, F_GETFD)) != -1) fcntl(event_fd, F_SETFD, i | FD_CLOEXEC);
+        close(pipefd[0]);
+
+        p = strrchr(daemon->lease_change_command, '/');
+        if (err == 0) {
+            execl(daemon->lease_change_command, p ? p + 1 : daemon->lease_change_command,
+                  action_str, daemon->dhcp_buff, inet_ntoa(data.addr), hostname, (char*) NULL);
+            err = errno;
+        }
+        /* failed, send event so the main process logs the problem */
+        send_event(event_fd, EVENT_EXEC_ERR, err);
+        _exit(0);
     }
 }
 
-static void my_setenv(const char *name, const char *value, int *error)
-{
-  if (*error == 0 && setenv(name, value, 1) != 0)
-    *error = errno;
+static void my_setenv(const char* name, const char* value, int* error) {
+    if (*error == 0 && setenv(name, value, 1) != 0) *error = errno;
 }
- 
-/* pack up lease data into a buffer */    
-void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t now)
-{
-  unsigned char *p;
-  size_t size;
-  unsigned int hostname_len = 0, clid_len = 0, vclass_len = 0;
-  unsigned int uclass_len = 0, shost_len = 0;
-  
-  /* no script */
-  if (daemon->helperfd == -1)
-    return;
 
-  if (lease->vendorclass)
-    vclass_len = lease->vendorclass_len;
-  if (lease->userclass)
-    uclass_len = lease->userclass_len;
-  if (lease->supplied_hostname)
-    shost_len = lease->supplied_hostname_len;
-  if (lease->clid)
-    clid_len = lease->clid_len;
-  if (hostname)
-    hostname_len = strlen(hostname) + 1;
+/* pack up lease data into a buffer */
+void queue_script(int action, struct dhcp_lease* lease, char* hostname, time_t now) {
+    unsigned char* p;
+    size_t size;
+    unsigned int hostname_len = 0, clid_len = 0, vclass_len = 0;
+    unsigned int uclass_len = 0, shost_len = 0;
 
-  size = sizeof(struct script_data) +  clid_len + vclass_len + uclass_len + shost_len + hostname_len;
+    /* no script */
+    if (daemon->helperfd == -1) return;
 
-  if (size > buf_size)
-    {
-      struct script_data *new;
-      
-      /* start with reasonable size, will almost never need extending. */
-      if (size < sizeof(struct script_data) + 200)
-	size = sizeof(struct script_data) + 200;
+    if (lease->vendorclass) vclass_len = lease->vendorclass_len;
+    if (lease->userclass) uclass_len = lease->userclass_len;
+    if (lease->supplied_hostname) shost_len = lease->supplied_hostname_len;
+    if (lease->clid) clid_len = lease->clid_len;
+    if (hostname) hostname_len = strlen(hostname) + 1;
 
-      if (!(new = whine_malloc(size)))
-	return;
-      if (buf)
-	free(buf);
-      buf = new;
-      buf_size = size;
+    size =
+        sizeof(struct script_data) + clid_len + vclass_len + uclass_len + shost_len + hostname_len;
+
+    if (size > buf_size) {
+        struct script_data* new;
+
+        /* start with reasonable size, will almost never need extending. */
+        if (size < sizeof(struct script_data) + 200) size = sizeof(struct script_data) + 200;
+
+        if (!(new = whine_malloc(size))) return;
+        if (buf) free(buf);
+        buf = new;
+        buf_size = size;
     }
 
-  buf->action = action;
-  buf->hwaddr_len = lease->hwaddr_len;
-  buf->hwaddr_type = lease->hwaddr_type;
-  buf->clid_len = clid_len;
-  buf->vclass_len = vclass_len;
-  buf->uclass_len = uclass_len;
-  buf->shost_len = shost_len;
-  buf->hostname_len = hostname_len;
-  buf->addr = lease->addr;
-  buf->giaddr = lease->giaddr;
-  memcpy(buf->hwaddr, lease->hwaddr, lease->hwaddr_len);
-  buf->interface[0] = 0;
+    buf->action = action;
+    buf->hwaddr_len = lease->hwaddr_len;
+    buf->hwaddr_type = lease->hwaddr_type;
+    buf->clid_len = clid_len;
+    buf->vclass_len = vclass_len;
+    buf->uclass_len = uclass_len;
+    buf->shost_len = shost_len;
+    buf->hostname_len = hostname_len;
+    buf->addr = lease->addr;
+    buf->giaddr = lease->giaddr;
+    memcpy(buf->hwaddr, lease->hwaddr, lease->hwaddr_len);
+    buf->interface[0] = 0;
 #ifdef HAVE_LINUX_NETWORK
-  if (lease->last_interface != 0)
-    {
-      struct ifreq ifr;
-      ifr.ifr_ifindex = lease->last_interface;
-      if (ioctl(daemon->dhcpfd, SIOCGIFNAME, &ifr) != -1)
-	strncpy(buf->interface, ifr.ifr_name, IF_NAMESIZE);
+    if (lease->last_interface != 0) {
+        struct ifreq ifr;
+        ifr.ifr_ifindex = lease->last_interface;
+        if (ioctl(daemon->dhcpfd, SIOCGIFNAME, &ifr) != -1)
+            strncpy(buf->interface, ifr.ifr_name, IF_NAMESIZE);
     }
 #else
-  if (lease->last_interface != 0)
-    if_indextoname(lease->last_interface, buf->interface);
+    if (lease->last_interface != 0) if_indextoname(lease->last_interface, buf->interface);
 #endif
-  
-#ifdef HAVE_BROKEN_RTC 
-  buf->length = lease->length;
+
+#ifdef HAVE_BROKEN_RTC
+    buf->length = lease->length;
 #else
-  buf->expires = lease->expires;
+    buf->expires = lease->expires;
 #endif
-  buf->remaining_time = (unsigned int)difftime(lease->expires, now);
+    buf->remaining_time = (unsigned int) difftime(lease->expires, now);
 
-  p = (unsigned char *)(buf+1);
-  if (clid_len != 0)
-    {
-      memcpy(p, lease->clid, clid_len);
-      p += clid_len;
+    p = (unsigned char*) (buf + 1);
+    if (clid_len != 0) {
+        memcpy(p, lease->clid, clid_len);
+        p += clid_len;
     }
-  if (vclass_len != 0)
-    {
-      memcpy(p, lease->vendorclass, vclass_len);
-      p += vclass_len;
+    if (vclass_len != 0) {
+        memcpy(p, lease->vendorclass, vclass_len);
+        p += vclass_len;
     }
-  if (uclass_len != 0)
-    {
-      memcpy(p, lease->userclass, uclass_len);
-      p += uclass_len;
+    if (uclass_len != 0) {
+        memcpy(p, lease->userclass, uclass_len);
+        p += uclass_len;
     }
-  if (shost_len != 0)
-    {
-      memcpy(p, lease->supplied_hostname, shost_len);
-      p += shost_len;
-    } 
-  if (hostname_len != 0)
-    {
-      memcpy(p, hostname, hostname_len);
-      p += hostname_len;
+    if (shost_len != 0) {
+        memcpy(p, lease->supplied_hostname, shost_len);
+        p += shost_len;
+    }
+    if (hostname_len != 0) {
+        memcpy(p, hostname, hostname_len);
+        p += hostname_len;
     }
 
-  bytes_in_buf = p - (unsigned char *)buf;
+    bytes_in_buf = p - (unsigned char*) buf;
 }
 
-int helper_buf_empty(void)
-{
-  return bytes_in_buf == 0;
+int helper_buf_empty(void) {
+    return bytes_in_buf == 0;
 }
 
-void helper_write(void)
-{
-  ssize_t rc;
+void helper_write(void) {
+    ssize_t rc;
 
-  if (bytes_in_buf == 0)
-    return;
-  
-  if ((rc = write(daemon->helperfd, buf, bytes_in_buf)) != -1)
-    {
-      if (bytes_in_buf != (size_t)rc)
-	memmove(buf, buf + rc, bytes_in_buf - rc); 
-      bytes_in_buf -= rc;
-    }
-  else
-    {
-      if (errno == EAGAIN || errno == EINTR)
-	return;
-      bytes_in_buf = 0;
+    if (bytes_in_buf == 0) return;
+
+    if ((rc = write(daemon->helperfd, buf, bytes_in_buf)) != -1) {
+        if (bytes_in_buf != (size_t) rc) memmove(buf, buf + rc, bytes_in_buf - rc);
+        bytes_in_buf -= rc;
+    } else {
+        if (errno == EAGAIN || errno == EINTR) return;
+        bytes_in_buf = 0;
     }
 }
 
 #endif
-
-
diff --git a/src/lease.c b/src/lease.c
index 985bd73..cc18464 100644
--- a/src/lease.c
+++ b/src/lease.c
@@ -4,12 +4,12 @@
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; version 2 dated June, 1991, or
    (at your option) version 3 dated 29 June, 2007.
- 
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-     
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
@@ -21,588 +21,502 @@
 static struct dhcp_lease *leases = NULL, *old_leases = NULL;
 static int dns_dirty, file_dirty, leases_left;
 
-void lease_init(time_t now)
-{
-  unsigned long ei;
-  struct in_addr addr;
-  struct dhcp_lease *lease;
-  int clid_len, hw_len, hw_type;
-  FILE *leasestream;
-  
-  /* These two each hold a DHCP option max size 255
-     and get a terminating zero added */
-  daemon->dhcp_buff = safe_malloc(256);
-  daemon->dhcp_buff2 = safe_malloc(256); 
-  
-  leases_left = daemon->dhcp_max;
+void lease_init(time_t now) {
+    unsigned long ei;
+    struct in_addr addr;
+    struct dhcp_lease* lease;
+    int clid_len, hw_len, hw_type;
+    FILE* leasestream;
 
-  if (daemon->options & OPT_LEASE_RO)
-    {
-      /* run "<lease_change_script> init" once to get the
-	 initial state of the database. If leasefile-ro is
-	 set without a script, we just do without any 
-	 lease database. */
+    /* These two each hold a DHCP option max size 255
+       and get a terminating zero added */
+    daemon->dhcp_buff = safe_malloc(256);
+    daemon->dhcp_buff2 = safe_malloc(256);
+
+    leases_left = daemon->dhcp_max;
+
+    if (daemon->options & OPT_LEASE_RO) {
+        /* run "<lease_change_script> init" once to get the
+       initial state of the database. If leasefile-ro is
+       set without a script, we just do without any
+       lease database. */
 #ifdef HAVE_SCRIPT
-      if (daemon->lease_change_command)
-	{
-	  strcpy(daemon->dhcp_buff, daemon->lease_change_command);
-	  strcat(daemon->dhcp_buff, " init");
-	  leasestream = popen(daemon->dhcp_buff, "r");
-	}
-      else
+        if (daemon->lease_change_command) {
+            strcpy(daemon->dhcp_buff, daemon->lease_change_command);
+            strcat(daemon->dhcp_buff, " init");
+            leasestream = popen(daemon->dhcp_buff, "r");
+        } else
 #endif
-	{
-          file_dirty = dns_dirty = 0;
-          return;
+        {
+            file_dirty = dns_dirty = 0;
+            return;
         }
 
-    }
-  else
-    {
-      /* NOTE: need a+ mode to create file if it doesn't exist */
-      leasestream = daemon->lease_stream = fopen(daemon->lease_file, "a+");
-      
-      if (!leasestream)
-	die(_("cannot open or create lease file %s: %s"), daemon->lease_file, EC_FILE);
-      
-      /* a+ mode leaves pointer at end. */
-      rewind(leasestream);
-    }
-  
-  /* client-id max length is 255 which is 255*2 digits + 254 colons 
-     borrow DNS packet buffer which is always larger than 1000 bytes */
-  if (leasestream)
-    while (fscanf(leasestream, "%lu %255s %16s %255s %764s",
-		  &ei, daemon->dhcp_buff2, daemon->namebuff, 
-		  daemon->dhcp_buff, daemon->packet) == 5)
-      {
-	hw_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, DHCP_CHADDR_MAX, NULL, &hw_type);
-	/* For backwards compatibility, no explict MAC address type means ether. */
-	if (hw_type == 0 && hw_len != 0)
-	  hw_type = ARPHRD_ETHER;
-	
-	addr.s_addr = inet_addr(daemon->namebuff);
-	
-	/* decode hex in place */
-	clid_len = 0;
-	if (strcmp(daemon->packet, "*") != 0)
-	  clid_len = parse_hex(daemon->packet, (unsigned char *)daemon->packet, 255, NULL, NULL);
-	
-	if (!(lease = lease_allocate(addr)))
-	  die (_("too many stored leases"), NULL, EC_MISC);
-       	
-#ifdef HAVE_BROKEN_RTC
-	if (ei != 0)
-	  lease->expires = (time_t)ei + now;
-	else
-	  lease->expires = (time_t)0;
-	lease->length = ei;
-#else
-	/* strictly time_t is opaque, but this hack should work on all sane systems,
-	   even when sizeof(time_t) == 8 */
-	lease->expires = (time_t)ei;
-#endif
-	
-	lease_set_hwaddr(lease, (unsigned char *)daemon->dhcp_buff2, (unsigned char *)daemon->packet, hw_len, hw_type, clid_len);
-	
-	if (strcmp(daemon->dhcp_buff, "*") !=  0)
-	  lease_set_hostname(lease, daemon->dhcp_buff, 0);
+    } else {
+        /* NOTE: need a+ mode to create file if it doesn't exist */
+        leasestream = daemon->lease_stream = fopen(daemon->lease_file, "a+");
 
-	/* set these correctly: the "old" events are generated later from
-	   the startup synthesised SIGHUP. */
-	lease->new = lease->changed = 0;
-      }
-  
+        if (!leasestream)
+            die(_("cannot open or create lease file %s: %s"), daemon->lease_file, EC_FILE);
+
+        /* a+ mode leaves pointer at end. */
+        rewind(leasestream);
+    }
+
+    /* client-id max length is 255 which is 255*2 digits + 254 colons
+       borrow DNS packet buffer which is always larger than 1000 bytes */
+    if (leasestream)
+        while (fscanf(leasestream, "%lu %255s %16s %255s %764s", &ei, daemon->dhcp_buff2,
+                      daemon->namebuff, daemon->dhcp_buff, daemon->packet) == 5) {
+            hw_len = parse_hex(daemon->dhcp_buff2, (unsigned char*) daemon->dhcp_buff2,
+                               DHCP_CHADDR_MAX, NULL, &hw_type);
+            /* For backwards compatibility, no explict MAC address type means ether. */
+            if (hw_type == 0 && hw_len != 0) hw_type = ARPHRD_ETHER;
+
+            addr.s_addr = inet_addr(daemon->namebuff);
+
+            /* decode hex in place */
+            clid_len = 0;
+            if (strcmp(daemon->packet, "*") != 0)
+                clid_len =
+                    parse_hex(daemon->packet, (unsigned char*) daemon->packet, 255, NULL, NULL);
+
+            if (!(lease = lease_allocate(addr))) die(_("too many stored leases"), NULL, EC_MISC);
+
+#ifdef HAVE_BROKEN_RTC
+            if (ei != 0)
+                lease->expires = (time_t) ei + now;
+            else
+                lease->expires = (time_t) 0;
+            lease->length = ei;
+#else
+            /* strictly time_t is opaque, but this hack should work on all sane systems,
+               even when sizeof(time_t) == 8 */
+            lease->expires = (time_t) ei;
+#endif
+
+            lease_set_hwaddr(lease, (unsigned char*) daemon->dhcp_buff2,
+                             (unsigned char*) daemon->packet, hw_len, hw_type, clid_len);
+
+            if (strcmp(daemon->dhcp_buff, "*") != 0)
+                lease_set_hostname(lease, daemon->dhcp_buff, 0);
+
+            /* set these correctly: the "old" events are generated later from
+               the startup synthesised SIGHUP. */
+            lease->new = lease->changed = 0;
+        }
+
 #ifdef HAVE_SCRIPT
-  if (!daemon->lease_stream)
-    {
-      int rc = 0;
+    if (!daemon->lease_stream) {
+        int rc = 0;
 
-      /* shell returns 127 for "command not found", 126 for bad permissions. */
-      if (!leasestream || (rc = pclose(leasestream)) == -1 || WEXITSTATUS(rc) == 127 || WEXITSTATUS(rc) == 126)
-	{
-	  if (WEXITSTATUS(rc) == 127)
-	    errno = ENOENT;
-	  else if (WEXITSTATUS(rc) == 126)
-	    errno = EACCES;
-	  die(_("cannot run lease-init script %s: %s"), daemon->lease_change_command, EC_FILE);
-	}
-      
-      if (WEXITSTATUS(rc) != 0)
-	{
-	  sprintf(daemon->dhcp_buff, "%d", WEXITSTATUS(rc));
-	  die(_("lease-init script returned exit code %s"), daemon->dhcp_buff, WEXITSTATUS(rc) + EC_INIT_OFFSET);
-	}
+        /* shell returns 127 for "command not found", 126 for bad permissions. */
+        if (!leasestream || (rc = pclose(leasestream)) == -1 || WEXITSTATUS(rc) == 127 ||
+            WEXITSTATUS(rc) == 126) {
+            if (WEXITSTATUS(rc) == 127)
+                errno = ENOENT;
+            else if (WEXITSTATUS(rc) == 126)
+                errno = EACCES;
+            die(_("cannot run lease-init script %s: %s"), daemon->lease_change_command, EC_FILE);
+        }
+
+        if (WEXITSTATUS(rc) != 0) {
+            sprintf(daemon->dhcp_buff, "%d", WEXITSTATUS(rc));
+            die(_("lease-init script returned exit code %s"), daemon->dhcp_buff,
+                WEXITSTATUS(rc) + EC_INIT_OFFSET);
+        }
     }
 #endif
 
-  /* Some leases may have expired */
-  file_dirty = 0;
-  lease_prune(NULL, now);
-  dns_dirty = 1;
+    /* Some leases may have expired */
+    file_dirty = 0;
+    lease_prune(NULL, now);
+    dns_dirty = 1;
 }
 
-void lease_update_from_configs(void)
-{
-  /* changes to the config may change current leases. */
-  
-  struct dhcp_lease *lease;
-  struct dhcp_config *config;
-  char *name;
+void lease_update_from_configs(void) {
+    /* changes to the config may change current leases. */
 
-  for (lease = leases; lease; lease = lease->next)
-    if ((config = find_config(daemon->dhcp_conf, NULL, lease->clid, lease->clid_len, 
-			      lease->hwaddr, lease->hwaddr_len, lease->hwaddr_type, NULL)) && 
-	(config->flags & CONFIG_NAME) &&
-	(!(config->flags & CONFIG_ADDR) || config->addr.s_addr == lease->addr.s_addr))
-      lease_set_hostname(lease, config->hostname, 1);
-    else if ((name = host_from_dns(lease->addr)))
-      lease_set_hostname(lease, name, 1); /* updates auth flag only */
-}
+    struct dhcp_lease* lease;
+    struct dhcp_config* config;
+    char* name;
 
-static void ourprintf(int *errp, char *format, ...)
-{
-  va_list ap;
-  
-  va_start(ap, format);
-  if (!(*errp) && vfprintf(daemon->lease_stream, format, ap) < 0)
-    *errp = errno;
-  va_end(ap);
-}
-
-void lease_update_file(time_t now)
-{
-  struct dhcp_lease *lease;
-  time_t next_event;
-  int i, err = 0;
-
-  if (file_dirty != 0 && daemon->lease_stream)
-    {
-      errno = 0;
-      rewind(daemon->lease_stream);
-      if (errno != 0 || ftruncate(fileno(daemon->lease_stream), 0) != 0)
-	err = errno;
-      
-      for (lease = leases; lease; lease = lease->next)
-	{
-#ifdef HAVE_BROKEN_RTC
-	  ourprintf(&err, "%u ", lease->length);
-#else
-	  ourprintf(&err, "%lu ", (unsigned long)lease->expires);
-#endif
-	  if (lease->hwaddr_type != ARPHRD_ETHER || lease->hwaddr_len == 0) 
-	    ourprintf(&err, "%.2x-", lease->hwaddr_type);
-	  for (i = 0; i < lease->hwaddr_len; i++)
-	    {
-	      ourprintf(&err, "%.2x", lease->hwaddr[i]);
-	      if (i != lease->hwaddr_len - 1)
-		ourprintf(&err, ":");
-	    }
-
-	  ourprintf(&err, " %s ", inet_ntoa(lease->addr));
-	  ourprintf(&err, "%s ", lease->hostname ? lease->hostname : "*");
-	  	  
-	  if (lease->clid && lease->clid_len != 0)
-	    {
-	      for (i = 0; i < lease->clid_len - 1; i++)
-		ourprintf(&err, "%.2x:", lease->clid[i]);
-	      ourprintf(&err, "%.2x\n", lease->clid[i]);
-	    }
-	  else
-	    ourprintf(&err, "*\n");	  
-	}
-      
-      if (fflush(daemon->lease_stream) != 0 ||
-	  fsync(fileno(daemon->lease_stream)) < 0)
-	err = errno;
-      
-      if (!err)
-	file_dirty = 0;
-    }
-  
-  /* Set alarm for when the first lease expires + slop. */
-  for (next_event = 0, lease = leases; lease; lease = lease->next)
-    if (lease->expires != 0 &&
-	(next_event == 0 || difftime(next_event, lease->expires + 10) > 0.0))
-      next_event = lease->expires + 10;
-   
-  if (err)
-    {
-      if (next_event == 0 || difftime(next_event, LEASE_RETRY + now) > 0.0)
-	next_event = LEASE_RETRY + now;
-      
-      my_syslog(MS_DHCP | LOG_ERR, _("failed to write %s: %s (retry in %us)"), 
-		daemon->lease_file, strerror(err),
-		(unsigned int)difftime(next_event, now));
-    }
-
-  if (next_event != 0)
-    alarm((unsigned)difftime(next_event, now)); 
-}
-
-void lease_update_dns(void)
-{
-  struct dhcp_lease *lease;
-  
-  if (daemon->port != 0 && dns_dirty)
-    {
-      cache_unhash_dhcp();
-      
-      for (lease = leases; lease; lease = lease->next)
-	{
-	  if (lease->fqdn)
-	    cache_add_dhcp_entry(lease->fqdn, &lease->addr, lease->expires);
-	     
-	  if (!(daemon->options & OPT_DHCP_FQDN) && lease->hostname)
-	    cache_add_dhcp_entry(lease->hostname, &lease->addr, lease->expires);
-	}
-      
-      dns_dirty = 0;
-    }
-}
-
-void lease_prune(struct dhcp_lease *target, time_t now)
-{
-  struct dhcp_lease *lease, *tmp, **up;
-
-  for (lease = leases, up = &leases; lease; lease = tmp)
-    {
-      tmp = lease->next;
-      if ((lease->expires != 0 && difftime(now, lease->expires) > 0) || lease == target)
-	{
-	  file_dirty = 1;
-	  if (lease->hostname)
-	    dns_dirty = 1;
-	  
-	  *up = lease->next; /* unlink */
-	  
-	  /* Put on old_leases list 'till we
-	     can run the script */
-	  lease->next = old_leases;
-	  old_leases = lease;
-	  
-	  leases_left++;
-	}
-      else
-	up = &lease->next;
-    }
-} 
-	
-  
-struct dhcp_lease *lease_find_by_client(unsigned char *hwaddr, int hw_len, int hw_type,
-					unsigned char *clid, int clid_len)
-{
-  struct dhcp_lease *lease;
-
-  if (clid)
     for (lease = leases; lease; lease = lease->next)
-      if (lease->clid && clid_len == lease->clid_len &&
-	  memcmp(clid, lease->clid, clid_len) == 0)
-	return lease;
-  
-  for (lease = leases; lease; lease = lease->next)	
-    if ((!lease->clid || !clid) && 
-	hw_len != 0 && 
-	lease->hwaddr_len == hw_len &&
-	lease->hwaddr_type == hw_type &&
-	memcmp(hwaddr, lease->hwaddr, hw_len) == 0)
-      return lease;
-  
-  return NULL;
+        if ((config = find_config(daemon->dhcp_conf, NULL, lease->clid, lease->clid_len,
+                                  lease->hwaddr, lease->hwaddr_len, lease->hwaddr_type, NULL)) &&
+            (config->flags & CONFIG_NAME) &&
+            (!(config->flags & CONFIG_ADDR) || config->addr.s_addr == lease->addr.s_addr))
+            lease_set_hostname(lease, config->hostname, 1);
+        else if ((name = host_from_dns(lease->addr)))
+            lease_set_hostname(lease, name, 1); /* updates auth flag only */
 }
 
-struct dhcp_lease *lease_find_by_addr(struct in_addr addr)
-{
-  struct dhcp_lease *lease;
+static void ourprintf(int* errp, char* format, ...) {
+    va_list ap;
 
-  for (lease = leases; lease; lease = lease->next)
-    if (lease->addr.s_addr == addr.s_addr)
-      return lease;
-  
-  return NULL;
+    va_start(ap, format);
+    if (!(*errp) && vfprintf(daemon->lease_stream, format, ap) < 0) *errp = errno;
+    va_end(ap);
 }
 
+void lease_update_file(time_t now) {
+    struct dhcp_lease* lease;
+    time_t next_event;
+    int i, err = 0;
 
-struct dhcp_lease *lease_allocate(struct in_addr addr)
-{
-  struct dhcp_lease *lease;
-  if (!leases_left || !(lease = whine_malloc(sizeof(struct dhcp_lease))))
+    if (file_dirty != 0 && daemon->lease_stream) {
+        errno = 0;
+        rewind(daemon->lease_stream);
+        if (errno != 0 || ftruncate(fileno(daemon->lease_stream), 0) != 0) err = errno;
+
+        for (lease = leases; lease; lease = lease->next) {
+#ifdef HAVE_BROKEN_RTC
+            ourprintf(&err, "%u ", lease->length);
+#else
+            ourprintf(&err, "%lu ", (unsigned long) lease->expires);
+#endif
+            if (lease->hwaddr_type != ARPHRD_ETHER || lease->hwaddr_len == 0)
+                ourprintf(&err, "%.2x-", lease->hwaddr_type);
+            for (i = 0; i < lease->hwaddr_len; i++) {
+                ourprintf(&err, "%.2x", lease->hwaddr[i]);
+                if (i != lease->hwaddr_len - 1) ourprintf(&err, ":");
+            }
+
+            ourprintf(&err, " %s ", inet_ntoa(lease->addr));
+            ourprintf(&err, "%s ", lease->hostname ? lease->hostname : "*");
+
+            if (lease->clid && lease->clid_len != 0) {
+                for (i = 0; i < lease->clid_len - 1; i++) ourprintf(&err, "%.2x:", lease->clid[i]);
+                ourprintf(&err, "%.2x\n", lease->clid[i]);
+            } else
+                ourprintf(&err, "*\n");
+        }
+
+        if (fflush(daemon->lease_stream) != 0 || fsync(fileno(daemon->lease_stream)) < 0)
+            err = errno;
+
+        if (!err) file_dirty = 0;
+    }
+
+    /* Set alarm for when the first lease expires + slop. */
+    for (next_event = 0, lease = leases; lease; lease = lease->next)
+        if (lease->expires != 0 &&
+            (next_event == 0 || difftime(next_event, lease->expires + 10) > 0.0))
+            next_event = lease->expires + 10;
+
+    if (err) {
+        if (next_event == 0 || difftime(next_event, LEASE_RETRY + now) > 0.0)
+            next_event = LEASE_RETRY + now;
+
+        my_syslog(MS_DHCP | LOG_ERR, _("failed to write %s: %s (retry in %us)"), daemon->lease_file,
+                  strerror(err), (unsigned int) difftime(next_event, now));
+    }
+
+    if (next_event != 0) alarm((unsigned) difftime(next_event, now));
+}
+
+void lease_update_dns(void) {
+    struct dhcp_lease* lease;
+
+    if (daemon->port != 0 && dns_dirty) {
+        cache_unhash_dhcp();
+
+        for (lease = leases; lease; lease = lease->next) {
+            if (lease->fqdn) cache_add_dhcp_entry(lease->fqdn, &lease->addr, lease->expires);
+
+            if (!(daemon->options & OPT_DHCP_FQDN) && lease->hostname)
+                cache_add_dhcp_entry(lease->hostname, &lease->addr, lease->expires);
+        }
+
+        dns_dirty = 0;
+    }
+}
+
+void lease_prune(struct dhcp_lease* target, time_t now) {
+    struct dhcp_lease *lease, *tmp, **up;
+
+    for (lease = leases, up = &leases; lease; lease = tmp) {
+        tmp = lease->next;
+        if ((lease->expires != 0 && difftime(now, lease->expires) > 0) || lease == target) {
+            file_dirty = 1;
+            if (lease->hostname) dns_dirty = 1;
+
+            *up = lease->next; /* unlink */
+
+            /* Put on old_leases list 'till we
+               can run the script */
+            lease->next = old_leases;
+            old_leases = lease;
+
+            leases_left++;
+        } else
+            up = &lease->next;
+    }
+}
+
+struct dhcp_lease* lease_find_by_client(unsigned char* hwaddr, int hw_len, int hw_type,
+                                        unsigned char* clid, int clid_len) {
+    struct dhcp_lease* lease;
+
+    if (clid)
+        for (lease = leases; lease; lease = lease->next)
+            if (lease->clid && clid_len == lease->clid_len &&
+                memcmp(clid, lease->clid, clid_len) == 0)
+                return lease;
+
+    for (lease = leases; lease; lease = lease->next)
+        if ((!lease->clid || !clid) && hw_len != 0 && lease->hwaddr_len == hw_len &&
+            lease->hwaddr_type == hw_type && memcmp(hwaddr, lease->hwaddr, hw_len) == 0)
+            return lease;
+
     return NULL;
-
-  memset(lease, 0, sizeof(struct dhcp_lease));
-  lease->new = 1;
-  lease->addr = addr;
-  lease->hwaddr_len = 256; /* illegal value */
-  lease->expires = 1;
-#ifdef HAVE_BROKEN_RTC
-  lease->length = 0xffffffff; /* illegal value */
-#endif
-  lease->next = leases;
-  leases = lease;
-  
-  file_dirty = 1;
-  leases_left--;
-
-  return lease;
 }
 
-void lease_set_expires(struct dhcp_lease *lease, unsigned int len, time_t now)
-{
-  time_t exp = now + (time_t)len;
-  
-  if (len == 0xffffffff)
-    {
-      exp = 0;
-      len = 0;
+struct dhcp_lease* lease_find_by_addr(struct in_addr addr) {
+    struct dhcp_lease* lease;
+
+    for (lease = leases; lease; lease = lease->next)
+        if (lease->addr.s_addr == addr.s_addr) return lease;
+
+    return NULL;
+}
+
+struct dhcp_lease* lease_allocate(struct in_addr addr) {
+    struct dhcp_lease* lease;
+    if (!leases_left || !(lease = whine_malloc(sizeof(struct dhcp_lease)))) return NULL;
+
+    memset(lease, 0, sizeof(struct dhcp_lease));
+    lease->new = 1;
+    lease->addr = addr;
+    lease->hwaddr_len = 256; /* illegal value */
+    lease->expires = 1;
+#ifdef HAVE_BROKEN_RTC
+    lease->length = 0xffffffff; /* illegal value */
+#endif
+    lease->next = leases;
+    leases = lease;
+
+    file_dirty = 1;
+    leases_left--;
+
+    return lease;
+}
+
+void lease_set_expires(struct dhcp_lease* lease, unsigned int len, time_t now) {
+    time_t exp = now + (time_t) len;
+
+    if (len == 0xffffffff) {
+        exp = 0;
+        len = 0;
     }
-  
-  if (exp != lease->expires)
-    {
-      dns_dirty = 1;
-      lease->expires = exp;
+
+    if (exp != lease->expires) {
+        dns_dirty = 1;
+        lease->expires = exp;
 #ifndef HAVE_BROKEN_RTC
-      lease->aux_changed = file_dirty = 1;
+        lease->aux_changed = file_dirty = 1;
 #endif
     }
-  
+
 #ifdef HAVE_BROKEN_RTC
-  if (len != lease->length)
-    {
-      lease->length = len;
-      lease->aux_changed = file_dirty = 1; 
+    if (len != lease->length) {
+        lease->length = len;
+        lease->aux_changed = file_dirty = 1;
     }
 #endif
-} 
-
-void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
-		      unsigned char *clid, int hw_len, int hw_type, int clid_len)
-{
-  if (hw_len != lease->hwaddr_len ||
-      hw_type != lease->hwaddr_type || 
-      (hw_len != 0 && memcmp(lease->hwaddr, hwaddr, hw_len) != 0))
-    {
-      memcpy(lease->hwaddr, hwaddr, hw_len);
-      lease->hwaddr_len = hw_len;
-      lease->hwaddr_type = hw_type;
-      lease->changed = file_dirty = 1; /* run script on change */
-    }
-
-  /* only update clid when one is available, stops packets
-     without a clid removing the record. Lease init uses
-     clid_len == 0 for no clid. */
-  if (clid_len != 0 && clid)
-    {
-      if (!lease->clid)
-	lease->clid_len = 0;
-
-      if (lease->clid_len != clid_len)
-	{
-	  lease->aux_changed = file_dirty = 1;
-	  free(lease->clid);
-	  if (!(lease->clid = whine_malloc(clid_len)))
-	    return;
-	}
-      else if (memcmp(lease->clid, clid, clid_len) != 0)
-	lease->aux_changed = file_dirty = 1;
-	  
-      lease->clid_len = clid_len;
-      memcpy(lease->clid, clid, clid_len);
-    }
-
 }
 
-static void kill_name(struct dhcp_lease *lease)
-{
-  /* run script to say we lost our old name */
-  
-  /* this shouldn't happen unless updates are very quick and the
-     script very slow, we just avoid a memory leak if it does. */
-  free(lease->old_hostname);
-  
-  /* If we know the fqdn, pass that. The helper will derive the
-     unqualified name from it, free the unqulaified name here. */
-
-  if (lease->fqdn)
-    {
-      lease->old_hostname = lease->fqdn;
-      free(lease->hostname);
-    }
-  else
-    lease->old_hostname = lease->hostname;
-
-  lease->hostname = lease->fqdn = NULL;
-}
-
-void lease_set_hostname(struct dhcp_lease *lease, char *name, int auth)
-{
-  struct dhcp_lease *lease_tmp;
-  char *new_name = NULL, *new_fqdn = NULL;
-  
-  if (lease->hostname && name && hostname_isequal(lease->hostname, name))
-    {
-      lease->auth_name = auth;
-      return;
-    }
-  
-  if (!name && !lease->hostname)
-    return;
-
-  /* If a machine turns up on a new net without dropping the old lease,
-     or two machines claim the same name, then we end up with two interfaces with
-     the same name. Check for that here and remove the name from the old lease.
-     Don't allow a name from the client to override a name from dnsmasq config. */
-  
-  if (name)
-    {
-      if ((new_name = whine_malloc(strlen(name) + 1)))
-	{
-	  char *suffix = get_domain(lease->addr);
-	  strcpy(new_name, name);
-	  if (suffix && (new_fqdn = whine_malloc(strlen(new_name) + strlen(suffix) + 2)))
-	    {
-	      strcpy(new_fqdn, name);
-	      strcat(new_fqdn, ".");
-	      strcat(new_fqdn, suffix);
-	    }
-	}
-	  
-      /* Depending on mode, we check either unqualified name or FQDN. */
-      for (lease_tmp = leases; lease_tmp; lease_tmp = lease_tmp->next)
-	{
-	  if (daemon->options & OPT_DHCP_FQDN)
-	    {
-	      if (!new_fqdn || !lease_tmp->fqdn || !hostname_isequal(lease_tmp->fqdn, new_fqdn) )
-		continue;
-	    }
-	  else
-	    {
-	      if (!new_name || !lease_tmp->hostname || !hostname_isequal(lease_tmp->hostname, new_name) )
-		continue; 
-	    }
-	  
-	  if (lease_tmp->auth_name && !auth)
-	    {
-	      free(new_name);
-	      free(new_fqdn);
-	      return;
-	    }
-	
-	  kill_name(lease_tmp);
-	  break;
-	}
+void lease_set_hwaddr(struct dhcp_lease* lease, unsigned char* hwaddr, unsigned char* clid,
+                      int hw_len, int hw_type, int clid_len) {
+    if (hw_len != lease->hwaddr_len || hw_type != lease->hwaddr_type ||
+        (hw_len != 0 && memcmp(lease->hwaddr, hwaddr, hw_len) != 0)) {
+        memcpy(lease->hwaddr, hwaddr, hw_len);
+        lease->hwaddr_len = hw_len;
+        lease->hwaddr_type = hw_type;
+        lease->changed = file_dirty = 1; /* run script on change */
     }
 
-  if (lease->hostname)
-    kill_name(lease);
+    /* only update clid when one is available, stops packets
+       without a clid removing the record. Lease init uses
+       clid_len == 0 for no clid. */
+    if (clid_len != 0 && clid) {
+        if (!lease->clid) lease->clid_len = 0;
 
-  lease->hostname = new_name;
-  lease->fqdn = new_fqdn;
-  lease->auth_name = auth;
-  
-  file_dirty = 1;
-  dns_dirty = 1; 
-  lease->changed = 1; /* run script on change */
+        if (lease->clid_len != clid_len) {
+            lease->aux_changed = file_dirty = 1;
+            free(lease->clid);
+            if (!(lease->clid = whine_malloc(clid_len))) return;
+        } else if (memcmp(lease->clid, clid, clid_len) != 0)
+            lease->aux_changed = file_dirty = 1;
+
+        lease->clid_len = clid_len;
+        memcpy(lease->clid, clid, clid_len);
+    }
 }
 
-void lease_set_interface(struct dhcp_lease *lease, int interface)
-{
-  if (lease->last_interface == interface)
-    return;
+static void kill_name(struct dhcp_lease* lease) {
+    /* run script to say we lost our old name */
 
-  lease->last_interface = interface;
-  lease->changed = 1;
+    /* this shouldn't happen unless updates are very quick and the
+       script very slow, we just avoid a memory leak if it does. */
+    free(lease->old_hostname);
+
+    /* If we know the fqdn, pass that. The helper will derive the
+       unqualified name from it, free the unqulaified name here. */
+
+    if (lease->fqdn) {
+        lease->old_hostname = lease->fqdn;
+        free(lease->hostname);
+    } else
+        lease->old_hostname = lease->hostname;
+
+    lease->hostname = lease->fqdn = NULL;
 }
 
-void rerun_scripts(void)
-{
-  struct dhcp_lease *lease;
-  
-  for (lease = leases; lease; lease = lease->next)
+void lease_set_hostname(struct dhcp_lease* lease, char* name, int auth) {
+    struct dhcp_lease* lease_tmp;
+    char *new_name = NULL, *new_fqdn = NULL;
+
+    if (lease->hostname && name && hostname_isequal(lease->hostname, name)) {
+        lease->auth_name = auth;
+        return;
+    }
+
+    if (!name && !lease->hostname) return;
+
+    /* If a machine turns up on a new net without dropping the old lease,
+       or two machines claim the same name, then we end up with two interfaces with
+       the same name. Check for that here and remove the name from the old lease.
+       Don't allow a name from the client to override a name from dnsmasq config. */
+
+    if (name) {
+        if ((new_name = whine_malloc(strlen(name) + 1))) {
+            char* suffix = get_domain(lease->addr);
+            strcpy(new_name, name);
+            if (suffix && (new_fqdn = whine_malloc(strlen(new_name) + strlen(suffix) + 2))) {
+                strcpy(new_fqdn, name);
+                strcat(new_fqdn, ".");
+                strcat(new_fqdn, suffix);
+            }
+        }
+
+        /* Depending on mode, we check either unqualified name or FQDN. */
+        for (lease_tmp = leases; lease_tmp; lease_tmp = lease_tmp->next) {
+            if (daemon->options & OPT_DHCP_FQDN) {
+                if (!new_fqdn || !lease_tmp->fqdn || !hostname_isequal(lease_tmp->fqdn, new_fqdn))
+                    continue;
+            } else {
+                if (!new_name || !lease_tmp->hostname ||
+                    !hostname_isequal(lease_tmp->hostname, new_name))
+                    continue;
+            }
+
+            if (lease_tmp->auth_name && !auth) {
+                free(new_name);
+                free(new_fqdn);
+                return;
+            }
+
+            kill_name(lease_tmp);
+            break;
+        }
+    }
+
+    if (lease->hostname) kill_name(lease);
+
+    lease->hostname = new_name;
+    lease->fqdn = new_fqdn;
+    lease->auth_name = auth;
+
+    file_dirty = 1;
+    dns_dirty = 1;
+    lease->changed = 1; /* run script on change */
+}
+
+void lease_set_interface(struct dhcp_lease* lease, int interface) {
+    if (lease->last_interface == interface) return;
+
+    lease->last_interface = interface;
     lease->changed = 1;
 }
 
+void rerun_scripts(void) {
+    struct dhcp_lease* lease;
+
+    for (lease = leases; lease; lease = lease->next) lease->changed = 1;
+}
+
 /* deleted leases get transferred to the old_leases list.
    remove them here, after calling the lease change
    script. Also run the lease change script on new/modified leases.
 
    Return zero if nothing to do. */
-int do_script_run(time_t now)
-{
-  struct dhcp_lease *lease;
+int do_script_run(time_t now) {
+    struct dhcp_lease* lease;
 
-  if (old_leases)
-    {
-      lease = old_leases;
-                  
-      /* If the lease still has an old_hostname, do the "old" action on that first */
-      if (lease->old_hostname)
-	{
+    if (old_leases) {
+        lease = old_leases;
+
+        /* If the lease still has an old_hostname, do the "old" action on that first */
+        if (lease->old_hostname) {
 #ifdef HAVE_SCRIPT
-	  queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now);
+            queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now);
 #endif
-	  free(lease->old_hostname);
-	  lease->old_hostname = NULL;
-	  return 1;
-	}
-      else 
-	{
-	  kill_name(lease);
+            free(lease->old_hostname);
+            lease->old_hostname = NULL;
+            return 1;
+        } else {
+            kill_name(lease);
 #ifdef HAVE_SCRIPT
-	  queue_script(ACTION_DEL, lease, lease->old_hostname, now);
+            queue_script(ACTION_DEL, lease, lease->old_hostname, now);
 #endif
-	  old_leases = lease->next;
-	  
-	  free(lease->old_hostname); 
-	  free(lease->clid);
-	  free(lease->vendorclass);
-	  free(lease->userclass);
-	  free(lease->supplied_hostname);
-	  free(lease);
-	    
-	  return 1; 
-	}
+            old_leases = lease->next;
+
+            free(lease->old_hostname);
+            free(lease->clid);
+            free(lease->vendorclass);
+            free(lease->userclass);
+            free(lease->supplied_hostname);
+            free(lease);
+
+            return 1;
+        }
     }
-  
-  /* make sure we announce the loss of a hostname before its new location. */
-  for (lease = leases; lease; lease = lease->next)
-    if (lease->old_hostname)
-      {	
-#ifdef HAVE_SCRIPT
-	queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now);
-#endif
-	free(lease->old_hostname);
-	lease->old_hostname = NULL;
-	return 1;
-      }
-  
-  for (lease = leases; lease; lease = lease->next)
-    if (lease->new || lease->changed || 
-	(lease->aux_changed && (daemon->options & OPT_LEASE_RO)))
-      {
-#ifdef HAVE_SCRIPT
-	queue_script(lease->new ? ACTION_ADD : ACTION_OLD, lease, 
-		     lease->fqdn ? lease->fqdn : lease->hostname, now);
-#endif
-	lease->new = lease->changed = lease->aux_changed = 0;
-	
-	/* these are used for the "add" call, then junked, since they're not in the database */
-	free(lease->vendorclass);
-	lease->vendorclass = NULL;
-	
-	free(lease->userclass);
-	lease->userclass = NULL;
-	
-	free(lease->supplied_hostname);
-	lease->supplied_hostname = NULL;
-			
-	return 1;
-      }
 
-  return 0; /* nothing to do */
+    /* make sure we announce the loss of a hostname before its new location. */
+    for (lease = leases; lease; lease = lease->next)
+        if (lease->old_hostname) {
+#ifdef HAVE_SCRIPT
+            queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now);
+#endif
+            free(lease->old_hostname);
+            lease->old_hostname = NULL;
+            return 1;
+        }
+
+    for (lease = leases; lease; lease = lease->next)
+        if (lease->new || lease->changed ||
+            (lease->aux_changed && (daemon->options & OPT_LEASE_RO))) {
+#ifdef HAVE_SCRIPT
+            queue_script(lease->new ? ACTION_ADD : ACTION_OLD, lease,
+                         lease->fqdn ? lease->fqdn : lease->hostname, now);
+#endif
+            lease->new = lease->changed = lease->aux_changed = 0;
+
+            /* these are used for the "add" call, then junked, since they're not in the database */
+            free(lease->vendorclass);
+            lease->vendorclass = NULL;
+
+            free(lease->userclass);
+            lease->userclass = NULL;
+
+            free(lease->supplied_hostname);
+            lease->supplied_hostname = NULL;
+
+            return 1;
+        }
+
+    return 0; /* nothing to do */
 }
 
 #endif
-	  
-
-      
-
diff --git a/src/log.c b/src/log.c
index 5399251..d1fcfb9 100644
--- a/src/log.c
+++ b/src/log.c
@@ -4,12 +4,12 @@
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; version 2 dated June, 1991, or
    (at your option) version 3 dated 29 June, 2007.
- 
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-     
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
@@ -20,10 +20,10 @@
 #include <android/log.h>
 #endif
 
-/* Implement logging to /dev/log asynchronously. If syslogd is 
+/* Implement logging to /dev/log asynchronously. If syslogd is
    making DNS lookups through dnsmasq, and dnsmasq blocks awaiting
    syslogd, then the two daemons can deadlock. We get around this
-   by not blocking when talking to syslog, instead we queue up to 
+   by not blocking when talking to syslog, instead we queue up to
    MAX_LOGS messages. If more are queued, they will be dropped,
    and the drop event itself logged. */
 
@@ -34,7 +34,7 @@
 
 /* defaults in case we die() before we log_start() */
 static int log_fac = LOG_DAEMON;
-static int log_stderr = 0; 
+static int log_stderr = 0;
 static int log_fd = -1;
 static int log_to_file = 0;
 static int entries_alloced = 0;
@@ -44,206 +44,169 @@
 static int connection_type = SOCK_DGRAM;
 
 struct log_entry {
-  int offset, length;
-  pid_t pid; /* to avoid duplicates over a fork */
-  struct log_entry *next;
-  char payload[MAX_MESSAGE];
+    int offset, length;
+    pid_t pid; /* to avoid duplicates over a fork */
+    struct log_entry* next;
+    char payload[MAX_MESSAGE];
 };
 
-static struct log_entry *entries = NULL;
-static struct log_entry *free_entries = NULL;
+static struct log_entry* entries = NULL;
+static struct log_entry* free_entries = NULL;
 
+int log_start(struct passwd* ent_pw, int errfd) {
+    int ret = 0;
 
-int log_start(struct passwd *ent_pw, int errfd)
-{
-  int ret = 0;
+    log_stderr = !!(daemon->options & OPT_DEBUG);
 
-  log_stderr = !!(daemon->options & OPT_DEBUG);
-
-  if (daemon->log_fac != -1)
-    log_fac = daemon->log_fac;
+    if (daemon->log_fac != -1) log_fac = daemon->log_fac;
 #ifdef LOG_LOCAL0
-  else if (daemon->options & OPT_DEBUG)
-    log_fac = LOG_LOCAL0;
+    else if (daemon->options & OPT_DEBUG)
+        log_fac = LOG_LOCAL0;
 #endif
 
-  if (daemon->log_file)
-    { 
-      log_to_file = 1;
-      daemon->max_logs = 0;
-    }
-  
-  max_logs = daemon->max_logs;
-
-  if (!log_reopen(daemon->log_file))
-    {
-      send_event(errfd, EVENT_LOG_ERR, errno);
-      _exit(0);
+    if (daemon->log_file) {
+        log_to_file = 1;
+        daemon->max_logs = 0;
     }
 
-  /* if queuing is inhibited, make sure we allocate
-     the one required buffer now. */
-  if (max_logs == 0)
-    {  
-      free_entries = safe_malloc(sizeof(struct log_entry));
-      free_entries->next = NULL;
-      entries_alloced = 1;
+    max_logs = daemon->max_logs;
+
+    if (!log_reopen(daemon->log_file)) {
+        send_event(errfd, EVENT_LOG_ERR, errno);
+        _exit(0);
     }
 
-  /* If we're running as root and going to change uid later,
-     change the ownership here so that the file is always owned by
-     the dnsmasq user. Then logrotate can just copy the owner.
-     Failure of the chown call is OK, (for instance when started as non-root) */
-  if (log_to_file && ent_pw && ent_pw->pw_uid != 0 && 
-      fchown(log_fd, ent_pw->pw_uid, -1) != 0)
-    ret = errno;
+    /* if queuing is inhibited, make sure we allocate
+       the one required buffer now. */
+    if (max_logs == 0) {
+        free_entries = safe_malloc(sizeof(struct log_entry));
+        free_entries->next = NULL;
+        entries_alloced = 1;
+    }
 
-  return ret;
+    /* If we're running as root and going to change uid later,
+       change the ownership here so that the file is always owned by
+       the dnsmasq user. Then logrotate can just copy the owner.
+       Failure of the chown call is OK, (for instance when started as non-root) */
+    if (log_to_file && ent_pw && ent_pw->pw_uid != 0 && fchown(log_fd, ent_pw->pw_uid, -1) != 0)
+        ret = errno;
+
+    return ret;
 }
 
-int log_reopen(char *log_file)
-{
-  if (log_fd != -1)
-    close(log_fd);
+int log_reopen(char* log_file) {
+    if (log_fd != -1) close(log_fd);
 
-  /* NOTE: umask is set to 022 by the time this gets called */
-     
-  if (log_file)
-    {
-      log_fd = open(log_file, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP);
-      return log_fd != -1;
-    }
-  else
+    /* NOTE: umask is set to 022 by the time this gets called */
+
+    if (log_file) {
+        log_fd = open(log_file, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP);
+        return log_fd != -1;
+    } else
 #if defined(__ANDROID__)
-#   define _PATH_LOG ""  /* dummy */
-    log_fd = -1;
+#define _PATH_LOG "" /* dummy */
+        log_fd = -1;
 #else
     {
-       int flags;
-       log_fd = socket(AF_UNIX, connection_type, 0);
-      
-      if (log_fd == -1)
-	return 0;
-      
-      /* if max_logs is zero, leave the socket blocking */
-      if (max_logs != 0 && (flags = fcntl(log_fd, F_GETFL)) != -1)
-	fcntl(log_fd, F_SETFL, flags | O_NONBLOCK);
+        int flags;
+        log_fd = socket(AF_UNIX, connection_type, 0);
+
+        if (log_fd == -1) return 0;
+
+        /* if max_logs is zero, leave the socket blocking */
+        if (max_logs != 0 && (flags = fcntl(log_fd, F_GETFL)) != -1)
+            fcntl(log_fd, F_SETFL, flags | O_NONBLOCK);
     }
 #endif
 
-  return 1;
+    return 1;
 }
 
-static void free_entry(void)
-{
-  struct log_entry *tmp = entries;
-  entries = tmp->next;
-  tmp->next = free_entries;
-  free_entries = tmp;
-}      
+static void free_entry(void) {
+    struct log_entry* tmp = entries;
+    entries = tmp->next;
+    tmp->next = free_entries;
+    free_entries = tmp;
+}
 
-static void log_write(void)
-{
-  ssize_t rc;
-   
-  while (entries)
-    {
-      /* Avoid duplicates over a fork() */
-      if (entries->pid != getpid())
-	{
-	  free_entry();
-	  continue;
-	}
+static void log_write(void) {
+    ssize_t rc;
 
-      connection_good = 1;
+    while (entries) {
+        /* Avoid duplicates over a fork() */
+        if (entries->pid != getpid()) {
+            free_entry();
+            continue;
+        }
 
-      if ((rc = write(log_fd, entries->payload + entries->offset, entries->length)) != -1)
-	{
-	  entries->length -= rc;
-	  entries->offset += rc;
-	  if (entries->length == 0)
-	    {
-	      free_entry();
-	      if (entries_lost != 0)
-		{
-		  int e = entries_lost;
-		  entries_lost = 0; /* avoid wild recursion */
-		  my_syslog(LOG_WARNING, _("overflow: %d log entries lost"), e);
-		}	  
-	    }
-	  continue;
-	}
-      
-      if (errno == EINTR)
-	continue;
+        connection_good = 1;
 
-      if (errno == EAGAIN)
-	return; /* syslogd busy, go again when select() or poll() says so */
-      
-      if (errno == ENOBUFS)
-	{
-	  connection_good = 0;
-	  return;
-	}
+        if ((rc = write(log_fd, entries->payload + entries->offset, entries->length)) != -1) {
+            entries->length -= rc;
+            entries->offset += rc;
+            if (entries->length == 0) {
+                free_entry();
+                if (entries_lost != 0) {
+                    int e = entries_lost;
+                    entries_lost = 0; /* avoid wild recursion */
+                    my_syslog(LOG_WARNING, _("overflow: %d log entries lost"), e);
+                }
+            }
+            continue;
+        }
 
-      /* errors handling after this assumes sockets */ 
-      if (!log_to_file)
-	{
-	  /* Once a stream socket hits EPIPE, we have to close and re-open
-	     (we ignore SIGPIPE) */
-	  if (errno == EPIPE)
-	    {
-	      if (log_reopen(NULL))
-		continue;
-	    }
-	  else if (errno == ECONNREFUSED || 
-		   errno == ENOTCONN || 
-		   errno == EDESTADDRREQ || 
-		   errno == ECONNRESET)
-	    {
-	      /* socket went (syslogd down?), try and reconnect. If we fail,
-		 stop trying until the next call to my_syslog() 
-		 ECONNREFUSED -> connection went down
-		 ENOTCONN -> nobody listening
-		 (ECONNRESET, EDESTADDRREQ are *BSD equivalents) */
-	      
-	      struct sockaddr_un logaddr;
+        if (errno == EINTR) continue;
 
-	      logaddr.sun_family = AF_UNIX;
-	      strncpy(logaddr.sun_path, _PATH_LOG, sizeof(logaddr.sun_path));
-	      
-	      /* Got connection back? try again. */
-	      if (connect(log_fd, (struct sockaddr *)&logaddr, sizeof(logaddr)) != -1)
-		continue;
-	      
-	      /* errors from connect which mean we should keep trying */
-	      if (errno == ENOENT || 
-		  errno == EALREADY || 
-		  errno == ECONNREFUSED ||
-		  errno == EISCONN || 
-		  errno == EINTR ||
-		  errno == EAGAIN)
-		{
-		  /* try again on next syslog() call */
-		  connection_good = 0;
-		  return;
-		}
-	      
-	      /* try the other sort of socket... */
-	      if (errno == EPROTOTYPE)
-		{
-		  connection_type = connection_type == SOCK_DGRAM ? SOCK_STREAM : SOCK_DGRAM;
-		  if (log_reopen(NULL))
-		    continue;
-		}
-	    }
-	}
+        if (errno == EAGAIN) return; /* syslogd busy, go again when select() or poll() says so */
 
-      /* give up - fall back to syslog() - this handles out-of-space
-	 when logging to a file, for instance. */
-      log_fd = -1;
-      my_syslog(LOG_CRIT, _("log failed: %s"), strerror(errno));
-      return;
+        if (errno == ENOBUFS) {
+            connection_good = 0;
+            return;
+        }
+
+        /* errors handling after this assumes sockets */
+        if (!log_to_file) {
+            /* Once a stream socket hits EPIPE, we have to close and re-open
+               (we ignore SIGPIPE) */
+            if (errno == EPIPE) {
+                if (log_reopen(NULL)) continue;
+            } else if (errno == ECONNREFUSED || errno == ENOTCONN || errno == EDESTADDRREQ ||
+                       errno == ECONNRESET) {
+                /* socket went (syslogd down?), try and reconnect. If we fail,
+               stop trying until the next call to my_syslog()
+               ECONNREFUSED -> connection went down
+               ENOTCONN -> nobody listening
+               (ECONNRESET, EDESTADDRREQ are *BSD equivalents) */
+
+                struct sockaddr_un logaddr;
+
+                logaddr.sun_family = AF_UNIX;
+                strncpy(logaddr.sun_path, _PATH_LOG, sizeof(logaddr.sun_path));
+
+                /* Got connection back? try again. */
+                if (connect(log_fd, (struct sockaddr*) &logaddr, sizeof(logaddr)) != -1) continue;
+
+                /* errors from connect which mean we should keep trying */
+                if (errno == ENOENT || errno == EALREADY || errno == ECONNREFUSED ||
+                    errno == EISCONN || errno == EINTR || errno == EAGAIN) {
+                    /* try again on next syslog() call */
+                    connection_good = 0;
+                    return;
+                }
+
+                /* try the other sort of socket... */
+                if (errno == EPROTOTYPE) {
+                    connection_type = connection_type == SOCK_DGRAM ? SOCK_STREAM : SOCK_DGRAM;
+                    if (log_reopen(NULL)) continue;
+                }
+            }
+        }
+
+        /* give up - fall back to syslog() - this handles out-of-space
+       when logging to a file, for instance. */
+        log_fd = -1;
+        my_syslog(LOG_CRIT, _("log failed: %s"), strerror(errno));
+        return;
     }
 }
 
@@ -251,186 +214,169 @@
    OR'd to priority can be MS_TFTP, MS_DHCP, ... to be able to do log separation between
    DNS, DHCP and TFTP services.
 */
-void my_syslog(int priority, const char *format, ...)
-{
-  va_list ap;
-  struct log_entry *entry;
-  time_t time_now;
-  char *p;
-  size_t len;
-  pid_t pid = getpid();
-  char *func = "";
+void my_syslog(int priority, const char* format, ...) {
+    va_list ap;
+    struct log_entry* entry;
+    time_t time_now;
+    char* p;
+    size_t len;
+    pid_t pid = getpid();
+    char* func = "";
 #ifdef __ANDROID__
-  int alog_lvl;
+    int alog_lvl;
 #endif
 
-  if ((LOG_FACMASK & priority) == MS_TFTP)
-    func = "-tftp";
-  else if ((LOG_FACMASK & priority) == MS_DHCP)
-    func = "-dhcp";
-      
-  priority = LOG_PRI(priority);
-  
-  if (log_stderr) 
-    {
-      fprintf(stderr, "dnsmasq%s: ", func);
-      va_start(ap, format);
-      vfprintf(stderr, format, ap);
-      va_end(ap);
-      fputc('\n', stderr);
+    if ((LOG_FACMASK & priority) == MS_TFTP)
+        func = "-tftp";
+    else if ((LOG_FACMASK & priority) == MS_DHCP)
+        func = "-dhcp";
+
+    priority = LOG_PRI(priority);
+
+    if (log_stderr) {
+        fprintf(stderr, "dnsmasq%s: ", func);
+        va_start(ap, format);
+        vfprintf(stderr, format, ap);
+        va_end(ap);
+        fputc('\n', stderr);
     }
 
 #ifdef __ANDROID__
     if (priority <= LOG_ERR)
-      alog_lvl = ANDROID_LOG_ERROR;
+        alog_lvl = ANDROID_LOG_ERROR;
     else if (priority == LOG_WARNING)
-      alog_lvl = ANDROID_LOG_WARN;
+        alog_lvl = ANDROID_LOG_WARN;
     else if (priority <= LOG_INFO)
-      alog_lvl = ANDROID_LOG_INFO;
+        alog_lvl = ANDROID_LOG_INFO;
     else
-      alog_lvl = ANDROID_LOG_DEBUG;
+        alog_lvl = ANDROID_LOG_DEBUG;
     va_start(ap, format);
     __android_log_vprint(alog_lvl, "dnsmasq", format, ap);
     va_end(ap);
 #else
 
-  if (log_fd == -1)
-    {
-      /* fall-back to syslog if we die during startup or fail during running. */
-      static int isopen = 0;
-      if (!isopen)
-	{
-	  openlog("dnsmasq", LOG_PID, log_fac);
-	  isopen = 1;
-	}
-      va_start(ap, format);  
-      vsyslog(priority, format, ap);
-      va_end(ap);
-      return;
+    if (log_fd == -1) {
+        /* fall-back to syslog if we die during startup or fail during running. */
+        static int isopen = 0;
+        if (!isopen) {
+            openlog("dnsmasq", LOG_PID, log_fac);
+            isopen = 1;
+        }
+        va_start(ap, format);
+        vsyslog(priority, format, ap);
+        va_end(ap);
+        return;
     }
-  
-  if ((entry = free_entries))
-    free_entries = entry->next;
-  else if (entries_alloced < max_logs && (entry = malloc(sizeof(struct log_entry))))
-    entries_alloced++;
-  
-  if (!entry)
-    entries_lost++;
-  else
-    {
-      /* add to end of list, consumed from the start */
-      entry->next = NULL;
-      if (!entries)
-	entries = entry;
-      else
-	{
-	  struct log_entry *tmp;
-	  for (tmp = entries; tmp->next; tmp = tmp->next);
-	  tmp->next = entry;
-	}
-      
-      time(&time_now);
-      p = entry->payload;
-      if (!log_to_file)
-	p += sprintf(p, "<%d>", priority | log_fac);
 
-      p += sprintf(p, "%.15s dnsmasq%s[%d]: ", ctime(&time_now) + 4, func, (int)pid);
-        
-      len = p - entry->payload;
-      va_start(ap, format);  
-      len += vsnprintf(p, MAX_MESSAGE - len, format, ap) + 1; /* include zero-terminator */
-      va_end(ap);
-      entry->length = len > MAX_MESSAGE ? MAX_MESSAGE : len;
-      entry->offset = 0;
-      entry->pid = pid;
+    if ((entry = free_entries))
+        free_entries = entry->next;
+    else if (entries_alloced < max_logs && (entry = malloc(sizeof(struct log_entry))))
+        entries_alloced++;
 
-      /* replace terminator with \n */
-      if (log_to_file)
-	entry->payload[entry->length - 1] = '\n';
+    if (!entry)
+        entries_lost++;
+    else {
+        /* add to end of list, consumed from the start */
+        entry->next = NULL;
+        if (!entries)
+            entries = entry;
+        else {
+            struct log_entry* tmp;
+            for (tmp = entries; tmp->next; tmp = tmp->next)
+                ;
+            tmp->next = entry;
+        }
+
+        time(&time_now);
+        p = entry->payload;
+        if (!log_to_file) p += sprintf(p, "<%d>", priority | log_fac);
+
+        p += sprintf(p, "%.15s dnsmasq%s[%d]: ", ctime(&time_now) + 4, func, (int) pid);
+
+        len = p - entry->payload;
+        va_start(ap, format);
+        len += vsnprintf(p, MAX_MESSAGE - len, format, ap) + 1; /* include zero-terminator */
+        va_end(ap);
+        entry->length = len > MAX_MESSAGE ? MAX_MESSAGE : len;
+        entry->offset = 0;
+        entry->pid = pid;
+
+        /* replace terminator with \n */
+        if (log_to_file) entry->payload[entry->length - 1] = '\n';
     }
-  
-  /* almost always, logging won't block, so try and write this now,
-     to save collecting too many log messages during a select loop. */
-  log_write();
-  
-  /* Since we're doing things asynchronously, a cache-dump, for instance,
-     can now generate log lines very fast. With a small buffer (desirable),
-     that means it can overflow the log-buffer very quickly,
-     so that the cache dump becomes mainly a count of how many lines 
-     overflowed. To avoid this, we delay here, the delay is controlled 
-     by queue-occupancy, and grows exponentially. The delay is limited to (2^8)ms.
-     The scaling stuff ensures that when the queue is bigger than 8, the delay
-     only occurs for the last 8 entries. Once the queue is full, we stop delaying
-     to preserve performance.
-  */
 
-  if (entries && max_logs != 0)
-    {
-      int d;
-      
-      for (d = 0,entry = entries; entry; entry = entry->next, d++);
-      
-      if (d == max_logs)
-	d = 0;
-      else if (max_logs > 8)
-	d -= max_logs - 8;
+    /* almost always, logging won't block, so try and write this now,
+       to save collecting too many log messages during a select loop. */
+    log_write();
 
-      if (d > 0)
-	{
-	  struct timespec waiter;
-	  waiter.tv_sec = 0;
-	  waiter.tv_nsec = 1000000 << (d - 1); /* 1 ms */
-	  nanosleep(&waiter, NULL);
-      
-	  /* Have another go now */
-	  log_write();
-	}
+    /* Since we're doing things asynchronously, a cache-dump, for instance,
+       can now generate log lines very fast. With a small buffer (desirable),
+       that means it can overflow the log-buffer very quickly,
+       so that the cache dump becomes mainly a count of how many lines
+       overflowed. To avoid this, we delay here, the delay is controlled
+       by queue-occupancy, and grows exponentially. The delay is limited to (2^8)ms.
+       The scaling stuff ensures that when the queue is bigger than 8, the delay
+       only occurs for the last 8 entries. Once the queue is full, we stop delaying
+       to preserve performance.
+    */
+
+    if (entries && max_logs != 0) {
+        int d;
+
+        for (d = 0, entry = entries; entry; entry = entry->next, d++)
+            ;
+
+        if (d == max_logs)
+            d = 0;
+        else if (max_logs > 8)
+            d -= max_logs - 8;
+
+        if (d > 0) {
+            struct timespec waiter;
+            waiter.tv_sec = 0;
+            waiter.tv_nsec = 1000000 << (d - 1); /* 1 ms */
+            nanosleep(&waiter, NULL);
+
+            /* Have another go now */
+            log_write();
+        }
     }
 #endif
 }
 
-void set_log_writer(fd_set *set, int *maxfdp)
-{
-  if (entries && log_fd != -1 && connection_good)
-    {
-      FD_SET(log_fd, set);
-      bump_maxfd(log_fd, maxfdp);
+void set_log_writer(fd_set* set, int* maxfdp) {
+    if (entries && log_fd != -1 && connection_good) {
+        FD_SET(log_fd, set);
+        bump_maxfd(log_fd, maxfdp);
     }
 }
 
-void check_log_writer(fd_set *set)
-{
-  if (log_fd != -1 && (!set || FD_ISSET(log_fd, set)))
-    log_write();
+void check_log_writer(fd_set* set) {
+    if (log_fd != -1 && (!set || FD_ISSET(log_fd, set))) log_write();
 }
 
-void flush_log(void)
-{
-  /* block until queue empty */
-  if (log_fd != -1)
-    {
-      int flags;
-      if ((flags = fcntl(log_fd, F_GETFL)) != -1)
-	fcntl(log_fd, F_SETFL, flags & ~O_NONBLOCK);
-      log_write();
-      close(log_fd);
+void flush_log(void) {
+    /* block until queue empty */
+    if (log_fd != -1) {
+        int flags;
+        if ((flags = fcntl(log_fd, F_GETFL)) != -1) fcntl(log_fd, F_SETFL, flags & ~O_NONBLOCK);
+        log_write();
+        close(log_fd);
     }
 }
 
-void die(char *message, char *arg1, int exit_code)
-{
-  char *errmess = strerror(errno);
-  
-  if (!arg1)
-    arg1 = errmess;
+void die(char* message, char* arg1, int exit_code) {
+    char* errmess = strerror(errno);
 
-  log_stderr = 1; /* print as well as log when we die.... */
-  fputc('\n', stderr); /* prettyfy  startup-script message */
-  my_syslog(LOG_CRIT, message, arg1, errmess);
-  
-  log_stderr = 0;
-  my_syslog(LOG_CRIT, _("FAILED to start up"));
-  flush_log();
-  
-  exit(exit_code);
+    if (!arg1) arg1 = errmess;
+
+    log_stderr = 1;      /* print as well as log when we die.... */
+    fputc('\n', stderr); /* prettyfy  startup-script message */
+    my_syslog(LOG_CRIT, message, arg1, errmess);
+
+    log_stderr = 0;
+    my_syslog(LOG_CRIT, _("FAILED to start up"));
+    flush_log();
+
+    exit(exit_code);
 }
diff --git a/src/nameser.h b/src/nameser.h
index 4f47f72..13fbb07 100644
--- a/src/nameser.h
+++ b/src/nameser.h
@@ -5,7 +5,7 @@
  * -
  * Copyright (c) 1983, 1989, 1993
  *    The Regents of the University of California.  All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -17,7 +17,7 @@
  * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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
@@ -31,14 +31,14 @@
  * SUCH DAMAGE.
  * -
  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- * 
+ *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies, and that
  * the name of Digital Equipment Corporation not be used in advertising or
  * publicity pertaining to distribution of the document or software without
  * specific, written prior permission.
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
@@ -92,184 +92,182 @@
  * is new enough to contain a certain feature.
  */
 
-#define __BIND		19960801	/* interface version stamp */
+#define __BIND 19960801 /* interface version stamp */
 
 /*
  * Define constants based on rfc883
  */
-#define PACKETSZ	512		/* maximum packet size */
-#define MAXDNAME	1025		/* maximum presentation domain name */
-#define MAXCDNAME	255		/* maximum compressed domain name */
-#define MAXLABEL	63		/* maximum length of domain label */
-#define HFIXEDSZ	12		/* #/bytes of fixed data in header */
-#define QFIXEDSZ	4		/* #/bytes of fixed data in query */
-#define RRFIXEDSZ	10		/* #/bytes of fixed data in r record */
-#define INT32SZ		4		/* for systems without 32-bit ints */
-#define INT16SZ		2		/* for systems without 16-bit ints */
-#define INADDRSZ	4		/* IPv4 T_A */
-#define IN6ADDRSZ	16		/* IPv6 T_AAAA */
+#define PACKETSZ 512  /* maximum packet size */
+#define MAXDNAME 1025 /* maximum presentation domain name */
+#define MAXCDNAME 255 /* maximum compressed domain name */
+#define MAXLABEL 63   /* maximum length of domain label */
+#define HFIXEDSZ 12   /* #/bytes of fixed data in header */
+#define QFIXEDSZ 4    /* #/bytes of fixed data in query */
+#define RRFIXEDSZ 10  /* #/bytes of fixed data in r record */
+#define INT32SZ 4     /* for systems without 32-bit ints */
+#define INT16SZ 2     /* for systems without 16-bit ints */
+#define INADDRSZ 4    /* IPv4 T_A */
+#define IN6ADDRSZ 16  /* IPv6 T_AAAA */
 
 /*
  * Internet nameserver port number
  */
-#define NAMESERVER_PORT	53
+#define NAMESERVER_PORT 53
 
 /*
  * Currently defined opcodes
  */
-#define QUERY		0x0		/* standard query */
-#define IQUERY		0x1		/* inverse query */
-#define STATUS		0x2		/* nameserver status query */
-/*#define xxx		0x3*/		/* 0x3 reserved */
-#define NS_NOTIFY_OP	0x4		/* notify secondary of SOA change */
+#define QUERY 0x0         /* standard query */
+#define IQUERY 0x1        /* inverse query */
+#define STATUS 0x2        /* nameserver status query */
+/*#define xxx		0x3*/ /* 0x3 reserved */
+#define NS_NOTIFY_OP 0x4  /* notify secondary of SOA change */
 /*
  * Currently defined response codes
  */
-#define NOERROR		0		/* no error */
-#define FORMERR		1		/* format error */
-#define SERVFAIL	2		/* server failure */
-#define NXDOMAIN	3		/* non existent domain */
-#define NOTIMP		4		/* not implemented */
-#define REFUSED		5		/* query refused */
+#define NOERROR 0  /* no error */
+#define FORMERR 1  /* format error */
+#define SERVFAIL 2 /* server failure */
+#define NXDOMAIN 3 /* non existent domain */
+#define NOTIMP 4   /* not implemented */
+#define REFUSED 5  /* query refused */
 
 /*
  * Type values for resources and queries
  */
-#define T_A		1		/* host address */
-#define T_NS		2		/* authoritative server */
-#define T_MD		3		/* mail destination */
-#define T_MF		4		/* mail forwarder */
-#define T_CNAME		5		/* canonical name */
-#define T_SOA		6		/* start of authority zone */
-#define T_MB		7		/* mailbox domain name */
-#define T_MG		8		/* mail group member */
-#define T_MR		9		/* mail rename name */
-#define T_NULL		10		/* null resource record */
-#define T_WKS		11		/* well known service */
-#define T_PTR		12		/* domain name pointer */
-#define T_HINFO		13		/* host information */
-#define T_MINFO		14		/* mailbox information */
-#define T_MX		15		/* mail routing information */
-#define T_TXT		16		/* text strings */
-#define T_RP		17		/* responsible person */
-#define T_AFSDB		18		/* AFS cell database */
-#define T_X25		19		/* X_25 calling address */
-#define T_ISDN		20		/* ISDN calling address */
-#define T_RT		21		/* router */
-#define T_NSAP		22		/* NSAP address */
-#define T_NSAP_PTR	23		/* reverse NSAP lookup (deprecated) */
-#define T_SIG		24		/* security signature */
-#define T_KEY		25		/* security key */
-#define T_PX		26		/* X.400 mail mapping */
-#define T_GPOS		27		/* geographical position (withdrawn) */
-#define T_AAAA		28		/* IP6 Address */
-#define T_LOC		29		/* Location Information */
-#define T_NXT		30		/* Next Valid Name in Zone */
-#define T_EID		31		/* Endpoint identifier */
-#define T_NIMLOC	32		/* Nimrod locator */
-#define T_SRV		33		/* Server selection */
-#define T_ATMA		34		/* ATM Address */
-#define T_NAPTR		35		/* Naming Authority PoinTeR */
-#define T_KX		36		/* Key Exchanger */
-#define T_CERT		37		/* CERT */
-#define T_A6		38		/* A6 */
-#define T_DNAME		39		/* DNAME */
-#define T_SINK		40		/* SINK */
-#define T_OPT		41		/* OPT pseudo-RR, RFC2671 */
-#define T_APL		42		/* APL */
-#define T_DS		43		/* Delegation Signer */
-#define T_SSHFP		44		/* SSH Key Fingerprint */
-#define T_RRSIG		46		/* RRSIG */
-#define T_NSEC		47		/* NSEC */
-#define T_DNSKEY	48		/* DNSKEY */
-	/* non standard */
-#define T_UINFO		100		/* user (finger) information */
-#define T_UID		101		/* user ID */
-#define T_GID		102		/* group ID */
-#define T_UNSPEC	103		/* Unspecified format (binary data) */
-	/* Query type values which do not appear in resource records */
-#define	T_TKEY		249		/* Transaction Key */
-#define	T_TSIG		250		/* Transaction Signature */
-#define	T_IXFR		251		/* incremental zone transfer */
-#define T_AXFR		252		/* transfer zone of authority */
-#define T_MAILB		253		/* transfer mailbox records */
-#define T_MAILA		254		/* transfer mail agent records */
-#define T_ANY		255		/* wildcard match */
+#define T_A 1         /* host address */
+#define T_NS 2        /* authoritative server */
+#define T_MD 3        /* mail destination */
+#define T_MF 4        /* mail forwarder */
+#define T_CNAME 5     /* canonical name */
+#define T_SOA 6       /* start of authority zone */
+#define T_MB 7        /* mailbox domain name */
+#define T_MG 8        /* mail group member */
+#define T_MR 9        /* mail rename name */
+#define T_NULL 10     /* null resource record */
+#define T_WKS 11      /* well known service */
+#define T_PTR 12      /* domain name pointer */
+#define T_HINFO 13    /* host information */
+#define T_MINFO 14    /* mailbox information */
+#define T_MX 15       /* mail routing information */
+#define T_TXT 16      /* text strings */
+#define T_RP 17       /* responsible person */
+#define T_AFSDB 18    /* AFS cell database */
+#define T_X25 19      /* X_25 calling address */
+#define T_ISDN 20     /* ISDN calling address */
+#define T_RT 21       /* router */
+#define T_NSAP 22     /* NSAP address */
+#define T_NSAP_PTR 23 /* reverse NSAP lookup (deprecated) */
+#define T_SIG 24      /* security signature */
+#define T_KEY 25      /* security key */
+#define T_PX 26       /* X.400 mail mapping */
+#define T_GPOS 27     /* geographical position (withdrawn) */
+#define T_AAAA 28     /* IP6 Address */
+#define T_LOC 29      /* Location Information */
+#define T_NXT 30      /* Next Valid Name in Zone */
+#define T_EID 31      /* Endpoint identifier */
+#define T_NIMLOC 32   /* Nimrod locator */
+#define T_SRV 33      /* Server selection */
+#define T_ATMA 34     /* ATM Address */
+#define T_NAPTR 35    /* Naming Authority PoinTeR */
+#define T_KX 36       /* Key Exchanger */
+#define T_CERT 37     /* CERT */
+#define T_A6 38       /* A6 */
+#define T_DNAME 39    /* DNAME */
+#define T_SINK 40     /* SINK */
+#define T_OPT 41      /* OPT pseudo-RR, RFC2671 */
+#define T_APL 42      /* APL */
+#define T_DS 43       /* Delegation Signer */
+#define T_SSHFP 44    /* SSH Key Fingerprint */
+#define T_RRSIG 46    /* RRSIG */
+#define T_NSEC 47     /* NSEC */
+#define T_DNSKEY 48   /* DNSKEY */
+                      /* non standard */
+#define T_UINFO 100   /* user (finger) information */
+#define T_UID 101     /* user ID */
+#define T_GID 102     /* group ID */
+#define T_UNSPEC 103  /* Unspecified format (binary data) */
+                      /* Query type values which do not appear in resource records */
+#define T_TKEY 249    /* Transaction Key */
+#define T_TSIG 250    /* Transaction Signature */
+#define T_IXFR 251    /* incremental zone transfer */
+#define T_AXFR 252    /* transfer zone of authority */
+#define T_MAILB 253   /* transfer mailbox records */
+#define T_MAILA 254   /* transfer mail agent records */
+#define T_ANY 255     /* wildcard match */
 
 /*
  * Values for class field
  */
 
-#define C_IN		1		/* the arpa internet */
-#define C_CHAOS		3		/* for chaos net (MIT) */
-#define C_HS		4		/* for Hesiod name server (MIT) (XXX) */
-	/* Query class values which do not appear in resource records */
-#define C_ANY		255		/* wildcard match */
+#define C_IN 1    /* the arpa internet */
+#define C_CHAOS 3 /* for chaos net (MIT) */
+#define C_HS 4    /* for Hesiod name server (MIT) (XXX) */
+                  /* Query class values which do not appear in resource records */
+#define C_ANY 255 /* wildcard match */
 
 /*
  * Flags field of the KEY RR rdata
  */
-#define	KEYFLAG_TYPEMASK	0xC000	/* Mask for "type" bits */
-#define	KEYFLAG_TYPE_AUTH_CONF	0x0000	/* Key usable for both */
-#define	KEYFLAG_TYPE_CONF_ONLY	0x8000	/* Key usable for confidentiality */
-#define	KEYFLAG_TYPE_AUTH_ONLY	0x4000	/* Key usable for authentication */
-#define	KEYFLAG_TYPE_NO_KEY	0xC000	/* No key usable for either; no key */
+#define KEYFLAG_TYPEMASK 0xC000       /* Mask for "type" bits */
+#define KEYFLAG_TYPE_AUTH_CONF 0x0000 /* Key usable for both */
+#define KEYFLAG_TYPE_CONF_ONLY 0x8000 /* Key usable for confidentiality */
+#define KEYFLAG_TYPE_AUTH_ONLY 0x4000 /* Key usable for authentication */
+#define KEYFLAG_TYPE_NO_KEY 0xC000    /* No key usable for either; no key */
 /* The type bits can also be interpreted independently, as single bits: */
-#define	KEYFLAG_NO_AUTH		0x8000	/* Key not usable for authentication */
-#define	KEYFLAG_NO_CONF		0x4000	/* Key not usable for confidentiality */
+#define KEYFLAG_NO_AUTH 0x8000 /* Key not usable for authentication */
+#define KEYFLAG_NO_CONF 0x4000 /* Key not usable for confidentiality */
 
-#define	KEYFLAG_EXPERIMENTAL	0x2000	/* Security is *mandatory* if bit=0 */
-#define	KEYFLAG_RESERVED3	0x1000  /* reserved - must be zero */
-#define	KEYFLAG_RESERVED4	0x0800  /* reserved - must be zero */
-#define	KEYFLAG_USERACCOUNT	0x0400	/* key is assoc. with a user acct */
-#define	KEYFLAG_ENTITY		0x0200	/* key is assoc. with entity eg host */
-#define	KEYFLAG_ZONEKEY		0x0100	/* key is zone key for the zone named */
-#define	KEYFLAG_IPSEC		0x0080  /* key is for IPSEC use (host or user)*/
-#define	KEYFLAG_EMAIL		0x0040  /* key is for email (MIME security) */
-#define	KEYFLAG_RESERVED10	0x0020  /* reserved - must be zero */
-#define	KEYFLAG_RESERVED11	0x0010  /* reserved - must be zero */
-#define	KEYFLAG_SIGNATORYMASK	0x000F	/* key can sign DNS RR's of same name */
+#define KEYFLAG_EXPERIMENTAL 0x2000  /* Security is *mandatory* if bit=0 */
+#define KEYFLAG_RESERVED3 0x1000     /* reserved - must be zero */
+#define KEYFLAG_RESERVED4 0x0800     /* reserved - must be zero */
+#define KEYFLAG_USERACCOUNT 0x0400   /* key is assoc. with a user acct */
+#define KEYFLAG_ENTITY 0x0200        /* key is assoc. with entity eg host */
+#define KEYFLAG_ZONEKEY 0x0100       /* key is zone key for the zone named */
+#define KEYFLAG_IPSEC 0x0080         /* key is for IPSEC use (host or user)*/
+#define KEYFLAG_EMAIL 0x0040         /* key is for email (MIME security) */
+#define KEYFLAG_RESERVED10 0x0020    /* reserved - must be zero */
+#define KEYFLAG_RESERVED11 0x0010    /* reserved - must be zero */
+#define KEYFLAG_SIGNATORYMASK 0x000F /* key can sign DNS RR's of same name */
 
-#define  KEYFLAG_RESERVED_BITMASK ( KEYFLAG_RESERVED3 | \
-				    KEYFLAG_RESERVED4 | \
-				    KEYFLAG_RESERVED10| KEYFLAG_RESERVED11) 
+#define KEYFLAG_RESERVED_BITMASK \
+    (KEYFLAG_RESERVED3 | KEYFLAG_RESERVED4 | KEYFLAG_RESERVED10 | KEYFLAG_RESERVED11)
 
 /* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */
-#define	ALGORITHM_MD5RSA	1	/* MD5 with RSA */
-#define	ALGORITHM_EXPIRE_ONLY	253	/* No alg, no security */
-#define	ALGORITHM_PRIVATE_OID	254	/* Key begins with OID indicating alg */
+#define ALGORITHM_MD5RSA 1        /* MD5 with RSA */
+#define ALGORITHM_EXPIRE_ONLY 253 /* No alg, no security */
+#define ALGORITHM_PRIVATE_OID 254 /* Key begins with OID indicating alg */
 
 /* Signatures */
-					/* Size of a mod or exp in bits */
-#define	MIN_MD5RSA_KEY_PART_BITS	 512
-#define	MAX_MD5RSA_KEY_PART_BITS	2552
-					/* Total of binary mod and exp, bytes */
-#define	MAX_MD5RSA_KEY_BYTES		((MAX_MD5RSA_KEY_PART_BITS+7/8)*2+3)
-					/* Max length of text sig block */
-#define	MAX_KEY_BASE64			(((MAX_MD5RSA_KEY_BYTES+2)/3)*4)
+/* Size of a mod or exp in bits */
+#define MIN_MD5RSA_KEY_PART_BITS 512
+#define MAX_MD5RSA_KEY_PART_BITS 2552
+/* Total of binary mod and exp, bytes */
+#define MAX_MD5RSA_KEY_BYTES ((MAX_MD5RSA_KEY_PART_BITS + 7 / 8) * 2 + 3)
+/* Max length of text sig block */
+#define MAX_KEY_BASE64 (((MAX_MD5RSA_KEY_BYTES + 2) / 3) * 4)
 
 /*
  * EDNS0 Z-field extended flags
  */
-#define DNS_MESSAGEEXTFLAG_DO	0x8000U
+#define DNS_MESSAGEEXTFLAG_DO 0x8000U
 
 /*
  * Status return codes for T_UNSPEC conversion routines
  */
-#define CONV_SUCCESS	0
-#define CONV_OVERFLOW	(-1)
-#define CONV_BADFMT	(-2)
-#define CONV_BADCKSUM	(-3)
-#define CONV_BADBUFLEN	(-4)
+#define CONV_SUCCESS 0
+#define CONV_OVERFLOW (-1)
+#define CONV_BADFMT (-2)
+#define CONV_BADCKSUM (-3)
+#define CONV_BADBUFLEN (-4)
 
 #if !defined(_BYTE_ORDER) || \
-    (_BYTE_ORDER != _BIG_ENDIAN && _BYTE_ORDER != _LITTLE_ENDIAN && \
-    _BYTE_ORDER != _PDP_ENDIAN)
-	/* you must determine what the correct bit order is for
-	 * your compiler - the next line is an intentional error
-	 * which will force your compiles to bomb until you fix
-	 * the above macros.
-	 */
+    (_BYTE_ORDER != _BIG_ENDIAN && _BYTE_ORDER != _LITTLE_ENDIAN && _BYTE_ORDER != _PDP_ENDIAN)
+/* you must determine what the correct bit order is for
+ * your compiler - the next line is an intentional error
+ * which will force your compiles to bomb until you fix
+ * the above macros.
+ */
 #error "Undefined or invalid _BYTE_ORDER";
 #endif
 
@@ -281,49 +279,49 @@
  */
 
 typedef struct {
-	unsigned	id :16;		/* query identification number */
+    unsigned id : 16; /* query identification number */
 #if _BYTE_ORDER == _BIG_ENDIAN
-			/* fields in third byte */
-	unsigned	qr: 1;		/* response flag */
-	unsigned	opcode: 4;	/* purpose of message */
-	unsigned	aa: 1;		/* authoritive answer */
-	unsigned	tc: 1;		/* truncated message */
-	unsigned	rd: 1;		/* recursion desired */
-			/* fields in fourth byte */
-	unsigned	ra: 1;		/* recursion available */
-	unsigned	unused :1;	/* unused bits (MBZ as of 4.9.3a3) */
-	unsigned	ad: 1;		/* authentic data from named */
-	unsigned	cd: 1;		/* checking disabled by resolver */
-	unsigned	rcode :4;	/* response code */
+    /* fields in third byte */
+    unsigned qr : 1;     /* response flag */
+    unsigned opcode : 4; /* purpose of message */
+    unsigned aa : 1;     /* authoritive answer */
+    unsigned tc : 1;     /* truncated message */
+    unsigned rd : 1;     /* recursion desired */
+                         /* fields in fourth byte */
+    unsigned ra : 1;     /* recursion available */
+    unsigned unused : 1; /* unused bits (MBZ as of 4.9.3a3) */
+    unsigned ad : 1;     /* authentic data from named */
+    unsigned cd : 1;     /* checking disabled by resolver */
+    unsigned rcode : 4;  /* response code */
 #endif
 #if _BYTE_ORDER == _LITTLE_ENDIAN || _BYTE_ORDER == _PDP_ENDIAN
-			/* fields in third byte */
-	unsigned	rd :1;		/* recursion desired */
-	unsigned	tc :1;		/* truncated message */
-	unsigned	aa :1;		/* authoritive answer */
-	unsigned	opcode :4;	/* purpose of message */
-	unsigned	qr :1;		/* response flag */
-			/* fields in fourth byte */
-	unsigned	rcode :4;	/* response code */
-	unsigned	cd: 1;		/* checking disabled by resolver */
-	unsigned	ad: 1;		/* authentic data from named */
-	unsigned	unused :1;	/* unused bits (MBZ as of 4.9.3a3) */
-	unsigned	ra :1;		/* recursion available */
+    /* fields in third byte */
+    unsigned rd : 1;     /* recursion desired */
+    unsigned tc : 1;     /* truncated message */
+    unsigned aa : 1;     /* authoritive answer */
+    unsigned opcode : 4; /* purpose of message */
+    unsigned qr : 1;     /* response flag */
+                         /* fields in fourth byte */
+    unsigned rcode : 4;  /* response code */
+    unsigned cd : 1;     /* checking disabled by resolver */
+    unsigned ad : 1;     /* authentic data from named */
+    unsigned unused : 1; /* unused bits (MBZ as of 4.9.3a3) */
+    unsigned ra : 1;     /* recursion available */
 #endif
-			/* remaining bytes */
-	unsigned	qdcount :16;	/* number of question entries */
-	unsigned	ancount :16;	/* number of answer entries */
-	unsigned	nscount :16;	/* number of authority entries */
-	unsigned	arcount :16;	/* number of resource entries */
+    /* remaining bytes */
+    unsigned qdcount : 16; /* number of question entries */
+    unsigned ancount : 16; /* number of answer entries */
+    unsigned nscount : 16; /* number of authority entries */
+    unsigned arcount : 16; /* number of resource entries */
 } HEADER;
 
 /*
  * Defines for handling compressed domain names
  */
-#define INDIR_MASK	0xc0
+#define INDIR_MASK 0xc0
 
-extern	u_int16_t	_getshort(const unsigned char *);
-extern	u_int32_t	_getlong(const unsigned char *);
+extern u_int16_t _getshort(const unsigned char*);
+extern u_int32_t _getlong(const unsigned char*);
 
 /*
  * Inline versions of get/put short/long.  Pointer is advanced.
@@ -331,40 +329,39 @@
  * These macros demonstrate the property of C whereby it can be
  * portable or it can be elegant but rarely both.
  */
-#define GETSHORT(s, cp) { \
-	unsigned char *t_cp = (unsigned char *)(cp); \
-	(s) = ((u_int16_t)t_cp[0] << 8) \
-	    | ((u_int16_t)t_cp[1]) \
-	    ; \
-	(cp) += INT16SZ; \
-}
+#define GETSHORT(s, cp)                                           \
+    {                                                             \
+        unsigned char* t_cp = (unsigned char*) (cp);              \
+        (s) = ((u_int16_t) t_cp[0] << 8) | ((u_int16_t) t_cp[1]); \
+        (cp) += INT16SZ;                                          \
+    }
 
-#define GETLONG(l, cp) { \
-	unsigned char *t_cp = (unsigned char *)(cp); \
-	(l) = ((u_int32_t)t_cp[0] << 24) \
-	    | ((u_int32_t)t_cp[1] << 16) \
-	    | ((u_int32_t)t_cp[2] << 8) \
-	    | ((u_int32_t)t_cp[3]) \
-	    ; \
-	(cp) += INT32SZ; \
-}
+#define GETLONG(l, cp)                                                    \
+    {                                                                     \
+        unsigned char* t_cp = (unsigned char*) (cp);                      \
+        (l) = ((u_int32_t) t_cp[0] << 24) | ((u_int32_t) t_cp[1] << 16) | \
+              ((u_int32_t) t_cp[2] << 8) | ((u_int32_t) t_cp[3]);         \
+        (cp) += INT32SZ;                                                  \
+    }
 
-#define PUTSHORT(s, cp) { \
-	u_int16_t t_s = (u_int16_t)(s); \
-	unsigned char *t_cp = (unsigned char *)(cp); \
-	*t_cp++ = t_s >> 8; \
-	*t_cp   = t_s; \
-	(cp) += INT16SZ; \
-}
+#define PUTSHORT(s, cp)                              \
+    {                                                \
+        u_int16_t t_s = (u_int16_t)(s);              \
+        unsigned char* t_cp = (unsigned char*) (cp); \
+        *t_cp++ = t_s >> 8;                          \
+        *t_cp = t_s;                                 \
+        (cp) += INT16SZ;                             \
+    }
 
-#define PUTLONG(l, cp) { \
-	u_int32_t t_l = (u_int32_t)(l); \
-	unsigned char *t_cp = (unsigned char *)(cp); \
-	*t_cp++ = t_l >> 24; \
-	*t_cp++ = t_l >> 16; \
-	*t_cp++ = t_l >> 8; \
-	*t_cp   = t_l; \
-	(cp) += INT32SZ; \
-}
+#define PUTLONG(l, cp)                               \
+    {                                                \
+        u_int32_t t_l = (u_int32_t)(l);              \
+        unsigned char* t_cp = (unsigned char*) (cp); \
+        *t_cp++ = t_l >> 24;                         \
+        *t_cp++ = t_l >> 16;                         \
+        *t_cp++ = t_l >> 8;                          \
+        *t_cp = t_l;                                 \
+        (cp) += INT32SZ;                             \
+    }
 
 #endif /* !_NAMESER_H_ */
diff --git a/src/netlink.c b/src/netlink.c
index 77c4385..4141805 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -4,12 +4,12 @@
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; version 2 dated June, 1991, or
    (at your option) version 3 dated 29 June, 2007.
- 
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-     
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
@@ -18,286 +18,258 @@
 
 #ifdef HAVE_LINUX_NETWORK
 
-#include <linux/types.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
+#include <linux/types.h>
 
-/* linux 2.6.19 buggers up the headers, patch it up here. */ 
+/* linux 2.6.19 buggers up the headers, patch it up here. */
 #ifndef IFA_RTA
-#  define IFA_RTA(r)  \
-       ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))))
+#define IFA_RTA(r) ((struct rtattr*) (((char*) (r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))))
 
-#  include <linux/if_addr.h>
+#include <linux/if_addr.h>
 #endif
 
 static struct iovec iov;
 static u32 netlink_pid;
 
-static void nl_err(struct nlmsghdr *h);
-static void nl_routechange(struct nlmsghdr *h);
+static void nl_err(struct nlmsghdr* h);
+static void nl_routechange(struct nlmsghdr* h);
 
-void netlink_init(void)
-{
-  struct sockaddr_nl addr;
-  socklen_t slen = sizeof(addr);
+void netlink_init(void) {
+    struct sockaddr_nl addr;
+    socklen_t slen = sizeof(addr);
 
-  addr.nl_family = AF_NETLINK;
-  addr.nl_pad = 0;
-  addr.nl_pid = 0; /* autobind */
+    addr.nl_family = AF_NETLINK;
+    addr.nl_pad = 0;
+    addr.nl_pid = 0; /* autobind */
 #ifdef HAVE_IPV6
-  addr.nl_groups = RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE;
+    addr.nl_groups = RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE;
 #else
-  addr.nl_groups = RTMGRP_IPV4_ROUTE;
+    addr.nl_groups = RTMGRP_IPV4_ROUTE;
 #endif
-  
-  /* May not be able to have permission to set multicast groups don't die in that case */
-  if ((daemon->netlinkfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) != -1)
-    {
-      if (bind(daemon->netlinkfd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
-	{
-	  addr.nl_groups = 0;
-	  if (errno != EPERM || bind(daemon->netlinkfd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
-	    daemon->netlinkfd = -1;
-	}
+
+    /* May not be able to have permission to set multicast groups don't die in that case */
+    if ((daemon->netlinkfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) != -1) {
+        if (bind(daemon->netlinkfd, (struct sockaddr*) &addr, sizeof(addr)) == -1) {
+            addr.nl_groups = 0;
+            if (errno != EPERM ||
+                bind(daemon->netlinkfd, (struct sockaddr*) &addr, sizeof(addr)) == -1)
+                daemon->netlinkfd = -1;
+        }
     }
-  
-  if (daemon->netlinkfd == -1 || 
-      getsockname(daemon->netlinkfd, (struct sockaddr *)&addr, &slen) == 1)
-    die(_("cannot create netlink socket: %s"), NULL, EC_MISC);
-   
-  /* save pid assigned by bind() and retrieved by getsockname() */ 
-  netlink_pid = addr.nl_pid;
-  
-  iov.iov_len = 100;
-  iov.iov_base = safe_malloc(iov.iov_len);
+
+    if (daemon->netlinkfd == -1 ||
+        getsockname(daemon->netlinkfd, (struct sockaddr*) &addr, &slen) == 1)
+        die(_("cannot create netlink socket: %s"), NULL, EC_MISC);
+
+    /* save pid assigned by bind() and retrieved by getsockname() */
+    netlink_pid = addr.nl_pid;
+
+    iov.iov_len = 100;
+    iov.iov_base = safe_malloc(iov.iov_len);
 }
 
-static ssize_t netlink_recv(void)
-{
-  struct msghdr msg;
-  struct sockaddr_nl nladdr;
-  ssize_t rc;
+static ssize_t netlink_recv(void) {
+    struct msghdr msg;
+    struct sockaddr_nl nladdr;
+    ssize_t rc;
 
-  while (1)
-    {
-      msg.msg_control = NULL;
-      msg.msg_controllen = 0;
-      msg.msg_name = &nladdr;
-      msg.msg_namelen = sizeof(nladdr);
-      msg.msg_iov = &iov;
-      msg.msg_iovlen = 1;
-      msg.msg_flags = 0;
-      
-      while ((rc = recvmsg(daemon->netlinkfd, &msg, MSG_PEEK | MSG_TRUNC)) == -1 && errno == EINTR);
-      
-      /* make buffer big enough */
-      if (rc != -1 && (msg.msg_flags & MSG_TRUNC))
-	{
-	  /* Very new Linux kernels return the actual size needed, older ones always return truncated size */
-	  if ((size_t)rc == iov.iov_len)
-	    {
-	      if (expand_buf(&iov, rc + 100))
-		continue;
-	    }
-	  else
-	    expand_buf(&iov, rc);
-	}
+    while (1) {
+        msg.msg_control = NULL;
+        msg.msg_controllen = 0;
+        msg.msg_name = &nladdr;
+        msg.msg_namelen = sizeof(nladdr);
+        msg.msg_iov = &iov;
+        msg.msg_iovlen = 1;
+        msg.msg_flags = 0;
 
-      /* read it for real */
-      msg.msg_flags = 0;
-      while ((rc = recvmsg(daemon->netlinkfd, &msg, 0)) == -1 && errno == EINTR);
-      
-      /* Make sure this is from the kernel */
-      if (rc == -1 || nladdr.nl_pid == 0)
-	break;
+        while ((rc = recvmsg(daemon->netlinkfd, &msg, MSG_PEEK | MSG_TRUNC)) == -1 && errno == EINTR)
+            ;
+
+        /* make buffer big enough */
+        if (rc != -1 && (msg.msg_flags & MSG_TRUNC)) {
+            /* Very new Linux kernels return the actual size needed, older ones always return
+             * truncated size */
+            if ((size_t) rc == iov.iov_len) {
+                if (expand_buf(&iov, rc + 100)) continue;
+            } else
+                expand_buf(&iov, rc);
+        }
+
+        /* read it for real */
+        msg.msg_flags = 0;
+        while ((rc = recvmsg(daemon->netlinkfd, &msg, 0)) == -1 && errno == EINTR)
+            ;
+
+        /* Make sure this is from the kernel */
+        if (rc == -1 || nladdr.nl_pid == 0) break;
     }
-      
-  /* discard stuff which is truncated at this point (expand_buf() may fail) */
-  if (msg.msg_flags & MSG_TRUNC)
-    {
-      rc = -1;
-      errno = ENOMEM;
+
+    /* discard stuff which is truncated at this point (expand_buf() may fail) */
+    if (msg.msg_flags & MSG_TRUNC) {
+        rc = -1;
+        errno = ENOMEM;
     }
-  
-  return rc;
+
+    return rc;
 }
-  
-int iface_enumerate(void *parm, int (*ipv4_callback)(), int (*ipv6_callback)())
-{
-  struct sockaddr_nl addr;
-  struct nlmsghdr *h;
-  ssize_t len;
-  static unsigned int seq = 0;
-  int family = AF_INET;
 
-  struct {
-    struct nlmsghdr nlh;
-    struct rtgenmsg g; 
-  } req;
+int iface_enumerate(void* parm, int (*ipv4_callback)(), int (*ipv6_callback)()) {
+    struct sockaddr_nl addr;
+    struct nlmsghdr* h;
+    ssize_t len;
+    static unsigned int seq = 0;
+    int family = AF_INET;
 
-  addr.nl_family = AF_NETLINK;
-  addr.nl_pad = 0;
-  addr.nl_groups = 0;
-  addr.nl_pid = 0; /* address to kernel */
+    struct {
+        struct nlmsghdr nlh;
+        struct rtgenmsg g;
+    } req;
 
- again:
-  req.nlh.nlmsg_len = sizeof(req);
-  req.nlh.nlmsg_type = RTM_GETADDR;
-  req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST | NLM_F_ACK; 
-  req.nlh.nlmsg_pid = 0;
-  req.nlh.nlmsg_seq = ++seq;
-  req.g.rtgen_family = family; 
+    addr.nl_family = AF_NETLINK;
+    addr.nl_pad = 0;
+    addr.nl_groups = 0;
+    addr.nl_pid = 0; /* address to kernel */
 
-  /* Don't block in recvfrom if send fails */
-  while((len = sendto(daemon->netlinkfd, (void *)&req, sizeof(req), 0, 
-		      (struct sockaddr *)&addr, sizeof(addr))) == -1 && retry_send());
-  
-  if (len == -1)
-    return 0;
-    
-  while (1)
-    {
-      if ((len = netlink_recv()) == -1)
-	{
-	  if (errno == ENOBUFS)
-	    {
-	      sleep(1);
-	      goto again;
-	    }
-	  return 0;
-	}
+again:
+    req.nlh.nlmsg_len = sizeof(req);
+    req.nlh.nlmsg_type = RTM_GETADDR;
+    req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST | NLM_F_ACK;
+    req.nlh.nlmsg_pid = 0;
+    req.nlh.nlmsg_seq = ++seq;
+    req.g.rtgen_family = family;
 
-      for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len))
-	if (h->nlmsg_seq != seq || h->nlmsg_pid != netlink_pid)
-	  nl_routechange(h); /* May be multicast arriving async */
-	else if (h->nlmsg_type == NLMSG_ERROR)
-	  nl_err(h);
-	else if (h->nlmsg_type == NLMSG_DONE)
-	  {
+    /* Don't block in recvfrom if send fails */
+    while ((len = sendto(daemon->netlinkfd, (void*) &req, sizeof(req), 0, (struct sockaddr*) &addr,
+                         sizeof(addr))) == -1 &&
+           retry_send())
+        ;
+
+    if (len == -1) return 0;
+
+    while (1) {
+        if ((len = netlink_recv()) == -1) {
+            if (errno == ENOBUFS) {
+                sleep(1);
+                goto again;
+            }
+            return 0;
+        }
+
+        for (h = (struct nlmsghdr*) iov.iov_base; NLMSG_OK(h, (size_t) len); h = NLMSG_NEXT(h, len))
+            if (h->nlmsg_seq != seq || h->nlmsg_pid != netlink_pid)
+                nl_routechange(h); /* May be multicast arriving async */
+            else if (h->nlmsg_type == NLMSG_ERROR)
+                nl_err(h);
+            else if (h->nlmsg_type == NLMSG_DONE) {
 #ifdef HAVE_IPV6
-	    if (family == AF_INET && ipv6_callback)
-	      {
-		family = AF_INET6;
-		goto again;
-	      }
+                if (family == AF_INET && ipv6_callback) {
+                    family = AF_INET6;
+                    goto again;
+                }
 #endif
-	    return 1;
-	  }
-	else if (h->nlmsg_type == RTM_NEWADDR)
-	  {
-	    struct ifaddrmsg *ifa = NLMSG_DATA(h);  
-	    struct rtattr *rta = IFA_RTA(ifa);
-	    unsigned int len1 = h->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa));
-	    
-	    if (ifa->ifa_family == AF_INET)
-	      {
-		struct in_addr netmask, addr, broadcast;
-		
-		netmask.s_addr = htonl(0xffffffff << (32 - ifa->ifa_prefixlen));
-		addr.s_addr = 0;
-		broadcast.s_addr = 0;
-		
-		while (RTA_OK(rta, len1))
-		  {
-		    if (rta->rta_type == IFA_LOCAL)
-		      addr = *((struct in_addr *)(rta+1));
-		    else if (rta->rta_type == IFA_BROADCAST)
-		      broadcast = *((struct in_addr *)(rta+1));
-		    
-		    rta = RTA_NEXT(rta, len1);
-		  }
-		
-		if (addr.s_addr && ipv4_callback)
-		  if (!((*ipv4_callback)(addr, ifa->ifa_index, netmask, broadcast, parm)))
-		    return 0;
-	      }
+                return 1;
+            } else if (h->nlmsg_type == RTM_NEWADDR) {
+                struct ifaddrmsg* ifa = NLMSG_DATA(h);
+                struct rtattr* rta = IFA_RTA(ifa);
+                unsigned int len1 = h->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa));
+
+                if (ifa->ifa_family == AF_INET) {
+                    struct in_addr netmask, addr, broadcast;
+
+                    netmask.s_addr = htonl(0xffffffff << (32 - ifa->ifa_prefixlen));
+                    addr.s_addr = 0;
+                    broadcast.s_addr = 0;
+
+                    while (RTA_OK(rta, len1)) {
+                        if (rta->rta_type == IFA_LOCAL)
+                            addr = *((struct in_addr*) (rta + 1));
+                        else if (rta->rta_type == IFA_BROADCAST)
+                            broadcast = *((struct in_addr*) (rta + 1));
+
+                        rta = RTA_NEXT(rta, len1);
+                    }
+
+                    if (addr.s_addr && ipv4_callback)
+                        if (!((*ipv4_callback)(addr, ifa->ifa_index, netmask, broadcast, parm)))
+                            return 0;
+                }
 #ifdef HAVE_IPV6
-	    else if (ifa->ifa_family == AF_INET6)
-	      {
-		struct in6_addr *addrp = NULL;
-		while (RTA_OK(rta, len1))
-		  {
-		    if (rta->rta_type == IFA_ADDRESS)
-		      addrp = ((struct in6_addr *)(rta+1)); 
-		    
-		    rta = RTA_NEXT(rta, len1);
-		  }
-		
-		if (addrp && ipv6_callback)
-		  if (!((*ipv6_callback)(addrp, ifa->ifa_index, ifa->ifa_index, parm)))
-		    return 0;
-	      }
+                else if (ifa->ifa_family == AF_INET6) {
+                    struct in6_addr* addrp = NULL;
+                    while (RTA_OK(rta, len1)) {
+                        if (rta->rta_type == IFA_ADDRESS) addrp = ((struct in6_addr*) (rta + 1));
+
+                        rta = RTA_NEXT(rta, len1);
+                    }
+
+                    if (addrp && ipv6_callback)
+                        if (!((*ipv6_callback)(addrp, ifa->ifa_index, ifa->ifa_index, parm)))
+                            return 0;
+                }
 #endif
-	  }
+            }
     }
 }
 
+void netlink_multicast(void) {
+    ssize_t len;
+    struct nlmsghdr* h;
+    int flags;
 
-void netlink_multicast(void)
-{
-  ssize_t len;
-  struct nlmsghdr *h;
-  int flags;
-  
-  /* don't risk blocking reading netlink messages here. */
-  if ((flags = fcntl(daemon->netlinkfd, F_GETFL)) == -1 ||
-      fcntl(daemon->netlinkfd, F_SETFL, flags | O_NONBLOCK) == -1) 
-    return;
-  
-  if ((len = netlink_recv()) != -1)
-    {
-      for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len))
-	if (h->nlmsg_type == NLMSG_ERROR)
-	  nl_err(h);
-	else
-	  nl_routechange(h);
+    /* don't risk blocking reading netlink messages here. */
+    if ((flags = fcntl(daemon->netlinkfd, F_GETFL)) == -1 ||
+        fcntl(daemon->netlinkfd, F_SETFL, flags | O_NONBLOCK) == -1)
+        return;
+
+    if ((len = netlink_recv()) != -1) {
+        for (h = (struct nlmsghdr*) iov.iov_base; NLMSG_OK(h, (size_t) len); h = NLMSG_NEXT(h, len))
+            if (h->nlmsg_type == NLMSG_ERROR)
+                nl_err(h);
+            else
+                nl_routechange(h);
     }
 
-  /* restore non-blocking status */
-  fcntl(daemon->netlinkfd, F_SETFL, flags); 
+    /* restore non-blocking status */
+    fcntl(daemon->netlinkfd, F_SETFL, flags);
 }
 
-static void nl_err(struct nlmsghdr *h)
-{
-  struct nlmsgerr *err = NLMSG_DATA(h);
-  
-  if (err->error != 0)
-    my_syslog(LOG_ERR, _("netlink returns error: %s"), strerror(-(err->error)));
+static void nl_err(struct nlmsghdr* h) {
+    struct nlmsgerr* err = NLMSG_DATA(h);
+
+    if (err->error != 0)
+        my_syslog(LOG_ERR, _("netlink returns error: %s"), strerror(-(err->error)));
 }
 
 /* We arrange to receive netlink multicast messages whenever the network route is added.
    If this happens and we still have a DNS packet in the buffer, we re-send it.
    This helps on DoD links, where frequently the packet which triggers dialling is
    a DNS query, which then gets lost. By re-sending, we can avoid the lookup
-   failing. Note that we only accept these messages from the kernel (pid == 0) */ 
-static void nl_routechange(struct nlmsghdr *h)
-{
-  if (h->nlmsg_pid == 0 && h->nlmsg_type == RTM_NEWROUTE)
-    {
-      struct rtmsg *rtm = NLMSG_DATA(h);
-      int fd;
+   failing. Note that we only accept these messages from the kernel (pid == 0) */
+static void nl_routechange(struct nlmsghdr* h) {
+    if (h->nlmsg_pid == 0 && h->nlmsg_type == RTM_NEWROUTE) {
+        struct rtmsg* rtm = NLMSG_DATA(h);
+        int fd;
 
-      if (rtm->rtm_type != RTN_UNICAST || rtm->rtm_scope != RT_SCOPE_LINK)
-	return;
+        if (rtm->rtm_type != RTN_UNICAST || rtm->rtm_scope != RT_SCOPE_LINK) return;
 
-      /* Force re-reading resolv file right now, for luck. */
-      daemon->last_resolv = 0;
+        /* Force re-reading resolv file right now, for luck. */
+        daemon->last_resolv = 0;
 
-      if (daemon->srv_save)
-	{
-	  if (daemon->srv_save->sfd)
-	    fd = daemon->srv_save->sfd->fd;
-	  else if (daemon->rfd_save && daemon->rfd_save->refcount != 0)
-	    fd = daemon->rfd_save->fd;
-	  else
-	    return;
-	  
-	  while(sendto(fd, daemon->packet, daemon->packet_len, 0,
-		       &daemon->srv_save->addr.sa, sa_len(&daemon->srv_save->addr)) == -1 && retry_send()); 
-	}
+        if (daemon->srv_save) {
+            if (daemon->srv_save->sfd)
+                fd = daemon->srv_save->sfd->fd;
+            else if (daemon->rfd_save && daemon->rfd_save->refcount != 0)
+                fd = daemon->rfd_save->fd;
+            else
+                return;
+
+            while (sendto(fd, daemon->packet, daemon->packet_len, 0, &daemon->srv_save->addr.sa,
+                          sa_len(&daemon->srv_save->addr)) == -1 &&
+                   retry_send())
+                ;
+        }
     }
 }
 
 #endif
-
-      
diff --git a/src/network.c b/src/network.c
index 40f0226..34d821d 100644
--- a/src/network.c
+++ b/src/network.c
@@ -4,12 +4,12 @@
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; version 2 dated June, 1991, or
    (at your option) version 3 dated 29 June, 2007.
- 
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-     
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
@@ -20,369 +20,319 @@
 
 #ifdef HAVE_LINUX_NETWORK
 
-int indextoname(int fd, int index, char *name)
-{
-  struct ifreq ifr;
-  
-  if (index == 0)
-    return 0;
+int indextoname(int fd, int index, char* name) {
+    struct ifreq ifr;
 
-  ifr.ifr_ifindex = index;
-  if (ioctl(fd, SIOCGIFNAME, &ifr) == -1)
-    return 0;
+    if (index == 0) return 0;
 
-  strncpy(name, ifr.ifr_name, IF_NAMESIZE);
+    ifr.ifr_ifindex = index;
+    if (ioctl(fd, SIOCGIFNAME, &ifr) == -1) return 0;
 
-  return 1;
+    strncpy(name, ifr.ifr_name, IF_NAMESIZE);
+
+    return 1;
 }
 
 #else
 
-int indextoname(int fd, int index, char *name)
-{ 
-  if (index == 0 || !if_indextoname(index, name))
+int indextoname(int fd, int index, char* name) {
+    if (index == 0 || !if_indextoname(index, name)) return 0;
+
+    return 1;
+}
+
+#endif
+
+int iface_check(int family, struct all_addr* addr, char* name, int* indexp) {
+    struct iname* tmp;
+    int ret = 1;
+
+    /* Note: have to check all and not bail out early, so that we set the
+       "used" flags. */
+
+    if (indexp) {
+        /* One form of bridging on BSD has the property that packets
+       can be recieved on bridge interfaces which do not have an IP address.
+       We allow these to be treated as aliases of another interface which does have
+       an IP address with --dhcp-bridge=interface,alias,alias */
+        struct dhcp_bridge *bridge, *alias;
+        for (bridge = daemon->bridges; bridge; bridge = bridge->next) {
+            for (alias = bridge->alias; alias; alias = alias->next)
+                if (strncmp(name, alias->iface, IF_NAMESIZE) == 0) {
+                    int newindex;
+
+                    if (!(newindex = if_nametoindex(bridge->iface))) {
+                        my_syslog(LOG_WARNING, _("unknown interface %s in bridge-interface"), name);
+                        return 0;
+                    } else {
+                        *indexp = newindex;
+                        strncpy(name, bridge->iface, IF_NAMESIZE);
+                        break;
+                    }
+                }
+            if (alias) break;
+        }
+    }
+
+    if (daemon->if_names || (addr && daemon->if_addrs)) {
+        ret = 0;
+
+        for (tmp = daemon->if_names; tmp; tmp = tmp->next)
+            if (tmp->name && (strcmp(tmp->name, name) == 0)) ret = tmp->used = 1;
+
+        for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
+            if (addr && tmp->addr.sa.sa_family == family) {
+                if (family == AF_INET && tmp->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr)
+                    ret = tmp->used = 1;
+#ifdef HAVE_IPV6
+                else if (family == AF_INET6 &&
+                         IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, &addr->addr.addr6) &&
+                         (!IN6_IS_ADDR_LINKLOCAL(&addr->addr.addr6) ||
+                          (tmp->addr.in6.sin6_scope_id == (uint32_t) *indexp)))
+                    ret = tmp->used = 1;
+#endif
+            }
+    }
+
+    for (tmp = daemon->if_except; tmp; tmp = tmp->next)
+        if (tmp->name && (strcmp(tmp->name, name) == 0)) ret = 0;
+
+    return ret;
+}
+
+static int iface_allowed(struct irec** irecp, int if_index, union mysockaddr* addr,
+                         struct in_addr netmask) {
+    struct irec* iface;
+    int fd, mtu = 0, loopback;
+    struct ifreq ifr;
+    int dhcp_ok = 1;
+    struct iname* tmp;
+
+    /* check whether the interface IP has been added already
+       we call this routine multiple times. */
+    for (iface = *irecp; iface; iface = iface->next)
+        if (sockaddr_isequal(&iface->addr, addr)) return 1;
+
+    if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1 || !indextoname(fd, if_index, ifr.ifr_name) ||
+        ioctl(fd, SIOCGIFFLAGS, &ifr) == -1) {
+        if (fd != -1) {
+            int errsave = errno;
+            close(fd);
+            errno = errsave;
+        }
+        return 0;
+    }
+
+    loopback = ifr.ifr_flags & IFF_LOOPBACK;
+
+    if (ioctl(fd, SIOCGIFMTU, &ifr) != -1) mtu = ifr.ifr_mtu;
+
+    close(fd);
+
+    /* If we are restricting the set of interfaces to use, make
+       sure that loopback interfaces are in that set. */
+    if (daemon->if_names && loopback) {
+        struct iname* lo;
+        for (lo = daemon->if_names; lo; lo = lo->next)
+            if (lo->name && strcmp(lo->name, ifr.ifr_name) == 0) {
+                lo->isloop = 1;
+                break;
+            }
+
+        if (!lo && (lo = whine_malloc(sizeof(struct iname))) &&
+            (lo->name = whine_malloc(strlen(ifr.ifr_name) + 1))) {
+            strcpy(lo->name, ifr.ifr_name);
+            lo->isloop = lo->used = 1;
+            lo->next = daemon->if_names;
+            daemon->if_names = lo;
+        }
+    }
+
+    if (addr->sa.sa_family == AF_INET &&
+        !iface_check(AF_INET, (struct all_addr*) &addr->in.sin_addr, ifr.ifr_name, NULL))
+        return 1;
+
+    for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
+        if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0)) dhcp_ok = 0;
+
+#ifdef HAVE_IPV6
+    int ifindex = (int) addr->in6.sin6_scope_id;
+    if (addr->sa.sa_family == AF_INET6 &&
+        !iface_check(AF_INET6, (struct all_addr*) &addr->in6.sin6_addr, ifr.ifr_name, &ifindex))
+        return 1;
+#endif
+
+    /* add to list */
+    if ((iface = whine_malloc(sizeof(struct irec)))) {
+        iface->addr = *addr;
+        iface->netmask = netmask;
+        iface->dhcp_ok = dhcp_ok;
+        iface->mtu = mtu;
+        iface->next = *irecp;
+        *irecp = iface;
+        return 1;
+    }
+
+    errno = ENOMEM;
     return 0;
-
-  return 1;
-}
-
-#endif
-
-int iface_check(int family, struct all_addr *addr, char *name, int *indexp)
-{
-  struct iname *tmp;
-  int ret = 1;
-
-  /* Note: have to check all and not bail out early, so that we set the
-     "used" flags. */
-
-  if (indexp)
-    {
-      /* One form of bridging on BSD has the property that packets
-	 can be recieved on bridge interfaces which do not have an IP address.
-	 We allow these to be treated as aliases of another interface which does have
-	 an IP address with --dhcp-bridge=interface,alias,alias */
-      struct dhcp_bridge *bridge, *alias;
-      for (bridge = daemon->bridges; bridge; bridge = bridge->next)
-	{
-	  for (alias = bridge->alias; alias; alias = alias->next)
-	    if (strncmp(name, alias->iface, IF_NAMESIZE) == 0)
-	      {
-		int newindex;
-		
-		if (!(newindex = if_nametoindex(bridge->iface)))
-		  {
-		    my_syslog(LOG_WARNING, _("unknown interface %s in bridge-interface"), name);
-		    return 0;
-		  }
-		else 
-		  {
-		    *indexp = newindex;
-		    strncpy(name,  bridge->iface, IF_NAMESIZE);
-		    break;
-		  }
-	      }
-	  if (alias)
-	    break;
-	}
-    }
-        
-  if (daemon->if_names || (addr && daemon->if_addrs))
-    {
-      ret = 0;
-
-      for (tmp = daemon->if_names; tmp; tmp = tmp->next)
-	if (tmp->name && (strcmp(tmp->name, name) == 0))
-	  ret = tmp->used = 1;
-	        
-      for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
-	if (addr && tmp->addr.sa.sa_family == family)
-	  {
-	    if (family == AF_INET &&
-		tmp->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr)
-	      ret = tmp->used = 1;
-#ifdef HAVE_IPV6
-	    else if (family == AF_INET6 &&
-		     IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, 
-					&addr->addr.addr6) &&
-		     (!IN6_IS_ADDR_LINKLOCAL(&addr->addr.addr6) ||
-		      (tmp->addr.in6.sin6_scope_id == (uint32_t) *indexp)))
-	      ret = tmp->used = 1;
-#endif
-	  }          
-    }
-  
-  for (tmp = daemon->if_except; tmp; tmp = tmp->next)
-    if (tmp->name && (strcmp(tmp->name, name) == 0))
-      ret = 0;
-  
-  return ret; 
-}
-      
-static int iface_allowed(struct irec **irecp, int if_index, 
-			 union mysockaddr *addr, struct in_addr netmask) 
-{
-  struct irec *iface;
-  int fd, mtu = 0, loopback;
-  struct ifreq ifr;
-  int dhcp_ok = 1;
-  struct iname *tmp;
-  
-  /* check whether the interface IP has been added already 
-     we call this routine multiple times. */
-  for (iface = *irecp; iface; iface = iface->next) 
-    if (sockaddr_isequal(&iface->addr, addr))
-      return 1;
-  
-  if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1 ||
-      !indextoname(fd, if_index, ifr.ifr_name) ||
-      ioctl(fd, SIOCGIFFLAGS, &ifr) == -1)
-    {
-      if (fd != -1)
-	{
-	  int errsave = errno;
-	  close(fd);
-	  errno = errsave;
-	}
-      return 0;
-    }
-   
-  loopback = ifr.ifr_flags & IFF_LOOPBACK;
-
-  if (ioctl(fd, SIOCGIFMTU, &ifr) != -1)
-    mtu = ifr.ifr_mtu;
-  
-  close(fd);
-  
-  /* If we are restricting the set of interfaces to use, make
-     sure that loopback interfaces are in that set. */
-  if (daemon->if_names && loopback)
-    {
-      struct iname *lo;
-      for (lo = daemon->if_names; lo; lo = lo->next)
-	if (lo->name && strcmp(lo->name, ifr.ifr_name) == 0)
-	  {
-	    lo->isloop = 1;
-	    break;
-	  }
-      
-      if (!lo && 
-	  (lo = whine_malloc(sizeof(struct iname))) &&
-	  (lo->name = whine_malloc(strlen(ifr.ifr_name)+1)))
-	{
-	  strcpy(lo->name, ifr.ifr_name);
-	  lo->isloop = lo->used = 1;
-	  lo->next = daemon->if_names;
-	  daemon->if_names = lo;
-	}
-    }
-  
-  if (addr->sa.sa_family == AF_INET &&
-      !iface_check(AF_INET, (struct all_addr *)&addr->in.sin_addr, ifr.ifr_name, NULL))
-    return 1;
-  
-  for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
-    if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
-      dhcp_ok = 0;
-  
-#ifdef HAVE_IPV6
-  int ifindex = (int) addr->in6.sin6_scope_id;
-  if (addr->sa.sa_family == AF_INET6 &&
-      !iface_check(AF_INET6, (struct all_addr *)&addr->in6.sin6_addr, ifr.ifr_name, &ifindex))
-    return 1;
-#endif
-
-  /* add to list */
-  if ((iface = whine_malloc(sizeof(struct irec))))
-    {
-      iface->addr = *addr;
-      iface->netmask = netmask;
-      iface->dhcp_ok = dhcp_ok;
-      iface->mtu = mtu;
-      iface->next = *irecp;
-      *irecp = iface;
-      return 1;
-    }
-  
-  errno = ENOMEM; 
-  return 0;
 }
 
 #ifdef HAVE_IPV6
-static int iface_allowed_v6(struct in6_addr *local, 
-			    int scope, int if_index, void *vparam)
-{
-  union mysockaddr addr;
-  struct in_addr netmask; /* dummy */
+static int iface_allowed_v6(struct in6_addr* local, int scope, int if_index, void* vparam) {
+    union mysockaddr addr;
+    struct in_addr netmask; /* dummy */
 
-  netmask.s_addr = 0;
+    netmask.s_addr = 0;
 
-  memset(&addr, 0, sizeof(addr));
-  addr.in6.sin6_family = AF_INET6;
-  addr.in6.sin6_addr = *local;
-  addr.in6.sin6_port = htons(daemon->port);
-  /**
-   * Only populate the scope ID if the address is link-local.
-   * Scope IDs are not meaningful for global addresses. Also, we do not want to
-   * think that two addresses are different if they differ only in scope ID,
-   * because the kernel will treat them as if they are the same.
-   */
-  if (IN6_IS_ADDR_LINKLOCAL(local)) {
-    addr.in6.sin6_scope_id = scope;
-  }
-  
-  return iface_allowed((struct irec **)vparam, if_index, &addr, netmask);
+    memset(&addr, 0, sizeof(addr));
+    addr.in6.sin6_family = AF_INET6;
+    addr.in6.sin6_addr = *local;
+    addr.in6.sin6_port = htons(daemon->port);
+    /**
+     * Only populate the scope ID if the address is link-local.
+     * Scope IDs are not meaningful for global addresses. Also, we do not want to
+     * think that two addresses are different if they differ only in scope ID,
+     * because the kernel will treat them as if they are the same.
+     */
+    if (IN6_IS_ADDR_LINKLOCAL(local)) {
+        addr.in6.sin6_scope_id = scope;
+    }
+
+    return iface_allowed((struct irec**) vparam, if_index, &addr, netmask);
 }
 #endif
 
-static int iface_allowed_v4(struct in_addr local, int if_index, 
-			    struct in_addr netmask, struct in_addr broadcast, void *vparam)
-{
-  union mysockaddr addr;
+static int iface_allowed_v4(struct in_addr local, int if_index, struct in_addr netmask,
+                            struct in_addr broadcast, void* vparam) {
+    union mysockaddr addr;
 
-  memset(&addr, 0, sizeof(addr));
-  addr.in.sin_family = AF_INET;
-  addr.in.sin_addr = broadcast; /* warning */
-  addr.in.sin_addr = local;
-  addr.in.sin_port = htons(daemon->port);
+    memset(&addr, 0, sizeof(addr));
+    addr.in.sin_family = AF_INET;
+    addr.in.sin_addr = broadcast; /* warning */
+    addr.in.sin_addr = local;
+    addr.in.sin_port = htons(daemon->port);
 
-  return iface_allowed((struct irec **)vparam, if_index, &addr, netmask);
+    return iface_allowed((struct irec**) vparam, if_index, &addr, netmask);
 }
-   
-int enumerate_interfaces(void)
-{
+
+int enumerate_interfaces(void) {
 #ifdef HAVE_IPV6
-  return iface_enumerate(&daemon->interfaces, iface_allowed_v4, iface_allowed_v6);
+    return iface_enumerate(&daemon->interfaces, iface_allowed_v4, iface_allowed_v6);
 #else
-  return iface_enumerate(&daemon->interfaces, iface_allowed_v4, NULL);
+    return iface_enumerate(&daemon->interfaces, iface_allowed_v4, NULL);
 #endif
 }
 
 /* set NONBLOCK bit on fd: See Stevens 16.6 */
-int fix_fd(int fd)
-{
-  int flags;
+int fix_fd(int fd) {
+    int flags;
 
-  if ((flags = fcntl(fd, F_GETFL)) == -1 ||
-      fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
-    return 0;
-  
-  return 1;
+    if ((flags = fcntl(fd, F_GETFL)) == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
+        return 0;
+
+    return 1;
 }
 
 #if defined(HAVE_IPV6)
-static int create_ipv6_listener(struct listener **link, int port)
-{
-  union mysockaddr addr;
-  int tcpfd, fd;
-  struct listener *l;
-  int opt = 1;
+static int create_ipv6_listener(struct listener** link, int port) {
+    union mysockaddr addr;
+    int tcpfd, fd;
+    struct listener* l;
+    int opt = 1;
 
-  memset(&addr, 0, sizeof(addr));
-  addr.in6.sin6_family = AF_INET6;
-  addr.in6.sin6_addr = in6addr_any;
-  addr.in6.sin6_port = htons(port);
+    memset(&addr, 0, sizeof(addr));
+    addr.in6.sin6_family = AF_INET6;
+    addr.in6.sin6_addr = in6addr_any;
+    addr.in6.sin6_port = htons(port);
 
-  /* No error of the kernel doesn't support IPv6 */
-  if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) == -1)
-    return (errno == EPROTONOSUPPORT ||
-	    errno == EAFNOSUPPORT ||
-	    errno == EINVAL);
+    /* No error of the kernel doesn't support IPv6 */
+    if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) == -1)
+        return (errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT || errno == EINVAL);
 
-  if ((tcpfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1)
-    return 0;
+    if ((tcpfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1) return 0;
 
-  if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
-      setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
-      setsockopt(fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
-      setsockopt(tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
-      !fix_fd(fd) ||
-      !fix_fd(tcpfd) ||
+    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
+        setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
+        setsockopt(fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
+        setsockopt(tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 || !fix_fd(fd) ||
+        !fix_fd(tcpfd) ||
 #ifdef IPV6_RECVPKTINFO
-      setsockopt(fd, IPV6_LEVEL, IPV6_RECVPKTINFO, &opt, sizeof(opt)) == -1 ||
+        setsockopt(fd, IPV6_LEVEL, IPV6_RECVPKTINFO, &opt, sizeof(opt)) == -1 ||
 #else
-      setsockopt(fd, IPV6_LEVEL, IPV6_PKTINFO, &opt, sizeof(opt)) == -1 ||
+        setsockopt(fd, IPV6_LEVEL, IPV6_PKTINFO, &opt, sizeof(opt)) == -1 ||
 #endif
-      bind(tcpfd, (struct sockaddr *)&addr, sa_len(&addr)) == -1 ||
-      listen(tcpfd, 5) == -1 ||
-      bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == -1) 
-    return 0;
-      
-  l = safe_malloc(sizeof(struct listener));
-  l->fd = fd;
-  l->tcpfd = tcpfd;
-  l->family = AF_INET6;
-  l->iface = NULL;
-  l->next = NULL;
-  *link = l;
-  
-  return 1;
+        bind(tcpfd, (struct sockaddr*) &addr, sa_len(&addr)) == -1 || listen(tcpfd, 5) == -1 ||
+        bind(fd, (struct sockaddr*) &addr, sa_len(&addr)) == -1)
+        return 0;
+
+    l = safe_malloc(sizeof(struct listener));
+    l->fd = fd;
+    l->tcpfd = tcpfd;
+    l->family = AF_INET6;
+    l->iface = NULL;
+    l->next = NULL;
+    *link = l;
+
+    return 1;
 }
 #endif
 
-struct listener *create_wildcard_listeners(void)
-{
-  union mysockaddr addr;
-  int opt = 1;
-  struct listener *l, *l6 = NULL;
-  int tcpfd = -1, fd = -1;
+struct listener* create_wildcard_listeners(void) {
+    union mysockaddr addr;
+    int opt = 1;
+    struct listener *l, *l6 = NULL;
+    int tcpfd = -1, fd = -1;
 
-  memset(&addr, 0, sizeof(addr));
-  addr.in.sin_family = AF_INET;
-  addr.in.sin_addr.s_addr = INADDR_ANY;
-  addr.in.sin_port = htons(daemon->port);
+    memset(&addr, 0, sizeof(addr));
+    addr.in.sin_family = AF_INET;
+    addr.in.sin_addr.s_addr = INADDR_ANY;
+    addr.in.sin_port = htons(daemon->port);
 
-  if (daemon->port != 0)
-    {
-      
-      if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 ||
-	  (tcpfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
-	return NULL;
-      
-      if (setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
-	  bind(tcpfd, (struct sockaddr *)&addr, sa_len(&addr)) == -1 ||
-	  listen(tcpfd, 5) == -1 ||
-	  !fix_fd(tcpfd) ||
+    if (daemon->port != 0) {
+        if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 ||
+            (tcpfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
+            return NULL;
+
+        if (setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
+            bind(tcpfd, (struct sockaddr*) &addr, sa_len(&addr)) == -1 || listen(tcpfd, 5) == -1 ||
+            !fix_fd(tcpfd) ||
 #ifdef HAVE_IPV6
-	  !create_ipv6_listener(&l6, daemon->port) ||
+            !create_ipv6_listener(&l6, daemon->port) ||
 #endif
-	  setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
-	  !fix_fd(fd) ||
-#if defined(HAVE_LINUX_NETWORK) 
-	  setsockopt(fd, SOL_IP, IP_PKTINFO, &opt, sizeof(opt)) == -1 ||
+            setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 || !fix_fd(fd) ||
+#if defined(HAVE_LINUX_NETWORK)
+            setsockopt(fd, SOL_IP, IP_PKTINFO, &opt, sizeof(opt)) == -1 ||
 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
-	  setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt)) == -1 ||
-	  setsockopt(fd, IPPROTO_IP, IP_RECVIF, &opt, sizeof(opt)) == -1 ||
-#endif 
-	  bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == -1)
-	return NULL;
+            setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt)) == -1 ||
+            setsockopt(fd, IPPROTO_IP, IP_RECVIF, &opt, sizeof(opt)) == -1 ||
+#endif
+            bind(fd, (struct sockaddr*) &addr, sa_len(&addr)) == -1)
+            return NULL;
 
 #ifdef __ANDROID__
-      uint32_t mark = daemon->listen_mark;
-      if (mark != 0 &&
-	  (setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1 ||
-	   setsockopt(tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1 ||
-	   setsockopt(l6->fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1 ||
-	   setsockopt(l6->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1))
-      {
-	my_syslog(LOG_WARNING, _("setsockopt(SO_MARK, 0x%x: %s"), mark, strerror(errno));
-	close(fd);
-	close(tcpfd);
-	close(l6->fd);
-	close(l6->tcpfd);
-	return NULL;
-      }
+        uint32_t mark = daemon->listen_mark;
+        if (mark != 0 && (setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1 ||
+                          setsockopt(tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1 ||
+                          setsockopt(l6->fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1 ||
+                          setsockopt(l6->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1)) {
+            my_syslog(LOG_WARNING, _("setsockopt(SO_MARK, 0x%x: %s"), mark, strerror(errno));
+            close(fd);
+            close(tcpfd);
+            close(l6->fd);
+            close(l6->tcpfd);
+            return NULL;
+        }
     }
 #endif /* __ANDROID__ */
 
-  l = safe_malloc(sizeof(struct listener));
-  l->family = AF_INET;
-  l->fd = fd;
-  l->tcpfd = tcpfd;
-  l->iface = NULL;
-  l->next = l6;
+    l = safe_malloc(sizeof(struct listener));
+    l->family = AF_INET;
+    l->fd = fd;
+    l->tcpfd = tcpfd;
+    l->iface = NULL;
+    l->next = l6;
 
-  return l;
+    return l;
 }
 
 #ifdef __ANDROID__
@@ -398,76 +348,67 @@
  *
  * die's on errors, so don't pass bad data.
  */
-void create_bound_listener(struct listener **listeners, struct irec *iface)
-{
-  int rc, opt = 1;
+void create_bound_listener(struct listener** listeners, struct irec* iface) {
+    int rc, opt = 1;
 #ifdef HAVE_IPV6
-  static int dad_count = 0;
+    static int dad_count = 0;
 #endif
 
-  struct listener *new = safe_malloc(sizeof(struct listener));
-  new->family = iface->addr.sa.sa_family;
-  new->iface = iface;
-  new->next = *listeners;
-  new->tcpfd = -1;
-  new->fd = -1;
-  *listeners = new;
+    struct listener* new = safe_malloc(sizeof(struct listener));
+    new->family = iface->addr.sa.sa_family;
+    new->iface = iface;
+    new->next = *listeners;
+    new->tcpfd = -1;
+    new->fd = -1;
+    *listeners = new;
 
-  if (daemon->port != 0)
-  {
-    if ((new->tcpfd = socket(iface->addr.sa.sa_family, SOCK_STREAM, 0)) == -1 ||
-        (new->fd = socket(iface->addr.sa.sa_family, SOCK_DGRAM, 0)) == -1 ||
-        setsockopt(new->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
-        setsockopt(new->tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
-        !fix_fd(new->tcpfd) ||
-        !fix_fd(new->fd))
-      die(_("failed to create listening socket: %s"), NULL, EC_BADNET);
+    if (daemon->port != 0) {
+        if ((new->tcpfd = socket(iface->addr.sa.sa_family, SOCK_STREAM, 0)) == -1 ||
+            (new->fd = socket(iface->addr.sa.sa_family, SOCK_DGRAM, 0)) == -1 ||
+            setsockopt(new->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
+            setsockopt(new->tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
+            !fix_fd(new->tcpfd) || !fix_fd(new->fd))
+            die(_("failed to create listening socket: %s"), NULL, EC_BADNET);
 
 #ifdef HAVE_IPV6
-    if (iface->addr.sa.sa_family == AF_INET6)
-    {
-      if (setsockopt(new->fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
-          setsockopt(new->tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1)
-        die(_("failed to set IPV6 options on listening socket: %s"), NULL, EC_BADNET);\
-    }
+        if (iface->addr.sa.sa_family == AF_INET6) {
+            if (setsockopt(new->fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
+                setsockopt(new->tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1)
+                die(_("failed to set IPV6 options on listening socket: %s"), NULL, EC_BADNET);
+        }
 #endif
 
-    while(1)
-    {
-      if ((rc = bind(new->fd, &iface->addr.sa, sa_len(&iface->addr))) != -1)
-        break;
+        while (1) {
+            if ((rc = bind(new->fd, &iface->addr.sa, sa_len(&iface->addr))) != -1) break;
 
 #ifdef HAVE_IPV6
-      /* An interface may have an IPv6 address which is still undergoing DAD.
-         If so, the bind will fail until the DAD completes, so we try over 20 seconds
-         before failing. */
-      /* TODO: What to do here? 20 seconds is way too long. We use optimistic addresses, so bind()
-         will only fail if the address has already failed DAD, in which case retrying won't help. */
-      if (iface->addr.sa.sa_family == AF_INET6 && (errno == ENODEV || errno == EADDRNOTAVAIL) &&
-          dad_count++ < DAD_WAIT)
-      {
-        sleep(1);
-        continue;
-      }
+            /* An interface may have an IPv6 address which is still undergoing DAD.
+               If so, the bind will fail until the DAD completes, so we try over 20 seconds
+               before failing. */
+            /* TODO: What to do here? 20 seconds is way too long. We use optimistic addresses, so
+               bind() will only fail if the address has already failed DAD, in which case retrying
+               won't help. */
+            if (iface->addr.sa.sa_family == AF_INET6 &&
+                (errno == ENODEV || errno == EADDRNOTAVAIL) && dad_count++ < DAD_WAIT) {
+                sleep(1);
+                continue;
+            }
 #endif
-      break;
+            break;
+        }
+
+        if (rc == -1 || bind(new->tcpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1) {
+            prettyprint_addr(&iface->addr, daemon->namebuff);
+            die(_("failed to bind listening socket for %s: %s"), daemon->namebuff, EC_BADNET);
+        }
+
+        uint32_t mark = daemon->listen_mark;
+        if (mark != 0 && (setsockopt(new->fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1 ||
+                          setsockopt(new->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1))
+            die(_("failed to set SO_MARK on listen socket: %s"), NULL, EC_BADNET);
+
+        if (listen(new->tcpfd, 5) == -1) die(_("failed to listen on socket: %s"), NULL, EC_BADNET);
     }
-
-    if (rc == -1 || bind(new->tcpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
-    {
-      prettyprint_addr(&iface->addr, daemon->namebuff);
-      die(_("failed to bind listening socket for %s: %s"), daemon->namebuff, EC_BADNET);
-    }
-
-    uint32_t mark = daemon->listen_mark;
-    if (mark != 0 &&
-	(setsockopt(new->fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1 ||
-	 setsockopt(new->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1))
-      die(_("failed to set SO_MARK on listen socket: %s"), NULL, EC_BADNET);
-
-    if (listen(new->tcpfd, 5) == -1)
-      die(_("failed to listen on socket: %s"), NULL, EC_BADNET);
-  }
 }
 
 /**
@@ -481,49 +422,46 @@
  *
  * See b/17475756 for further discussion.
  */
-void fixup_possible_existing_listener(struct irec *new_iface) {
-  /* find the listener, if present */
-  struct listener *l;
-  for (l = daemon->listeners; l; l = l->next) {
-    struct irec *listener_iface = l->iface;
-    if (listener_iface) {
-      if (sockaddr_isequal(&listener_iface->addr, &new_iface->addr)) {
-        l->iface = new_iface;
-        return;
-      }
+void fixup_possible_existing_listener(struct irec* new_iface) {
+    /* find the listener, if present */
+    struct listener* l;
+    for (l = daemon->listeners; l; l = l->next) {
+        struct irec* listener_iface = l->iface;
+        if (listener_iface) {
+            if (sockaddr_isequal(&listener_iface->addr, &new_iface->addr)) {
+                l->iface = new_iface;
+                return;
+            }
+        }
     }
-  }
 }
 
 /**
  * Closes the sockets of the specified listener, deletes it from the list, and frees it.
  *
  */
-int delete_listener(struct listener **l)
-{
-  struct listener *listener = *l;
-  if (listener == NULL) return 0;
+int delete_listener(struct listener** l) {
+    struct listener* listener = *l;
+    if (listener == NULL) return 0;
 
-  if (listener->iface) {
-    int port = prettyprint_addr(&listener->iface->addr, daemon->namebuff);
-    my_syslog(LOG_INFO, _("Closing listener [%s]:%d"), daemon->namebuff, port);
-  } else {
-    my_syslog(LOG_INFO, _("Closing wildcard listener family=%d"), listener->family);
-  }
+    if (listener->iface) {
+        int port = prettyprint_addr(&listener->iface->addr, daemon->namebuff);
+        my_syslog(LOG_INFO, _("Closing listener [%s]:%d"), daemon->namebuff, port);
+    } else {
+        my_syslog(LOG_INFO, _("Closing wildcard listener family=%d"), listener->family);
+    }
 
-  if (listener->tcpfd != -1)
-  {
-    close(listener->tcpfd);
-    listener->tcpfd = -1;
-  }
-  if (listener->fd != -1)
-  {
-    close(listener->fd);
-    listener->fd = -1;
-  }
-  *l = listener->next;
-  free(listener);
-  return -1;
+    if (listener->tcpfd != -1) {
+        close(listener->tcpfd);
+        listener->tcpfd = -1;
+    }
+    if (listener->fd != -1) {
+        close(listener->fd);
+        listener->fd = -1;
+    }
+    *l = listener->next;
+    free(listener);
+    return -1;
 }
 
 /**
@@ -536,357 +474,314 @@
  *
  * interface - input of the interface details to listen on
  */
-int close_bound_listener(struct irec *iface)
-{
-  /* find the listener */
-  int ret = 0;
-  struct listener **l = &daemon->listeners;
-  while (*l) {
-    struct irec *listener_iface = (*l)->iface;
-    struct listener **next = &((*l)->next);
-    if (iface && listener_iface && sockaddr_isequal(&listener_iface->addr, &iface->addr)) {
-      // Listener bound to an IP address. There can be only one of these.
-      ret = delete_listener(l);
-      break;
+int close_bound_listener(struct irec* iface) {
+    /* find the listener */
+    int ret = 0;
+    struct listener** l = &daemon->listeners;
+    while (*l) {
+        struct irec* listener_iface = (*l)->iface;
+        struct listener** next = &((*l)->next);
+        if (iface && listener_iface && sockaddr_isequal(&listener_iface->addr, &iface->addr)) {
+            // Listener bound to an IP address. There can be only one of these.
+            ret = delete_listener(l);
+            break;
+        }
+        if (iface == NULL && listener_iface == NULL) {
+            // Wildcard listener. There is one of these per address family.
+            ret = delete_listener(l);
+            continue;
+        }
+        l = next;
     }
-    if (iface == NULL && listener_iface == NULL) {
-      // Wildcard listener. There is one of these per address family.
-      ret = delete_listener(l);
-      continue;
-    }
-    l = next;
-  }
-  return ret;
+    return ret;
 }
 #endif /* __ANDROID__ */
 
-struct listener *create_bound_listeners(void)
-{
-  struct listener *listeners = NULL;
-  struct irec *iface;
+struct listener* create_bound_listeners(void) {
+    struct listener* listeners = NULL;
+    struct irec* iface;
 #ifndef __ANDROID__
-  int rc, opt = 1;
+    int rc, opt = 1;
 #ifdef HAVE_IPV6
-  static int dad_count = 0;
+    static int dad_count = 0;
 #endif
 #endif
 
-  for (iface = daemon->interfaces; iface; iface = iface->next)
-    {
+    for (iface = daemon->interfaces; iface; iface = iface->next) {
 #ifdef __ANDROID__
-      create_bound_listener(&listeners, iface);
+        create_bound_listener(&listeners, iface);
 #else
-      struct listener *new = safe_malloc(sizeof(struct listener));
-      new->family = iface->addr.sa.sa_family;
-      new->iface = iface;
-      new->next = listeners;
-      new->tcpfd = -1;
-      new->fd = -1;
-      listeners = new;
+            struct listener* new = safe_malloc(sizeof(struct listener));
+            new->family = iface->addr.sa.sa_family;
+            new->iface = iface;
+            new->next = listeners;
+            new->tcpfd = -1;
+            new->fd = -1;
+            listeners = new;
 
-      if (daemon->port != 0)
-	{
-	  if ((new->tcpfd = socket(iface->addr.sa.sa_family, SOCK_STREAM, 0)) == -1 ||
-	      (new->fd = socket(iface->addr.sa.sa_family, SOCK_DGRAM, 0)) == -1 ||
-	      setsockopt(new->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
-	      setsockopt(new->tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
-	      !fix_fd(new->tcpfd) ||
-	      !fix_fd(new->fd))
-	    die(_("failed to create listening socket: %s"), NULL, EC_BADNET);
-	  
+            if (daemon->port != 0) {
+                if ((new->tcpfd = socket(iface->addr.sa.sa_family, SOCK_STREAM, 0)) == -1 ||
+                    (new->fd = socket(iface->addr.sa.sa_family, SOCK_DGRAM, 0)) == -1 ||
+                    setsockopt(new->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
+                    setsockopt(new->tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
+                    !fix_fd(new->tcpfd) || !fix_fd(new->fd))
+                    die(_("failed to create listening socket: %s"), NULL, EC_BADNET);
+
 #ifdef HAVE_IPV6
-	  if (iface->addr.sa.sa_family == AF_INET6)
-	    {
-	      if (setsockopt(new->fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
-		  setsockopt(new->tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1)
-		die(_("failed to set IPV6 options on listening socket: %s"), NULL, EC_BADNET);
-	    }
+                if (iface->addr.sa.sa_family == AF_INET6) {
+                    if (setsockopt(new->fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
+                        setsockopt(new->tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1)
+                        die(_("failed to set IPV6 options on listening socket: %s"), NULL,
+                            EC_BADNET);
+                }
 #endif
 
-	  while(1)
-	    {
-	      if ((rc = bind(new->fd, &iface->addr.sa, sa_len(&iface->addr))) != -1)
-		break;
-	      
+                while (1) {
+                    if ((rc = bind(new->fd, &iface->addr.sa, sa_len(&iface->addr))) != -1) break;
+
 #ifdef HAVE_IPV6
-	      /* An interface may have an IPv6 address which is still undergoing DAD. 
-		 If so, the bind will fail until the DAD completes, so we try over 20 seconds
-		 before failing. */
-	      if (iface->addr.sa.sa_family == AF_INET6 && (errno == ENODEV || errno == EADDRNOTAVAIL) && 
-		  dad_count++ < DAD_WAIT)
-		{
-		  sleep(1);
-		  continue;
-		}
+                    /* An interface may have an IPv6 address which is still undergoing DAD.
+                   If so, the bind will fail until the DAD completes, so we try over 20 seconds
+                   before failing. */
+                    if (iface->addr.sa.sa_family == AF_INET6 &&
+                        (errno == ENODEV || errno == EADDRNOTAVAIL) && dad_count++ < DAD_WAIT) {
+                        sleep(1);
+                        continue;
+                    }
 #endif
-	      break;
-	    }
-	  
-	  if (rc == -1 || bind(new->tcpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
-	    {
-	      prettyprint_addr(&iface->addr, daemon->namebuff);
-	      die(_("failed to bind listening socket for %s: %s"), 
-		  daemon->namebuff, EC_BADNET);
-	    }
-	    
-	  if (listen(new->tcpfd, 5) == -1)
-	    die(_("failed to listen on socket: %s"), NULL, EC_BADNET);
-	}
+                    break;
+                }
+
+                if (rc == -1 || bind(new->tcpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1) {
+                    prettyprint_addr(&iface->addr, daemon->namebuff);
+                    die(_("failed to bind listening socket for %s: %s"), daemon->namebuff,
+                        EC_BADNET);
+                }
+
+                if (listen(new->tcpfd, 5) == -1)
+                    die(_("failed to listen on socket: %s"), NULL, EC_BADNET);
+            }
 #endif /* !__ANDROID */
     }
 
-  return listeners;
+    return listeners;
 }
 
-
 /* return a UDP socket bound to a random port, have to cope with straying into
    occupied port nos and reserved ones. */
-int random_sock(int family)
-{
-  int fd;
+int random_sock(int family) {
+    int fd;
 
-  if ((fd = socket(family, SOCK_DGRAM, 0)) != -1)
-    {
-      union mysockaddr addr;
-      unsigned int ports_avail = 65536u - (unsigned short)daemon->min_port;
-      int tries = ports_avail < 30 ? 3 * ports_avail : 100;
+    if ((fd = socket(family, SOCK_DGRAM, 0)) != -1) {
+        union mysockaddr addr;
+        unsigned int ports_avail = 65536u - (unsigned short) daemon->min_port;
+        int tries = ports_avail < 30 ? 3 * ports_avail : 100;
 
-      memset(&addr, 0, sizeof(addr));
-      addr.sa.sa_family = family;
+        memset(&addr, 0, sizeof(addr));
+        addr.sa.sa_family = family;
 
-      /* don't loop forever if all ports in use. */
+        /* don't loop forever if all ports in use. */
 
-      if (fix_fd(fd))
-	while(tries--)
-	  {
-	    unsigned short port = rand16();
-	    
-	    if (daemon->min_port != 0)
-	      port = htons(daemon->min_port + (port % ((unsigned short)ports_avail)));
+        if (fix_fd(fd))
+            while (tries--) {
+                unsigned short port = rand16();
 
-	    if (family == AF_INET) {
-		addr.in.sin_addr.s_addr = INADDR_ANY;
-		addr.in.sin_port = port;
-	    } else {
-		addr.in6.sin6_addr = in6addr_any;
-		addr.in6.sin6_port = port;
-	    }
+                if (daemon->min_port != 0)
+                    port = htons(daemon->min_port + (port % ((unsigned short) ports_avail)));
 
-	    if (bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == 0)
-	      return fd;
-	    
-	    if (errno != EADDRINUSE && errno != EACCES)
-	      break;
-	  }
+                if (family == AF_INET) {
+                    addr.in.sin_addr.s_addr = INADDR_ANY;
+                    addr.in.sin_port = port;
+                } else {
+                    addr.in6.sin6_addr = in6addr_any;
+                    addr.in6.sin6_port = port;
+                }
 
-      close(fd);
+                if (bind(fd, (struct sockaddr*) &addr, sa_len(&addr)) == 0) return fd;
+
+                if (errno != EADDRINUSE && errno != EACCES) break;
+            }
+
+        close(fd);
     }
 
-  return -1; 
+    return -1;
 }
-  
 
-int local_bind(int fd, union mysockaddr *addr, char *intname, uint32_t mark, int is_tcp)
-{
-  union mysockaddr addr_copy = *addr;
+int local_bind(int fd, union mysockaddr* addr, char* intname, uint32_t mark, int is_tcp) {
+    union mysockaddr addr_copy = *addr;
 
-  /* cannot set source _port_ for TCP connections. */
-  if (is_tcp)
-    {
-      if (addr_copy.sa.sa_family == AF_INET)
-	addr_copy.in.sin_port = 0;
+    /* cannot set source _port_ for TCP connections. */
+    if (is_tcp) {
+        if (addr_copy.sa.sa_family == AF_INET) addr_copy.in.sin_port = 0;
 #ifdef HAVE_IPV6
-      else
-	addr_copy.in6.sin6_port = 0;
+        else
+            addr_copy.in6.sin6_port = 0;
 #endif
     }
-  
-  if (bind(fd, (struct sockaddr *)&addr_copy, sa_len(&addr_copy)) == -1)
-    return 0;
-    
+
+    if (bind(fd, (struct sockaddr*) &addr_copy, sa_len(&addr_copy)) == -1) return 0;
+
 #if defined(SO_BINDTODEVICE)
-  if (intname[0] != 0 &&
-      setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, strlen(intname)) == -1)
-    return 0;
+    if (intname[0] != 0 &&
+        setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, strlen(intname)) == -1)
+        return 0;
 #endif
 
-  if (mark != 0 && setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1)
-    return 0;
+    if (mark != 0 && setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1) return 0;
 
-  return 1;
+    return 1;
 }
 
-static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname, uint32_t mark)
-{
-  struct serverfd *sfd;
-  int errsave;
+static struct serverfd* allocate_sfd(union mysockaddr* addr, char* intname, uint32_t mark) {
+    struct serverfd* sfd;
+    int errsave;
 
-  /* when using random ports, servers which would otherwise use
-     the INADDR_ANY/port0 socket have sfd set to NULL */
-  if (!daemon->osport && intname[0] == 0)
-    {
-      errno = 0;
-      
-      if (addr->sa.sa_family == AF_INET &&
-	  addr->in.sin_addr.s_addr == INADDR_ANY &&
-	  addr->in.sin_port == htons(0)) 
-	return NULL;
+    /* when using random ports, servers which would otherwise use
+       the INADDR_ANY/port0 socket have sfd set to NULL */
+    if (!daemon->osport && intname[0] == 0) {
+        errno = 0;
+
+        if (addr->sa.sa_family == AF_INET && addr->in.sin_addr.s_addr == INADDR_ANY &&
+            addr->in.sin_port == htons(0))
+            return NULL;
 
 #ifdef HAVE_IPV6
-      if (addr->sa.sa_family == AF_INET6 &&
-	  memcmp(&addr->in6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0 &&
-	  addr->in6.sin6_port == htons(0)) 
-	return NULL;
+        if (addr->sa.sa_family == AF_INET6 &&
+            memcmp(&addr->in6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0 &&
+            addr->in6.sin6_port == htons(0))
+            return NULL;
 #endif
     }
-      
-  /* may have a suitable one already */
-  for (sfd = daemon->sfds; sfd; sfd = sfd->next )
-    if (sockaddr_isequal(&sfd->source_addr, addr) &&
-	mark == sfd->mark &&
-	strcmp(intname, sfd->interface) == 0)
-      return sfd;
-  
-  /* need to make a new one. */
-  errno = ENOMEM; /* in case malloc fails. */
-  if (!(sfd = whine_malloc(sizeof(struct serverfd))))
-    return NULL;
-  
-  if ((sfd->fd = socket(addr->sa.sa_family, SOCK_DGRAM, 0)) == -1)
-    {
-      free(sfd);
-      return NULL;
+
+    /* may have a suitable one already */
+    for (sfd = daemon->sfds; sfd; sfd = sfd->next)
+        if (sockaddr_isequal(&sfd->source_addr, addr) && mark == sfd->mark &&
+            strcmp(intname, sfd->interface) == 0)
+            return sfd;
+
+    /* need to make a new one. */
+    errno = ENOMEM; /* in case malloc fails. */
+    if (!(sfd = whine_malloc(sizeof(struct serverfd)))) return NULL;
+
+    if ((sfd->fd = socket(addr->sa.sa_family, SOCK_DGRAM, 0)) == -1) {
+        free(sfd);
+        return NULL;
     }
-  
-  if (!local_bind(sfd->fd, addr, intname, mark, 0) || !fix_fd(sfd->fd))
-    { 
-      errsave = errno; /* save error from bind. */
-      close(sfd->fd);
-      free(sfd);
-      errno = errsave;
-      return NULL;
+
+    if (!local_bind(sfd->fd, addr, intname, mark, 0) || !fix_fd(sfd->fd)) {
+        errsave = errno; /* save error from bind. */
+        close(sfd->fd);
+        free(sfd);
+        errno = errsave;
+        return NULL;
     }
-    
-  strcpy(sfd->interface, intname); 
-  sfd->source_addr = *addr;
-  sfd->mark = mark;
-  sfd->next = daemon->sfds;
-  daemon->sfds = sfd;
-  return sfd; 
+
+    strcpy(sfd->interface, intname);
+    sfd->source_addr = *addr;
+    sfd->mark = mark;
+    sfd->next = daemon->sfds;
+    daemon->sfds = sfd;
+    return sfd;
 }
 
 /* create upstream sockets during startup, before root is dropped which may be needed
    this allows query_port to be a low port and interface binding */
-void pre_allocate_sfds(void)
-{
-  struct server *srv;
+void pre_allocate_sfds(void) {
+    struct server* srv;
 
-  if (daemon->query_port != 0)
-    {
-      union  mysockaddr addr;
-      memset(&addr, 0, sizeof(addr));
-      addr.in.sin_family = AF_INET;
-      addr.in.sin_addr.s_addr = INADDR_ANY;
-      addr.in.sin_port = htons(daemon->query_port);
-      allocate_sfd(&addr, "", 0);
+    if (daemon->query_port != 0) {
+        union mysockaddr addr;
+        memset(&addr, 0, sizeof(addr));
+        addr.in.sin_family = AF_INET;
+        addr.in.sin_addr.s_addr = INADDR_ANY;
+        addr.in.sin_port = htons(daemon->query_port);
+        allocate_sfd(&addr, "", 0);
 #ifdef HAVE_IPV6
-      memset(&addr, 0, sizeof(addr));
-      addr.in6.sin6_family = AF_INET6;
-      addr.in6.sin6_addr = in6addr_any;
-      addr.in6.sin6_port = htons(daemon->query_port);
-      allocate_sfd(&addr, "", 0);
+        memset(&addr, 0, sizeof(addr));
+        addr.in6.sin6_family = AF_INET6;
+        addr.in6.sin6_addr = in6addr_any;
+        addr.in6.sin6_port = htons(daemon->query_port);
+        allocate_sfd(&addr, "", 0);
 #endif
     }
 
-  for (srv = daemon->servers; srv; srv = srv->next)
-    if (!(srv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)) &&
-	!allocate_sfd(&srv->source_addr, srv->interface, srv->mark) &&
-	errno != 0 &&
-	(daemon->options & OPT_NOWILD))
-      {
-	prettyprint_addr(&srv->addr, daemon->namebuff);
-	if (srv->interface[0] != 0)
-	  {
-	    strcat(daemon->namebuff, " ");
-	    strcat(daemon->namebuff, srv->interface);
-	  }
-	die(_("failed to bind server socket for %s: %s"),
-	    daemon->namebuff, EC_BADNET);
-      }  
+    for (srv = daemon->servers; srv; srv = srv->next)
+        if (!(srv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)) &&
+            !allocate_sfd(&srv->source_addr, srv->interface, srv->mark) && errno != 0 &&
+            (daemon->options & OPT_NOWILD)) {
+            prettyprint_addr(&srv->addr, daemon->namebuff);
+            if (srv->interface[0] != 0) {
+                strcat(daemon->namebuff, " ");
+                strcat(daemon->namebuff, srv->interface);
+            }
+            die(_("failed to bind server socket for %s: %s"), daemon->namebuff, EC_BADNET);
+        }
 }
 
+void check_servers(void) {
+    struct irec* iface;
+    struct server* new, *tmp, *ret = NULL;
+    int port = 0;
 
-void check_servers(void)
-{
-  struct irec *iface;
-  struct server *new, *tmp, *ret = NULL;
-  int port = 0;
+    for (new = daemon->servers; new; new = tmp) {
+        tmp = new->next;
 
-  for (new = daemon->servers; new; new = tmp)
-    {
-      tmp = new->next;
-      
-      if (!(new->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)))
-	{
-	  port = prettyprint_addr(&new->addr, daemon->namebuff);
+        if (!(new->flags&(SERV_LITERAL_ADDRESS | SERV_NO_ADDR))) {
+            port = prettyprint_addr(&new->addr, daemon->namebuff);
 
-	  /* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
-	  if (new->addr.sa.sa_family == AF_INET &&
-	      new->addr.in.sin_addr.s_addr == 0)
-	    {
-	      free(new);
-	      continue;
-	    }
+            /* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
+            if (new->addr.sa.sa_family == AF_INET && new->addr.in.sin_addr.s_addr == 0) {
+                free(new);
+                continue;
+            }
 
-	  for (iface = daemon->interfaces; iface; iface = iface->next)
-	    if (sockaddr_isequal(&new->addr, &iface->addr))
-	      break;
-	  if (iface)
-	    {
-	      my_syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"), daemon->namebuff);
-	      free(new);
-	      continue;
-	    }
-	  
-	  /* Do we need a socket set? */
-	  if (!new->sfd && 
-	      !(new->sfd = allocate_sfd(&new->source_addr, new->interface, new->mark)) &&
-	      errno != 0)
-	    {
-	      my_syslog(LOG_WARNING, 
-			_("ignoring nameserver %s - cannot make/bind socket: %s"),
-			daemon->namebuff, strerror(errno));
-	      free(new);
-	      continue;
-	    }
-	}
-      
-      /* reverse order - gets it right. */
-      new->next = ret;
-      ret = new;
-      
-      if (new->flags & (SERV_HAS_DOMAIN | SERV_FOR_NODOTS))
-	{
-	  char *s1, *s2;
-	  if (!(new->flags & SERV_HAS_DOMAIN))
-	    s1 = _("unqualified"), s2 = _("names");
-	  else if (strlen(new->domain) == 0)
-	    s1 = _("default"), s2 = "";
-	  else
-	    s1 = _("domain"), s2 = new->domain;
-	  
-	  if (new->flags & SERV_NO_ADDR)
-	    my_syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
-	  else if (!(new->flags & SERV_LITERAL_ADDRESS))
-	    my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s"), daemon->namebuff, port, s1, s2);
-	}
-      else if (new->interface[0] != 0)
-	my_syslog(LOG_INFO, _("using nameserver %s#%d(via %s)"), daemon->namebuff, port, new->interface); 
-      else
-	my_syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port); 
+            for (iface = daemon->interfaces; iface; iface = iface->next)
+                if (sockaddr_isequal(&new->addr, &iface->addr)) break;
+            if (iface) {
+                my_syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"),
+                          daemon->namebuff);
+                free(new);
+                continue;
+            }
+
+            /* Do we need a socket set? */
+            if (!new->sfd &&
+                !(new->sfd = allocate_sfd(&new->source_addr, new->interface, new->mark)) &&
+                errno != 0) {
+                my_syslog(LOG_WARNING, _("ignoring nameserver %s - cannot make/bind socket: %s"),
+                          daemon->namebuff, strerror(errno));
+                free(new);
+                continue;
+            }
+        }
+
+        /* reverse order - gets it right. */
+        new->next = ret;
+        ret = new;
+
+        if (new->flags&(SERV_HAS_DOMAIN | SERV_FOR_NODOTS)) {
+            char *s1, *s2;
+            if (!(new->flags& SERV_HAS_DOMAIN))
+                s1 = _("unqualified"), s2 = _("names");
+            else if (strlen(new->domain) == 0)
+                s1 = _("default"), s2 = "";
+            else
+                s1 = _("domain"), s2 = new->domain;
+
+            if (new->flags & SERV_NO_ADDR)
+                my_syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
+            else if (!(new->flags& SERV_LITERAL_ADDRESS))
+                my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s"), daemon->namebuff, port,
+                          s1, s2);
+        } else if (new->interface[0] != 0)
+            my_syslog(LOG_INFO, _("using nameserver %s#%d(via %s)"), daemon->namebuff, port,
+                      new->interface);
+        else
+            my_syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port);
     }
-  
-  daemon->servers = ret;
+
+    daemon->servers = ret;
 }
 
 #ifdef __ANDROID__
@@ -897,14 +792,13 @@
  *
  * interfaces - input in the format "bt-pan|eth0|wlan0|..>" up to 1024 bytes long
  */
-void set_interfaces(const char *interfaces)
-{
-    struct iname *if_tmp;
-    struct iname *prev_if_names;
+void set_interfaces(const char* interfaces) {
+    struct iname* if_tmp;
+    struct iname* prev_if_names;
     struct irec *old_iface, *new_iface, *prev_interfaces;
     char s[1024];
-    char *next = s;
-    char *interface;
+    char* next = s;
+    char* interface;
     int was_wild = 0;
 
 #ifdef __ANDROID_DEBUG__
@@ -920,11 +814,10 @@
         die(_("interface string too long: %s"), NULL, EC_BADNET);
     }
     strncpy(s, interfaces, sizeof(s));
-    while((interface = strsep(&next, SEPARATOR))) {
+    while ((interface = strsep(&next, SEPARATOR))) {
         if (!if_nametoindex(interface)) {
-            my_syslog(LOG_ERR,
-                    _("interface given in %s: '%s' has no ifindex; ignoring"),
-                    __FUNCTION__, interface);
+            my_syslog(LOG_ERR, _("interface given in %s: '%s' has no ifindex; ignoring"),
+                      __FUNCTION__, interface);
             continue;
         }
         if_tmp = safe_malloc(sizeof(struct iname));
@@ -953,26 +846,26 @@
 
     /* success! - setup to free the old */
     /* check for any that have been removed */
-    for (old_iface = prev_interfaces; old_iface; old_iface=old_iface->next) {
-      int found = 0;
-      for (new_iface = daemon->interfaces; new_iface; new_iface = new_iface->next) {
-        if (sockaddr_isequal(&old_iface->addr, &new_iface->addr)) {
-            found = 1;
-            break;
+    for (old_iface = prev_interfaces; old_iface; old_iface = old_iface->next) {
+        int found = 0;
+        for (new_iface = daemon->interfaces; new_iface; new_iface = new_iface->next) {
+            if (sockaddr_isequal(&old_iface->addr, &new_iface->addr)) {
+                found = 1;
+                break;
+            }
         }
-      }
 
-      if (found) {
-        fixup_possible_existing_listener(new_iface);
-      } else {
+        if (found) {
+            fixup_possible_existing_listener(new_iface);
+        } else {
 #ifdef __ANDROID_DEBUG__
-        char debug_buff[MAXDNAME];
-        prettyprint_addr(&old_iface->addr, debug_buff);
-        my_syslog(LOG_DEBUG, _("closing listener for %s"), debug_buff);
+            char debug_buff[MAXDNAME];
+            prettyprint_addr(&old_iface->addr, debug_buff);
+            my_syslog(LOG_DEBUG, _("closing listener for %s"), debug_buff);
 #endif
 
-        close_bound_listener(old_iface);
-      }
+            close_bound_listener(old_iface);
+        }
     }
 
     /* remove wildchar listeners */
@@ -981,37 +874,37 @@
 
     /* check for any that have been added */
     for (new_iface = daemon->interfaces; new_iface; new_iface = new_iface->next) {
-      int found = 0;
+        int found = 0;
 
-      /* if the previous setup used a wildchar, then add any current interfaces */
-      if (!was_wild) {
-        for (old_iface = prev_interfaces; old_iface; old_iface = old_iface->next) {
-          if(sockaddr_isequal(&old_iface->addr, &new_iface->addr)) {
-            found = -1;
-            break;
-          }
+        /* if the previous setup used a wildchar, then add any current interfaces */
+        if (!was_wild) {
+            for (old_iface = prev_interfaces; old_iface; old_iface = old_iface->next) {
+                if (sockaddr_isequal(&old_iface->addr, &new_iface->addr)) {
+                    found = -1;
+                    break;
+                }
+            }
         }
-      }
-      if (!found) {
+        if (!found) {
 #ifdef __ANDROID_DEBUG__
-        char debug_buff[MAXDNAME];
-        prettyprint_addr(&new_iface->addr, debug_buff);
-        my_syslog(LOG_DEBUG, _("adding listener for %s"), debug_buff);
+            char debug_buff[MAXDNAME];
+            prettyprint_addr(&new_iface->addr, debug_buff);
+            my_syslog(LOG_DEBUG, _("adding listener for %s"), debug_buff);
 #endif
-        create_bound_listener(&(daemon->listeners), new_iface);
-      }
+            create_bound_listener(&(daemon->listeners), new_iface);
+        }
     }
 
     while (prev_if_names) {
-      if (prev_if_names->name) free(prev_if_names->name);
-      if_tmp = prev_if_names->next;
-      free(prev_if_names);
-      prev_if_names = if_tmp;
+        if (prev_if_names->name) free(prev_if_names->name);
+        if_tmp = prev_if_names->next;
+        free(prev_if_names);
+        prev_if_names = if_tmp;
     }
     while (prev_interfaces) {
-      struct irec *tmp_irec = prev_interfaces->next;
-      free(prev_interfaces);
-      prev_interfaces = tmp_irec;
+        struct irec* tmp_irec = prev_interfaces->next;
+        free(prev_interfaces);
+        prev_interfaces = tmp_irec;
     }
 #ifdef __ANDROID_DEBUG__
     my_syslog(LOG_DEBUG, _("done with setInterfaces"));
@@ -1023,228 +916,202 @@
  *  - The first element is the socket mark to set on sockets that forward DNS queries.
  *  - The subsequent elements are the DNS servers to forward queries to.
  */
-int set_servers(const char *servers)
-{
-  char s[1024];
-  struct server *old_servers = NULL;
-  struct server *new_servers = NULL;
-  struct server *serv;
-  char *mark_string;
-  uint32_t mark;
+int set_servers(const char* servers) {
+    char s[1024];
+    struct server* old_servers = NULL;
+    struct server* new_servers = NULL;
+    struct server* serv;
+    char* mark_string;
+    uint32_t mark;
 
-  strncpy(s, servers, sizeof(s));
+    strncpy(s, servers, sizeof(s));
 
-  /* move old servers to free list - we can reuse the memory
-     and not risk malloc if there are the same or fewer new servers.
-     Servers which were specced on the command line go to the new list. */
-  for (serv = daemon->servers; serv;)
-    {
-      struct server *tmp = serv->next;
-      if (serv->flags & SERV_FROM_RESOLV)
-	{
-	  serv->next = old_servers;
-	  old_servers = serv;
-	  /* forward table rules reference servers, so have to blow them away */
-	  server_gone(serv);
-	}
-      else
-	{
-	  serv->next = new_servers;
-	  new_servers = serv;
-	}
-      serv = tmp;
+    /* move old servers to free list - we can reuse the memory
+       and not risk malloc if there are the same or fewer new servers.
+       Servers which were specced on the command line go to the new list. */
+    for (serv = daemon->servers; serv;) {
+        struct server* tmp = serv->next;
+        if (serv->flags & SERV_FROM_RESOLV) {
+            serv->next = old_servers;
+            old_servers = serv;
+            /* forward table rules reference servers, so have to blow them away */
+            server_gone(serv);
+        } else {
+            serv->next = new_servers;
+            new_servers = serv;
+        }
+        serv = tmp;
     }
 
-  char *next = s;
-  char *saddr;
+    char* next = s;
+    char* saddr;
 
-  /* Parse the mark. */
-  mark_string = strsep(&next, SEPARATOR);
-  mark = strtoul(mark_string, NULL, 0);
+    /* Parse the mark. */
+    mark_string = strsep(&next, SEPARATOR);
+    mark = strtoul(mark_string, NULL, 0);
 
-  while ((saddr = strsep(&next, SEPARATOR))) {
-      union mysockaddr addr, source_addr;
-      memset(&addr, 0, sizeof(addr));
-      memset(&source_addr, 0, sizeof(source_addr));
+    while ((saddr = strsep(&next, SEPARATOR))) {
+        union mysockaddr addr, source_addr;
+        memset(&addr, 0, sizeof(addr));
+        memset(&source_addr, 0, sizeof(source_addr));
 
-      if (parse_addr(AF_INET, saddr, &addr) == 0)
-	{
-	  addr.in.sin_port = htons(NAMESERVER_PORT);
-	  source_addr.in.sin_family = AF_INET;
-	  source_addr.in.sin_addr.s_addr = INADDR_ANY;
-	  source_addr.in.sin_port = htons(daemon->query_port);
-	}
+        if (parse_addr(AF_INET, saddr, &addr) == 0) {
+            addr.in.sin_port = htons(NAMESERVER_PORT);
+            source_addr.in.sin_family = AF_INET;
+            source_addr.in.sin_addr.s_addr = INADDR_ANY;
+            source_addr.in.sin_port = htons(daemon->query_port);
+        }
 #ifdef HAVE_IPV6
-      else if (parse_addr(AF_INET6, saddr, &addr) == 0)
-	{
-	  addr.in6.sin6_port = htons(NAMESERVER_PORT);
-	  source_addr.in6.sin6_family = AF_INET6;
-	  source_addr.in6.sin6_addr = in6addr_any;
-	  source_addr.in6.sin6_port = htons(daemon->query_port);
-	}
+        else if (parse_addr(AF_INET6, saddr, &addr) == 0) {
+            addr.in6.sin6_port = htons(NAMESERVER_PORT);
+            source_addr.in6.sin6_family = AF_INET6;
+            source_addr.in6.sin6_addr = in6addr_any;
+            source_addr.in6.sin6_port = htons(daemon->query_port);
+        }
 #endif /* IPV6 */
-      else
-	continue;
+        else
+            continue;
 
-      if (old_servers)
-	{
-	  serv = old_servers;
-	  old_servers = old_servers->next;
-	}
-      else if (!(serv = whine_malloc(sizeof (struct server))))
-	continue;
+        if (old_servers) {
+            serv = old_servers;
+            old_servers = old_servers->next;
+        } else if (!(serv = whine_malloc(sizeof(struct server))))
+            continue;
 
-      /* this list is reverse ordered:
-	 it gets reversed again in check_servers */
-      serv->next = new_servers;
-      new_servers = serv;
-      serv->addr = addr;
-      serv->source_addr = source_addr;
-      serv->domain = NULL;
-      serv->interface[0] = 0;
-      serv->mark = mark;
-      serv->sfd = NULL;
-      serv->flags = SERV_FROM_RESOLV;
-      serv->queries = serv->failed_queries = 0;
+        /* this list is reverse ordered:
+       it gets reversed again in check_servers */
+        serv->next = new_servers;
+        new_servers = serv;
+        serv->addr = addr;
+        serv->source_addr = source_addr;
+        serv->domain = NULL;
+        serv->interface[0] = 0;
+        serv->mark = mark;
+        serv->sfd = NULL;
+        serv->flags = SERV_FROM_RESOLV;
+        serv->queries = serv->failed_queries = 0;
     }
 
-  /* Free any memory not used. */
-  while (old_servers)
-    {
-      struct server *tmp = old_servers->next;
-      free(old_servers);
-      old_servers = tmp;
+    /* Free any memory not used. */
+    while (old_servers) {
+        struct server* tmp = old_servers->next;
+        free(old_servers);
+        old_servers = tmp;
     }
 
-  daemon->servers = new_servers;
-  return 0;
+    daemon->servers = new_servers;
+    return 0;
 }
 #endif
 
 /* Return zero if no servers found, in that case we keep polling.
    This is a protection against an update-time/write race on resolv.conf */
-int reload_servers(char *fname)
-{
-  FILE *f;
-  char *line;
-  struct server *old_servers = NULL;
-  struct server *new_servers = NULL;
-  struct server *serv;
-  int gotone = 0;
+int reload_servers(char* fname) {
+    FILE* f;
+    char* line;
+    struct server* old_servers = NULL;
+    struct server* new_servers = NULL;
+    struct server* serv;
+    int gotone = 0;
 
-  /* buff happens to be MAXDNAME long... */
-  if (!(f = fopen(fname, "r")))
-    {
-      my_syslog(LOG_ERR, _("failed to read %s: %s"), fname, strerror(errno));
-      return 0;
+    /* buff happens to be MAXDNAME long... */
+    if (!(f = fopen(fname, "r"))) {
+        my_syslog(LOG_ERR, _("failed to read %s: %s"), fname, strerror(errno));
+        return 0;
     }
-  
-  /* move old servers to free list - we can reuse the memory 
-     and not risk malloc if there are the same or fewer new servers. 
-     Servers which were specced on the command line go to the new list. */
-  for (serv = daemon->servers; serv;)
-    {
-      struct server *tmp = serv->next;
-      if (serv->flags & SERV_FROM_RESOLV)
-	{
-	  serv->next = old_servers;
-	  old_servers = serv; 
-	  /* forward table rules reference servers, so have to blow them away */
-	  server_gone(serv);
-	}
-      else
-	{
-	  serv->next = new_servers;
-	  new_servers = serv;
-	}
-      serv = tmp;
-    }
-  
-  while ((line = fgets(daemon->namebuff, MAXDNAME, f)))
-    {
-      union mysockaddr addr, source_addr;
-      char *token = strtok(line, " \t\n\r");
-      
-      if (!token)
-	continue;
-      if (strcmp(token, "nameserver") != 0 && strcmp(token, "server") != 0)
-	continue;
-      if (!(token = strtok(NULL, " \t\n\r")))
-	continue;
-      
-      memset(&addr, 0, sizeof(addr));
-      memset(&source_addr, 0, sizeof(source_addr));
 
-      if (parse_addr(AF_INET, token, &addr) == 0)
-	{
-	  addr.in.sin_port = htons(NAMESERVER_PORT);
-	  source_addr.in.sin_family = AF_INET;
-	  source_addr.in.sin_addr.s_addr = INADDR_ANY;
-	  source_addr.in.sin_port = htons(daemon->query_port);
-	}
+    /* move old servers to free list - we can reuse the memory
+       and not risk malloc if there are the same or fewer new servers.
+       Servers which were specced on the command line go to the new list. */
+    for (serv = daemon->servers; serv;) {
+        struct server* tmp = serv->next;
+        if (serv->flags & SERV_FROM_RESOLV) {
+            serv->next = old_servers;
+            old_servers = serv;
+            /* forward table rules reference servers, so have to blow them away */
+            server_gone(serv);
+        } else {
+            serv->next = new_servers;
+            new_servers = serv;
+        }
+        serv = tmp;
+    }
+
+    while ((line = fgets(daemon->namebuff, MAXDNAME, f))) {
+        union mysockaddr addr, source_addr;
+        char* token = strtok(line, " \t\n\r");
+
+        if (!token) continue;
+        if (strcmp(token, "nameserver") != 0 && strcmp(token, "server") != 0) continue;
+        if (!(token = strtok(NULL, " \t\n\r"))) continue;
+
+        memset(&addr, 0, sizeof(addr));
+        memset(&source_addr, 0, sizeof(source_addr));
+
+        if (parse_addr(AF_INET, token, &addr) == 0) {
+            addr.in.sin_port = htons(NAMESERVER_PORT);
+            source_addr.in.sin_family = AF_INET;
+            source_addr.in.sin_addr.s_addr = INADDR_ANY;
+            source_addr.in.sin_port = htons(daemon->query_port);
+        }
 #ifdef HAVE_IPV6
-      else if (parse_addr(AF_INET6, token, &addr) == 0)
-	{
-	  addr.in6.sin6_port = htons(NAMESERVER_PORT);
-	  source_addr.in6.sin6_family = AF_INET6;
-	  source_addr.in6.sin6_addr = in6addr_any;
-	  source_addr.in6.sin6_port = htons(daemon->query_port);
-	}
+        else if (parse_addr(AF_INET6, token, &addr) == 0) {
+            addr.in6.sin6_port = htons(NAMESERVER_PORT);
+            source_addr.in6.sin6_family = AF_INET6;
+            source_addr.in6.sin6_addr = in6addr_any;
+            source_addr.in6.sin6_port = htons(daemon->query_port);
+        }
 #endif /* IPV6 */
-      else
-	continue;
-      
-      if (old_servers)
-	{
-	  serv = old_servers;
-	  old_servers = old_servers->next;
-	}
-      else if (!(serv = whine_malloc(sizeof (struct server))))
-	continue;
-      
-      /* this list is reverse ordered: 
-	 it gets reversed again in check_servers */
-      serv->next = new_servers;
-      new_servers = serv;
-      serv->addr = addr;
-      serv->source_addr = source_addr;
-      serv->domain = NULL;
-      serv->interface[0] = 0;
-      serv->mark = 0;
-      serv->sfd = NULL;
-      serv->flags = SERV_FROM_RESOLV;
-      serv->queries = serv->failed_queries = 0;
-      gotone = 1;
-    }
-  
-  /* Free any memory not used. */
-  while (old_servers)
-    {
-      struct server *tmp = old_servers->next;
-      free(old_servers);
-      old_servers = tmp;
+        else
+            continue;
+
+        if (old_servers) {
+            serv = old_servers;
+            old_servers = old_servers->next;
+        } else if (!(serv = whine_malloc(sizeof(struct server))))
+            continue;
+
+        /* this list is reverse ordered:
+       it gets reversed again in check_servers */
+        serv->next = new_servers;
+        new_servers = serv;
+        serv->addr = addr;
+        serv->source_addr = source_addr;
+        serv->domain = NULL;
+        serv->interface[0] = 0;
+        serv->mark = 0;
+        serv->sfd = NULL;
+        serv->flags = SERV_FROM_RESOLV;
+        serv->queries = serv->failed_queries = 0;
+        gotone = 1;
     }
 
-  daemon->servers = new_servers;
-  fclose(f);
+    /* Free any memory not used. */
+    while (old_servers) {
+        struct server* tmp = old_servers->next;
+        free(old_servers);
+        old_servers = tmp;
+    }
 
-  return gotone;
+    daemon->servers = new_servers;
+    fclose(f);
+
+    return gotone;
 }
 
-
 /* Use an IPv4 listener socket for ioctling */
-struct in_addr get_ifaddr(char *intr)
-{
-  struct listener *l;
-  struct ifreq ifr;
+struct in_addr get_ifaddr(char* intr) {
+    struct listener* l;
+    struct ifreq ifr;
 
-  for (l = daemon->listeners; l && l->family != AF_INET; l = l->next);
-  
-  strncpy(ifr.ifr_name, intr, IF_NAMESIZE);
-  ifr.ifr_addr.sa_family = AF_INET;
-  
-  if (!l || ioctl(l->fd, SIOCGIFADDR, &ifr) == -1)
-    ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = -1;
-  
-  return ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
+    for (l = daemon->listeners; l && l->family != AF_INET; l = l->next)
+        ;
+
+    strncpy(ifr.ifr_name, intr, IF_NAMESIZE);
+    ifr.ifr_addr.sa_family = AF_INET;
+
+    if (!l || ioctl(l->fd, SIOCGIFADDR, &ifr) == -1)
+        ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr = -1;
+
+    return ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr;
 }
diff --git a/src/option.c b/src/option.c
index 09814d9..fbb10db 100644
--- a/src/option.c
+++ b/src/option.c
@@ -4,301 +4,360 @@
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; version 2 dated June, 1991, or
    (at your option) version 3 dated 29 June, 2007.
- 
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-     
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 /* define this to get facilitynames */
 #define SYSLOG_NAMES
-#include "dnsmasq.h"
 #include <setjmp.h>
+#include "dnsmasq.h"
 
 static volatile int mem_recover = 0;
 static jmp_buf mem_jmp;
-static void one_file(char *file, int nest, int hard_opt);
+static void one_file(char* file, int nest, int hard_opt);
 
 #ifndef HAVE_GETOPT_LONG
 struct myoption {
-  const char *name;
-  int has_arg;
-  int *flag;
-  int val;
+    const char* name;
+    int has_arg;
+    int* flag;
+    int val;
 };
 #endif
 
-#define OPTSTRING "951yZDNLERKzowefnbvhdkqr:m:p:c:l:s:i:t:u:g:a:x:S:C:A:T:H:Q:I:B:F:G:O:M:X:V:U:j:P:J:W:Y:2:4:6:7:8:0:3:"
+#define OPTSTRING                                                                                 \
+    "951yZDNLERKzowefnbvhdkqr:m:p:c:l:s:i:t:u:g:a:x:S:C:A:T:H:Q:I:B:F:G:O:M:X:V:U:j:P:J:W:Y:2:4:" \
+    "6:7:8:0:3:"
 
 /* options which don't have a one-char version */
-#define LOPT_RELOAD    256
-#define LOPT_NO_NAMES  257
-#define LOPT_TFTP      258
-#define LOPT_SECURE    259
-#define LOPT_PREFIX    260
-#define LOPT_PTR       261
-#define LOPT_BRIDGE    262
-#define LOPT_TFTP_MAX  263
-#define LOPT_FORCE     264
-#define LOPT_NOBLOCK   265
-#define LOPT_LOG_OPTS  266
-#define LOPT_MAX_LOGS  267
-#define LOPT_CIRCUIT   268
-#define LOPT_REMOTE    269
-#define LOPT_SUBSCR    270
-#define LOPT_INTNAME   271
-#define LOPT_BANK      272
+#define LOPT_RELOAD 256
+#define LOPT_NO_NAMES 257
+#define LOPT_TFTP 258
+#define LOPT_SECURE 259
+#define LOPT_PREFIX 260
+#define LOPT_PTR 261
+#define LOPT_BRIDGE 262
+#define LOPT_TFTP_MAX 263
+#define LOPT_FORCE 264
+#define LOPT_NOBLOCK 265
+#define LOPT_LOG_OPTS 266
+#define LOPT_MAX_LOGS 267
+#define LOPT_CIRCUIT 268
+#define LOPT_REMOTE 269
+#define LOPT_SUBSCR 270
+#define LOPT_INTNAME 271
+#define LOPT_BANK 272
 #define LOPT_DHCP_HOST 273
-#define LOPT_APREF     274
-#define LOPT_OVERRIDE  275
+#define LOPT_APREF 274
+#define LOPT_OVERRIDE 275
 #define LOPT_TFTPPORTS 276
-#define LOPT_REBIND    277
-#define LOPT_NOLAST    278
-#define LOPT_OPTS      279
+#define LOPT_REBIND 277
+#define LOPT_NOLAST 278
+#define LOPT_OPTS 279
 #define LOPT_DHCP_OPTS 280
-#define LOPT_MATCH     281
+#define LOPT_MATCH 281
 #define LOPT_BROADCAST 282
-#define LOPT_NEGTTL    283
-#define LOPT_ALTPORT   284
+#define LOPT_NEGTTL 283
+#define LOPT_ALTPORT 284
 #define LOPT_SCRIPTUSR 285
-#define LOPT_LOCAL     286
-#define LOPT_NAPTR     287
-#define LOPT_MINPORT   288
+#define LOPT_LOCAL 286
+#define LOPT_NAPTR 287
+#define LOPT_MINPORT 288
 #define LOPT_DHCP_FQDN 289
-#define LOPT_CNAME     290
+#define LOPT_CNAME 290
 #define LOPT_PXE_PROMT 291
-#define LOPT_PXE_SERV  292
-#define LOPT_TEST      293
+#define LOPT_PXE_SERV 292
+#define LOPT_TEST 293
 #define LOPT_LISTNMARK 294
 
 #ifdef HAVE_GETOPT_LONG
-static const struct option opts[] =  
+static const struct option opts[] =
 #else
-static const struct myoption opts[] = 
+static const struct myoption opts[] =
 #endif
-  { 
-    { "version", 0, 0, 'v' },
-    { "no-hosts", 0, 0, 'h' },
-    { "no-poll", 0, 0, 'n' },
-    { "help", 0, 0, 'w' },
-    { "no-daemon", 0, 0, 'd' },
-    { "log-queries", 0, 0, 'q' },
-    { "user", 1, 0, 'u' },
-    { "group", 2, 0, 'g' },
-    { "resolv-file", 2, 0, 'r' },
-    { "mx-host", 1, 0, 'm' },
-    { "mx-target", 1, 0, 't' },
-    { "cache-size", 2, 0, 'c' },
-    { "port", 1, 0, 'p' },
-    { "dhcp-leasefile", 2, 0, 'l' },
-    { "dhcp-lease", 1, 0, 'l' },
-    { "dhcp-host", 1, 0, 'G' },
-    { "dhcp-range", 1, 0, 'F' },
-    { "dhcp-option", 1, 0, 'O' },
-    { "dhcp-boot", 1, 0, 'M' },
-    { "domain", 1, 0, 's' },
-    { "domain-suffix", 1, 0, 's' },
-    { "interface", 1, 0, 'i' },
-    { "listen-address", 1, 0, 'a' },
-    { "bogus-priv", 0, 0, 'b' },
-    { "bogus-nxdomain", 1, 0, 'B' },
-    { "selfmx", 0, 0, 'e' },
-    { "filterwin2k", 0, 0, 'f' },
-    { "pid-file", 2, 0, 'x' },
-    { "strict-order", 0, 0, 'o' },
-    { "server", 1, 0, 'S' },
-    { "local", 1, 0, LOPT_LOCAL },
-    { "address", 1, 0, 'A' },
-    { "conf-file", 2, 0, 'C' },
-    { "no-resolv", 0, 0, 'R' },
-    { "expand-hosts", 0, 0, 'E' },
-    { "localmx", 0, 0, 'L' },
-    { "local-ttl", 1, 0, 'T' },
-    { "no-negcache", 0, 0, 'N' },
-    { "addn-hosts", 1, 0, 'H' },
-    { "query-port", 1, 0, 'Q' },
-    { "except-interface", 1, 0, 'I' },
-    { "no-dhcp-interface", 1, 0, '2' },
-    { "domain-needed", 0, 0, 'D' },
-    { "dhcp-lease-max", 1, 0, 'X' },
-    { "bind-interfaces", 0, 0, 'z' },
-    { "alias", 1, 0, 'V' },
-    { "dhcp-vendorclass", 1, 0, 'U' },
-    { "dhcp-userclass", 1, 0, 'j' },
-    { "dhcp-ignore", 1, 0, 'J' },
-    { "edns-packet-max", 1, 0, 'P' },
-    { "keep-in-foreground", 0, 0, 'k' },
-    { "dhcp-authoritative", 0, 0, 'K' },
-    { "srv-host", 1, 0, 'W' },
-    { "localise-queries", 0, 0, 'y' },
-    { "txt-record", 1, 0, 'Y' },
-    { "enable-dbus", 0, 0, '1' },
-    { "bootp-dynamic", 2, 0, '3' },
-    { "dhcp-mac", 1, 0, '4' },
-    { "no-ping", 0, 0, '5' },
-    { "dhcp-script", 1, 0, '6' },
-    { "conf-dir", 1, 0, '7' },
-    { "log-facility", 1, 0 ,'8' },
-    { "leasefile-ro", 0, 0, '9' },
-    { "dns-forward-max", 1, 0, '0' },
-    { "clear-on-reload", 0, 0, LOPT_RELOAD },
-    { "dhcp-ignore-names", 2, 0, LOPT_NO_NAMES },
-    { "enable-tftp", 0, 0, LOPT_TFTP },
-    { "tftp-secure", 0, 0, LOPT_SECURE },
-    { "tftp-unique-root", 0, 0, LOPT_APREF },
-    { "tftp-root", 1, 0, LOPT_PREFIX },
-    { "tftp-max", 1, 0, LOPT_TFTP_MAX },
-    { "ptr-record", 1, 0, LOPT_PTR },
-    { "naptr-record", 1, 0, LOPT_NAPTR },
-    { "bridge-interface", 1, 0 , LOPT_BRIDGE },
-    { "dhcp-option-force", 1, 0, LOPT_FORCE },
-    { "tftp-no-blocksize", 0, 0, LOPT_NOBLOCK },
-    { "log-dhcp", 0, 0, LOPT_LOG_OPTS },
-    { "log-async", 2, 0, LOPT_MAX_LOGS },
-    { "dhcp-circuitid", 1, 0, LOPT_CIRCUIT },
-    { "dhcp-remoteid", 1, 0, LOPT_REMOTE },
-    { "dhcp-subscrid", 1, 0, LOPT_SUBSCR },
-    { "interface-name", 1, 0, LOPT_INTNAME },
-    { "dhcp-hostsfile", 1, 0, LOPT_DHCP_HOST },
-    { "dhcp-optsfile", 1, 0, LOPT_DHCP_OPTS },
-    { "dhcp-no-override", 0, 0, LOPT_OVERRIDE },
-    { "tftp-port-range", 1, 0, LOPT_TFTPPORTS },
-    { "stop-dns-rebind", 0, 0, LOPT_REBIND },
-    { "all-servers", 0, 0, LOPT_NOLAST }, 
-    { "dhcp-match", 1, 0, LOPT_MATCH }, 
-    { "dhcp-broadcast", 1, 0, LOPT_BROADCAST },
-    { "neg-ttl", 1, 0, LOPT_NEGTTL },
-    { "dhcp-alternate-port", 2, 0, LOPT_ALTPORT },
-    { "dhcp-scriptuser", 1, 0, LOPT_SCRIPTUSR },
-    { "min-port", 1, 0, LOPT_MINPORT },
-    { "dhcp-fqdn", 0, 0, LOPT_DHCP_FQDN },
-    { "cname", 1, 0, LOPT_CNAME },
-    { "pxe-prompt", 1, 0, LOPT_PXE_PROMT },
-    { "pxe-service", 1, 0, LOPT_PXE_SERV },
+    {{"version", 0, 0, 'v'},
+     {"no-hosts", 0, 0, 'h'},
+     {"no-poll", 0, 0, 'n'},
+     {"help", 0, 0, 'w'},
+     {"no-daemon", 0, 0, 'd'},
+     {"log-queries", 0, 0, 'q'},
+     {"user", 1, 0, 'u'},
+     {"group", 2, 0, 'g'},
+     {"resolv-file", 2, 0, 'r'},
+     {"mx-host", 1, 0, 'm'},
+     {"mx-target", 1, 0, 't'},
+     {"cache-size", 2, 0, 'c'},
+     {"port", 1, 0, 'p'},
+     {"dhcp-leasefile", 2, 0, 'l'},
+     {"dhcp-lease", 1, 0, 'l'},
+     {"dhcp-host", 1, 0, 'G'},
+     {"dhcp-range", 1, 0, 'F'},
+     {"dhcp-option", 1, 0, 'O'},
+     {"dhcp-boot", 1, 0, 'M'},
+     {"domain", 1, 0, 's'},
+     {"domain-suffix", 1, 0, 's'},
+     {"interface", 1, 0, 'i'},
+     {"listen-address", 1, 0, 'a'},
+     {"bogus-priv", 0, 0, 'b'},
+     {"bogus-nxdomain", 1, 0, 'B'},
+     {"selfmx", 0, 0, 'e'},
+     {"filterwin2k", 0, 0, 'f'},
+     {"pid-file", 2, 0, 'x'},
+     {"strict-order", 0, 0, 'o'},
+     {"server", 1, 0, 'S'},
+     {"local", 1, 0, LOPT_LOCAL},
+     {"address", 1, 0, 'A'},
+     {"conf-file", 2, 0, 'C'},
+     {"no-resolv", 0, 0, 'R'},
+     {"expand-hosts", 0, 0, 'E'},
+     {"localmx", 0, 0, 'L'},
+     {"local-ttl", 1, 0, 'T'},
+     {"no-negcache", 0, 0, 'N'},
+     {"addn-hosts", 1, 0, 'H'},
+     {"query-port", 1, 0, 'Q'},
+     {"except-interface", 1, 0, 'I'},
+     {"no-dhcp-interface", 1, 0, '2'},
+     {"domain-needed", 0, 0, 'D'},
+     {"dhcp-lease-max", 1, 0, 'X'},
+     {"bind-interfaces", 0, 0, 'z'},
+     {"alias", 1, 0, 'V'},
+     {"dhcp-vendorclass", 1, 0, 'U'},
+     {"dhcp-userclass", 1, 0, 'j'},
+     {"dhcp-ignore", 1, 0, 'J'},
+     {"edns-packet-max", 1, 0, 'P'},
+     {"keep-in-foreground", 0, 0, 'k'},
+     {"dhcp-authoritative", 0, 0, 'K'},
+     {"srv-host", 1, 0, 'W'},
+     {"localise-queries", 0, 0, 'y'},
+     {"txt-record", 1, 0, 'Y'},
+     {"enable-dbus", 0, 0, '1'},
+     {"bootp-dynamic", 2, 0, '3'},
+     {"dhcp-mac", 1, 0, '4'},
+     {"no-ping", 0, 0, '5'},
+     {"dhcp-script", 1, 0, '6'},
+     {"conf-dir", 1, 0, '7'},
+     {"log-facility", 1, 0, '8'},
+     {"leasefile-ro", 0, 0, '9'},
+     {"dns-forward-max", 1, 0, '0'},
+     {"clear-on-reload", 0, 0, LOPT_RELOAD},
+     {"dhcp-ignore-names", 2, 0, LOPT_NO_NAMES},
+     {"enable-tftp", 0, 0, LOPT_TFTP},
+     {"tftp-secure", 0, 0, LOPT_SECURE},
+     {"tftp-unique-root", 0, 0, LOPT_APREF},
+     {"tftp-root", 1, 0, LOPT_PREFIX},
+     {"tftp-max", 1, 0, LOPT_TFTP_MAX},
+     {"ptr-record", 1, 0, LOPT_PTR},
+     {"naptr-record", 1, 0, LOPT_NAPTR},
+     {"bridge-interface", 1, 0, LOPT_BRIDGE},
+     {"dhcp-option-force", 1, 0, LOPT_FORCE},
+     {"tftp-no-blocksize", 0, 0, LOPT_NOBLOCK},
+     {"log-dhcp", 0, 0, LOPT_LOG_OPTS},
+     {"log-async", 2, 0, LOPT_MAX_LOGS},
+     {"dhcp-circuitid", 1, 0, LOPT_CIRCUIT},
+     {"dhcp-remoteid", 1, 0, LOPT_REMOTE},
+     {"dhcp-subscrid", 1, 0, LOPT_SUBSCR},
+     {"interface-name", 1, 0, LOPT_INTNAME},
+     {"dhcp-hostsfile", 1, 0, LOPT_DHCP_HOST},
+     {"dhcp-optsfile", 1, 0, LOPT_DHCP_OPTS},
+     {"dhcp-no-override", 0, 0, LOPT_OVERRIDE},
+     {"tftp-port-range", 1, 0, LOPT_TFTPPORTS},
+     {"stop-dns-rebind", 0, 0, LOPT_REBIND},
+     {"all-servers", 0, 0, LOPT_NOLAST},
+     {"dhcp-match", 1, 0, LOPT_MATCH},
+     {"dhcp-broadcast", 1, 0, LOPT_BROADCAST},
+     {"neg-ttl", 1, 0, LOPT_NEGTTL},
+     {"dhcp-alternate-port", 2, 0, LOPT_ALTPORT},
+     {"dhcp-scriptuser", 1, 0, LOPT_SCRIPTUSR},
+     {"min-port", 1, 0, LOPT_MINPORT},
+     {"dhcp-fqdn", 0, 0, LOPT_DHCP_FQDN},
+     {"cname", 1, 0, LOPT_CNAME},
+     {"pxe-prompt", 1, 0, LOPT_PXE_PROMT},
+     {"pxe-service", 1, 0, LOPT_PXE_SERV},
 #ifdef __ANDROID__
-    { "listen-mark", 1, 0, LOPT_LISTNMARK },
+     {"listen-mark", 1, 0, LOPT_LISTNMARK},
 #endif /* __ANDROID__ */
-    { "test", 0, 0, LOPT_TEST },
-    { NULL, 0, 0, 0 }
-  };
+     {"test", 0, 0, LOPT_TEST},
+     {NULL, 0, 0, 0}};
 
 /* These must have more the one '1' bit */
-#define ARG_DUP       3
-#define ARG_ONE       5
-#define ARG_USED_CL   7
+#define ARG_DUP 3
+#define ARG_ONE 5
+#define ARG_USED_CL 7
 #define ARG_USED_FILE 9
 
 static struct {
-  int opt;
-  unsigned int rept;
-  char * const flagdesc;
-  char * const desc;
-  char * const arg;
+    int opt;
+    unsigned int rept;
+    char* const flagdesc;
+    char* const desc;
+    char* const arg;
 } usage[] = {
-  { 'a', ARG_DUP, "ipaddr",  gettext_noop("Specify local address(es) to listen on."), NULL },
-  { 'A', ARG_DUP, "/domain/ipaddr", gettext_noop("Return ipaddr for all hosts in specified domains."), NULL },
-  { 'b', OPT_BOGUSPRIV, NULL, gettext_noop("Fake reverse lookups for RFC1918 private address ranges."), NULL },
-  { 'B', ARG_DUP, "ipaddr", gettext_noop("Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."), NULL }, 
-  { 'c', ARG_ONE, "cachesize", gettext_noop("Specify the size of the cache in entries (defaults to %s)."), "$" },
-  { 'C', ARG_DUP, "path", gettext_noop("Specify configuration file (defaults to %s)."), CONFFILE },
-  { 'd', OPT_DEBUG, NULL, gettext_noop("Do NOT fork into the background: run in debug mode."), NULL },
-  { 'D', OPT_NODOTS_LOCAL, NULL, gettext_noop("Do NOT forward queries with no domain part."), NULL }, 
-  { 'e', OPT_SELFMX, NULL, gettext_noop("Return self-pointing MX records for local hosts."), NULL },
-  { 'E', OPT_EXPAND, NULL, gettext_noop("Expand simple names in /etc/hosts with domain-suffix."), NULL },
-  { 'f', OPT_FILTER, NULL, gettext_noop("Don't forward spurious DNS requests from Windows hosts."), NULL },
-  { 'F', ARG_DUP, "ipaddr,ipaddr,time", gettext_noop("Enable DHCP in the range given with lease duration."), NULL },
-  { 'g', ARG_ONE, "groupname", gettext_noop("Change to this group after startup (defaults to %s)."), CHGRP },
-  { 'G', ARG_DUP, "<hostspec>", gettext_noop("Set address or hostname for a specified machine."), NULL },
-  { LOPT_DHCP_HOST, ARG_ONE, "<filename>", gettext_noop("Read DHCP host specs from file"), NULL },
-  { LOPT_DHCP_OPTS, ARG_ONE, "<filename>", gettext_noop("Read DHCP option specs from file"), NULL },
-  { 'h', OPT_NO_HOSTS, NULL, gettext_noop("Do NOT load %s file."), HOSTSFILE },
-  { 'H', ARG_DUP, "path", gettext_noop("Specify a hosts file to be read in addition to %s."), HOSTSFILE },
-  { 'i', ARG_DUP, "interface", gettext_noop("Specify interface(s) to listen on."), NULL },
-  { 'I', ARG_DUP, "int", gettext_noop("Specify interface(s) NOT to listen on.") , NULL },
-  { 'j', ARG_DUP, "<tag>,<class>", gettext_noop("Map DHCP user class to tag."), NULL },
-  { LOPT_CIRCUIT, ARG_DUP, "<tag>,<circuit>", gettext_noop("Map RFC3046 circuit-id to tag."), NULL },
-  { LOPT_REMOTE, ARG_DUP, "<tag>,<remote>", gettext_noop("Map RFC3046 remote-id to tag."), NULL },
-  { LOPT_SUBSCR, ARG_DUP, "<tag>,<remote>", gettext_noop("Map RFC3993 subscriber-id to tag."), NULL },
-  { 'J', ARG_DUP, "=<id>[,<id>]", gettext_noop("Don't do DHCP for hosts with tag set."), NULL },
-  { LOPT_BROADCAST, ARG_DUP, "=<id>[,<id>]", gettext_noop("Force broadcast replies for hosts with tag set."), NULL }, 
-  { 'k', OPT_NO_FORK, NULL, gettext_noop("Do NOT fork into the background, do NOT run in debug mode."), NULL },
-  { 'K', OPT_AUTHORITATIVE, NULL, gettext_noop("Assume we are the only DHCP server on the local network."), NULL },
-  { 'l', ARG_ONE, "path", gettext_noop("Specify where to store DHCP leases (defaults to %s)."), LEASEFILE },
-  { 'L', OPT_LOCALMX, NULL, gettext_noop("Return MX records for local hosts."), NULL },
-  { 'm', ARG_DUP, "host_name,target,pref", gettext_noop("Specify an MX record."), NULL },
-  { 'M', ARG_DUP, "<bootp opts>", gettext_noop("Specify BOOTP options to DHCP server."), NULL },
-  { 'n', OPT_NO_POLL, NULL, gettext_noop("Do NOT poll %s file, reload only on SIGHUP."), RESOLVFILE }, 
-  { 'N', OPT_NO_NEG, NULL, gettext_noop("Do NOT cache failed search results."), NULL },
-  { 'o', OPT_ORDER, NULL, gettext_noop("Use nameservers strictly in the order given in %s."), RESOLVFILE },
-  { 'O', ARG_DUP, "<optspec>", gettext_noop("Specify options to be sent to DHCP clients."), NULL },
-  { LOPT_FORCE, ARG_DUP, "<optspec>", gettext_noop("DHCP option sent even if the client does not request it."), NULL},
-  { 'p', ARG_ONE, "number", gettext_noop("Specify port to listen for DNS requests on (defaults to 53)."), NULL },
-  { 'P', ARG_ONE, "<size>", gettext_noop("Maximum supported UDP packet size for EDNS.0 (defaults to %s)."), "*" },
-  { 'q', OPT_LOG, NULL, gettext_noop("Log DNS queries."), NULL },
-  { 'Q', ARG_ONE, "number", gettext_noop("Force the originating port for upstream DNS queries."), NULL },
-  { 'R', OPT_NO_RESOLV, NULL, gettext_noop("Do NOT read resolv.conf."), NULL },
-  { 'r', ARG_DUP, "path", gettext_noop("Specify path to resolv.conf (defaults to %s)."), RESOLVFILE }, 
-  { 'S', ARG_DUP, "/domain/ipaddr", gettext_noop("Specify address(es) of upstream servers with optional domains."), NULL },
-  { LOPT_LOCAL, ARG_DUP, "/domain/", gettext_noop("Never forward queries to specified domains."), NULL },
-  { 's', ARG_DUP, "<domain>[,<range>]", gettext_noop("Specify the domain to be assigned in DHCP leases."), NULL },
-  { 't', ARG_ONE, "host_name", gettext_noop("Specify default target in an MX record."), NULL },
-  { 'T', ARG_ONE, "time", gettext_noop("Specify time-to-live in seconds for replies from /etc/hosts."), NULL },
-  { LOPT_NEGTTL, ARG_ONE, "time", gettext_noop("Specify time-to-live in seconds for negative caching."), NULL },
-  { 'u', ARG_ONE, "username", gettext_noop("Change to this user after startup. (defaults to %s)."), CHUSER }, 
-  { 'U', ARG_DUP, "<id>,<class>", gettext_noop("Map DHCP vendor class to tag."), NULL },
-  { 'v', 0, NULL, gettext_noop("Display dnsmasq version and copyright information."), NULL },
-  { 'V', ARG_DUP, "addr,addr,mask", gettext_noop("Translate IPv4 addresses from upstream servers."), NULL },
-  { 'W', ARG_DUP, "name,target,...", gettext_noop("Specify a SRV record."), NULL },
-  { 'w', 0, NULL, gettext_noop("Display this message. Use --help dhcp for known DHCP options."), NULL },
-  { 'x', ARG_ONE, "path", gettext_noop("Specify path of PID file (defaults to %s)."), RUNFILE },
-  { 'X', ARG_ONE, "number", gettext_noop("Specify maximum number of DHCP leases (defaults to %s)."), "&" },
-  { 'y', OPT_LOCALISE, NULL, gettext_noop("Answer DNS queries based on the interface a query was sent to."), NULL },
-  { 'Y', ARG_DUP, "name,txt....", gettext_noop("Specify TXT DNS record."), NULL },
-  { LOPT_PTR, ARG_DUP, "name,target", gettext_noop("Specify PTR DNS record."), NULL },
-  { LOPT_INTNAME, ARG_DUP, "name,interface", gettext_noop("Give DNS name to IPv4 address of interface."), NULL },
-  { 'z', OPT_NOWILD, NULL, gettext_noop("Bind only to interfaces in use."), NULL },
-  { '1', OPT_DBUS, NULL, gettext_noop("Enable the DBus interface for setting upstream servers, etc."), NULL },
-  { '2', ARG_DUP, "interface", gettext_noop("Do not provide DHCP on this interface, only provide DNS."), NULL },
-  { '3', ARG_DUP, "[=<id>[,<id>]]", gettext_noop("Enable dynamic address allocation for bootp."), NULL },
-  { '4', ARG_DUP, "<id>,<mac address>", gettext_noop("Map MAC address (with wildcards) to option set."), NULL },
-  { LOPT_BRIDGE, ARG_DUP, "iface,alias,..", gettext_noop("Treat DHCP requests on aliases as arriving from interface."), NULL },
-  { '5', OPT_NO_PING, NULL, gettext_noop("Disable ICMP echo address checking in the DHCP server."), NULL },
-  { '6', ARG_ONE, "path", gettext_noop("Script to run on DHCP lease creation and destruction."), NULL },
-  { '7', ARG_DUP, "path", gettext_noop("Read configuration from all the files in this directory."), NULL },
-  { '8', ARG_ONE, "<facilty>|<file>", gettext_noop("Log to this syslog facility or file. (defaults to DAEMON)"), NULL },
-  { '9', OPT_LEASE_RO, NULL, gettext_noop("Do not use leasefile."), NULL },
-  { '0', ARG_ONE, "<queries>", gettext_noop("Maximum number of concurrent DNS queries. (defaults to %s)"), "!" }, 
-  { LOPT_RELOAD, OPT_RELOAD, NULL, gettext_noop("Clear DNS cache when reloading %s."), RESOLVFILE },
-  { LOPT_NO_NAMES, ARG_DUP, "[=<id>[,<id>]]", gettext_noop("Ignore hostnames provided by DHCP clients."), NULL },
-  { LOPT_OVERRIDE, OPT_NO_OVERRIDE, NULL, gettext_noop("Do NOT reuse filename and server fields for extra DHCP options."), NULL },
-  { LOPT_TFTP, OPT_TFTP, NULL, gettext_noop("Enable integrated read-only TFTP server."), NULL },
-  { LOPT_PREFIX, ARG_ONE, "<directory>", gettext_noop("Export files by TFTP only from the specified subtree."), NULL },
-  { LOPT_APREF, OPT_TFTP_APREF, NULL, gettext_noop("Add client IP address to tftp-root."), NULL },
-  { LOPT_SECURE, OPT_TFTP_SECURE, NULL, gettext_noop("Allow access only to files owned by the user running dnsmasq."), NULL },
-  { LOPT_TFTP_MAX, ARG_ONE, "<connections>", gettext_noop("Maximum number of conncurrent TFTP transfers (defaults to %s)."), "#" },
-  { LOPT_NOBLOCK, OPT_TFTP_NOBLOCK, NULL, gettext_noop("Disable the TFTP blocksize extension."), NULL },
-  { LOPT_TFTPPORTS, ARG_ONE, "<start>,<end>", gettext_noop("Ephemeral port range for use by TFTP transfers."), NULL },
-  { LOPT_LOG_OPTS, OPT_LOG_OPTS, NULL, gettext_noop("Extra logging for DHCP."), NULL },
-  { LOPT_MAX_LOGS, ARG_ONE, "[=<log lines>]", gettext_noop("Enable async. logging; optionally set queue length."), NULL },
-  { LOPT_REBIND, OPT_NO_REBIND, NULL, gettext_noop("Stop DNS rebinding. Filter private IP ranges when resolving."), NULL },
-  { LOPT_NOLAST, OPT_ALL_SERVERS, NULL, gettext_noop("Always perform DNS queries to all servers."), NULL },
-  { LOPT_MATCH, ARG_DUP, "<netid>,<optspec>", gettext_noop("Set tag if client includes matching option in request."), NULL },
-  { LOPT_ALTPORT, ARG_ONE, "[=<ports>]", gettext_noop("Use alternative ports for DHCP."), NULL },
-  { LOPT_SCRIPTUSR, ARG_ONE, "<username>", gettext_noop("Run lease-change script as this user."), NULL },
-  { LOPT_NAPTR, ARG_DUP, "<name>,<naptr>", gettext_noop("Specify NAPTR DNS record."), NULL },
-  { LOPT_MINPORT, ARG_ONE, "<port>", gettext_noop("Specify lowest port available for DNS query transmission."), NULL },
-  { LOPT_DHCP_FQDN, OPT_DHCP_FQDN, NULL, gettext_noop("Use only fully qualified domain names for DHCP clients."), NULL },
-  { LOPT_CNAME, ARG_DUP, "<alias>,<target>", gettext_noop("Specify alias name for LOCAL DNS name."), NULL },
-  { LOPT_PXE_PROMT, ARG_DUP, "<prompt>,[<timeout>]", gettext_noop("Prompt to send to PXE clients."), NULL },
-  { LOPT_PXE_SERV, ARG_DUP, "<service>", gettext_noop("Boot service for PXE menu."), NULL },
-  { LOPT_LISTNMARK, ARG_ONE, NULL, gettext_noop("Socket mark to use for listen sockets."), NULL },
-  { LOPT_TEST, 0, NULL, gettext_noop("Check configuration syntax."), NULL },
-  { 0, 0, NULL, NULL, NULL }
-}; 
+    {'a', ARG_DUP, "ipaddr", gettext_noop("Specify local address(es) to listen on."), NULL},
+    {'A', ARG_DUP, "/domain/ipaddr",
+     gettext_noop("Return ipaddr for all hosts in specified domains."), NULL},
+    {'b', OPT_BOGUSPRIV, NULL,
+     gettext_noop("Fake reverse lookups for RFC1918 private address ranges."), NULL},
+    {'B', ARG_DUP, "ipaddr", gettext_noop("Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."),
+     NULL},
+    {'c', ARG_ONE, "cachesize",
+     gettext_noop("Specify the size of the cache in entries (defaults to %s)."), "$"},
+    {'C', ARG_DUP, "path", gettext_noop("Specify configuration file (defaults to %s)."), CONFFILE},
+    {'d', OPT_DEBUG, NULL, gettext_noop("Do NOT fork into the background: run in debug mode."),
+     NULL},
+    {'D', OPT_NODOTS_LOCAL, NULL, gettext_noop("Do NOT forward queries with no domain part."), NULL},
+    {'e', OPT_SELFMX, NULL, gettext_noop("Return self-pointing MX records for local hosts."), NULL},
+    {'E', OPT_EXPAND, NULL, gettext_noop("Expand simple names in /etc/hosts with domain-suffix."),
+     NULL},
+    {'f', OPT_FILTER, NULL, gettext_noop("Don't forward spurious DNS requests from Windows hosts."),
+     NULL},
+    {'F', ARG_DUP, "ipaddr,ipaddr,time",
+     gettext_noop("Enable DHCP in the range given with lease duration."), NULL},
+    {'g', ARG_ONE, "groupname",
+     gettext_noop("Change to this group after startup (defaults to %s)."), CHGRP},
+    {'G', ARG_DUP, "<hostspec>", gettext_noop("Set address or hostname for a specified machine."),
+     NULL},
+    {LOPT_DHCP_HOST, ARG_ONE, "<filename>", gettext_noop("Read DHCP host specs from file"), NULL},
+    {LOPT_DHCP_OPTS, ARG_ONE, "<filename>", gettext_noop("Read DHCP option specs from file"), NULL},
+    {'h', OPT_NO_HOSTS, NULL, gettext_noop("Do NOT load %s file."), HOSTSFILE},
+    {'H', ARG_DUP, "path", gettext_noop("Specify a hosts file to be read in addition to %s."),
+     HOSTSFILE},
+    {'i', ARG_DUP, "interface", gettext_noop("Specify interface(s) to listen on."), NULL},
+    {'I', ARG_DUP, "int", gettext_noop("Specify interface(s) NOT to listen on."), NULL},
+    {'j', ARG_DUP, "<tag>,<class>", gettext_noop("Map DHCP user class to tag."), NULL},
+    {LOPT_CIRCUIT, ARG_DUP, "<tag>,<circuit>", gettext_noop("Map RFC3046 circuit-id to tag."), NULL},
+    {LOPT_REMOTE, ARG_DUP, "<tag>,<remote>", gettext_noop("Map RFC3046 remote-id to tag."), NULL},
+    {LOPT_SUBSCR, ARG_DUP, "<tag>,<remote>", gettext_noop("Map RFC3993 subscriber-id to tag."),
+     NULL},
+    {'J', ARG_DUP, "=<id>[,<id>]", gettext_noop("Don't do DHCP for hosts with tag set."), NULL},
+    {LOPT_BROADCAST, ARG_DUP, "=<id>[,<id>]",
+     gettext_noop("Force broadcast replies for hosts with tag set."), NULL},
+    {'k', OPT_NO_FORK, NULL,
+     gettext_noop("Do NOT fork into the background, do NOT run in debug mode."), NULL},
+    {'K', OPT_AUTHORITATIVE, NULL,
+     gettext_noop("Assume we are the only DHCP server on the local network."), NULL},
+    {'l', ARG_ONE, "path", gettext_noop("Specify where to store DHCP leases (defaults to %s)."),
+     LEASEFILE},
+    {'L', OPT_LOCALMX, NULL, gettext_noop("Return MX records for local hosts."), NULL},
+    {'m', ARG_DUP, "host_name,target,pref", gettext_noop("Specify an MX record."), NULL},
+    {'M', ARG_DUP, "<bootp opts>", gettext_noop("Specify BOOTP options to DHCP server."), NULL},
+    {'n', OPT_NO_POLL, NULL, gettext_noop("Do NOT poll %s file, reload only on SIGHUP."),
+     RESOLVFILE},
+    {'N', OPT_NO_NEG, NULL, gettext_noop("Do NOT cache failed search results."), NULL},
+    {'o', OPT_ORDER, NULL, gettext_noop("Use nameservers strictly in the order given in %s."),
+     RESOLVFILE},
+    {'O', ARG_DUP, "<optspec>", gettext_noop("Specify options to be sent to DHCP clients."), NULL},
+    {LOPT_FORCE, ARG_DUP, "<optspec>",
+     gettext_noop("DHCP option sent even if the client does not request it."), NULL},
+    {'p', ARG_ONE, "number",
+     gettext_noop("Specify port to listen for DNS requests on (defaults to 53)."), NULL},
+    {'P', ARG_ONE, "<size>",
+     gettext_noop("Maximum supported UDP packet size for EDNS.0 (defaults to %s)."), "*"},
+    {'q', OPT_LOG, NULL, gettext_noop("Log DNS queries."), NULL},
+    {'Q', ARG_ONE, "number", gettext_noop("Force the originating port for upstream DNS queries."),
+     NULL},
+    {'R', OPT_NO_RESOLV, NULL, gettext_noop("Do NOT read resolv.conf."), NULL},
+    {'r', ARG_DUP, "path", gettext_noop("Specify path to resolv.conf (defaults to %s)."),
+     RESOLVFILE},
+    {'S', ARG_DUP, "/domain/ipaddr",
+     gettext_noop("Specify address(es) of upstream servers with optional domains."), NULL},
+    {LOPT_LOCAL, ARG_DUP, "/domain/", gettext_noop("Never forward queries to specified domains."),
+     NULL},
+    {'s', ARG_DUP, "<domain>[,<range>]",
+     gettext_noop("Specify the domain to be assigned in DHCP leases."), NULL},
+    {'t', ARG_ONE, "host_name", gettext_noop("Specify default target in an MX record."), NULL},
+    {'T', ARG_ONE, "time",
+     gettext_noop("Specify time-to-live in seconds for replies from /etc/hosts."), NULL},
+    {LOPT_NEGTTL, ARG_ONE, "time",
+     gettext_noop("Specify time-to-live in seconds for negative caching."), NULL},
+    {'u', ARG_ONE, "username", gettext_noop("Change to this user after startup. (defaults to %s)."),
+     CHUSER},
+    {'U', ARG_DUP, "<id>,<class>", gettext_noop("Map DHCP vendor class to tag."), NULL},
+    {'v', 0, NULL, gettext_noop("Display dnsmasq version and copyright information."), NULL},
+    {'V', ARG_DUP, "addr,addr,mask",
+     gettext_noop("Translate IPv4 addresses from upstream servers."), NULL},
+    {'W', ARG_DUP, "name,target,...", gettext_noop("Specify a SRV record."), NULL},
+    {'w', 0, NULL, gettext_noop("Display this message. Use --help dhcp for known DHCP options."),
+     NULL},
+    {'x', ARG_ONE, "path", gettext_noop("Specify path of PID file (defaults to %s)."), RUNFILE},
+    {'X', ARG_ONE, "number",
+     gettext_noop("Specify maximum number of DHCP leases (defaults to %s)."), "&"},
+    {'y', OPT_LOCALISE, NULL,
+     gettext_noop("Answer DNS queries based on the interface a query was sent to."), NULL},
+    {'Y', ARG_DUP, "name,txt....", gettext_noop("Specify TXT DNS record."), NULL},
+    {LOPT_PTR, ARG_DUP, "name,target", gettext_noop("Specify PTR DNS record."), NULL},
+    {LOPT_INTNAME, ARG_DUP, "name,interface",
+     gettext_noop("Give DNS name to IPv4 address of interface."), NULL},
+    {'z', OPT_NOWILD, NULL, gettext_noop("Bind only to interfaces in use."), NULL},
+    {'1', OPT_DBUS, NULL,
+     gettext_noop("Enable the DBus interface for setting upstream servers, etc."), NULL},
+    {'2', ARG_DUP, "interface",
+     gettext_noop("Do not provide DHCP on this interface, only provide DNS."), NULL},
+    {'3', ARG_DUP, "[=<id>[,<id>]]", gettext_noop("Enable dynamic address allocation for bootp."),
+     NULL},
+    {'4', ARG_DUP, "<id>,<mac address>",
+     gettext_noop("Map MAC address (with wildcards) to option set."), NULL},
+    {LOPT_BRIDGE, ARG_DUP, "iface,alias,..",
+     gettext_noop("Treat DHCP requests on aliases as arriving from interface."), NULL},
+    {'5', OPT_NO_PING, NULL, gettext_noop("Disable ICMP echo address checking in the DHCP server."),
+     NULL},
+    {'6', ARG_ONE, "path", gettext_noop("Script to run on DHCP lease creation and destruction."),
+     NULL},
+    {'7', ARG_DUP, "path", gettext_noop("Read configuration from all the files in this directory."),
+     NULL},
+    {'8', ARG_ONE, "<facilty>|<file>",
+     gettext_noop("Log to this syslog facility or file. (defaults to DAEMON)"), NULL},
+    {'9', OPT_LEASE_RO, NULL, gettext_noop("Do not use leasefile."), NULL},
+    {'0', ARG_ONE, "<queries>",
+     gettext_noop("Maximum number of concurrent DNS queries. (defaults to %s)"), "!"},
+    {LOPT_RELOAD, OPT_RELOAD, NULL, gettext_noop("Clear DNS cache when reloading %s."), RESOLVFILE},
+    {LOPT_NO_NAMES, ARG_DUP, "[=<id>[,<id>]]",
+     gettext_noop("Ignore hostnames provided by DHCP clients."), NULL},
+    {LOPT_OVERRIDE, OPT_NO_OVERRIDE, NULL,
+     gettext_noop("Do NOT reuse filename and server fields for extra DHCP options."), NULL},
+    {LOPT_TFTP, OPT_TFTP, NULL, gettext_noop("Enable integrated read-only TFTP server."), NULL},
+    {LOPT_PREFIX, ARG_ONE, "<directory>",
+     gettext_noop("Export files by TFTP only from the specified subtree."), NULL},
+    {LOPT_APREF, OPT_TFTP_APREF, NULL, gettext_noop("Add client IP address to tftp-root."), NULL},
+    {LOPT_SECURE, OPT_TFTP_SECURE, NULL,
+     gettext_noop("Allow access only to files owned by the user running dnsmasq."), NULL},
+    {LOPT_TFTP_MAX, ARG_ONE, "<connections>",
+     gettext_noop("Maximum number of conncurrent TFTP transfers (defaults to %s)."), "#"},
+    {LOPT_NOBLOCK, OPT_TFTP_NOBLOCK, NULL, gettext_noop("Disable the TFTP blocksize extension."),
+     NULL},
+    {LOPT_TFTPPORTS, ARG_ONE, "<start>,<end>",
+     gettext_noop("Ephemeral port range for use by TFTP transfers."), NULL},
+    {LOPT_LOG_OPTS, OPT_LOG_OPTS, NULL, gettext_noop("Extra logging for DHCP."), NULL},
+    {LOPT_MAX_LOGS, ARG_ONE, "[=<log lines>]",
+     gettext_noop("Enable async. logging; optionally set queue length."), NULL},
+    {LOPT_REBIND, OPT_NO_REBIND, NULL,
+     gettext_noop("Stop DNS rebinding. Filter private IP ranges when resolving."), NULL},
+    {LOPT_NOLAST, OPT_ALL_SERVERS, NULL, gettext_noop("Always perform DNS queries to all servers."),
+     NULL},
+    {LOPT_MATCH, ARG_DUP, "<netid>,<optspec>",
+     gettext_noop("Set tag if client includes matching option in request."), NULL},
+    {LOPT_ALTPORT, ARG_ONE, "[=<ports>]", gettext_noop("Use alternative ports for DHCP."), NULL},
+    {LOPT_SCRIPTUSR, ARG_ONE, "<username>", gettext_noop("Run lease-change script as this user."),
+     NULL},
+    {LOPT_NAPTR, ARG_DUP, "<name>,<naptr>", gettext_noop("Specify NAPTR DNS record."), NULL},
+    {LOPT_MINPORT, ARG_ONE, "<port>",
+     gettext_noop("Specify lowest port available for DNS query transmission."), NULL},
+    {LOPT_DHCP_FQDN, OPT_DHCP_FQDN, NULL,
+     gettext_noop("Use only fully qualified domain names for DHCP clients."), NULL},
+    {LOPT_CNAME, ARG_DUP, "<alias>,<target>",
+     gettext_noop("Specify alias name for LOCAL DNS name."), NULL},
+    {LOPT_PXE_PROMT, ARG_DUP, "<prompt>,[<timeout>]",
+     gettext_noop("Prompt to send to PXE clients."), NULL},
+    {LOPT_PXE_SERV, ARG_DUP, "<service>", gettext_noop("Boot service for PXE menu."), NULL},
+    {LOPT_LISTNMARK, ARG_ONE, NULL, gettext_noop("Socket mark to use for listen sockets."), NULL},
+    {LOPT_TEST, 0, NULL, gettext_noop("Check configuration syntax."), NULL},
+    {0, 0, NULL, NULL, NULL}};
 
 #ifdef HAVE_DHCP
 /* makes options which take a list of addresses */
@@ -308,97 +367,95 @@
 #define OT_NAME 0x20
 
 static const struct {
-  char *name;
-  unsigned char val, size;
-} opttab[] = {
-  { "netmask", 1, OT_ADDR_LIST },
-  { "time-offset", 2, 4 },
-  { "router", 3, OT_ADDR_LIST  },
-  { "dns-server", 6, OT_ADDR_LIST },
-  { "log-server", 7, OT_ADDR_LIST },
-  { "lpr-server", 9, OT_ADDR_LIST },
-  { "hostname", 12, OT_INTERNAL | OT_NAME },
-  { "boot-file-size", 13, 2 },
-  { "domain-name", 15, OT_NAME },
-  { "swap-server", 16, OT_ADDR_LIST },
-  { "root-path", 17, 0 },
-  { "extension-path", 18, 0 },
-  { "ip-forward-enable", 19, 1 },
-  { "non-local-source-routing", 20, 1 },
-  { "policy-filter", 21, OT_ADDR_LIST },
-  { "max-datagram-reassembly", 22, 2 },
-  { "default-ttl", 23, 1 },
-  { "mtu", 26, 2 },
-  { "all-subnets-local", 27, 1 },
-  { "broadcast", 28, OT_INTERNAL | OT_ADDR_LIST },
-  { "router-discovery", 31, 1 },
-  { "router-solicitation", 32, OT_ADDR_LIST },
-  { "static-route", 33, OT_ADDR_LIST },
-  { "trailer-encapsulation", 34, 1 },
-  { "arp-timeout", 35, 4 },
-  { "ethernet-encap", 36, 1 },
-  { "tcp-ttl", 37, 1 },
-  { "tcp-keepalive", 38, 4 },
-  { "nis-domain", 40, 0 },
-  { "nis-server", 41, OT_ADDR_LIST },
-  { "ntp-server", 42, OT_ADDR_LIST },
-  { "vendor-encap", 43, OT_INTERNAL },
-  { "netbios-ns", 44, OT_ADDR_LIST },
-  { "netbios-dd", 45, OT_ADDR_LIST },
-  { "netbios-nodetype", 46, 1 },
-  { "netbios-scope", 47, 0 },
-  { "x-windows-fs", 48, OT_ADDR_LIST },
-  { "x-windows-dm", 49, OT_ADDR_LIST },
-  { "requested-address", 50, OT_INTERNAL | OT_ADDR_LIST },
-  { "lease-time", 51, OT_INTERNAL },
-  { "option-overload", 52, OT_INTERNAL },
-  { "message-type", 53, OT_INTERNAL, },
-  { "server-identifier", 54, OT_INTERNAL | OT_ADDR_LIST },
-  { "parameter-request", 55, OT_INTERNAL },
-  { "message", 56, OT_INTERNAL },
-  { "max-message-size", 57, OT_INTERNAL },
-  { "T1", 58, OT_INTERNAL },
-  { "T2", 59, OT_INTERNAL },
-  { "vendor-class", 60, 0 },
-  { "client-id", 61,OT_INTERNAL },
-  { "nis+-domain", 64, 0 },
-  { "nis+-server", 65, OT_ADDR_LIST },
-  { "tftp-server", 66, 0 },
-  { "bootfile-name", 67, 0 },
-  { "mobile-ip-home", 68, OT_ADDR_LIST }, 
-  { "smtp-server", 69, OT_ADDR_LIST }, 
-  { "pop3-server", 70, OT_ADDR_LIST }, 
-  { "nntp-server", 71, OT_ADDR_LIST }, 
-  { "irc-server", 74, OT_ADDR_LIST }, 
-  { "user-class", 77, 0 },
-  { "FQDN", 81, OT_INTERNAL },
-  { "agent-id", 82, OT_INTERNAL },
-  { "client-arch", 93, 2 },
-  { "client-interface-id", 94, 0 },
-  { "client-machine-id", 97, 0 },
-  { "subnet-select", 118, OT_INTERNAL },
-  { "domain-search", 119, 0 },
-  { "sip-server", 120, 0 },
-  { "classless-static-route", 121, 0 },
-  { "server-ip-address", 255, OT_ADDR_LIST }, /* special, internal only, sets siaddr */
-  { NULL, 0, 0 }
-};
+    char* name;
+    unsigned char val, size;
+} opttab[] = {{"netmask", 1, OT_ADDR_LIST},
+              {"time-offset", 2, 4},
+              {"router", 3, OT_ADDR_LIST},
+              {"dns-server", 6, OT_ADDR_LIST},
+              {"log-server", 7, OT_ADDR_LIST},
+              {"lpr-server", 9, OT_ADDR_LIST},
+              {"hostname", 12, OT_INTERNAL | OT_NAME},
+              {"boot-file-size", 13, 2},
+              {"domain-name", 15, OT_NAME},
+              {"swap-server", 16, OT_ADDR_LIST},
+              {"root-path", 17, 0},
+              {"extension-path", 18, 0},
+              {"ip-forward-enable", 19, 1},
+              {"non-local-source-routing", 20, 1},
+              {"policy-filter", 21, OT_ADDR_LIST},
+              {"max-datagram-reassembly", 22, 2},
+              {"default-ttl", 23, 1},
+              {"mtu", 26, 2},
+              {"all-subnets-local", 27, 1},
+              {"broadcast", 28, OT_INTERNAL | OT_ADDR_LIST},
+              {"router-discovery", 31, 1},
+              {"router-solicitation", 32, OT_ADDR_LIST},
+              {"static-route", 33, OT_ADDR_LIST},
+              {"trailer-encapsulation", 34, 1},
+              {"arp-timeout", 35, 4},
+              {"ethernet-encap", 36, 1},
+              {"tcp-ttl", 37, 1},
+              {"tcp-keepalive", 38, 4},
+              {"nis-domain", 40, 0},
+              {"nis-server", 41, OT_ADDR_LIST},
+              {"ntp-server", 42, OT_ADDR_LIST},
+              {"vendor-encap", 43, OT_INTERNAL},
+              {"netbios-ns", 44, OT_ADDR_LIST},
+              {"netbios-dd", 45, OT_ADDR_LIST},
+              {"netbios-nodetype", 46, 1},
+              {"netbios-scope", 47, 0},
+              {"x-windows-fs", 48, OT_ADDR_LIST},
+              {"x-windows-dm", 49, OT_ADDR_LIST},
+              {"requested-address", 50, OT_INTERNAL | OT_ADDR_LIST},
+              {"lease-time", 51, OT_INTERNAL},
+              {"option-overload", 52, OT_INTERNAL},
+              {
+                  "message-type",
+                  53,
+                  OT_INTERNAL,
+              },
+              {"server-identifier", 54, OT_INTERNAL | OT_ADDR_LIST},
+              {"parameter-request", 55, OT_INTERNAL},
+              {"message", 56, OT_INTERNAL},
+              {"max-message-size", 57, OT_INTERNAL},
+              {"T1", 58, OT_INTERNAL},
+              {"T2", 59, OT_INTERNAL},
+              {"vendor-class", 60, 0},
+              {"client-id", 61, OT_INTERNAL},
+              {"nis+-domain", 64, 0},
+              {"nis+-server", 65, OT_ADDR_LIST},
+              {"tftp-server", 66, 0},
+              {"bootfile-name", 67, 0},
+              {"mobile-ip-home", 68, OT_ADDR_LIST},
+              {"smtp-server", 69, OT_ADDR_LIST},
+              {"pop3-server", 70, OT_ADDR_LIST},
+              {"nntp-server", 71, OT_ADDR_LIST},
+              {"irc-server", 74, OT_ADDR_LIST},
+              {"user-class", 77, 0},
+              {"FQDN", 81, OT_INTERNAL},
+              {"agent-id", 82, OT_INTERNAL},
+              {"client-arch", 93, 2},
+              {"client-interface-id", 94, 0},
+              {"client-machine-id", 97, 0},
+              {"subnet-select", 118, OT_INTERNAL},
+              {"domain-search", 119, 0},
+              {"sip-server", 120, 0},
+              {"classless-static-route", 121, 0},
+              {"server-ip-address", 255, OT_ADDR_LIST}, /* special, internal only, sets siaddr */
+              {NULL, 0, 0}};
 
-char *option_string(unsigned char opt, int *is_ip, int *is_name)
-{
-  int i;
+char* option_string(unsigned char opt, int* is_ip, int* is_name) {
+    int i;
 
-  for (i = 0; opttab[i].name; i++)
-    if (opttab[i].val == opt)
-      {
-	if (is_ip)
-	  *is_ip = !!(opttab[i].size & OT_ADDR_LIST);
-	if (is_name)
-	  *is_name = !!(opttab[i].size & OT_NAME);
-	return opttab[i].name;
-      }
+    for (i = 0; opttab[i].name; i++)
+        if (opttab[i].val == opt) {
+            if (is_ip) *is_ip = !!(opttab[i].size & OT_ADDR_LIST);
+            if (is_name) *is_name = !!(opttab[i].size & OT_NAME);
+            return opttab[i].name;
+        }
 
-  return NULL;
+    return NULL;
 }
 
 #endif
@@ -407,8 +464,8 @@
    character space. Note that the \0, \t \b \r \033 and \n characters are carefully placed in the
    following sequence so that they map to themselves: it is therefore possible to call
    unhide_metas repeatedly on string without breaking things.
-   The transformation gets undone by opt_canonicalise, atoi_check and opt_string_alloc, and a 
-   couple of other places. 
+   The transformation gets undone by opt_canonicalise, atoi_check and opt_string_alloc, and a
+   couple of other places.
    Note that space is included here so that
    --dhcp-option=3, string
    has five characters, whilst
@@ -418,2516 +475,2133 @@
 
 static const char meta[] = "\000123456 \b\t\n78\r90abcdefABCDE\033F:,.";
 
-static char hide_meta(char c)
-{
-  unsigned int i;
+static char hide_meta(char c) {
+    unsigned int i;
 
-  for (i = 0; i < (sizeof(meta) - 1); i++)
-    if (c == meta[i])
-      return (char)i;
-  
-  return c;
+    for (i = 0; i < (sizeof(meta) - 1); i++)
+        if (c == meta[i]) return (char) i;
+
+    return c;
 }
 
-static char unhide_meta(char cr)
-{ 
-  unsigned int c = cr;
-  
-  if (c < (sizeof(meta) - 1))
-    cr = meta[c];
-  
-  return cr;
+static char unhide_meta(char cr) {
+    unsigned int c = cr;
+
+    if (c < (sizeof(meta) - 1)) cr = meta[c];
+
+    return cr;
 }
 
-static void unhide_metas(char *cp)
-{
-  if (cp)
-    for(; *cp; cp++)
-      *cp = unhide_meta(*cp);
+static void unhide_metas(char* cp) {
+    if (cp)
+        for (; *cp; cp++) *cp = unhide_meta(*cp);
 }
 
-static void *opt_malloc(size_t size)
-{
-  void *ret;
+static void* opt_malloc(size_t size) {
+    void* ret;
 
-  if (mem_recover)
-    {
-      ret = whine_malloc(size);
-      if (!ret)
-	longjmp(mem_jmp, 1);
+    if (mem_recover) {
+        ret = whine_malloc(size);
+        if (!ret) longjmp(mem_jmp, 1);
+    } else
+        ret = safe_malloc(size);
+
+    return ret;
+}
+
+static char* opt_string_alloc(char* cp) {
+    char* ret = NULL;
+
+    if (cp && strlen(cp) != 0) {
+        ret = opt_malloc(strlen(cp) + 1);
+        strcpy(ret, cp);
+
+        /* restore hidden metachars */
+        unhide_metas(ret);
     }
-  else
-    ret = safe_malloc(size);
-  
-  return ret;
-}
 
-static char *opt_string_alloc(char *cp)
-{
-  char *ret = NULL;
-  
-  if (cp && strlen(cp) != 0)
-    {
-      ret = opt_malloc(strlen(cp)+1);
-      strcpy(ret, cp); 
-      
-      /* restore hidden metachars */
-      unhide_metas(ret);
-    }
-    
-  return ret;
+    return ret;
 }
 
-
 /* find next comma, split string with zero and eliminate spaces.
    return start of string following comma */
 
-static char *split_chr(char *s, char c)
-{
-  char *comma, *p;
+static char* split_chr(char* s, char c) {
+    char *comma, *p;
 
-  if (!s || !(comma = strchr(s, c)))
-    return NULL;
-  
-  p = comma;
-  *comma = ' ';
-  
-  for (; isspace((int)*comma); comma++);
- 
-  for (; (p >= s) && isspace((int)*p); p--)
-    *p = 0;
-    
-  return comma;
+    if (!s || !(comma = strchr(s, c))) return NULL;
+
+    p = comma;
+    *comma = ' ';
+
+    for (; isspace((int) *comma); comma++)
+        ;
+
+    for (; (p >= s) && isspace((int) *p); p--) *p = 0;
+
+    return comma;
 }
 
-static char *split(char *s)
-{
-  return split_chr(s, ',');
+static char* split(char* s) {
+    return split_chr(s, ',');
 }
 
-static char *canonicalise_opt(char *s)
-{
-  char *ret;
-  int nomem;
+static char* canonicalise_opt(char* s) {
+    char* ret;
+    int nomem;
 
-  if (!s)
-    return 0;
+    if (!s) return 0;
 
-  unhide_metas(s);
-  if (!(ret = canonicalise(s, &nomem)) && nomem)
-    {
-      if (mem_recover)
-	longjmp(mem_jmp, 1);
-      else
-	die(_("could not get memory"), NULL, EC_NOMEM);
+    unhide_metas(s);
+    if (!(ret = canonicalise(s, &nomem)) && nomem) {
+        if (mem_recover)
+            longjmp(mem_jmp, 1);
+        else
+            die(_("could not get memory"), NULL, EC_NOMEM);
     }
 
-  return ret;
+    return ret;
 }
 
-static int atoi_check(char *a, int *res)
-{
-  char *p;
+static int atoi_check(char* a, int* res) {
+    char* p;
 
-  if (!a)
-    return 0;
+    if (!a) return 0;
 
-  unhide_metas(a);
-  
-  for (p = a; *p; p++)
-     if (*p < '0' || *p > '9')
-       return 0;
+    unhide_metas(a);
 
-  *res = atoi(a);
-  return 1;
+    for (p = a; *p; p++)
+        if (*p < '0' || *p > '9') return 0;
+
+    *res = atoi(a);
+    return 1;
 }
 
-static int atoi_check16(char *a, int *res)
-{
-  if (!(atoi_check(a, res)) ||
-      *res < 0 ||
-      *res > 0xffff)
-    return 0;
+static int atoi_check16(char* a, int* res) {
+    if (!(atoi_check(a, res)) || *res < 0 || *res > 0xffff) return 0;
 
-  return 1;
-}
-	
-static void add_txt(char *name, char *txt)
-{
-  size_t len = strlen(txt);
-  struct txt_record *r = opt_malloc(sizeof(struct txt_record));
-  
-  r->name = opt_string_alloc(name);
-  r->next = daemon->txt;
-  daemon->txt = r;
-  r->class = C_CHAOS;
-  r->txt = opt_malloc(len+1);
-  r->len = len+1;
-  *(r->txt) = len;
-  memcpy((r->txt)+1, txt, len);
+    return 1;
 }
 
-static void do_usage(void)
-{
-  char buff[100];
-  int i, j;
+static void add_txt(char* name, char* txt) {
+    size_t len = strlen(txt);
+    struct txt_record* r = opt_malloc(sizeof(struct txt_record));
 
-  struct {
-    char handle;
-    int val;
-  } tab[] = {
-    { '$', CACHESIZ },
-    { '*', EDNS_PKTSZ },
-    { '&', MAXLEASES },
-    { '!', FTABSIZ },
-    { '\0', 0 }
-  };
+    r->name = opt_string_alloc(name);
+    r->next = daemon->txt;
+    daemon->txt = r;
+    r->class = C_CHAOS;
+    r->txt = opt_malloc(len + 1);
+    r->len = len + 1;
+    *(r->txt) = len;
+    memcpy((r->txt) + 1, txt, len);
+}
 
-  printf(_("Usage: dnsmasq [options]\n\n"));
+static void do_usage(void) {
+    char buff[100];
+    int i, j;
+
+    struct {
+        char handle;
+        int val;
+    } tab[] = {{'$', CACHESIZ}, {'*', EDNS_PKTSZ}, {'&', MAXLEASES}, {'!', FTABSIZ}, {'\0', 0}};
+
+    printf(_("Usage: dnsmasq [options]\n\n"));
 #ifndef HAVE_GETOPT_LONG
-  printf(_("Use short options only on the command line.\n"));
+    printf(_("Use short options only on the command line.\n"));
 #endif
-  printf(_("Valid options are:\n"));
-  
-  for (i = 0; usage[i].opt != 0; i++)
-    {
-      char *desc = usage[i].flagdesc; 
-      char *eq = "=";
-      
-      if (!desc || *desc == '[')
-	eq = "";
-      
-      if (!desc)
-	desc = "";
+    printf(_("Valid options are:\n"));
 
-      for ( j = 0; opts[j].name; j++)
-	if (opts[j].val == usage[i].opt)
-	  break;
-      if (usage[i].opt < 256)
-	sprintf(buff, "-%c, ", usage[i].opt);
-      else
-	sprintf(buff, "    ");
-      
-      sprintf(buff+4, "--%s%s%s", opts[j].name, eq, desc);
-      printf("%-36.36s", buff);
-	     
-      if (usage[i].arg)
-	{
-	  strcpy(buff, usage[i].arg);
-	  for (j = 0; tab[j].handle; j++)
-	    if (tab[j].handle == *(usage[i].arg))
-	      sprintf(buff, "%d", tab[j].val);
-	}
-      printf(_(usage[i].desc), buff);
-      printf("\n");
+    for (i = 0; usage[i].opt != 0; i++) {
+        char* desc = usage[i].flagdesc;
+        char* eq = "=";
+
+        if (!desc || *desc == '[') eq = "";
+
+        if (!desc) desc = "";
+
+        for (j = 0; opts[j].name; j++)
+            if (opts[j].val == usage[i].opt) break;
+        if (usage[i].opt < 256)
+            sprintf(buff, "-%c, ", usage[i].opt);
+        else
+            sprintf(buff, "    ");
+
+        sprintf(buff + 4, "--%s%s%s", opts[j].name, eq, desc);
+        printf("%-36.36s", buff);
+
+        if (usage[i].arg) {
+            strcpy(buff, usage[i].arg);
+            for (j = 0; tab[j].handle; j++)
+                if (tab[j].handle == *(usage[i].arg)) sprintf(buff, "%d", tab[j].val);
+        }
+        printf(_(usage[i].desc), buff);
+        printf("\n");
     }
 }
 
 #ifdef HAVE_DHCP
-static void display_opts(void)
-{
-  int i;
-  
-  printf(_("Known DHCP options:\n"));
-  
-  for (i = 0; opttab[i].name; i++)
-    if (!(opttab[i].size & OT_INTERNAL))
-      printf("%3d %s\n", opttab[i].val, opttab[i].name);
+static void display_opts(void) {
+    int i;
+
+    printf(_("Known DHCP options:\n"));
+
+    for (i = 0; opttab[i].name; i++)
+        if (!(opttab[i].size & OT_INTERNAL)) printf("%3d %s\n", opttab[i].val, opttab[i].name);
 }
 
 /* This is too insanely large to keep in-line in the switch */
-static char *parse_dhcp_opt(char *arg, int flags)
-{
-  struct dhcp_opt *new = opt_malloc(sizeof(struct dhcp_opt));
-  char lenchar = 0, *cp;
-  int i, addrs, digs, is_addr, is_hex, is_dec, is_string, dots;
-  char *comma = NULL, *problem = NULL;
-  struct dhcp_netid *np = NULL;
-  unsigned char opt_len = 0;
+static char* parse_dhcp_opt(char* arg, int flags) {
+    struct dhcp_opt* new = opt_malloc(sizeof(struct dhcp_opt));
+    char lenchar = 0, *cp;
+    int i, addrs, digs, is_addr, is_hex, is_dec, is_string, dots;
+    char *comma = NULL, *problem = NULL;
+    struct dhcp_netid* np = NULL;
+    unsigned char opt_len = 0;
 
-  new->len = 0;
-  new->flags = flags;
-  new->netid = NULL;
-  new->val = NULL;
-  new->opt = 0;
-  
-  while (arg)
-    {
-      comma = split(arg);      
+    new->len = 0;
+    new->flags = flags;
+    new->netid = NULL;
+    new->val = NULL;
+    new->opt = 0;
 
-      for (cp = arg; *cp; cp++)
-	if (*cp < '0' || *cp > '9')
-	  break;
-      
-      if (!*cp)
-	{
-	  new->opt = atoi(arg);
-	  opt_len = 0;
-	  break;
-	}
-      
-      if (strstr(arg, "option:") == arg)
-	{
-	  for (i = 0; opttab[i].name; i++)
-	    if (!(opttab[i].size & OT_INTERNAL) &&
-		strcasecmp(opttab[i].name, arg+7) == 0)
-	      {
-		new->opt = opttab[i].val;
-		opt_len = opttab[i].size;
-		break;
-	      }
-	  /* option:<optname> must follow tag and vendor string. */
-	  break;
-	}
-      else if (strstr(arg, "vendor:") == arg)
-	{
-	  new->u.vendor_class = (unsigned char *)opt_string_alloc(arg+7);
-	  new->flags |= DHOPT_VENDOR;
-	}
-      else if (strstr(arg, "encap:") == arg)
-	{
-	  new->u.encap = atoi(arg+6);
-	  new->flags |= DHOPT_ENCAPSULATE;
-	}
-      else
-	{
-	  new->netid = opt_malloc(sizeof (struct dhcp_netid));
-	  /* allow optional "net:" for consistency */
-	  if (strstr(arg, "net:") == arg)
-	    new->netid->net = opt_string_alloc(arg+4);
-	  else
-	    new->netid->net = opt_string_alloc(arg);
-	  new->netid->next = np;
-	  np = new->netid;
-	}
-      
-      arg = comma; 
-    }
-  
-  if (new->opt == 0)
-    problem = _("bad dhcp-option");
-  else if (comma)
-    {
-      /* characterise the value */
-      char c;
-      is_addr = is_hex = is_dec = is_string = 1;
-      addrs = digs = 1;
-      dots = 0;
-      for (cp = comma; (c = *cp); cp++)
-	if (c == ',')
-	  {
-	    addrs++;
-	    is_dec = is_hex = 0;
-	  }
-	else if (c == ':')
-	  {
-	    digs++;
-	    is_dec = is_addr = 0;
-	  }
-	else if (c == '/') 
-	  {
-	    is_dec = is_hex = 0;
-	    if (cp == comma) /* leading / means a pathname */
-	      is_addr = 0;
-	  } 
-	else if (c == '.')	
-	  {
-	    is_dec = is_hex = 0;
-	    dots++;
-	  }
-	else if (c == '-')
-	  is_hex = is_addr = 0;
-	else if (c == ' ')
-	  is_dec = is_hex = 0;
-	else if (!(c >='0' && c <= '9'))
-	  {
-	    is_addr = 0;
-	    if (cp[1] == 0 && is_dec &&
-		(c == 'b' || c == 's' || c == 'i'))
-	      {
-		lenchar = c;
-		*cp = 0;
-	      }
-	    else
-	      is_dec = 0;
-	    if (!((c >='A' && c <= 'F') ||
-		  (c >='a' && c <= 'f') || 
-		  (c == '*' && (flags & DHOPT_MATCH))))
-	      is_hex = 0;
-	  }
-     
-      /* We know that some options take addresses */
+    while (arg) {
+        comma = split(arg);
 
-      if (opt_len & OT_ADDR_LIST)
-	{
-	  is_string = is_dec = is_hex = 0;
-	  if (!is_addr || dots == 0)
-	    problem = _("bad IP address");
-	}
-	  
-      if (is_hex && digs > 1)
-	{
-	  new->len = digs;
-	  new->val = opt_malloc(new->len);
-	  parse_hex(comma, new->val, digs, (flags & DHOPT_MATCH) ? &new->u.wildcard_mask : NULL, NULL);
-	  new->flags |= DHOPT_HEX;
-	}
-      else if (is_dec)
-	{
-	  int i, val = atoi(comma);
-	  /* assume numeric arg is 1 byte except for
-	     options where it is known otherwise.
-	     For vendor class option, we have to hack. */
-	  if (opt_len != 0)
-	    new->len = opt_len;
-	  else if (val & 0xffff0000)
-	    new->len = 4;
-	  else if (val & 0xff00)
-	    new->len = 2;
-	  else
-	    new->len = 1;
+        for (cp = arg; *cp; cp++)
+            if (*cp < '0' || *cp > '9') break;
 
-	  if (lenchar == 'b')
-	    new->len = 1;
-	  else if (lenchar == 's')
-	    new->len = 2;
-	  else if (lenchar == 'i')
-	    new->len = 4;
-	  
-	  new->val = opt_malloc(new->len);
-	  for (i=0; i<new->len; i++)
-	    new->val[i] = val>>((new->len - i - 1)*8);
-	}
-      else if (is_addr)	
-	{
-	  struct in_addr in;
-	  unsigned char *op;
-	  char *slash;
-	  /* max length of address/subnet descriptor is five bytes,
-	     add one for the option 120 enc byte too */
-	  new->val = op = opt_malloc((5 * addrs) + 1);
-	  new->flags |= DHOPT_ADDR;
-
-	  if (!(new->flags & DHOPT_ENCAPSULATE) && new->opt == 120)
-	    {
-	      *(op++) = 1; /* RFC 3361 "enc byte" */
-	      new->flags &= ~DHOPT_ADDR;
-	    }
-	  while (addrs--) 
-	    {
-	      cp = comma;
-	      comma = split(cp);
-	      slash = split_chr(cp, '/');
-	      in.s_addr = inet_addr(cp);
-	      if (!slash)
-		{
-		  memcpy(op, &in, INADDRSZ);
-		  op += INADDRSZ;
-		}
-	      else
-		{
-		  unsigned char *p = (unsigned char *)&in;
-		  int netsize = atoi(slash);
-		  *op++ = netsize;
-		  if (netsize > 0)
-		    *op++ = *p++;
-		  if (netsize > 8)
-		    *op++ = *p++;
-		  if (netsize > 16)
-		    *op++ = *p++;
-		  if (netsize > 24)
-		    *op++ = *p++;
-		  new->flags &= ~DHOPT_ADDR; /* cannot re-write descriptor format */
-		} 
-	    }
-	  new->len = op - new->val;
-	}
-      else if (is_string)
-	{
-	  /* text arg */
-	  if ((new->opt == 119 || new->opt == 120) && !(new->flags & DHOPT_ENCAPSULATE))
-	    {
-	      /* dns search, RFC 3397, or SIP, RFC 3361 */
-	      unsigned char *q, *r, *tail;
-	      unsigned char *p, *m = NULL, *newp;
-	      size_t newlen, len = 0;
-	      int header_size = (new->opt == 119) ? 0 : 1;
-	      
-	      arg = comma;
-	      comma = split(arg);
-	      
-	      while (arg && *arg)
-		{
-		  char *dom;
-		  if (!(dom = arg = canonicalise_opt(arg)))
-		    {
-		      problem = _("bad domain in dhcp-option");
-		      break;
-		    }
-		  
-		  newp = opt_malloc(len + strlen(arg) + 2 + header_size);
-		  if (m)
-		    memcpy(newp, m, header_size + len);
-		  m = newp;
-		  p = m + header_size;
-		  q = p + len;
-		  
-		  /* add string on the end in RFC1035 format */
-		  while (*arg) 
-		    {
-		      unsigned char *cp = q++;
-		      int j;
-		      for (j = 0; *arg && (*arg != '.'); arg++, j++)
-			*q++ = *arg;
-		      *cp = j;
-		      if (*arg)
-			arg++;
-		    }
-		  *q++ = 0;
-		  free(dom);
-
-		  /* Now tail-compress using earlier names. */
-		  newlen = q - p;
-		  for (tail = p + len; *tail; tail += (*tail) + 1)
-		    for (r = p; r - p < (int)len; r += (*r) + 1)
-		      if (strcmp((char *)r, (char *)tail) == 0)
-			{
-			  PUTSHORT((r - p) | 0xc000, tail); 
-			  newlen = tail - p;
-			  goto end;
-			}
-		end:
-		  len = newlen;
-		  
-		  arg = comma;
-		  comma = split(arg);
-		}
-      
-	      /* RFC 3361, enc byte is zero for names */
-	      if (new->opt == 120)
-		m[0] = 0;
-	      new->len = (int) len + header_size;
-	      new->val = m;
-	    }
-	  else
-	    {
-	      new->len = strlen(comma);
-	      /* keep terminating zero on string */
-	      new->val = (unsigned char *)opt_string_alloc(comma);
-	      new->flags |= DHOPT_STRING;
-	    }
-	}
-    }
-
-  if ((new->len > 255) || (new->len > 253 && (new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE))))
-    problem = _("dhcp-option too long");
-  
-  if (!problem)
-    {
-      if (flags == DHOPT_MATCH)
-	{
-	  if ((new->flags & (DHOPT_ENCAPSULATE | DHOPT_VENDOR)) ||
-	      !new->netid ||
-	      new->netid->next)
-	    problem = _("illegal dhcp-match");
-	  else
-	    {
-	      new->next = daemon->dhcp_match;
-	      daemon->dhcp_match = new;
-	    }
-	}
-      else     
-	{
-	  new->next = daemon->dhcp_opts;
-	  daemon->dhcp_opts = new;
-	}
-    }
-
-  return problem;
-}
-
-#endif
-
-static char *one_opt(int option, char *arg, char *gen_prob, int nest)
-{      
-  int i;
-  char *comma, *problem = NULL;;
-
-  if (option == '?')
-    return gen_prob;
-  
-  for (i=0; usage[i].opt != 0; i++)
-    if (usage[i].opt == option)
-      {
-	 int rept = usage[i].rept;
-	 
-	 if (nest == 0)
-	   {
-	     /* command line */
-	     if (rept == ARG_USED_CL)
-	       return _("illegal repeated flag");
-	     if (rept == ARG_ONE)
-	       usage[i].rept = ARG_USED_CL;
-	   }
-	 else
-	   {
-	     /* allow file to override command line */
-	     if (rept == ARG_USED_FILE)
-	       return _("illegal repeated keyword");
-	     if (rept == ARG_USED_CL || rept == ARG_ONE)
-	       usage[i].rept = ARG_USED_FILE;
-	   }
-
-	 if (rept != ARG_DUP && rept != ARG_ONE && rept != ARG_USED_CL) 
-	   {
-	     daemon->options |= rept;
-	     return NULL;
-	   }
-       
-	 break;
-      }
-  
-  switch (option)
-    { 
-    case 'C': /* --conf-file */
-      {
-	char *file = opt_string_alloc(arg);
-	if (file)
-	  {
-	    one_file(file, nest, 0);
-	    free(file);
-	  }
-	break;
-      }
-
-    case '7': /* --conf-dir */	      
-      {
-	DIR *dir_stream;
-	struct dirent *ent;
-	char *directory, *path;
-	struct list {
-	  char *suffix;
-	  struct list *next;
-	} *ignore_suffix = NULL, *li;
-	
-	comma = split(arg);
-	if (!(directory = opt_string_alloc(arg)))
-	  break;
-	
-	for (arg = comma; arg; arg = comma) 
-	  {
-	    comma = split(arg);
-	    li = opt_malloc(sizeof(struct list));
-	    li->next = ignore_suffix;
-	    ignore_suffix = li;
-	    /* Have to copy: buffer is overwritten */
-	    li->suffix = opt_string_alloc(arg);
-	  };
-	
-	if (!(dir_stream = opendir(directory)))
-	  die(_("cannot access directory %s: %s"), directory, EC_FILE);
-	
-	while ((ent = readdir(dir_stream)))
-	  {
-	    size_t len = strlen(ent->d_name);
-	    struct stat buf;
-	    
-	    /* ignore emacs backups and dotfiles */
-	    if (len == 0 ||
-		ent->d_name[len - 1] == '~' ||
-		(ent->d_name[0] == '#' && ent->d_name[len - 1] == '#') ||
-		ent->d_name[0] == '.')
-	      continue;
-
-	    for (li = ignore_suffix; li; li = li->next)
-	      {
-		/* check for proscribed suffices */
-		size_t ls = strlen(li->suffix);
-		if (len > ls &&
-		    strcmp(li->suffix, &ent->d_name[len - ls]) == 0)
-		  break;
-	      }
-	    if (li)
-	      continue;
-	    
-	    path = opt_malloc(strlen(directory) + len + 2);
-	    strcpy(path, directory);
-	    strcat(path, "/");
-	    strcat(path, ent->d_name);
-
-	    if (stat(path, &buf) == -1)
-	      die(_("cannot access %s: %s"), path, EC_FILE);
-	    /* only reg files allowed. */
-	    if (!S_ISREG(buf.st_mode))
-	      continue;
-	    
-	    /* dir is one level, so files must be readable */
-	    one_file(path, nest + 1, 0);
-	    free(path);
-	  }
-     
-	closedir(dir_stream);
-	free(directory);
-	for(; ignore_suffix; ignore_suffix = li)
-	  {
-	    li = ignore_suffix->next;
-	    free(ignore_suffix->suffix);
-	    free(ignore_suffix);
-	  }
-	      
-	break;
-      }
-
-    case '8': /* --log-facility */
-      /* may be a filename */
-      if (strchr(arg, '/'))
-	daemon->log_file = opt_string_alloc(arg);
-      else
-	{
-#ifdef __ANDROID__
-	    problem = "Android does not support log facilities";
-#else	  
-	  for (i = 0; facilitynames[i].c_name; i++)
-	    if (hostname_isequal((char *)facilitynames[i].c_name, arg))
-	      break;
-	  
-	  if (facilitynames[i].c_name)
-	    daemon->log_fac = facilitynames[i].c_val;
-	  else
-	    problem = "bad log facility";
-#endif
-	}
-      break;
-      
-    case 'x': /* --pid-file */
-      daemon->runfile = opt_string_alloc(arg);
-      break;
-
-    case LOPT_DHCP_HOST: /* --dhcp-hostfile */
-      if (daemon->dhcp_hosts_file)
-	problem = _("only one dhcp-hostsfile allowed");
-      else
-	daemon->dhcp_hosts_file = opt_string_alloc(arg);
-      break;
-     
-    case LOPT_DHCP_OPTS: /* --dhcp-optsfile */
-      if (daemon->dhcp_opts_file)
-	problem = _("only one dhcp-optsfile allowed");
-      else
-	daemon->dhcp_opts_file = opt_string_alloc(arg);
-      break; 
-      
-    case 'r': /* --resolv-file */
-      {
-	char *name = opt_string_alloc(arg);
-	struct resolvc *new, *list = daemon->resolv_files;
-	
-	if (list && list->is_default)
-	  {
-	    /* replace default resolv file - possibly with nothing */
-	    if (name)
-	      {
-		list->is_default = 0;
-		list->name = name;
-	      }
-	    else
-	      list = NULL;
-	  }
-	else if (name)
-	  {
-	    new = opt_malloc(sizeof(struct resolvc));
-	    new->next = list;
-	    new->name = name;
-	    new->is_default = 0;
-	    new->mtime = 0;
-	    new->logged = 0;
-	    list = new;
-	  }
-	daemon->resolv_files = list;
-	break;
-      }
-      
-    case 'm':  /* --mx-host */
-      {
-	int pref = 1;
-	struct mx_srv_record *new;
-	char *name, *target = NULL;
-
-	if ((comma = split(arg)))
-	  {
-	    char *prefstr;
-	    if ((prefstr = split(comma)) && !atoi_check16(prefstr, &pref))
-	      problem = _("bad MX preference");
-	  }
-	
-	if (!(name = canonicalise_opt(arg)) || 
-	    (comma && !(target = canonicalise_opt(comma))))
-	  problem = _("bad MX name");
-	
-	new = opt_malloc(sizeof(struct mx_srv_record));
-	new->next = daemon->mxnames;
-	daemon->mxnames = new;
-	new->issrv = 0;
-	new->name = name;
-	new->target = target; /* may be NULL */
-	new->weight = pref;
-	break;
-      }
-      
-    case 't': /*  --mx-target */
-      if (!(daemon->mxtarget = canonicalise_opt(arg)))
-	problem = _("bad MX target");
-      break;
-
-#ifdef HAVE_DHCP      
-    case 'l':  /* --dhcp-leasefile */
-      daemon->lease_file = opt_string_alloc(arg);
-      break;
-      
-    case '6': /* --dhcp-script */
-#  if defined(NO_FORK)
-      problem = _("cannot run scripts under uClinux");
-#  elif !defined(HAVE_SCRIPT)
-      problem = _("recompile with HAVE_SCRIPT defined to enable lease-change scripts");
-#  else
-      daemon->lease_change_command = opt_string_alloc(arg);
-#  endif
-      break;
-#endif
-
-    case 'H': /* --addn-hosts */
-      {
-	struct hostsfile *new = opt_malloc(sizeof(struct hostsfile));
-	static int hosts_index = 1;
-	new->fname = opt_string_alloc(arg);
-	new->index = hosts_index++;
-	new->flags = 0;
-	new->next = daemon->addn_hosts;
-	daemon->addn_hosts = new;
-	break;
-      }
-      
-    case 's': /* --domain */
-      if (strcmp (arg, "#") == 0)
-	daemon->options |= OPT_RESOLV_DOMAIN;
-      else
-	{
-	  char *d;
-	  comma = split(arg);
-	  if (!(d = canonicalise_opt(arg)))
-	    option = '?';
-	  else
-	    {
-	      if (comma)
-		{
-		  struct cond_domain *new = safe_malloc(sizeof(struct cond_domain));
-		  unhide_metas(comma);
-		  if ((arg = split_chr(comma, '/')))
-		    {
-		      int mask;
-		      if ((new->start.s_addr = inet_addr(comma)) == (in_addr_t)-1 ||
-			  !atoi_check(arg, &mask))
-			option = '?';
-		      else
-			{
-			  mask = (1 << (32 - mask)) - 1;
-			  new->start.s_addr = ntohl(htonl(new->start.s_addr) & ~mask);
-			  new->end.s_addr = new->start.s_addr | htonl(mask);
-			}
-		    }
-		  else if ((arg = split(comma)))
-		    {
-		      if ((new->start.s_addr = inet_addr(comma)) == (in_addr_t)-1 ||
-			  (new->end.s_addr = inet_addr(arg)) == (in_addr_t)-1)
-			option = '?';
-		    }
-		  else if ((new->start.s_addr = new->end.s_addr = inet_addr(comma)) == (in_addr_t)-1)
-		    option = '?';
-
-		  new->domain = d;
-		  new->next = daemon->cond_domain;
-		  daemon->cond_domain = new;
-		}
-	      else
-		daemon->domain_suffix = d;
-	    }
-	}
-      break;
-      
-    case 'u':  /* --user */
-      daemon->username = opt_string_alloc(arg);
-      break;
-      
-    case 'g':  /* --group */
-      daemon->groupname = opt_string_alloc(arg);
-      daemon->group_set = 1;
-      break;
-
-#ifdef HAVE_DHCP
-    case LOPT_SCRIPTUSR: /* --scriptuser */
-      daemon->scriptuser = opt_string_alloc(arg);
-      break;
-#endif
-      
-    case 'i':  /* --interface */
-      do {
-	struct iname *new = opt_malloc(sizeof(struct iname));
-	comma = split(arg);
-	new->next = daemon->if_names;
-	daemon->if_names = new;
-	/* new->name may be NULL if someone does
-	   "interface=" to disable all interfaces except loop. */
-	new->name = opt_string_alloc(arg);
-	new->isloop = new->used = 0;
-	arg = comma;
-      } while (arg);
-      break;
-      
-    case 'I':  /* --except-interface */
-    case '2':  /* --no-dhcp-interface */
-      do {
-	struct iname *new = opt_malloc(sizeof(struct iname));
-	comma = split(arg);
-	new->name = opt_string_alloc(arg);
-	if (option == 'I')
-	  {
-	    new->next = daemon->if_except;
-	    daemon->if_except = new;
-	  }
-	else
-	  {
-	    new->next = daemon->dhcp_except;
-	    daemon->dhcp_except = new;
-	  }
-	arg = comma;
-      } while (arg);
-      break;
-      
-    case 'B':  /* --bogus-nxdomain */
-      {
-	struct in_addr addr;
-	unhide_metas(arg);
-	if (arg && (addr.s_addr = inet_addr(arg)) != (in_addr_t)-1)
-	  {
-	    struct bogus_addr *baddr = opt_malloc(sizeof(struct bogus_addr));
-	    baddr->next = daemon->bogus_addr;
-	    daemon->bogus_addr = baddr;
-	    baddr->addr = addr;
-	  }
-	else
-	  option = '?'; /* error */
-	break;	
-      }
-      
-    case 'a':  /* --listen-address */
-      do {
-	struct iname *new = opt_malloc(sizeof(struct iname));
-	comma = split(arg);
-	unhide_metas(arg);
-	new->next = daemon->if_addrs;
-	if (arg &&
-	    parse_addr(AF_INET, arg, &new->addr) != 0 &&
-	    parse_addr(AF_INET6, arg, &new->addr) != 0)
-	  {
-	    option = '?'; /* error */
-	    break;
-	  }
-	
-	daemon->if_addrs = new;
-	arg = comma;
-      } while (arg);
-      break;
-      
-    case 'S':        /*  --server */
-    case LOPT_LOCAL: /*  --local */
-    case 'A':        /*  --address */
-      {
-	struct server *serv, *newlist = NULL;
-	
-	unhide_metas(arg);
-	
-	if (arg && *arg == '/')
-	  {
-	    char *end;
-	    arg++;
-	    while ((end = split_chr(arg, '/')))
-	      {
-		char *domain = NULL;
-		/* # matches everything and becomes a zero length domain string */
-		if (strcmp(arg, "#") == 0)
-		  domain = "";
-		else if (strlen (arg) != 0 && !(domain = canonicalise_opt(arg)))
-		  option = '?';
-		serv = opt_malloc(sizeof(struct server));
-		memset(serv, 0, sizeof(struct server));
-		serv->next = newlist;
-		newlist = serv;
-		serv->domain = domain;
-		serv->flags = domain ? SERV_HAS_DOMAIN : SERV_FOR_NODOTS;
-		arg = end;
-	      }
-	    if (!newlist)
-	      {
-		option = '?';
-		break;
-	      }
-	    
-	  }
-	else
-	  {
-	    newlist = opt_malloc(sizeof(struct server));
-	    memset(newlist, 0, sizeof(struct server));
-	  }
-	
-	if (option == 'A')
-	  {
-	    newlist->flags |= SERV_LITERAL_ADDRESS;
-	    if (!(newlist->flags & SERV_TYPE))
-	      option = '?';
-	  }
-	
-	if (!arg || !*arg)
-	  {
-	    newlist->flags |= SERV_NO_ADDR; /* no server */
-	    if (newlist->flags & SERV_LITERAL_ADDRESS)
-	      option = '?';
-	  }
-	else
-	  {
-	    int source_port = 0, serv_port = NAMESERVER_PORT;
-	    char *portno, *source;
-	    
-	    if ((source = split_chr(arg, '@')) && /* is there a source. */
-		(portno = split_chr(source, '#')) &&
-		!atoi_check16(portno, &source_port))
-	      problem = _("bad port");
-	       	    
-	    if ((portno = split_chr(arg, '#')) && /* is there a port no. */
-		!atoi_check16(portno, &serv_port))
-	      problem = _("bad port");
-	    
-	    if (parse_addr(AF_INET, arg, &newlist->addr) == 0)
-	      {
-		newlist->addr.in.sin_port = htons(serv_port);
-		if (source)
-		  {
-		    newlist->flags |= SERV_HAS_SOURCE;
-		    if (parse_addr(AF_INET, source, &newlist->addr) != 0)
-		      {
-#if defined(SO_BINDTODEVICE)
-			newlist->source_addr.in.sin_addr.s_addr = INADDR_ANY;
-			strncpy(newlist->interface, source, IF_NAMESIZE);
-#else
-			problem = _("interface binding not supported");
-#endif
-		      }
-		  }
-		else
-		  newlist->source_addr.in.sin_addr.s_addr = INADDR_ANY;
-
-		newlist->source_addr.in.sin_port = htons(source_port);
-		newlist->source_addr.sa.sa_family = AF_INET;
-	      }
-#ifdef HAVE_IPV6
-	    else if (parse_addr(AF_INET6, arg, &newlist->addr) == 0)
-	      {
-		newlist->addr.in6.sin6_port = htons(serv_port);
-		if (source)
-		  {
-		     newlist->flags |= SERV_HAS_SOURCE;
-		     if (parse_addr(AF_INET6, source, &newlist->source_addr) != 0)
-		      {
-#if defined(SO_BINDTODEVICE)
-			newlist->source_addr.in6.sin6_addr = in6addr_any; 
-			strncpy(newlist->interface, source, IF_NAMESIZE);
-#else
-			problem = _("interface binding not supported");
-#endif
-		      }
-		  }
-		else
-		  newlist->source_addr.in6.sin6_addr = in6addr_any; 
-
-		newlist->source_addr.in6.sin6_port = htons(source_port);
-		newlist->source_addr.sa.sa_family = AF_INET6;
-	      }
-#endif
-	    else
-	      option = '?'; /* error */
-	    
-	  }
-	
-	serv = newlist;
-	while (serv->next)
-	  {
-	    serv->next->flags = serv->flags;
-	    serv->next->addr = serv->addr;
-	    serv->next->source_addr = serv->source_addr;
-	    serv = serv->next;
-	  }
-	serv->next = daemon->servers;
-	daemon->servers = newlist;
-	break;
-      }
-      
-    case 'c':  /* --cache-size */
-      {
-	int size;
-	
-	if (!atoi_check(arg, &size))
-	  option = '?';
-	else
-	  {
-	    /* zero is OK, and means no caching. */
-	    
-	    if (size < 0)
-	      size = 0;
-	    else if (size > 10000)
-	      size = 10000;
-	    
-	    daemon->cachesize = size;
-	  }
-	break;
-      }
-      
-    case 'p':  /* --port */
-      if (!atoi_check16(arg, &daemon->port))
-	option = '?';
-      break;
-    
-    case LOPT_MINPORT:  /* --min-port */
-      if (!atoi_check16(arg, &daemon->min_port))
-	option = '?';
-      break;
-
-    case '0':  /* --dns-forward-max */
-      if (!atoi_check(arg, &daemon->ftabsize))
-	option = '?';
-      break;  
-    
-    case LOPT_MAX_LOGS:  /* --log-async */
-      daemon->max_logs = LOG_MAX; /* default */
-      if (arg && !atoi_check(arg, &daemon->max_logs))
-	option = '?';
-      else if (daemon->max_logs > 100)
-	daemon->max_logs = 100;
-      break;  
-
-    case 'P': /* --edns-packet-max */
-      {
-	int i;
-	if (!atoi_check(arg, &i))
-	  option = '?';
-	daemon->edns_pktsz = (unsigned short)i;	
-	break;
-      }
-      
-    case 'Q':  /* --query-port */
-      if (!atoi_check16(arg, &daemon->query_port))
-	option = '?';
-      /* if explicitly set to zero, use single OS ephemeral port
-	 and disable random ports */
-      if (daemon->query_port == 0)
-	daemon->osport = 1;
-      break;
-      
-    case 'T':         /* --local-ttl */
-    case LOPT_NEGTTL: /* --neg-ttl */
-      {
-	int ttl;
-	if (!atoi_check(arg, &ttl))
-	  option = '?';
-	else if (option == LOPT_NEGTTL)
-	  daemon->neg_ttl = (unsigned long)ttl;
-	else
-	  daemon->local_ttl = (unsigned long)ttl;
-	break;
-      }
-      
-#ifdef HAVE_DHCP
-    case 'X': /* --dhcp-lease-max */
-      if (!atoi_check(arg, &daemon->dhcp_max))
-	option = '?';
-      break;
-#endif
-
-    case LOPT_BRIDGE:   /* --bridge-interface */
-      {
-	struct dhcp_bridge *new = opt_malloc(sizeof(struct dhcp_bridge));
-	if (!(comma = split(arg)))
-	  {
-	    problem = _("bad bridge-interface");
-	    break;
-	  }
-	
-	strncpy(new->iface, arg, IF_NAMESIZE);
-	new->alias = NULL;
-	new->next = daemon->bridges;
-	daemon->bridges = new;
-
-	do {
-	  arg = comma;
-	  comma = split(arg);
-	  if (strlen(arg) != 0)
-	    {
-	      struct dhcp_bridge *b = opt_malloc(sizeof(struct dhcp_bridge)); 
-	      b->next = new->alias;
-	      new->alias = b;
-	      strncpy(b->iface, arg, IF_NAMESIZE);
-	    }
-	} while (comma);
-	
-	break;
-      }
-
-#ifdef HAVE_DHCP
-    case 'F':  /* --dhcp-range */
-      {
-	int k, leasepos = 2;
-	char *cp, *a[5] = { NULL, NULL, NULL, NULL, NULL };
-	struct dhcp_context *new = opt_malloc(sizeof(struct dhcp_context));
-	
-	new->next = daemon->dhcp;
-	new->lease_time = DEFLEASE;
-	new->addr_epoch = 0;
-	new->netmask.s_addr = 0;
-	new->broadcast.s_addr = 0;
-	new->router.s_addr = 0;
-	new->netid.net = NULL;
-	new->filter = NULL;
-	new->flags = 0;
-	
-	gen_prob = _("bad dhcp-range");
-	
-	if (!arg)
-	  {
-	    option = '?';
-	    break;
-	  }
-	
-	while(1)
-	  {
-	    for (cp = arg; *cp; cp++)
-	      if (!(*cp == ' ' || *cp == '.' ||  (*cp >='0' && *cp <= '9')))
-		break;
-	    
-	    if (*cp != ',' && (comma = split(arg)))
-	      {
-		if (strstr(arg, "net:") == arg)
-		  {
-		    struct dhcp_netid *tt = opt_malloc(sizeof (struct dhcp_netid));
-		    tt->net = opt_string_alloc(arg+4);
-		    tt->next = new->filter;
-		    new->filter = tt;
-		  }
-		else
-		  {
-		    if (new->netid.net)
-		      problem = _("only one netid tag allowed");
-		    else
-		      new->netid.net = opt_string_alloc(arg);
-		  }
-		arg = comma;
-	      }
-	    else
-	      {
-		a[0] = arg;
-		break;
-	      }
-	  }
-	
-	for (k = 1; k < 5; k++)
-	  if (!(a[k] = split(a[k-1])))
-	    break;
-	
-	if ((k < 2) || ((new->start.s_addr = inet_addr(a[0])) == (in_addr_t)-1))
-	  option = '?';
-	else if (strcmp(a[1], "static") == 0)
-	  {
-	    new->end = new->start;
-	    new->flags |= CONTEXT_STATIC;
-	  }
-	else if (strcmp(a[1], "proxy") == 0)
-	  {
-	    new->end = new->start;
-	    new->flags |= CONTEXT_PROXY;
-	  }
-	else if ((new->end.s_addr = inet_addr(a[1])) == (in_addr_t)-1)
-	  option = '?';
-	
-	if (ntohl(new->start.s_addr) > ntohl(new->end.s_addr))
-	  {
-	    struct in_addr tmp = new->start;
-	    new->start = new->end;
-	    new->end = tmp;
-	  }
-	
-	if (option != '?' && k >= 3 && strchr(a[2], '.') &&  
-	    ((new->netmask.s_addr = inet_addr(a[2])) != (in_addr_t)-1))
-	  {
-	    new->flags |= CONTEXT_NETMASK;
-	    leasepos = 3;
-	    if (!is_same_net(new->start, new->end, new->netmask))
-	      problem = _("inconsistent DHCP range");
-	  }
-	daemon->dhcp = new;
-	
-	if (k >= 4 && strchr(a[3], '.') &&  
-	    ((new->broadcast.s_addr = inet_addr(a[3])) != (in_addr_t)-1))
-	  {
-	    new->flags |= CONTEXT_BRDCAST;
-	    leasepos = 4;
-	  }
-	
-	if (k >= leasepos+1)
-	  {
-	    if (strcmp(a[leasepos], "infinite") == 0)
-	      new->lease_time = 0xffffffff;
-	    else
-	      {
-		int fac = 1;
-		if (strlen(a[leasepos]) > 0)
-		  {
-		    switch (a[leasepos][strlen(a[leasepos]) - 1])
-		      {
-		      case 'd':
-		      case 'D':
-			fac *= 24;
-			/* fall though */
-		      case 'h':
-		      case 'H':
-			fac *= 60;
-			/* fall through */
-		      case 'm':
-		      case 'M':
-			fac *= 60;
-			/* fall through */
-		      case 's':
-		      case 'S':
-			a[leasepos][strlen(a[leasepos]) - 1] = 0;
-		      }
-		    
-		    new->lease_time = atoi(a[leasepos]) * fac;
-		    /* Leases of a minute or less confuse
-		       some clients, notably Apple's */
-		    if (new->lease_time < 120)
-		      new->lease_time = 120;
-		  }
-	      }
-	  }
-	break;
-      }
-
-    case LOPT_BANK:
-    case 'G':  /* --dhcp-host */
-      {
-	int j, k = 0;
-	char *a[6] = { NULL, NULL, NULL, NULL, NULL, NULL };
-	struct dhcp_config *new;
-	struct in_addr in;
-	
-	new = opt_malloc(sizeof(struct dhcp_config));
-	
-	new->next = daemon->dhcp_conf;
-	new->flags = (option == LOPT_BANK) ? CONFIG_BANK : 0;
-	new->hwaddr = NULL;
-	
-	if ((a[0] = arg))
-	  for (k = 1; k < 6; k++)
-	    if (!(a[k] = split(a[k-1])))
-	      break;
-	
-	for (j = 0; j < k; j++)
-	  if (strchr(a[j], ':')) /* ethernet address, netid or binary CLID */
-	    {
-	      char *arg = a[j];
-	      
-	      if ((arg[0] == 'i' || arg[0] == 'I') &&
-		  (arg[1] == 'd' || arg[1] == 'D') &&
-		  arg[2] == ':')
-		{
-		  if (arg[3] == '*')
-		    new->flags |= CONFIG_NOCLID;
-		  else
-		    {
-		      int len;
-		      arg += 3; /* dump id: */
-		      if (strchr(arg, ':'))
-			len = parse_hex(arg, (unsigned char *)arg, -1, NULL, NULL);
-		      else
-			{
-			  unhide_metas(arg);
-			  len = (int) strlen(arg);
-			}
-
-		      if ((new->clid = opt_malloc(len)))
-			{
-			  new->flags |= CONFIG_CLID;
-			  new->clid_len = len;
-			  memcpy(new->clid, arg, len);
-			}
-		    }
-		}
-	      else if (strstr(arg, "net:") == arg)
-		{
-		  int len = strlen(arg + 4) + 1;
-		  if ((new->netid.net = opt_malloc(len)))
-		    {
-		      new->flags |= CONFIG_NETID;
-		      strcpy(new->netid.net, arg+4);
-		      unhide_metas(new->netid.net);
-		    }
-		}
-	      else 
-		{
-		  struct hwaddr_config *newhw = opt_malloc(sizeof(struct hwaddr_config));
-		  newhw->next = new->hwaddr;
-		  new->hwaddr = newhw;
-		  newhw->hwaddr_len = parse_hex(a[j], newhw->hwaddr, DHCP_CHADDR_MAX, 
-						&newhw->wildcard_mask, &newhw->hwaddr_type);
-		}
-	    }
-	  else if (strchr(a[j], '.') && (in.s_addr = inet_addr(a[j])) != (in_addr_t)-1)
-	    {
-	      new->addr = in;
-	      new->flags |= CONFIG_ADDR;
-	    }
-	  else
-	    {
-	      char *cp, *lastp = NULL, last = 0;
-	      int fac = 1;
-	      
-	      if (strlen(a[j]) > 1)
-		{
-		  lastp = a[j] + strlen(a[j]) - 1;
-		  last = *lastp;
-		  switch (last)
-		    {
-		    case 'd':
-		    case 'D':
-		      fac *= 24;
-		      /* fall through */
-		    case 'h':
-		    case 'H':
-		      fac *= 60;
-		      /* fall through */
-		    case 'm':
-		    case 'M':
-		      fac *= 60;
-		      /* fall through */
-		    case 's':
-		    case 'S':
-		      *lastp = 0;
-		    }
-		}
-	      
-	      for (cp = a[j]; *cp; cp++)
-		if (!isdigit((int)*cp) && *cp != ' ')
-		  break;
-	      
-	      if (*cp)
-		{
-		  if (lastp)
-		    *lastp = last;
-		  if (strcmp(a[j], "infinite") == 0)
-		    {
-		      new->lease_time = 0xffffffff;
-		      new->flags |= CONFIG_TIME;
-		    }
-		  else if (strcmp(a[j], "ignore") == 0)
-		    new->flags |= CONFIG_DISABLE;
-		  else
-		    {
-		      if (!(new->hostname = canonicalise_opt(a[j])) ||
-			  !legal_hostname(new->hostname))
-			problem = _("bad DHCP host name");
-		      else
-			new->flags |= CONFIG_NAME;
-		      new->domain = NULL;			
-		    }
-		}
-	      else
-		{
-		  new->lease_time = atoi(a[j]) * fac; 
-		  /* Leases of a minute or less confuse
-		     some clients, notably Apple's */
-		  if (new->lease_time < 120)
-		    new->lease_time = 120;
-		  new->flags |= CONFIG_TIME;
-		}
-	    }
-	
-	daemon->dhcp_conf = new;
-	break;
-      }
-      
-    case 'O':           /* --dhcp-option */
-    case LOPT_FORCE:    /* --dhcp-option-force */
-    case LOPT_OPTS:
-    case LOPT_MATCH:    /* --dhcp-match */
-      problem = parse_dhcp_opt(arg, 
-			       option == LOPT_FORCE ? DHOPT_FORCE : 
-			       (option == LOPT_MATCH ? DHOPT_MATCH :
-			       (option == LOPT_OPTS ? DHOPT_BANK : 0)));
-      break;
-      
-    case 'M': /* --dhcp-boot */
-      {
-	struct dhcp_netid *id = NULL;
-	while (arg && strstr(arg, "net:") == arg)
-	  {
-	    struct dhcp_netid *newid = opt_malloc(sizeof(struct dhcp_netid));
-	    newid->next = id;
-	    id = newid;
-	    comma = split(arg);
-	    newid->net = opt_string_alloc(arg+4);
-	    arg = comma;
-	  };
-	
-	if (!arg)
-	  option = '?';
-	else 
-	  {
-	    char *dhcp_file, *dhcp_sname = NULL;
-	    struct in_addr dhcp_next_server;
-	    comma = split(arg);
-	    dhcp_file = opt_string_alloc(arg);
-	    dhcp_next_server.s_addr = 0;
-	    if (comma)
-	      {
-		arg = comma;
-		comma = split(arg);
-		dhcp_sname = opt_string_alloc(arg);
-		if (comma)
-		  {
-		    unhide_metas(comma);
-		    if ((dhcp_next_server.s_addr = inet_addr(comma)) == (in_addr_t)-1)
-		      option = '?';
-		  }
-	      }
-	    if (option != '?')
-	      {
-		struct dhcp_boot *new = opt_malloc(sizeof(struct dhcp_boot));
-		new->file = dhcp_file;
-		new->sname = dhcp_sname;
-		new->next_server = dhcp_next_server;
-		new->netid = id;
-		new->next = daemon->boot_config;
-		daemon->boot_config = new;
-	      }
-	  }
-	
-	break;
-      }
-
-    case LOPT_PXE_PROMT:  /* --pxe-prompt */
-       {
-	 struct dhcp_opt *new = opt_malloc(sizeof(struct dhcp_opt));
-	 int timeout;
-
-	 new->netid = NULL;
-	 new->opt = 10; /* PXE_MENU_PROMPT */
-
-	 while (arg && strstr(arg, "net:") == arg)
-	   {
-	     struct dhcp_netid *nn = opt_malloc(sizeof (struct dhcp_netid));
-	     comma = split(arg);
-	     nn->next = new->netid;
-	     new->netid = nn;
-	     nn->net = opt_string_alloc(arg+4);
-	     arg = comma;
-	   }
-	 
-	 if (!arg)
-	   option = '?';
-	 else
-	   {
-	     comma = split(arg);
-	     unhide_metas(arg);
-	     new->len = strlen(arg) + 1;
-	     new->val = opt_malloc(new->len);
-	     memcpy(new->val + 1, arg, new->len - 1);
-	     
-	     new->u.vendor_class = (unsigned char *)"PXEClient";
-	     new->flags = DHOPT_VENDOR;
-	     
-	     if (comma && atoi_check(comma, &timeout))
-	       *(new->val) = timeout;
-	     else
-	       *(new->val) = 255;
-
-	     new->next = daemon->dhcp_opts;
-	     daemon->dhcp_opts = new;
-	     daemon->enable_pxe = 1;
-	   }
-	 
-	 break;
-       }
-       
-    case LOPT_PXE_SERV:  /* --pxe-service */
-       {
-	 struct pxe_service *new = opt_malloc(sizeof(struct pxe_service));
-	 char *CSA[] = { "x86PC", "PC98", "IA64_EFI", "Alpha", "Arc_x86", "Intel_Lean_Client",
-			 "IA32_EFI", "BC_EFI", "Xscale_EFI", "x86-64_EFI", NULL };  
-	 static int boottype = 32768;
-	 
-	 new->netid = NULL;
-	 new->server.s_addr = 0;
-
-	 while (arg && strstr(arg, "net:") == arg)
-	   {
-	     struct dhcp_netid *nn = opt_malloc(sizeof (struct dhcp_netid));
-	     comma = split(arg);
-	     nn->next = new->netid;
-	     new->netid = nn;
-	     nn->net = opt_string_alloc(arg+4);
-	     arg = comma;
-	   }
-       
-	 if (arg && (comma = split(arg)))
-	   {
-	     for (i = 0; CSA[i]; i++)
-	       if (strcasecmp(CSA[i], arg) == 0)
-		 break;
-	     
-	     if (CSA[i] || atoi_check(arg, &i))
-	       {
-		 arg = comma;
-		 comma = split(arg);
-		 
-		 new->CSA = i;
-		 new->menu = opt_string_alloc(arg);
-		 
-		 if (comma)
-		   {
-		     arg = comma;
-		     comma = split(arg);
-		     if (atoi_check(arg, &i))
-		       {
-			 new->type = i;
-			 new->basename = NULL;
-		       }
-		     else
-		       {
-			 new->type = boottype++;
-			 new->basename = opt_string_alloc(arg);
-		       }
-		     
-		     if (comma && (new->server.s_addr = inet_addr(comma)) == (in_addr_t)-1)
-		       option = '?';
-		     
-		     /* Order matters */
-		     new->next = NULL;
-		     if (!daemon->pxe_services)
-		       daemon->pxe_services = new; 
-		     else
-		       {
-			 struct pxe_service *s;
-			 for (s = daemon->pxe_services; s->next; s = s->next);
-			 s->next = new;
-		       }
-		     
-		     daemon->enable_pxe = 1;
-		     break;
-		   }
-	       }
-	   }
-	 
-	 option = '?';
-	 break;
-       }
-	 
-    case '4':  /* --dhcp-mac */
-      {
-	if (!(comma = split(arg)))
-	  option = '?';
-	else
-	  {
-	    struct dhcp_mac *new = opt_malloc(sizeof(struct dhcp_mac));
-	    if (strstr(arg, "net:") == arg)
-	      new->netid.net = opt_string_alloc(arg+4);
-	    else
-	      new->netid.net = opt_string_alloc(arg);
-	    unhide_metas(comma);
-	    new->hwaddr_len = parse_hex(comma, new->hwaddr, DHCP_CHADDR_MAX, &new->mask, &new->hwaddr_type);
-	    new->next = daemon->dhcp_macs;
-	    daemon->dhcp_macs = new;
-	  }
-      }
-      break;
-      
-    case 'U':           /* --dhcp-vendorclass */
-    case 'j':           /* --dhcp-userclass */
-    case LOPT_CIRCUIT:  /* --dhcp-circuitid */
-    case LOPT_REMOTE:   /* --dhcp-remoteid */
-    case LOPT_SUBSCR:   /* --dhcp-subscrid */
-      {
-	if (!(comma = split(arg)))
-	  option = '?';
-	else
-	  {
-	    char *p;
-	    int dig = 0;
-	    struct dhcp_vendor *new = opt_malloc(sizeof(struct dhcp_vendor));
-	    if (strstr(arg, "net:") == arg)
-	      new->netid.net = opt_string_alloc(arg+4);
-	    else
-	      new->netid.net = opt_string_alloc(arg);
-	    /* check for hex string - must digits may include : must not have nothing else, 
-	       only allowed for agent-options. */
-	    for (p = comma; *p; p++)
-	      if (isxdigit((int)*p))
-		dig = 1;
-	      else if (*p != ':')
-		break;
-	    unhide_metas(comma);
-	    if (option == 'U' || option == 'j' || *p || !dig)
-	      {
-		new->len = strlen(comma);  
-		new->data = opt_malloc(new->len);
-		memcpy(new->data, comma, new->len);
-	      }
-	    else
-	      {
-		new->len = parse_hex(comma, (unsigned char *)comma, strlen(comma), NULL, NULL);
-		new->data = opt_malloc(new->len);
-		memcpy(new->data, comma, new->len);
-	      }
-
-	    switch (option)
-	      {
-	      case 'j':
-		new->match_type = MATCH_USER;
-		break;
-	      case 'U':
-		new->match_type = MATCH_VENDOR;
-		break; 
-	      case LOPT_CIRCUIT:
-		new->match_type = MATCH_CIRCUIT;
-		break;
-	      case LOPT_REMOTE:
-		new->match_type = MATCH_REMOTE;
-		break;
-	      case LOPT_SUBSCR:
-		new->match_type = MATCH_SUBSCRIBER;
-		break;
-	      }
-	    new->next = daemon->dhcp_vendors;
-	    daemon->dhcp_vendors = new;
-	  }
-	break;
-      }
-      
-    case LOPT_ALTPORT:   /* --dhcp-alternate-port */
-      if (!arg)
-	{
-	  daemon->dhcp_server_port = DHCP_SERVER_ALTPORT;
-	  daemon->dhcp_client_port = DHCP_CLIENT_ALTPORT;
-	}
-      else
-	{
-	  comma = split(arg);
-	  if (!atoi_check16(arg, &daemon->dhcp_server_port) || 
-	      (comma && !atoi_check16(comma, &daemon->dhcp_client_port)))
-	    problem = _("invalid port number");
-	  if (!comma)
-	    daemon->dhcp_client_port = daemon->dhcp_server_port+1; 
-	}
-      break;
-
-    case 'J':            /* --dhcp-ignore */
-    case LOPT_NO_NAMES:  /* --dhcp-ignore-names */
-    case LOPT_BROADCAST: /* --dhcp-broadcast */
-    case '3':            /* --bootp-dynamic */ 
-      {
-	struct dhcp_netid_list *new = opt_malloc(sizeof(struct dhcp_netid_list));
-	struct dhcp_netid *list = NULL;
-	if (option == 'J')
-	  {
-	    new->next = daemon->dhcp_ignore;
-	    daemon->dhcp_ignore = new;
-	  }
-	else if (option == LOPT_BROADCAST)
-	  {
-	    new->next = daemon->force_broadcast;
-	    daemon->force_broadcast = new;
-	  }
-	else if (option == '3')
-	  {
-	    new->next = daemon->bootp_dynamic;
-	    daemon->bootp_dynamic = new;
-	  }
-	else
-	  {
-	    new->next = daemon->dhcp_ignore_names;
-	    daemon->dhcp_ignore_names = new;
-	  }
-	
-	while (arg) {
-	  struct dhcp_netid *member = opt_malloc(sizeof(struct dhcp_netid));
-	  comma = split(arg);
-	  member->next = list;
-	  list = member;
-	  if (strstr(arg, "net:") == arg)
-	    member->net = opt_string_alloc(arg+4);
-	  else
-	    member->net = opt_string_alloc(arg);
-	  arg = comma;
-	}
-	
-	new->list = list;
-	break;
-      }
-#endif
-      
-    case 'V':  /* --alias */
-      {
-	char *dash, *a[3] = { NULL, NULL, NULL };
-	int k = 0;
-	struct doctor *new = opt_malloc(sizeof(struct doctor));
-	new->next = daemon->doctors;
-	daemon->doctors = new;
-	new->mask.s_addr = 0xffffffff;
-	new->end.s_addr = 0;
-
-	if ((a[0] = arg))
-	  for (k = 1; k < 3; k++)
-	    {
-	      if (!(a[k] = split(a[k-1])))
-		break;
-	      unhide_metas(a[k]);
-	    }
-	
-	dash = split_chr(a[0], '-');
-
-	if ((k < 2) || 
-	    ((new->in.s_addr = inet_addr(a[0])) == (in_addr_t)-1) ||
-	    ((new->out.s_addr = inet_addr(a[1])) == (in_addr_t)-1))
-	  option = '?';
-	
-	if (k == 3)
-	  new->mask.s_addr = inet_addr(a[2]);
-	
-	if (dash && 
-	    ((new->end.s_addr = inet_addr(dash)) == (in_addr_t)-1 ||
-	     !is_same_net(new->in, new->end, new->mask) ||
-	     ntohl(new->in.s_addr) > ntohl(new->end.s_addr)))
-	  problem = _("invalid alias range");
-	
-	break;
-      }
-      
-    case LOPT_INTNAME:  /* --interface-name */
-      {
-	struct interface_name *new, **up;
-	char *domain = NULL;
-
-	comma = split(arg);
-	
-	if (!comma || !(domain = canonicalise_opt(arg)))
-	  problem = _("bad interface name");
-	
-	new = opt_malloc(sizeof(struct interface_name));
-	new->next = NULL;
-	/* Add to the end of the list, so that first name
-	   of an interface is used for PTR lookups. */
-	for (up = &daemon->int_names; *up; up = &((*up)->next));
-	*up = new;
-	new->name = domain;
-	new->intr = opt_string_alloc(comma);
-	break;
-      }
-      
-    case LOPT_CNAME: /* --cname */
-      {
-	struct cname *new;
-	
-	if (!(comma = split(arg)))
-	  option = '?';
-	else
-	  {
-	    char *alias = canonicalise_opt(arg);
-	    char *target = canonicalise_opt(comma);
-	    
-	    if (!alias || !target)
-	      problem = _("bad CNAME");
-	    else
-	      {
-		for (new = daemon->cnames; new; new = new->next)
-		  if (hostname_isequal(new->alias, arg))
-		    problem = _("duplicate CNAME");
-		new = opt_malloc(sizeof(struct cname));
-		new->next = daemon->cnames;
-		daemon->cnames = new;
-		new->alias = alias;
-		new->target = target;
-	      }
-	  }
-	break;
-      }
-
-    case LOPT_PTR:  /* --ptr-record */
-      {
-	struct ptr_record *new;
-	char *dom, *target = NULL;
-
-	comma = split(arg);
-	
-	if (!(dom = canonicalise_opt(arg)) ||
-	    (comma && !(target = canonicalise_opt(comma))))
-	  problem = _("bad PTR record");
-	else
-	  {
-	    new = opt_malloc(sizeof(struct ptr_record));
-	    new->next = daemon->ptr;
-	    daemon->ptr = new;
-	    new->name = dom;
-	    new->ptr = target;
-	  }
-	break;
-      }
-
-    case LOPT_NAPTR: /* --naptr-record */
-      {
-	char *a[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
-	int k = 0;
-	struct naptr *new;
-	int order, pref;
-	char *name, *replace = NULL;
-
-	if ((a[0] = arg))
-	  for (k = 1; k < 7; k++)
-	    if (!(a[k] = split(a[k-1])))
-	      break;
-	
-	
-	if (k < 6 || 
-	    !(name = canonicalise_opt(a[0])) ||
-	    !atoi_check16(a[1], &order) || 
-	    !atoi_check16(a[2], &pref) ||
-	    (k == 7 && !(replace = canonicalise_opt(a[6]))))
-	  problem = _("bad NAPTR record");
-	else
-	  {
-	    new = opt_malloc(sizeof(struct naptr));
-	    new->next = daemon->naptr;
-	    daemon->naptr = new;
-	    new->name = name;
-	    new->flags = opt_string_alloc(a[3]);
-	    new->services = opt_string_alloc(a[4]);
-	    new->regexp = opt_string_alloc(a[5]);
-	    new->replace = replace;
-	    new->order = order;
-	    new->pref = pref;
-	  }
-	break;
-      }
-       
-    case 'Y':  /* --txt-record */
-      {
-	struct txt_record *new;
-	unsigned char *p, *q;
-	
-	if ((comma = split(arg)))
-	  comma--;
-	
-	gen_prob = _("TXT record string too long");
-	
-	if ((q = (unsigned char *)comma))
-	  while (1)
-	    {
-	      size_t len;
-	      if ((p = (unsigned char *)strchr((char*)q+1, ',')))
-		{
-		  if ((len = p - q - 1) > 255)
-		    option = '?';
-		  *q = len;
-		  for (q = q+1; q < p; q++)
-		    *q = unhide_meta(*q);
-		}
-	      else
-		{
-		  if ((len = strlen((char *)q+1)) > 255)
-		    option = '?';
-		  *q = len;
-		  for (q = q+1; *q; q++)
-		    *q = unhide_meta(*q);
-		  break;
-		}
-	    }
-	
-	new = opt_malloc(sizeof(struct txt_record));
-	new->next = daemon->txt;
-	daemon->txt = new;
-	new->class = C_IN;
-	if (comma)
-	  {
-	    new->len = q - ((unsigned char *)comma);
-	    new->txt = opt_malloc(new->len);
-	    memcpy(new->txt, comma, new->len);
-	  }
-	else
-	  {
-	    static char empty[] = "";
-	    new->len = 1;
-	    new->txt = empty;
-	  }
-	
-	/* ensure arg is terminated */
-	if (comma)
-	  *comma = 0;
-
-	if (!(new->name = canonicalise_opt(arg)))
-	  {
-	    problem = _("bad TXT record");
-	    break;
-	  }
-
-	break;
-      }
-      
-    case 'W':  /* --srv-host */
-      {
-	int port = 1, priority = 0, weight = 0;
-	char *name, *target = NULL;
-	struct mx_srv_record *new;
-	
-	comma = split(arg);
-	
-	if (!(name = canonicalise_opt(arg)))
-	  problem = _("bad SRV record");
-	  
-	if (comma)
-	  {
-	    arg = comma;
-	    comma = split(arg);
-	    if (!(target = canonicalise_opt(arg))
-)	      problem = _("bad SRV target");
-		
-	    if (comma)
-	      {
-		arg = comma;
-		comma = split(arg);
-		if (!atoi_check16(arg, &port))
-		  problem = _("invalid port number");
-		
-		if (comma)
-		  {
-		    arg = comma;
-		    comma = split(arg);
-		    if (!atoi_check16(arg, &priority))
-		      problem = _("invalid priority");
-			
-		    if (comma)
-		      {
-			arg = comma;
-			comma = split(arg);
-			if (!atoi_check16(arg, &weight))
-			  problem = _("invalid weight");
-		      }
-		  }
-	      }
-	  }
-	
-	new = opt_malloc(sizeof(struct mx_srv_record));
-	new->next = daemon->mxnames;
-	daemon->mxnames = new;
-	new->issrv = 1;
-	new->name = name;
-	new->target = target;
-	new->srvport = port;
-	new->priority = priority;
-	new->weight = weight;
-	break;
-      }
-      
-    case LOPT_LISTNMARK: /* --listen-mark */
-      {
-	char *endptr;
-	uint32_t mark = strtoul(arg, &endptr, 0);
-        // my_syslog(LOG_WARNING, "passed-in mark: %s", arg);
-	if (!*endptr)
-	  daemon->listen_mark = mark;
-	else
-	  problem = _("invalid mark");
-        // my_syslog(LOG_WARNING, "daemon->listen_mark: 0x%x, *endptr=%d", daemon->listen_mark, *endptr);
-	break;
-      }
-
-    default:
-      return _("unsupported option (check that dnsmasq was compiled with DHCP support)");
-
-    }
-
-  if (problem)
-    return problem;
-  
-  if (option == '?')
-    return gen_prob;
-
-  return NULL;
-}
-
-static void one_file(char *file, int nest, int hard_opt)	
-{
-  volatile int lineno = 0;
-  int i, option; 
-  FILE *f;
-  char *p, *arg, *start, *buff = daemon->namebuff;
-  static struct fileread {
-    dev_t dev;
-    ino_t ino;
-    struct fileread *next;
-  } *filesread = NULL;
-  struct stat statbuf;
-  
-  /* ignore repeated files. */
-  if (hard_opt == 0 && stat(file, &statbuf) == 0)
-    {
-      struct fileread *r;
-
-      for (r = filesread; r; r = r->next)
-	if (r->dev == statbuf.st_dev && r->ino == statbuf.st_ino)
-	  return;
-
-      r = safe_malloc(sizeof(struct fileread));
-      r->next = filesread;
-      filesread = r;
-      r->dev = statbuf.st_dev;
-      r->ino = statbuf.st_ino;
-    }
-
-  if (nest > 20)
-    die(_("files nested too deep in %s"), file, EC_BADCONF);
-
-  if (!(f = fopen(file, "r")))
-    {   
-      if (errno == ENOENT && nest == 0)
-	return; /* No conffile, all done. */
-      else
-	{
-	  char *str = _("cannot read %s: %s");
-	  if (hard_opt != 0)
-	    {
-	      my_syslog(LOG_ERR, str, file, strerror(errno));
-	      return;
-	    }
-	  else
-	    die(str, file, EC_FILE);
-	}
-    } 
-  
-  while (fgets(buff, MAXDNAME, f))
-    {
-      int white;
-      unsigned int lastquote;
-      char *errmess;
-
-      /* Memory allocation failure longjmps here if mem_recover == 1 */ 
-      if (hard_opt)
-	{
-	  if (setjmp(mem_jmp))
-	    continue;
-	  mem_recover = 1;
-	}
-      
-      lineno++;
-      errmess = NULL;
-      
-      /* Implement quotes, inside quotes we allow \\ \" \n and \t 
-	 metacharacters get hidden also strip comments */
-      
-      for (white = 1, lastquote = 0, p = buff; *p; p++)
-	{
-	  if (*p == '"')
-	    {
-	      memmove(p, p+1, strlen(p+1)+1);
-	      for(; *p && *p != '"'; p++)
-		{
-		  if (*p == '\\' && strchr("\"tnebr\\", p[1]))
-		    {
-		      if (p[1] == 't')
-			p[1] = '\t';
-		      else if (p[1] == 'n')
-			p[1] = '\n';
-		      else if (p[1] == 'b')
-			p[1] = '\b';
-		      else if (p[1] == 'r')
-			p[1] = '\r';
-		      else if (p[1] == 'e') /* escape */
-			p[1] = '\033';
-		      memmove(p, p+1, strlen(p+1)+1);
-		    }
-		  *p = hide_meta(*p);
-		}
-	      if (*p == '"') 
-		{
-		  memmove(p, p+1, strlen(p+1)+1);
-		  lastquote = p - buff;
-		}
-	      else
-		{
-		  errmess = _("missing \"");
-		  goto oops; 
-		}
-	    }
-
-	  if (white && *p == '#')
-	    { 
-	      *p = 0;
-	      break;
-	    }
-	  white = isspace((int)unhide_meta(*p)); 
-	}
-
-      /* fgets gets end of line char too. */
-      while (strlen(buff) > lastquote && isspace((int)unhide_meta(buff[strlen(buff)-1])))
-	buff[strlen(buff)-1] = 0;
-
-      if (*buff == 0)
-	continue; 
-
-      if (hard_opt != 0)
-	arg = buff;
-      else if ((p=strchr(buff, '=')))
-	{
-	  /* allow spaces around "=" */
-	  arg = p+1;
-	  for (; p >= buff && (isspace((int)*p) || *p == '='); p--)
-	    *p = 0;
-	}
-      else
-	arg = NULL;
-
-      if (hard_opt != 0)
-	option = hard_opt;
-      else
-	{
-	  /* skip leading space */
-	  for (start = buff; *start && isspace((int)*start); start++);
-	  
-	  for (option = 0, i = 0; opts[i].name; i++) 
-	    if (strcmp(opts[i].name, start) == 0)
-	      {
-		option = opts[i].val;
-		break;
-	      }
-	  
-	  if (!option)
-	    errmess = _("bad option");
-	  else if (opts[i].has_arg == 0 && arg)
-	    errmess = _("extraneous parameter");
-	  else if (opts[i].has_arg == 1 && !arg)
-	    errmess = _("missing parameter");
-	}
-	  
-      if (!errmess)
-	{
-	  if (arg)
-	    for (; isspace((int)*arg); arg++);
-	  
-	  errmess = one_opt(option, arg, _("error"), nest + 1);
-	}
-      
-      if (errmess)
-	{
-	oops:
-	  sprintf(buff, _("%s at line %d of %%s"), errmess, lineno);
-	  if (hard_opt != 0)
-	    my_syslog(LOG_ERR, buff, file);
-	  else
-	    die(buff, file, EC_BADCONF);
-	}
-    }
-
-  mem_recover = 1;
-  fclose(f);
-}
-
-#ifdef HAVE_DHCP
-void reread_dhcp(void)
-{
-  if (daemon->dhcp_hosts_file)
-    {
-      struct dhcp_config *configs, *cp, **up;
-      
-      /* remove existing... */
-      for (up = &daemon->dhcp_conf, configs = daemon->dhcp_conf; configs; configs = cp)
-	{
-	  cp = configs->next;
-	  
-	  if (configs->flags & CONFIG_BANK)
-	    {
-	      struct hwaddr_config *mac, *tmp;
-	      
-	      for (mac = configs->hwaddr; mac; mac = tmp)
-		{
-		  tmp = mac->next;
-		  free(mac);
-		}
-	      if (configs->flags & CONFIG_CLID)
-		free(configs->clid);
-	      if (configs->flags & CONFIG_NETID)
-		free(configs->netid.net);
-	      if (configs->flags & CONFIG_NAME)
-		free(configs->hostname);
-	      
-     
-	      *up = configs->next;
-	      free(configs);
-	    }
-	  else
-	    up = &configs->next;
-	}
-      
-      one_file(daemon->dhcp_hosts_file, 1, LOPT_BANK);  
-      my_syslog(MS_DHCP | LOG_INFO, _("read %s"), daemon->dhcp_hosts_file);
-    }
-
-  if (daemon->dhcp_opts_file)
-    {
-      struct dhcp_opt *opts, *cp, **up;
-      struct dhcp_netid *id, *next;
-
-      for (up = &daemon->dhcp_opts, opts = daemon->dhcp_opts; opts; opts = cp)
-	{
-	  cp = opts->next;
-	  
-	  if (opts->flags & DHOPT_BANK)
-	    {
-	      if ((opts->flags & DHOPT_VENDOR))
-		free(opts->u.vendor_class);
-	      free(opts->val);
-	      for (id = opts->netid; id; id = next)
-		{
-		  next = id->next;
-		  free(id->net);
-		  free(id);
-		}
-	      *up = opts->next;
-	      free(opts);
-	    }
-	  else
-	    up = &opts->next;
-	}
-      
-      one_file(daemon->dhcp_opts_file, 1, LOPT_OPTS);  
-      my_syslog(MS_DHCP | LOG_INFO, _("read %s"), daemon->dhcp_opts_file);
-    }
-}
-#endif
-    
-void read_opts(int argc, char **argv, char *compile_opts)
-{
-  char *buff = opt_malloc(MAXDNAME);
-  int option, nest = 0, testmode = 0;
-  char *errmess, *arg, *conffile = CONFFILE;
-      
-  opterr = 0;
-
-  daemon = opt_malloc(sizeof(struct daemon));
-  memset(daemon, 0, sizeof(struct daemon));
-  daemon->namebuff = buff;
-
-  /* Set defaults - everything else is zero or NULL */
-  daemon->cachesize = CACHESIZ;
-  daemon->ftabsize = FTABSIZ;
-  daemon->port = NAMESERVER_PORT;
-  daemon->dhcp_client_port = DHCP_CLIENT_PORT;
-  daemon->dhcp_server_port = DHCP_SERVER_PORT;
-  daemon->default_resolv.is_default = 1;
-  daemon->default_resolv.name = RESOLVFILE;
-  daemon->resolv_files = &daemon->default_resolv;
-  daemon->username = CHUSER;
-  daemon->runfile =  RUNFILE;
-  daemon->dhcp_max = MAXLEASES;
-  daemon->edns_pktsz = EDNS_PKTSZ;
-  daemon->log_fac = -1;
-  add_txt("version.bind", "dnsmasq-" VERSION );
-  add_txt("authors.bind", "Simon Kelley");
-  add_txt("copyright.bind", COPYRIGHT);
-
-  while (1) 
-    {
-#ifdef HAVE_GETOPT_LONG
-      option = getopt_long(argc, argv, OPTSTRING, opts, NULL);
-#else
-      option = getopt(argc, argv, OPTSTRING);
-#endif
-      
-      if (option == -1)
-	break;
-      
-      /* Copy optarg so that argv doesn't get changed */
-      if (optarg)
-	{
-	  strncpy(buff, optarg, MAXDNAME);
-	  buff[MAXDNAME-1] = 0;
-	  arg = buff;
-	}
-      else
-	arg = NULL;
-      
-      /* command-line only stuff */
-      if (option == LOPT_TEST)
-	testmode = 1;
-      else if (option == 'w')
-	{
-	  if (argc != 3 ||  strcmp(argv[2], "dhcp") != 0)
-	    do_usage();
-#ifdef HAVE_DHCP
-	  else
-	    display_opts();
-#endif
-	  exit(0);
-	}
-      else if (option == 'v')
-	{
-	  printf(_("Dnsmasq version %s  %s\n"), VERSION, COPYRIGHT);
-	  printf(_("Compile time options %s\n\n"), compile_opts); 
-	  printf(_("This software comes with ABSOLUTELY NO WARRANTY.\n"));
-	  printf(_("Dnsmasq is free software, and you are welcome to redistribute it\n"));
-	  printf(_("under the terms of the GNU General Public License, version 2 or 3.\n"));
-          exit(0);
+        if (!*cp) {
+            new->opt = atoi(arg);
+            opt_len = 0;
+            break;
         }
-      else if (option == 'C')
-	{
-	  conffile = opt_string_alloc(arg);
-	  nest++;
-	}
-      else
-	{
+
+        if (strstr(arg, "option:") == arg) {
+            for (i = 0; opttab[i].name; i++)
+                if (!(opttab[i].size & OT_INTERNAL) && strcasecmp(opttab[i].name, arg + 7) == 0) {
+                    new->opt = opttab[i].val;
+                    opt_len = opttab[i].size;
+                    break;
+                }
+            /* option:<optname> must follow tag and vendor string. */
+            break;
+        } else if (strstr(arg, "vendor:") == arg) {
+            new->u.vendor_class = (unsigned char*) opt_string_alloc(arg + 7);
+            new->flags |= DHOPT_VENDOR;
+        } else if (strstr(arg, "encap:") == arg) {
+            new->u.encap = atoi(arg + 6);
+            new->flags |= DHOPT_ENCAPSULATE;
+        } else {
+            new->netid = opt_malloc(sizeof(struct dhcp_netid));
+            /* allow optional "net:" for consistency */
+            if (strstr(arg, "net:") == arg)
+                new->netid->net = opt_string_alloc(arg + 4);
+            else
+                new->netid->net = opt_string_alloc(arg);
+            new->netid->next = np;
+            np = new->netid;
+        }
+
+        arg = comma;
+    }
+
+    if (new->opt == 0)
+        problem = _("bad dhcp-option");
+    else if (comma) {
+        /* characterise the value */
+        char c;
+        is_addr = is_hex = is_dec = is_string = 1;
+        addrs = digs = 1;
+        dots = 0;
+        for (cp = comma; (c = *cp); cp++)
+            if (c == ',') {
+                addrs++;
+                is_dec = is_hex = 0;
+            } else if (c == ':') {
+                digs++;
+                is_dec = is_addr = 0;
+            } else if (c == '/') {
+                is_dec = is_hex = 0;
+                if (cp == comma) /* leading / means a pathname */
+                    is_addr = 0;
+            } else if (c == '.') {
+                is_dec = is_hex = 0;
+                dots++;
+            } else if (c == '-')
+                is_hex = is_addr = 0;
+            else if (c == ' ')
+                is_dec = is_hex = 0;
+            else if (!(c >= '0' && c <= '9')) {
+                is_addr = 0;
+                if (cp[1] == 0 && is_dec && (c == 'b' || c == 's' || c == 'i')) {
+                    lenchar = c;
+                    *cp = 0;
+                } else
+                    is_dec = 0;
+                if (!((c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f') ||
+                      (c == '*' && (flags & DHOPT_MATCH))))
+                    is_hex = 0;
+            }
+
+        /* We know that some options take addresses */
+
+        if (opt_len & OT_ADDR_LIST) {
+            is_string = is_dec = is_hex = 0;
+            if (!is_addr || dots == 0) problem = _("bad IP address");
+        }
+
+        if (is_hex && digs > 1) {
+            new->len = digs;
+            new->val = opt_malloc(new->len);
+            parse_hex(comma, new->val, digs, (flags & DHOPT_MATCH) ? &new->u.wildcard_mask : NULL,
+                      NULL);
+            new->flags |= DHOPT_HEX;
+        } else if (is_dec) {
+            int i, val = atoi(comma);
+            /* assume numeric arg is 1 byte except for
+               options where it is known otherwise.
+               For vendor class option, we have to hack. */
+            if (opt_len != 0)
+                new->len = opt_len;
+            else if (val & 0xffff0000)
+                new->len = 4;
+            else if (val & 0xff00)
+                new->len = 2;
+            else
+                new->len = 1;
+
+            if (lenchar == 'b')
+                new->len = 1;
+            else if (lenchar == 's')
+                new->len = 2;
+            else if (lenchar == 'i')
+                new->len = 4;
+
+            new->val = opt_malloc(new->len);
+            for (i = 0; i < new->len; i++) new->val[i] = val >> ((new->len - i - 1) * 8);
+        } else if (is_addr) {
+            struct in_addr in;
+            unsigned char* op;
+            char* slash;
+            /* max length of address/subnet descriptor is five bytes,
+               add one for the option 120 enc byte too */
+            new->val = op = opt_malloc((5 * addrs) + 1);
+            new->flags |= DHOPT_ADDR;
+
+            if (!(new->flags& DHOPT_ENCAPSULATE) && new->opt == 120) {
+                *(op++) = 1; /* RFC 3361 "enc byte" */
+                new->flags &= ~DHOPT_ADDR;
+            }
+            while (addrs--) {
+                cp = comma;
+                comma = split(cp);
+                slash = split_chr(cp, '/');
+                in.s_addr = inet_addr(cp);
+                if (!slash) {
+                    memcpy(op, &in, INADDRSZ);
+                    op += INADDRSZ;
+                } else {
+                    unsigned char* p = (unsigned char*) &in;
+                    int netsize = atoi(slash);
+                    *op++ = netsize;
+                    if (netsize > 0) *op++ = *p++;
+                    if (netsize > 8) *op++ = *p++;
+                    if (netsize > 16) *op++ = *p++;
+                    if (netsize > 24) *op++ = *p++;
+                    new->flags &= ~DHOPT_ADDR; /* cannot re-write descriptor format */
+                }
+            }
+            new->len = op - new->val;
+        } else if (is_string) {
+            /* text arg */
+            if ((new->opt == 119 || new->opt == 120) && !(new->flags& DHOPT_ENCAPSULATE)) {
+                /* dns search, RFC 3397, or SIP, RFC 3361 */
+                unsigned char *q, *r, *tail;
+                unsigned char *p, *m = NULL, *newp;
+                size_t newlen, len = 0;
+                int header_size = (new->opt == 119) ? 0 : 1;
+
+                arg = comma;
+                comma = split(arg);
+
+                while (arg && *arg) {
+                    char* dom;
+                    if (!(dom = arg = canonicalise_opt(arg))) {
+                        problem = _("bad domain in dhcp-option");
+                        break;
+                    }
+
+                    newp = opt_malloc(len + strlen(arg) + 2 + header_size);
+                    if (m) memcpy(newp, m, header_size + len);
+                    m = newp;
+                    p = m + header_size;
+                    q = p + len;
+
+                    /* add string on the end in RFC1035 format */
+                    while (*arg) {
+                        unsigned char* cp = q++;
+                        int j;
+                        for (j = 0; *arg && (*arg != '.'); arg++, j++) *q++ = *arg;
+                        *cp = j;
+                        if (*arg) arg++;
+                    }
+                    *q++ = 0;
+                    free(dom);
+
+                    /* Now tail-compress using earlier names. */
+                    newlen = q - p;
+                    for (tail = p + len; *tail; tail += (*tail) + 1)
+                        for (r = p; r - p < (int) len; r += (*r) + 1)
+                            if (strcmp((char*) r, (char*) tail) == 0) {
+                                PUTSHORT((r - p) | 0xc000, tail);
+                                newlen = tail - p;
+                                goto end;
+                            }
+                end:
+                    len = newlen;
+
+                    arg = comma;
+                    comma = split(arg);
+                }
+
+                /* RFC 3361, enc byte is zero for names */
+                if (new->opt == 120) m[0] = 0;
+                new->len = (int) len + header_size;
+                new->val = m;
+            } else {
+                new->len = strlen(comma);
+                /* keep terminating zero on string */
+                new->val = (unsigned char*) opt_string_alloc(comma);
+                new->flags |= DHOPT_STRING;
+            }
+        }
+    }
+
+    if ((new->len > 255) || (new->len > 253 && (new->flags&(DHOPT_VENDOR | DHOPT_ENCAPSULATE))))
+        problem = _("dhcp-option too long");
+
+    if (!problem) {
+        if (flags == DHOPT_MATCH) {
+            if ((new->flags&(DHOPT_ENCAPSULATE | DHOPT_VENDOR)) || !new->netid || new->netid->next)
+                problem = _("illegal dhcp-match");
+            else {
+                new->next = daemon->dhcp_match;
+                daemon->dhcp_match = new;
+            }
+        } else {
+            new->next = daemon->dhcp_opts;
+            daemon->dhcp_opts = new;
+        }
+    }
+
+    return problem;
+}
+
+#endif
+
+static char* one_opt(int option, char* arg, char* gen_prob, int nest) {
+    int i;
+    char *comma, *problem = NULL;
+    ;
+
+    if (option == '?') return gen_prob;
+
+    for (i = 0; usage[i].opt != 0; i++)
+        if (usage[i].opt == option) {
+            int rept = usage[i].rept;
+
+            if (nest == 0) {
+                /* command line */
+                if (rept == ARG_USED_CL) return _("illegal repeated flag");
+                if (rept == ARG_ONE) usage[i].rept = ARG_USED_CL;
+            } else {
+                /* allow file to override command line */
+                if (rept == ARG_USED_FILE) return _("illegal repeated keyword");
+                if (rept == ARG_USED_CL || rept == ARG_ONE) usage[i].rept = ARG_USED_FILE;
+            }
+
+            if (rept != ARG_DUP && rept != ARG_ONE && rept != ARG_USED_CL) {
+                daemon->options |= rept;
+                return NULL;
+            }
+
+            break;
+        }
+
+    switch (option) {
+        case 'C': /* --conf-file */
+        {
+            char* file = opt_string_alloc(arg);
+            if (file) {
+                one_file(file, nest, 0);
+                free(file);
+            }
+            break;
+        }
+
+        case '7': /* --conf-dir */
+        {
+            DIR* dir_stream;
+            struct dirent* ent;
+            char *directory, *path;
+            struct list {
+                char* suffix;
+                struct list* next;
+            }* ignore_suffix = NULL, *li;
+
+            comma = split(arg);
+            if (!(directory = opt_string_alloc(arg))) break;
+
+            for (arg = comma; arg; arg = comma) {
+                comma = split(arg);
+                li = opt_malloc(sizeof(struct list));
+                li->next = ignore_suffix;
+                ignore_suffix = li;
+                /* Have to copy: buffer is overwritten */
+                li->suffix = opt_string_alloc(arg);
+            };
+
+            if (!(dir_stream = opendir(directory)))
+                die(_("cannot access directory %s: %s"), directory, EC_FILE);
+
+            while ((ent = readdir(dir_stream))) {
+                size_t len = strlen(ent->d_name);
+                struct stat buf;
+
+                /* ignore emacs backups and dotfiles */
+                if (len == 0 || ent->d_name[len - 1] == '~' ||
+                    (ent->d_name[0] == '#' && ent->d_name[len - 1] == '#') || ent->d_name[0] == '.')
+                    continue;
+
+                for (li = ignore_suffix; li; li = li->next) {
+                    /* check for proscribed suffices */
+                    size_t ls = strlen(li->suffix);
+                    if (len > ls && strcmp(li->suffix, &ent->d_name[len - ls]) == 0) break;
+                }
+                if (li) continue;
+
+                path = opt_malloc(strlen(directory) + len + 2);
+                strcpy(path, directory);
+                strcat(path, "/");
+                strcat(path, ent->d_name);
+
+                if (stat(path, &buf) == -1) die(_("cannot access %s: %s"), path, EC_FILE);
+                /* only reg files allowed. */
+                if (!S_ISREG(buf.st_mode)) continue;
+
+                /* dir is one level, so files must be readable */
+                one_file(path, nest + 1, 0);
+                free(path);
+            }
+
+            closedir(dir_stream);
+            free(directory);
+            for (; ignore_suffix; ignore_suffix = li) {
+                li = ignore_suffix->next;
+                free(ignore_suffix->suffix);
+                free(ignore_suffix);
+            }
+
+            break;
+        }
+
+        case '8': /* --log-facility */
+            /* may be a filename */
+            if (strchr(arg, '/'))
+                daemon->log_file = opt_string_alloc(arg);
+            else {
+#ifdef __ANDROID__
+                problem = "Android does not support log facilities";
+#else
+                for (i = 0; facilitynames[i].c_name; i++)
+                    if (hostname_isequal((char*) facilitynames[i].c_name, arg)) break;
+
+                if (facilitynames[i].c_name)
+                    daemon->log_fac = facilitynames[i].c_val;
+                else
+                    problem = "bad log facility";
+#endif
+            }
+            break;
+
+        case 'x': /* --pid-file */
+            daemon->runfile = opt_string_alloc(arg);
+            break;
+
+        case LOPT_DHCP_HOST: /* --dhcp-hostfile */
+            if (daemon->dhcp_hosts_file)
+                problem = _("only one dhcp-hostsfile allowed");
+            else
+                daemon->dhcp_hosts_file = opt_string_alloc(arg);
+            break;
+
+        case LOPT_DHCP_OPTS: /* --dhcp-optsfile */
+            if (daemon->dhcp_opts_file)
+                problem = _("only one dhcp-optsfile allowed");
+            else
+                daemon->dhcp_opts_file = opt_string_alloc(arg);
+            break;
+
+        case 'r': /* --resolv-file */
+        {
+            char* name = opt_string_alloc(arg);
+            struct resolvc* new, *list = daemon->resolv_files;
+
+            if (list && list->is_default) {
+                /* replace default resolv file - possibly with nothing */
+                if (name) {
+                    list->is_default = 0;
+                    list->name = name;
+                } else
+                    list = NULL;
+            } else if (name) {
+                new = opt_malloc(sizeof(struct resolvc));
+                new->next = list;
+                new->name = name;
+                new->is_default = 0;
+                new->mtime = 0;
+                new->logged = 0;
+                list = new;
+            }
+            daemon->resolv_files = list;
+            break;
+        }
+
+        case 'm': /* --mx-host */
+        {
+            int pref = 1;
+            struct mx_srv_record* new;
+            char *name, *target = NULL;
+
+            if ((comma = split(arg))) {
+                char* prefstr;
+                if ((prefstr = split(comma)) && !atoi_check16(prefstr, &pref))
+                    problem = _("bad MX preference");
+            }
+
+            if (!(name = canonicalise_opt(arg)) || (comma && !(target = canonicalise_opt(comma))))
+                problem = _("bad MX name");
+
+            new = opt_malloc(sizeof(struct mx_srv_record));
+            new->next = daemon->mxnames;
+            daemon->mxnames = new;
+            new->issrv = 0;
+            new->name = name;
+            new->target = target; /* may be NULL */
+            new->weight = pref;
+            break;
+        }
+
+        case 't': /*  --mx-target */
+            if (!(daemon->mxtarget = canonicalise_opt(arg))) problem = _("bad MX target");
+            break;
+
+#ifdef HAVE_DHCP
+        case 'l': /* --dhcp-leasefile */
+            daemon->lease_file = opt_string_alloc(arg);
+            break;
+
+        case '6': /* --dhcp-script */
+#if defined(NO_FORK)
+            problem = _("cannot run scripts under uClinux");
+#elif !defined(HAVE_SCRIPT)
+            problem = _("recompile with HAVE_SCRIPT defined to enable lease-change scripts");
+#else
+            daemon->lease_change_command = opt_string_alloc(arg);
+#endif
+            break;
+#endif
+
+        case 'H': /* --addn-hosts */
+        {
+            struct hostsfile* new = opt_malloc(sizeof(struct hostsfile));
+            static int hosts_index = 1;
+            new->fname = opt_string_alloc(arg);
+            new->index = hosts_index++;
+            new->flags = 0;
+            new->next = daemon->addn_hosts;
+            daemon->addn_hosts = new;
+            break;
+        }
+
+        case 's': /* --domain */
+            if (strcmp(arg, "#") == 0)
+                daemon->options |= OPT_RESOLV_DOMAIN;
+            else {
+                char* d;
+                comma = split(arg);
+                if (!(d = canonicalise_opt(arg)))
+                    option = '?';
+                else {
+                    if (comma) {
+                        struct cond_domain* new = safe_malloc(sizeof(struct cond_domain));
+                        unhide_metas(comma);
+                        if ((arg = split_chr(comma, '/'))) {
+                            int mask;
+                            if ((new->start.s_addr = inet_addr(comma)) == (in_addr_t) -1 ||
+                                !atoi_check(arg, &mask))
+                                option = '?';
+                            else {
+                                mask = (1 << (32 - mask)) - 1;
+                                new->start.s_addr = ntohl(htonl(new->start.s_addr) & ~mask);
+                                new->end.s_addr = new->start.s_addr | htonl(mask);
+                            }
+                        } else if ((arg = split(comma))) {
+                            if ((new->start.s_addr = inet_addr(comma)) == (in_addr_t) -1 ||
+                                (new->end.s_addr = inet_addr(arg)) == (in_addr_t) -1)
+                                option = '?';
+                        } else if ((new->start.s_addr = new->end.s_addr = inet_addr(comma)) ==
+                                   (in_addr_t) -1)
+                            option = '?';
+
+                        new->domain = d;
+                        new->next = daemon->cond_domain;
+                        daemon->cond_domain = new;
+                    } else
+                        daemon->domain_suffix = d;
+                }
+            }
+            break;
+
+        case 'u': /* --user */
+            daemon->username = opt_string_alloc(arg);
+            break;
+
+        case 'g': /* --group */
+            daemon->groupname = opt_string_alloc(arg);
+            daemon->group_set = 1;
+            break;
+
+#ifdef HAVE_DHCP
+        case LOPT_SCRIPTUSR: /* --scriptuser */
+            daemon->scriptuser = opt_string_alloc(arg);
+            break;
+#endif
+
+        case 'i': /* --interface */
+            do {
+                struct iname* new = opt_malloc(sizeof(struct iname));
+                comma = split(arg);
+                new->next = daemon->if_names;
+                daemon->if_names = new;
+                /* new->name may be NULL if someone does
+                   "interface=" to disable all interfaces except loop. */
+                new->name = opt_string_alloc(arg);
+                new->isloop = new->used = 0;
+                arg = comma;
+            } while (arg);
+            break;
+
+        case 'I': /* --except-interface */
+        case '2': /* --no-dhcp-interface */
+            do {
+                struct iname* new = opt_malloc(sizeof(struct iname));
+                comma = split(arg);
+                new->name = opt_string_alloc(arg);
+                if (option == 'I') {
+                    new->next = daemon->if_except;
+                    daemon->if_except = new;
+                } else {
+                    new->next = daemon->dhcp_except;
+                    daemon->dhcp_except = new;
+                }
+                arg = comma;
+            } while (arg);
+            break;
+
+        case 'B': /* --bogus-nxdomain */
+        {
+            struct in_addr addr;
+            unhide_metas(arg);
+            if (arg && (addr.s_addr = inet_addr(arg)) != (in_addr_t) -1) {
+                struct bogus_addr* baddr = opt_malloc(sizeof(struct bogus_addr));
+                baddr->next = daemon->bogus_addr;
+                daemon->bogus_addr = baddr;
+                baddr->addr = addr;
+            } else
+                option = '?'; /* error */
+            break;
+        }
+
+        case 'a': /* --listen-address */
+            do {
+                struct iname* new = opt_malloc(sizeof(struct iname));
+                comma = split(arg);
+                unhide_metas(arg);
+                new->next = daemon->if_addrs;
+                if (arg && parse_addr(AF_INET, arg, &new->addr) != 0 &&
+                    parse_addr(AF_INET6, arg, &new->addr) != 0) {
+                    option = '?'; /* error */
+                    break;
+                }
+
+                daemon->if_addrs = new;
+                arg = comma;
+            } while (arg);
+            break;
+
+        case 'S':        /*  --server */
+        case LOPT_LOCAL: /*  --local */
+        case 'A':        /*  --address */
+        {
+            struct server *serv, *newlist = NULL;
+
+            unhide_metas(arg);
+
+            if (arg && *arg == '/') {
+                char* end;
+                arg++;
+                while ((end = split_chr(arg, '/'))) {
+                    char* domain = NULL;
+                    /* # matches everything and becomes a zero length domain string */
+                    if (strcmp(arg, "#") == 0)
+                        domain = "";
+                    else if (strlen(arg) != 0 && !(domain = canonicalise_opt(arg)))
+                        option = '?';
+                    serv = opt_malloc(sizeof(struct server));
+                    memset(serv, 0, sizeof(struct server));
+                    serv->next = newlist;
+                    newlist = serv;
+                    serv->domain = domain;
+                    serv->flags = domain ? SERV_HAS_DOMAIN : SERV_FOR_NODOTS;
+                    arg = end;
+                }
+                if (!newlist) {
+                    option = '?';
+                    break;
+                }
+
+            } else {
+                newlist = opt_malloc(sizeof(struct server));
+                memset(newlist, 0, sizeof(struct server));
+            }
+
+            if (option == 'A') {
+                newlist->flags |= SERV_LITERAL_ADDRESS;
+                if (!(newlist->flags & SERV_TYPE)) option = '?';
+            }
+
+            if (!arg || !*arg) {
+                newlist->flags |= SERV_NO_ADDR; /* no server */
+                if (newlist->flags & SERV_LITERAL_ADDRESS) option = '?';
+            } else {
+                int source_port = 0, serv_port = NAMESERVER_PORT;
+                char *portno, *source;
+
+                if ((source = split_chr(arg, '@')) && /* is there a source. */
+                    (portno = split_chr(source, '#')) && !atoi_check16(portno, &source_port))
+                    problem = _("bad port");
+
+                if ((portno = split_chr(arg, '#')) && /* is there a port no. */
+                    !atoi_check16(portno, &serv_port))
+                    problem = _("bad port");
+
+                if (parse_addr(AF_INET, arg, &newlist->addr) == 0) {
+                    newlist->addr.in.sin_port = htons(serv_port);
+                    if (source) {
+                        newlist->flags |= SERV_HAS_SOURCE;
+                        if (parse_addr(AF_INET, source, &newlist->addr) != 0) {
+#if defined(SO_BINDTODEVICE)
+                            newlist->source_addr.in.sin_addr.s_addr = INADDR_ANY;
+                            strncpy(newlist->interface, source, IF_NAMESIZE);
+#else
+                            problem = _("interface binding not supported");
+#endif
+                        }
+                    } else
+                        newlist->source_addr.in.sin_addr.s_addr = INADDR_ANY;
+
+                    newlist->source_addr.in.sin_port = htons(source_port);
+                    newlist->source_addr.sa.sa_family = AF_INET;
+                }
+#ifdef HAVE_IPV6
+                else if (parse_addr(AF_INET6, arg, &newlist->addr) == 0) {
+                    newlist->addr.in6.sin6_port = htons(serv_port);
+                    if (source) {
+                        newlist->flags |= SERV_HAS_SOURCE;
+                        if (parse_addr(AF_INET6, source, &newlist->source_addr) != 0) {
+#if defined(SO_BINDTODEVICE)
+                            newlist->source_addr.in6.sin6_addr = in6addr_any;
+                            strncpy(newlist->interface, source, IF_NAMESIZE);
+#else
+                            problem = _("interface binding not supported");
+#endif
+                        }
+                    } else
+                        newlist->source_addr.in6.sin6_addr = in6addr_any;
+
+                    newlist->source_addr.in6.sin6_port = htons(source_port);
+                    newlist->source_addr.sa.sa_family = AF_INET6;
+                }
+#endif
+                else
+                    option = '?'; /* error */
+            }
+
+            serv = newlist;
+            while (serv->next) {
+                serv->next->flags = serv->flags;
+                serv->next->addr = serv->addr;
+                serv->next->source_addr = serv->source_addr;
+                serv = serv->next;
+            }
+            serv->next = daemon->servers;
+            daemon->servers = newlist;
+            break;
+        }
+
+        case 'c': /* --cache-size */
+        {
+            int size;
+
+            if (!atoi_check(arg, &size))
+                option = '?';
+            else {
+                /* zero is OK, and means no caching. */
+
+                if (size < 0)
+                    size = 0;
+                else if (size > 10000)
+                    size = 10000;
+
+                daemon->cachesize = size;
+            }
+            break;
+        }
+
+        case 'p': /* --port */
+            if (!atoi_check16(arg, &daemon->port)) option = '?';
+            break;
+
+        case LOPT_MINPORT: /* --min-port */
+            if (!atoi_check16(arg, &daemon->min_port)) option = '?';
+            break;
+
+        case '0': /* --dns-forward-max */
+            if (!atoi_check(arg, &daemon->ftabsize)) option = '?';
+            break;
+
+        case LOPT_MAX_LOGS:             /* --log-async */
+            daemon->max_logs = LOG_MAX; /* default */
+            if (arg && !atoi_check(arg, &daemon->max_logs))
+                option = '?';
+            else if (daemon->max_logs > 100)
+                daemon->max_logs = 100;
+            break;
+
+        case 'P': /* --edns-packet-max */
+        {
+            int i;
+            if (!atoi_check(arg, &i)) option = '?';
+            daemon->edns_pktsz = (unsigned short) i;
+            break;
+        }
+
+        case 'Q': /* --query-port */
+            if (!atoi_check16(arg, &daemon->query_port)) option = '?';
+            /* if explicitly set to zero, use single OS ephemeral port
+           and disable random ports */
+            if (daemon->query_port == 0) daemon->osport = 1;
+            break;
+
+        case 'T':         /* --local-ttl */
+        case LOPT_NEGTTL: /* --neg-ttl */
+        {
+            int ttl;
+            if (!atoi_check(arg, &ttl))
+                option = '?';
+            else if (option == LOPT_NEGTTL)
+                daemon->neg_ttl = (unsigned long) ttl;
+            else
+                daemon->local_ttl = (unsigned long) ttl;
+            break;
+        }
+
+#ifdef HAVE_DHCP
+        case 'X': /* --dhcp-lease-max */
+            if (!atoi_check(arg, &daemon->dhcp_max)) option = '?';
+            break;
+#endif
+
+        case LOPT_BRIDGE: /* --bridge-interface */
+        {
+            struct dhcp_bridge* new = opt_malloc(sizeof(struct dhcp_bridge));
+            if (!(comma = split(arg))) {
+                problem = _("bad bridge-interface");
+                break;
+            }
+
+            strncpy(new->iface, arg, IF_NAMESIZE);
+            new->alias = NULL;
+            new->next = daemon->bridges;
+            daemon->bridges = new;
+
+            do {
+                arg = comma;
+                comma = split(arg);
+                if (strlen(arg) != 0) {
+                    struct dhcp_bridge* b = opt_malloc(sizeof(struct dhcp_bridge));
+                    b->next = new->alias;
+                    new->alias = b;
+                    strncpy(b->iface, arg, IF_NAMESIZE);
+                }
+            } while (comma);
+
+            break;
+        }
+
+#ifdef HAVE_DHCP
+        case 'F': /* --dhcp-range */
+        {
+            int k, leasepos = 2;
+            char *cp, *a[5] = {NULL, NULL, NULL, NULL, NULL};
+            struct dhcp_context* new = opt_malloc(sizeof(struct dhcp_context));
+
+            new->next = daemon->dhcp;
+            new->lease_time = DEFLEASE;
+            new->addr_epoch = 0;
+            new->netmask.s_addr = 0;
+            new->broadcast.s_addr = 0;
+            new->router.s_addr = 0;
+            new->netid.net = NULL;
+            new->filter = NULL;
+            new->flags = 0;
+
+            gen_prob = _("bad dhcp-range");
+
+            if (!arg) {
+                option = '?';
+                break;
+            }
+
+            while (1) {
+                for (cp = arg; *cp; cp++)
+                    if (!(*cp == ' ' || *cp == '.' || (*cp >= '0' && *cp <= '9'))) break;
+
+                if (*cp != ',' && (comma = split(arg))) {
+                    if (strstr(arg, "net:") == arg) {
+                        struct dhcp_netid* tt = opt_malloc(sizeof(struct dhcp_netid));
+                        tt->net = opt_string_alloc(arg + 4);
+                        tt->next = new->filter;
+                        new->filter = tt;
+                    } else {
+                        if (new->netid.net)
+                            problem = _("only one netid tag allowed");
+                        else
+                            new->netid.net = opt_string_alloc(arg);
+                    }
+                    arg = comma;
+                } else {
+                    a[0] = arg;
+                    break;
+                }
+            }
+
+            for (k = 1; k < 5; k++)
+                if (!(a[k] = split(a[k - 1]))) break;
+
+            if ((k < 2) || ((new->start.s_addr = inet_addr(a[0])) == (in_addr_t) -1))
+                option = '?';
+            else if (strcmp(a[1], "static") == 0) {
+                new->end = new->start;
+                new->flags |= CONTEXT_STATIC;
+            } else if (strcmp(a[1], "proxy") == 0) {
+                new->end = new->start;
+                new->flags |= CONTEXT_PROXY;
+            } else if ((new->end.s_addr = inet_addr(a[1])) == (in_addr_t) -1)
+                option = '?';
+
+            if (ntohl(new->start.s_addr) > ntohl(new->end.s_addr)) {
+                struct in_addr tmp = new->start;
+                new->start = new->end;
+                new->end = tmp;
+            }
+
+            if (option != '?' && k >= 3 && strchr(a[2], '.') &&
+                ((new->netmask.s_addr = inet_addr(a[2])) != (in_addr_t) -1)) {
+                new->flags |= CONTEXT_NETMASK;
+                leasepos = 3;
+                if (!is_same_net(new->start, new->end, new->netmask))
+                    problem = _("inconsistent DHCP range");
+            }
+            daemon->dhcp = new;
+
+            if (k >= 4 && strchr(a[3], '.') &&
+                ((new->broadcast.s_addr = inet_addr(a[3])) != (in_addr_t) -1)) {
+                new->flags |= CONTEXT_BRDCAST;
+                leasepos = 4;
+            }
+
+            if (k >= leasepos + 1) {
+                if (strcmp(a[leasepos], "infinite") == 0)
+                    new->lease_time = 0xffffffff;
+                else {
+                    int fac = 1;
+                    if (strlen(a[leasepos]) > 0) {
+                        switch (a[leasepos][strlen(a[leasepos]) - 1]) {
+                            case 'd':
+                            case 'D':
+                                fac *= 24;
+                                /* fall though */
+                            case 'h':
+                            case 'H':
+                                fac *= 60;
+                                /* fall through */
+                            case 'm':
+                            case 'M':
+                                fac *= 60;
+                                /* fall through */
+                            case 's':
+                            case 'S':
+                                a[leasepos][strlen(a[leasepos]) - 1] = 0;
+                        }
+
+                        new->lease_time = atoi(a[leasepos]) * fac;
+                        /* Leases of a minute or less confuse
+                           some clients, notably Apple's */
+                        if (new->lease_time < 120) new->lease_time = 120;
+                    }
+                }
+            }
+            break;
+        }
+
+        case LOPT_BANK:
+        case 'G': /* --dhcp-host */
+        {
+            int j, k = 0;
+            char* a[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
+            struct dhcp_config* new;
+            struct in_addr in;
+
+            new = opt_malloc(sizeof(struct dhcp_config));
+
+            new->next = daemon->dhcp_conf;
+            new->flags = (option == LOPT_BANK) ? CONFIG_BANK : 0;
+            new->hwaddr = NULL;
+
+            if ((a[0] = arg))
+                for (k = 1; k < 6; k++)
+                    if (!(a[k] = split(a[k - 1]))) break;
+
+            for (j = 0; j < k; j++)
+                if (strchr(a[j], ':')) /* ethernet address, netid or binary CLID */
+                {
+                    char* arg = a[j];
+
+                    if ((arg[0] == 'i' || arg[0] == 'I') && (arg[1] == 'd' || arg[1] == 'D') &&
+                        arg[2] == ':') {
+                        if (arg[3] == '*')
+                            new->flags |= CONFIG_NOCLID;
+                        else {
+                            int len;
+                            arg += 3; /* dump id: */
+                            if (strchr(arg, ':'))
+                                len = parse_hex(arg, (unsigned char*) arg, -1, NULL, NULL);
+                            else {
+                                unhide_metas(arg);
+                                len = (int) strlen(arg);
+                            }
+
+                            if ((new->clid = opt_malloc(len))) {
+                                new->flags |= CONFIG_CLID;
+                                new->clid_len = len;
+                                memcpy(new->clid, arg, len);
+                            }
+                        }
+                    } else if (strstr(arg, "net:") == arg) {
+                        int len = strlen(arg + 4) + 1;
+                        if ((new->netid.net = opt_malloc(len))) {
+                            new->flags |= CONFIG_NETID;
+                            strcpy(new->netid.net, arg + 4);
+                            unhide_metas(new->netid.net);
+                        }
+                    } else {
+                        struct hwaddr_config* newhw = opt_malloc(sizeof(struct hwaddr_config));
+                        newhw->next = new->hwaddr;
+                        new->hwaddr = newhw;
+                        newhw->hwaddr_len = parse_hex(a[j], newhw->hwaddr, DHCP_CHADDR_MAX,
+                                                      &newhw->wildcard_mask, &newhw->hwaddr_type);
+                    }
+                } else if (strchr(a[j], '.') && (in.s_addr = inet_addr(a[j])) != (in_addr_t) -1) {
+                    new->addr = in;
+                    new->flags |= CONFIG_ADDR;
+                } else {
+                    char *cp, *lastp = NULL, last = 0;
+                    int fac = 1;
+
+                    if (strlen(a[j]) > 1) {
+                        lastp = a[j] + strlen(a[j]) - 1;
+                        last = *lastp;
+                        switch (last) {
+                            case 'd':
+                            case 'D':
+                                fac *= 24;
+                                /* fall through */
+                            case 'h':
+                            case 'H':
+                                fac *= 60;
+                                /* fall through */
+                            case 'm':
+                            case 'M':
+                                fac *= 60;
+                                /* fall through */
+                            case 's':
+                            case 'S':
+                                *lastp = 0;
+                        }
+                    }
+
+                    for (cp = a[j]; *cp; cp++)
+                        if (!isdigit((int) *cp) && *cp != ' ') break;
+
+                    if (*cp) {
+                        if (lastp) *lastp = last;
+                        if (strcmp(a[j], "infinite") == 0) {
+                            new->lease_time = 0xffffffff;
+                            new->flags |= CONFIG_TIME;
+                        } else if (strcmp(a[j], "ignore") == 0)
+                            new->flags |= CONFIG_DISABLE;
+                        else {
+                            if (!(new->hostname = canonicalise_opt(a[j])) ||
+                                !legal_hostname(new->hostname))
+                                problem = _("bad DHCP host name");
+                            else
+                                new->flags |= CONFIG_NAME;
+                            new->domain = NULL;
+                        }
+                    } else {
+                        new->lease_time = atoi(a[j]) * fac;
+                        /* Leases of a minute or less confuse
+                           some clients, notably Apple's */
+                        if (new->lease_time < 120) new->lease_time = 120;
+                        new->flags |= CONFIG_TIME;
+                    }
+                }
+
+            daemon->dhcp_conf = new;
+            break;
+        }
+
+        case 'O':        /* --dhcp-option */
+        case LOPT_FORCE: /* --dhcp-option-force */
+        case LOPT_OPTS:
+        case LOPT_MATCH: /* --dhcp-match */
+            problem = parse_dhcp_opt(
+                arg, option == LOPT_FORCE
+                         ? DHOPT_FORCE
+                         : (option == LOPT_MATCH ? DHOPT_MATCH
+                                                 : (option == LOPT_OPTS ? DHOPT_BANK : 0)));
+            break;
+
+        case 'M': /* --dhcp-boot */
+        {
+            struct dhcp_netid* id = NULL;
+            while (arg && strstr(arg, "net:") == arg) {
+                struct dhcp_netid* newid = opt_malloc(sizeof(struct dhcp_netid));
+                newid->next = id;
+                id = newid;
+                comma = split(arg);
+                newid->net = opt_string_alloc(arg + 4);
+                arg = comma;
+            };
+
+            if (!arg)
+                option = '?';
+            else {
+                char *dhcp_file, *dhcp_sname = NULL;
+                struct in_addr dhcp_next_server;
+                comma = split(arg);
+                dhcp_file = opt_string_alloc(arg);
+                dhcp_next_server.s_addr = 0;
+                if (comma) {
+                    arg = comma;
+                    comma = split(arg);
+                    dhcp_sname = opt_string_alloc(arg);
+                    if (comma) {
+                        unhide_metas(comma);
+                        if ((dhcp_next_server.s_addr = inet_addr(comma)) == (in_addr_t) -1)
+                            option = '?';
+                    }
+                }
+                if (option != '?') {
+                    struct dhcp_boot* new = opt_malloc(sizeof(struct dhcp_boot));
+                    new->file = dhcp_file;
+                    new->sname = dhcp_sname;
+                    new->next_server = dhcp_next_server;
+                    new->netid = id;
+                    new->next = daemon->boot_config;
+                    daemon->boot_config = new;
+                }
+            }
+
+            break;
+        }
+
+        case LOPT_PXE_PROMT: /* --pxe-prompt */
+        {
+            struct dhcp_opt* new = opt_malloc(sizeof(struct dhcp_opt));
+            int timeout;
+
+            new->netid = NULL;
+            new->opt = 10; /* PXE_MENU_PROMPT */
+
+            while (arg && strstr(arg, "net:") == arg) {
+                struct dhcp_netid* nn = opt_malloc(sizeof(struct dhcp_netid));
+                comma = split(arg);
+                nn->next = new->netid;
+                new->netid = nn;
+                nn->net = opt_string_alloc(arg + 4);
+                arg = comma;
+            }
+
+            if (!arg)
+                option = '?';
+            else {
+                comma = split(arg);
+                unhide_metas(arg);
+                new->len = strlen(arg) + 1;
+                new->val = opt_malloc(new->len);
+                memcpy(new->val + 1, arg, new->len - 1);
+
+                new->u.vendor_class = (unsigned char*) "PXEClient";
+                new->flags = DHOPT_VENDOR;
+
+                if (comma && atoi_check(comma, &timeout))
+                    *(new->val) = timeout;
+                else
+                    *(new->val) = 255;
+
+                new->next = daemon->dhcp_opts;
+                daemon->dhcp_opts = new;
+                daemon->enable_pxe = 1;
+            }
+
+            break;
+        }
+
+        case LOPT_PXE_SERV: /* --pxe-service */
+        {
+            struct pxe_service* new = opt_malloc(sizeof(struct pxe_service));
+            char* CSA[] = {
+                "x86PC",    "PC98",   "IA64_EFI",   "Alpha",      "Arc_x86", "Intel_Lean_Client",
+                "IA32_EFI", "BC_EFI", "Xscale_EFI", "x86-64_EFI", NULL};
+            static int boottype = 32768;
+
+            new->netid = NULL;
+            new->server.s_addr = 0;
+
+            while (arg && strstr(arg, "net:") == arg) {
+                struct dhcp_netid* nn = opt_malloc(sizeof(struct dhcp_netid));
+                comma = split(arg);
+                nn->next = new->netid;
+                new->netid = nn;
+                nn->net = opt_string_alloc(arg + 4);
+                arg = comma;
+            }
+
+            if (arg && (comma = split(arg))) {
+                for (i = 0; CSA[i]; i++)
+                    if (strcasecmp(CSA[i], arg) == 0) break;
+
+                if (CSA[i] || atoi_check(arg, &i)) {
+                    arg = comma;
+                    comma = split(arg);
+
+                    new->CSA = i;
+                    new->menu = opt_string_alloc(arg);
+
+                    if (comma) {
+                        arg = comma;
+                        comma = split(arg);
+                        if (atoi_check(arg, &i)) {
+                            new->type = i;
+                            new->basename = NULL;
+                        } else {
+                            new->type = boottype++;
+                            new->basename = opt_string_alloc(arg);
+                        }
+
+                        if (comma && (new->server.s_addr = inet_addr(comma)) == (in_addr_t) -1)
+                            option = '?';
+
+                        /* Order matters */
+                        new->next = NULL;
+                        if (!daemon->pxe_services)
+                            daemon->pxe_services = new;
+                        else {
+                            struct pxe_service* s;
+                            for (s = daemon->pxe_services; s->next; s = s->next)
+                                ;
+                            s->next = new;
+                        }
+
+                        daemon->enable_pxe = 1;
+                        break;
+                    }
+                }
+            }
+
+            option = '?';
+            break;
+        }
+
+        case '4': /* --dhcp-mac */
+        {
+            if (!(comma = split(arg)))
+                option = '?';
+            else {
+                struct dhcp_mac* new = opt_malloc(sizeof(struct dhcp_mac));
+                if (strstr(arg, "net:") == arg)
+                    new->netid.net = opt_string_alloc(arg + 4);
+                else
+                    new->netid.net = opt_string_alloc(arg);
+                unhide_metas(comma);
+                new->hwaddr_len =
+                    parse_hex(comma, new->hwaddr, DHCP_CHADDR_MAX, &new->mask, &new->hwaddr_type);
+                new->next = daemon->dhcp_macs;
+                daemon->dhcp_macs = new;
+            }
+        } break;
+
+        case 'U':          /* --dhcp-vendorclass */
+        case 'j':          /* --dhcp-userclass */
+        case LOPT_CIRCUIT: /* --dhcp-circuitid */
+        case LOPT_REMOTE:  /* --dhcp-remoteid */
+        case LOPT_SUBSCR:  /* --dhcp-subscrid */
+        {
+            if (!(comma = split(arg)))
+                option = '?';
+            else {
+                char* p;
+                int dig = 0;
+                struct dhcp_vendor* new = opt_malloc(sizeof(struct dhcp_vendor));
+                if (strstr(arg, "net:") == arg)
+                    new->netid.net = opt_string_alloc(arg + 4);
+                else
+                    new->netid.net = opt_string_alloc(arg);
+                /* check for hex string - must digits may include : must not have nothing else,
+                   only allowed for agent-options. */
+                for (p = comma; *p; p++)
+                    if (isxdigit((int) *p))
+                        dig = 1;
+                    else if (*p != ':')
+                        break;
+                unhide_metas(comma);
+                if (option == 'U' || option == 'j' || *p || !dig) {
+                    new->len = strlen(comma);
+                    new->data = opt_malloc(new->len);
+                    memcpy(new->data, comma, new->len);
+                } else {
+                    new->len = parse_hex(comma, (unsigned char*) comma, strlen(comma), NULL, NULL);
+                    new->data = opt_malloc(new->len);
+                    memcpy(new->data, comma, new->len);
+                }
+
+                switch (option) {
+                    case 'j':
+                        new->match_type = MATCH_USER;
+                        break;
+                    case 'U':
+                        new->match_type = MATCH_VENDOR;
+                        break;
+                    case LOPT_CIRCUIT:
+                        new->match_type = MATCH_CIRCUIT;
+                        break;
+                    case LOPT_REMOTE:
+                        new->match_type = MATCH_REMOTE;
+                        break;
+                    case LOPT_SUBSCR:
+                        new->match_type = MATCH_SUBSCRIBER;
+                        break;
+                }
+                new->next = daemon->dhcp_vendors;
+                daemon->dhcp_vendors = new;
+            }
+            break;
+        }
+
+        case LOPT_ALTPORT: /* --dhcp-alternate-port */
+            if (!arg) {
+                daemon->dhcp_server_port = DHCP_SERVER_ALTPORT;
+                daemon->dhcp_client_port = DHCP_CLIENT_ALTPORT;
+            } else {
+                comma = split(arg);
+                if (!atoi_check16(arg, &daemon->dhcp_server_port) ||
+                    (comma && !atoi_check16(comma, &daemon->dhcp_client_port)))
+                    problem = _("invalid port number");
+                if (!comma) daemon->dhcp_client_port = daemon->dhcp_server_port + 1;
+            }
+            break;
+
+        case 'J':            /* --dhcp-ignore */
+        case LOPT_NO_NAMES:  /* --dhcp-ignore-names */
+        case LOPT_BROADCAST: /* --dhcp-broadcast */
+        case '3':            /* --bootp-dynamic */
+        {
+            struct dhcp_netid_list* new = opt_malloc(sizeof(struct dhcp_netid_list));
+            struct dhcp_netid* list = NULL;
+            if (option == 'J') {
+                new->next = daemon->dhcp_ignore;
+                daemon->dhcp_ignore = new;
+            } else if (option == LOPT_BROADCAST) {
+                new->next = daemon->force_broadcast;
+                daemon->force_broadcast = new;
+            } else if (option == '3') {
+                new->next = daemon->bootp_dynamic;
+                daemon->bootp_dynamic = new;
+            } else {
+                new->next = daemon->dhcp_ignore_names;
+                daemon->dhcp_ignore_names = new;
+            }
+
+            while (arg) {
+                struct dhcp_netid* member = opt_malloc(sizeof(struct dhcp_netid));
+                comma = split(arg);
+                member->next = list;
+                list = member;
+                if (strstr(arg, "net:") == arg)
+                    member->net = opt_string_alloc(arg + 4);
+                else
+                    member->net = opt_string_alloc(arg);
+                arg = comma;
+            }
+
+            new->list = list;
+            break;
+        }
+#endif
+
+        case 'V': /* --alias */
+        {
+            char *dash, *a[3] = {NULL, NULL, NULL};
+            int k = 0;
+            struct doctor* new = opt_malloc(sizeof(struct doctor));
+            new->next = daemon->doctors;
+            daemon->doctors = new;
+            new->mask.s_addr = 0xffffffff;
+            new->end.s_addr = 0;
+
+            if ((a[0] = arg))
+                for (k = 1; k < 3; k++) {
+                    if (!(a[k] = split(a[k - 1]))) break;
+                    unhide_metas(a[k]);
+                }
+
+            dash = split_chr(a[0], '-');
+
+            if ((k < 2) || ((new->in.s_addr = inet_addr(a[0])) == (in_addr_t) -1) ||
+                ((new->out.s_addr = inet_addr(a[1])) == (in_addr_t) -1))
+                option = '?';
+
+            if (k == 3) new->mask.s_addr = inet_addr(a[2]);
+
+            if (dash && ((new->end.s_addr = inet_addr(dash)) == (in_addr_t) -1 ||
+                         !is_same_net(new->in, new->end, new->mask) ||
+                         ntohl(new->in.s_addr) > ntohl(new->end.s_addr)))
+                problem = _("invalid alias range");
+
+            break;
+        }
+
+        case LOPT_INTNAME: /* --interface-name */
+        {
+            struct interface_name* new, **up;
+            char* domain = NULL;
+
+            comma = split(arg);
+
+            if (!comma || !(domain = canonicalise_opt(arg))) problem = _("bad interface name");
+
+            new = opt_malloc(sizeof(struct interface_name));
+            new->next = NULL;
+            /* Add to the end of the list, so that first name
+               of an interface is used for PTR lookups. */
+            for (up = &daemon->int_names; *up; up = &((*up)->next))
+                ;
+            *up = new;
+            new->name = domain;
+            new->intr = opt_string_alloc(comma);
+            break;
+        }
+
+        case LOPT_CNAME: /* --cname */
+        {
+            struct cname* new;
+
+            if (!(comma = split(arg)))
+                option = '?';
+            else {
+                char* alias = canonicalise_opt(arg);
+                char* target = canonicalise_opt(comma);
+
+                if (!alias || !target)
+                    problem = _("bad CNAME");
+                else {
+                    for (new = daemon->cnames; new; new = new->next)
+                        if (hostname_isequal(new->alias, arg)) problem = _("duplicate CNAME");
+                    new = opt_malloc(sizeof(struct cname));
+                    new->next = daemon->cnames;
+                    daemon->cnames = new;
+                    new->alias = alias;
+                    new->target = target;
+                }
+            }
+            break;
+        }
+
+        case LOPT_PTR: /* --ptr-record */
+        {
+            struct ptr_record* new;
+            char *dom, *target = NULL;
+
+            comma = split(arg);
+
+            if (!(dom = canonicalise_opt(arg)) || (comma && !(target = canonicalise_opt(comma))))
+                problem = _("bad PTR record");
+            else {
+                new = opt_malloc(sizeof(struct ptr_record));
+                new->next = daemon->ptr;
+                daemon->ptr = new;
+                new->name = dom;
+                new->ptr = target;
+            }
+            break;
+        }
+
+        case LOPT_NAPTR: /* --naptr-record */
+        {
+            char* a[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
+            int k = 0;
+            struct naptr* new;
+            int order, pref;
+            char *name, *replace = NULL;
+
+            if ((a[0] = arg))
+                for (k = 1; k < 7; k++)
+                    if (!(a[k] = split(a[k - 1]))) break;
+
+            if (k < 6 || !(name = canonicalise_opt(a[0])) || !atoi_check16(a[1], &order) ||
+                !atoi_check16(a[2], &pref) || (k == 7 && !(replace = canonicalise_opt(a[6]))))
+                problem = _("bad NAPTR record");
+            else {
+                new = opt_malloc(sizeof(struct naptr));
+                new->next = daemon->naptr;
+                daemon->naptr = new;
+                new->name = name;
+                new->flags = opt_string_alloc(a[3]);
+                new->services = opt_string_alloc(a[4]);
+                new->regexp = opt_string_alloc(a[5]);
+                new->replace = replace;
+                new->order = order;
+                new->pref = pref;
+            }
+            break;
+        }
+
+        case 'Y': /* --txt-record */
+        {
+            struct txt_record* new;
+            unsigned char *p, *q;
+
+            if ((comma = split(arg))) comma--;
+
+            gen_prob = _("TXT record string too long");
+
+            if ((q = (unsigned char*) comma))
+                while (1) {
+                    size_t len;
+                    if ((p = (unsigned char*) strchr((char*) q + 1, ','))) {
+                        if ((len = p - q - 1) > 255) option = '?';
+                        *q = len;
+                        for (q = q + 1; q < p; q++) *q = unhide_meta(*q);
+                    } else {
+                        if ((len = strlen((char*) q + 1)) > 255) option = '?';
+                        *q = len;
+                        for (q = q + 1; *q; q++) *q = unhide_meta(*q);
+                        break;
+                    }
+                }
+
+            new = opt_malloc(sizeof(struct txt_record));
+            new->next = daemon->txt;
+            daemon->txt = new;
+            new->class = C_IN;
+            if (comma) {
+                new->len = q - ((unsigned char*) comma);
+                new->txt = opt_malloc(new->len);
+                memcpy(new->txt, comma, new->len);
+            } else {
+                static char empty[] = "";
+                new->len = 1;
+                new->txt = empty;
+            }
+
+            /* ensure arg is terminated */
+            if (comma) *comma = 0;
+
+            if (!(new->name = canonicalise_opt(arg))) {
+                problem = _("bad TXT record");
+                break;
+            }
+
+            break;
+        }
+
+        case 'W': /* --srv-host */
+        {
+            int port = 1, priority = 0, weight = 0;
+            char *name, *target = NULL;
+            struct mx_srv_record* new;
+
+            comma = split(arg);
+
+            if (!(name = canonicalise_opt(arg))) problem = _("bad SRV record");
+
+            if (comma) {
+                arg = comma;
+                comma = split(arg);
+                if (!(target = canonicalise_opt(arg))) problem = _("bad SRV target");
+
+                if (comma) {
+                    arg = comma;
+                    comma = split(arg);
+                    if (!atoi_check16(arg, &port)) problem = _("invalid port number");
+
+                    if (comma) {
+                        arg = comma;
+                        comma = split(arg);
+                        if (!atoi_check16(arg, &priority)) problem = _("invalid priority");
+
+                        if (comma) {
+                            arg = comma;
+                            comma = split(arg);
+                            if (!atoi_check16(arg, &weight)) problem = _("invalid weight");
+                        }
+                    }
+                }
+            }
+
+            new = opt_malloc(sizeof(struct mx_srv_record));
+            new->next = daemon->mxnames;
+            daemon->mxnames = new;
+            new->issrv = 1;
+            new->name = name;
+            new->target = target;
+            new->srvport = port;
+            new->priority = priority;
+            new->weight = weight;
+            break;
+        }
+
+        case LOPT_LISTNMARK: /* --listen-mark */
+        {
+            char* endptr;
+            uint32_t mark = strtoul(arg, &endptr, 0);
+            // my_syslog(LOG_WARNING, "passed-in mark: %s", arg);
+            if (!*endptr)
+                daemon->listen_mark = mark;
+            else
+                problem = _("invalid mark");
+            // my_syslog(LOG_WARNING, "daemon->listen_mark: 0x%x, *endptr=%d", daemon->listen_mark, *endptr);
+            break;
+        }
+
+        default:
+            return _("unsupported option (check that dnsmasq was compiled with DHCP support)");
+    }
+
+    if (problem) return problem;
+
+    if (option == '?') return gen_prob;
+
+    return NULL;
+}
+
+static void one_file(char* file, int nest, int hard_opt) {
+    volatile int lineno = 0;
+    int i, option;
+    FILE* f;
+    char *p, *arg, *start, *buff = daemon->namebuff;
+    static struct fileread {
+        dev_t dev;
+        ino_t ino;
+        struct fileread* next;
+    }* filesread = NULL;
+    struct stat statbuf;
+
+    /* ignore repeated files. */
+    if (hard_opt == 0 && stat(file, &statbuf) == 0) {
+        struct fileread* r;
+
+        for (r = filesread; r; r = r->next)
+            if (r->dev == statbuf.st_dev && r->ino == statbuf.st_ino) return;
+
+        r = safe_malloc(sizeof(struct fileread));
+        r->next = filesread;
+        filesread = r;
+        r->dev = statbuf.st_dev;
+        r->ino = statbuf.st_ino;
+    }
+
+    if (nest > 20) die(_("files nested too deep in %s"), file, EC_BADCONF);
+
+    if (!(f = fopen(file, "r"))) {
+        if (errno == ENOENT && nest == 0)
+            return; /* No conffile, all done. */
+        else {
+            char* str = _("cannot read %s: %s");
+            if (hard_opt != 0) {
+                my_syslog(LOG_ERR, str, file, strerror(errno));
+                return;
+            } else
+                die(str, file, EC_FILE);
+        }
+    }
+
+    while (fgets(buff, MAXDNAME, f)) {
+        int white;
+        unsigned int lastquote;
+        char* errmess;
+
+        /* Memory allocation failure longjmps here if mem_recover == 1 */
+        if (hard_opt) {
+            if (setjmp(mem_jmp)) continue;
+            mem_recover = 1;
+        }
+
+        lineno++;
+        errmess = NULL;
+
+        /* Implement quotes, inside quotes we allow \\ \" \n and \t
+       metacharacters get hidden also strip comments */
+
+        for (white = 1, lastquote = 0, p = buff; *p; p++) {
+            if (*p == '"') {
+                memmove(p, p + 1, strlen(p + 1) + 1);
+                for (; *p && *p != '"'; p++) {
+                    if (*p == '\\' && strchr("\"tnebr\\", p[1])) {
+                        if (p[1] == 't')
+                            p[1] = '\t';
+                        else if (p[1] == 'n')
+                            p[1] = '\n';
+                        else if (p[1] == 'b')
+                            p[1] = '\b';
+                        else if (p[1] == 'r')
+                            p[1] = '\r';
+                        else if (p[1] == 'e') /* escape */
+                            p[1] = '\033';
+                        memmove(p, p + 1, strlen(p + 1) + 1);
+                    }
+                    *p = hide_meta(*p);
+                }
+                if (*p == '"') {
+                    memmove(p, p + 1, strlen(p + 1) + 1);
+                    lastquote = p - buff;
+                } else {
+                    errmess = _("missing \"");
+                    goto oops;
+                }
+            }
+
+            if (white && *p == '#') {
+                *p = 0;
+                break;
+            }
+            white = isspace((int) unhide_meta(*p));
+        }
+
+        /* fgets gets end of line char too. */
+        while (strlen(buff) > lastquote && isspace((int) unhide_meta(buff[strlen(buff) - 1])))
+            buff[strlen(buff) - 1] = 0;
+
+        if (*buff == 0) continue;
+
+        if (hard_opt != 0)
+            arg = buff;
+        else if ((p = strchr(buff, '='))) {
+            /* allow spaces around "=" */
+            arg = p + 1;
+            for (; p >= buff && (isspace((int) *p) || *p == '='); p--) *p = 0;
+        } else
+            arg = NULL;
+
+        if (hard_opt != 0)
+            option = hard_opt;
+        else {
+            /* skip leading space */
+            for (start = buff; *start && isspace((int) *start); start++)
+                ;
+
+            for (option = 0, i = 0; opts[i].name; i++)
+                if (strcmp(opts[i].name, start) == 0) {
+                    option = opts[i].val;
+                    break;
+                }
+
+            if (!option)
+                errmess = _("bad option");
+            else if (opts[i].has_arg == 0 && arg)
+                errmess = _("extraneous parameter");
+            else if (opts[i].has_arg == 1 && !arg)
+                errmess = _("missing parameter");
+        }
+
+        if (!errmess) {
+            if (arg)
+                for (; isspace((int) *arg); arg++)
+                    ;
+
+            errmess = one_opt(option, arg, _("error"), nest + 1);
+        }
+
+        if (errmess) {
+        oops:
+            sprintf(buff, _("%s at line %d of %%s"), errmess, lineno);
+            if (hard_opt != 0)
+                my_syslog(LOG_ERR, buff, file);
+            else
+                die(buff, file, EC_BADCONF);
+        }
+    }
+
+    mem_recover = 1;
+    fclose(f);
+}
+
+#ifdef HAVE_DHCP
+void reread_dhcp(void) {
+    if (daemon->dhcp_hosts_file) {
+        struct dhcp_config *configs, *cp, **up;
+
+        /* remove existing... */
+        for (up = &daemon->dhcp_conf, configs = daemon->dhcp_conf; configs; configs = cp) {
+            cp = configs->next;
+
+            if (configs->flags & CONFIG_BANK) {
+                struct hwaddr_config *mac, *tmp;
+
+                for (mac = configs->hwaddr; mac; mac = tmp) {
+                    tmp = mac->next;
+                    free(mac);
+                }
+                if (configs->flags & CONFIG_CLID) free(configs->clid);
+                if (configs->flags & CONFIG_NETID) free(configs->netid.net);
+                if (configs->flags & CONFIG_NAME) free(configs->hostname);
+
+                *up = configs->next;
+                free(configs);
+            } else
+                up = &configs->next;
+        }
+
+        one_file(daemon->dhcp_hosts_file, 1, LOPT_BANK);
+        my_syslog(MS_DHCP | LOG_INFO, _("read %s"), daemon->dhcp_hosts_file);
+    }
+
+    if (daemon->dhcp_opts_file) {
+        struct dhcp_opt *opts, *cp, **up;
+        struct dhcp_netid *id, *next;
+
+        for (up = &daemon->dhcp_opts, opts = daemon->dhcp_opts; opts; opts = cp) {
+            cp = opts->next;
+
+            if (opts->flags & DHOPT_BANK) {
+                if ((opts->flags & DHOPT_VENDOR)) free(opts->u.vendor_class);
+                free(opts->val);
+                for (id = opts->netid; id; id = next) {
+                    next = id->next;
+                    free(id->net);
+                    free(id);
+                }
+                *up = opts->next;
+                free(opts);
+            } else
+                up = &opts->next;
+        }
+
+        one_file(daemon->dhcp_opts_file, 1, LOPT_OPTS);
+        my_syslog(MS_DHCP | LOG_INFO, _("read %s"), daemon->dhcp_opts_file);
+    }
+}
+#endif
+
+void read_opts(int argc, char** argv, char* compile_opts) {
+    char* buff = opt_malloc(MAXDNAME);
+    int option, nest = 0, testmode = 0;
+    char *errmess, *arg, *conffile = CONFFILE;
+
+    opterr = 0;
+
+    daemon = opt_malloc(sizeof(struct daemon));
+    memset(daemon, 0, sizeof(struct daemon));
+    daemon->namebuff = buff;
+
+    /* Set defaults - everything else is zero or NULL */
+    daemon->cachesize = CACHESIZ;
+    daemon->ftabsize = FTABSIZ;
+    daemon->port = NAMESERVER_PORT;
+    daemon->dhcp_client_port = DHCP_CLIENT_PORT;
+    daemon->dhcp_server_port = DHCP_SERVER_PORT;
+    daemon->default_resolv.is_default = 1;
+    daemon->default_resolv.name = RESOLVFILE;
+    daemon->resolv_files = &daemon->default_resolv;
+    daemon->username = CHUSER;
+    daemon->runfile = RUNFILE;
+    daemon->dhcp_max = MAXLEASES;
+    daemon->edns_pktsz = EDNS_PKTSZ;
+    daemon->log_fac = -1;
+    add_txt("version.bind", "dnsmasq-" VERSION);
+    add_txt("authors.bind", "Simon Kelley");
+    add_txt("copyright.bind", COPYRIGHT);
+
+    while (1) {
 #ifdef HAVE_GETOPT_LONG
-	  errmess = one_opt(option, arg, _("try --help"), 0);
-#else 
-	  errmess = one_opt(option, arg, _("try -w"), 0); 
-#endif  
-	  if (errmess)
-	    die(_("bad command line options: %s"), errmess, EC_BADCONF);
-	}
+        option = getopt_long(argc, argv, OPTSTRING, opts, NULL);
+#else
+        option = getopt(argc, argv, OPTSTRING);
+#endif
+
+        if (option == -1) break;
+
+        /* Copy optarg so that argv doesn't get changed */
+        if (optarg) {
+            strncpy(buff, optarg, MAXDNAME);
+            buff[MAXDNAME - 1] = 0;
+            arg = buff;
+        } else
+            arg = NULL;
+
+        /* command-line only stuff */
+        if (option == LOPT_TEST)
+            testmode = 1;
+        else if (option == 'w') {
+            if (argc != 3 || strcmp(argv[2], "dhcp") != 0) do_usage();
+#ifdef HAVE_DHCP
+            else
+                display_opts();
+#endif
+            exit(0);
+        } else if (option == 'v') {
+            printf(_("Dnsmasq version %s  %s\n"), VERSION, COPYRIGHT);
+            printf(_("Compile time options %s\n\n"), compile_opts);
+            printf(_("This software comes with ABSOLUTELY NO WARRANTY.\n"));
+            printf(_("Dnsmasq is free software, and you are welcome to redistribute it\n"));
+            printf(_("under the terms of the GNU General Public License, version 2 or 3.\n"));
+            exit(0);
+        } else if (option == 'C') {
+            conffile = opt_string_alloc(arg);
+            nest++;
+        } else {
+#ifdef HAVE_GETOPT_LONG
+            errmess = one_opt(option, arg, _("try --help"), 0);
+#else
+            errmess = one_opt(option, arg, _("try -w"), 0);
+#endif
+            if (errmess) die(_("bad command line options: %s"), errmess, EC_BADCONF);
+        }
     }
 
-  if (conffile)
-    one_file(conffile, nest, 0);
+    if (conffile) one_file(conffile, nest, 0);
 
-  /* port might not be known when the address is parsed - fill in here */
-  if (daemon->servers)
-    {
-      struct server *tmp;
-      for (tmp = daemon->servers; tmp; tmp = tmp->next)
-	if (!(tmp->flags & SERV_HAS_SOURCE))
-	  {
-	    if (tmp->source_addr.sa.sa_family == AF_INET)
-	      tmp->source_addr.in.sin_port = htons(daemon->query_port);
+    /* port might not be known when the address is parsed - fill in here */
+    if (daemon->servers) {
+        struct server* tmp;
+        for (tmp = daemon->servers; tmp; tmp = tmp->next)
+            if (!(tmp->flags & SERV_HAS_SOURCE)) {
+                if (tmp->source_addr.sa.sa_family == AF_INET)
+                    tmp->source_addr.in.sin_port = htons(daemon->query_port);
 #ifdef HAVE_IPV6
-	    else if (tmp->source_addr.sa.sa_family == AF_INET6)
-	      tmp->source_addr.in6.sin6_port = htons(daemon->query_port);
-#endif 
-	  } 
+                else if (tmp->source_addr.sa.sa_family == AF_INET6)
+                    tmp->source_addr.in6.sin6_port = htons(daemon->query_port);
+#endif
+            }
     }
-  
-  if (daemon->if_addrs)
-    {  
-      struct iname *tmp;
-      for(tmp = daemon->if_addrs; tmp; tmp = tmp->next)
-	if (tmp->addr.sa.sa_family == AF_INET)
-	  tmp->addr.in.sin_port = htons(daemon->port);
+
+    if (daemon->if_addrs) {
+        struct iname* tmp;
+        for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
+            if (tmp->addr.sa.sa_family == AF_INET) tmp->addr.in.sin_port = htons(daemon->port);
 #ifdef HAVE_IPV6
-	else if (tmp->addr.sa.sa_family == AF_INET6)
-	  tmp->addr.in6.sin6_port = htons(daemon->port);
+            else if (tmp->addr.sa.sa_family == AF_INET6)
+                tmp->addr.in6.sin6_port = htons(daemon->port);
 #endif /* IPv6 */
     }
-		      
-  /* only one of these need be specified: the other defaults to the host-name */
-  if ((daemon->options & OPT_LOCALMX) || daemon->mxnames || daemon->mxtarget)
-    {
-      struct mx_srv_record *mx;
-      
-      if (gethostname(buff, MAXDNAME) == -1)
-	die(_("cannot get host-name: %s"), NULL, EC_MISC);
-      
-      for (mx = daemon->mxnames; mx; mx = mx->next)
-	if (!mx->issrv && hostname_isequal(mx->name, buff))
-	  break;
-      
-      if ((daemon->mxtarget || (daemon->options & OPT_LOCALMX)) && !mx)
-	{
-	  mx = opt_malloc(sizeof(struct mx_srv_record));
-	  mx->next = daemon->mxnames;
-	  mx->issrv = 0;
-	  mx->target = NULL;
-	  mx->name = opt_string_alloc(buff);
-	  daemon->mxnames = mx;
-	}
-      
-      if (!daemon->mxtarget)
-	daemon->mxtarget = opt_string_alloc(buff);
 
-      for (mx = daemon->mxnames; mx; mx = mx->next)
-	if (!mx->issrv && !mx->target)
-	  mx->target = daemon->mxtarget;
+    /* only one of these need be specified: the other defaults to the host-name */
+    if ((daemon->options & OPT_LOCALMX) || daemon->mxnames || daemon->mxtarget) {
+        struct mx_srv_record* mx;
+
+        if (gethostname(buff, MAXDNAME) == -1) die(_("cannot get host-name: %s"), NULL, EC_MISC);
+
+        for (mx = daemon->mxnames; mx; mx = mx->next)
+            if (!mx->issrv && hostname_isequal(mx->name, buff)) break;
+
+        if ((daemon->mxtarget || (daemon->options & OPT_LOCALMX)) && !mx) {
+            mx = opt_malloc(sizeof(struct mx_srv_record));
+            mx->next = daemon->mxnames;
+            mx->issrv = 0;
+            mx->target = NULL;
+            mx->name = opt_string_alloc(buff);
+            daemon->mxnames = mx;
+        }
+
+        if (!daemon->mxtarget) daemon->mxtarget = opt_string_alloc(buff);
+
+        for (mx = daemon->mxnames; mx; mx = mx->next)
+            if (!mx->issrv && !mx->target) mx->target = daemon->mxtarget;
     }
 
-  if (!(daemon->options & OPT_NO_RESOLV) &&
-      daemon->resolv_files && 
-      daemon->resolv_files->next && 
-      (daemon->options & OPT_NO_POLL))
-    die(_("only one resolv.conf file allowed in no-poll mode."), NULL, EC_BADCONF);
-  
-  if (daemon->options & OPT_RESOLV_DOMAIN)
-    {
-      char *line;
-      FILE *f;
+    if (!(daemon->options & OPT_NO_RESOLV) && daemon->resolv_files && daemon->resolv_files->next &&
+        (daemon->options & OPT_NO_POLL))
+        die(_("only one resolv.conf file allowed in no-poll mode."), NULL, EC_BADCONF);
 
-      if ((daemon->options & OPT_NO_RESOLV) ||
-	  !daemon->resolv_files || 
-	  (daemon->resolv_files)->next)
-	die(_("must have exactly one resolv.conf to read domain from."), NULL, EC_BADCONF);
-      
-      if (!(f = fopen((daemon->resolv_files)->name, "r")))
-	die(_("failed to read %s: %s"), (daemon->resolv_files)->name, EC_FILE);
-      
-      while ((line = fgets(buff, MAXDNAME, f)))
-	{
-	  char *token = strtok(line, " \t\n\r");
-	  
-	  if (!token || strcmp(token, "search") != 0)
-	    continue;
-	  
-	  if ((token = strtok(NULL, " \t\n\r")) &&  
-	      (daemon->domain_suffix = canonicalise_opt(token)))
-	    break;
-	}
+    if (daemon->options & OPT_RESOLV_DOMAIN) {
+        char* line;
+        FILE* f;
 
-      fclose(f);
+        if ((daemon->options & OPT_NO_RESOLV) || !daemon->resolv_files ||
+            (daemon->resolv_files)->next)
+            die(_("must have exactly one resolv.conf to read domain from."), NULL, EC_BADCONF);
 
-      if (!daemon->domain_suffix)
-	die(_("no search directive found in %s"), (daemon->resolv_files)->name, EC_MISC);
+        if (!(f = fopen((daemon->resolv_files)->name, "r")))
+            die(_("failed to read %s: %s"), (daemon->resolv_files)->name, EC_FILE);
+
+        while ((line = fgets(buff, MAXDNAME, f))) {
+            char* token = strtok(line, " \t\n\r");
+
+            if (!token || strcmp(token, "search") != 0) continue;
+
+            if ((token = strtok(NULL, " \t\n\r")) &&
+                (daemon->domain_suffix = canonicalise_opt(token)))
+                break;
+        }
+
+        fclose(f);
+
+        if (!daemon->domain_suffix)
+            die(_("no search directive found in %s"), (daemon->resolv_files)->name, EC_MISC);
     }
 
-  if (daemon->domain_suffix)
-    {
-       /* add domain for any srv record without one. */
-      struct mx_srv_record *srv;
-      
-      for (srv = daemon->mxnames; srv; srv = srv->next)
-	if (srv->issrv &&
-	    strchr(srv->name, '.') && 
-	    strchr(srv->name, '.') == strrchr(srv->name, '.'))
-	  {
-	    strcpy(buff, srv->name);
-	    strcat(buff, ".");
-	    strcat(buff, daemon->domain_suffix);
-	    free(srv->name);
-	    srv->name = opt_string_alloc(buff);
-	  }
-    }
-  else if (daemon->options & OPT_DHCP_FQDN)
-    die(_("there must be a default domain when --dhcp-fqdn is set"), NULL, EC_BADCONF);
+    if (daemon->domain_suffix) {
+        /* add domain for any srv record without one. */
+        struct mx_srv_record* srv;
 
-  if (testmode)
-    {
-      fprintf(stderr, "dnsmasq: %s.\n", _("syntax check OK"));
-      exit(0);
+        for (srv = daemon->mxnames; srv; srv = srv->next)
+            if (srv->issrv && strchr(srv->name, '.') &&
+                strchr(srv->name, '.') == strrchr(srv->name, '.')) {
+                strcpy(buff, srv->name);
+                strcat(buff, ".");
+                strcat(buff, daemon->domain_suffix);
+                free(srv->name);
+                srv->name = opt_string_alloc(buff);
+            }
+    } else if (daemon->options & OPT_DHCP_FQDN)
+        die(_("there must be a default domain when --dhcp-fqdn is set"), NULL, EC_BADCONF);
+
+    if (testmode) {
+        fprintf(stderr, "dnsmasq: %s.\n", _("syntax check OK"));
+        exit(0);
     }
-}  
+}
diff --git a/src/rfc1035.c b/src/rfc1035.c
index d4e9bf5..0f883e1 100644
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -4,1609 +4,1336 @@
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; version 2 dated June, 1991, or
    (at your option) version 3 dated 29 June, 2007.
- 
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-     
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "dnsmasq.h"
 
-static int add_resource_record(HEADER *header, char *limit, int *truncp, 
-			       unsigned int nameoffset, unsigned char **pp, 
-			       unsigned long ttl, unsigned int *offset, unsigned short type, 
-			       unsigned short class, char *format, ...);
+static int add_resource_record(HEADER* header, char* limit, int* truncp, unsigned int nameoffset,
+                               unsigned char** pp, unsigned long ttl, unsigned int* offset,
+                               unsigned short type, unsigned short class, char* format, ...);
 
 #define CHECK_LEN(header, pp, plen, len) \
-    ((size_t)((pp) - (unsigned char *)(header) + (len)) <= (plen))
+    ((size_t)((pp) - (unsigned char*) (header) + (len)) <= (plen))
 
 #define ADD_RDLEN(header, pp, plen, len) \
-    (!CHECK_LEN(header, pp, plen, len) ? 0 : (long)((pp) += (len)), 1)
+    (!CHECK_LEN(header, pp, plen, len) ? 0 : (long) ((pp) += (len)), 1)
 
-static int extract_name(HEADER *header, size_t plen, unsigned char **pp, 
-			char *name, int isExtract, int extrabytes)
-{
-  unsigned char *cp = (unsigned char *)name, *p = *pp, *p1 = NULL;
-  unsigned int j, l, hops = 0;
-  int retvalue = 1;
-  
-  if (isExtract)
-    *cp = 0;
+static int extract_name(HEADER* header, size_t plen, unsigned char** pp, char* name, int isExtract,
+                        int extrabytes) {
+    unsigned char *cp = (unsigned char*) name, *p = *pp, *p1 = NULL;
+    unsigned int j, l, hops = 0;
+    int retvalue = 1;
 
-  while (1)
-    { 
-      unsigned int label_type;
+    if (isExtract) *cp = 0;
 
-      if (!CHECK_LEN(header, p, plen, 1))
-	return 0;
-      
-      if ((l = *p++) == 0) 
-	/* end marker */
-	{
-	  /* check that there are the correct no of bytes after the name */
-	  if (!CHECK_LEN(header, p1 ? p1 : p, plen, extrabytes))
-	    return 0;
-	  
-	  if (isExtract)
-	    {
-	      if (cp != (unsigned char *)name)
-		cp--;
-	      *cp = 0; /* terminate: lose final period */
-	    }
-	  else if (*cp != 0)
-	    retvalue = 2;
-	  
-	  if (p1) /* we jumped via compression */
-	    *pp = p1;
-	  else
-	    *pp = p;
-	  
-	  return retvalue;
-	}
+    while (1) {
+        unsigned int label_type;
 
-      label_type = l & 0xc0;
-      
-      if (label_type == 0xc0) /* pointer */
-	{ 
-	  if (!CHECK_LEN(header, p, plen, 1))
-	    return 0;
-	      
-	  /* get offset */
-	  l = (l&0x3f) << 8;
-	  l |= *p++;
-	  
-	  if (!p1) /* first jump, save location to go back to */
-	    p1 = p;
-	      
-	  hops++; /* break malicious infinite loops */
-	  if (hops > 255)
-	    return 0;
-	  
-	  p = l + (unsigned char *)header;
-	}
-      else if (label_type == 0x80)
-	return 0; /* reserved */
-      else if (label_type == 0x40)
-	{ /* ELT */
-	  unsigned int count, digs;
-	  
-	  if ((l & 0x3f) != 1)
-	    return 0; /* we only understand bitstrings */
+        if (!CHECK_LEN(header, p, plen, 1)) return 0;
 
-	  if (!isExtract)
-	    return 0; /* Cannot compare bitsrings */
-	  
-	  count = *p++;
-	  if (count == 0)
-	    count = 256;
-	  digs = ((count-1)>>2)+1;
-	  
-	  /* output is \[x<hex>/siz]. which is digs+9 chars */
-	  if (cp - (unsigned char *)name + digs + 9 >= MAXDNAME)
-	    return 0;
-	  if (!CHECK_LEN(header, p, plen, (count-1)>>3))
-	    return 0;
+        if ((l = *p++) == 0)
+        /* end marker */
+        {
+            /* check that there are the correct no of bytes after the name */
+            if (!CHECK_LEN(header, p1 ? p1 : p, plen, extrabytes)) return 0;
 
-	  *cp++ = '\\';
-	  *cp++ = '[';
-	  *cp++ = 'x';
-	  for (j=0; j<digs; j++)
-	    {
-	      unsigned int dig;
-	      if (j%2 == 0)
-		dig = *p >> 4;
-	      else
-		dig = *p++ & 0x0f;
-	      
-	      *cp++ = dig < 10 ? dig + '0' : dig + 'A' - 10;
-	    } 
-	  cp += sprintf((char *)cp, "/%d]", count);
-	  /* do this here to overwrite the zero char from sprintf */
-	  *cp++ = '.';
-	}
-      else 
-	{ /* label_type = 0 -> label. */
-	  if (cp - (unsigned char *)name + l + 1 >= MAXDNAME)
-	    return 0;
-	  if (!CHECK_LEN(header, p, plen, l))
-	    return 0;
-	  
-	  for(j=0; j<l; j++, p++)
-	    if (isExtract)
-	      {
-		unsigned char c = *p;
-		if (isascii(c) && !iscntrl(c) && c != '.')
-		  *cp++ = *p;
-		else
-		  return 0;
-	      }
-	    else 
-	      {
-		unsigned char c1 = *cp, c2 = *p;
-		
-		if (c1 == 0)
-		  retvalue = 2;
-		else 
-		  {
-		    cp++;
-		    if (c1 >= 'A' && c1 <= 'Z')
-		      c1 += 'a' - 'A';
-		    if (c2 >= 'A' && c2 <= 'Z')
-		      c2 += 'a' - 'A';
-		    
-		    if (c1 != c2)
-		      retvalue =  2;
-		  }
-	      }
-	  
-	  if (isExtract)
-	    *cp++ = '.';
-	  else if (*cp != 0 && *cp++ != '.')
-	    retvalue = 2;
-	}
+            if (isExtract) {
+                if (cp != (unsigned char*) name) cp--;
+                *cp = 0; /* terminate: lose final period */
+            } else if (*cp != 0)
+                retvalue = 2;
+
+            if (p1) /* we jumped via compression */
+                *pp = p1;
+            else
+                *pp = p;
+
+            return retvalue;
+        }
+
+        label_type = l & 0xc0;
+
+        if (label_type == 0xc0) /* pointer */
+        {
+            if (!CHECK_LEN(header, p, plen, 1)) return 0;
+
+            /* get offset */
+            l = (l & 0x3f) << 8;
+            l |= *p++;
+
+            if (!p1) /* first jump, save location to go back to */
+                p1 = p;
+
+            hops++; /* break malicious infinite loops */
+            if (hops > 255) return 0;
+
+            p = l + (unsigned char*) header;
+        } else if (label_type == 0x80)
+            return 0;                  /* reserved */
+        else if (label_type == 0x40) { /* ELT */
+            unsigned int count, digs;
+
+            if ((l & 0x3f) != 1) return 0; /* we only understand bitstrings */
+
+            if (!isExtract) return 0; /* Cannot compare bitsrings */
+
+            count = *p++;
+            if (count == 0) count = 256;
+            digs = ((count - 1) >> 2) + 1;
+
+            /* output is \[x<hex>/siz]. which is digs+9 chars */
+            if (cp - (unsigned char*) name + digs + 9 >= MAXDNAME) return 0;
+            if (!CHECK_LEN(header, p, plen, (count - 1) >> 3)) return 0;
+
+            *cp++ = '\\';
+            *cp++ = '[';
+            *cp++ = 'x';
+            for (j = 0; j < digs; j++) {
+                unsigned int dig;
+                if (j % 2 == 0)
+                    dig = *p >> 4;
+                else
+                    dig = *p++ & 0x0f;
+
+                *cp++ = dig < 10 ? dig + '0' : dig + 'A' - 10;
+            }
+            cp += sprintf((char*) cp, "/%d]", count);
+            /* do this here to overwrite the zero char from sprintf */
+            *cp++ = '.';
+        } else { /* label_type = 0 -> label. */
+            if (cp - (unsigned char*) name + l + 1 >= MAXDNAME) return 0;
+            if (!CHECK_LEN(header, p, plen, l)) return 0;
+
+            for (j = 0; j < l; j++, p++)
+                if (isExtract) {
+                    unsigned char c = *p;
+                    if (isascii(c) && !iscntrl(c) && c != '.')
+                        *cp++ = *p;
+                    else
+                        return 0;
+                } else {
+                    unsigned char c1 = *cp, c2 = *p;
+
+                    if (c1 == 0)
+                        retvalue = 2;
+                    else {
+                        cp++;
+                        if (c1 >= 'A' && c1 <= 'Z') c1 += 'a' - 'A';
+                        if (c2 >= 'A' && c2 <= 'Z') c2 += 'a' - 'A';
+
+                        if (c1 != c2) retvalue = 2;
+                    }
+                }
+
+            if (isExtract)
+                *cp++ = '.';
+            else if (*cp != 0 && *cp++ != '.')
+                retvalue = 2;
+        }
     }
 }
- 
+
 /* Max size of input string (for IPv6) is 75 chars.) */
 #define MAXARPANAME 75
-static int in_arpa_name_2_addr(char *namein, struct all_addr *addrp)
-{
-  int j;
-  char name[MAXARPANAME+1], *cp1;
-  unsigned char *addr = (unsigned char *)addrp;
-  char *lastchunk = NULL, *penchunk = NULL;
-  
-  if (strlen(namein) > MAXARPANAME)
-    return 0;
+static int in_arpa_name_2_addr(char* namein, struct all_addr* addrp) {
+    int j;
+    char name[MAXARPANAME + 1], *cp1;
+    unsigned char* addr = (unsigned char*) addrp;
+    char *lastchunk = NULL, *penchunk = NULL;
 
-  memset(addrp, 0, sizeof(struct all_addr));
+    if (strlen(namein) > MAXARPANAME) return 0;
 
-  /* turn name into a series of asciiz strings */
-  /* j counts no of labels */
-  for(j = 1,cp1 = name; *namein; cp1++, namein++)
-    if (*namein == '.')
-      {
-	penchunk = lastchunk;
-        lastchunk = cp1 + 1;
-	*cp1 = 0;
-	j++;
-      }
-    else
-      *cp1 = *namein;
-  
-  *cp1 = 0;
+    memset(addrp, 0, sizeof(struct all_addr));
 
-  if (j<3)
-    return 0;
+    /* turn name into a series of asciiz strings */
+    /* j counts no of labels */
+    for (j = 1, cp1 = name; *namein; cp1++, namein++)
+        if (*namein == '.') {
+            penchunk = lastchunk;
+            lastchunk = cp1 + 1;
+            *cp1 = 0;
+            j++;
+        } else
+            *cp1 = *namein;
 
-  if (hostname_isequal(lastchunk, "arpa") && hostname_isequal(penchunk, "in-addr"))
-    {
-      /* IP v4 */
-      /* address arives as a name of the form
-	 www.xxx.yyy.zzz.in-addr.arpa
-	 some of the low order address octets might be missing
-	 and should be set to zero. */
-      for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1)+1)
-	{
-	  /* check for digits only (weeds out things like
-	     50.0/24.67.28.64.in-addr.arpa which are used 
-	     as CNAME targets according to RFC 2317 */
-	  char *cp;
-	  for (cp = cp1; *cp; cp++)
-	    if (!isdigit((int)*cp))
-	      return 0;
-	  
-	  addr[3] = addr[2];
-	  addr[2] = addr[1];
-	  addr[1] = addr[0];
-	  addr[0] = atoi(cp1);
-	}
+    *cp1 = 0;
 
-      return F_IPV4;
+    if (j < 3) return 0;
+
+    if (hostname_isequal(lastchunk, "arpa") && hostname_isequal(penchunk, "in-addr")) {
+        /* IP v4 */
+        /* address arives as a name of the form
+       www.xxx.yyy.zzz.in-addr.arpa
+       some of the low order address octets might be missing
+       and should be set to zero. */
+        for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1) + 1) {
+            /* check for digits only (weeds out things like
+               50.0/24.67.28.64.in-addr.arpa which are used
+               as CNAME targets according to RFC 2317 */
+            char* cp;
+            for (cp = cp1; *cp; cp++)
+                if (!isdigit((int) *cp)) return 0;
+
+            addr[3] = addr[2];
+            addr[2] = addr[1];
+            addr[1] = addr[0];
+            addr[0] = atoi(cp1);
+        }
+
+        return F_IPV4;
     }
 #ifdef HAVE_IPV6
-  else if (hostname_isequal(penchunk, "ip6") && 
-	   (hostname_isequal(lastchunk, "int") || hostname_isequal(lastchunk, "arpa")))
-    {
-      /* IP v6:
-         Address arrives as 0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.ip6.[int|arpa]
-    	 or \[xfedcba9876543210fedcba9876543210/128].ip6.[int|arpa]
-      
-	 Note that most of these the various reprentations are obsolete and 
-	 left-over from the many DNS-for-IPv6 wars. We support all the formats
-	 that we can since there is no reason not to.
-      */
+    else if (hostname_isequal(penchunk, "ip6") &&
+             (hostname_isequal(lastchunk, "int") || hostname_isequal(lastchunk, "arpa"))) {
+        /* IP v6:
+           Address arrives as 0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.ip6.[int|arpa]
+           or \[xfedcba9876543210fedcba9876543210/128].ip6.[int|arpa]
 
-      /* TODO: does this make sense? */
+       Note that most of these the various reprentations are obsolete and
+       left-over from the many DNS-for-IPv6 wars. We support all the formats
+       that we can since there is no reason not to.
+        */
 
-      if (*name == '\\' && *(name+1) == '[' && 
-	  (*(name+2) == 'x' || *(name+2) == 'X'))
-	{	  
-	  for (j = 0, cp1 = name+3; *cp1 && isxdigit((int) *cp1) && j < 32; cp1++, j++)
-	    {
-	      char xdig[2];
-	      xdig[0] = *cp1;
-	      xdig[1] = 0;
-	      if (j%2)
-		addr[j/2] |= strtol(xdig, NULL, 16);
-	      else
-		addr[j/2] = strtol(xdig, NULL, 16) << 4;
-	    }
-	  
-	  if (*cp1 == '/' && j == 32)
-	    return F_IPV6;
-	}
-      else
-	{
-	  for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1)+1)
-	    {
-	      if (*(cp1+1) || !isxdigit((int)*cp1))
-		return 0;
-	      
-	      for (j = sizeof(struct all_addr)-1; j>0; j--)
-		addr[j] = (addr[j] >> 4) | (addr[j-1] << 4);
-	      addr[0] = (addr[0] >> 4) | (strtol(cp1, NULL, 16) << 4);
-	    }
-	  
-	  return F_IPV6;
-	}
+        /* TODO: does this make sense? */
+
+        if (*name == '\\' && *(name + 1) == '[' && (*(name + 2) == 'x' || *(name + 2) == 'X')) {
+            for (j = 0, cp1 = name + 3; *cp1 && isxdigit((int) *cp1) && j < 32; cp1++, j++) {
+                char xdig[2];
+                xdig[0] = *cp1;
+                xdig[1] = 0;
+                if (j % 2)
+                    addr[j / 2] |= strtol(xdig, NULL, 16);
+                else
+                    addr[j / 2] = strtol(xdig, NULL, 16) << 4;
+            }
+
+            if (*cp1 == '/' && j == 32) return F_IPV6;
+        } else {
+            for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1) + 1) {
+                if (*(cp1 + 1) || !isxdigit((int) *cp1)) return 0;
+
+                for (j = sizeof(struct all_addr) - 1; j > 0; j--)
+                    addr[j] = (addr[j] >> 4) | (addr[j - 1] << 4);
+                addr[0] = (addr[0] >> 4) | (strtol(cp1, NULL, 16) << 4);
+            }
+
+            return F_IPV6;
+        }
     }
 #endif
-  
-  return 0;
+
+    return 0;
 }
 
-static unsigned char *skip_name(unsigned char *ansp, HEADER *header, size_t plen, int extrabytes)
-{
-  while(1)
-    {
-      unsigned int label_type;
-      
-      if (!CHECK_LEN(header, ansp, plen, 1))
-	return NULL;
-      
-      label_type = (*ansp) & 0xc0;
+static unsigned char* skip_name(unsigned char* ansp, HEADER* header, size_t plen, int extrabytes) {
+    while (1) {
+        unsigned int label_type;
 
-      if (label_type == 0xc0)
-	{
-	  /* pointer for compression. */
-	  ansp += 2;	
-	  break;
-	}
-      else if (label_type == 0x80)
-	return NULL; /* reserved */
-      else if (label_type == 0x40)
-	{
-	  /* Extended label type */
-	  unsigned int count;
-	  
-	  if (!CHECK_LEN(header, ansp, plen, 2))
-	    return NULL;
-	  
-	  if (((*ansp++) & 0x3f) != 1)
-	    return NULL; /* we only understand bitstrings */
-	  
-	  count = *(ansp++); /* Bits in bitstring */
-	  
-	  if (count == 0) /* count == 0 means 256 bits */
-	    ansp += 32;
-	  else
-	    ansp += ((count-1)>>3)+1;
-	}
-      else
-	{ /* label type == 0 Bottom six bits is length */
-	  unsigned int len = (*ansp++) & 0x3f;
-	  
-	  if (!ADD_RDLEN(header, ansp, plen, len))
-	    return NULL;
+        if (!CHECK_LEN(header, ansp, plen, 1)) return NULL;
 
-	  if (len == 0)
-	    break; /* zero length label marks the end. */
-	}
+        label_type = (*ansp) & 0xc0;
+
+        if (label_type == 0xc0) {
+            /* pointer for compression. */
+            ansp += 2;
+            break;
+        } else if (label_type == 0x80)
+            return NULL; /* reserved */
+        else if (label_type == 0x40) {
+            /* Extended label type */
+            unsigned int count;
+
+            if (!CHECK_LEN(header, ansp, plen, 2)) return NULL;
+
+            if (((*ansp++) & 0x3f) != 1) return NULL; /* we only understand bitstrings */
+
+            count = *(ansp++); /* Bits in bitstring */
+
+            if (count == 0) /* count == 0 means 256 bits */
+                ansp += 32;
+            else
+                ansp += ((count - 1) >> 3) + 1;
+        } else { /* label type == 0 Bottom six bits is length */
+            unsigned int len = (*ansp++) & 0x3f;
+
+            if (!ADD_RDLEN(header, ansp, plen, len)) return NULL;
+
+            if (len == 0) break; /* zero length label marks the end. */
+        }
     }
 
-  if (!CHECK_LEN(header, ansp, plen, extrabytes))
-    return NULL;
-  
-  return ansp;
+    if (!CHECK_LEN(header, ansp, plen, extrabytes)) return NULL;
+
+    return ansp;
 }
 
-static unsigned char *skip_questions(HEADER *header, size_t plen)
-{
-  int q;
-  unsigned char *ansp = (unsigned char *)(header+1);
+static unsigned char* skip_questions(HEADER* header, size_t plen) {
+    int q;
+    unsigned char* ansp = (unsigned char*) (header + 1);
 
-  for (q = ntohs(header->qdcount); q != 0; q--)
-    {
-      if (!(ansp = skip_name(ansp, header, plen, 4)))
-	return NULL;
-      ansp += 4; /* class and type */
-    }
-  
-  return ansp;
-}
-
-static unsigned char *skip_section(unsigned char *ansp, int count, HEADER *header, size_t plen)
-{
-  int i, rdlen;
-  
-  for (i = 0; i < count; i++)
-    {
-      if (!(ansp = skip_name(ansp, header, plen, 10)))
-	return NULL; 
-      ansp += 8; /* type, class, TTL */
-      GETSHORT(rdlen, ansp);
-      if (!ADD_RDLEN(header, ansp, plen, rdlen))
-	return NULL;
+    for (q = ntohs(header->qdcount); q != 0; q--) {
+        if (!(ansp = skip_name(ansp, header, plen, 4))) return NULL;
+        ansp += 4; /* class and type */
     }
 
-  return ansp;
+    return ansp;
 }
 
-/* CRC the question section. This is used to safely detect query 
-   retransmision and to detect answers to questions we didn't ask, which 
-   might be poisoning attacks. Note that we decode the name rather 
-   than CRC the raw bytes, since replies might be compressed differently. 
+static unsigned char* skip_section(unsigned char* ansp, int count, HEADER* header, size_t plen) {
+    int i, rdlen;
+
+    for (i = 0; i < count; i++) {
+        if (!(ansp = skip_name(ansp, header, plen, 10))) return NULL;
+        ansp += 8; /* type, class, TTL */
+        GETSHORT(rdlen, ansp);
+        if (!ADD_RDLEN(header, ansp, plen, rdlen)) return NULL;
+    }
+
+    return ansp;
+}
+
+/* CRC the question section. This is used to safely detect query
+   retransmision and to detect answers to questions we didn't ask, which
+   might be poisoning attacks. Note that we decode the name rather
+   than CRC the raw bytes, since replies might be compressed differently.
    We ignore case in the names for the same reason. Return all-ones
    if there is not question section. */
-unsigned int questions_crc(HEADER *header, size_t plen, char *name)
-{
-  int q;
-  unsigned int crc = 0xffffffff;
-  unsigned char *p1, *p = (unsigned char *)(header+1);
+unsigned int questions_crc(HEADER* header, size_t plen, char* name) {
+    int q;
+    unsigned int crc = 0xffffffff;
+    unsigned char *p1, *p = (unsigned char*) (header + 1);
 
-  for (q = ntohs(header->qdcount); q != 0; q--) 
-    {
-      if (!extract_name(header, plen, &p, name, 1, 4))
-	return crc; /* bad packet */
-      
-      for (p1 = (unsigned char *)name; *p1; p1++)
-	{
-	  int i = 8;
-	  char c = *p1;
+    for (q = ntohs(header->qdcount); q != 0; q--) {
+        if (!extract_name(header, plen, &p, name, 1, 4)) return crc; /* bad packet */
 
-	  if (c >= 'A' && c <= 'Z')
-	    c += 'a' - 'A';
+        for (p1 = (unsigned char*) name; *p1; p1++) {
+            int i = 8;
+            char c = *p1;
 
-	  crc ^= c << 24;
-	  while (i--)
-	    crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
-	}
-      
-      /* CRC the class and type as well */
-      for (p1 = p; p1 < p+4; p1++)
-	{
-	  int i = 8;
-	  crc ^= *p1 << 24;
-	  while (i--)
-	    crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
-	}
+            if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
 
-      p += 4;
-      if (!CHECK_LEN(header, p, plen, 0))
-	return crc; /* bad packet */
+            crc ^= c << 24;
+            while (i--) crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
+        }
+
+        /* CRC the class and type as well */
+        for (p1 = p; p1 < p + 4; p1++) {
+            int i = 8;
+            crc ^= *p1 << 24;
+            while (i--) crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
+        }
+
+        p += 4;
+        if (!CHECK_LEN(header, p, plen, 0)) return crc; /* bad packet */
     }
 
-  return crc;
+    return crc;
 }
 
+size_t resize_packet(HEADER* header, size_t plen, unsigned char* pheader, size_t hlen) {
+    unsigned char* ansp = skip_questions(header, plen);
 
-size_t resize_packet(HEADER *header, size_t plen, unsigned char *pheader, size_t hlen)
-{
-  unsigned char *ansp = skip_questions(header, plen);
-    
-  /* if packet is malformed, just return as-is. */
-  if (!ansp)
-    return plen;
-  
-  if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount),
-			    header, plen)))
-    return plen;
-    
-  /* restore pseudoheader */
-  if (pheader && ntohs(header->arcount) == 0)
-    {
-      /* must use memmove, may overlap */
-      memmove(ansp, pheader, hlen);
-      header->arcount = htons(1);
-      ansp += hlen;
+    /* if packet is malformed, just return as-is. */
+    if (!ansp) return plen;
+
+    if (!(ansp = skip_section(
+              ansp, ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount),
+              header, plen)))
+        return plen;
+
+    /* restore pseudoheader */
+    if (pheader && ntohs(header->arcount) == 0) {
+        /* must use memmove, may overlap */
+        memmove(ansp, pheader, hlen);
+        header->arcount = htons(1);
+        ansp += hlen;
     }
 
-  return ansp - (unsigned char *)header;
+    return ansp - (unsigned char*) header;
 }
 
-unsigned char *find_pseudoheader(HEADER *header, size_t plen, size_t  *len, unsigned char **p, int *is_sign)
-{
-  /* See if packet has an RFC2671 pseudoheader, and if so return a pointer to it. 
-     also return length of pseudoheader in *len and pointer to the UDP size in *p
-     Finally, check to see if a packet is signed. If it is we cannot change a single bit before
-     forwarding. We look for SIG and TSIG in the addition section, and TKEY queries (for GSS-TSIG) */
-  
-  int i, arcount = ntohs(header->arcount);
-  unsigned char *ansp = (unsigned char *)(header+1);
-  unsigned short rdlen, type, class;
-  unsigned char *ret = NULL;
+unsigned char* find_pseudoheader(HEADER* header, size_t plen, size_t* len, unsigned char** p,
+                                 int* is_sign) {
+    /* See if packet has an RFC2671 pseudoheader, and if so return a pointer to it.
+       also return length of pseudoheader in *len and pointer to the UDP size in *p
+       Finally, check to see if a packet is signed. If it is we cannot change a single bit before
+       forwarding. We look for SIG and TSIG in the addition section, and TKEY queries (for GSS-TSIG) */
 
-  if (is_sign)
-    {
-      *is_sign = 0;
+    int i, arcount = ntohs(header->arcount);
+    unsigned char* ansp = (unsigned char*) (header + 1);
+    unsigned short rdlen, type, class;
+    unsigned char* ret = NULL;
 
-      if (header->opcode == QUERY)
-	{
-	  for (i = ntohs(header->qdcount); i != 0; i--)
-	    {
-	      if (!(ansp = skip_name(ansp, header, plen, 4)))
-		return NULL;
-	      
-	      GETSHORT(type, ansp); 
-	      GETSHORT(class, ansp);
-	      
-	      if (class == C_IN && type == T_TKEY)
-		*is_sign = 1;
-	    }
-	}
+    if (is_sign) {
+        *is_sign = 0;
+
+        if (header->opcode == QUERY) {
+            for (i = ntohs(header->qdcount); i != 0; i--) {
+                if (!(ansp = skip_name(ansp, header, plen, 4))) return NULL;
+
+                GETSHORT(type, ansp);
+                GETSHORT(class, ansp);
+
+                if (class == C_IN && type == T_TKEY) *is_sign = 1;
+            }
+        }
+    } else {
+        if (!(ansp = skip_questions(header, plen))) return NULL;
     }
-  else
-    {
-      if (!(ansp = skip_questions(header, plen)))
-	return NULL;
-    }
-    
-  if (arcount == 0)
-    return NULL;
-  
-  if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount), header, plen)))
-    return NULL; 
-  
-  for (i = 0; i < arcount; i++)
-    {
-      unsigned char *save, *start = ansp;
-      if (!(ansp = skip_name(ansp, header, plen, 10)))
-	return NULL; 
 
-      GETSHORT(type, ansp);
-      save = ansp;
-      GETSHORT(class, ansp);
-      ansp += 4; /* TTL */
-      GETSHORT(rdlen, ansp);
-      if (!ADD_RDLEN(header, ansp, plen, rdlen))
-	return NULL;
-      if (type == T_OPT)
-	{
-	  if (len)
-	    *len = ansp - start;
-	  if (p)
-	    *p = save;
-	  ret = start;
-	}
-      else if (is_sign && 
-	       i == arcount - 1 && 
-	       class == C_ANY && 
-	       (type == T_SIG || type == T_TSIG))
-	*is_sign = 1;
-    }
-  
-  return ret;
-}
-      
-  
-/* is addr in the non-globally-routed IP space? */ 
-static int private_net(struct in_addr addr) 
-{
-  in_addr_t ip_addr = ntohl(addr.s_addr);
+    if (arcount == 0) return NULL;
 
-  return
-    ((ip_addr & 0xFF000000) == 0x7F000000)  /* 127.0.0.0/8    (loopback) */ || 
-    ((ip_addr & 0xFFFF0000) == 0xC0A80000)  /* 192.168.0.0/16 (private)  */ ||
-    ((ip_addr & 0xFF000000) == 0x0A000000)  /* 10.0.0.0/8     (private)  */ ||
-    ((ip_addr & 0xFFF00000) == 0xAC100000)  /* 172.16.0.0/12  (private)  */ ||
-    ((ip_addr & 0xFFFF0000) == 0xA9FE0000)  /* 169.254.0.0/16 (zeroconf) */ ;
+    if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount), header, plen)))
+        return NULL;
+
+    for (i = 0; i < arcount; i++) {
+        unsigned char *save, *start = ansp;
+        if (!(ansp = skip_name(ansp, header, plen, 10))) return NULL;
+
+        GETSHORT(type, ansp);
+        save = ansp;
+        GETSHORT(class, ansp);
+        ansp += 4; /* TTL */
+        GETSHORT(rdlen, ansp);
+        if (!ADD_RDLEN(header, ansp, plen, rdlen)) return NULL;
+        if (type == T_OPT) {
+            if (len) *len = ansp - start;
+            if (p) *p = save;
+            ret = start;
+        } else if (is_sign && i == arcount - 1 && class == C_ANY &&
+                   (type == T_SIG || type == T_TSIG))
+            *is_sign = 1;
+    }
+
+    return ret;
 }
 
-static unsigned char *do_doctor(unsigned char *p, int count, HEADER *header, size_t qlen)
-{
-  int i, qtype, qclass, rdlen;
-  unsigned long ttl;
+/* is addr in the non-globally-routed IP space? */
+static int private_net(struct in_addr addr) {
+    in_addr_t ip_addr = ntohl(addr.s_addr);
 
-  for (i = count; i != 0; i--)
-    {
-      if (!(p = skip_name(p, header, qlen, 10)))
-	return 0; /* bad packet */
-      
-      GETSHORT(qtype, p); 
-      GETSHORT(qclass, p);
-      GETLONG(ttl, p);
-      GETSHORT(rdlen, p);
-      
-      if ((qclass == C_IN) && (qtype == T_A))
-	{
-	  struct doctor *doctor;
-	  struct in_addr addr;
-	  
-	  if (!CHECK_LEN(header, p, qlen, INADDRSZ))
-	    return 0;
-	   
-	   /* alignment */
-	  memcpy(&addr, p, INADDRSZ);
-	  
-	  for (doctor = daemon->doctors; doctor; doctor = doctor->next)
-	    {
-	      if (doctor->end.s_addr == 0)
-		{
-		  if (!is_same_net(doctor->in, addr, doctor->mask))
-		    continue;
-		}
-	      else if (ntohl(doctor->in.s_addr) > ntohl(addr.s_addr) || 
-		       ntohl(doctor->end.s_addr) < ntohl(addr.s_addr))
-		continue;
-	     
-	      addr.s_addr &= ~doctor->mask.s_addr;
-	      addr.s_addr |= (doctor->out.s_addr & doctor->mask.s_addr);
-	      /* Since we munged the data, the server it came from is no longer authoritative */
-	      header->aa = 0;
-	      memcpy(p, &addr, INADDRSZ);
-	      break;
-	    }
-	}
-      
-      if (!ADD_RDLEN(header, p, qlen, rdlen))
-	 return 0; /* bad packet */
-    }
-  
-  return p; 
+    return ((ip_addr & 0xFF000000) == 0x7F000000) /* 127.0.0.0/8    (loopback) */ ||
+           ((ip_addr & 0xFFFF0000) == 0xC0A80000) /* 192.168.0.0/16 (private)  */ ||
+           ((ip_addr & 0xFF000000) == 0x0A000000) /* 10.0.0.0/8     (private)  */ ||
+           ((ip_addr & 0xFFF00000) == 0xAC100000) /* 172.16.0.0/12  (private)  */ ||
+           ((ip_addr & 0xFFFF0000) == 0xA9FE0000) /* 169.254.0.0/16 (zeroconf) */;
 }
 
-static int find_soa(HEADER *header, size_t qlen)
-{
-  unsigned char *p;
-  int qtype, qclass, rdlen;
-  unsigned long ttl, minttl = ULONG_MAX;
-  int i, found_soa = 0;
-  
-  /* first move to NS section and find TTL from any SOA section */
-  if (!(p = skip_questions(header, qlen)) ||
-      !(p = do_doctor(p, ntohs(header->ancount), header, qlen)))
-    return 0;  /* bad packet */
-  
-  for (i = ntohs(header->nscount); i != 0; i--)
-    {
-      if (!(p = skip_name(p, header, qlen, 10)))
-	return 0; /* bad packet */
-      
-      GETSHORT(qtype, p); 
-      GETSHORT(qclass, p);
-      GETLONG(ttl, p);
-      GETSHORT(rdlen, p);
-      
-      if ((qclass == C_IN) && (qtype == T_SOA))
-	{
-	  found_soa = 1;
-	  if (ttl < minttl)
-	    minttl = ttl;
+static unsigned char* do_doctor(unsigned char* p, int count, HEADER* header, size_t qlen) {
+    int i, qtype, qclass, rdlen;
+    unsigned long ttl;
 
-	  /* MNAME */
-	  if (!(p = skip_name(p, header, qlen, 0)))
-	    return 0;
-	  /* RNAME */
-	  if (!(p = skip_name(p, header, qlen, 20)))
-	    return 0;
-	  p += 16; /* SERIAL REFRESH RETRY EXPIRE */
-	  
-	  GETLONG(ttl, p); /* minTTL */
-	  if (ttl < minttl)
-	    minttl = ttl;
-	}
-      else if (!ADD_RDLEN(header, p, qlen, rdlen))
-	return 0; /* bad packet */
+    for (i = count; i != 0; i--) {
+        if (!(p = skip_name(p, header, qlen, 10))) return 0; /* bad packet */
+
+        GETSHORT(qtype, p);
+        GETSHORT(qclass, p);
+        GETLONG(ttl, p);
+        GETSHORT(rdlen, p);
+
+        if ((qclass == C_IN) && (qtype == T_A)) {
+            struct doctor* doctor;
+            struct in_addr addr;
+
+            if (!CHECK_LEN(header, p, qlen, INADDRSZ)) return 0;
+
+            /* alignment */
+            memcpy(&addr, p, INADDRSZ);
+
+            for (doctor = daemon->doctors; doctor; doctor = doctor->next) {
+                if (doctor->end.s_addr == 0) {
+                    if (!is_same_net(doctor->in, addr, doctor->mask)) continue;
+                } else if (ntohl(doctor->in.s_addr) > ntohl(addr.s_addr) ||
+                           ntohl(doctor->end.s_addr) < ntohl(addr.s_addr))
+                    continue;
+
+                addr.s_addr &= ~doctor->mask.s_addr;
+                addr.s_addr |= (doctor->out.s_addr & doctor->mask.s_addr);
+                /* Since we munged the data, the server it came from is no longer authoritative */
+                header->aa = 0;
+                memcpy(p, &addr, INADDRSZ);
+                break;
+            }
+        }
+
+        if (!ADD_RDLEN(header, p, qlen, rdlen)) return 0; /* bad packet */
     }
-  
-  /* rewrite addresses in additioal section too */
-  if (!do_doctor(p, ntohs(header->arcount), header, qlen))
-    return 0;
-  
-  if (!found_soa)
-    minttl = daemon->neg_ttl;
 
-  return minttl;
+    return p;
+}
+
+static int find_soa(HEADER* header, size_t qlen) {
+    unsigned char* p;
+    int qtype, qclass, rdlen;
+    unsigned long ttl, minttl = ULONG_MAX;
+    int i, found_soa = 0;
+
+    /* first move to NS section and find TTL from any SOA section */
+    if (!(p = skip_questions(header, qlen)) ||
+        !(p = do_doctor(p, ntohs(header->ancount), header, qlen)))
+        return 0; /* bad packet */
+
+    for (i = ntohs(header->nscount); i != 0; i--) {
+        if (!(p = skip_name(p, header, qlen, 10))) return 0; /* bad packet */
+
+        GETSHORT(qtype, p);
+        GETSHORT(qclass, p);
+        GETLONG(ttl, p);
+        GETSHORT(rdlen, p);
+
+        if ((qclass == C_IN) && (qtype == T_SOA)) {
+            found_soa = 1;
+            if (ttl < minttl) minttl = ttl;
+
+            /* MNAME */
+            if (!(p = skip_name(p, header, qlen, 0))) return 0;
+            /* RNAME */
+            if (!(p = skip_name(p, header, qlen, 20))) return 0;
+            p += 16; /* SERIAL REFRESH RETRY EXPIRE */
+
+            GETLONG(ttl, p); /* minTTL */
+            if (ttl < minttl) minttl = ttl;
+        } else if (!ADD_RDLEN(header, p, qlen, rdlen))
+            return 0; /* bad packet */
+    }
+
+    /* rewrite addresses in additioal section too */
+    if (!do_doctor(p, ntohs(header->arcount), header, qlen)) return 0;
+
+    if (!found_soa) minttl = daemon->neg_ttl;
+
+    return minttl;
 }
 
 /* Note that the following code can create CNAME chains that don't point to a real record,
-   either because of lack of memory, or lack of SOA records.  These are treated by the cache code as 
-   expired and cleaned out that way. 
+   either because of lack of memory, or lack of SOA records.  These are treated by the cache code as
+   expired and cleaned out that way.
    Return 1 if we reject an address because it look like parct of dns-rebinding attack. */
-int extract_addresses(HEADER *header, size_t qlen, char *name, time_t now)
-{
-  unsigned char *p, *p1, *endrr, *namep;
-  int i, j, qtype, qclass, aqtype, aqclass, ardlen, res, searched_soa = 0;
-  unsigned long ttl = 0;
-  struct all_addr addr;
+int extract_addresses(HEADER* header, size_t qlen, char* name, time_t now) {
+    unsigned char *p, *p1, *endrr, *namep;
+    int i, j, qtype, qclass, aqtype, aqclass, ardlen, res, searched_soa = 0;
+    unsigned long ttl = 0;
+    struct all_addr addr;
 
-  cache_start_insert();
+    cache_start_insert();
 
-  /* find_soa is needed for dns_doctor side-effects, so don't call it lazily if there are any. */
-  if (daemon->doctors)
-    {
-      searched_soa = 1;
-      ttl = find_soa(header, qlen);
+    /* find_soa is needed for dns_doctor side-effects, so don't call it lazily if there are any. */
+    if (daemon->doctors) {
+        searched_soa = 1;
+        ttl = find_soa(header, qlen);
     }
-  
-  /* go through the questions. */
-  p = (unsigned char *)(header+1);
-  
-  for (i = ntohs(header->qdcount); i != 0; i--)
-    {
-      int found = 0, cname_count = 5;
-      struct crec *cpp = NULL;
-      int flags = header->rcode == NXDOMAIN ? F_NXDOMAIN : 0;
-      unsigned long cttl = ULONG_MAX, attl;
-      
-      namep = p;
-      if (!extract_name(header, qlen, &p, name, 1, 4))
-	return 0; /* bad packet */
-           
-      GETSHORT(qtype, p); 
-      GETSHORT(qclass, p);
-      
-      if (qclass != C_IN)
-	continue;
 
-      /* PTRs: we chase CNAMEs here, since we have no way to 
-	 represent them in the cache. */
-      if (qtype == T_PTR)
-	{ 
-	  int name_encoding = in_arpa_name_2_addr(name, &addr);
-	  
-	  if (!name_encoding)
-	    continue;
+    /* go through the questions. */
+    p = (unsigned char*) (header + 1);
 
-	  if (!(flags & F_NXDOMAIN))
-	    {
-	    cname_loop:
-	      if (!(p1 = skip_questions(header, qlen)))
-		return 0;
-	      
-	      for (j = ntohs(header->ancount); j != 0; j--) 
-		{
-		  unsigned char *tmp = namep;
-		  /* the loop body overwrites the original name, so get it back here. */
-		  if (!extract_name(header, qlen, &tmp, name, 1, 0) ||
-		      !(res = extract_name(header, qlen, &p1, name, 0, 10)))
-		    return 0; /* bad packet */
-		  
-		  GETSHORT(aqtype, p1); 
-		  GETSHORT(aqclass, p1);
-		  GETLONG(attl, p1);
-		  GETSHORT(ardlen, p1);
-		  endrr = p1+ardlen;
-		  
-		  /* TTL of record is minimum of CNAMES and PTR */
-		  if (attl < cttl)
-		    cttl = attl;
+    for (i = ntohs(header->qdcount); i != 0; i--) {
+        int found = 0, cname_count = 5;
+        struct crec* cpp = NULL;
+        int flags = header->rcode == NXDOMAIN ? F_NXDOMAIN : 0;
+        unsigned long cttl = ULONG_MAX, attl;
 
-		  if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == T_PTR))
-		    {
-		      if (!extract_name(header, qlen, &p1, name, 1, 0))
-			return 0;
-		      
-		      if (aqtype == T_CNAME)
-			{
-			  if (!cname_count--)
-			    return 0; /* looped CNAMES */
-			  goto cname_loop;
-			}
-		      
-		      cache_insert(name, &addr, now, cttl, name_encoding | F_REVERSE);
-		      found = 1; 
-		    }
-		  
-		  p1 = endrr;
-		  if (!CHECK_LEN(header, p1, qlen, 0))
-		    return 0; /* bad packet */
-		}
-	    }
-	  
-	   if (!found && !(daemon->options & OPT_NO_NEG))
-	    {
-	      if (!searched_soa)
-		{
-		  searched_soa = 1;
-		  ttl = find_soa(header, qlen);
-		}
-	      if (ttl)
-		cache_insert(NULL, &addr, now, ttl, name_encoding | F_REVERSE | F_NEG | flags);	
-	    }
-	}
-      else
-	{
-	  /* everything other than PTR */
-	  struct crec *newc;
-	  int addrlen;
+        namep = p;
+        if (!extract_name(header, qlen, &p, name, 1, 4)) return 0; /* bad packet */
 
-	  if (qtype == T_A)
-	    {
-	      addrlen = INADDRSZ;
-	      flags |= F_IPV4;
-	    }
+        GETSHORT(qtype, p);
+        GETSHORT(qclass, p);
+
+        if (qclass != C_IN) continue;
+
+        /* PTRs: we chase CNAMEs here, since we have no way to
+       represent them in the cache. */
+        if (qtype == T_PTR) {
+            int name_encoding = in_arpa_name_2_addr(name, &addr);
+
+            if (!name_encoding) continue;
+
+            if (!(flags & F_NXDOMAIN)) {
+            cname_loop:
+                if (!(p1 = skip_questions(header, qlen))) return 0;
+
+                for (j = ntohs(header->ancount); j != 0; j--) {
+                    unsigned char* tmp = namep;
+                    /* the loop body overwrites the original name, so get it back here. */
+                    if (!extract_name(header, qlen, &tmp, name, 1, 0) ||
+                        !(res = extract_name(header, qlen, &p1, name, 0, 10)))
+                        return 0; /* bad packet */
+
+                    GETSHORT(aqtype, p1);
+                    GETSHORT(aqclass, p1);
+                    GETLONG(attl, p1);
+                    GETSHORT(ardlen, p1);
+                    endrr = p1 + ardlen;
+
+                    /* TTL of record is minimum of CNAMES and PTR */
+                    if (attl < cttl) cttl = attl;
+
+                    if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == T_PTR)) {
+                        if (!extract_name(header, qlen, &p1, name, 1, 0)) return 0;
+
+                        if (aqtype == T_CNAME) {
+                            if (!cname_count--) return 0; /* looped CNAMES */
+                            goto cname_loop;
+                        }
+
+                        cache_insert(name, &addr, now, cttl, name_encoding | F_REVERSE);
+                        found = 1;
+                    }
+
+                    p1 = endrr;
+                    if (!CHECK_LEN(header, p1, qlen, 0)) return 0; /* bad packet */
+                }
+            }
+
+            if (!found && !(daemon->options & OPT_NO_NEG)) {
+                if (!searched_soa) {
+                    searched_soa = 1;
+                    ttl = find_soa(header, qlen);
+                }
+                if (ttl)
+                    cache_insert(NULL, &addr, now, ttl, name_encoding | F_REVERSE | F_NEG | flags);
+            }
+        } else {
+            /* everything other than PTR */
+            struct crec* newc;
+            int addrlen;
+
+            if (qtype == T_A) {
+                addrlen = INADDRSZ;
+                flags |= F_IPV4;
+            }
 #ifdef HAVE_IPV6
-	  else if (qtype == T_AAAA)
-	    {
-	      addrlen = IN6ADDRSZ;
-	      flags |= F_IPV6;
-	    }
+            else if (qtype == T_AAAA) {
+                addrlen = IN6ADDRSZ;
+                flags |= F_IPV6;
+            }
 #endif
-	  else 
-	    continue;
-	    
-	  if (!(flags & F_NXDOMAIN))
-	    {
-	    cname_loop1:
-	      if (!(p1 = skip_questions(header, qlen)))
-		return 0;
-	      
-	      for (j = ntohs(header->ancount); j != 0; j--) 
-		{
-		  if (!(res = extract_name(header, qlen, &p1, name, 0, 10)))
-		    return 0; /* bad packet */
-		  
-		  GETSHORT(aqtype, p1); 
-		  GETSHORT(aqclass, p1);
-		  GETLONG(attl, p1);
-		  GETSHORT(ardlen, p1);
-		  endrr = p1+ardlen;
-		  
-		  if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == qtype))
-		    {
-		      if (aqtype == T_CNAME)
-			{
-			  if (!cname_count--)
-			    return 0; /* looped CNAMES */
-			  newc = cache_insert(name, NULL, now, attl, F_CNAME | F_FORWARD);
-			  if (newc && cpp)
-			    {
-			      cpp->addr.cname.cache = newc;
-			      cpp->addr.cname.uid = newc->uid;
-			    }
+            else
+                continue;
 
-			  cpp = newc;
-			  if (attl < cttl)
-			    cttl = attl;
-			  
-			  if (!extract_name(header, qlen, &p1, name, 1, 0))
-			    return 0;
-			  goto cname_loop1;
-			}
-		      else
-			{
-			  found = 1;
-			  
-			  /* copy address into aligned storage */
-			  if (!CHECK_LEN(header, p1, qlen, addrlen))
-			    return 0; /* bad packet */
-			  memcpy(&addr, p1, addrlen);
-			  
-			  /* check for returned address in private space */
-			  if ((daemon->options & OPT_NO_REBIND) &&
-			      (flags & F_IPV4) &&
-			      private_net(addr.addr.addr4))
-			    return 1;
-			  
-			  newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD);
-			  if (newc && cpp)
-			    {
-			      cpp->addr.cname.cache = newc;
-			      cpp->addr.cname.uid = newc->uid;
-			    }
-			  cpp = NULL;
-			}
-		    }
-		  
-		  p1 = endrr;
-		  if (!CHECK_LEN(header, p1, qlen, 0))
-		    return 0; /* bad packet */
-		}
-	    }
-	  
-	  if (!found && !(daemon->options & OPT_NO_NEG))
-	    {
-	      if (!searched_soa)
-		{
-		  searched_soa = 1;
-		  ttl = find_soa(header, qlen);
-		}
-	      /* If there's no SOA to get the TTL from, but there is a CNAME 
-		 pointing at this, inherit its TTL */
-	      if (ttl || cpp)
-		{
-		  newc = cache_insert(name, NULL, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags);	
-		  if (newc && cpp)
-		    {
-		      cpp->addr.cname.cache = newc;
-		      cpp->addr.cname.uid = newc->uid;
-		    }
-		}
-	    }
-	}
+            if (!(flags & F_NXDOMAIN)) {
+            cname_loop1:
+                if (!(p1 = skip_questions(header, qlen))) return 0;
+
+                for (j = ntohs(header->ancount); j != 0; j--) {
+                    if (!(res = extract_name(header, qlen, &p1, name, 0, 10)))
+                        return 0; /* bad packet */
+
+                    GETSHORT(aqtype, p1);
+                    GETSHORT(aqclass, p1);
+                    GETLONG(attl, p1);
+                    GETSHORT(ardlen, p1);
+                    endrr = p1 + ardlen;
+
+                    if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == qtype)) {
+                        if (aqtype == T_CNAME) {
+                            if (!cname_count--) return 0; /* looped CNAMES */
+                            newc = cache_insert(name, NULL, now, attl, F_CNAME | F_FORWARD);
+                            if (newc && cpp) {
+                                cpp->addr.cname.cache = newc;
+                                cpp->addr.cname.uid = newc->uid;
+                            }
+
+                            cpp = newc;
+                            if (attl < cttl) cttl = attl;
+
+                            if (!extract_name(header, qlen, &p1, name, 1, 0)) return 0;
+                            goto cname_loop1;
+                        } else {
+                            found = 1;
+
+                            /* copy address into aligned storage */
+                            if (!CHECK_LEN(header, p1, qlen, addrlen)) return 0; /* bad packet */
+                            memcpy(&addr, p1, addrlen);
+
+                            /* check for returned address in private space */
+                            if ((daemon->options & OPT_NO_REBIND) && (flags & F_IPV4) &&
+                                private_net(addr.addr.addr4))
+                                return 1;
+
+                            newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD);
+                            if (newc && cpp) {
+                                cpp->addr.cname.cache = newc;
+                                cpp->addr.cname.uid = newc->uid;
+                            }
+                            cpp = NULL;
+                        }
+                    }
+
+                    p1 = endrr;
+                    if (!CHECK_LEN(header, p1, qlen, 0)) return 0; /* bad packet */
+                }
+            }
+
+            if (!found && !(daemon->options & OPT_NO_NEG)) {
+                if (!searched_soa) {
+                    searched_soa = 1;
+                    ttl = find_soa(header, qlen);
+                }
+                /* If there's no SOA to get the TTL from, but there is a CNAME
+               pointing at this, inherit its TTL */
+                if (ttl || cpp) {
+                    newc =
+                        cache_insert(name, NULL, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags);
+                    if (newc && cpp) {
+                        cpp->addr.cname.cache = newc;
+                        cpp->addr.cname.uid = newc->uid;
+                    }
+                }
+            }
+        }
     }
-  
-  /* Don't put stuff from a truncated packet into the cache, but do everything else */
-  if (!header->tc)
-    cache_end_insert();
 
-  return 0;
+    /* Don't put stuff from a truncated packet into the cache, but do everything else */
+    if (!header->tc) cache_end_insert();
+
+    return 0;
 }
 
 /* If the packet holds exactly one query
-   return F_IPV4 or F_IPV6  and leave the name from the query in name. 
+   return F_IPV4 or F_IPV6  and leave the name from the query in name.
    Abuse F_BIGNAME to indicate an NS query - yuck. */
 
-unsigned short extract_request(HEADER *header, size_t qlen, char *name, unsigned short *typep)
-{
-  unsigned char *p = (unsigned char *)(header+1);
-  int qtype, qclass;
+unsigned short extract_request(HEADER* header, size_t qlen, char* name, unsigned short* typep) {
+    unsigned char* p = (unsigned char*) (header + 1);
+    int qtype, qclass;
 
-  if (typep)
-    *typep = 0;
+    if (typep) *typep = 0;
 
-  if (ntohs(header->qdcount) != 1 || header->opcode != QUERY)
-    return 0; /* must be exactly one query. */
-  
-  if (!extract_name(header, qlen, &p, name, 1, 4))
-    return 0; /* bad packet */
-   
-  GETSHORT(qtype, p); 
-  GETSHORT(qclass, p);
+    if (ntohs(header->qdcount) != 1 || header->opcode != QUERY)
+        return 0; /* must be exactly one query. */
 
-  if (typep)
-    *typep = qtype;
+    if (!extract_name(header, qlen, &p, name, 1, 4)) return 0; /* bad packet */
 
-  if (qclass == C_IN)
-    {
-      if (qtype == T_A)
-	return F_IPV4;
-      if (qtype == T_AAAA)
-	return F_IPV6;
-      if (qtype == T_ANY)
-	return  F_IPV4 | F_IPV6;
-      if (qtype == T_NS || qtype == T_SOA)
-	return F_QUERY | F_BIGNAME;
+    GETSHORT(qtype, p);
+    GETSHORT(qclass, p);
+
+    if (typep) *typep = qtype;
+
+    if (qclass == C_IN) {
+        if (qtype == T_A) return F_IPV4;
+        if (qtype == T_AAAA) return F_IPV6;
+        if (qtype == T_ANY) return F_IPV4 | F_IPV6;
+        if (qtype == T_NS || qtype == T_SOA) return F_QUERY | F_BIGNAME;
     }
-  
-  return F_QUERY;
+
+    return F_QUERY;
 }
 
+size_t setup_reply(HEADER* header, size_t qlen, struct all_addr* addrp, unsigned short flags,
+                   unsigned long ttl) {
+    unsigned char* p;
 
-size_t setup_reply(HEADER *header, size_t qlen,
-		struct all_addr *addrp, unsigned short flags, unsigned long ttl)
-{
-  unsigned char *p;
+    if (!(p = skip_questions(header, qlen))) return 0;
 
-  if (!(p = skip_questions(header, qlen)))
-    return 0;
-
-  header->qr = 1; /* response */
-  header->aa = 0; /* authoritive */
-  header->ra = 1; /* recursion if available */
-  header->tc = 0; /* not truncated */
-  header->nscount = htons(0);
-  header->arcount = htons(0);
-  header->ancount = htons(0); /* no answers unless changed below */
-  if (flags == F_NEG)
-    header->rcode = SERVFAIL; /* couldn't get memory */
-  else if (flags == F_NOERR)
-    header->rcode = NOERROR; /* empty domain */
-  else if (flags == F_NXDOMAIN)
-    header->rcode = NXDOMAIN;
-  else if (flags == F_IPV4)
-    { /* we know the address */
-      header->rcode = NOERROR;
-      header->ancount = htons(1);
-      header->aa = 1;
-      add_resource_record(header, NULL, NULL, sizeof(HEADER), &p, ttl, NULL, T_A, C_IN, "4", addrp);
+    header->qr = 1; /* response */
+    header->aa = 0; /* authoritive */
+    header->ra = 1; /* recursion if available */
+    header->tc = 0; /* not truncated */
+    header->nscount = htons(0);
+    header->arcount = htons(0);
+    header->ancount = htons(0); /* no answers unless changed below */
+    if (flags == F_NEG)
+        header->rcode = SERVFAIL; /* couldn't get memory */
+    else if (flags == F_NOERR)
+        header->rcode = NOERROR; /* empty domain */
+    else if (flags == F_NXDOMAIN)
+        header->rcode = NXDOMAIN;
+    else if (flags == F_IPV4) { /* we know the address */
+        header->rcode = NOERROR;
+        header->ancount = htons(1);
+        header->aa = 1;
+        add_resource_record(header, NULL, NULL, sizeof(HEADER), &p, ttl, NULL, T_A, C_IN, "4",
+                            addrp);
     }
 #ifdef HAVE_IPV6
-  else if (flags == F_IPV6)
-    {
-      header->rcode = NOERROR;
-      header->ancount = htons(1);
-      header->aa = 1;
-      add_resource_record(header, NULL, NULL, sizeof(HEADER), &p, ttl, NULL, T_AAAA, C_IN, "6", addrp);
+    else if (flags == F_IPV6) {
+        header->rcode = NOERROR;
+        header->ancount = htons(1);
+        header->aa = 1;
+        add_resource_record(header, NULL, NULL, sizeof(HEADER), &p, ttl, NULL, T_AAAA, C_IN, "6",
+                            addrp);
     }
 #endif
-  else /* nowhere to forward to */
-    header->rcode = REFUSED;
- 
-  return p - (unsigned char *)header;
+    else /* nowhere to forward to */
+        header->rcode = REFUSED;
+
+    return p - (unsigned char*) header;
 }
 
 /* check if name matches local names ie from /etc/hosts or DHCP or local mx names. */
-int check_for_local_domain(char *name, time_t now)
-{
-  struct crec *crecp;
-  struct mx_srv_record *mx;
-  struct txt_record *txt;
-  struct interface_name *intr;
-  struct ptr_record *ptr;
-  
-  if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6)) &&
-      (crecp->flags & (F_HOSTS | F_DHCP)))
-    return 1;
-  
-  for (mx = daemon->mxnames; mx; mx = mx->next)
-    if (hostname_isequal(name, mx->name))
-      return 1;
+int check_for_local_domain(char* name, time_t now) {
+    struct crec* crecp;
+    struct mx_srv_record* mx;
+    struct txt_record* txt;
+    struct interface_name* intr;
+    struct ptr_record* ptr;
 
-  for (txt = daemon->txt; txt; txt = txt->next)
-    if (hostname_isequal(name, txt->name))
-      return 1;
+    if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6)) &&
+        (crecp->flags & (F_HOSTS | F_DHCP)))
+        return 1;
 
-  for (intr = daemon->int_names; intr; intr = intr->next)
-    if (hostname_isequal(name, intr->name))
-      return 1;
+    for (mx = daemon->mxnames; mx; mx = mx->next)
+        if (hostname_isequal(name, mx->name)) return 1;
 
-  for (ptr = daemon->ptr; ptr; ptr = ptr->next)
-    if (hostname_isequal(name, ptr->name))
-      return 1;
- 
-  return 0;
+    for (txt = daemon->txt; txt; txt = txt->next)
+        if (hostname_isequal(name, txt->name)) return 1;
+
+    for (intr = daemon->int_names; intr; intr = intr->next)
+        if (hostname_isequal(name, intr->name)) return 1;
+
+    for (ptr = daemon->ptr; ptr; ptr = ptr->next)
+        if (hostname_isequal(name, ptr->name)) return 1;
+
+    return 0;
 }
 
 /* Is the packet a reply with the answer address equal to addr?
    If so mung is into an NXDOMAIN reply and also put that information
    in the cache. */
-int check_for_bogus_wildcard(HEADER *header, size_t qlen, char *name, 
-			     struct bogus_addr *baddr, time_t now)
-{
-  unsigned char *p;
-  int i, qtype, qclass, rdlen;
-  unsigned long ttl;
-  struct bogus_addr *baddrp;
+int check_for_bogus_wildcard(HEADER* header, size_t qlen, char* name, struct bogus_addr* baddr,
+                             time_t now) {
+    unsigned char* p;
+    int i, qtype, qclass, rdlen;
+    unsigned long ttl;
+    struct bogus_addr* baddrp;
 
-  /* skip over questions */
-  if (!(p = skip_questions(header, qlen)))
-    return 0; /* bad packet */
+    /* skip over questions */
+    if (!(p = skip_questions(header, qlen))) return 0; /* bad packet */
 
-  for (i = ntohs(header->ancount); i != 0; i--)
-    {
-      if (!extract_name(header, qlen, &p, name, 1, 10))
-	return 0; /* bad packet */
-  
-      GETSHORT(qtype, p); 
-      GETSHORT(qclass, p);
-      GETLONG(ttl, p);
-      GETSHORT(rdlen, p);
-      
-      if (qclass == C_IN && qtype == T_A)
-	{
-	  if (!CHECK_LEN(header, p, qlen, INADDRSZ))
-	    return 0;
-	  
-	  for (baddrp = baddr; baddrp; baddrp = baddrp->next)
-	    if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
-	      {
-		/* Found a bogus address. Insert that info here, since there no SOA record
-		   to get the ttl from in the normal processing */
-		cache_start_insert();
-		cache_insert(name, NULL, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN | F_CONFIG);
-		cache_end_insert();
-		
-		return 1;
-	      }
-	}
-      
-      if (!ADD_RDLEN(header, p, qlen, rdlen))
-	return 0;
+    for (i = ntohs(header->ancount); i != 0; i--) {
+        if (!extract_name(header, qlen, &p, name, 1, 10)) return 0; /* bad packet */
+
+        GETSHORT(qtype, p);
+        GETSHORT(qclass, p);
+        GETLONG(ttl, p);
+        GETSHORT(rdlen, p);
+
+        if (qclass == C_IN && qtype == T_A) {
+            if (!CHECK_LEN(header, p, qlen, INADDRSZ)) return 0;
+
+            for (baddrp = baddr; baddrp; baddrp = baddrp->next)
+                if (memcmp(&baddrp->addr, p, INADDRSZ) == 0) {
+                    /* Found a bogus address. Insert that info here, since there no SOA record
+                       to get the ttl from in the normal processing */
+                    cache_start_insert();
+                    cache_insert(name, NULL, now, ttl,
+                                 F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN | F_CONFIG);
+                    cache_end_insert();
+
+                    return 1;
+                }
+        }
+
+        if (!ADD_RDLEN(header, p, qlen, rdlen)) return 0;
     }
-  
-  return 0;
-}
 
-static int add_resource_record(HEADER *header, char *limit, int *truncp, unsigned int nameoffset, unsigned char **pp, 
-			       unsigned long ttl, unsigned int *offset, unsigned short type, unsigned short class, char *format, ...)
-{
-  va_list ap;
-  unsigned char *sav, *p = *pp;
-  int j;
-  unsigned short usval;
-  long lval;
-  char *sval;
-
-  if (truncp && *truncp)
     return 0;
+}
 
-  PUTSHORT(nameoffset | 0xc000, p);
-  PUTSHORT(type, p);
-  PUTSHORT(class, p);
-  PUTLONG(ttl, p);      /* TTL */
+static int add_resource_record(HEADER* header, char* limit, int* truncp, unsigned int nameoffset,
+                               unsigned char** pp, unsigned long ttl, unsigned int* offset,
+                               unsigned short type, unsigned short class, char* format, ...) {
+    va_list ap;
+    unsigned char *sav, *p = *pp;
+    int j;
+    unsigned short usval;
+    long lval;
+    char* sval;
 
-  sav = p;              /* Save pointer to RDLength field */
-  PUTSHORT(0, p);       /* Placeholder RDLength */
+    if (truncp && *truncp) return 0;
 
-  va_start(ap, format);   /* make ap point to 1st unamed argument */
-  
-  for (; *format; format++)
-    switch (*format)
-      {
+    PUTSHORT(nameoffset | 0xc000, p);
+    PUTSHORT(type, p);
+    PUTSHORT(class, p);
+    PUTLONG(ttl, p); /* TTL */
+
+    sav = p;        /* Save pointer to RDLength field */
+    PUTSHORT(0, p); /* Placeholder RDLength */
+
+    va_start(ap, format); /* make ap point to 1st unamed argument */
+
+    for (; *format; format++) switch (*format) {
 #ifdef HAVE_IPV6
-      case '6':
-	sval = va_arg(ap, char *); 
-	memcpy(p, sval, IN6ADDRSZ);
-	p += IN6ADDRSZ;
-	break;
+            case '6':
+                sval = va_arg(ap, char*);
+                memcpy(p, sval, IN6ADDRSZ);
+                p += IN6ADDRSZ;
+                break;
 #endif
-	
-      case '4':
-	sval = va_arg(ap, char *); 
-	memcpy(p, sval, INADDRSZ);
-	p += INADDRSZ;
-	break;
-	
-      case 's':
-	usval = va_arg(ap, int);
-	PUTSHORT(usval, p);
-	break;
-	
-      case 'l':
-	lval = va_arg(ap, long);
-	PUTLONG(lval, p);
-	break;
-	
-      case 'd':
-	/* get domain-name answer arg and store it in RDATA field */
-	if (offset)
-	  *offset = p - (unsigned char *)header;
-	p = do_rfc1035_name(p, va_arg(ap, char *));
-	*p++ = 0;
-	break;
-	
-      case 't':
-	usval = va_arg(ap, int);
-	sval = va_arg(ap, char *);
-	memcpy(p, sval, usval);
-	p += usval;
-	break;
 
-      case 'z':
-	sval = va_arg(ap, char *);
-	usval = sval ? strlen(sval) : 0;
-	if (usval > 255)
-	  usval = 255;
-	*p++ = (unsigned char)usval;
-	memcpy(p, sval, usval);
-	p += usval;
-	break;
-      }
+            case '4':
+                sval = va_arg(ap, char*);
+                memcpy(p, sval, INADDRSZ);
+                p += INADDRSZ;
+                break;
 
-  va_end(ap);	/* clean up variable argument pointer */
-  
-  j = p - sav - 2;
-  PUTSHORT(j, sav);     /* Now, store real RDLength */
-  
-  /* check for overflow of buffer */
-  if (limit && ((unsigned char *)limit - p) < 0)
-    {
-      if (truncp)
-	*truncp = 1;
-      return 0;
+            case 's':
+                usval = va_arg(ap, int);
+                PUTSHORT(usval, p);
+                break;
+
+            case 'l':
+                lval = va_arg(ap, long);
+                PUTLONG(lval, p);
+                break;
+
+            case 'd':
+                /* get domain-name answer arg and store it in RDATA field */
+                if (offset) *offset = p - (unsigned char*) header;
+                p = do_rfc1035_name(p, va_arg(ap, char*));
+                *p++ = 0;
+                break;
+
+            case 't':
+                usval = va_arg(ap, int);
+                sval = va_arg(ap, char*);
+                memcpy(p, sval, usval);
+                p += usval;
+                break;
+
+            case 'z':
+                sval = va_arg(ap, char*);
+                usval = sval ? strlen(sval) : 0;
+                if (usval > 255) usval = 255;
+                *p++ = (unsigned char) usval;
+                memcpy(p, sval, usval);
+                p += usval;
+                break;
+        }
+
+    va_end(ap); /* clean up variable argument pointer */
+
+    j = p - sav - 2;
+    PUTSHORT(j, sav); /* Now, store real RDLength */
+
+    /* check for overflow of buffer */
+    if (limit && ((unsigned char*) limit - p) < 0) {
+        if (truncp) *truncp = 1;
+        return 0;
     }
-  
-  *pp = p;
-  return 1;
+
+    *pp = p;
+    return 1;
 }
 
-static unsigned long crec_ttl(struct crec *crecp, time_t now)
-{
-  /* Return 0 ttl for DHCP entries, which might change
-     before the lease expires. */
+static unsigned long crec_ttl(struct crec* crecp, time_t now) {
+    /* Return 0 ttl for DHCP entries, which might change
+       before the lease expires. */
 
-  if  (crecp->flags & (F_IMMORTAL | F_DHCP))
-    return daemon->local_ttl;
-  
-  return crecp->ttd - now;
+    if (crecp->flags & (F_IMMORTAL | F_DHCP)) return daemon->local_ttl;
+
+    return crecp->ttd - now;
 }
-  
 
 /* return zero if we can't answer from cache, or packet size if we can */
-size_t answer_request(HEADER *header, char *limit, size_t qlen,  
-		      struct in_addr local_addr, struct in_addr local_netmask, time_t now) 
-{
-  char *name = daemon->namebuff;
-  unsigned char *p, *ansp, *pheader;
-  int qtype, qclass;
-  struct all_addr addr;
-  unsigned int nameoffset;
-  unsigned short flag;
-  int q, ans, anscount = 0, addncount = 0;
-  int dryrun = 0, sec_reqd = 0;
-  int is_sign;
-  struct crec *crecp;
-  int nxdomain = 0, auth = 1, trunc = 0;
-  struct mx_srv_record *rec;
+size_t answer_request(HEADER* header, char* limit, size_t qlen, struct in_addr local_addr,
+                      struct in_addr local_netmask, time_t now) {
+    char* name = daemon->namebuff;
+    unsigned char *p, *ansp, *pheader;
+    int qtype, qclass;
+    struct all_addr addr;
+    unsigned int nameoffset;
+    unsigned short flag;
+    int q, ans, anscount = 0, addncount = 0;
+    int dryrun = 0, sec_reqd = 0;
+    int is_sign;
+    struct crec* crecp;
+    int nxdomain = 0, auth = 1, trunc = 0;
+    struct mx_srv_record* rec;
 
-  // Make sure we do not underflow here too.
-  if (qlen > (size_t)(limit - ((char *)header))) return 0;
- 
-  /* If there is an RFC2671 pseudoheader then it will be overwritten by
-     partial replies, so we have to do a dry run to see if we can answer
-     the query. We check to see if the do bit is set, if so we always
-     forward rather than answering from the cache, which doesn't include
-     security information. */
+    // Make sure we do not underflow here too.
+    if (qlen > (size_t)(limit - ((char*) header))) return 0;
 
-  if (find_pseudoheader(header, qlen, NULL, &pheader, &is_sign))
-    { 
-      unsigned short udpsz, ext_rcode, flags;
-      unsigned char *psave = pheader;
+    /* If there is an RFC2671 pseudoheader then it will be overwritten by
+       partial replies, so we have to do a dry run to see if we can answer
+       the query. We check to see if the do bit is set, if so we always
+       forward rather than answering from the cache, which doesn't include
+       security information. */
 
-      GETSHORT(udpsz, pheader);
-      GETSHORT(ext_rcode, pheader);
-      GETSHORT(flags, pheader);
-      
-      sec_reqd = flags & 0x8000; /* do bit */ 
+    if (find_pseudoheader(header, qlen, NULL, &pheader, &is_sign)) {
+        unsigned short udpsz, ext_rcode, flags;
+        unsigned char* psave = pheader;
 
-      /* If our client is advertising a larger UDP packet size
-	 than we allow, trim it so that we don't get an overlarge
-	 response from upstream */
+        GETSHORT(udpsz, pheader);
+        GETSHORT(ext_rcode, pheader);
+        GETSHORT(flags, pheader);
 
-      if (!is_sign && (udpsz > daemon->edns_pktsz))
-	PUTSHORT(daemon->edns_pktsz, psave); 
+        sec_reqd = flags & 0x8000; /* do bit */
 
-      dryrun = 1;
+        /* If our client is advertising a larger UDP packet size
+       than we allow, trim it so that we don't get an overlarge
+       response from upstream */
+
+        if (!is_sign && (udpsz > daemon->edns_pktsz)) PUTSHORT(daemon->edns_pktsz, psave);
+
+        dryrun = 1;
     }
 
-  if (ntohs(header->qdcount) == 0 || header->opcode != QUERY )
-    return 0;
-  
-  for (rec = daemon->mxnames; rec; rec = rec->next)
-    rec->offset = 0;
-  
- rerun:
-  /* determine end of question section (we put answers there) */
-  if (!(ansp = skip_questions(header, qlen)))
-    return 0; /* bad packet */
-   
-  /* now process each question, answers go in RRs after the question */
-  p = (unsigned char *)(header+1);
+    if (ntohs(header->qdcount) == 0 || header->opcode != QUERY) return 0;
 
-  for (q = ntohs(header->qdcount); q != 0; q--)
-    {
-      /* save pointer to name for copying into answers */
-      nameoffset = p - (unsigned char *)header;
+    for (rec = daemon->mxnames; rec; rec = rec->next) rec->offset = 0;
 
-      /* now extract name as .-concatenated string into name */
-      if (!extract_name(header, qlen, &p, name, 1, 4))
-	return 0; /* bad packet */
-            
-      GETSHORT(qtype, p); 
-      GETSHORT(qclass, p);
+rerun:
+    /* determine end of question section (we put answers there) */
+    if (!(ansp = skip_questions(header, qlen))) return 0; /* bad packet */
 
-      ans = 0; /* have we answered this question */
-      
-      if (qtype == T_TXT || qtype == T_ANY)
-	{
-	  struct txt_record *t;
-	  for(t = daemon->txt; t ; t = t->next)
-	    {
-	      if (t->class == qclass && hostname_isequal(name, t->name))
-		{
-		  ans = 1;
-		  if (!dryrun)
-		    {
-		      log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<TXT>");
-		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
-					      daemon->local_ttl, NULL,
-					      T_TXT, t->class, "t", t->len, t->txt))
-			anscount++;
+    /* now process each question, answers go in RRs after the question */
+    p = (unsigned char*) (header + 1);
 
-		    }
-		}
-	    }
-	}
+    for (q = ntohs(header->qdcount); q != 0; q--) {
+        /* save pointer to name for copying into answers */
+        nameoffset = p - (unsigned char*) header;
 
-      if (qclass == C_IN)
-	{
-	  if (qtype == T_PTR || qtype == T_ANY)
-	    {
-	      /* see if it's w.z.y.z.in-addr.arpa format */
-	      int is_arpa = in_arpa_name_2_addr(name, &addr);
-	      struct ptr_record *ptr;
-	      struct interface_name* intr = NULL;
+        /* now extract name as .-concatenated string into name */
+        if (!extract_name(header, qlen, &p, name, 1, 4)) return 0; /* bad packet */
 
-	      for (ptr = daemon->ptr; ptr; ptr = ptr->next)
-		if (hostname_isequal(name, ptr->name))
-		  break;
+        GETSHORT(qtype, p);
+        GETSHORT(qclass, p);
 
-	      if (is_arpa == F_IPV4)
-		for (intr = daemon->int_names; intr; intr = intr->next)
-		  {
-		    if (addr.addr.addr4.s_addr == get_ifaddr(intr->intr).s_addr)
-		      break;
-		    else
-		      while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
-			intr = intr->next;
-		  }
-	      
-	      if (intr)
-		{
-		  ans = 1;
-		  if (!dryrun)
-		    {
-		      log_query(F_IPV4 | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
-		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
-					      daemon->local_ttl, NULL,
-					      T_PTR, C_IN, "d", intr->name))
-			anscount++;
-		    }
-		}
-	      else if (ptr)
-		{
-		  ans = 1;
-		  if (!dryrun)
-		    {
-		      log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<PTR>");
-		      for (ptr = daemon->ptr; ptr; ptr = ptr->next)
-			if (hostname_isequal(name, ptr->name) &&
-			    add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
-						daemon->local_ttl, NULL,
-						T_PTR, C_IN, "d", ptr->ptr))
-			  anscount++;
-			 
-		    }
-		}
-	      else if ((crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
-		do 
-		  { 
-		    /* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */
-		    if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
-		      continue;
-		    
-		    if (crecp->flags & F_NEG)
-		      {
-			ans = 1;
-			auth = 0;
-			if (crecp->flags & F_NXDOMAIN)
-			  nxdomain = 1;
-			if (!dryrun)
-			  log_query(crecp->flags & ~F_FORWARD, name, &addr, NULL);
-		      }
-		    else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd)
-		      {
-			ans = 1;
-			if (!(crecp->flags & (F_HOSTS | F_DHCP)))
-			  auth = 0;
-			if (!dryrun)
-			  {
-			    log_query(crecp->flags & ~F_FORWARD, cache_get_name(crecp), &addr, 
-				      record_source(crecp->uid));
-			    
-			    if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
-						    crec_ttl(crecp, now), NULL,
-						    T_PTR, C_IN, "d", cache_get_name(crecp)))
-			      anscount++;
-			  }
-		      }
-		  } while ((crecp = cache_find_by_addr(crecp, &addr, now, is_arpa)));
-	      else if (is_arpa == F_IPV4 && 
-		       (daemon->options & OPT_BOGUSPRIV) && 
-		       private_net(addr.addr.addr4))
-		{
-		  /* if not in cache, enabled and private IPV4 address, return NXDOMAIN */
-		  ans = 1;
-		  nxdomain = 1;
-		  if (!dryrun)
-		    log_query(F_CONFIG | F_REVERSE | F_IPV4 | F_NEG | F_NXDOMAIN, 
-			      name, &addr, NULL);
-		}
-	    }
-	    
-	  for (flag = F_IPV4; flag; flag = (flag == F_IPV4) ? F_IPV6 : 0)
-	    {
-	      unsigned short type = T_A;
-	      
-	      if (flag == F_IPV6)
+        ans = 0; /* have we answered this question */
+
+        if (qtype == T_TXT || qtype == T_ANY) {
+            struct txt_record* t;
+            for (t = daemon->txt; t; t = t->next) {
+                if (t->class == qclass && hostname_isequal(name, t->name)) {
+                    ans = 1;
+                    if (!dryrun) {
+                        log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<TXT>");
+                        if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+                                                daemon->local_ttl, NULL, T_TXT, t->class, "t",
+                                                t->len, t->txt))
+                            anscount++;
+                    }
+                }
+            }
+        }
+
+        if (qclass == C_IN) {
+            if (qtype == T_PTR || qtype == T_ANY) {
+                /* see if it's w.z.y.z.in-addr.arpa format */
+                int is_arpa = in_arpa_name_2_addr(name, &addr);
+                struct ptr_record* ptr;
+                struct interface_name* intr = NULL;
+
+                for (ptr = daemon->ptr; ptr; ptr = ptr->next)
+                    if (hostname_isequal(name, ptr->name)) break;
+
+                if (is_arpa == F_IPV4)
+                    for (intr = daemon->int_names; intr; intr = intr->next) {
+                        if (addr.addr.addr4.s_addr == get_ifaddr(intr->intr).s_addr)
+                            break;
+                        else
+                            while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
+                                intr = intr->next;
+                    }
+
+                if (intr) {
+                    ans = 1;
+                    if (!dryrun) {
+                        log_query(F_IPV4 | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
+                        if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+                                                daemon->local_ttl, NULL, T_PTR, C_IN, "d",
+                                                intr->name))
+                            anscount++;
+                    }
+                } else if (ptr) {
+                    ans = 1;
+                    if (!dryrun) {
+                        log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<PTR>");
+                        for (ptr = daemon->ptr; ptr; ptr = ptr->next)
+                            if (hostname_isequal(name, ptr->name) &&
+                                add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+                                                    daemon->local_ttl, NULL, T_PTR, C_IN, "d",
+                                                    ptr->ptr))
+                                anscount++;
+                    }
+                } else if ((crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
+                    do {
+                        /* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */
+                        if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP))) continue;
+
+                        if (crecp->flags & F_NEG) {
+                            ans = 1;
+                            auth = 0;
+                            if (crecp->flags & F_NXDOMAIN) nxdomain = 1;
+                            if (!dryrun) log_query(crecp->flags & ~F_FORWARD, name, &addr, NULL);
+                        } else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd) {
+                            ans = 1;
+                            if (!(crecp->flags & (F_HOSTS | F_DHCP))) auth = 0;
+                            if (!dryrun) {
+                                log_query(crecp->flags & ~F_FORWARD, cache_get_name(crecp), &addr,
+                                          record_source(crecp->uid));
+
+                                if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+                                                        crec_ttl(crecp, now), NULL, T_PTR, C_IN,
+                                                        "d", cache_get_name(crecp)))
+                                    anscount++;
+                            }
+                        }
+                    } while ((crecp = cache_find_by_addr(crecp, &addr, now, is_arpa)));
+                else if (is_arpa == F_IPV4 && (daemon->options & OPT_BOGUSPRIV) &&
+                         private_net(addr.addr.addr4)) {
+                    /* if not in cache, enabled and private IPV4 address, return NXDOMAIN */
+                    ans = 1;
+                    nxdomain = 1;
+                    if (!dryrun)
+                        log_query(F_CONFIG | F_REVERSE | F_IPV4 | F_NEG | F_NXDOMAIN, name, &addr,
+                                  NULL);
+                }
+            }
+
+            for (flag = F_IPV4; flag; flag = (flag == F_IPV4) ? F_IPV6 : 0) {
+                unsigned short type = T_A;
+
+                if (flag == F_IPV6)
 #ifdef HAVE_IPV6
-		type = T_AAAA;
+                    type = T_AAAA;
 #else
-	        break;
+                    break;
 #endif
-	      
-	      if (qtype != type && qtype != T_ANY)
-		continue;
-	      
-	      /* Check for "A for A"  queries */
-	      if (qtype == T_A && (addr.addr.addr4.s_addr = inet_addr(name)) != (in_addr_t) -1)
-		{
-		  ans = 1;
-		  if (!dryrun)
-		    {
-		      log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
-		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
-					      daemon->local_ttl, NULL, type, C_IN, "4", &addr))
-			anscount++;
-		    }
-		  continue;
-		}
 
-	      /* interface name stuff */
-	      if (qtype == T_A)
-		{
-		  struct interface_name *intr;
+                if (qtype != type && qtype != T_ANY) continue;
 
-		  for (intr = daemon->int_names; intr; intr = intr->next)
-		    if (hostname_isequal(name, intr->name))
-		      break;
-		  
-		  if (intr)
-		    {
-		      ans = 1;
-		      if (!dryrun)
-			{
-			  if ((addr.addr.addr4 = get_ifaddr(intr->intr)).s_addr == (in_addr_t) -1)
-			    log_query(F_FORWARD | F_CONFIG | F_IPV4 | F_NEG, name, NULL, NULL);
-			  else
-			    {
-			      log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
-			      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
-						      daemon->local_ttl, NULL, type, C_IN, "4", &addr))
-				anscount++;
-			    }
-			}
-		      continue;
-		    }
-		}
+                /* Check for "A for A"  queries */
+                if (qtype == T_A && (addr.addr.addr4.s_addr = inet_addr(name)) != (in_addr_t) -1) {
+                    ans = 1;
+                    if (!dryrun) {
+                        log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
+                        if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+                                                daemon->local_ttl, NULL, type, C_IN, "4", &addr))
+                            anscount++;
+                    }
+                    continue;
+                }
 
-	    cname_restart:
-	      if ((crecp = cache_find_by_name(NULL, name, now, flag | F_CNAME)))
-		{
-		  int localise = 0;
-		  
-		  /* See if a putative address is on the network from which we recieved
-		     the query, is so we'll filter other answers. */
-		  if (local_addr.s_addr != 0 && (daemon->options & OPT_LOCALISE) && flag == F_IPV4)
-		    {
-		      struct crec *save = crecp;
-		      do {
-			if ((crecp->flags & F_HOSTS) &&
-			    is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
-			  {
-			    localise = 1;
-			    break;
-			  } 
-			} while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
-		      crecp = save;
-		    }
-			  
-		  do
-		    { 
-		      /* don't answer wildcard queries with data not from /etc/hosts
-			 or DHCP leases */
-		      if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
-			break;
-		      
-		      if (crecp->flags & F_CNAME)
-			{
-			  if (!dryrun)
-			    {
-			      log_query(crecp->flags, name, NULL, record_source(crecp->uid));
-			      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
-						      crec_ttl(crecp, now), &nameoffset,
-						      T_CNAME, C_IN, "d", cache_get_name(crecp->addr.cname.cache)))
-				anscount++;
-			    }
-			  
-			  strcpy(name, cache_get_name(crecp->addr.cname.cache));
-			  goto cname_restart;
-			}
-		      
-		      if (crecp->flags & F_NEG)
-			{
-			  ans = 1;
-			  auth = 0;
-			  if (crecp->flags & F_NXDOMAIN)
-			    nxdomain = 1;
-			  if (!dryrun)
-			    log_query(crecp->flags, name, NULL, NULL);
-			}
-		      else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd)
-			{
-			  /* If we are returning local answers depending on network,
-			     filter here. */
-			  if (localise && 
-			      (crecp->flags & F_HOSTS) &&
-			      !is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
-			    continue;
-       
-			  if (!(crecp->flags & (F_HOSTS | F_DHCP)))
-			    auth = 0;
-			  
-			  ans = 1;
-			  if (!dryrun)
-			    {
-			      log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr.addr,
-					record_source(crecp->uid));
-			      
-			      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
-						      crec_ttl(crecp, now), NULL, type, C_IN, 
-						      type == T_A ? "4" : "6", &crecp->addr))
-				anscount++;
-			    }
-			}
-		    } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
-		}
-	    }
-	  
-	  if (qtype == T_MX || qtype == T_ANY)
-	    {
-	      int found = 0;
-	      for (rec = daemon->mxnames; rec; rec = rec->next)
-		if (!rec->issrv && hostname_isequal(name, rec->name))
-		  {
-		  ans = found = 1;
-		  if (!dryrun)
-		    {
-		      unsigned int offset;
-		      log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<MX>");
-		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
-					      &offset, T_MX, C_IN, "sd", rec->weight, rec->target))
-			{
-			  anscount++;
-			  if (rec->target)
-			    rec->offset = offset;
-			}
-		    }
-		  }
-	      
-	      if (!found && (daemon->options & (OPT_SELFMX | OPT_LOCALMX)) && 
-		  cache_find_by_name(NULL, name, now, F_HOSTS | F_DHCP))
-		{ 
-		  ans = 1;
-		  if (!dryrun)
-		    {
-		      log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<MX>");
-		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, NULL, 
-					      T_MX, C_IN, "sd", 1, 
-					      (daemon->options & OPT_SELFMX) ? name : daemon->mxtarget))
-			anscount++;
-		    }
-		}
-	    }
-	  	  
-	  if (qtype == T_SRV || qtype == T_ANY)
-	    {
-	      int found = 0;
-	      
-	      for (rec = daemon->mxnames; rec; rec = rec->next)
-		if (rec->issrv && hostname_isequal(name, rec->name))
-		  {
-		    found = ans = 1;
-		    if (!dryrun)
-		      {
-			unsigned int offset;
-			log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<SRV>");
-			if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, 
-						&offset, T_SRV, C_IN, "sssd", 
-						rec->priority, rec->weight, rec->srvport, rec->target))
-			  {
-			    anscount++;
-			    if (rec->target)
-			      rec->offset = offset;
-			  }
-		      }
-		  }
-	      
-	      if (!found && (daemon->options & OPT_FILTER) &&  (qtype == T_SRV || (qtype == T_ANY && strchr(name, '_'))))
-		{
-		  ans = 1;
-		  if (!dryrun)
-		    log_query(F_CONFIG | F_NEG, name, NULL, NULL);
-		}
-	    }
+                /* interface name stuff */
+                if (qtype == T_A) {
+                    struct interface_name* intr;
 
-	  if (qtype == T_NAPTR || qtype == T_ANY)
-	    {
-	      struct naptr *na;
-	      for (na = daemon->naptr; na; na = na->next)
-		if (hostname_isequal(name, na->name))
-		  {
-		    ans = 1;
-		    if (!dryrun)
-		      {
-			log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<NAPTR>");
-			if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, 
-						NULL, T_NAPTR, C_IN, "sszzzd", 
-						na->order, na->pref, na->flags, na->services, na->regexp, na->replace))
-			  anscount++;
-		      }
-		  }
-	    }
-	  
-	  if (qtype == T_MAILB)
-	    ans = 1, nxdomain = 1;
+                    for (intr = daemon->int_names; intr; intr = intr->next)
+                        if (hostname_isequal(name, intr->name)) break;
 
-	  if (qtype == T_SOA && (daemon->options & OPT_FILTER))
-	    {
-	      ans = 1; 
-	      if (!dryrun)
-		log_query(F_CONFIG | F_NEG, name, &addr, NULL);
-	    }
-	}
+                    if (intr) {
+                        ans = 1;
+                        if (!dryrun) {
+                            if ((addr.addr.addr4 = get_ifaddr(intr->intr)).s_addr == (in_addr_t) -1)
+                                log_query(F_FORWARD | F_CONFIG | F_IPV4 | F_NEG, name, NULL, NULL);
+                            else {
+                                log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
+                                if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+                                                        daemon->local_ttl, NULL, type, C_IN, "4",
+                                                        &addr))
+                                    anscount++;
+                            }
+                        }
+                        continue;
+                    }
+                }
 
-      if (!ans)
-	return 0; /* failed to answer a question */
+            cname_restart:
+                if ((crecp = cache_find_by_name(NULL, name, now, flag | F_CNAME))) {
+                    int localise = 0;
+
+                    /* See if a putative address is on the network from which we recieved
+                       the query, is so we'll filter other answers. */
+                    if (local_addr.s_addr != 0 && (daemon->options & OPT_LOCALISE) &&
+                        flag == F_IPV4) {
+                        struct crec* save = crecp;
+                        do {
+                            if ((crecp->flags & F_HOSTS) &&
+                                is_same_net(*((struct in_addr*) &crecp->addr), local_addr,
+                                            local_netmask)) {
+                                localise = 1;
+                                break;
+                            }
+                        } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
+                        crecp = save;
+                    }
+
+                    do {
+                        /* don't answer wildcard queries with data not from /etc/hosts
+                       or DHCP leases */
+                        if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP))) break;
+
+                        if (crecp->flags & F_CNAME) {
+                            if (!dryrun) {
+                                log_query(crecp->flags, name, NULL, record_source(crecp->uid));
+                                if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+                                                        crec_ttl(crecp, now), &nameoffset, T_CNAME,
+                                                        C_IN, "d",
+                                                        cache_get_name(crecp->addr.cname.cache)))
+                                    anscount++;
+                            }
+
+                            strcpy(name, cache_get_name(crecp->addr.cname.cache));
+                            goto cname_restart;
+                        }
+
+                        if (crecp->flags & F_NEG) {
+                            ans = 1;
+                            auth = 0;
+                            if (crecp->flags & F_NXDOMAIN) nxdomain = 1;
+                            if (!dryrun) log_query(crecp->flags, name, NULL, NULL);
+                        } else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd) {
+                            /* If we are returning local answers depending on network,
+                               filter here. */
+                            if (localise && (crecp->flags & F_HOSTS) &&
+                                !is_same_net(*((struct in_addr*) &crecp->addr), local_addr,
+                                             local_netmask))
+                                continue;
+
+                            if (!(crecp->flags & (F_HOSTS | F_DHCP))) auth = 0;
+
+                            ans = 1;
+                            if (!dryrun) {
+                                log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr.addr,
+                                          record_source(crecp->uid));
+
+                                if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+                                                        crec_ttl(crecp, now), NULL, type, C_IN,
+                                                        type == T_A ? "4" : "6", &crecp->addr))
+                                    anscount++;
+                            }
+                        }
+                    } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
+                }
+            }
+
+            if (qtype == T_MX || qtype == T_ANY) {
+                int found = 0;
+                for (rec = daemon->mxnames; rec; rec = rec->next)
+                    if (!rec->issrv && hostname_isequal(name, rec->name)) {
+                        ans = found = 1;
+                        if (!dryrun) {
+                            unsigned int offset;
+                            log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL,
+                                      "<MX>");
+                            if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+                                                    daemon->local_ttl, &offset, T_MX, C_IN, "sd",
+                                                    rec->weight, rec->target)) {
+                                anscount++;
+                                if (rec->target) rec->offset = offset;
+                            }
+                        }
+                    }
+
+                if (!found && (daemon->options & (OPT_SELFMX | OPT_LOCALMX)) &&
+                    cache_find_by_name(NULL, name, now, F_HOSTS | F_DHCP)) {
+                    ans = 1;
+                    if (!dryrun) {
+                        log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<MX>");
+                        if (add_resource_record(
+                                header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, NULL,
+                                T_MX, C_IN, "sd", 1,
+                                (daemon->options & OPT_SELFMX) ? name : daemon->mxtarget))
+                            anscount++;
+                    }
+                }
+            }
+
+            if (qtype == T_SRV || qtype == T_ANY) {
+                int found = 0;
+
+                for (rec = daemon->mxnames; rec; rec = rec->next)
+                    if (rec->issrv && hostname_isequal(name, rec->name)) {
+                        found = ans = 1;
+                        if (!dryrun) {
+                            unsigned int offset;
+                            log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL,
+                                      "<SRV>");
+                            if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+                                                    daemon->local_ttl, &offset, T_SRV, C_IN, "sssd",
+                                                    rec->priority, rec->weight, rec->srvport,
+                                                    rec->target)) {
+                                anscount++;
+                                if (rec->target) rec->offset = offset;
+                            }
+                        }
+                    }
+
+                if (!found && (daemon->options & OPT_FILTER) &&
+                    (qtype == T_SRV || (qtype == T_ANY && strchr(name, '_')))) {
+                    ans = 1;
+                    if (!dryrun) log_query(F_CONFIG | F_NEG, name, NULL, NULL);
+                }
+            }
+
+            if (qtype == T_NAPTR || qtype == T_ANY) {
+                struct naptr* na;
+                for (na = daemon->naptr; na; na = na->next)
+                    if (hostname_isequal(name, na->name)) {
+                        ans = 1;
+                        if (!dryrun) {
+                            log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL,
+                                      "<NAPTR>");
+                            if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+                                                    daemon->local_ttl, NULL, T_NAPTR, C_IN,
+                                                    "sszzzd", na->order, na->pref, na->flags,
+                                                    na->services, na->regexp, na->replace))
+                                anscount++;
+                        }
+                    }
+            }
+
+            if (qtype == T_MAILB) ans = 1, nxdomain = 1;
+
+            if (qtype == T_SOA && (daemon->options & OPT_FILTER)) {
+                ans = 1;
+                if (!dryrun) log_query(F_CONFIG | F_NEG, name, &addr, NULL);
+            }
+        }
+
+        if (!ans) return 0; /* failed to answer a question */
     }
-  
-  if (dryrun)
-    {
-      dryrun = 0;
-      goto rerun;
+
+    if (dryrun) {
+        dryrun = 0;
+        goto rerun;
     }
-  
-  /* create an additional data section, for stuff in SRV and MX record replies. */
-  for (rec = daemon->mxnames; rec; rec = rec->next)
-    if (rec->offset != 0)
-      {
-	/* squash dupes */
-	struct mx_srv_record *tmp;
-	for (tmp = rec->next; tmp; tmp = tmp->next)
-	  if (tmp->offset != 0 && hostname_isequal(rec->target, tmp->target))
-	    tmp->offset = 0;
-	
-	crecp = NULL;
-	while ((crecp = cache_find_by_name(crecp, rec->target, now, F_IPV4 | F_IPV6)))
-	  {
+
+    /* create an additional data section, for stuff in SRV and MX record replies. */
+    for (rec = daemon->mxnames; rec; rec = rec->next)
+        if (rec->offset != 0) {
+            /* squash dupes */
+            struct mx_srv_record* tmp;
+            for (tmp = rec->next; tmp; tmp = tmp->next)
+                if (tmp->offset != 0 && hostname_isequal(rec->target, tmp->target)) tmp->offset = 0;
+
+            crecp = NULL;
+            while ((crecp = cache_find_by_name(crecp, rec->target, now, F_IPV4 | F_IPV6))) {
 #ifdef HAVE_IPV6
-	    int type =  crecp->flags & F_IPV4 ? T_A : T_AAAA;
+                int type = crecp->flags & F_IPV4 ? T_A : T_AAAA;
 #else
-	    int type = T_A;
+                int type = T_A;
 #endif
-	    if (crecp->flags & F_NEG)
-	      continue;
+                if (crecp->flags & F_NEG) continue;
 
-	    if (add_resource_record(header, limit, NULL, rec->offset, &ansp, 
-				    crec_ttl(crecp, now), NULL, type, C_IN, 
-				    crecp->flags & F_IPV4 ? "4" : "6", &crecp->addr))
-	      addncount++;
-	  }
-      }
-  
-  /* done all questions, set up header and return length of result */
-  header->qr = 1; /* response */
-  header->aa = auth; /* authoritive - only hosts and DHCP derived names. */
-  header->ra = 1; /* recursion if available */
-  header->tc = trunc; /* truncation */
-  if (anscount == 0 && nxdomain)
-    header->rcode = NXDOMAIN;
-  else
-    header->rcode = NOERROR; /* no error */
-  header->ancount = htons(anscount);
-  header->nscount = htons(0);
-  header->arcount = htons(addncount);
-  return ansp - (unsigned char *)header;
+                if (add_resource_record(header, limit, NULL, rec->offset, &ansp,
+                                        crec_ttl(crecp, now), NULL, type, C_IN,
+                                        crecp->flags & F_IPV4 ? "4" : "6", &crecp->addr))
+                    addncount++;
+            }
+        }
+
+    /* done all questions, set up header and return length of result */
+    header->qr = 1;     /* response */
+    header->aa = auth;  /* authoritive - only hosts and DHCP derived names. */
+    header->ra = 1;     /* recursion if available */
+    header->tc = trunc; /* truncation */
+    if (anscount == 0 && nxdomain)
+        header->rcode = NXDOMAIN;
+    else
+        header->rcode = NOERROR; /* no error */
+    header->ancount = htons(anscount);
+    header->nscount = htons(0);
+    header->arcount = htons(addncount);
+    return ansp - (unsigned char*) header;
 }
-
-
-
-
-
diff --git a/src/rfc2131.c b/src/rfc2131.c
index 1ef8569..f74ecb9 100644
--- a/src/rfc2131.c
+++ b/src/rfc2131.c
@@ -4,12 +4,12 @@
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; version 2 dated June, 1991, or
    (at your option) version 3 dated 29 June, 2007.
- 
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-     
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
@@ -18,2307 +18,1981 @@
 
 #ifdef HAVE_DHCP
 
-#define BOOTREQUEST              1
-#define BOOTREPLY                2
-#define DHCP_COOKIE              0x63825363
+#define BOOTREQUEST 1
+#define BOOTREPLY 2
+#define DHCP_COOKIE 0x63825363
 
-/* The Linux in-kernel DHCP client silently ignores any packet 
+/* The Linux in-kernel DHCP client silently ignores any packet
    smaller than this. Sigh...........   */
-#define MIN_PACKETSZ             300
+#define MIN_PACKETSZ 300
 
-#define OPTION_PAD               0
-#define OPTION_NETMASK           1
-#define OPTION_ROUTER            3
-#define OPTION_DNSSERVER         6
-#define OPTION_HOSTNAME          12
-#define OPTION_DOMAINNAME        15
-#define OPTION_BROADCAST         28
-#define OPTION_VENDOR_CLASS_OPT  43
-#define OPTION_REQUESTED_IP      50 
-#define OPTION_LEASE_TIME        51
-#define OPTION_OVERLOAD          52
-#define OPTION_MESSAGE_TYPE      53
+#define OPTION_PAD 0
+#define OPTION_NETMASK 1
+#define OPTION_ROUTER 3
+#define OPTION_DNSSERVER 6
+#define OPTION_HOSTNAME 12
+#define OPTION_DOMAINNAME 15
+#define OPTION_BROADCAST 28
+#define OPTION_VENDOR_CLASS_OPT 43
+#define OPTION_REQUESTED_IP 50
+#define OPTION_LEASE_TIME 51
+#define OPTION_OVERLOAD 52
+#define OPTION_MESSAGE_TYPE 53
 #define OPTION_SERVER_IDENTIFIER 54
 #define OPTION_REQUESTED_OPTIONS 55
-#define OPTION_MESSAGE           56
-#define OPTION_MAXMESSAGE        57
-#define OPTION_T1                58
-#define OPTION_T2                59
-#define OPTION_VENDOR_ID         60
-#define OPTION_CLIENT_ID         61
-#define OPTION_SNAME             66
-#define OPTION_FILENAME          67
-#define OPTION_USER_CLASS        77
-#define OPTION_CLIENT_FQDN       81
-#define OPTION_AGENT_ID          82
-#define OPTION_ARCH              93
-#define OPTION_PXE_UUID          97
-#define OPTION_SUBNET_SELECT     118
-#define OPTION_END               255
+#define OPTION_MESSAGE 56
+#define OPTION_MAXMESSAGE 57
+#define OPTION_T1 58
+#define OPTION_T2 59
+#define OPTION_VENDOR_ID 60
+#define OPTION_CLIENT_ID 61
+#define OPTION_SNAME 66
+#define OPTION_FILENAME 67
+#define OPTION_USER_CLASS 77
+#define OPTION_CLIENT_FQDN 81
+#define OPTION_AGENT_ID 82
+#define OPTION_ARCH 93
+#define OPTION_PXE_UUID 97
+#define OPTION_SUBNET_SELECT 118
+#define OPTION_END 255
 
-#define SUBOPT_CIRCUIT_ID        1
-#define SUBOPT_REMOTE_ID         2
-#define SUBOPT_SUBNET_SELECT     5     /* RFC 3527 */
-#define SUBOPT_SUBSCR_ID         6     /* RFC 3393 */
-#define SUBOPT_SERVER_OR         11    /* RFC 5107 */
+#define SUBOPT_CIRCUIT_ID 1
+#define SUBOPT_REMOTE_ID 2
+#define SUBOPT_SUBNET_SELECT 5 /* RFC 3527 */
+#define SUBOPT_SUBSCR_ID 6     /* RFC 3393 */
+#define SUBOPT_SERVER_OR 11    /* RFC 5107 */
 
-#define SUBOPT_PXE_BOOT_ITEM     71    /* PXE standard */
-#define SUBOPT_PXE_DISCOVERY     6
-#define SUBOPT_PXE_SERVERS       8
-#define SUBOPT_PXE_MENU          9
-#define SUBOPT_PXE_MENU_PROMPT   10
+#define SUBOPT_PXE_BOOT_ITEM 71 /* PXE standard */
+#define SUBOPT_PXE_DISCOVERY 6
+#define SUBOPT_PXE_SERVERS 8
+#define SUBOPT_PXE_MENU 9
+#define SUBOPT_PXE_MENU_PROMPT 10
 
-#define DHCPDISCOVER             1
-#define DHCPOFFER                2
-#define DHCPREQUEST              3
-#define DHCPDECLINE              4
-#define DHCPACK                  5
-#define DHCPNAK                  6
-#define DHCPRELEASE              7
-#define DHCPINFORM               8
+#define DHCPDISCOVER 1
+#define DHCPOFFER 2
+#define DHCPREQUEST 3
+#define DHCPDECLINE 4
+#define DHCPACK 5
+#define DHCPNAK 6
+#define DHCPRELEASE 7
+#define DHCPINFORM 8
 
-#define have_config(config, mask) ((config) && ((config)->flags & (mask))) 
-#define option_len(opt) ((int)(((unsigned char *)(opt))[1]))
-#define option_ptr(opt, i) ((void *)&(((unsigned char *)(opt))[2u+(unsigned int)(i)]))
+#define have_config(config, mask) ((config) && ((config)->flags & (mask)))
+#define option_len(opt) ((int) (((unsigned char*) (opt))[1]))
+#define option_ptr(opt, i) ((void*) &(((unsigned char*) (opt))[2u + (unsigned int) (i)]))
 
-static int sanitise(unsigned char *opt, char *buf);
-static struct in_addr server_id(struct dhcp_context *context, struct in_addr override, struct in_addr fallback);
-static unsigned int calc_time(struct dhcp_context *context, struct dhcp_config *config, unsigned char *opt);
-static void option_put(struct dhcp_packet *mess, unsigned char *end, int opt, int len, unsigned int val);
-static void option_put_string(struct dhcp_packet *mess, unsigned char *end, 
-			      int opt, char *string, int null_term);
-static struct in_addr option_addr(unsigned char *opt);
-static struct in_addr option_addr_arr(unsigned char *opt, int offset);
-static unsigned int option_uint(unsigned char *opt, int i, int size);
-static void log_packet(char *type, void *addr, unsigned char *ext_mac, 
-		       int mac_len, char *interface, char *string, u32 xid);
-static unsigned char *option_find(struct dhcp_packet *mess, size_t size, int opt_type, int minsize);
-static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt, int minsize);
-static size_t dhcp_packet_size(struct dhcp_packet *mess, struct dhcp_netid *netid,
-			       unsigned char *agent_id, unsigned char *real_end);
-static void clear_packet(struct dhcp_packet *mess, unsigned char *end);
-static void do_options(struct dhcp_context *context,
-		       struct dhcp_packet *mess,
-		       unsigned char *real_end, 
-		       unsigned char *req_options,
-		       char *hostname, 
-		       char *domain, char *config_domain,
-		       struct dhcp_netid *netid,
-		       struct in_addr subnet_addr,
-		       unsigned char fqdn_flags,
-		       int null_term, int pxearch,
-		       unsigned char *uuid);
+static int sanitise(unsigned char* opt, char* buf);
+static struct in_addr server_id(struct dhcp_context* context, struct in_addr override,
+                                struct in_addr fallback);
+static unsigned int calc_time(struct dhcp_context* context, struct dhcp_config* config,
+                              unsigned char* opt);
+static void option_put(struct dhcp_packet* mess, unsigned char* end, int opt, int len,
+                       unsigned int val);
+static void option_put_string(struct dhcp_packet* mess, unsigned char* end, int opt, char* string,
+                              int null_term);
+static struct in_addr option_addr(unsigned char* opt);
+static struct in_addr option_addr_arr(unsigned char* opt, int offset);
+static unsigned int option_uint(unsigned char* opt, int i, int size);
+static void log_packet(char* type, void* addr, unsigned char* ext_mac, int mac_len, char* interface,
+                       char* string, u32 xid);
+static unsigned char* option_find(struct dhcp_packet* mess, size_t size, int opt_type, int minsize);
+static unsigned char* option_find1(unsigned char* p, unsigned char* end, int opt, int minsize);
+static size_t dhcp_packet_size(struct dhcp_packet* mess, struct dhcp_netid* netid,
+                               unsigned char* agent_id, unsigned char* real_end);
+static void clear_packet(struct dhcp_packet* mess, unsigned char* end);
+static void do_options(struct dhcp_context* context, struct dhcp_packet* mess,
+                       unsigned char* real_end, unsigned char* req_options, char* hostname,
+                       char* domain, char* config_domain, struct dhcp_netid* netid,
+                       struct in_addr subnet_addr, unsigned char fqdn_flags, int null_term,
+                       int pxearch, unsigned char* uuid);
 
+static void match_vendor_opts(unsigned char* opt, struct dhcp_opt* dopt);
+static void do_encap_opts(struct dhcp_opt* opts, int encap, int flag, struct dhcp_packet* mess,
+                          unsigned char* end, int null_term);
+static void pxe_misc(struct dhcp_packet* mess, unsigned char* end, unsigned char* uuid);
+static int prune_vendor_opts(struct dhcp_netid* netid);
+static struct dhcp_opt* pxe_opts(int pxe_arch, struct dhcp_netid* netid);
+struct dhcp_boot* find_boot(struct dhcp_netid* netid);
 
-static void match_vendor_opts(unsigned char *opt, struct dhcp_opt *dopt); 
-static void do_encap_opts(struct dhcp_opt *opts, int encap, int flag, struct dhcp_packet *mess, unsigned char *end, int null_term);
-static void pxe_misc(struct dhcp_packet *mess, unsigned char *end, unsigned char *uuid);
-static int prune_vendor_opts(struct dhcp_netid *netid);
-static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid);
-struct dhcp_boot *find_boot(struct dhcp_netid *netid);
+size_t dhcp_reply(struct dhcp_context* context, char* iface_name, int int_index, size_t sz,
+                  time_t now, int unicast_dest, int* is_inform) {
+    unsigned char *opt, *clid = NULL;
+    struct dhcp_lease *ltmp, *lease = NULL;
+    struct dhcp_vendor* vendor;
+    struct dhcp_mac* mac;
+    struct dhcp_netid_list* id_list;
+    int clid_len = 0, ignore = 0, do_classes = 0, selecting = 0, pxearch = -1;
+    struct dhcp_packet* mess = (struct dhcp_packet*) daemon->dhcp_packet.iov_base;
+    unsigned char* end = (unsigned char*) (mess + 1);
+    unsigned char* real_end = (unsigned char*) (mess + 1);
+    char *hostname = NULL, *offer_hostname = NULL, *client_hostname = NULL, *domain = NULL;
+    int hostname_auth = 0, borken_opt = 0;
+    unsigned char* req_options = NULL;
+    char* message = NULL;
+    unsigned int time;
+    struct dhcp_config* config;
+    struct dhcp_netid* netid;
+    struct in_addr subnet_addr, fallback, override;
+    unsigned short fuzz = 0;
+    unsigned int mess_type = 0;
+    unsigned char fqdn_flags = 0;
+    unsigned char *agent_id = NULL, *uuid = NULL;
+    unsigned char* emac = NULL;
+    int emac_len = 0;
+    struct dhcp_netid known_id, iface_id;
+    struct dhcp_opt* o;
+    unsigned char pxe_uuid[17];
 
-  
-size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
-		  size_t sz, time_t now, int unicast_dest, int *is_inform)
-{
-  unsigned char *opt, *clid = NULL;
-  struct dhcp_lease *ltmp, *lease = NULL;
-  struct dhcp_vendor *vendor;
-  struct dhcp_mac *mac;
-  struct dhcp_netid_list *id_list;
-  int clid_len = 0, ignore = 0, do_classes = 0, selecting = 0, pxearch = -1;
-  struct dhcp_packet *mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base;
-  unsigned char *end = (unsigned char *)(mess + 1); 
-  unsigned char *real_end = (unsigned char *)(mess + 1); 
-  char *hostname = NULL, *offer_hostname = NULL, *client_hostname = NULL, *domain = NULL;
-  int hostname_auth = 0, borken_opt = 0;
-  unsigned char *req_options = NULL;
-  char *message = NULL;
-  unsigned int time;
-  struct dhcp_config *config;
-  struct dhcp_netid *netid;
-  struct in_addr subnet_addr, fallback, override;
-  unsigned short fuzz = 0;
-  unsigned int mess_type = 0;
-  unsigned char fqdn_flags = 0;
-  unsigned char *agent_id = NULL, *uuid = NULL;
-  unsigned char *emac = NULL;
-  int emac_len = 0;
-  struct dhcp_netid known_id, iface_id;
-  struct dhcp_opt *o;
-  unsigned char pxe_uuid[17];
+    subnet_addr.s_addr = override.s_addr = 0;
 
-  subnet_addr.s_addr = override.s_addr = 0;
+    /* set tag with name == interface */
+    iface_id.net = iface_name;
+    iface_id.next = NULL;
+    netid = &iface_id;
 
-  /* set tag with name == interface */
-  iface_id.net = iface_name;
-  iface_id.next = NULL;
-  netid = &iface_id; 
-  
-  if (mess->op != BOOTREQUEST || mess->hlen > DHCP_CHADDR_MAX)
+    if (mess->op != BOOTREQUEST || mess->hlen > DHCP_CHADDR_MAX) return 0;
+
+    if (mess->htype == 0 && mess->hlen != 0) return 0;
+
+    /* check for DHCP rather than BOOTP */
+    if ((opt = option_find(mess, sz, OPTION_MESSAGE_TYPE, 1))) {
+        mess_type = option_uint(opt, 0, 1);
+
+        /* only insist on a cookie for DHCP. */
+        if (*((u32*) &mess->options) != htonl(DHCP_COOKIE)) return 0;
+
+        /* two things to note here: expand_buf may move the packet,
+       so reassign mess from daemon->packet. Also, the size
+       sent includes the IP and UDP headers, hence the magic "-28" */
+        if ((opt = option_find(mess, sz, OPTION_MAXMESSAGE, 2))) {
+            size_t size = (size_t) option_uint(opt, 0, 2) - 28;
+
+            if (size > DHCP_PACKET_MAX)
+                size = DHCP_PACKET_MAX;
+            else if (size < sizeof(struct dhcp_packet))
+                size = sizeof(struct dhcp_packet);
+
+            if (expand_buf(&daemon->dhcp_packet, size)) {
+                mess = (struct dhcp_packet*) daemon->dhcp_packet.iov_base;
+                real_end = end = ((unsigned char*) mess) + size;
+            }
+        }
+
+        /* Some buggy clients set ciaddr when they shouldn't, so clear that here since
+       it can affect the context-determination code. */
+        if ((option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ) || mess_type == DHCPDISCOVER))
+            mess->ciaddr.s_addr = 0;
+
+        if ((opt = option_find(mess, sz, OPTION_AGENT_ID, 1))) {
+            /* Any agent-id needs to be copied back out, verbatim, as the last option
+               in the packet. Here, we shift it to the very end of the buffer, if it doesn't
+               get overwritten, then it will be shuffled back at the end of processing.
+               Note that the incoming options must not be overwritten here, so there has to
+               be enough free space at the end of the packet to copy the option. */
+            unsigned char* sopt;
+            unsigned int total = option_len(opt) + 2;
+            unsigned char* last_opt = option_find(mess, sz, OPTION_END, 0);
+            if (last_opt && last_opt < end - total) {
+                end -= total;
+                agent_id = end;
+                memcpy(agent_id, opt, total);
+            }
+
+            /* look for RFC3527 Link selection sub-option */
+            if ((sopt = option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)),
+                                     SUBOPT_SUBNET_SELECT, INADDRSZ)))
+                subnet_addr = option_addr(sopt);
+
+            /* look for RFC5107 server-identifier-override */
+            if ((sopt = option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)),
+                                     SUBOPT_SERVER_OR, INADDRSZ)))
+                override = option_addr(sopt);
+
+            /* if a circuit-id or remote-is option is provided, exact-match to options. */
+            for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next) {
+                int search;
+
+                if (vendor->match_type == MATCH_CIRCUIT)
+                    search = SUBOPT_CIRCUIT_ID;
+                else if (vendor->match_type == MATCH_REMOTE)
+                    search = SUBOPT_REMOTE_ID;
+                else if (vendor->match_type == MATCH_SUBSCRIBER)
+                    search = SUBOPT_SUBSCR_ID;
+                else
+                    continue;
+
+                if ((sopt = option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)),
+                                         search, 1)) &&
+                    vendor->len == option_len(sopt) &&
+                    memcmp(option_ptr(sopt, 0), vendor->data, vendor->len) == 0) {
+                    vendor->netid.next = netid;
+                    netid = &vendor->netid;
+                    break;
+                }
+            }
+        }
+
+        /* Check for RFC3011 subnet selector - only if RFC3527 one not present */
+        if (subnet_addr.s_addr == 0 && (opt = option_find(mess, sz, OPTION_SUBNET_SELECT, INADDRSZ)))
+            subnet_addr = option_addr(opt);
+
+        /* If there is no client identifier option, use the hardware address */
+        if ((opt = option_find(mess, sz, OPTION_CLIENT_ID, 1))) {
+            clid_len = option_len(opt);
+            clid = option_ptr(opt, 0);
+        }
+
+        /* do we have a lease in store? */
+        lease = lease_find_by_client(mess->chaddr, mess->hlen, mess->htype, clid, clid_len);
+
+        /* If this request is missing a clid, but we've seen one before,
+       use it again for option matching etc. */
+        if (lease && !clid && lease->clid) {
+            clid_len = lease->clid_len;
+            clid = lease->clid;
+        }
+
+        /* find mac to use for logging and hashing */
+        emac = extended_hwaddr(mess->htype, mess->hlen, mess->chaddr, clid_len, clid, &emac_len);
+    }
+
+    for (mac = daemon->dhcp_macs; mac; mac = mac->next)
+        if (mac->hwaddr_len == mess->hlen &&
+            (mac->hwaddr_type == mess->htype || mac->hwaddr_type == 0) &&
+            memcmp_masked(mac->hwaddr, mess->chaddr, mess->hlen, mac->mask)) {
+            mac->netid.next = netid;
+            netid = &mac->netid;
+        }
+
+    /* Determine network for this packet. Our caller will have already linked all the
+       contexts which match the addresses of the receiving interface but if the
+       machine has an address already, or came via a relay, or we have a subnet selector,
+       we search again. If we don't have have a giaddr or explicit subnet selector,
+       use the ciaddr. This is necessary because a  machine which got a lease via a
+       relay won't use the relay to renew. If matching a ciaddr fails but we have a context
+       from the physical network, continue using that to allow correct DHCPNAK generation later. */
+    if (mess->giaddr.s_addr || subnet_addr.s_addr || mess->ciaddr.s_addr) {
+        struct dhcp_context *context_tmp, *context_new = NULL;
+        struct in_addr addr;
+        int force = 0;
+
+        if (subnet_addr.s_addr) {
+            addr = subnet_addr;
+            force = 1;
+        } else if (mess->giaddr.s_addr) {
+            addr = mess->giaddr;
+            force = 1;
+        } else {
+            /* If ciaddr is in the hardware derived set of contexts, leave that unchanged */
+            addr = mess->ciaddr;
+            for (context_tmp = context; context_tmp; context_tmp = context_tmp->current)
+                if (context_tmp->netmask.s_addr &&
+                    is_same_net(addr, context_tmp->start, context_tmp->netmask) &&
+                    is_same_net(addr, context_tmp->end, context_tmp->netmask)) {
+                    context_new = context;
+                    break;
+                }
+        }
+
+        if (!context_new)
+            for (context_tmp = daemon->dhcp; context_tmp; context_tmp = context_tmp->next)
+                if (context_tmp->netmask.s_addr &&
+                    is_same_net(addr, context_tmp->start, context_tmp->netmask) &&
+                    is_same_net(addr, context_tmp->end, context_tmp->netmask)) {
+                    context_tmp->current = context_new;
+                    context_new = context_tmp;
+                }
+
+        if (context_new || force) context = context_new;
+    }
+
+    if (!context) {
+        //      my_syslog(MS_DHCP | LOG_WARNING, _("no address range available for DHCP request %s
+        //      %s"),
+        //		subnet_addr.s_addr ? _("with subnet selector") : _("via"),
+        //		subnet_addr.s_addr ? inet_ntoa(subnet_addr) : (mess->giaddr.s_addr ?
+        //inet_ntoa(mess->giaddr) : iface_name));
+        return 0;
+    }
+
+    /* keep _a_ local address available. */
+    fallback = context->local;
+
+    if (daemon->options & OPT_LOG_OPTS) {
+        struct dhcp_context* context_tmp;
+        for (context_tmp = context; context_tmp; context_tmp = context_tmp->current) {
+            strcpy(daemon->namebuff, inet_ntoa(context_tmp->start));
+            if (context_tmp->flags & (CONTEXT_STATIC | CONTEXT_PROXY))
+                my_syslog(MS_DHCP | LOG_INFO, _("%u Available DHCP subnet: %s/%s"),
+                          ntohl(mess->xid), daemon->namebuff, inet_ntoa(context_tmp->netmask));
+            else
+                my_syslog(MS_DHCP | LOG_INFO, _("%u Available DHCP range: %s -- %s"),
+                          ntohl(mess->xid), daemon->namebuff, inet_ntoa(context_tmp->end));
+        }
+    }
+
+    mess->op = BOOTREPLY;
+
+    config = find_config(daemon->dhcp_conf, context, clid, clid_len, mess->chaddr, mess->hlen,
+                         mess->htype, NULL);
+
+    /* set "known" tag for known hosts */
+    if (config) {
+        known_id.net = "known";
+        known_id.next = netid;
+        netid = &known_id;
+    }
+
+    if (mess_type == 0) {
+        /* BOOTP request */
+        struct dhcp_netid id, bootp_id;
+        struct in_addr* logaddr = NULL;
+
+        /* must have a MAC addr for bootp */
+        if (mess->htype == 0 || mess->hlen == 0 || (context->flags & CONTEXT_PROXY)) return 0;
+
+        if (have_config(config, CONFIG_DISABLE)) message = _("disabled");
+
+        end = mess->options + 64; /* BOOTP vend area is only 64 bytes */
+
+        if (have_config(config, CONFIG_NAME)) {
+            hostname = config->hostname;
+            domain = config->domain;
+        }
+
+        if (have_config(config, CONFIG_NETID)) {
+            config->netid.next = netid;
+            netid = &config->netid;
+        }
+
+        /* Match incoming filename field as a netid. */
+        if (mess->file[0]) {
+            memcpy(daemon->dhcp_buff2, mess->file, sizeof(mess->file));
+            daemon->dhcp_buff2[sizeof(mess->file) + 1] = 0; /* ensure zero term. */
+            id.net = (char*) daemon->dhcp_buff2;
+            id.next = netid;
+            netid = &id;
+        }
+
+        /* Add "bootp" as a tag to allow different options, address ranges etc
+       for BOOTP clients */
+        bootp_id.net = "bootp";
+        bootp_id.next = netid;
+        netid = &bootp_id;
+
+        for (id_list = daemon->dhcp_ignore; id_list; id_list = id_list->next)
+            if (match_netid(id_list->list, netid, 0)) message = _("ignored");
+
+        if (!message) {
+            int nailed = 0;
+
+            if (have_config(config, CONFIG_ADDR)) {
+                nailed = 1;
+                logaddr = &config->addr;
+                mess->yiaddr = config->addr;
+                if ((lease = lease_find_by_addr(config->addr)) &&
+                    (lease->hwaddr_len != mess->hlen || lease->hwaddr_type != mess->htype ||
+                     memcmp(lease->hwaddr, mess->chaddr, lease->hwaddr_len) != 0))
+                    message = _("address in use");
+            } else {
+                if (!(lease = lease_find_by_client(mess->chaddr, mess->hlen, mess->htype, NULL, 0)) ||
+                    !address_available(context, lease->addr, netid)) {
+                    if (lease) {
+                        /* lease exists, wrong network. */
+                        lease_prune(lease, now);
+                        lease = NULL;
+                    }
+                    if (!address_allocate(context, &mess->yiaddr, mess->chaddr, mess->hlen, netid,
+                                          now))
+                        message = _("no address available");
+                } else
+                    mess->yiaddr = lease->addr;
+            }
+
+            if (!message && !(context = narrow_context(context, mess->yiaddr, netid)))
+                message = _("wrong network");
+            else if (context->netid.net) {
+                context->netid.next = netid;
+                netid = &context->netid;
+            }
+
+            if (!message && !nailed) {
+                for (id_list = daemon->bootp_dynamic; id_list; id_list = id_list->next)
+                    if ((!id_list->list) || match_netid(id_list->list, netid, 0)) break;
+                if (!id_list) message = _("no address configured");
+            }
+
+            if (!message && !lease && (!(lease = lease_allocate(mess->yiaddr))))
+                message = _("no leases left");
+
+            if (!message) {
+                logaddr = &mess->yiaddr;
+
+                lease_set_hwaddr(lease, mess->chaddr, NULL, mess->hlen, mess->htype, 0);
+                if (hostname) lease_set_hostname(lease, hostname, 1);
+                /* infinite lease unless nailed in dhcp-host line. */
+                lease_set_expires(
+                    lease, have_config(config, CONFIG_TIME) ? config->lease_time : 0xffffffff, now);
+                lease_set_interface(lease, int_index);
+
+                clear_packet(mess, end);
+                do_options(context, mess, end, NULL, hostname, get_domain(mess->yiaddr), domain,
+                           netid, subnet_addr, 0, 0, 0, NULL);
+            }
+        }
+
+        log_packet("BOOTP", logaddr, mess->chaddr, mess->hlen, iface_name, message, mess->xid);
+
+        return message ? 0 : dhcp_packet_size(mess, netid, agent_id, real_end);
+    }
+
+    if ((opt = option_find(mess, sz, OPTION_CLIENT_FQDN, 4))) {
+        /* http://tools.ietf.org/wg/dhc/draft-ietf-dhc-fqdn-option/draft-ietf-dhc-fqdn-option-10.txt */
+        int len = option_len(opt);
+        char* pq = daemon->dhcp_buff;
+        unsigned char *pp, *op = option_ptr(opt, 0);
+
+        fqdn_flags = *op;
+        len -= 3;
+        op += 3;
+        pp = op;
+
+        /* Always force update, since the client has no way to do it itself. */
+        if (!(fqdn_flags & 0x01)) fqdn_flags |= 0x02;
+
+        fqdn_flags &= ~0x08;
+        fqdn_flags |= 0x01;
+
+        if (fqdn_flags & 0x04)
+            while (*op != 0 && ((op + (*op) + 1) - pp) < len) {
+                memcpy(pq, op + 1, *op);
+                pq += *op;
+                op += (*op) + 1;
+                *(pq++) = '.';
+            }
+        else {
+            memcpy(pq, op, len);
+            if (len > 0 && op[len - 1] == 0) borken_opt = 1;
+            pq += len + 1;
+        }
+
+        if (pq != daemon->dhcp_buff) pq--;
+
+        *pq = 0;
+
+        if (legal_hostname(daemon->dhcp_buff)) offer_hostname = client_hostname = daemon->dhcp_buff;
+    } else if ((opt = option_find(mess, sz, OPTION_HOSTNAME, 1))) {
+        int len = option_len(opt);
+        memcpy(daemon->dhcp_buff, option_ptr(opt, 0), len);
+        /* Microsoft clients are broken, and need zero-terminated strings
+       in options. We detect this state here, and do the same in
+       any options we send */
+        if (len > 0 && daemon->dhcp_buff[len - 1] == 0)
+            borken_opt = 1;
+        else
+            daemon->dhcp_buff[len] = 0;
+        if (legal_hostname(daemon->dhcp_buff)) client_hostname = daemon->dhcp_buff;
+    }
+
+    if (client_hostname && daemon->options & OPT_LOG_OPTS)
+        my_syslog(MS_DHCP | LOG_INFO, _("%u client provides name: %s"), ntohl(mess->xid),
+                  client_hostname);
+
+    if (have_config(config, CONFIG_NAME)) {
+        hostname = config->hostname;
+        domain = config->domain;
+        hostname_auth = 1;
+        /* be careful not to send an OFFER with a hostname not matching the DISCOVER. */
+        if (fqdn_flags != 0 || !client_hostname || hostname_isequal(hostname, client_hostname))
+            offer_hostname = hostname;
+    } else if (client_hostname) {
+        domain = strip_hostname(client_hostname);
+
+        if (strlen(client_hostname) != 0) {
+            hostname = client_hostname;
+            if (!config) {
+                /* Search again now we have a hostname.
+               Only accept configs without CLID and HWADDR here, (they won't match)
+               to avoid impersonation by name. */
+                struct dhcp_config* new =
+                    find_config(daemon->dhcp_conf, context, NULL, 0, mess->chaddr, mess->hlen,
+                                mess->htype, hostname);
+                if (new && !have_config(new, CONFIG_CLID) && !new->hwaddr) {
+                    config = new;
+                    /* set "known" tag for known hosts */
+                    known_id.net = "known";
+                    known_id.next = netid;
+                    netid = &known_id;
+                }
+            }
+        }
+    }
+
+    if (have_config(config, CONFIG_NETID)) {
+        config->netid.next = netid;
+        netid = &config->netid;
+    }
+
+    /* dhcp-match. If we have hex-and-wildcards, look for a left-anchored match.
+       Otherwise assume the option is an array, and look for a matching element.
+       If no data given, existance of the option is enough. */
+    for (o = daemon->dhcp_match; o; o = o->next) {
+        int i, matched = 0;
+
+        if (!(opt = option_find(mess, sz, o->opt, 1)) || o->len > option_len(opt)) continue;
+
+        if (o->len == 0)
+            matched = 1;
+        else if (o->flags & DHOPT_HEX) {
+            if (memcmp_masked(o->val, option_ptr(opt, 0), o->len, o->u.wildcard_mask)) matched = 1;
+        } else
+            for (i = 0; i <= (option_len(opt) - o->len);) {
+                if (memcmp(o->val, option_ptr(opt, i), o->len) == 0) {
+                    matched = 1;
+                    break;
+                }
+
+                if (o->flags & DHOPT_STRING)
+                    i++;
+                else
+                    i += o->len;
+            }
+
+        if (matched) {
+            o->netid->next = netid;
+            netid = o->netid;
+        }
+    }
+
+    /* user-class options are, according to RFC3004, supposed to contain
+       a set of counted strings. Here we check that this is so (by seeing
+       if the counts are consistent with the overall option length) and if
+       so zero the counts so that we don't get spurious matches between
+       the vendor string and the counts. If the lengths don't add up, we
+       assume that the option is a single string and non RFC3004 compliant
+       and just do the substring match. dhclient provides these broken options.
+       The code, later, which sends user-class data to the lease-change script
+       relies on the transformation done here.
+    */
+
+    if ((opt = option_find(mess, sz, OPTION_USER_CLASS, 1))) {
+        unsigned char* ucp = option_ptr(opt, 0);
+        int tmp, j;
+        for (j = 0; j < option_len(opt); j += ucp[j] + 1)
+            ;
+        if (j == option_len(opt))
+            for (j = 0; j < option_len(opt); j = tmp) {
+                tmp = j + ucp[j] + 1;
+                ucp[j] = 0;
+            }
+    }
+
+    for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next) {
+        int mopt;
+
+        if (vendor->match_type == MATCH_VENDOR)
+            mopt = OPTION_VENDOR_ID;
+        else if (vendor->match_type == MATCH_USER)
+            mopt = OPTION_USER_CLASS;
+        else
+            continue;
+
+        if ((opt = option_find(mess, sz, mopt, 1))) {
+            int i;
+            for (i = 0; i <= (option_len(opt) - vendor->len); i++)
+                if (memcmp(vendor->data, option_ptr(opt, i), vendor->len) == 0) {
+                    vendor->netid.next = netid;
+                    netid = &vendor->netid;
+                    break;
+                }
+        }
+    }
+
+    /* mark vendor-encapsulated options which match the client-supplied vendor class */
+    match_vendor_opts(option_find(mess, sz, OPTION_VENDOR_ID, 1), daemon->dhcp_opts);
+
+    if (daemon->options & OPT_LOG_OPTS) {
+        if (sanitise(option_find(mess, sz, OPTION_VENDOR_ID, 1), daemon->namebuff))
+            my_syslog(MS_DHCP | LOG_INFO, _("%u Vendor class: %s"), ntohl(mess->xid),
+                      daemon->namebuff);
+        if (sanitise(option_find(mess, sz, OPTION_USER_CLASS, 1), daemon->namebuff))
+            my_syslog(MS_DHCP | LOG_INFO, _("%u User class: %s"), ntohl(mess->xid),
+                      daemon->namebuff);
+    }
+
+    /* if all the netids in the ignore list are present, ignore this client */
+    for (id_list = daemon->dhcp_ignore; id_list; id_list = id_list->next)
+        if (match_netid(id_list->list, netid, 0)) ignore = 1;
+
+    /* Can have setting to ignore the client ID for a particular MAC address or hostname */
+    if (have_config(config, CONFIG_NOCLID)) clid = NULL;
+
+    /* Check if client is PXE client. */
+    if (daemon->enable_pxe && (opt = option_find(mess, sz, OPTION_VENDOR_ID, 9)) &&
+        strncmp(option_ptr(opt, 0), "PXEClient", 9) == 0) {
+        if ((opt = option_find(mess, sz, OPTION_PXE_UUID, 17))) {
+            memcpy(pxe_uuid, option_ptr(opt, 0), 17);
+            uuid = pxe_uuid;
+        }
+
+        /* Check if this is really a PXE bootserver request, and handle specially if so. */
+        if ((mess_type == DHCPREQUEST || mess_type == DHCPINFORM) &&
+            (opt = option_find(mess, sz, OPTION_VENDOR_CLASS_OPT, 1)) &&
+            (opt = option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)),
+                                SUBOPT_PXE_BOOT_ITEM, 4))) {
+            struct pxe_service* service;
+            int type = option_uint(opt, 0, 2);
+            int layer = option_uint(opt, 2, 2);
+            unsigned char save71[4];
+            struct dhcp_opt opt71;
+
+            if (ignore) return 0;
+
+            if (layer & 0x8000) {
+                my_syslog(MS_DHCP | LOG_ERR, _("PXE BIS not supported"));
+                return 0;
+            }
+
+            memcpy(save71, option_ptr(opt, 0), 4);
+
+            for (service = daemon->pxe_services; service; service = service->next)
+                if (service->type == type) break;
+
+            if (!service || !service->basename) return 0;
+
+            clear_packet(mess, end);
+
+            mess->yiaddr = mess->ciaddr;
+            mess->ciaddr.s_addr = 0;
+            if (service->server.s_addr != 0)
+                mess->siaddr = service->server;
+            else
+                mess->siaddr = context->local;
+
+            snprintf((char*) mess->file, sizeof(mess->file), "%s.%d", service->basename, layer);
+            option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
+            option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, htonl(context->local.s_addr));
+            pxe_misc(mess, end, uuid);
+
+            prune_vendor_opts(netid);
+            opt71.val = save71;
+            opt71.opt = SUBOPT_PXE_BOOT_ITEM;
+            opt71.len = 4;
+            opt71.flags = DHOPT_VENDOR_MATCH;
+            opt71.netid = NULL;
+            opt71.next = daemon->dhcp_opts;
+            do_encap_opts(&opt71, OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0);
+
+            log_packet("PXE", &mess->yiaddr, emac, emac_len, iface_name, (char*) mess->file,
+                       mess->xid);
+            return dhcp_packet_size(mess, netid, agent_id, real_end);
+        }
+
+        if ((opt = option_find(mess, sz, OPTION_ARCH, 2))) {
+            pxearch = option_uint(opt, 0, 2);
+
+            /* proxy DHCP here. The DHCPREQUEST stuff is for gPXE */
+            if ((mess_type == DHCPDISCOVER || mess_type == DHCPREQUEST) &&
+                (context->flags & CONTEXT_PROXY)) {
+                struct dhcp_boot* boot = find_boot(netid);
+
+                mess->yiaddr.s_addr = 0;
+                if (mess_type == DHCPDISCOVER || mess->ciaddr.s_addr == 0) {
+                    mess->ciaddr.s_addr = 0;
+                    mess->flags |= htons(0x8000); /* broadcast */
+                }
+
+                clear_packet(mess, end);
+
+                /* Provide the bootfile here, for gPXE, and in case we have no menu items
+               and set discovery_control = 8 */
+                if (boot) {
+                    if (boot->next_server.s_addr) mess->siaddr = boot->next_server;
+
+                    if (boot->file) strncpy((char*) mess->file, boot->file, sizeof(mess->file) - 1);
+                }
+
+                option_put(mess, end, OPTION_MESSAGE_TYPE, 1,
+                           mess_type == DHCPDISCOVER ? DHCPOFFER : DHCPACK);
+                option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ,
+                           htonl(context->local.s_addr));
+                pxe_misc(mess, end, uuid);
+                prune_vendor_opts(netid);
+                do_encap_opts(pxe_opts(pxearch, netid), OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH,
+                              mess, end, 0);
+
+                log_packet("PXE", NULL, emac, emac_len, iface_name,
+                           ignore ? "proxy" : "proxy-ignored", mess->xid);
+                return ignore ? 0 : dhcp_packet_size(mess, netid, agent_id, real_end);
+            }
+        }
+    }
+
+    /* if we're just a proxy server, go no further */
+    if (context->flags & CONTEXT_PROXY) return 0;
+
+    if ((opt = option_find(mess, sz, OPTION_REQUESTED_OPTIONS, 0))) {
+        req_options = (unsigned char*) daemon->dhcp_buff2;
+        memcpy(req_options, option_ptr(opt, 0), option_len(opt));
+        req_options[option_len(opt)] = OPTION_END;
+    }
+
+    switch (mess_type) {
+        case DHCPDECLINE:
+            if (!(opt = option_find(mess, sz, OPTION_SERVER_IDENTIFIER, INADDRSZ)) ||
+                option_addr(opt).s_addr != server_id(context, override, fallback).s_addr)
+                return 0;
+
+            /* sanitise any message. Paranoid? Moi? */
+            sanitise(option_find(mess, sz, OPTION_MESSAGE, 1), daemon->dhcp_buff);
+
+            if (!(opt = option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ))) return 0;
+
+            log_packet("DHCPDECLINE", option_ptr(opt, 0), emac, emac_len, iface_name,
+                       daemon->dhcp_buff, mess->xid);
+
+            if (lease && lease->addr.s_addr == option_addr(opt).s_addr) lease_prune(lease, now);
+
+            if (have_config(config, CONFIG_ADDR) && config->addr.s_addr == option_addr(opt).s_addr) {
+                prettyprint_time(daemon->dhcp_buff, DECLINE_BACKOFF);
+                my_syslog(MS_DHCP | LOG_WARNING, _("disabling DHCP static address %s for %s"),
+                          inet_ntoa(config->addr), daemon->dhcp_buff);
+                config->flags |= CONFIG_DECLINED;
+                config->decline_time = now;
+            } else
+                /* make sure this host gets a different address next time. */
+                for (; context; context = context->current) context->addr_epoch++;
+
+            return 0;
+
+        case DHCPRELEASE:
+            if (!(context = narrow_context(context, mess->ciaddr, netid)) ||
+                !(opt = option_find(mess, sz, OPTION_SERVER_IDENTIFIER, INADDRSZ)) ||
+                option_addr(opt).s_addr != server_id(context, override, fallback).s_addr)
+                return 0;
+
+            if (lease && lease->addr.s_addr == mess->ciaddr.s_addr)
+                lease_prune(lease, now);
+            else
+                message = _("unknown lease");
+
+            log_packet("DHCPRELEASE", &mess->ciaddr, emac, emac_len, iface_name, message, mess->xid);
+
+            return 0;
+
+        case DHCPDISCOVER:
+            if (ignore || have_config(config, CONFIG_DISABLE)) {
+                message = _("ignored");
+                opt = NULL;
+            } else {
+                struct in_addr addr, conf;
+
+                addr.s_addr = conf.s_addr = 0;
+
+                if ((opt = option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ)))
+                    addr = option_addr(opt);
+
+                if (have_config(config, CONFIG_ADDR)) {
+                    char* addrs = inet_ntoa(config->addr);
+
+                    if ((ltmp = lease_find_by_addr(config->addr)) && ltmp != lease &&
+                        !config_has_mac(config, ltmp->hwaddr, ltmp->hwaddr_len, ltmp->hwaddr_type)) {
+                        int len;
+                        unsigned char* mac =
+                            extended_hwaddr(ltmp->hwaddr_type, ltmp->hwaddr_len, ltmp->hwaddr,
+                                            ltmp->clid_len, ltmp->clid, &len);
+                        my_syslog(MS_DHCP | LOG_WARNING,
+                                  _("not using configured address %s because it is leased to %s"),
+                                  addrs, print_mac(daemon->namebuff, mac, len));
+                    } else {
+                        struct dhcp_context* tmp;
+                        for (tmp = context; tmp; tmp = tmp->current)
+                            if (context->router.s_addr == config->addr.s_addr) break;
+                        if (tmp)
+                            my_syslog(MS_DHCP | LOG_WARNING,
+                                      _("not using configured address %s because it is in use by "
+                                        "the server or relay"),
+                                      addrs);
+                        else if (have_config(config, CONFIG_DECLINED) &&
+                                 difftime(now, config->decline_time) < (float) DECLINE_BACKOFF)
+                            my_syslog(MS_DHCP | LOG_WARNING,
+                                      _("not using configured address %s because it was previously "
+                                        "declined"),
+                                      addrs);
+                        else
+                            conf = config->addr;
+                    }
+                }
+
+                if (conf.s_addr)
+                    mess->yiaddr = conf;
+                else if (lease && address_available(context, lease->addr, netid) &&
+                         !config_find_by_address(daemon->dhcp_conf, lease->addr))
+                    mess->yiaddr = lease->addr;
+                else if (opt && address_available(context, addr, netid) &&
+                         !lease_find_by_addr(addr) &&
+                         !config_find_by_address(daemon->dhcp_conf, addr))
+                    mess->yiaddr = addr;
+                else if (emac_len == 0)
+                    message = _("no unique-id");
+                else if (!address_allocate(context, &mess->yiaddr, emac, emac_len, netid, now))
+                    message = _("no address available");
+            }
+
+            log_packet("DHCPDISCOVER", opt ? option_ptr(opt, 0) : NULL, emac, emac_len, iface_name,
+                       message, mess->xid);
+
+            if (message || !(context = narrow_context(context, mess->yiaddr, netid))) return 0;
+
+            log_packet("DHCPOFFER", &mess->yiaddr, emac, emac_len, iface_name, NULL, mess->xid);
+
+            if (context->netid.net) {
+                context->netid.next = netid;
+                netid = &context->netid;
+            }
+
+            time = calc_time(context, config, option_find(mess, sz, OPTION_LEASE_TIME, 4));
+            clear_packet(mess, end);
+            option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPOFFER);
+            option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ,
+                       ntohl(server_id(context, override, fallback).s_addr));
+            option_put(mess, end, OPTION_LEASE_TIME, 4, time);
+            /* T1 and T2 are required in DHCPOFFER by HP's wacky Jetdirect client. */
+            if (time != 0xffffffff) {
+                option_put(mess, end, OPTION_T1, 4, (time / 2));
+                option_put(mess, end, OPTION_T2, 4, (time * 7) / 8);
+            }
+            do_options(context, mess, end, req_options, offer_hostname, get_domain(mess->yiaddr),
+                       domain, netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid);
+
+            return dhcp_packet_size(mess, netid, agent_id, real_end);
+
+        case DHCPREQUEST:
+            if (ignore || have_config(config, CONFIG_DISABLE)) return 0;
+            if ((opt = option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ))) {
+                /* SELECTING  or INIT_REBOOT */
+                mess->yiaddr = option_addr(opt);
+
+                /* send vendor and user class info for new or recreated lease */
+                do_classes = 1;
+
+                if ((opt = option_find(mess, sz, OPTION_SERVER_IDENTIFIER, INADDRSZ))) {
+                    /* SELECTING */
+                    selecting = 1;
+
+                    if (override.s_addr != 0) {
+                        if (option_addr(opt).s_addr != override.s_addr) return 0;
+                    } else {
+                        for (; context; context = context->current)
+                            if (context->local.s_addr == option_addr(opt).s_addr) break;
+
+                        if (!context) {
+                            /* In auth mode, a REQUEST sent to the wrong server
+                           should be faulted, so that the client establishes
+                           communication with us, otherwise, silently ignore. */
+                            if (!(daemon->options & OPT_AUTHORITATIVE)) return 0;
+                            message = _("wrong server-ID");
+                        }
+                    }
+
+                    /* If a lease exists for this host and another address, squash it. */
+                    if (lease && lease->addr.s_addr != mess->yiaddr.s_addr) {
+                        lease_prune(lease, now);
+                        lease = NULL;
+                    }
+                } else {
+                    /* INIT-REBOOT */
+                    if (!lease && !(daemon->options & OPT_AUTHORITATIVE)) return 0;
+
+                    if (lease && lease->addr.s_addr != mess->yiaddr.s_addr) {
+                        message = _("wrong address");
+                        /* avoid loops when client brain-dead */
+                        lease_prune(lease, now);
+                        lease = NULL;
+                    }
+                }
+            } else {
+                /* RENEWING or REBINDING */
+                /* Check existing lease for this address.
+                   We allow it to be missing if dhcp-authoritative mode
+                   as long as we can allocate the lease now - checked below.
+                   This makes for a smooth recovery from a lost lease DB */
+                if ((lease && mess->ciaddr.s_addr != lease->addr.s_addr) ||
+                    (!lease && !(daemon->options & OPT_AUTHORITATIVE))) {
+                    message = _("lease not found");
+                    /* ensure we broadcast NAK */
+                    unicast_dest = 0;
+                }
+                /* desynchronise renewals */
+                fuzz = rand16();
+                mess->yiaddr = mess->ciaddr;
+            }
+
+            log_packet("DHCPREQUEST", &mess->yiaddr, emac, emac_len, iface_name, NULL, mess->xid);
+
+            if (!message) {
+                struct dhcp_config* addr_config;
+                struct dhcp_context* tmp = NULL;
+
+                if (have_config(config, CONFIG_ADDR))
+                    for (tmp = context; tmp; tmp = tmp->current)
+                        if (context->router.s_addr == config->addr.s_addr) break;
+
+                if (!(context = narrow_context(context, mess->yiaddr, netid))) {
+                    /* If a machine moves networks whilst it has a lease, we catch that here. */
+                    message = _("wrong network");
+                    /* ensure we broadcast NAK */
+                    unicast_dest = 0;
+                }
+
+                /* Check for renewal of a lease which is outside the allowed range. */
+                else if (!address_available(context, mess->yiaddr, netid) &&
+                         (!have_config(config, CONFIG_ADDR) ||
+                          config->addr.s_addr != mess->yiaddr.s_addr))
+                    message = _("address not available");
+
+                /* Check if a new static address has been configured. Be very sure that
+                   when the client does DISCOVER, it will get the static address, otherwise
+                   an endless protocol loop will ensue. */
+                else if (!tmp && !selecting && have_config(config, CONFIG_ADDR) &&
+                         (!have_config(config, CONFIG_DECLINED) ||
+                          difftime(now, config->decline_time) > (float) DECLINE_BACKOFF) &&
+                         config->addr.s_addr != mess->yiaddr.s_addr &&
+                         (!(ltmp = lease_find_by_addr(config->addr)) || ltmp == lease))
+                    message = _("static lease available");
+
+                /* Check to see if the address is reserved as a static address for another host */
+                else if ((addr_config = config_find_by_address(daemon->dhcp_conf, mess->yiaddr)) &&
+                         addr_config != config)
+                    message = _("address reserved");
+
+                else if (!lease && (ltmp = lease_find_by_addr(mess->yiaddr))) {
+                    /* If a host is configured with more than one MAC address, it's OK to 'nix
+                   a lease from one of it's MACs to give the address to another. */
+                    if (config &&
+                        config_has_mac(config, ltmp->hwaddr, ltmp->hwaddr_len, ltmp->hwaddr_type)) {
+                        my_syslog(MS_DHCP | LOG_INFO, _("abandoning lease to %s of %s"),
+                                  print_mac(daemon->namebuff, ltmp->hwaddr, ltmp->hwaddr_len),
+                                  inet_ntoa(ltmp->addr));
+                        lease = ltmp;
+                    } else
+                        message = _("address in use");
+                }
+
+                if (!message) {
+                    if (emac_len == 0)
+                        message = _("no unique-id");
+
+                    else if (!lease) {
+                        if ((lease = lease_allocate(mess->yiaddr)))
+                            do_classes = 1;
+                        else
+                            message = _("no leases left");
+                    }
+                }
+            }
+
+            if (message) {
+                log_packet("DHCPNAK", &mess->yiaddr, emac, emac_len, iface_name, message, mess->xid);
+
+                mess->yiaddr.s_addr = 0;
+                clear_packet(mess, end);
+                option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPNAK);
+                option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ,
+                           ntohl(server_id(context, override, fallback).s_addr));
+                option_put_string(mess, end, OPTION_MESSAGE, message, borken_opt);
+                /* This fixes a problem with the DHCP spec, broadcasting a NAK to a host on
+                   a distant subnet which unicast a REQ to us won't work. */
+                if (!unicast_dest || mess->giaddr.s_addr != 0 || mess->ciaddr.s_addr == 0 ||
+                    is_same_net(context->local, mess->ciaddr, context->netmask)) {
+                    mess->flags |= htons(0x8000); /* broadcast */
+                    mess->ciaddr.s_addr = 0;
+                }
+            } else {
+                if (do_classes) {
+                    if (mess->giaddr.s_addr) lease->giaddr = mess->giaddr;
+
+                    lease->changed = 1;
+                    /* copy user-class and vendor class into new lease, for the script */
+                    if ((opt = option_find(mess, sz, OPTION_USER_CLASS, 1))) {
+                        int len = option_len(opt);
+                        unsigned char* ucp = option_ptr(opt, 0);
+                        /* If the user-class option started as counted strings, the first byte will
+                         * be zero. */
+                        if (len != 0 && ucp[0] == 0) ucp++, len--;
+                        free(lease->userclass);
+                        if ((lease->userclass = whine_malloc(len + 1))) {
+                            memcpy(lease->userclass, ucp, len);
+                            lease->userclass[len] = 0;
+                            lease->userclass_len = len + 1;
+                        }
+                    }
+                    if ((opt = option_find(mess, sz, OPTION_VENDOR_ID, 1))) {
+                        int len = option_len(opt);
+                        unsigned char* ucp = option_ptr(opt, 0);
+                        free(lease->vendorclass);
+                        if ((lease->vendorclass = whine_malloc(len + 1))) {
+                            memcpy(lease->vendorclass, ucp, len);
+                            lease->vendorclass[len] = 0;
+                            lease->vendorclass_len = len + 1;
+                        }
+                    }
+                    if ((opt = option_find(mess, sz, OPTION_HOSTNAME, 1))) {
+                        int len = option_len(opt);
+                        unsigned char* ucp = option_ptr(opt, 0);
+                        free(lease->supplied_hostname);
+                        if ((lease->supplied_hostname = whine_malloc(len + 1))) {
+                            memcpy(lease->supplied_hostname, ucp, len);
+                            lease->supplied_hostname[len] = 0;
+                            lease->supplied_hostname_len = len + 1;
+                        }
+                    }
+                }
+
+                if (!hostname_auth && (client_hostname = host_from_dns(mess->yiaddr))) {
+                    hostname = client_hostname;
+                    hostname_auth = 1;
+                }
+
+                if (context->netid.net) {
+                    context->netid.next = netid;
+                    netid = &context->netid;
+                }
+
+                time = calc_time(context, config, option_find(mess, sz, OPTION_LEASE_TIME, 4));
+                lease_set_hwaddr(lease, mess->chaddr, clid, mess->hlen, mess->htype, clid_len);
+
+                /* if all the netids in the ignore_name list are present, ignore client-supplied name */
+                if (!hostname_auth) {
+                    for (id_list = daemon->dhcp_ignore_names; id_list; id_list = id_list->next)
+                        if ((!id_list->list) || match_netid(id_list->list, netid, 0)) break;
+                    if (id_list) hostname = NULL;
+                }
+                if (hostname) lease_set_hostname(lease, hostname, hostname_auth);
+
+                lease_set_expires(lease, time, now);
+                lease_set_interface(lease, int_index);
+
+                if (override.s_addr != 0)
+                    lease->override = override;
+                else
+                    override = lease->override;
+
+                log_packet("DHCPACK", &mess->yiaddr, emac, emac_len, iface_name, hostname,
+                           mess->xid);
+
+                clear_packet(mess, end);
+                option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
+                option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ,
+                           ntohl(server_id(context, override, fallback).s_addr));
+                option_put(mess, end, OPTION_LEASE_TIME, 4, time);
+                if (time != 0xffffffff) {
+                    while (fuzz > (time / 16)) fuzz = fuzz / 2;
+                    option_put(mess, end, OPTION_T1, 4, (time / 2) - fuzz);
+                    option_put(mess, end, OPTION_T2, 4, ((time / 8) * 7) - fuzz);
+                }
+                do_options(context, mess, end, req_options, hostname, get_domain(mess->yiaddr),
+                           domain, netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid);
+            }
+
+            return dhcp_packet_size(mess, netid, agent_id, real_end);
+
+        case DHCPINFORM:
+            if (ignore || have_config(config, CONFIG_DISABLE)) message = _("ignored");
+
+            log_packet("DHCPINFORM", &mess->ciaddr, emac, emac_len, iface_name, message, mess->xid);
+
+            if (message || mess->ciaddr.s_addr == 0) return 0;
+
+            /* For DHCPINFORM only, cope without a valid context */
+            context = narrow_context(context, mess->ciaddr, netid);
+
+            /* Find a least based on IP address if we didn't
+           get one from MAC address/client-d */
+            if (!lease && (lease = lease_find_by_addr(mess->ciaddr)) && lease->hostname)
+                hostname = lease->hostname;
+
+            if (!hostname) hostname = host_from_dns(mess->ciaddr);
+
+            log_packet("DHCPACK", &mess->ciaddr, emac, emac_len, iface_name, hostname, mess->xid);
+
+            if (context && context->netid.net) {
+                context->netid.next = netid;
+                netid = &context->netid;
+            }
+
+            if (lease) {
+                if (override.s_addr != 0)
+                    lease->override = override;
+                else
+                    override = lease->override;
+            }
+
+            clear_packet(mess, end);
+            option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
+            option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ,
+                       ntohl(server_id(context, override, fallback).s_addr));
+
+            if (lease) {
+                if (lease->expires == 0)
+                    time = 0xffffffff;
+                else
+                    time = (unsigned int) difftime(lease->expires, now);
+                option_put(mess, end, OPTION_LEASE_TIME, 4, time);
+                lease_set_interface(lease, int_index);
+            }
+
+            do_options(context, mess, end, req_options, hostname, get_domain(mess->ciaddr), domain,
+                       netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid);
+
+            *is_inform = 1; /* handle reply differently */
+            return dhcp_packet_size(mess, netid, agent_id, real_end);
+    }
+
     return 0;
-   
-  if (mess->htype == 0 && mess->hlen != 0)
-    return 0;
-
-  /* check for DHCP rather than BOOTP */
-  if ((opt = option_find(mess, sz, OPTION_MESSAGE_TYPE, 1)))
-    {
-      mess_type = option_uint(opt, 0, 1);
-
-      /* only insist on a cookie for DHCP. */
-      if (*((u32 *)&mess->options) != htonl(DHCP_COOKIE))
-	return 0;
-
-      /* two things to note here: expand_buf may move the packet,
-	 so reassign mess from daemon->packet. Also, the size
-	 sent includes the IP and UDP headers, hence the magic "-28" */
-      if ((opt = option_find(mess, sz, OPTION_MAXMESSAGE, 2)))
-	{
-	  size_t size = (size_t)option_uint(opt, 0, 2) - 28;
-	  
-	  if (size > DHCP_PACKET_MAX)
-	    size = DHCP_PACKET_MAX;
-	  else if (size < sizeof(struct dhcp_packet))
-	    size = sizeof(struct dhcp_packet);
-	  
-	  if (expand_buf(&daemon->dhcp_packet, size))
-	    {
-	      mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base;
-	      real_end = end = ((unsigned char *)mess) + size;
-	    }
-	}
-
-      /* Some buggy clients set ciaddr when they shouldn't, so clear that here since
-	 it can affect the context-determination code. */
-      if ((option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ) || mess_type == DHCPDISCOVER))
-	mess->ciaddr.s_addr = 0;
-
-      if ((opt = option_find(mess, sz, OPTION_AGENT_ID, 1)))
-	{
-	  /* Any agent-id needs to be copied back out, verbatim, as the last option
-	     in the packet. Here, we shift it to the very end of the buffer, if it doesn't
-	     get overwritten, then it will be shuffled back at the end of processing.
-	     Note that the incoming options must not be overwritten here, so there has to 
-	     be enough free space at the end of the packet to copy the option. */
-	  unsigned char *sopt;
-	  unsigned int total = option_len(opt) + 2;
-	  unsigned char *last_opt = option_find(mess, sz, OPTION_END, 0);
-	  if (last_opt && last_opt < end - total)
-	    {
-	      end -= total;
-	      agent_id = end;
-	      memcpy(agent_id, opt, total);
-	    }
-
-	  /* look for RFC3527 Link selection sub-option */
-	  if ((sopt = option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)), SUBOPT_SUBNET_SELECT, INADDRSZ)))
-	    subnet_addr = option_addr(sopt);
-
-	  /* look for RFC5107 server-identifier-override */
-	  if ((sopt = option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)), SUBOPT_SERVER_OR, INADDRSZ)))
-	    override = option_addr(sopt);
-	  
-	  /* if a circuit-id or remote-is option is provided, exact-match to options. */ 
-	  for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
-	    {
-	      int search;
-	      
-	      if (vendor->match_type == MATCH_CIRCUIT)
-		search = SUBOPT_CIRCUIT_ID;
-	      else if (vendor->match_type == MATCH_REMOTE)
-		search = SUBOPT_REMOTE_ID;
-	      else if (vendor->match_type == MATCH_SUBSCRIBER)
-		search = SUBOPT_SUBSCR_ID;
-	      else 
-		continue;
-
-	      if ((sopt = option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)), search, 1)) &&
-		  vendor->len == option_len(sopt) &&
-		  memcmp(option_ptr(sopt, 0), vendor->data, vendor->len) == 0)
-		{
-		  vendor->netid.next = netid;
-		  netid = &vendor->netid;
-		  break;
-		} 
-	    }
-	}
-
-      /* Check for RFC3011 subnet selector - only if RFC3527 one not present */
-      if (subnet_addr.s_addr == 0 && (opt = option_find(mess, sz, OPTION_SUBNET_SELECT, INADDRSZ)))
-	subnet_addr = option_addr(opt);
-      
-      /* If there is no client identifier option, use the hardware address */
-      if ((opt = option_find(mess, sz, OPTION_CLIENT_ID, 1)))
-	{
-	  clid_len = option_len(opt);
-	  clid = option_ptr(opt, 0);
-	}
-
-      /* do we have a lease in store? */
-      lease = lease_find_by_client(mess->chaddr, mess->hlen, mess->htype, clid, clid_len);
-
-      /* If this request is missing a clid, but we've seen one before, 
-	 use it again for option matching etc. */
-      if (lease && !clid && lease->clid)
-	{
-	  clid_len = lease->clid_len;
-	  clid = lease->clid;
-	}
-
-      /* find mac to use for logging and hashing */
-      emac = extended_hwaddr(mess->htype, mess->hlen, mess->chaddr, clid_len, clid, &emac_len);
-    }
-  
-  for (mac = daemon->dhcp_macs; mac; mac = mac->next)
-    if (mac->hwaddr_len == mess->hlen &&
-	(mac->hwaddr_type == mess->htype || mac->hwaddr_type == 0) &&
-	memcmp_masked(mac->hwaddr, mess->chaddr, mess->hlen, mac->mask))
-      {
-	mac->netid.next = netid;
-	netid = &mac->netid;
-      }
-  
-  /* Determine network for this packet. Our caller will have already linked all the 
-     contexts which match the addresses of the receiving interface but if the 
-     machine has an address already, or came via a relay, or we have a subnet selector, 
-     we search again. If we don't have have a giaddr or explicit subnet selector, 
-     use the ciaddr. This is necessary because a  machine which got a lease via a 
-     relay won't use the relay to renew. If matching a ciaddr fails but we have a context 
-     from the physical network, continue using that to allow correct DHCPNAK generation later. */
-  if (mess->giaddr.s_addr || subnet_addr.s_addr || mess->ciaddr.s_addr)
-    {
-      struct dhcp_context *context_tmp, *context_new = NULL;
-      struct in_addr addr;
-      int force = 0;
-      
-      if (subnet_addr.s_addr)
-	{
-	  addr = subnet_addr;
-	  force = 1;
-	}
-      else if (mess->giaddr.s_addr)
-	{
-	  addr = mess->giaddr;
-	  force = 1;
-	}
-      else
-	{
-	  /* If ciaddr is in the hardware derived set of contexts, leave that unchanged */
-	  addr = mess->ciaddr;
-	  for (context_tmp = context; context_tmp; context_tmp = context_tmp->current)
-	    if (context_tmp->netmask.s_addr && 
-		is_same_net(addr, context_tmp->start, context_tmp->netmask) &&
-		is_same_net(addr, context_tmp->end, context_tmp->netmask))
-	      {
-		context_new = context;
-		break;
-	      }
-	} 
-		
-      if (!context_new)
-	for (context_tmp = daemon->dhcp; context_tmp; context_tmp = context_tmp->next)
-	  if (context_tmp->netmask.s_addr  && 
-	      is_same_net(addr, context_tmp->start, context_tmp->netmask) &&
-	      is_same_net(addr, context_tmp->end, context_tmp->netmask))
-	    {
-	      context_tmp->current = context_new;
-	      context_new = context_tmp;
-	    }
-      
-      if (context_new || force)
-	context = context_new;
-      
-    }
-  
-  if (!context)
-    {
-//      my_syslog(MS_DHCP | LOG_WARNING, _("no address range available for DHCP request %s %s"), 
-//		subnet_addr.s_addr ? _("with subnet selector") : _("via"),
-//		subnet_addr.s_addr ? inet_ntoa(subnet_addr) : (mess->giaddr.s_addr ? inet_ntoa(mess->giaddr) : iface_name));
-      return 0;
-    }
-
-  /* keep _a_ local address available. */
-  fallback = context->local;
-  
-  if (daemon->options & OPT_LOG_OPTS)
-    {
-      struct dhcp_context *context_tmp;
-      for (context_tmp = context; context_tmp; context_tmp = context_tmp->current)
-	{
-	  strcpy(daemon->namebuff, inet_ntoa(context_tmp->start));
-	  if (context_tmp->flags & (CONTEXT_STATIC | CONTEXT_PROXY))
-	    my_syslog(MS_DHCP | LOG_INFO, _("%u Available DHCP subnet: %s/%s"),
-		      ntohl(mess->xid), daemon->namebuff, inet_ntoa(context_tmp->netmask));
-	  else
-	    my_syslog(MS_DHCP | LOG_INFO, _("%u Available DHCP range: %s -- %s"), 
-		      ntohl(mess->xid), daemon->namebuff, inet_ntoa(context_tmp->end));
-	}
-    }
-
-  mess->op = BOOTREPLY;
-  
-  config = find_config(daemon->dhcp_conf, context, clid, clid_len, 
-		       mess->chaddr, mess->hlen, mess->htype, NULL);
-
-  /* set "known" tag for known hosts */
-  if (config)
-    {
-      known_id.net = "known";
-      known_id.next = netid;
-      netid = &known_id;
-    }
-  
-  if (mess_type == 0)
-    {
-      /* BOOTP request */
-      struct dhcp_netid id, bootp_id;
-      struct in_addr *logaddr = NULL;
-
-      /* must have a MAC addr for bootp */
-      if (mess->htype == 0 || mess->hlen == 0 || (context->flags & CONTEXT_PROXY))
-	return 0;
-      
-      if (have_config(config, CONFIG_DISABLE))
-	message = _("disabled");
-
-      end = mess->options + 64; /* BOOTP vend area is only 64 bytes */
-            
-      if (have_config(config, CONFIG_NAME))
-	{
-	  hostname = config->hostname;
-	  domain = config->domain;
-	}
-
-      if (have_config(config, CONFIG_NETID))
-	{
-	  config->netid.next = netid;
-	  netid = &config->netid;
-	}
-
-      /* Match incoming filename field as a netid. */
-      if (mess->file[0])
-	{
-	  memcpy(daemon->dhcp_buff2, mess->file, sizeof(mess->file));
-	  daemon->dhcp_buff2[sizeof(mess->file) + 1] = 0; /* ensure zero term. */
-	  id.net = (char *)daemon->dhcp_buff2;
-	  id.next = netid;
-	  netid = &id;
-	}
-
-      /* Add "bootp" as a tag to allow different options, address ranges etc
-	 for BOOTP clients */
-      bootp_id.net = "bootp";
-      bootp_id.next = netid;
-      netid = &bootp_id;
-      
-      for (id_list = daemon->dhcp_ignore; id_list; id_list = id_list->next)
-	if (match_netid(id_list->list, netid, 0))
-	  message = _("ignored");
-      
-      if (!message)
-	{
-	  int nailed = 0;
-
-	  if (have_config(config, CONFIG_ADDR))
-	    {
-	      nailed = 1;
-	      logaddr = &config->addr;
-	      mess->yiaddr = config->addr;
-	      if ((lease = lease_find_by_addr(config->addr)) &&
-		  (lease->hwaddr_len != mess->hlen ||
-		   lease->hwaddr_type != mess->htype ||
-		   memcmp(lease->hwaddr, mess->chaddr, lease->hwaddr_len) != 0))
-		message = _("address in use");
-	    }
-	  else
-	    {
-	      if (!(lease = lease_find_by_client(mess->chaddr, mess->hlen, mess->htype, NULL, 0)) ||
-		  !address_available(context, lease->addr, netid))
-		{
-		   if (lease)
-		     {
-		       /* lease exists, wrong network. */
-		       lease_prune(lease, now);
-		       lease = NULL;
-		     }
-		   if (!address_allocate(context, &mess->yiaddr, mess->chaddr, mess->hlen, netid, now))
-		     message = _("no address available");
-		}
-	      else
-		mess->yiaddr = lease->addr;
-	    }
-	  
-	  if (!message && !(context = narrow_context(context, mess->yiaddr, netid)))
-	    message = _("wrong network");
-	  else if (context->netid.net)
-	    {
-	      context->netid.next = netid;
-	      netid = &context->netid;
-	    }	 
-	  
-	  if (!message && !nailed)
-	    {
-	      for (id_list = daemon->bootp_dynamic; id_list; id_list = id_list->next)
-		if ((!id_list->list) || match_netid(id_list->list, netid, 0))
-		  break;
-	      if (!id_list)
-		message = _("no address configured");
-	    }
-
-	  if (!message && 
-	      !lease && 
-	      (!(lease = lease_allocate(mess->yiaddr))))
-	    message = _("no leases left");
-	  
-	  if (!message)
-	    {
-	      logaddr = &mess->yiaddr;
-		
-	      lease_set_hwaddr(lease, mess->chaddr, NULL, mess->hlen, mess->htype, 0);
-	      if (hostname)
-		lease_set_hostname(lease, hostname, 1); 
-	      /* infinite lease unless nailed in dhcp-host line. */
-	      lease_set_expires(lease,  
-				have_config(config, CONFIG_TIME) ? config->lease_time : 0xffffffff, 
-				now); 
-	      lease_set_interface(lease, int_index);
-	      
-	      clear_packet(mess, end);
-	      do_options(context, mess, end, NULL, hostname, get_domain(mess->yiaddr), 
-			 domain, netid, subnet_addr, 0, 0, 0, NULL);
-	    }
-	}
-      
-      log_packet("BOOTP", logaddr, mess->chaddr, mess->hlen, iface_name, message, mess->xid);
-      
-      return message ? 0 : dhcp_packet_size(mess, netid, agent_id, real_end);
-    }
-      
-  if ((opt = option_find(mess, sz, OPTION_CLIENT_FQDN, 4)))
-    {
-      /* http://tools.ietf.org/wg/dhc/draft-ietf-dhc-fqdn-option/draft-ietf-dhc-fqdn-option-10.txt */
-      int len = option_len(opt);
-      char *pq = daemon->dhcp_buff;
-      unsigned char *pp, *op = option_ptr(opt, 0);
-      
-      fqdn_flags = *op;
-      len -= 3;
-      op += 3;
-      pp = op;
-      
-      /* Always force update, since the client has no way to do it itself. */
-      if (!(fqdn_flags & 0x01))
-	fqdn_flags |= 0x02;
-      
-      fqdn_flags &= ~0x08;
-      fqdn_flags |= 0x01;
-      
-      if (fqdn_flags & 0x04)
-	while (*op != 0 && ((op + (*op) + 1) - pp) < len)
-	  {
-	    memcpy(pq, op+1, *op);
-	    pq += *op;
-	    op += (*op)+1;
-	    *(pq++) = '.';
-	  }
-      else
-	{
-	  memcpy(pq, op, len);
-	  if (len > 0 && op[len-1] == 0)
-	    borken_opt = 1;
-	  pq += len + 1;
-	}
-      
-      if (pq != daemon->dhcp_buff)
-	pq--;
-      
-      *pq = 0;
-      
-      if (legal_hostname(daemon->dhcp_buff))
-	offer_hostname = client_hostname = daemon->dhcp_buff;
-    }
-  else if ((opt = option_find(mess, sz, OPTION_HOSTNAME, 1)))
-    {
-      int len = option_len(opt);
-      memcpy(daemon->dhcp_buff, option_ptr(opt, 0), len);
-      /* Microsoft clients are broken, and need zero-terminated strings
-	 in options. We detect this state here, and do the same in
-	 any options we send */
-      if (len > 0 && daemon->dhcp_buff[len-1] == 0)
-	borken_opt = 1;
-      else
-	daemon->dhcp_buff[len] = 0;
-      if (legal_hostname(daemon->dhcp_buff))
-	client_hostname = daemon->dhcp_buff;
-    }
-
-  if (client_hostname && daemon->options & OPT_LOG_OPTS)
-    my_syslog(MS_DHCP | LOG_INFO, _("%u client provides name: %s"), ntohl(mess->xid), client_hostname);
-  
-  if (have_config(config, CONFIG_NAME))
-    {
-      hostname = config->hostname;
-      domain = config->domain;
-      hostname_auth = 1;
-      /* be careful not to send an OFFER with a hostname not matching the DISCOVER. */
-      if (fqdn_flags != 0 || !client_hostname || hostname_isequal(hostname, client_hostname))
-        offer_hostname = hostname;
-    }
-  else if (client_hostname)
-    {
-      domain = strip_hostname(client_hostname);
-      
-      if (strlen(client_hostname) != 0)
-	{
-	  hostname = client_hostname;
-	  if (!config)
-	    {
-	      /* Search again now we have a hostname. 
-		 Only accept configs without CLID and HWADDR here, (they won't match)
-		 to avoid impersonation by name. */
-	      struct dhcp_config *new = find_config(daemon->dhcp_conf, context, NULL, 0,
-						    mess->chaddr, mess->hlen, 
-						    mess->htype, hostname);
-	      if (new && !have_config(new, CONFIG_CLID) && !new->hwaddr)
-		{
-		  config = new;
-		  /* set "known" tag for known hosts */
-		  known_id.net = "known";
-		  known_id.next = netid;
-		  netid = &known_id;
-		}
-	    }
-	}
-    }
-  
-  if (have_config(config, CONFIG_NETID))
-    {
-      config->netid.next = netid;
-      netid = &config->netid;
-    }
-  
-  /* dhcp-match. If we have hex-and-wildcards, look for a left-anchored match.
-     Otherwise assume the option is an array, and look for a matching element. 
-     If no data given, existance of the option is enough. */
-  for (o = daemon->dhcp_match; o; o = o->next)
-    {
-      int i, matched = 0;
-      
-      if (!(opt = option_find(mess, sz, o->opt, 1)) ||
-	  o->len > option_len(opt))
-	continue;
-      
-      if (o->len == 0)
-	matched = 1;
-      else if (o->flags & DHOPT_HEX)
-	{ 
-	  if (memcmp_masked(o->val, option_ptr(opt, 0), o->len, o->u.wildcard_mask))
-	    matched = 1;
-	}
-      else 
-	for (i = 0; i <= (option_len(opt) - o->len); ) 
-	  {
-	    if (memcmp(o->val, option_ptr(opt, i), o->len) == 0)
-	      {
-		matched = 1;
-		break;
-	      }
-
-	    if (o->flags & DHOPT_STRING)
-	      i++;
-	    else
-	      i += o->len;
-	  }
-      
-      if (matched)
-	{
-	  o->netid->next = netid;
-	  netid = o->netid;
-	}
-    }
-	
-  /* user-class options are, according to RFC3004, supposed to contain
-     a set of counted strings. Here we check that this is so (by seeing
-     if the counts are consistent with the overall option length) and if
-     so zero the counts so that we don't get spurious matches between 
-     the vendor string and the counts. If the lengths don't add up, we
-     assume that the option is a single string and non RFC3004 compliant 
-     and just do the substring match. dhclient provides these broken options.
-     The code, later, which sends user-class data to the lease-change script
-     relies on the transformation done here.
-  */
-
-  if ((opt = option_find(mess, sz, OPTION_USER_CLASS, 1)))
-    {
-      unsigned char *ucp = option_ptr(opt, 0);
-      int tmp, j;
-      for (j = 0; j < option_len(opt); j += ucp[j] + 1);
-      if (j == option_len(opt))
-	for (j = 0; j < option_len(opt); j = tmp)
-	  {
-	    tmp = j + ucp[j] + 1;
-	    ucp[j] = 0;
-	  }
-    }
-    
-  for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
-    {
-      int mopt;
-      
-      if (vendor->match_type == MATCH_VENDOR)
-	mopt = OPTION_VENDOR_ID;
-      else if (vendor->match_type == MATCH_USER)
-	mopt = OPTION_USER_CLASS; 
-      else
-	continue;
-
-      if ((opt = option_find(mess, sz, mopt, 1)))
-	{
-	  int i;
-	  for (i = 0; i <= (option_len(opt) - vendor->len); i++)
-	    if (memcmp(vendor->data, option_ptr(opt, i), vendor->len) == 0)
-	      {
-		vendor->netid.next = netid;
-		netid = &vendor->netid;
-		break;
-	      }
-	}
-    }
-
-  /* mark vendor-encapsulated options which match the client-supplied vendor class */
-  match_vendor_opts(option_find(mess, sz, OPTION_VENDOR_ID, 1), daemon->dhcp_opts);
-    
-  if (daemon->options & OPT_LOG_OPTS)
-    {
-      if (sanitise(option_find(mess, sz, OPTION_VENDOR_ID, 1), daemon->namebuff))
-	my_syslog(MS_DHCP | LOG_INFO, _("%u Vendor class: %s"), ntohl(mess->xid), daemon->namebuff);
-      if (sanitise(option_find(mess, sz, OPTION_USER_CLASS, 1), daemon->namebuff))
-	my_syslog(MS_DHCP | LOG_INFO, _("%u User class: %s"), ntohl(mess->xid), daemon->namebuff);
-    }
-
-  /* if all the netids in the ignore list are present, ignore this client */
-  for (id_list = daemon->dhcp_ignore; id_list; id_list = id_list->next)
-    if (match_netid(id_list->list, netid, 0))
-      ignore = 1;
-   
-  /* Can have setting to ignore the client ID for a particular MAC address or hostname */
-  if (have_config(config, CONFIG_NOCLID))
-    clid = NULL;
-          
-  /* Check if client is PXE client. */
-  if (daemon->enable_pxe && 
-      (opt = option_find(mess, sz, OPTION_VENDOR_ID, 9)) && 
-      strncmp(option_ptr(opt, 0), "PXEClient", 9) == 0)
-    {
-      if ((opt = option_find(mess, sz, OPTION_PXE_UUID, 17)))
-	{
-	  memcpy(pxe_uuid, option_ptr(opt, 0), 17);
-	  uuid = pxe_uuid;
-	}
-
-      /* Check if this is really a PXE bootserver request, and handle specially if so. */
-      if ((mess_type == DHCPREQUEST || mess_type == DHCPINFORM) &&
-	  (opt = option_find(mess, sz, OPTION_VENDOR_CLASS_OPT, 1)) &&
-	  (opt = option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)), SUBOPT_PXE_BOOT_ITEM, 4)))
-	{
-	  struct pxe_service *service;
-	  int type = option_uint(opt, 0, 2);
-	  int layer = option_uint(opt, 2, 2);
-	  unsigned char save71[4];
-	  struct dhcp_opt opt71;
-
-	  if (ignore)
-	    return 0;
-
-	  if (layer & 0x8000)
-	    {
-	      my_syslog(MS_DHCP | LOG_ERR, _("PXE BIS not supported"));
-	      return 0;
-	    }
-
-	  memcpy(save71, option_ptr(opt, 0), 4);
-	  
-	  for (service = daemon->pxe_services; service; service = service->next)
-	    if (service->type == type)
-	      break;
-	  
-	  if (!service || !service->basename)
-	    return 0;
-	  
-	  clear_packet(mess, end);
-	  
-	  mess->yiaddr = mess->ciaddr;
-	  mess->ciaddr.s_addr = 0;
-	  if (service->server.s_addr != 0)
-	    mess->siaddr = service->server; 
-	  else
-	    mess->siaddr = context->local; 
-	  
-	  snprintf((char *)mess->file, sizeof(mess->file), "%s.%d", service->basename, layer);
-	  option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
-	  option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, htonl(context->local.s_addr));
-	  pxe_misc(mess, end, uuid);
-	  
-	  prune_vendor_opts(netid);
-	  opt71.val = save71;
-	  opt71.opt = SUBOPT_PXE_BOOT_ITEM;
-	  opt71.len = 4;
-	  opt71.flags = DHOPT_VENDOR_MATCH;
-	  opt71.netid = NULL;
-	  opt71.next = daemon->dhcp_opts;
-	  do_encap_opts(&opt71, OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0);
-	  
-	  log_packet("PXE", &mess->yiaddr, emac, emac_len, iface_name, (char *)mess->file, mess->xid);
-	  return dhcp_packet_size(mess, netid, agent_id, real_end);	  
-	}
-      
-      if ((opt = option_find(mess, sz, OPTION_ARCH, 2)))
-	{
-	  pxearch = option_uint(opt, 0, 2);
-
-	  /* proxy DHCP here. The DHCPREQUEST stuff is for gPXE */
-	  if ((mess_type == DHCPDISCOVER || mess_type == DHCPREQUEST) && 
-	      (context->flags & CONTEXT_PROXY))
-	    {
-	      struct dhcp_boot *boot = find_boot(netid);
-
-	      mess->yiaddr.s_addr = 0;
-	      if  (mess_type == DHCPDISCOVER || mess->ciaddr.s_addr == 0)
-		{
-		  mess->ciaddr.s_addr = 0;
-		  mess->flags |= htons(0x8000); /* broadcast */
-		}
-
-	      clear_packet(mess, end);
-	      
-	      /* Provide the bootfile here, for gPXE, and in case we have no menu items
-		 and set discovery_control = 8 */
-	      if (boot)
-		{
-		  if (boot->next_server.s_addr)
-		    mess->siaddr = boot->next_server;
-		  
-		  if (boot->file)
-		    strncpy((char *)mess->file, boot->file, sizeof(mess->file)-1);
-		}
-
-	      option_put(mess, end, OPTION_MESSAGE_TYPE, 1, 
-			 mess_type == DHCPDISCOVER ? DHCPOFFER : DHCPACK);
-	      option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, htonl(context->local.s_addr));
-	      pxe_misc(mess, end, uuid);
-	      prune_vendor_opts(netid);
-	      do_encap_opts(pxe_opts(pxearch, netid), OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0);
-	      
-	      log_packet("PXE", NULL, emac, emac_len, iface_name, ignore ? "proxy" : "proxy-ignored", mess->xid);
-	      return ignore ? 0 : dhcp_packet_size(mess, netid, agent_id, real_end);	  
-	    }
-	}
-    }
-
-  /* if we're just a proxy server, go no further */
-  if (context->flags & CONTEXT_PROXY)
-    return 0;
-  
-  if ((opt = option_find(mess, sz, OPTION_REQUESTED_OPTIONS, 0)))
-    {
-      req_options = (unsigned char *)daemon->dhcp_buff2;
-      memcpy(req_options, option_ptr(opt, 0), option_len(opt));
-      req_options[option_len(opt)] = OPTION_END;
-    }
-  
-  switch (mess_type)
-    {
-    case DHCPDECLINE:
-      if (!(opt = option_find(mess, sz, OPTION_SERVER_IDENTIFIER, INADDRSZ)) ||
-	  option_addr(opt).s_addr != server_id(context, override, fallback).s_addr)
-	return 0;
-      
-      /* sanitise any message. Paranoid? Moi? */
-      sanitise(option_find(mess, sz, OPTION_MESSAGE, 1), daemon->dhcp_buff);
-      
-      if (!(opt = option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ)))
-	return 0;
-      
-      log_packet("DHCPDECLINE", option_ptr(opt, 0), emac, emac_len, iface_name, daemon->dhcp_buff, mess->xid);
-      
-      if (lease && lease->addr.s_addr == option_addr(opt).s_addr)
-	lease_prune(lease, now);
-      
-      if (have_config(config, CONFIG_ADDR) && 
-	  config->addr.s_addr == option_addr(opt).s_addr)
-	{
-	  prettyprint_time(daemon->dhcp_buff, DECLINE_BACKOFF);
-	  my_syslog(MS_DHCP | LOG_WARNING, _("disabling DHCP static address %s for %s"), 
-		    inet_ntoa(config->addr), daemon->dhcp_buff);
-	  config->flags |= CONFIG_DECLINED;
-	  config->decline_time = now;
-	}
-      else
-	/* make sure this host gets a different address next time. */
-	for (; context; context = context->current)
-	  context->addr_epoch++;
-      
-      return 0;
-
-    case DHCPRELEASE:
-      if (!(context = narrow_context(context, mess->ciaddr, netid)) ||
-	  !(opt = option_find(mess, sz, OPTION_SERVER_IDENTIFIER, INADDRSZ)) ||
-	  option_addr(opt).s_addr != server_id(context, override, fallback).s_addr)
-	return 0;
-      
-      if (lease && lease->addr.s_addr == mess->ciaddr.s_addr)
-	lease_prune(lease, now);
-      else
-	message = _("unknown lease");
-
-      log_packet("DHCPRELEASE", &mess->ciaddr, emac, emac_len, iface_name, message, mess->xid);
-	
-      return 0;
-      
-    case DHCPDISCOVER:
-      if (ignore || have_config(config, CONFIG_DISABLE))
-	{
-	  message = _("ignored");
-	  opt = NULL;
-	}
-      else 
-	{
-	  struct in_addr addr, conf;
-	  
-	  addr.s_addr = conf.s_addr = 0;
-
-	  if ((opt = option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ)))	 
-	    addr = option_addr(opt);
-	  
-	  if (have_config(config, CONFIG_ADDR))
-	    {
-	      char *addrs = inet_ntoa(config->addr);
-	      
-	      if ((ltmp = lease_find_by_addr(config->addr)) && 
-		  ltmp != lease &&
-		  !config_has_mac(config, ltmp->hwaddr, ltmp->hwaddr_len, ltmp->hwaddr_type))
-		{
-		  int len;
-		  unsigned char *mac = extended_hwaddr(ltmp->hwaddr_type, ltmp->hwaddr_len,
-						       ltmp->hwaddr, ltmp->clid_len, ltmp->clid, &len);
-		  my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it is leased to %s"),
-			    addrs, print_mac(daemon->namebuff, mac, len));
-		}
-	      else
-		{
-		  struct dhcp_context *tmp;
-		  for (tmp = context; tmp; tmp = tmp->current)
-		    if (context->router.s_addr == config->addr.s_addr)
-		      break;
-		  if (tmp)
-		    my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it is in use by the server or relay"), addrs);
-		  else if (have_config(config, CONFIG_DECLINED) &&
-			   difftime(now, config->decline_time) < (float)DECLINE_BACKOFF)
-		    my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it was previously declined"), addrs);
-		  else
-		    conf = config->addr;
-		}
-	    }
-	  
-	  if (conf.s_addr)
-	    mess->yiaddr = conf;
-	  else if (lease && 
-		   address_available(context, lease->addr, netid) && 
-		   !config_find_by_address(daemon->dhcp_conf, lease->addr))
-	    mess->yiaddr = lease->addr;
-	  else if (opt && address_available(context, addr, netid) && !lease_find_by_addr(addr) && 
-		   !config_find_by_address(daemon->dhcp_conf, addr))
-	    mess->yiaddr = addr;
-	  else if (emac_len == 0)
-	    message = _("no unique-id");
-	  else if (!address_allocate(context, &mess->yiaddr, emac, emac_len, netid, now))
-	    message = _("no address available");      
-	}
-      
-      log_packet("DHCPDISCOVER", opt ? option_ptr(opt, 0) : NULL, emac, emac_len, iface_name, message, mess->xid); 
-
-      if (message || !(context = narrow_context(context, mess->yiaddr, netid)))
-	return 0;
-
-      log_packet("DHCPOFFER" , &mess->yiaddr, emac, emac_len, iface_name, NULL, mess->xid);
-
-      if (context->netid.net)
-	{
-	  context->netid.next = netid;
-	  netid = &context->netid;
-	}
-       
-      time = calc_time(context, config, option_find(mess, sz, OPTION_LEASE_TIME, 4));
-      clear_packet(mess, end);
-      option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPOFFER);
-      option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
-      option_put(mess, end, OPTION_LEASE_TIME, 4, time);
-      /* T1 and T2 are required in DHCPOFFER by HP's wacky Jetdirect client. */
-      if (time != 0xffffffff)
-	{
-	  option_put(mess, end, OPTION_T1, 4, (time/2));
-	  option_put(mess, end, OPTION_T2, 4, (time*7)/8);
-	}
-      do_options(context, mess, end, req_options, offer_hostname, get_domain(mess->yiaddr), 
-		 domain, netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid);
-      
-      return dhcp_packet_size(mess, netid, agent_id, real_end);
-      
-    case DHCPREQUEST:
-      if (ignore || have_config(config, CONFIG_DISABLE))
-	return 0;
-      if ((opt = option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ)))
-	{
-	  /* SELECTING  or INIT_REBOOT */
-	  mess->yiaddr = option_addr(opt);
-	  
-	  /* send vendor and user class info for new or recreated lease */
-	  do_classes = 1;
-	  
-	  if ((opt = option_find(mess, sz, OPTION_SERVER_IDENTIFIER, INADDRSZ)))
-	    {
-	      /* SELECTING */
-	      selecting = 1;
-	      
-	      if (override.s_addr != 0)
-		{
-		  if (option_addr(opt).s_addr != override.s_addr)
-		    return 0;
-		}
-	      else 
-		{
-		  for (; context; context = context->current)
-		    if (context->local.s_addr == option_addr(opt).s_addr)
-		      break;
-		  
-		  if (!context)
-		    {
-		      /* In auth mode, a REQUEST sent to the wrong server
-			 should be faulted, so that the client establishes 
-			 communication with us, otherwise, silently ignore. */
-		      if (!(daemon->options & OPT_AUTHORITATIVE))
-			return 0;
-		      message = _("wrong server-ID");
-		    }
-		}
-
-	      /* If a lease exists for this host and another address, squash it. */
-	      if (lease && lease->addr.s_addr != mess->yiaddr.s_addr)
-		{
-		  lease_prune(lease, now);
-		  lease = NULL;
-		}
-	    }
-	  else
-	    {
-	      /* INIT-REBOOT */
-	      if (!lease && !(daemon->options & OPT_AUTHORITATIVE))
-		return 0;
-	      
-	      if (lease && lease->addr.s_addr != mess->yiaddr.s_addr)
-		{
-		  message = _("wrong address");
-		  /* avoid loops when client brain-dead */
-		  lease_prune(lease, now);
-		  lease = NULL;
-		}
-	    }
-	}
-      else
-	{
-	  /* RENEWING or REBINDING */ 
-	  /* Check existing lease for this address.
-	     We allow it to be missing if dhcp-authoritative mode
-	     as long as we can allocate the lease now - checked below.
-	     This makes for a smooth recovery from a lost lease DB */
-	  if ((lease && mess->ciaddr.s_addr != lease->addr.s_addr) ||
-	      (!lease && !(daemon->options & OPT_AUTHORITATIVE)))
-	    {
-	      message = _("lease not found");
-	      /* ensure we broadcast NAK */
-	      unicast_dest = 0;
-	    }
-	  /* desynchronise renewals */
-	  fuzz = rand16();
-	  mess->yiaddr = mess->ciaddr;
-	}
-      
-      log_packet("DHCPREQUEST", &mess->yiaddr, emac, emac_len, iface_name, NULL, mess->xid);
- 
-      if (!message)
-	{
-	  struct dhcp_config *addr_config;
-	  struct dhcp_context *tmp = NULL;
-	  
-	  if (have_config(config, CONFIG_ADDR))
-	    for (tmp = context; tmp; tmp = tmp->current)
-	      if (context->router.s_addr == config->addr.s_addr)
-		break;
-	  
-	  if (!(context = narrow_context(context, mess->yiaddr, netid)))
-	    {
-	      /* If a machine moves networks whilst it has a lease, we catch that here. */
-	      message = _("wrong network");
-	      /* ensure we broadcast NAK */
-	      unicast_dest = 0;
-	    }
-	  
-	  /* Check for renewal of a lease which is outside the allowed range. */
-	  else if (!address_available(context, mess->yiaddr, netid) &&
-		   (!have_config(config, CONFIG_ADDR) || config->addr.s_addr != mess->yiaddr.s_addr))
-	    message = _("address not available");
-	  
-	  /* Check if a new static address has been configured. Be very sure that
-	     when the client does DISCOVER, it will get the static address, otherwise
-	     an endless protocol loop will ensue. */
-	  else if (!tmp && !selecting &&
-		   have_config(config, CONFIG_ADDR) && 
-		   (!have_config(config, CONFIG_DECLINED) ||
-		    difftime(now, config->decline_time) > (float)DECLINE_BACKOFF) &&
-		   config->addr.s_addr != mess->yiaddr.s_addr &&
-		   (!(ltmp = lease_find_by_addr(config->addr)) || ltmp == lease))
-	    message = _("static lease available");
-
-	  /* Check to see if the address is reserved as a static address for another host */
-	  else if ((addr_config = config_find_by_address(daemon->dhcp_conf, mess->yiaddr)) && addr_config != config)
-	    message = _("address reserved");
-
-	  else if (!lease && (ltmp = lease_find_by_addr(mess->yiaddr)))
-	    {
-	      /* If a host is configured with more than one MAC address, it's OK to 'nix 
-		 a lease from one of it's MACs to give the address to another. */
-	      if (config && config_has_mac(config, ltmp->hwaddr, ltmp->hwaddr_len, ltmp->hwaddr_type))
-		{
-		  my_syslog(MS_DHCP | LOG_INFO, _("abandoning lease to %s of %s"),
-			    print_mac(daemon->namebuff, ltmp->hwaddr, ltmp->hwaddr_len), 
-			    inet_ntoa(ltmp->addr));
-		  lease = ltmp;
-		}
-	      else
-		message = _("address in use");
-	    }
-
-	  if (!message)
-	    {
-	      if (emac_len == 0)
-		message = _("no unique-id");
-	      
-	      else if (!lease)
-		{	     
-		  if ((lease = lease_allocate(mess->yiaddr)))
-		    do_classes = 1;
-		  else
-		    message = _("no leases left");
-		}
-	    }
-	}
-
-      if (message)
-	{
-	  log_packet("DHCPNAK", &mess->yiaddr, emac, emac_len, iface_name, message, mess->xid);
-	  
-	  mess->yiaddr.s_addr = 0;
-	  clear_packet(mess, end);
-	  option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPNAK);
-	  option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
-	  option_put_string(mess, end, OPTION_MESSAGE, message, borken_opt);
-	  /* This fixes a problem with the DHCP spec, broadcasting a NAK to a host on 
-	     a distant subnet which unicast a REQ to us won't work. */
-	  if (!unicast_dest || mess->giaddr.s_addr != 0 || 
-	      mess->ciaddr.s_addr == 0 || is_same_net(context->local, mess->ciaddr, context->netmask))
-	    {
-	      mess->flags |= htons(0x8000); /* broadcast */
-	      mess->ciaddr.s_addr = 0;
-	    }
-	}
-      else
-	{
-	   if (do_classes)
-	     {
-	       if (mess->giaddr.s_addr)
-		 lease->giaddr = mess->giaddr;
-	       
-	       lease->changed = 1;
-	       /* copy user-class and vendor class into new lease, for the script */
-	       if ((opt = option_find(mess, sz, OPTION_USER_CLASS, 1)))
-		 {
-		   int len = option_len(opt);
-		   unsigned char *ucp = option_ptr(opt, 0);
-		   /* If the user-class option started as counted strings, the first byte will be zero. */
-		   if (len != 0 && ucp[0] == 0)
-		     ucp++, len--;
-		   free(lease->userclass);
-		   if ((lease->userclass = whine_malloc(len+1)))
-		     {
-		       memcpy(lease->userclass, ucp, len);
-		       lease->userclass[len] = 0;
-		       lease->userclass_len = len+1;
-		     }
-		 }
-	       if ((opt = option_find(mess, sz, OPTION_VENDOR_ID, 1)))
-		 {
-		   int len = option_len(opt);
-		   unsigned char *ucp = option_ptr(opt, 0);
-		   free(lease->vendorclass);
-		   if ((lease->vendorclass = whine_malloc(len+1)))
-		     {
-		       memcpy(lease->vendorclass, ucp, len);
-		       lease->vendorclass[len] = 0;
-		       lease->vendorclass_len = len+1;
-		     }
-		 }
-	       if ((opt = option_find(mess, sz, OPTION_HOSTNAME, 1)))
-		 {
-		   int len = option_len(opt);
-		   unsigned char *ucp = option_ptr(opt, 0);
-		   free(lease->supplied_hostname);
-		   if ((lease->supplied_hostname = whine_malloc(len+1)))
-		     {
-		       memcpy(lease->supplied_hostname, ucp, len);
-		       lease->supplied_hostname[len] = 0;
-		       lease->supplied_hostname_len = len+1;
-		     }
-		 }
-	     }
-	   
-	   if (!hostname_auth && (client_hostname = host_from_dns(mess->yiaddr)))
-	     {
-	      hostname = client_hostname;
-	      hostname_auth = 1;
-	    }
-      
-	  if (context->netid.net)
-	    {
-	      context->netid.next = netid;
-	      netid = &context->netid;
-	    }
-	
-	  time = calc_time(context, config, option_find(mess, sz, OPTION_LEASE_TIME, 4));
-	  lease_set_hwaddr(lease, mess->chaddr, clid, mess->hlen, mess->htype, clid_len);
-	   
-	  /* if all the netids in the ignore_name list are present, ignore client-supplied name */
-	  if (!hostname_auth)
-	    {
-	      for (id_list = daemon->dhcp_ignore_names; id_list; id_list = id_list->next)
-		if ((!id_list->list) || match_netid(id_list->list, netid, 0))
-		  break;
-	      if (id_list)
-		hostname = NULL;
-	    }
-	  if (hostname)
-	    lease_set_hostname(lease, hostname, hostname_auth);
-	  
-	  lease_set_expires(lease, time, now);
-	  lease_set_interface(lease, int_index);
-
-	  if (override.s_addr != 0)
-	    lease->override = override;
-	  else
-	    override = lease->override;
-
-	  log_packet("DHCPACK", &mess->yiaddr, emac, emac_len, iface_name, hostname, mess->xid);  
-	  
-	  clear_packet(mess, end);
-	  option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
-	  option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
-	  option_put(mess, end, OPTION_LEASE_TIME, 4, time);
-	  if (time != 0xffffffff)
-	    {
-	      while (fuzz > (time/16))
-		fuzz = fuzz/2; 
-	      option_put(mess, end, OPTION_T1, 4, (time/2) - fuzz);
-	      option_put(mess, end, OPTION_T2, 4, ((time/8)*7) - fuzz);
-	    }
-	  do_options(context, mess, end, req_options, hostname, get_domain(mess->yiaddr), 
-		     domain, netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid);
-	}
-
-      return dhcp_packet_size(mess, netid, agent_id, real_end); 
-      
-    case DHCPINFORM:
-      if (ignore || have_config(config, CONFIG_DISABLE))
-	message = _("ignored");
-      
-      log_packet("DHCPINFORM", &mess->ciaddr, emac, emac_len, iface_name, message, mess->xid);
-     
-      if (message || mess->ciaddr.s_addr == 0)
-	return 0;
-
-      /* For DHCPINFORM only, cope without a valid context */
-      context = narrow_context(context, mess->ciaddr, netid);
-      
-      /* Find a least based on IP address if we didn't
-	 get one from MAC address/client-d */
-      if (!lease &&
-	  (lease = lease_find_by_addr(mess->ciaddr)) && 
-	  lease->hostname)
-	hostname = lease->hostname;
-      
-      if (!hostname)
-	hostname = host_from_dns(mess->ciaddr);
-
-      log_packet("DHCPACK", &mess->ciaddr, emac, emac_len, iface_name, hostname, mess->xid);
-      
-      if (context && context->netid.net)
-	{
-	  context->netid.next = netid;
-	  netid = &context->netid;
-	}
-      
-      if (lease)
-	{
-	  if (override.s_addr != 0)
-	    lease->override = override;
-	  else
-	    override = lease->override;
-	}
-
-      clear_packet(mess, end);
-      option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
-      option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
-      
-      if (lease)
-	{
-	  if (lease->expires == 0)
-	    time = 0xffffffff;
-	  else
-	    time = (unsigned int)difftime(lease->expires, now);
-	  option_put(mess, end, OPTION_LEASE_TIME, 4, time);
-	  lease_set_interface(lease, int_index);
-	}
-
-      do_options(context, mess, end, req_options, hostname, get_domain(mess->ciaddr),
-		 domain, netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid);
-      
-      *is_inform = 1; /* handle reply differently */
-      return dhcp_packet_size(mess, netid, agent_id, real_end); 
-    }
-  
-  return 0;
 }
 
 /* find a good value to use as MAC address for logging and address-allocation hashing.
    This is normally just the chaddr field from the DHCP packet,
-   but eg Firewire will have hlen == 0 and use the client-id instead. 
+   but eg Firewire will have hlen == 0 and use the client-id instead.
    This could be anything, but will normally be EUI64 for Firewire.
    We assume that if the first byte of the client-id equals the htype byte
-   then the client-id is using the usual encoding and use the rest of the 
+   then the client-id is using the usual encoding and use the rest of the
    client-id: if not we can use the whole client-id. This should give
    sane MAC address logs. */
-unsigned char *extended_hwaddr(int hwtype, int hwlen, unsigned char *hwaddr, 
-				      int clid_len, unsigned char *clid, int *len_out)
-{
-  if (hwlen == 0 && clid && clid_len > 3)
-    {
-      if (clid[0]  == hwtype)
-	{
-	  *len_out = clid_len - 1 ;
-	  return clid + 1;
-	}
+unsigned char* extended_hwaddr(int hwtype, int hwlen, unsigned char* hwaddr, int clid_len,
+                               unsigned char* clid, int* len_out) {
+    if (hwlen == 0 && clid && clid_len > 3) {
+        if (clid[0] == hwtype) {
+            *len_out = clid_len - 1;
+            return clid + 1;
+        }
 
 #if defined(ARPHRD_EUI64) && defined(ARPHRD_IEEE1394)
-      if (clid[0] ==  ARPHRD_EUI64 && hwtype == ARPHRD_IEEE1394)
-	{
-	  *len_out = clid_len - 1 ;
-	  return clid + 1;
-	}
+        if (clid[0] == ARPHRD_EUI64 && hwtype == ARPHRD_IEEE1394) {
+            *len_out = clid_len - 1;
+            return clid + 1;
+        }
 #endif
-      
-      *len_out = clid_len;
-      return clid;
-    }
-  
-  *len_out = hwlen;
-  return hwaddr;
-}
 
-static unsigned int calc_time(struct dhcp_context *context, struct dhcp_config *config, unsigned char *opt)
-{
-  unsigned int time = have_config(config, CONFIG_TIME) ? config->lease_time : context->lease_time;
-  
-  if (opt)
-    { 
-      unsigned int req_time = option_uint(opt, 0, 4);
-      if (req_time < 120 )
-	req_time = 120; /* sanity */
-      if (time == 0xffffffff || (req_time != 0xffffffff && req_time < time))
-	time = req_time;
+        *len_out = clid_len;
+        return clid;
     }
 
-  return time;
+    *len_out = hwlen;
+    return hwaddr;
 }
 
-static struct in_addr server_id(struct dhcp_context *context, struct in_addr override, struct in_addr fallback)
-{
-  if (override.s_addr != 0)
-    return override;
-  else if (context)
-    return context->local;
-  else
-    return fallback;
-}
+static unsigned int calc_time(struct dhcp_context* context, struct dhcp_config* config,
+                              unsigned char* opt) {
+    unsigned int time = have_config(config, CONFIG_TIME) ? config->lease_time : context->lease_time;
 
-static int sanitise(unsigned char *opt, char *buf)
-{
-  char *p;
-  int i;
-  
-  *buf = 0;
-  
-  if (!opt)
-    return 0;
-
-  p = option_ptr(opt, 0);
-
-  for (i = option_len(opt); i > 0; i--)
-    {
-      char c = *p++;
-      if (isprint((int)c))
-	*buf++ = c;
+    if (opt) {
+        unsigned int req_time = option_uint(opt, 0, 4);
+        if (req_time < 120) req_time = 120; /* sanity */
+        if (time == 0xffffffff || (req_time != 0xffffffff && req_time < time)) time = req_time;
     }
-  *buf = 0; /* add terminator */
-  
-  return 1;
+
+    return time;
 }
 
-static void log_packet(char *type, void *addr, unsigned char *ext_mac, 
-		       int mac_len, char *interface, char *string, u32 xid)
-{
-  struct in_addr a;
- 
-  /* addr may be misaligned */
-  if (addr)
-    memcpy(&a, addr, sizeof(a));
-  
-  print_mac(daemon->namebuff, ext_mac, mac_len);
-  
-  if(daemon->options & OPT_LOG_OPTS)
-     my_syslog(MS_DHCP | LOG_INFO, "%u %s(%s) %s%s%s %s",
-	       ntohl(xid), 
-	       type,
-	       interface, 
-	       addr ? inet_ntoa(a) : "",
-	       addr ? " " : "",
-	       daemon->namebuff,
-	       string ? string : "");
-  else
-    my_syslog(MS_DHCP | LOG_INFO, "%s(%s) %s%s%s %s",
-	      type,
-	      interface, 
-	      addr ? inet_ntoa(a) : "",
-	      addr ? " " : "",
-	      daemon->namebuff,
-	      string ? string : "");
+static struct in_addr server_id(struct dhcp_context* context, struct in_addr override,
+                                struct in_addr fallback) {
+    if (override.s_addr != 0)
+        return override;
+    else if (context)
+        return context->local;
+    else
+        return fallback;
 }
 
-static void log_options(unsigned char *start, u32 xid)
-{
-  while (*start != OPTION_END)
-    {
-      int is_ip, is_name, i;
-      char *text = option_string(start[0], &is_ip, &is_name);
-      unsigned char trunc = option_len(start);
-      
-      if (is_ip)
-	for (daemon->namebuff[0]= 0, i = 0; i <= trunc - INADDRSZ; i += INADDRSZ) 
-	  {
-	    if (i != 0)
-	      strncat(daemon->namebuff, ", ", 256 - strlen(daemon->namebuff));
-	    strncat(daemon->namebuff, inet_ntoa(option_addr_arr(start, i)), 256 - strlen(daemon->namebuff));
-	  }
-      else if (!is_name || !sanitise(start, daemon->namebuff))
-	{
-	  if (trunc > 13)
-	    trunc = 13;
-	  print_mac(daemon->namebuff, option_ptr(start, 0), trunc);
-	}
-      
-      my_syslog(MS_DHCP | LOG_INFO, "%u sent size:%3d option:%3d%s%s%s%s%s", 
-		ntohl(xid), option_len(start), start[0],
-		text ? ":" : "", text ? text : "",
-		trunc == 0 ? "" : "  ",
-		trunc == 0 ? "" : daemon->namebuff,
-		trunc == option_len(start) ? "" : "...");
-      start += start[1] + 2;
+static int sanitise(unsigned char* opt, char* buf) {
+    char* p;
+    int i;
+
+    *buf = 0;
+
+    if (!opt) return 0;
+
+    p = option_ptr(opt, 0);
+
+    for (i = option_len(opt); i > 0; i--) {
+        char c = *p++;
+        if (isprint((int) c)) *buf++ = c;
+    }
+    *buf = 0; /* add terminator */
+
+    return 1;
+}
+
+static void log_packet(char* type, void* addr, unsigned char* ext_mac, int mac_len, char* interface,
+                       char* string, u32 xid) {
+    struct in_addr a;
+
+    /* addr may be misaligned */
+    if (addr) memcpy(&a, addr, sizeof(a));
+
+    print_mac(daemon->namebuff, ext_mac, mac_len);
+
+    if (daemon->options & OPT_LOG_OPTS)
+        my_syslog(MS_DHCP | LOG_INFO, "%u %s(%s) %s%s%s %s", ntohl(xid), type, interface,
+                  addr ? inet_ntoa(a) : "", addr ? " " : "", daemon->namebuff, string ? string : "");
+    else
+        my_syslog(MS_DHCP | LOG_INFO, "%s(%s) %s%s%s %s", type, interface, addr ? inet_ntoa(a) : "",
+                  addr ? " " : "", daemon->namebuff, string ? string : "");
+}
+
+static void log_options(unsigned char* start, u32 xid) {
+    while (*start != OPTION_END) {
+        int is_ip, is_name, i;
+        char* text = option_string(start[0], &is_ip, &is_name);
+        unsigned char trunc = option_len(start);
+
+        if (is_ip)
+            for (daemon->namebuff[0] = 0, i = 0; i <= trunc - INADDRSZ; i += INADDRSZ) {
+                if (i != 0) strncat(daemon->namebuff, ", ", 256 - strlen(daemon->namebuff));
+                strncat(daemon->namebuff, inet_ntoa(option_addr_arr(start, i)),
+                        256 - strlen(daemon->namebuff));
+            }
+        else if (!is_name || !sanitise(start, daemon->namebuff)) {
+            if (trunc > 13) trunc = 13;
+            print_mac(daemon->namebuff, option_ptr(start, 0), trunc);
+        }
+
+        my_syslog(MS_DHCP | LOG_INFO, "%u sent size:%3d option:%3d%s%s%s%s%s", ntohl(xid),
+                  option_len(start), start[0], text ? ":" : "", text ? text : "",
+                  trunc == 0 ? "" : "  ", trunc == 0 ? "" : daemon->namebuff,
+                  trunc == option_len(start) ? "" : "...");
+        start += start[1] + 2;
     }
 }
 
-static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt, int minsize)
-{
-  while (1) 
-    {
-      if (p > end)
-	return NULL;
-      else if (*p == OPTION_END)
-	return opt == OPTION_END ? p : NULL;
-      else if (*p == OPTION_PAD)
-	p++;
-      else 
-	{ 
-	  int opt_len;
-	  if (p > end - 2)
-	    return NULL; /* malformed packet */
-	  opt_len = option_len(p);
-	  if (p > end - (2 + opt_len))
-	    return NULL; /* malformed packet */
-	  if (*p == opt && opt_len >= minsize)
-	    return p;
-	  p += opt_len + 2;
-	}
+static unsigned char* option_find1(unsigned char* p, unsigned char* end, int opt, int minsize) {
+    while (1) {
+        if (p > end)
+            return NULL;
+        else if (*p == OPTION_END)
+            return opt == OPTION_END ? p : NULL;
+        else if (*p == OPTION_PAD)
+            p++;
+        else {
+            int opt_len;
+            if (p > end - 2) return NULL; /* malformed packet */
+            opt_len = option_len(p);
+            if (p > end - (2 + opt_len)) return NULL; /* malformed packet */
+            if (*p == opt && opt_len >= minsize) return p;
+            p += opt_len + 2;
+        }
     }
 }
- 
-static unsigned char *option_find(struct dhcp_packet *mess, size_t size, int opt_type, int minsize)
-{
-  unsigned char *ret, *overload;
-  
-  /* skip over DHCP cookie; */
-  if ((ret = option_find1(&mess->options[0] + sizeof(u32), ((unsigned char *)mess) + size, opt_type, minsize)))
-    return ret;
 
-  /* look for overload option. */
-  if (!(overload = option_find1(&mess->options[0] + sizeof(u32), ((unsigned char *)mess) + size, OPTION_OVERLOAD, 1)))
+static unsigned char* option_find(struct dhcp_packet* mess, size_t size, int opt_type, int minsize) {
+    unsigned char *ret, *overload;
+
+    /* skip over DHCP cookie; */
+    if ((ret = option_find1(&mess->options[0] + sizeof(u32), ((unsigned char*) mess) + size,
+                            opt_type, minsize)))
+        return ret;
+
+    /* look for overload option. */
+    if (!(overload = option_find1(&mess->options[0] + sizeof(u32), ((unsigned char*) mess) + size,
+                                  OPTION_OVERLOAD, 1)))
+        return NULL;
+
+    /* Can we look in filename area ? */
+    if ((overload[2] & 1) &&
+        (ret = option_find1(&mess->file[0], &mess->file[128], opt_type, minsize)))
+        return ret;
+
+    /* finally try sname area */
+    if ((overload[2] & 2) &&
+        (ret = option_find1(&mess->sname[0], &mess->sname[64], opt_type, minsize)))
+        return ret;
+
     return NULL;
-  
-  /* Can we look in filename area ? */
-  if ((overload[2] & 1) &&
-      (ret = option_find1(&mess->file[0], &mess->file[128], opt_type, minsize)))
+}
+
+static struct in_addr option_addr_arr(unsigned char* opt, int offset) {
+    /* this worries about unaligned data in the option. */
+    /* struct in_addr is network byte order */
+    struct in_addr ret;
+
+    memcpy(&ret, option_ptr(opt, offset), INADDRSZ);
+
     return ret;
+}
 
-  /* finally try sname area */
-  if ((overload[2] & 2) &&
-      (ret = option_find1(&mess->sname[0], &mess->sname[64], opt_type, minsize)))
+static struct in_addr option_addr(unsigned char* opt) {
+    return option_addr_arr(opt, 0);
+}
+
+static unsigned int option_uint(unsigned char* opt, int offset, int size) {
+    /* this worries about unaligned data and byte order */
+    unsigned int ret = 0;
+    int i;
+    unsigned char* p = option_ptr(opt, offset);
+
+    for (i = 0; i < size; i++) ret = (ret << 8) | *p++;
+
     return ret;
-
-  return NULL;
 }
 
-static struct in_addr option_addr_arr(unsigned char *opt, int offset)
-{
-  /* this worries about unaligned data in the option. */
-  /* struct in_addr is network byte order */
-  struct in_addr ret;
-
-  memcpy(&ret, option_ptr(opt, offset), INADDRSZ);
-
-  return ret;
+static unsigned char* dhcp_skip_opts(unsigned char* start) {
+    while (*start != 0) start += start[1] + 2;
+    return start;
 }
 
-static struct in_addr option_addr(unsigned char *opt)
-{
-  return option_addr_arr(opt, 0);
-}
+/* only for use when building packet: doesn't check for bad data. */
+static unsigned char* find_overload(struct dhcp_packet* mess) {
+    unsigned char* p = &mess->options[0] + sizeof(u32);
 
-static unsigned int option_uint(unsigned char *opt, int offset, int size)
-{
-  /* this worries about unaligned data and byte order */
-  unsigned int ret = 0;
-  int i;
-  unsigned char *p = option_ptr(opt, offset);
-  
-  for (i = 0; i < size; i++)
-    ret = (ret << 8) | *p++;
-
-  return ret;
-}
-
-static unsigned char *dhcp_skip_opts(unsigned char *start)
-{
-  while (*start != 0)
-    start += start[1] + 2;
-  return start;
-}
-
-/* only for use when building packet: doesn't check for bad data. */ 
-static unsigned char *find_overload(struct dhcp_packet *mess)
-{
-  unsigned char *p = &mess->options[0] + sizeof(u32);
-  
-  while (*p != 0)
-    {
-      if (*p == OPTION_OVERLOAD)
-	return p;
-      p += p[1] + 2;
+    while (*p != 0) {
+        if (*p == OPTION_OVERLOAD) return p;
+        p += p[1] + 2;
     }
-  return NULL;
+    return NULL;
 }
 
-static size_t dhcp_packet_size(struct dhcp_packet *mess, struct dhcp_netid *netid,
-			       unsigned char *agent_id, unsigned char *real_end)
-{
-  unsigned char *p = dhcp_skip_opts(&mess->options[0] + sizeof(u32));
-  unsigned char *overload;
-  size_t ret;
-  struct dhcp_netid_list *id_list;
-  struct dhcp_netid *n;
+static size_t dhcp_packet_size(struct dhcp_packet* mess, struct dhcp_netid* netid,
+                               unsigned char* agent_id, unsigned char* real_end) {
+    unsigned char* p = dhcp_skip_opts(&mess->options[0] + sizeof(u32));
+    unsigned char* overload;
+    size_t ret;
+    struct dhcp_netid_list* id_list;
+    struct dhcp_netid* n;
 
-  /* move agent_id back down to the end of the packet */
-  if (agent_id)
-    {
-      memmove(p, agent_id, real_end - agent_id);
-      p += real_end - agent_id;
-      memset(p, 0, real_end - p); /* in case of overlap */
+    /* move agent_id back down to the end of the packet */
+    if (agent_id) {
+        memmove(p, agent_id, real_end - agent_id);
+        p += real_end - agent_id;
+        memset(p, 0, real_end - p); /* in case of overlap */
     }
-  
-  /* We do logging too */
-  if (netid && (daemon->options & OPT_LOG_OPTS))
-    {
-      char *s = daemon->namebuff;
-      for (*s = 0; netid; netid = netid->next)
-	{
-	  /* kill dupes. */
-	  for (n = netid->next; n; n = n->next)
-	    if (strcmp(netid->net, n->net) == 0)
-	      break;
-	  
-	  if (!n)
-	    {
-	      strncat (s, netid->net, (MAXDNAME-1) - strlen(s));
-	      if (netid->next)
-		strncat (s, ", ", (MAXDNAME-1) - strlen(s));
-	    }
-	}
-      my_syslog(MS_DHCP | LOG_INFO, _("%u tags: %s"), ntohl(mess->xid), s);
-    } 
-   
-  /* add END options to the regions. */
-  overload = find_overload(mess);
-  
-  if (overload && (option_uint(overload, 0, 1) & 1))
-    {
-      *dhcp_skip_opts(mess->file) = OPTION_END;
-      if (daemon->options & OPT_LOG_OPTS)
-	log_options(mess->file, mess->xid);
+
+    /* We do logging too */
+    if (netid && (daemon->options & OPT_LOG_OPTS)) {
+        char* s = daemon->namebuff;
+        for (*s = 0; netid; netid = netid->next) {
+            /* kill dupes. */
+            for (n = netid->next; n; n = n->next)
+                if (strcmp(netid->net, n->net) == 0) break;
+
+            if (!n) {
+                strncat(s, netid->net, (MAXDNAME - 1) - strlen(s));
+                if (netid->next) strncat(s, ", ", (MAXDNAME - 1) - strlen(s));
+            }
+        }
+        my_syslog(MS_DHCP | LOG_INFO, _("%u tags: %s"), ntohl(mess->xid), s);
     }
-  else if ((daemon->options & OPT_LOG_OPTS) && strlen((char *)mess->file) != 0)
-    my_syslog(MS_DHCP | LOG_INFO, _("%u bootfile name: %s"), ntohl(mess->xid), (char *)mess->file);
-  
-  if (overload && (option_uint(overload, 0, 1) & 2))
-    {
-      *dhcp_skip_opts(mess->sname) = OPTION_END;
-      if (daemon->options & OPT_LOG_OPTS)
-	log_options(mess->sname, mess->xid);
+
+    /* add END options to the regions. */
+    overload = find_overload(mess);
+
+    if (overload && (option_uint(overload, 0, 1) & 1)) {
+        *dhcp_skip_opts(mess->file) = OPTION_END;
+        if (daemon->options & OPT_LOG_OPTS) log_options(mess->file, mess->xid);
+    } else if ((daemon->options & OPT_LOG_OPTS) && strlen((char*) mess->file) != 0)
+        my_syslog(MS_DHCP | LOG_INFO, _("%u bootfile name: %s"), ntohl(mess->xid),
+                  (char*) mess->file);
+
+    if (overload && (option_uint(overload, 0, 1) & 2)) {
+        *dhcp_skip_opts(mess->sname) = OPTION_END;
+        if (daemon->options & OPT_LOG_OPTS) log_options(mess->sname, mess->xid);
+    } else if ((daemon->options & OPT_LOG_OPTS) && strlen((char*) mess->sname) != 0)
+        my_syslog(MS_DHCP | LOG_INFO, _("%u server name: %s"), ntohl(mess->xid),
+                  (char*) mess->sname);
+
+    *p++ = OPTION_END;
+
+    if (daemon->options & OPT_LOG_OPTS) {
+        if (mess->siaddr.s_addr != 0)
+            my_syslog(MS_DHCP | LOG_INFO, _("%u next server: %s"), ntohl(mess->xid),
+                      inet_ntoa(mess->siaddr));
+
+        log_options(&mess->options[0] + sizeof(u32), mess->xid);
     }
-  else if ((daemon->options & OPT_LOG_OPTS) && strlen((char *)mess->sname) != 0)
-    my_syslog(MS_DHCP | LOG_INFO, _("%u server name: %s"), ntohl(mess->xid), (char *)mess->sname);
 
+    for (id_list = daemon->force_broadcast; id_list; id_list = id_list->next)
+        if (match_netid(id_list->list, netid, 0))
+            mess->flags |= htons(0x8000); /* force broadcast */
 
-  *p++ = OPTION_END;
-  
-  if (daemon->options & OPT_LOG_OPTS)
-    {
-      if (mess->siaddr.s_addr != 0)
-	my_syslog(MS_DHCP | LOG_INFO, _("%u next server: %s"), ntohl(mess->xid), inet_ntoa(mess->siaddr));
-      
-      log_options(&mess->options[0] + sizeof(u32), mess->xid);
-    } 
-  
-  for (id_list = daemon->force_broadcast; id_list; id_list = id_list->next)
-    if (match_netid(id_list->list, netid, 0))
-      mess->flags |= htons(0x8000); /* force broadcast */
-  
-  ret = (size_t)(p - (unsigned char *)mess);
-  
-  if (ret < MIN_PACKETSZ)
-    ret = MIN_PACKETSZ;
+    ret = (size_t)(p - (unsigned char*) mess);
 
-  return ret;
+    if (ret < MIN_PACKETSZ) ret = MIN_PACKETSZ;
+
+    return ret;
 }
 
-static unsigned char *free_space(struct dhcp_packet *mess, unsigned char *end, int opt, int len)
-{
-  unsigned char *p = dhcp_skip_opts(&mess->options[0] + sizeof(u32));
-  
-  if (p + len + 3 >= end)
+static unsigned char* free_space(struct dhcp_packet* mess, unsigned char* end, int opt, int len) {
+    unsigned char* p = dhcp_skip_opts(&mess->options[0] + sizeof(u32));
+
+    if (p + len + 3 >= end)
     /* not enough space in options area, try and use overload, if poss */
     {
-      unsigned char *overload;
-      
-      if (!(overload = find_overload(mess)) &&
-	  (mess->file[0] == 0 || mess->sname[0] == 0))
-	{
-	  /* attempt to overload fname and sname areas, we've reserved space for the
-	     overflow option previuously. */
-	  overload = p;
-	  *(p++) = OPTION_OVERLOAD;
-	  *(p++) = 1;
-	}
-      
-      p = NULL;
-      
-      /* using filename field ? */
-      if (overload)
-	{
-	  if (mess->file[0] == 0)
-	    overload[2] |= 1;
-	  
-	  if (overload[2] & 1)
-	    {
-	      p = dhcp_skip_opts(mess->file);
-	      if (p + len + 3 >= mess->file + sizeof(mess->file))
-		p = NULL;
-	    }
-	  
-	  if (!p)
-	    {
-	      /* try to bring sname into play (it may be already) */
-	      if (mess->sname[0] == 0)
-		overload[2] |= 2;
-	      
-	      if (overload[2] & 2)
-		{
-		  p = dhcp_skip_opts(mess->sname);
-		  if (p + len + 3 >= mess->sname + sizeof(mess->file))
-		    p = NULL;
-		}
-	    }
-	}
-      
-      if (!p)
-	my_syslog(MS_DHCP | LOG_WARNING, _("cannot send DHCP/BOOTP option %d: no space left in packet"), opt);
-    }
- 
-  if (p)
-    {
-      *(p++) = opt;
-      *(p++) = len;
+        unsigned char* overload;
+
+        if (!(overload = find_overload(mess)) && (mess->file[0] == 0 || mess->sname[0] == 0)) {
+            /* attempt to overload fname and sname areas, we've reserved space for the
+               overflow option previuously. */
+            overload = p;
+            *(p++) = OPTION_OVERLOAD;
+            *(p++) = 1;
+        }
+
+        p = NULL;
+
+        /* using filename field ? */
+        if (overload) {
+            if (mess->file[0] == 0) overload[2] |= 1;
+
+            if (overload[2] & 1) {
+                p = dhcp_skip_opts(mess->file);
+                if (p + len + 3 >= mess->file + sizeof(mess->file)) p = NULL;
+            }
+
+            if (!p) {
+                /* try to bring sname into play (it may be already) */
+                if (mess->sname[0] == 0) overload[2] |= 2;
+
+                if (overload[2] & 2) {
+                    p = dhcp_skip_opts(mess->sname);
+                    if (p + len + 3 >= mess->sname + sizeof(mess->file)) p = NULL;
+                }
+            }
+        }
+
+        if (!p)
+            my_syslog(MS_DHCP | LOG_WARNING,
+                      _("cannot send DHCP/BOOTP option %d: no space left in packet"), opt);
     }
 
-  return p;
-}
-	      
-static void option_put(struct dhcp_packet *mess, unsigned char *end, int opt, int len, unsigned int val)
-{
-  int i;
-  unsigned char *p = free_space(mess, end, opt, len);
-  
-  if (p) 
-    for (i = 0; i < len; i++)
-      *(p++) = val >> (8 * (len - (i + 1)));
+    if (p) {
+        *(p++) = opt;
+        *(p++) = len;
+    }
+
+    return p;
 }
 
-static void option_put_string(struct dhcp_packet *mess, unsigned char *end, int opt, 
-			      char *string, int null_term)
-{
-  unsigned char *p;
-  size_t len = strlen(string);
+static void option_put(struct dhcp_packet* mess, unsigned char* end, int opt, int len,
+                       unsigned int val) {
+    int i;
+    unsigned char* p = free_space(mess, end, opt, len);
 
-  if (null_term && len != 255)
-    len++;
+    if (p)
+        for (i = 0; i < len; i++) *(p++) = val >> (8 * (len - (i + 1)));
+}
 
-  if ((p = free_space(mess, end, opt, len)))
-    memcpy(p, string, len);
+static void option_put_string(struct dhcp_packet* mess, unsigned char* end, int opt, char* string,
+                              int null_term) {
+    unsigned char* p;
+    size_t len = strlen(string);
+
+    if (null_term && len != 255) len++;
+
+    if ((p = free_space(mess, end, opt, len))) memcpy(p, string, len);
 }
 
 /* return length, note this only does the data part */
-static int do_opt(struct dhcp_opt *opt, unsigned char *p, struct dhcp_context *context, int null_term)
-{
-  int len = opt->len;
-  
-  if ((opt->flags & DHOPT_STRING) && null_term && len != 255)
-    len++;
+static int do_opt(struct dhcp_opt* opt, unsigned char* p, struct dhcp_context* context,
+                  int null_term) {
+    int len = opt->len;
 
-  if (p && len != 0)
-    {
-      if (context && (opt->flags & DHOPT_ADDR))
-	{
-	  int j;
-	  struct in_addr *a = (struct in_addr *)opt->val;
-	  for (j = 0; j < opt->len; j+=INADDRSZ, a++)
-	    {
-	      /* zero means "self" (but not in vendorclass options.) */
-	      if (a->s_addr == 0)
-		memcpy(p, &context->local, INADDRSZ);
-	      else
-		memcpy(p, a, INADDRSZ);
-	      p += INADDRSZ;
-	    }
-	}
-      else
-	memcpy(p, opt->val, len);
-    }  
-  return len;
+    if ((opt->flags & DHOPT_STRING) && null_term && len != 255) len++;
+
+    if (p && len != 0) {
+        if (context && (opt->flags & DHOPT_ADDR)) {
+            int j;
+            struct in_addr* a = (struct in_addr*) opt->val;
+            for (j = 0; j < opt->len; j += INADDRSZ, a++) {
+                /* zero means "self" (but not in vendorclass options.) */
+                if (a->s_addr == 0)
+                    memcpy(p, &context->local, INADDRSZ);
+                else
+                    memcpy(p, a, INADDRSZ);
+                p += INADDRSZ;
+            }
+        } else
+            memcpy(p, opt->val, len);
+    }
+    return len;
 }
 
-static int in_list(unsigned char *list, int opt)
-{
-  int i;
+static int in_list(unsigned char* list, int opt) {
+    int i;
 
-   /* If no requested options, send everything, not nothing. */
-  if (!list)
-    return 1;
-  
-  for (i = 0; list[i] != OPTION_END; i++)
-    if (opt == list[i])
-      return 1;
+    /* If no requested options, send everything, not nothing. */
+    if (!list) return 1;
 
-  return 0;
+    for (i = 0; list[i] != OPTION_END; i++)
+        if (opt == list[i]) return 1;
+
+    return 0;
 }
 
-static struct dhcp_opt *option_find2(struct dhcp_netid *netid, struct dhcp_opt *opts, int opt)
-{
-  struct dhcp_opt *tmp;  
-  for (tmp = opts; tmp; tmp = tmp->next)
-    if (tmp->opt == opt && !(tmp->flags & (DHOPT_ENCAPSULATE | DHOPT_VENDOR)))
-      if (match_netid(tmp->netid, netid, netid ? 0 : 1))
-	return tmp;
-	      
-  return netid ? option_find2(NULL, opts, opt) : NULL;
+static struct dhcp_opt* option_find2(struct dhcp_netid* netid, struct dhcp_opt* opts, int opt) {
+    struct dhcp_opt* tmp;
+    for (tmp = opts; tmp; tmp = tmp->next)
+        if (tmp->opt == opt && !(tmp->flags & (DHOPT_ENCAPSULATE | DHOPT_VENDOR)))
+            if (match_netid(tmp->netid, netid, netid ? 0 : 1)) return tmp;
+
+    return netid ? option_find2(NULL, opts, opt) : NULL;
 }
 
 /* mark vendor-encapsulated options which match the client-supplied  or
    config-supplied vendor class */
-static void match_vendor_opts(unsigned char *opt, struct dhcp_opt *dopt)
-{
-  for (; dopt; dopt = dopt->next)
-    {
-      dopt->flags &= ~DHOPT_VENDOR_MATCH;
-      if (opt && (dopt->flags & DHOPT_VENDOR))
-	{
-	  int i, len = 0;
-	  if (dopt->u.vendor_class)
-	    len = strlen((char *)dopt->u.vendor_class);
-	  for (i = 0; i <= (option_len(opt) - len); i++)
-	    if (len == 0 || memcmp(dopt->u.vendor_class, option_ptr(opt, i), len) == 0)
-	      {
-		dopt->flags |= DHOPT_VENDOR_MATCH;
-		break;
-	      }
-	}
+static void match_vendor_opts(unsigned char* opt, struct dhcp_opt* dopt) {
+    for (; dopt; dopt = dopt->next) {
+        dopt->flags &= ~DHOPT_VENDOR_MATCH;
+        if (opt && (dopt->flags & DHOPT_VENDOR)) {
+            int i, len = 0;
+            if (dopt->u.vendor_class) len = strlen((char*) dopt->u.vendor_class);
+            for (i = 0; i <= (option_len(opt) - len); i++)
+                if (len == 0 || memcmp(dopt->u.vendor_class, option_ptr(opt, i), len) == 0) {
+                    dopt->flags |= DHOPT_VENDOR_MATCH;
+                    break;
+                }
+        }
     }
 }
 
-static void do_encap_opts(struct dhcp_opt *opt, int encap, int flag,  
-			  struct dhcp_packet *mess, unsigned char *end, int null_term)
-{
-  int len, enc_len;
-  struct dhcp_opt *start;
-  unsigned char *p;
-    
-  /* find size in advance */
-  for (enc_len = 0, start = opt; opt; opt = opt->next)
-    if (opt->flags & flag)
-      {
-	int new = do_opt(opt, NULL, NULL, null_term) + 2;
-	if (enc_len + new <= 255)
-	  enc_len += new;
-	else
-	  {
-	    p = free_space(mess, end, encap, enc_len);
-	    for (; start && start != opt; start = start->next)
-	      if (p && (start->flags & flag))
-		{
-		  len = do_opt(start, p + 2, NULL, null_term);
-		  *(p++) = start->opt;
-		  *(p++) = len;
-		  p += len;
-		}
-	    enc_len = new;
-	    start = opt;
-	  }
-      }
-  
-  if (enc_len != 0 &&
-      (p = free_space(mess, end, encap, enc_len + 1)))
-    {
-      for (; start; start = start->next)
-	if (start->flags & flag)
-	  {
-	    len = do_opt(start, p + 2, NULL, null_term);
-	    *(p++) = start->opt;
-	    *(p++) = len;
-	    p += len;
-	  }
-      *p = OPTION_END;
+static void do_encap_opts(struct dhcp_opt* opt, int encap, int flag, struct dhcp_packet* mess,
+                          unsigned char* end, int null_term) {
+    int len, enc_len;
+    struct dhcp_opt* start;
+    unsigned char* p;
+
+    /* find size in advance */
+    for (enc_len = 0, start = opt; opt; opt = opt->next)
+        if (opt->flags & flag) {
+            int new = do_opt(opt, NULL, NULL, null_term) + 2;
+            if (enc_len + new <= 255)
+                enc_len += new;
+            else {
+                p = free_space(mess, end, encap, enc_len);
+                for (; start && start != opt; start = start->next)
+                    if (p && (start->flags & flag)) {
+                        len = do_opt(start, p + 2, NULL, null_term);
+                        *(p++) = start->opt;
+                        *(p++) = len;
+                        p += len;
+                    }
+                enc_len = new;
+                start = opt;
+            }
+        }
+
+    if (enc_len != 0 && (p = free_space(mess, end, encap, enc_len + 1))) {
+        for (; start; start = start->next)
+            if (start->flags & flag) {
+                len = do_opt(start, p + 2, NULL, null_term);
+                *(p++) = start->opt;
+                *(p++) = len;
+                p += len;
+            }
+        *p = OPTION_END;
     }
 }
 
-static void pxe_misc(struct dhcp_packet *mess, unsigned char *end, unsigned char *uuid)
-{
-  unsigned char *p;
+static void pxe_misc(struct dhcp_packet* mess, unsigned char* end, unsigned char* uuid) {
+    unsigned char* p;
 
-  option_put_string(mess, end, OPTION_VENDOR_ID, "PXEClient", 0);
-  if (uuid && (p = free_space(mess, end, OPTION_PXE_UUID, 17)))
-    memcpy(p, uuid, 17);
+    option_put_string(mess, end, OPTION_VENDOR_ID, "PXEClient", 0);
+    if (uuid && (p = free_space(mess, end, OPTION_PXE_UUID, 17))) memcpy(p, uuid, 17);
 }
 
-static int prune_vendor_opts(struct dhcp_netid *netid)
-{
-  int force = 0;
-  struct dhcp_opt *opt;
+static int prune_vendor_opts(struct dhcp_netid* netid) {
+    int force = 0;
+    struct dhcp_opt* opt;
 
-  /* prune vendor-encapsulated options based on netid, and look if we're forcing them to be sent */
-  for (opt = daemon->dhcp_opts; opt; opt = opt->next)
-    if (opt->flags & DHOPT_VENDOR_MATCH)
-      {
-	if (!match_netid(opt->netid, netid, 1))
-	  opt->flags &= ~DHOPT_VENDOR_MATCH;
-	else if (opt->flags & DHOPT_FORCE)
-	  force = 1;
-      }
-  return force;
+    /* prune vendor-encapsulated options based on netid, and look if we're forcing them to be sent */
+    for (opt = daemon->dhcp_opts; opt; opt = opt->next)
+        if (opt->flags & DHOPT_VENDOR_MATCH) {
+            if (!match_netid(opt->netid, netid, 1))
+                opt->flags &= ~DHOPT_VENDOR_MATCH;
+            else if (opt->flags & DHOPT_FORCE)
+                force = 1;
+        }
+    return force;
 }
 
-static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid)
-{
-#define NUM_OPTS 4  
+static struct dhcp_opt* pxe_opts(int pxe_arch, struct dhcp_netid* netid) {
+#define NUM_OPTS 4
 
-  unsigned  char *p, *q;
-  struct pxe_service *service;
-  static struct dhcp_opt *o, *ret;
-  int i, j = NUM_OPTS - 1;
-  
-  /* We pass back references to these, hence they are declared static */
-  static unsigned char discovery_control;
-  static unsigned char fake_prompt[] = { 0, 'P', 'X', 'E' }; 
-  static struct dhcp_opt *fake_opts = NULL;
-  
-  /* We are found by broadcast, so disable multicast. It gets switched on again
-     if we point to other servers and don't give a unicast address. Note that
-     we don't provide our own address for services we are the boot server for because unicast 
-     discovery is to port 4011 and we don't listen there. If you are using proxy DHCP 
-     and DHCP relays, the relay will need to forward to the proxy too. */
-  discovery_control = 2;
-  
-  ret = daemon->dhcp_opts;
-  
-  if (!fake_opts && !(fake_opts = whine_malloc(NUM_OPTS * sizeof(struct dhcp_opt))))
+    unsigned char *p, *q;
+    struct pxe_service* service;
+    static struct dhcp_opt *o, *ret;
+    int i, j = NUM_OPTS - 1;
+
+    /* We pass back references to these, hence they are declared static */
+    static unsigned char discovery_control;
+    static unsigned char fake_prompt[] = {0, 'P', 'X', 'E'};
+    static struct dhcp_opt* fake_opts = NULL;
+
+    /* We are found by broadcast, so disable multicast. It gets switched on again
+       if we point to other servers and don't give a unicast address. Note that
+       we don't provide our own address for services we are the boot server for because unicast
+       discovery is to port 4011 and we don't listen there. If you are using proxy DHCP
+       and DHCP relays, the relay will need to forward to the proxy too. */
+    discovery_control = 2;
+
+    ret = daemon->dhcp_opts;
+
+    if (!fake_opts && !(fake_opts = whine_malloc(NUM_OPTS * sizeof(struct dhcp_opt)))) return ret;
+
+    for (i = 0; i < NUM_OPTS; i++) {
+        fake_opts[i].flags = DHOPT_VENDOR_MATCH;
+        fake_opts[i].netid = NULL;
+        fake_opts[i].next = i == (NUM_OPTS - 1) ? ret : &fake_opts[i + 1];
+    }
+
+    /* create the data for the PXE_MENU and PXE_SERVERS options. */
+    p = (unsigned char*) daemon->dhcp_buff;
+    q = (unsigned char*) daemon->dhcp_buff2;
+
+    for (i = 0, service = daemon->pxe_services; service; service = service->next)
+        if (pxe_arch == service->CSA && match_netid(service->netid, netid, 1)) {
+            size_t len = strlen(service->menu);
+            /* opt 43 max size is 255. encapsulated option has type and length
+               bytes, so its max size is 253. */
+            if (p - (unsigned char*) daemon->dhcp_buff + len + 3 < 253) {
+                *(p++) = service->type >> 8;
+                *(p++) = service->type;
+                *(p++) = len;
+                memcpy(p, service->menu, len);
+                p += len;
+                i++;
+            } else {
+            toobig:
+                my_syslog(MS_DHCP | LOG_ERR, _("PXE menu too large"));
+                return daemon->dhcp_opts;
+            }
+
+            if (!service->basename) {
+                if (service->server.s_addr != 0) {
+                    if (q - (unsigned char*) daemon->dhcp_buff2 + 3 + INADDRSZ >= 253) goto toobig;
+
+                    /* Boot service with known address - give it */
+                    *(q++) = service->type >> 8;
+                    *(q++) = service->type;
+                    *(q++) = 1;
+                    /* dest misaligned */
+                    memcpy(q, &service->server.s_addr, INADDRSZ);
+                    q += INADDRSZ;
+                } else if (service->type != 0)
+                    /* We're not supplying a server, so let the client multicast.
+                   type zero is "local boot" so no need for M/C on that. */
+                    discovery_control = 0;
+            }
+        }
+
+    /* if no prompt, wait forever if there's a choice */
+    fake_prompt[0] = (i > 1) ? 255 : 0;
+
+    if (i == 0)
+        discovery_control = 8; /* no menu - just use use mess->filename */
+    else {
+        ret = &fake_opts[j--];
+        ret->len = p - (unsigned char*) daemon->dhcp_buff;
+        ret->val = (unsigned char*) daemon->dhcp_buff;
+        ret->opt = SUBOPT_PXE_MENU;
+
+        if (q - (unsigned char*) daemon->dhcp_buff2 != 0) {
+            ret = &fake_opts[j--];
+            ret->len = q - (unsigned char*) daemon->dhcp_buff2;
+            ret->val = (unsigned char*) daemon->dhcp_buff2;
+            ret->opt = SUBOPT_PXE_SERVERS;
+        }
+    }
+
+    for (o = daemon->dhcp_opts; o; o = o->next)
+        if ((o->flags & DHOPT_VENDOR_MATCH) && o->opt == SUBOPT_PXE_MENU_PROMPT) break;
+
+    if (!o) {
+        ret = &fake_opts[j--];
+        ret->len = sizeof(fake_prompt);
+        ret->val = fake_prompt;
+        ret->opt = SUBOPT_PXE_MENU_PROMPT;
+    }
+
+    if (discovery_control != 0) {
+        ret = &fake_opts[j--];
+        ret->len = 1;
+        ret->opt = SUBOPT_PXE_DISCOVERY;
+        ret->val = &discovery_control;
+    }
+
     return ret;
-
-  for (i = 0; i < NUM_OPTS; i++)
-    {
-      fake_opts[i].flags = DHOPT_VENDOR_MATCH;
-      fake_opts[i].netid = NULL;
-      fake_opts[i].next = i == (NUM_OPTS - 1) ? ret : &fake_opts[i+1];
-    }
-  
-  /* create the data for the PXE_MENU and PXE_SERVERS options. */
-  p = (unsigned char *)daemon->dhcp_buff;
-  q = (unsigned char *)daemon->dhcp_buff2;
-
-  for (i = 0, service = daemon->pxe_services; service; service = service->next)
-    if (pxe_arch == service->CSA && match_netid(service->netid, netid, 1))
-      {
-	size_t len = strlen(service->menu);
-	/* opt 43 max size is 255. encapsulated option has type and length
-	   bytes, so its max size is 253. */
-	if (p - (unsigned char *)daemon->dhcp_buff + len + 3 < 253)
-	  {
-	    *(p++) = service->type >> 8;
-	    *(p++) = service->type;
-	    *(p++) = len;
-	    memcpy(p, service->menu, len);
-	    p += len;
-	    i++;
-	  }
-	else
-	  {
-	  toobig:
-	    my_syslog(MS_DHCP | LOG_ERR, _("PXE menu too large"));
-	    return daemon->dhcp_opts;
-	  }
-	
-	if (!service->basename)
-	  {
-	    if (service->server.s_addr != 0)
-	      {
-		if (q - (unsigned char *)daemon->dhcp_buff2 + 3 + INADDRSZ >= 253)
-		  goto toobig;
-		
-		/* Boot service with known address - give it */
-		*(q++) = service->type >> 8;
-		*(q++) = service->type;
-		*(q++) = 1;
-		/* dest misaligned */
-		memcpy(q, &service->server.s_addr, INADDRSZ);
-		q += INADDRSZ;
-	      }
-	    else if (service->type != 0)
-	      /* We're not supplying a server, so let the client multicast.
-		 type zero is "local boot" so no need for M/C on that. */
-	      discovery_control = 0;
-	  }	  
-      }
-
-  /* if no prompt, wait forever if there's a choice */
-  fake_prompt[0] = (i > 1) ? 255 : 0;
-  
-  if (i == 0)
-    discovery_control = 8; /* no menu - just use use mess->filename */
-  else
-    {
-      ret = &fake_opts[j--];
-      ret->len = p - (unsigned char *)daemon->dhcp_buff;
-      ret->val = (unsigned char *)daemon->dhcp_buff;
-      ret->opt = SUBOPT_PXE_MENU;
-
-      if (q - (unsigned char *)daemon->dhcp_buff2 != 0)
-	{
-	  ret = &fake_opts[j--]; 
-	  ret->len = q - (unsigned char *)daemon->dhcp_buff2;
-	  ret->val = (unsigned char *)daemon->dhcp_buff2;
-	  ret->opt = SUBOPT_PXE_SERVERS;
-	}
-    }
-
-  for (o = daemon->dhcp_opts; o; o = o->next)
-    if ((o->flags & DHOPT_VENDOR_MATCH) && o->opt == SUBOPT_PXE_MENU_PROMPT)
-      break;
-  
-  if (!o)
-    {
-      ret = &fake_opts[j--]; 
-      ret->len = sizeof(fake_prompt);
-      ret->val = fake_prompt;
-      ret->opt = SUBOPT_PXE_MENU_PROMPT;
-    }
-  
-  if (discovery_control != 0)
-    {
-      ret = &fake_opts[j--]; 
-      ret->len = 1;
-      ret->opt = SUBOPT_PXE_DISCOVERY;
-      ret->val= &discovery_control;
-    }
-
-  return ret;
-}
-  
-static void clear_packet(struct dhcp_packet *mess, unsigned char *end)
-{
-  memset(mess->sname, 0, sizeof(mess->sname));
-  memset(mess->file, 0, sizeof(mess->file));
-  memset(&mess->options[0] + sizeof(u32), 0, end - (&mess->options[0] + sizeof(u32)));
-  mess->siaddr.s_addr = 0;
 }
 
-struct dhcp_boot *find_boot(struct dhcp_netid *netid)
-{
-  struct dhcp_boot *boot;
+static void clear_packet(struct dhcp_packet* mess, unsigned char* end) {
+    memset(mess->sname, 0, sizeof(mess->sname));
+    memset(mess->file, 0, sizeof(mess->file));
+    memset(&mess->options[0] + sizeof(u32), 0, end - (&mess->options[0] + sizeof(u32)));
+    mess->siaddr.s_addr = 0;
+}
 
-  /* decide which dhcp-boot option we're using */
-  for (boot = daemon->boot_config; boot; boot = boot->next)
-    if (match_netid(boot->netid, netid, 0))
-      break;
-  if (!boot)
-    /* No match, look for one without a netid */
+struct dhcp_boot* find_boot(struct dhcp_netid* netid) {
+    struct dhcp_boot* boot;
+
+    /* decide which dhcp-boot option we're using */
     for (boot = daemon->boot_config; boot; boot = boot->next)
-      if (match_netid(boot->netid, netid, 1))
-	break;
+        if (match_netid(boot->netid, netid, 0)) break;
+    if (!boot) /* No match, look for one without a netid */
+        for (boot = daemon->boot_config; boot; boot = boot->next)
+            if (match_netid(boot->netid, netid, 1)) break;
 
-  return boot;
+    return boot;
 }
 
-static void do_options(struct dhcp_context *context,
-		       struct dhcp_packet *mess,
-		       unsigned char *end, 
-		       unsigned char *req_options,
-		       char *hostname, 
-		       char *domain, char *config_domain,
-		       struct dhcp_netid *netid,
-		       struct in_addr subnet_addr,
-		       unsigned char fqdn_flags,
-		       int null_term, int pxe_arch,
-		       unsigned char *uuid)
-{
-  struct dhcp_opt *opt, *config_opts = daemon->dhcp_opts;
-  struct dhcp_boot *boot;
-  unsigned char *p;
-  int i, len, force_encap = 0;
-  unsigned char f0 = 0, s0 = 0;
-  int done_file = 0, done_server = 0;
+static void do_options(struct dhcp_context* context, struct dhcp_packet* mess, unsigned char* end,
+                       unsigned char* req_options, char* hostname, char* domain,
+                       char* config_domain, struct dhcp_netid* netid, struct in_addr subnet_addr,
+                       unsigned char fqdn_flags, int null_term, int pxe_arch, unsigned char* uuid) {
+    struct dhcp_opt *opt, *config_opts = daemon->dhcp_opts;
+    struct dhcp_boot* boot;
+    unsigned char* p;
+    int i, len, force_encap = 0;
+    unsigned char f0 = 0, s0 = 0;
+    int done_file = 0, done_server = 0;
 
-  if (config_domain && (!domain || !hostname_isequal(domain, config_domain)))
-    my_syslog(MS_DHCP | LOG_WARNING, _("Ignoring domain %s for DHCP host name %s"), config_domain, hostname);
-  
-  /* logging */
-  if ((daemon->options & OPT_LOG_OPTS) && req_options)
-    {
-      char *q = daemon->namebuff;
-      for (i = 0; req_options[i] != OPTION_END; i++)
-	{
-	  char *s = option_string(req_options[i], NULL, NULL);
-	  q += snprintf(q, MAXDNAME - (q - daemon->namebuff),
-			"%d%s%s%s", 
-			req_options[i],
-			s ? ":" : "",
-			s ? s : "", 
-			req_options[i+1] == OPTION_END ? "" : ", ");
-	  if (req_options[i+1] == OPTION_END || (q - daemon->namebuff) > 40)
-	    {
-	      q = daemon->namebuff;
-	      my_syslog(MS_DHCP | LOG_INFO, _("%u requested options: %s"), ntohl(mess->xid), daemon->namebuff);
-	    }
-	}
+    if (config_domain && (!domain || !hostname_isequal(domain, config_domain)))
+        my_syslog(MS_DHCP | LOG_WARNING, _("Ignoring domain %s for DHCP host name %s"),
+                  config_domain, hostname);
+
+    /* logging */
+    if ((daemon->options & OPT_LOG_OPTS) && req_options) {
+        char* q = daemon->namebuff;
+        for (i = 0; req_options[i] != OPTION_END; i++) {
+            char* s = option_string(req_options[i], NULL, NULL);
+            q += snprintf(q, MAXDNAME - (q - daemon->namebuff), "%d%s%s%s", req_options[i],
+                          s ? ":" : "", s ? s : "", req_options[i + 1] == OPTION_END ? "" : ", ");
+            if (req_options[i + 1] == OPTION_END || (q - daemon->namebuff) > 40) {
+                q = daemon->namebuff;
+                my_syslog(MS_DHCP | LOG_INFO, _("%u requested options: %s"), ntohl(mess->xid),
+                          daemon->namebuff);
+            }
+        }
     }
-      
-  if (context)
-    mess->siaddr = context->local;
-  
-  /* See if we can send the boot stuff as options.
-     To do this we need a requested option list, BOOTP
-     and very old DHCP clients won't have this, we also 
-     provide an manual option to disable it.
-     Some PXE ROMs have bugs (surprise!) and need zero-terminated 
-     names, so we always send those.  */
-  if ((boot = find_boot(netid)))
-    {
-      if (boot->sname)
-	{	  
-	  if (!(daemon->options & OPT_NO_OVERRIDE) &&
-	      req_options && 
-	      in_list(req_options, OPTION_SNAME))
-	    option_put_string(mess, end, OPTION_SNAME, boot->sname, 1);
-	  else
-	    strncpy((char *)mess->sname, boot->sname, sizeof(mess->sname)-1);
-	}
-      
-      if (boot->file)
-	{
-	  if (!(daemon->options & OPT_NO_OVERRIDE) &&
-	      req_options && 
-	      in_list(req_options, OPTION_FILENAME))
-	    option_put_string(mess, end, OPTION_FILENAME, boot->file, 1);
-	  else
-	    strncpy((char *)mess->file, boot->file, sizeof(mess->file)-1);
-	}
-      
-      if (boot->next_server.s_addr)
-	mess->siaddr = boot->next_server;
-    }
-  else
+
+    if (context) mess->siaddr = context->local;
+
+    /* See if we can send the boot stuff as options.
+       To do this we need a requested option list, BOOTP
+       and very old DHCP clients won't have this, we also
+       provide an manual option to disable it.
+       Some PXE ROMs have bugs (surprise!) and need zero-terminated
+       names, so we always send those.  */
+    if ((boot = find_boot(netid))) {
+        if (boot->sname) {
+            if (!(daemon->options & OPT_NO_OVERRIDE) && req_options &&
+                in_list(req_options, OPTION_SNAME))
+                option_put_string(mess, end, OPTION_SNAME, boot->sname, 1);
+            else
+                strncpy((char*) mess->sname, boot->sname, sizeof(mess->sname) - 1);
+        }
+
+        if (boot->file) {
+            if (!(daemon->options & OPT_NO_OVERRIDE) && req_options &&
+                in_list(req_options, OPTION_FILENAME))
+                option_put_string(mess, end, OPTION_FILENAME, boot->file, 1);
+            else
+                strncpy((char*) mess->file, boot->file, sizeof(mess->file) - 1);
+        }
+
+        if (boot->next_server.s_addr) mess->siaddr = boot->next_server;
+    } else
     /* Use the values of the relevant options if no dhcp-boot given and
        they're not explicitly asked for as options. OPTION_END is used
        as an internal way to specify siaddr without using dhcp-boot, for use in
        dhcp-optsfile. */
     {
-      if ((!req_options || !in_list(req_options, OPTION_FILENAME)) && mess->file[0] == 0 &&
-	  (opt = option_find2(netid, config_opts, OPTION_FILENAME)) && !(opt->flags & DHOPT_FORCE))
-	{
-	  strncpy((char *)mess->file, (char *)opt->val, sizeof(mess->file)-1);
-	  done_file = 1;
-	}
-      
-      if ((!req_options || !in_list(req_options, OPTION_SNAME)) &&
-	  (opt = option_find2(netid, config_opts, OPTION_SNAME)) && !(opt->flags & DHOPT_FORCE))
-	{
-	  strncpy((char *)mess->sname, (char *)opt->val, sizeof(mess->sname)-1);
-	  done_server = 1;
-	}
-      
-      if ((opt = option_find2(netid, config_opts, OPTION_END)))
-	mess->siaddr.s_addr = ((struct in_addr *)opt->val)->s_addr;	
-    }
-        
-  /* We don't want to do option-overload for BOOTP, so make the file and sname
-     fields look like they are in use, even when they aren't. This gets restored
-     at the end of this function. */
+        if ((!req_options || !in_list(req_options, OPTION_FILENAME)) && mess->file[0] == 0 &&
+            (opt = option_find2(netid, config_opts, OPTION_FILENAME)) &&
+            !(opt->flags & DHOPT_FORCE)) {
+            strncpy((char*) mess->file, (char*) opt->val, sizeof(mess->file) - 1);
+            done_file = 1;
+        }
 
-  if (!req_options || (daemon->options & OPT_NO_OVERRIDE))
-    {
-      f0 = mess->file[0];
-      mess->file[0] = 1;
-      s0 = mess->sname[0];
-      mess->sname[0] = 1;
-    }
-      
-  /* At this point, if mess->sname or mess->file are zeroed, they are available
-     for option overload, reserve space for the overload option. */
-  if (mess->file[0] == 0 || mess->sname[0] == 0)
-    end -= 3;
+        if ((!req_options || !in_list(req_options, OPTION_SNAME)) &&
+            (opt = option_find2(netid, config_opts, OPTION_SNAME)) && !(opt->flags & DHOPT_FORCE)) {
+            strncpy((char*) mess->sname, (char*) opt->val, sizeof(mess->sname) - 1);
+            done_server = 1;
+        }
 
-  /* rfc3011 says this doesn't need to be in the requested options list. */
-  if (subnet_addr.s_addr)
-    option_put(mess, end, OPTION_SUBNET_SELECT, INADDRSZ, ntohl(subnet_addr.s_addr));
-  
-  /* replies to DHCPINFORM may not have a valid context */
-  if (context)
-    {
-      if (!option_find2(netid, config_opts, OPTION_NETMASK))
-	option_put(mess, end, OPTION_NETMASK, INADDRSZ, ntohl(context->netmask.s_addr));
-  
-      /* May not have a "guessed" broadcast address if we got no packets via a relay
-	 from this net yet (ie just unicast renewals after a restart */
-      if (context->broadcast.s_addr &&
-	  !option_find2(netid, config_opts, OPTION_BROADCAST))
-	option_put(mess, end, OPTION_BROADCAST, INADDRSZ, ntohl(context->broadcast.s_addr));
-      
-      /* Same comments as broadcast apply, and also may not be able to get a sensible
-	 default when using subnet select.  User must configure by steam in that case. */
-      if (context->router.s_addr &&
-	  in_list(req_options, OPTION_ROUTER) &&
-	  !option_find2(netid, config_opts, OPTION_ROUTER))
-	option_put(mess, end, OPTION_ROUTER, INADDRSZ, ntohl(context->router.s_addr));
-      
-      if (in_list(req_options, OPTION_DNSSERVER) &&
-	  !option_find2(netid, config_opts, OPTION_DNSSERVER))
-	option_put(mess, end, OPTION_DNSSERVER, INADDRSZ, ntohl(context->local.s_addr));
+        if ((opt = option_find2(netid, config_opts, OPTION_END)))
+            mess->siaddr.s_addr = ((struct in_addr*) opt->val)->s_addr;
     }
 
-  if (domain && in_list(req_options, OPTION_DOMAINNAME) && 
-      !option_find2(netid, config_opts, OPTION_DOMAINNAME))
-    option_put_string(mess, end, OPTION_DOMAINNAME, domain, null_term);
- 
-  /* Note that we ignore attempts to set the fqdn using --dhc-option=81,<name> */
-  if (hostname)
-    {
-      if (in_list(req_options, OPTION_HOSTNAME) &&
-	  !option_find2(netid, config_opts, OPTION_HOSTNAME))
-	option_put_string(mess, end, OPTION_HOSTNAME, hostname, null_term);
-      
-      if (fqdn_flags != 0)
-	{
-	  len = strlen(hostname) + 3;
-	  
-	  if (fqdn_flags & 0x04)
-	    len += 2;
-	  else if (null_term)
-	    len++;
+    /* We don't want to do option-overload for BOOTP, so make the file and sname
+       fields look like they are in use, even when they aren't. This gets restored
+       at the end of this function. */
 
-	  if (domain)
-	    len += strlen(domain) + 1;
-	  
-	  if ((p = free_space(mess, end, OPTION_CLIENT_FQDN, len)))
-	    {
-	      *(p++) = fqdn_flags;
-	      *(p++) = 255;
-	      *(p++) = 255;
-
-	      if (fqdn_flags & 0x04)
-		{
-		  p = do_rfc1035_name(p, hostname);
-		  if (domain)
-		    p = do_rfc1035_name(p, domain);
-		  *p++ = 0;
-		}
-	      else
-		{
-		  memcpy(p, hostname, strlen(hostname));
-		  p += strlen(hostname);
-		  if (domain)
-		    {
-		      *(p++) = '.';
-		      memcpy(p, domain, strlen(domain));
-		      p += strlen(domain);
-		    }
-		  if (null_term)
-		    *(p++) = 0;
-		}
-	    }
-	}
-    }      
-
-  for (opt = config_opts; opt; opt = opt->next)
-    {
-      int optno = opt->opt;
-
-      /* was it asked for, or are we sending it anyway? */
-      if (!(opt->flags & DHOPT_FORCE) && !in_list(req_options, optno))
-	continue;
-      
-      /* prohibit some used-internally options */
-      if (optno == OPTION_CLIENT_FQDN ||
-	  optno == OPTION_MAXMESSAGE ||
-	  optno == OPTION_OVERLOAD ||
-	  optno == OPTION_PAD ||
-	  optno == OPTION_END)
-	continue;
-
-      if (optno == OPTION_SNAME && done_server)
-	continue;
-
-      if (optno == OPTION_FILENAME && done_file)
-	continue;
-      
-      /* netids match and not encapsulated? */
-      if (opt != option_find2(netid, config_opts, optno))
-	continue;
-      
-      /* For the options we have default values on
-	 dhc-option=<optionno> means "don't include this option"
-	 not "include a zero-length option" */
-      if (opt->len == 0 && 
-	  (optno == OPTION_NETMASK ||
-	   optno == OPTION_BROADCAST ||
-	   optno == OPTION_ROUTER ||
-	   optno == OPTION_DNSSERVER || 
-	   optno == OPTION_DOMAINNAME ||
-	   optno == OPTION_HOSTNAME))
-	continue;
-
-      /* vendor-class comes from elsewhere for PXE */
-      if (pxe_arch != -1 && optno == OPTION_VENDOR_ID)
-	continue;
-      
-      /* always force null-term for filename and servername - buggy PXE again. */
-      len = do_opt(opt, NULL, context, 
-		   (optno == OPTION_SNAME || optno == OPTION_FILENAME) ? 1 : null_term);
-
-      if ((p = free_space(mess, end, optno, len)))
-	{
-	  do_opt(opt, p, context, 
-		 (optno == OPTION_SNAME || optno == OPTION_FILENAME) ? 1 : null_term);
-	  
-	  /* If we send a vendor-id, revisit which vendor-ops we consider 
-	     it appropriate to send. */
-	  if (optno == OPTION_VENDOR_ID)
-	    match_vendor_opts(p - 2, config_opts);
-	}  
+    if (!req_options || (daemon->options & OPT_NO_OVERRIDE)) {
+        f0 = mess->file[0];
+        mess->file[0] = 1;
+        s0 = mess->sname[0];
+        mess->sname[0] = 1;
     }
 
-  /* Now send options to be encapsulated in arbitrary options, 
-     eg dhcp-option=encap:172,17,.......
-     The may be more that one "outer" to do, so group
-     all the options which match each outer in turn. */
-  for (opt = config_opts; opt; opt = opt->next)
-    opt->flags &= ~DHOPT_ENCAP_DONE;
-  
-  for (opt = config_opts; opt; opt = opt->next)
-    if ((opt->flags & (DHOPT_ENCAPSULATE | DHOPT_ENCAP_DONE)) ==  DHOPT_ENCAPSULATE)
-      {
-	struct dhcp_opt *o;
-	int found = 0;
-	
-	for (o = config_opts; o; o = o->next)
-	  {
-	    o->flags &= ~DHOPT_ENCAP_MATCH;
-	    if ((o->flags & DHOPT_ENCAPSULATE) && opt->u.encap == o->u.encap)
-	      {
-		o->flags |= DHOPT_ENCAP_DONE;
-		if (match_netid(o->netid, netid, 1) &&
-		    (o->flags & DHOPT_FORCE || in_list(req_options, o->u.encap)))
-		  {
-		    o->flags |= DHOPT_ENCAP_MATCH;
-		    found = 1;
-		  }
-	      }
-	  }
-	
-	if (found)
-	  do_encap_opts(config_opts, opt->u.encap, DHOPT_ENCAP_MATCH, mess, end, null_term);
-      }
+    /* At this point, if mess->sname or mess->file are zeroed, they are available
+       for option overload, reserve space for the overload option. */
+    if (mess->file[0] == 0 || mess->sname[0] == 0) end -= 3;
 
-  /* Must precede pxe_opts, since it overwrites req_options */
-  force_encap = prune_vendor_opts(netid);
-  if (in_list(req_options, OPTION_VENDOR_CLASS_OPT))
-    force_encap = 1;
+    /* rfc3011 says this doesn't need to be in the requested options list. */
+    if (subnet_addr.s_addr)
+        option_put(mess, end, OPTION_SUBNET_SELECT, INADDRSZ, ntohl(subnet_addr.s_addr));
 
-  if (pxe_arch != -1)
-    {
-      pxe_misc(mess, end, uuid);
-      config_opts = pxe_opts(pxe_arch, netid);
+    /* replies to DHCPINFORM may not have a valid context */
+    if (context) {
+        if (!option_find2(netid, config_opts, OPTION_NETMASK))
+            option_put(mess, end, OPTION_NETMASK, INADDRSZ, ntohl(context->netmask.s_addr));
+
+        /* May not have a "guessed" broadcast address if we got no packets via a relay
+       from this net yet (ie just unicast renewals after a restart */
+        if (context->broadcast.s_addr && !option_find2(netid, config_opts, OPTION_BROADCAST))
+            option_put(mess, end, OPTION_BROADCAST, INADDRSZ, ntohl(context->broadcast.s_addr));
+
+        /* Same comments as broadcast apply, and also may not be able to get a sensible
+       default when using subnet select.  User must configure by steam in that case. */
+        if (context->router.s_addr && in_list(req_options, OPTION_ROUTER) &&
+            !option_find2(netid, config_opts, OPTION_ROUTER))
+            option_put(mess, end, OPTION_ROUTER, INADDRSZ, ntohl(context->router.s_addr));
+
+        if (in_list(req_options, OPTION_DNSSERVER) &&
+            !option_find2(netid, config_opts, OPTION_DNSSERVER))
+            option_put(mess, end, OPTION_DNSSERVER, INADDRSZ, ntohl(context->local.s_addr));
     }
 
-  if (force_encap)
-    do_encap_opts(config_opts, OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, null_term);
-  
-   /* restore BOOTP anti-overload hack */
-  if (!req_options || (daemon->options & OPT_NO_OVERRIDE))
-    {
-      mess->file[0] = f0;
-      mess->sname[0] = s0;
+    if (domain && in_list(req_options, OPTION_DOMAINNAME) &&
+        !option_find2(netid, config_opts, OPTION_DOMAINNAME))
+        option_put_string(mess, end, OPTION_DOMAINNAME, domain, null_term);
+
+    /* Note that we ignore attempts to set the fqdn using --dhc-option=81,<name> */
+    if (hostname) {
+        if (in_list(req_options, OPTION_HOSTNAME) &&
+            !option_find2(netid, config_opts, OPTION_HOSTNAME))
+            option_put_string(mess, end, OPTION_HOSTNAME, hostname, null_term);
+
+        if (fqdn_flags != 0) {
+            len = strlen(hostname) + 3;
+
+            if (fqdn_flags & 0x04)
+                len += 2;
+            else if (null_term)
+                len++;
+
+            if (domain) len += strlen(domain) + 1;
+
+            if ((p = free_space(mess, end, OPTION_CLIENT_FQDN, len))) {
+                *(p++) = fqdn_flags;
+                *(p++) = 255;
+                *(p++) = 255;
+
+                if (fqdn_flags & 0x04) {
+                    p = do_rfc1035_name(p, hostname);
+                    if (domain) p = do_rfc1035_name(p, domain);
+                    *p++ = 0;
+                } else {
+                    memcpy(p, hostname, strlen(hostname));
+                    p += strlen(hostname);
+                    if (domain) {
+                        *(p++) = '.';
+                        memcpy(p, domain, strlen(domain));
+                        p += strlen(domain);
+                    }
+                    if (null_term) *(p++) = 0;
+                }
+            }
+        }
+    }
+
+    for (opt = config_opts; opt; opt = opt->next) {
+        int optno = opt->opt;
+
+        /* was it asked for, or are we sending it anyway? */
+        if (!(opt->flags & DHOPT_FORCE) && !in_list(req_options, optno)) continue;
+
+        /* prohibit some used-internally options */
+        if (optno == OPTION_CLIENT_FQDN || optno == OPTION_MAXMESSAGE || optno == OPTION_OVERLOAD ||
+            optno == OPTION_PAD || optno == OPTION_END)
+            continue;
+
+        if (optno == OPTION_SNAME && done_server) continue;
+
+        if (optno == OPTION_FILENAME && done_file) continue;
+
+        /* netids match and not encapsulated? */
+        if (opt != option_find2(netid, config_opts, optno)) continue;
+
+        /* For the options we have default values on
+       dhc-option=<optionno> means "don't include this option"
+       not "include a zero-length option" */
+        if (opt->len == 0 &&
+            (optno == OPTION_NETMASK || optno == OPTION_BROADCAST || optno == OPTION_ROUTER ||
+             optno == OPTION_DNSSERVER || optno == OPTION_DOMAINNAME || optno == OPTION_HOSTNAME))
+            continue;
+
+        /* vendor-class comes from elsewhere for PXE */
+        if (pxe_arch != -1 && optno == OPTION_VENDOR_ID) continue;
+
+        /* always force null-term for filename and servername - buggy PXE again. */
+        len = do_opt(opt, NULL, context,
+                     (optno == OPTION_SNAME || optno == OPTION_FILENAME) ? 1 : null_term);
+
+        if ((p = free_space(mess, end, optno, len))) {
+            do_opt(opt, p, context,
+                   (optno == OPTION_SNAME || optno == OPTION_FILENAME) ? 1 : null_term);
+
+            /* If we send a vendor-id, revisit which vendor-ops we consider
+               it appropriate to send. */
+            if (optno == OPTION_VENDOR_ID) match_vendor_opts(p - 2, config_opts);
+        }
+    }
+
+    /* Now send options to be encapsulated in arbitrary options,
+       eg dhcp-option=encap:172,17,.......
+       The may be more that one "outer" to do, so group
+       all the options which match each outer in turn. */
+    for (opt = config_opts; opt; opt = opt->next) opt->flags &= ~DHOPT_ENCAP_DONE;
+
+    for (opt = config_opts; opt; opt = opt->next)
+        if ((opt->flags & (DHOPT_ENCAPSULATE | DHOPT_ENCAP_DONE)) == DHOPT_ENCAPSULATE) {
+            struct dhcp_opt* o;
+            int found = 0;
+
+            for (o = config_opts; o; o = o->next) {
+                o->flags &= ~DHOPT_ENCAP_MATCH;
+                if ((o->flags & DHOPT_ENCAPSULATE) && opt->u.encap == o->u.encap) {
+                    o->flags |= DHOPT_ENCAP_DONE;
+                    if (match_netid(o->netid, netid, 1) &&
+                        (o->flags & DHOPT_FORCE || in_list(req_options, o->u.encap))) {
+                        o->flags |= DHOPT_ENCAP_MATCH;
+                        found = 1;
+                    }
+                }
+            }
+
+            if (found)
+                do_encap_opts(config_opts, opt->u.encap, DHOPT_ENCAP_MATCH, mess, end, null_term);
+        }
+
+    /* Must precede pxe_opts, since it overwrites req_options */
+    force_encap = prune_vendor_opts(netid);
+    if (in_list(req_options, OPTION_VENDOR_CLASS_OPT)) force_encap = 1;
+
+    if (pxe_arch != -1) {
+        pxe_misc(mess, end, uuid);
+        config_opts = pxe_opts(pxe_arch, netid);
+    }
+
+    if (force_encap)
+        do_encap_opts(config_opts, OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end,
+                      null_term);
+
+    /* restore BOOTP anti-overload hack */
+    if (!req_options || (daemon->options & OPT_NO_OVERRIDE)) {
+        mess->file[0] = f0;
+        mess->sname[0] = s0;
     }
 }
 
diff --git a/src/util.c b/src/util.c
index 9d7a055..53e3137 100644
--- a/src/util.c
+++ b/src/util.c
@@ -4,20 +4,19 @@
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; version 2 dated June, 1991, or
    (at your option) version 3 dated 29 June, 2007.
- 
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-      
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-/* The SURF random number generator was taken from djbdns-1.05, by 
+/* The SURF random number generator was taken from djbdns-1.05, by
    Daniel J Bernstein, which is public domain. */
 
-
 #include "dnsmasq.h"
 
 #include <netdb.h>
@@ -31,14 +30,12 @@
 #endif
 
 #ifdef HAVE_ARC4RANDOM
-void rand_init(void)
-{
-  return;
+void rand_init(void) {
+    return;
 }
 
-unsigned short rand16(void)
-{
-   return (unsigned short) (arc4random() >> 15);
+unsigned short rand16(void) {
+    return (unsigned short) (arc4random() >> 15);
 }
 
 #else
@@ -51,227 +48,199 @@
 static uint32 in[12];
 static uint32 out[8];
 
-void rand_init()
-{
-  int fd = open(RANDFILE, O_RDONLY);
-  
-  if (fd == -1 ||
-      !read_write(fd, (unsigned char *)&seed, sizeof(seed), 1) ||
-      !read_write(fd, (unsigned char *)&in, sizeof(in), 1))
-    die(_("failed to seed the random number generator: %s"), NULL, EC_MISC);
-  
-  close(fd);
+void rand_init() {
+    int fd = open(RANDFILE, O_RDONLY);
+
+    if (fd == -1 || !read_write(fd, (unsigned char*) &seed, sizeof(seed), 1) ||
+        !read_write(fd, (unsigned char*) &in, sizeof(in), 1))
+        die(_("failed to seed the random number generator: %s"), NULL, EC_MISC);
+
+    close(fd);
 }
 
-#define ROTATE(x,b) (((x) << (b)) | ((x) >> (32 - (b))))
-#define MUSH(i,b) x = t[i] += (((x ^ seed[i]) + sum) ^ ROTATE(x,b));
+#define ROTATE(x, b) (((x) << (b)) | ((x) >> (32 - (b))))
+#define MUSH(i, b) x = t[i] += (((x ^ seed[i]) + sum) ^ ROTATE(x, b));
 
-static void surf(void)
-{
-  uint32 t[12]; uint32 x; uint32 sum = 0;
-  int r; int i; int loop;
+static void surf(void) {
+    uint32 t[12];
+    uint32 x;
+    uint32 sum = 0;
+    int r;
+    int i;
+    int loop;
 
-  for (i = 0;i < 12;++i) t[i] = in[i] ^ seed[12 + i];
-  for (i = 0;i < 8;++i) out[i] = seed[24 + i];
-  x = t[11];
-  for (loop = 0;loop < 2;++loop) {
-    for (r = 0;r < 16;++r) {
-      sum += 0x9e3779b9;
-      MUSH(0,5) MUSH(1,7) MUSH(2,9) MUSH(3,13)
-      MUSH(4,5) MUSH(5,7) MUSH(6,9) MUSH(7,13)
-      MUSH(8,5) MUSH(9,7) MUSH(10,9) MUSH(11,13)
+    for (i = 0; i < 12; ++i) t[i] = in[i] ^ seed[12 + i];
+    for (i = 0; i < 8; ++i) out[i] = seed[24 + i];
+    x = t[11];
+    for (loop = 0; loop < 2; ++loop) {
+        for (r = 0; r < 16; ++r) {
+            sum += 0x9e3779b9;
+            MUSH(0, 5)
+            MUSH(1, 7) MUSH(2, 9) MUSH(3, 13) MUSH(4, 5) MUSH(5, 7) MUSH(6, 9) MUSH(7, 13)
+                MUSH(8, 5) MUSH(9, 7) MUSH(10, 9) MUSH(11, 13)
+        }
+        for (i = 0; i < 8; ++i) out[i] ^= t[i + 4];
     }
-    for (i = 0;i < 8;++i) out[i] ^= t[i + 4];
-  }
 }
 
-unsigned short rand16(void)
-{
-  static int outleft = 0;
+unsigned short rand16(void) {
+    static int outleft = 0;
 
-  if (!outleft) {
-    if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3];
-    surf();
-    outleft = 8;
-  }
+    if (!outleft) {
+        if (!++in[0])
+            if (!++in[1])
+                if (!++in[2]) ++in[3];
+        surf();
+        outleft = 8;
+    }
 
-  return (unsigned short) out[--outleft];
+    return (unsigned short) out[--outleft];
 }
 
 #endif
 
-static int check_name(char *in)
-{
-  /* remove trailing . 
-     also fail empty string and label > 63 chars */
-  size_t dotgap = 0, l = strlen(in);
-  char c;
-  int nowhite = 0;
-  
-  if (l == 0 || l > MAXDNAME) return 0;
-  
-  if (in[l-1] == '.')
-    {
-      if (l == 1) return 0;
-      in[l-1] = 0;
+static int check_name(char* in) {
+    /* remove trailing .
+       also fail empty string and label > 63 chars */
+    size_t dotgap = 0, l = strlen(in);
+    char c;
+    int nowhite = 0;
+
+    if (l == 0 || l > MAXDNAME) return 0;
+
+    if (in[l - 1] == '.') {
+        if (l == 1) return 0;
+        in[l - 1] = 0;
     }
-  
-  for (; (c = *in); in++)
-    {
-      if (c == '.')
-	dotgap = 0;
-      else if (++dotgap > MAXLABEL)
-	return 0;
-      else if (isascii(c) && iscntrl(c)) 
-	/* iscntrl only gives expected results for ascii */
-	return 0;
+
+    for (; (c = *in); in++) {
+        if (c == '.')
+            dotgap = 0;
+        else if (++dotgap > MAXLABEL)
+            return 0;
+        else if (isascii(c) && iscntrl(c))
+            /* iscntrl only gives expected results for ascii */
+            return 0;
 #ifndef LOCALEDIR
-      else if (!isascii(c))
-	return 0;
+        else if (!isascii(c))
+            return 0;
 #endif
-      else if (c != ' ')
-	nowhite = 1;
+        else if (c != ' ')
+            nowhite = 1;
     }
 
-  if (!nowhite)
-    return 0;
+    if (!nowhite) return 0;
 
-  return 1;
+    return 1;
 }
 
 /* Hostnames have a more limited valid charset than domain names
-   so check for legal char a-z A-Z 0-9 - _ 
-   Note that this may receive a FQDN, so only check the first label 
+   so check for legal char a-z A-Z 0-9 - _
+   Note that this may receive a FQDN, so only check the first label
    for the tighter criteria. */
-int legal_hostname(char *name)
-{
-  char c;
+int legal_hostname(char* name) {
+    char c;
 
-  if (!check_name(name))
-    return 0;
+    if (!check_name(name)) return 0;
 
-  for (; (c = *name); name++)
+    for (; (c = *name); name++)
     /* check for legal char a-z A-Z 0-9 - _ . */
     {
-      if ((c >= 'A' && c <= 'Z') ||
-	  (c >= 'a' && c <= 'z') ||
-	  (c >= '0' && c <= '9') ||
-	  c == '-' || c == '_')
-	continue;
-      
-      /* end of hostname part */
-      if (c == '.')
-	return 1;
-      
-      return 0;
+        if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
+            c == '-' || c == '_')
+            continue;
+
+        /* end of hostname part */
+        if (c == '.') return 1;
+
+        return 0;
     }
-  
-  return 1;
+
+    return 1;
 }
-  
-char *canonicalise(char *in, int *nomem)
-{
-  char *ret = NULL;
+
+char* canonicalise(char* in, int* nomem) {
+    char* ret = NULL;
 #ifdef LOCALEDIR
-  int rc;
+    int rc;
 #endif
 
-  if (nomem)
-    *nomem = 0;
-  
-  if (!check_name(in))
-    return NULL;
-  
-#ifdef LOCALEDIR
-  if ((rc = idna_to_ascii_lz(in, &ret, 0)) != IDNA_SUCCESS)
-    {
-      if (ret)
-	free(ret);
+    if (nomem) *nomem = 0;
 
-      if (nomem && (rc == IDNA_MALLOC_ERROR || rc == IDNA_DLOPEN_ERROR))
-	{
-	  my_syslog(LOG_ERR, _("failed to allocate memory"));
-	  *nomem = 1;
-	}
-    
-      return NULL;
+    if (!check_name(in)) return NULL;
+
+#ifdef LOCALEDIR
+    if ((rc = idna_to_ascii_lz(in, &ret, 0)) != IDNA_SUCCESS) {
+        if (ret) free(ret);
+
+        if (nomem && (rc == IDNA_MALLOC_ERROR || rc == IDNA_DLOPEN_ERROR)) {
+            my_syslog(LOG_ERR, _("failed to allocate memory"));
+            *nomem = 1;
+        }
+
+        return NULL;
     }
 #else
-  if ((ret = whine_malloc(strlen(in)+1)))
-    strcpy(ret, in);
-  else if (nomem)
-    *nomem = 1;    
+    if ((ret = whine_malloc(strlen(in) + 1)))
+        strcpy(ret, in);
+    else if (nomem)
+        *nomem = 1;
 #endif
 
-  return ret;
+    return ret;
 }
 
-unsigned char *do_rfc1035_name(unsigned char *p, char *sval)
-{
-  int j;
-  
-  while (sval && *sval)
-    {
-      unsigned char *cp = p++;
-      for (j = 0; *sval && (*sval != '.'); sval++, j++)
-	*p++ = *sval;
-      *cp  = j;
-      if (*sval)
-	sval++;
+unsigned char* do_rfc1035_name(unsigned char* p, char* sval) {
+    int j;
+
+    while (sval && *sval) {
+        unsigned char* cp = p++;
+        for (j = 0; *sval && (*sval != '.'); sval++, j++) *p++ = *sval;
+        *cp = j;
+        if (*sval) sval++;
     }
-  return p;
+    return p;
 }
 
 /* for use during startup */
-void *safe_malloc(size_t size)
-{
-  void *ret = malloc(size);
-  
-  if (!ret)
-    die(_("could not get memory"), NULL, EC_NOMEM);
-     
-  return ret;
-}    
+void* safe_malloc(size_t size) {
+    void* ret = malloc(size);
 
-void safe_pipe(int *fd, int read_noblock)
-{
-  if (pipe(fd) == -1 || 
-      !fix_fd(fd[1]) ||
-      (read_noblock && !fix_fd(fd[0])))
-    die(_("cannot create pipe: %s"), NULL, EC_MISC);
+    if (!ret) die(_("could not get memory"), NULL, EC_NOMEM);
+
+    return ret;
 }
 
-void *whine_malloc(size_t size)
-{
-  void *ret = malloc(size);
-
-  if (!ret)
-    my_syslog(LOG_ERR, _("failed to allocate %d bytes"), (int) size);
-
-  return ret;
+void safe_pipe(int* fd, int read_noblock) {
+    if (pipe(fd) == -1 || !fix_fd(fd[1]) || (read_noblock && !fix_fd(fd[0])))
+        die(_("cannot create pipe: %s"), NULL, EC_MISC);
 }
 
-int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2)
-{
-  if (s1->sa.sa_family == s2->sa.sa_family)
-    { 
-      if (s1->sa.sa_family == AF_INET &&
-	  s1->in.sin_port == s2->in.sin_port &&
-	  s1->in.sin_addr.s_addr == s2->in.sin_addr.s_addr)
-	return 1;
-#ifdef HAVE_IPV6      
-      if (s1->sa.sa_family == AF_INET6 &&
-	  s1->in6.sin6_port == s2->in6.sin6_port &&
-	  IN6_ARE_ADDR_EQUAL(&s1->in6.sin6_addr, &s2->in6.sin6_addr) &&
-	  (!IN6_IS_ADDR_LINKLOCAL(&s1->in6.sin6_addr) ||
-	   (s1->in6.sin6_scope_id == s2->in6.sin6_scope_id)))
-	return 1;
+void* whine_malloc(size_t size) {
+    void* ret = malloc(size);
+
+    if (!ret) my_syslog(LOG_ERR, _("failed to allocate %d bytes"), (int) size);
+
+    return ret;
+}
+
+int sockaddr_isequal(union mysockaddr* s1, union mysockaddr* s2) {
+    if (s1->sa.sa_family == s2->sa.sa_family) {
+        if (s1->sa.sa_family == AF_INET && s1->in.sin_port == s2->in.sin_port &&
+            s1->in.sin_addr.s_addr == s2->in.sin_addr.s_addr)
+            return 1;
+#ifdef HAVE_IPV6
+        if (s1->sa.sa_family == AF_INET6 && s1->in6.sin6_port == s2->in6.sin6_port &&
+            IN6_ARE_ADDR_EQUAL(&s1->in6.sin6_addr, &s2->in6.sin6_addr) &&
+            (!IN6_IS_ADDR_LINKLOCAL(&s1->in6.sin6_addr) ||
+             (s1->in6.sin6_scope_id == s2->in6.sin6_scope_id)))
+            return 1;
 #endif
     }
-  return 0;
+    return 0;
 }
 
-int sa_len(union mysockaddr *addr) {
+int sa_len(union mysockaddr* addr) {
     if (addr->sa.sa_family == AF_INET6)
         return sizeof(addr->in6);
     else
@@ -279,258 +248,216 @@
 }
 
 /* don't use strcasecmp and friends here - they may be messed up by LOCALE */
-int hostname_isequal(char *a, char *b)
-{
-  unsigned int c1, c2;
-  
-  do {
-    c1 = (unsigned char) *a++;
-    c2 = (unsigned char) *b++;
-    
-    if (c1 >= 'A' && c1 <= 'Z')
-      c1 += 'a' - 'A';
-    if (c2 >= 'A' && c2 <= 'Z')
-      c2 += 'a' - 'A';
-    
-    if (c1 != c2)
-      return 0;
-  } while (c1);
-  
-  return 1;
+int hostname_isequal(char* a, char* b) {
+    unsigned int c1, c2;
+
+    do {
+        c1 = (unsigned char) *a++;
+        c2 = (unsigned char) *b++;
+
+        if (c1 >= 'A' && c1 <= 'Z') c1 += 'a' - 'A';
+        if (c2 >= 'A' && c2 <= 'Z') c2 += 'a' - 'A';
+
+        if (c1 != c2) return 0;
+    } while (c1);
+
+    return 1;
 }
-    
-time_t dnsmasq_time(void)
-{
+
+time_t dnsmasq_time(void) {
 #ifdef HAVE_BROKEN_RTC
-  struct tms dummy;
-  static long tps = 0;
+    struct tms dummy;
+    static long tps = 0;
 
-  if (tps == 0)
-    tps = sysconf(_SC_CLK_TCK);
+    if (tps == 0) tps = sysconf(_SC_CLK_TCK);
 
-  return (time_t)(times(&dummy)/tps);
+    return (time_t)(times(&dummy) / tps);
 #else
-  return time(NULL);
+    return time(NULL);
 #endif
 }
 
-int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask)
-{
-  return (a.s_addr & mask.s_addr) == (b.s_addr & mask.s_addr);
-} 
+int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask) {
+    return (a.s_addr & mask.s_addr) == (b.s_addr & mask.s_addr);
+}
 
-int parse_addr(int family, const char *addrstr, union mysockaddr *addr)
-{
-  struct addrinfo *res, hints = {
-    .ai_flags = AI_NUMERICHOST,
-    .ai_family = family,
-    .ai_socktype = SOCK_DGRAM,
-  };
+int parse_addr(int family, const char* addrstr, union mysockaddr* addr) {
+    struct addrinfo *res, hints = {
+                              .ai_flags = AI_NUMERICHOST,
+                              .ai_family = family,
+                              .ai_socktype = SOCK_DGRAM,
+                          };
 
-  int ret = getaddrinfo(addrstr, NULL, &hints, &res);
-  if (ret) {
-    return ret;
-  }
+    int ret = getaddrinfo(addrstr, NULL, &hints, &res);
+    if (ret) {
+        return ret;
+    }
 
-  switch (res->ai_family) {
-    case AF_INET:
-      addr->in = *((struct sockaddr_in *) res->ai_addr);
-      break;
+    switch (res->ai_family) {
+        case AF_INET:
+            addr->in = *((struct sockaddr_in*) res->ai_addr);
+            break;
 #ifdef HAVE_IPV6
-    case AF_INET6:
-      addr->in6 = *((struct sockaddr_in6 *) res->ai_addr);
-      break;
+        case AF_INET6:
+            addr->in6 = *((struct sockaddr_in6*) res->ai_addr);
+            break;
 #endif
-    default:
-      errno = EAFNOSUPPORT;
-      ret = -1;
-      break;
-  }
-  freeaddrinfo(res);
-  return ret;
+        default:
+            errno = EAFNOSUPPORT;
+            ret = -1;
+            break;
+    }
+    freeaddrinfo(res);
+    return ret;
 }
 
 /* returns port number from address */
-int prettyprint_addr(const union mysockaddr *addr, char *buf)
-{
-  int port = 0;
-  
+int prettyprint_addr(const union mysockaddr* addr, char* buf) {
+    int port = 0;
+
 #ifdef HAVE_IPV6
-  char portstr[strlen("65535")];
-  getnameinfo((const struct sockaddr *) addr, sizeof(*addr), buf, ADDRSTRLEN,
-              portstr, sizeof(portstr), NI_NUMERICHOST | NI_NUMERICSERV);
-  port = atoi(portstr);
+    char portstr[strlen("65535")];
+    getnameinfo((const struct sockaddr*) addr, sizeof(*addr), buf, ADDRSTRLEN, portstr,
+                sizeof(portstr), NI_NUMERICHOST | NI_NUMERICSERV);
+    port = atoi(portstr);
 #else
-  strcpy(buf, inet_ntoa(addr->in.sin_addr));
-  port = ntohs(addr->in.sin_port); 
+    strcpy(buf, inet_ntoa(addr->in.sin_addr));
+    port = ntohs(addr->in.sin_port);
 #endif
-  
-  return port;
+
+    return port;
 }
 
-void prettyprint_time(char *buf, unsigned int t)
-{
-  if (t == 0xffffffff)
-    sprintf(buf, _("infinite"));
-  else
-    {
-      unsigned int x, p = 0;
-       if ((x = t/86400))
-	p += sprintf(&buf[p], "%dd", x);
-       if ((x = (t/3600)%24))
-	p += sprintf(&buf[p], "%dh", x);
-      if ((x = (t/60)%60))
-	p += sprintf(&buf[p], "%dm", x);
-      if ((x = t%60))
-	p += sprintf(&buf[p], "%ds", x);
+void prettyprint_time(char* buf, unsigned int t) {
+    if (t == 0xffffffff)
+        sprintf(buf, _("infinite"));
+    else {
+        unsigned int x, p = 0;
+        if ((x = t / 86400)) p += sprintf(&buf[p], "%dd", x);
+        if ((x = (t / 3600) % 24)) p += sprintf(&buf[p], "%dh", x);
+        if ((x = (t / 60) % 60)) p += sprintf(&buf[p], "%dm", x);
+        if ((x = t % 60)) p += sprintf(&buf[p], "%ds", x);
     }
 }
 
-
 /* in may equal out, when maxlen may be -1 (No max len). */
-int parse_hex(char *in, unsigned char *out, int maxlen, 
-	      unsigned int *wildcard_mask, int *mac_type)
-{
-  int mask = 0, i = 0;
-  char *r;
-    
-  if (mac_type)
-    *mac_type = 0;
-  
-  while (maxlen == -1 || i < maxlen)
-    {
-      for (r = in; *r != 0 && *r != ':' && *r != '-'; r++);
-      if (*r == 0)
-	maxlen = i;
-      
-      if (r != in )
-	{
-	  if (*r == '-' && i == 0 && mac_type)
-	   {
-	      *r = 0;
-	      *mac_type = strtol(in, NULL, 16);
-	      mac_type = NULL;
-	   }
-	  else
-	    {
-	      *r = 0;
-	      mask = mask << 1;
-	      if (strcmp(in, "*") == 0)
-		mask |= 1;
-	      else
-		out[i] = strtol(in, NULL, 16);
-	      i++;
-	    }
-	}
-      in = r+1;
-    }
-  
-  if (wildcard_mask)
-    *wildcard_mask = mask;
+int parse_hex(char* in, unsigned char* out, int maxlen, unsigned int* wildcard_mask, int* mac_type) {
+    int mask = 0, i = 0;
+    char* r;
 
-  return i;
+    if (mac_type) *mac_type = 0;
+
+    while (maxlen == -1 || i < maxlen) {
+        for (r = in; *r != 0 && *r != ':' && *r != '-'; r++)
+            ;
+        if (*r == 0) maxlen = i;
+
+        if (r != in) {
+            if (*r == '-' && i == 0 && mac_type) {
+                *r = 0;
+                *mac_type = strtol(in, NULL, 16);
+                mac_type = NULL;
+            } else {
+                *r = 0;
+                mask = mask << 1;
+                if (strcmp(in, "*") == 0)
+                    mask |= 1;
+                else
+                    out[i] = strtol(in, NULL, 16);
+                i++;
+            }
+        }
+        in = r + 1;
+    }
+
+    if (wildcard_mask) *wildcard_mask = mask;
+
+    return i;
 }
 
 /* return 0 for no match, or (no matched octets) + 1 */
-int memcmp_masked(unsigned char *a, unsigned char *b, int len, unsigned int mask)
-{
-  int i, count;
-  for (count = 1, i = len - 1; i >= 0; i--, mask = mask >> 1)
-    if (!(mask & 1))
-      {
-	if (a[i] == b[i])
-	  count++;
-	else
-	  return 0;
-      }
-  return count;
+int memcmp_masked(unsigned char* a, unsigned char* b, int len, unsigned int mask) {
+    int i, count;
+    for (count = 1, i = len - 1; i >= 0; i--, mask = mask >> 1)
+        if (!(mask & 1)) {
+            if (a[i] == b[i])
+                count++;
+            else
+                return 0;
+        }
+    return count;
 }
 
 /* _note_ may copy buffer */
-int expand_buf(struct iovec *iov, size_t size)
-{
-  void *new;
+int expand_buf(struct iovec* iov, size_t size) {
+    void* new;
 
-  if (size <= (size_t)iov->iov_len)
-    return 1;
+    if (size <= (size_t) iov->iov_len) return 1;
 
-  if (!(new = whine_malloc(size)))
-    {
-      errno = ENOMEM;
-      return 0;
-    }
-
-  if (iov->iov_base)
-    {
-      memcpy(new, iov->iov_base, iov->iov_len);
-      free(iov->iov_base);
-    }
-
-  iov->iov_base = new;
-  iov->iov_len = size;
-
-  return 1;
-}
-
-char *print_mac(char *buff, unsigned char *mac, int len)
-{
-  char *p = buff;
-  int i;
-   
-  if (len == 0)
-    sprintf(p, "<null>");
-  else
-    for (i = 0; i < len; i++)
-      p += sprintf(p, "%.2x%s", mac[i], (i == len - 1) ? "" : ":");
-  
-  return buff;
-}
-
-void bump_maxfd(int fd, int *max)
-{
-  if (fd > *max)
-    *max = fd;
-}
-
-int retry_send(void)
-{
-   struct timespec waiter;
-   if (errno == EAGAIN)
-     {
-       waiter.tv_sec = 0;
-       waiter.tv_nsec = 10000;
-       nanosleep(&waiter, NULL);
-       return 1;
-     }
-   
-   if (errno == EINTR)
-     return 1;
-
-   return 0;
-}
-
-int read_write(int fd, unsigned char *packet, int size, int rw)
-{
-  ssize_t n, done;
-  
-  for (done = 0; done < size; done += n)
-    {
-    retry:
-      if (rw)
-        n = read(fd, &packet[done], (size_t)(size - done));
-      else
-        n = write(fd, &packet[done], (size_t)(size - done));
-
-      if (n == 0)
+    if (!(new = whine_malloc(size))) {
+        errno = ENOMEM;
         return 0;
-      else if (n == -1)
-        {
-          if (retry_send() || errno == ENOMEM || errno == ENOBUFS)
-            goto retry;
-          else
+    }
+
+    if (iov->iov_base) {
+        memcpy(new, iov->iov_base, iov->iov_len);
+        free(iov->iov_base);
+    }
+
+    iov->iov_base = new;
+    iov->iov_len = size;
+
+    return 1;
+}
+
+char* print_mac(char* buff, unsigned char* mac, int len) {
+    char* p = buff;
+    int i;
+
+    if (len == 0)
+        sprintf(p, "<null>");
+    else
+        for (i = 0; i < len; i++) p += sprintf(p, "%.2x%s", mac[i], (i == len - 1) ? "" : ":");
+
+    return buff;
+}
+
+void bump_maxfd(int fd, int* max) {
+    if (fd > *max) *max = fd;
+}
+
+int retry_send(void) {
+    struct timespec waiter;
+    if (errno == EAGAIN) {
+        waiter.tv_sec = 0;
+        waiter.tv_nsec = 10000;
+        nanosleep(&waiter, NULL);
+        return 1;
+    }
+
+    if (errno == EINTR) return 1;
+
+    return 0;
+}
+
+int read_write(int fd, unsigned char* packet, int size, int rw) {
+    ssize_t n, done;
+
+    for (done = 0; done < size; done += n) {
+    retry:
+        if (rw)
+            n = read(fd, &packet[done], (size_t)(size - done));
+        else
+            n = write(fd, &packet[done], (size_t)(size - done));
+
+        if (n == 0)
             return 0;
+        else if (n == -1) {
+            if (retry_send() || errno == ENOMEM || errno == ENOBUFS)
+                goto retry;
+            else
+                return 0;
         }
     }
-  return 1;
+    return 1;
 }
-