Skip site navigation (1)Skip section navigation (2)
Date:      Wed,  2 Apr 2008 00:42:27 +0200 (CEST)
From:      Sten Spans <sten@blinkenlights.nl>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   ports/122360: dns/powerdns-recursor: update to 3.1.5
Message-ID:  <20080401224227.8FE0873025@mx0.blinkenlights.nl>
Resent-Message-ID: <200804012250.m31Mo1HN064063@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         122360
>Category:       ports
>Synopsis:       dns/powerdns-recursor: update to 3.1.5
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          maintainer-update
>Submitter-Id:   current-users
>Arrival-Date:   Tue Apr 01 22:50:01 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator:     Sten Spans
>Release:        FreeBSD 6.3-RELEASE i386
>Organization:
>Environment:
System: FreeBSD earth.blinkenlights.nl 6.3-RELEASE FreeBSD 6.3-RELEASE #2: Mon Feb 4 21:44:57 CET 2008 root@earth.blinkenlights.nl:/usr/obj/usr/src/sys/1650 i386


	
>Description:
	The new 3.1.5 release fixes problems, adds features. upgrading also
	fixes a security issue

>How-To-Repeat:
	
>Fix:

	add the patch

diff -Nru powerdns-recursor.orig/Makefile powerdns-recursor/Makefile
--- powerdns-recursor.orig/Makefile	2008-04-02 00:06:41.000000000 +0200
+++ powerdns-recursor/Makefile	2008-04-02 00:11:34.000000000 +0200
@@ -6,8 +6,7 @@
 #
 
 PORTNAME=	powerdns-recursor
-PORTVERSION=	3.1.4
-PORTREVISION=	6
+PORTVERSION=	3.1.5
 CATEGORIES=	dns ipv6
 MASTER_SITES=	http://downloads.powerdns.com/releases/ \
 		http://mirrors.evolva.ro/powerdns.com/releases/
diff -Nru powerdns-recursor.orig/distinfo powerdns-recursor/distinfo
--- powerdns-recursor.orig/distinfo	2008-04-02 00:06:41.000000000 +0200
+++ powerdns-recursor/distinfo	2008-04-02 00:09:05.000000000 +0200
@@ -1,3 +1,3 @@
-MD5 (pdns-recursor-3.1.4.tar.bz2) = 439a10639f53def0ba47c0851e4a2671
-SHA256 (pdns-recursor-3.1.4.tar.bz2) = 9975ec73e311bda4c22f302f18f4ed4fe701d63bce3155f300ccc561d5b0cc39
-SIZE (pdns-recursor-3.1.4.tar.bz2) = 139191
+MD5 (pdns-recursor-3.1.5.tar.bz2) = 682529d59c80076f986003ed5f47e26f
+SHA256 (pdns-recursor-3.1.5.tar.bz2) = 8fde0df7033ee66e720b422038c827d7443ea8eb0e1077da19b34402d9b8d10e
+SIZE (pdns-recursor-3.1.5.tar.bz2) = 171466
diff -Nru powerdns-recursor.orig/files/patch-gcc-skip-locking powerdns-recursor/files/patch-gcc-skip-locking
--- powerdns-recursor.orig/files/patch-gcc-skip-locking	2008-04-02 00:06:41.000000000 +0200
+++ powerdns-recursor/files/patch-gcc-skip-locking	1970-01-01 01:00:00.000000000 +0100
@@ -1,11 +0,0 @@
---- config.h.bak	Sun Nov 12 16:56:13 2006
-+++ config.h	Wed Jun  6 08:01:20 2007
-@@ -1,7 +1,6 @@
--#define SYSCONFDIR "/etc/powerdns/" 
-+#define SYSCONFDIR "/usr/local/etc/pdns/" 
- #define LOCALSTATEDIR "/var/run/" 
- #define VERSION "3.1.4"
- #define RECURSOR
- #ifndef WIN32
--#define GCC_SKIP_LOCKING
- #endif
diff -Nru powerdns-recursor.orig/files/patch-makefile powerdns-recursor/files/patch-makefile
--- powerdns-recursor.orig/files/patch-makefile	2008-04-02 00:06:41.000000000 +0200
+++ powerdns-recursor/files/patch-makefile	2008-04-02 00:13:28.000000000 +0200
@@ -1,14 +1,14 @@
---- Makefile.orig	Tue Nov 14 13:26:24 2006
-+++ Makefile	Tue Nov 14 13:26:51 2006
+--- Makefile.orig	2008-03-30 22:41:25.000000000 +0200
++++ Makefile	2008-04-02 00:13:01.000000000 +0200
 @@ -2,7 +2,6 @@
  SBINDIR=/usr/sbin/
  BINDIR=/usr/bin/
  CONFIGDIR="/etc/powerdns/"
 -OPTFLAGS?=-O3
- CXXFLAGS:= $(CXXFLAGS) -Wall $(OPTFLAGS) $(PROFILEFLAGS)
+ CXXFLAGS:= $(CXXFLAGS) -Wall -DBOOST_SP_DISABLE_THREADS $(OPTFLAGS) $(PROFILEFLAGS)
  CFLAGS:=$(CFLAGS) -Wall $(OPTFLAGS) $(PROFILEFLAGS)
  LINKCC=$(CXX)
-@@ -52,16 +52,14 @@
+@@ -54,16 +53,14 @@
  	 fi
  
  install: all
diff -Nru powerdns-recursor.orig/files/patch-manpages powerdns-recursor/files/patch-manpages
--- powerdns-recursor.orig/files/patch-manpages	2008-04-02 00:06:41.000000000 +0200
+++ powerdns-recursor/files/patch-manpages	2008-04-02 00:16:35.000000000 +0200
@@ -1,58 +1,58 @@
---- rec_control.1.orig	Tue Nov 14 13:47:26 2006
-+++ rec_control.1	Tue Nov 14 13:47:55 2006
-@@ -17,7 +17,7 @@
- .el .ne 3
- .IP "\\$1" \\$2
- ..
--.TH "REC_CONTROL" 1 "" "" ""
-+.TH "REC_CONTROL" 8 "" "" ""
- .SH NAME
- rec_control \- control pdns_recursor
- .SH "SYNOPSIS"
-@@ -28,7 +28,7 @@
+--- pdns_recursor.1.orig	2008-03-30 22:41:26.000000000 +0200
++++ pdns_recursor.1	2008-04-02 00:15:05.000000000 +0200
+@@ -5,7 +5,7 @@
+ .\"    Manual: 
+ .\"    Source: 
+ .\"
+-.TH "PDNS_RECURSOR" "1" "03/22/2008" "" ""
++.TH "PDNS_RECURSOR" "8" "03/22/2008" "" ""
+ .\" disable hyphenation
+ .nh
+ .\" disable justification (adjust text to left margin only)
+@@ -16,7 +16,7 @@
+ \fIpdns_recursor\fR [\-\-daemon] [\-\-local\-address] [\-\-help, \-h] [\-\-allow\-from]
+ .sp
  .SH "DESCRIPTION"
- 
- 
--rec_control(1) allows the operator to control a running instance of the pdns_recursor\&.
-+rec_control(8) allows the operator to control a running instance of the pdns_recursor\&.
- 
- 
- The commands that can be passed to the recursor are described on http://doc\&.powerdns\&.com/rec\-control\&.html
-@@ -111,7 +111,7 @@
+-pdns_recursor(1) is a high performance, simple and secure recursing nameserver. It currently powers over two million internet connections.
++pdns_recursor(8) is a high performance, simple and secure recursing nameserver. It currently powers over two million internet connections.
+ .sp
+ The recursor is configured via a configuration file, but each item in that file can be overridden on the command line.
+ .sp
+@@ -243,7 +243,7 @@
+ Website: http://wiki.powerdns.com, http://www.powerdns.com
+ .sp
  .SH "SEE ALSO"
- 
- 
--pdns_recursor(1)
-+pdns_recursor(8)
- 
+-rec_control(1)
++rec_control(8)
+ .sp
  .SH "COPYING"
- 
---- pdns_recursor.1.orig	Tue Nov 14 13:48:13 2006
-+++ pdns_recursor.1	Tue Nov 14 13:48:44 2006
-@@ -17,7 +17,7 @@
- .el .ne 3
- .IP "\\$1" \\$2
- ..
--.TH "PDNS_RECURSOR" 1 "" "" ""
-+.TH "PDNS_RECURSOR" 8 "" "" ""
- .SH NAME
- pdns_recursor \- high-performance, simple and secure recursing nameserver
- .SH "SYNOPSIS"
-@@ -28,7 +28,7 @@
+ Copyright \(co 2006 PowerDNS.COM BV. Free use of this software is granted under the terms of the GNU General Public License (GPL) version 2.
+--- rec_control.1.orig	2008-03-30 22:41:26.000000000 +0200
++++ rec_control.1	2008-04-02 00:15:23.000000000 +0200
+@@ -5,7 +5,7 @@
+ .\"    Manual: 
+ .\"    Source: 
+ .\"
+-.TH "REC_CONTROL" "1" "03/16/2008" "" ""
++.TH "REC_CONTROL" "8" "03/16/2008" "" ""
+ .\" disable hyphenation
+ .nh
+ .\" disable justification (adjust text to left margin only)
+@@ -16,7 +16,7 @@
+ \fIrec_control\fR [\-\-help] [\-\-socket\-dir] [\-\-socket\-pid] command ..
+ .sp
  .SH "DESCRIPTION"
- 
- 
--pdns_recursor(1) is a high performance, simple and secure recursing nameserver\&. It currently powers over two million internet connections\&.
-+pdns_recursor(8) is a high performance, simple and secure recursing nameserver\&. It currently powers over two million internet connections\&.
- 
- 
- The recursor is configured via a configuration file, but each item in that file can be overridden on the command line\&.
-@@ -211,7 +211,7 @@
+-rec_control(1) allows the operator to control a running instance of the pdns_recursor.
++rec_control(8) allows the operator to control a running instance of the pdns_recursor.
+ .sp
+ The commands that can be passed to the recursor are described on http://doc.powerdns.com/rec\-control.html
+ .sp
+@@ -105,7 +105,7 @@
+ Website: http://wiki.powerdns.com, http://www.powerdns.com
+ .sp
  .SH "SEE ALSO"
- 
- 
--rec_control(1)
-+rec_control(8)
- 
+-pdns_recursor(1)
++pdns_recursor(8)
+ .sp
  .SH "COPYING"
- 
+ Copyright \(co 2006 PowerDNS.COM BV. Free use of this software is granted under the terms of the GNU General Public License (GPL) version 2.
diff -Nru powerdns-recursor.orig/files/patch-multiline_txt_records powerdns-recursor/files/patch-multiline_txt_records
--- powerdns-recursor.orig/files/patch-multiline_txt_records	2008-04-02 00:06:41.000000000 +0200
+++ powerdns-recursor/files/patch-multiline_txt_records	1970-01-01 01:00:00.000000000 +0100
@@ -1,398 +0,0 @@
-Index: dnswriter.hh
-===================================================================
---- dnswriter.hh (revision 962)
-+++ dnswriter.hh (revision 996)
-@@ -84,5 +84,5 @@
- 
-   void xfrLabel(const string& label, bool compress=false);
--  void xfrText(const string& text);
-+  void xfrText(const string& text, bool multi=false);
-   void xfrBlob(const string& blob);
-   void xfrHexBlob(const string& blob);
-Index: dnsparser.hh
-===================================================================
---- dnsparser.hh (revision 972)
-+++ dnsparser.hh (revision 996)
-@@ -110,7 +110,7 @@
-   }
- 
--  void xfrText(string &text)
--  {
--    text=getText();
-+  void xfrText(string &text, bool multi=false)
-+  {
-+    text=getText(multi);
-   }
- 
-@@ -126,5 +126,5 @@
- 
-   string getLabel(unsigned int recurs=0);
--  string getText();
-+  string getText(bool multi);
- 
-   uint16_t d_pos;
-Index: zoneparser-tng.cc
-===================================================================
---- zoneparser-tng.cc (revision 989)
-+++ zoneparser-tng.cc (revision 996)
-@@ -281,6 +281,5 @@
-     }
-     catch(...) {
--      cerr<<"Oops, this doesn't look like a qtype, stopping loop\n";
--      break;
-+      throw runtime_error("Parsing zone content line: '"+nextpart+"' doesn't look like a qtype, stopping loop");
-     }
-   }
-Index: dnswriter.cc
-===================================================================
---- dnswriter.cc (revision 962)
-+++ dnswriter.cc (revision 996)
-@@ -2,4 +2,5 @@
- #include "misc.hh"
- #include "dnsparser.hh"
-+#include <boost/tokenizer.hpp>
- 
- DNSPacketWriter::DNSPacketWriter(vector<uint8_t>& content, const string& qname, uint16_t  qtype, uint16_t qclass, uint8_t opcode)
-@@ -116,9 +117,20 @@
- }
- 
--void DNSPacketWriter::xfrText(const string& text)
--{
--  d_record.push_back(text.length());
--  const uint8_t* ptr=(uint8_t*)(text.c_str());
--  d_record.insert(d_record.end(), ptr, ptr+text.size());
-+void DNSPacketWriter::xfrText(const string& text, bool)
-+{
-+  escaped_list_separator<char> sep('\\', ' ' , '"');
-+  tokenizer<escaped_list_separator<char> > tok(text, sep);
-+
-+  tokenizer<escaped_list_separator<char> >::iterator beg=tok.begin();
-+
-+  if(beg==tok.end()) {
-+    d_record.push_back(0);
-+  }
-+  else 
-+    for(; beg!=tok.end(); ++beg){
-+      d_record.push_back(beg->length());
-+      const uint8_t* ptr=(uint8_t*)(beg->c_str());
-+      d_record.insert(d_record.end(), ptr, ptr+beg->length());
-+    }
- }
- 
-Index: dnsparser.cc
-===================================================================
---- dnsparser.cc (revision 972)
-+++ dnsparser.cc (revision 996)
-@@ -359,14 +359,42 @@
- }
- 
--string PacketReader::getText()
-+static string txtEscape(const string &name)
-+{
-+  string ret;
-+
-+  for(string::const_iterator i=name.begin();i!=name.end();++i)
-+    if(*i=='"' || *i=='\\'){
-+      ret += '\\';
-+      ret += *i;
-+    }
-+    else
-+      ret += *i;
-+  return ret;
-+}
-+
-+// exceptions thrown here do not result in logging in the main pdns auth server - just so you know!
-+string PacketReader::getText(bool multi)
- {
-   string ret;
-   ret.reserve(40);
--
--  unsigned char labellen=d_content.at(d_pos++);
--  ret.append(&d_content.at(d_pos), &d_content.at(d_pos+labellen-1)+1); // the end is one beyond the packet
--  d_pos+=labellen;
--  return ret;
--}
-+  while(d_pos < d_startrecordpos + d_recordlen ) {
-+    if(!ret.empty()) {
-+      ret.append(1,' ');
-+    }
-+    unsigned char labellen=d_content.at(d_pos++);
-+    
-+    ret.append(1,'"');
-+    string val(&d_content.at(d_pos), &d_content.at(d_pos+labellen-1)+1);
-+    
-+    ret.append(txtEscape(val)); // the end is one beyond the packet
-+    ret.append(1,'"');
-+    d_pos+=labellen;
-+    if(!multi)
-+      break;
-+  }
-+
-+  return ret;
-+}
-+
- 
- void PacketReader::getLabelFromContent(const vector<uint8_t>& content, uint16_t& frompos, string& ret, int recurs) 
-Index: rcpgenerator.hh
-===================================================================
---- rcpgenerator.hh (revision 802)
-+++ rcpgenerator.hh (revision 996)
-@@ -51,5 +51,5 @@
- 
-   void xfrLabel(string& val, bool compress=false);
--  void xfrText(string& val);
-+  void xfrText(string& val, bool multi=false);
-   void xfrHexBlob(string& val);
-   void xfrBlob(string& val);
-@@ -76,5 +76,5 @@
-   void xfrType(const uint16_t& val);
-   void xfrLabel(const string& val, bool compress=false);
--  void xfrText(const string& val);
-+  void xfrText(const string& val, bool multi=false);
-   void xfrBlob(const string& val);
-   void xfrHexBlob(const string& val);
-Index: dnsrecords.cc
-===================================================================
---- dnsrecords.cc (revision 823)
-+++ dnsrecords.cc (revision 996)
-@@ -1,5 +1,5 @@
- /*
-     PowerDNS Versatile Database Driven Nameserver
--    Copyright (C) 2005 - 2006  PowerDNS.COM BV
-+    Copyright (C) 2005 - 2007  PowerDNS.COM BV
- 
-     This program is free software; you can redistribute it and/or modify
-@@ -178,6 +178,6 @@
- boilerplate_conv(PTR, ns_t_ptr, conv.xfrLabel(d_content, true));
- boilerplate_conv(CNAME, ns_t_cname, conv.xfrLabel(d_content, true));
--boilerplate_conv(TXT, ns_t_txt, conv.xfrText(d_text));
--boilerplate_conv(SPF, 99, conv.xfrText(d_text));
-+boilerplate_conv(TXT, ns_t_txt, conv.xfrText(d_text, true));
-+boilerplate_conv(SPF, 99, conv.xfrText(d_text, true));
- boilerplate_conv(HINFO, ns_t_hinfo,  conv.xfrText(d_cpu);   conv.xfrText(d_host));
- 
-@@ -199,4 +199,9 @@
- 		 conv.xfr16BitInt(d_preference);
- 		 conv.xfrLabel(d_mxname, true);
-+		 )
-+
-+boilerplate_conv(AFSDB, ns_t_afsdb, 
-+		 conv.xfr16BitInt(d_subtype);
-+		 conv.xfrLabel(d_hostname);
- 		 )
- 
-@@ -235,4 +240,11 @@
- 		 conv.xfr32BitInt(d_st.expire);
- 		 conv.xfr32BitInt(d_st.minimum);
-+		 );
-+#undef KEY
-+boilerplate_conv(KEY, ns_t_key, 
-+		 conv.xfr16BitInt(d_flags); 
-+		 conv.xfr8BitInt(d_protocol); 
-+		 conv.xfr8BitInt(d_algorithm); 
-+		 conv.xfrBlob(d_certificate);
- 		 );
- 
-@@ -294,7 +306,9 @@
- void reportOtherTypes()
- {
-+   AFSDBRecordContent::report();
-    SPFRecordContent::report();
-    NAPTRRecordContent::report();
-    RPRecordContent::report();
-+   KEYRecordContent::report();
-    DNSKEYRecordContent::report();
-    RRSIGRecordContent::report();
-Index: dnsrecords.hh
-===================================================================
---- dnsrecords.hh (revision 823)
-+++ dnsrecords.hh (revision 978)
-@@ -196,4 +196,26 @@
-   string d_fingerprint;
- };
-+
-+class KEYRecordContent : public DNSRecordContent
-+{
-+public:
-+  includeboilerplate(KEY)
-+
-+private:
-+  uint16_t d_flags;
-+  uint8_t d_protocol, d_algorithm;
-+  string d_certificate;
-+};
-+
-+class AFSDBRecordContent : public DNSRecordContent
-+{
-+public:
-+  includeboilerplate(AFSDB)
-+
-+private:
-+  uint16_t d_subtype;
-+  string d_hostname;
-+};
-+
- 
- class CERTRecordContent : public DNSRecordContent
-Index: rcpgenerator.cc
-===================================================================
---- rcpgenerator.cc (revision 850)
-+++ rcpgenerator.cc (revision 996)
-@@ -67,9 +67,38 @@
-   if(!isdigit(d_string.at(d_pos)))
-     throw RecordTextException("while parsing IP address, expected digits at position "+lexical_cast<string>(d_pos)+" in '"+d_string+"'");
--  
--  string ip;
--  xfrLabel(ip);
--  if(!IpToU32(ip, &val))
--    throw RecordTextException("unable to parse IP address '"+ip+"'");
-+
-+  uint32_t octet=0;
-+  val=0;
-+  char count=0;
-+  
-+  for(;;) {
-+    if(d_string.at(d_pos)=='.') {
-+      val<<=8;
-+      val+=octet;
-+      octet=0;
-+      count++;
-+      if(count > 3)
-+	break;
-+    }
-+    else if(isdigit(d_string.at(d_pos))) {
-+      octet*=10;
-+      octet+=d_string.at(d_pos) - '0';
-+      if(octet > 255)
-+	throw RecordTextException("unable to parse IP address");
-+    }
-+    else if(dns_isspace(d_string.at(d_pos))) 
-+      break;
-+    else
-+      throw RecordTextException("unable to parse IP address, strange character: "+d_string.at(d_pos));
-+
-+    d_pos++;
-+    if(d_pos == d_string.length())
-+      break;
-+  }
-+  if(count<=3) {
-+    val<<=8;
-+    val+=octet;
-+  }
-+  val=ntohl(val);
- }
- 
-@@ -178,23 +207,31 @@
- }
- 
--
--void RecordTextReader::xfrText(string& val)
--{
--  skipSpaces();
--  if(d_string[d_pos]!='"')
--    throw RecordTextException("Data field in DNS should start with quote (\") at position "+lexical_cast<string>(d_pos)+" of '"+d_string+"'");
--
-+void RecordTextReader::xfrText(string& val, bool multi)
-+{
-   val.clear();
-   val.reserve(d_end - d_pos);
--  
--  while(++d_pos < d_end && d_string[d_pos]!='"') {
--    if(d_string[d_pos]=='\\' && d_pos+1!=d_end) {
--      ++d_pos;
-+
-+  while(d_pos != d_end) {
-+    if(!val.empty())
-+      val.append(1, ' ');
-+
-+    skipSpaces();
-+    if(d_string[d_pos]!='"')
-+      throw RecordTextException("Data field in DNS should start with quote (\") at position "+lexical_cast<string>(d_pos)+" of '"+d_string+"'");
-+
-+    val.append(1, '"');
-+    while(++d_pos < d_end && d_string[d_pos]!='"') {
-+      if(d_string[d_pos]=='\\' && d_pos+1!=d_end) {
-+	val.append(1, d_string[d_pos++]);
-+      }
-+      val.append(1, d_string[d_pos]);
-     }
--    val.append(1, d_string[d_pos]);
--  }
--  if(d_pos == d_end)
--    throw RecordTextException("Data field in DNS should end on a quote (\") in '"+d_string+"'");
--  d_pos++;
-+    val.append(1,'"');
-+    if(d_pos == d_end)
-+      throw RecordTextException("Data field in DNS should end on a quote (\") in '"+d_string+"'");
-+    d_pos++;
-+    if(!multi)
-+      break;
-+  }
- }
- 
-@@ -251,11 +288,28 @@
- 
-   char tmp[17];
--  snprintf(tmp, sizeof(tmp)-1, "%u.%u.%u.%u", 
--	   (val >> 24)&0xff,
--	   (val >> 16)&0xff,
--	   (val >>  8)&0xff,
--	   (val      )&0xff);
--  
--  d_string+=tmp;
-+  uint32_t ip=htonl(val);
-+  uint8_t vals[4];
-+
-+  memcpy(&vals[0], &ip, sizeof(ip));
-+
-+  char *pos=tmp;
-+
-+  for(int n=0; n < 4; ++n) {
-+    if(vals[n]<10) {
-+      *(pos++)=vals[n]+'0';
-+    } else if(vals[n] < 100) {
-+      *(pos++)=(vals[n]/10) +'0';
-+      *(pos++)=(vals[n]%10) +'0';
-+    } else {
-+      *(pos++)=(vals[n]/100) +'0';
-+      vals[n]%=100;
-+      *(pos++)=(vals[n]/10) +'0';
-+      *(pos++)=(vals[n]%10) +'0';
-+    }
-+    if(n!=3)
-+      *(pos++)='.';
-+  }
-+  *pos=0;
-+  d_string.append(tmp, pos);
- }
- 
-@@ -338,23 +392,10 @@
- }
- 
--void RecordTextWriter::xfrText(const string& val)
--{
--  if(!d_string.empty())
--    d_string.append(1,' ');
--  d_string.append(1,'"');
--
--  if(val.find_first_of("\\\"") == string::npos)
--    d_string+=val;
--  else {
--    string::size_type end=val.size();
--    
--    for(string::size_type pos=0; pos < end; ++pos) {
--      if(val[pos]=='\'' || val[pos]=='"')
--	d_string.append(1,'\\');
--      d_string.append(1, val[pos]);
--    }
--  }
--
--  d_string.append(1,'"');
-+void RecordTextWriter::xfrText(const string& val, bool multi)
-+{
-+  if(!d_string.empty())
-+    d_string.append(1,' ');
-+
-+  d_string.append(val);
- }
- 

>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20080401224227.8FE0873025>