]> git.ipfire.org Git - thirdparty/pdns.git/blobdiff - pdns/arguments.cc
auth: switch circleci mssql image
[thirdparty/pdns.git] / pdns / arguments.cc
index 6278dadaad3317285e1537523a6be64ab1a7a33f..1f2d04456a0c2609a38c26fdd84887594bcb88b8 100644 (file)
@@ -1,24 +1,24 @@
 /*
-    PowerDNS Versatile Database Driven Nameserver
-    Copyright (C) 2002 - 2008  PowerDNS.COM BV
-
   This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2 as published 
-    by the Free Software Foundation
-
-    Additionally, the license of this program contains a special
-    exception which allows to distribute the program in binary form when
   it is linked against OpenSSL.
-
   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, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-*/
+ * This file is part of PowerDNS or dnsdist.
+ * Copyright -- PowerDNS.COM B.V. and its contributors
+ *
* This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In addition, for the avoidance of any doubt, permission is granted to
+ * link this program with OpenSSL and to (re)distribute the binaries
* produced as the result of such linking.
+ *
* 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -26,7 +26,7 @@
 #include <boost/algorithm/string.hpp>
 #include <boost/algorithm/string/compare.hpp>
 #include <boost/algorithm/string/predicate.hpp>
-#include <boost/foreach.hpp>
+
 #include "namespaces.hh"
 #include "logger.hh"
 #include <sys/types.h>
@@ -97,11 +97,10 @@ bool ArgvMap::contains(const string &var, const string &val)
     return false;
   }
   vector<string> parts;
-  vector<string>::const_iterator i;
   
   stringtok( parts, param->second, ", \t" );
-  for( i = parts.begin(); i != parts.end(); i++ ) {
-    if( *i == val ) {
+  for (const auto& part: parts) {
+    if (part == val) {
       return true;
     }
   }
@@ -115,30 +114,27 @@ string ArgvMap::helpstring(string prefix)
     prefix="";
   
   string help;
-  
-  for(map<string,string>::const_iterator i=helpmap.begin();
-      i!=helpmap.end();
-      i++)
-    {
-      if(!prefix.empty() && i->first.find(prefix)) // only print items with prefix
-        continue;
+
+  for (const auto& i: helpmap) {
+      if(!prefix.empty() && i.first.find(prefix) != 0) // only print items with prefix
+          continue;
 
       help+="  --";
-      help+=i->first;
+      help+=i.first;
       
-      string type=d_typeMap[i->first];
+      string type=d_typeMap[i.first];
 
       if(type=="Parameter")
         help+="=...";
       else if(type=="Switch")
         {
-          help+=" | --"+i->first+"=yes";
-          help+=" | --"+i->first+"=no";
+          help+=" | --"+i.first+"=yes";
+          help+=" | --"+i.first+"=no";
         }
       
 
       help+="\n\t";
-      help+=i->second;
+      help+=i.second;
       help+="\n";
 
     }
@@ -154,20 +150,20 @@ string ArgvMap::configstring(bool current)
   else
     help="# Autogenerated configuration file template\n";
   
-  for(map<string,string>::const_iterator i=helpmap.begin(); i!=helpmap.end(); i++) {
-    if(d_typeMap[i->first]=="Command")
+  for(const auto& i: helpmap) {
+    if(d_typeMap[i.first]=="Command")
       continue;
 
     help+="#################################\n";
     help+="# ";
-    help+=i->first;
+    help+=i.first;
     help+="\t";
-    help+=i->second;
+    help+=i.second;
     help+="\n#\n";
     if (current) {
-      help+=i->first+"="+params[i->first]+"\n\n";
+      help+=i.first+"="+params[i.first]+"\n\n";
     } else {
-      help+="# "+i->first+"="+params[i->first]+"\n\n";
+      help+="# "+i.first+"="+params[i.first]+"\n\n";
     }
   }
   return help;
@@ -255,7 +251,7 @@ int ArgvMap::asNum(const string &arg, int def)
   cptr_orig = params[arg].c_str();
   retval = static_cast<int>(strtol(cptr_orig, &cptr_ret, 0));
   if (!retval && cptr_ret == cptr_orig)
-   throw ArgException("'"+arg+string("' is not valid number"));
+   throw ArgException("'"+arg+"' value '"+string(cptr_orig) + string( "' is not a valid number"));
 
   return retval;
 }
@@ -304,18 +300,18 @@ void ArgvMap::parseOne(const string &arg, const string &parseOnly, bool lax)
   string::size_type pos;
   bool incremental = false;
 
-  if(!arg.find("--") && (pos=arg.find("+="))!=string::npos) // this is a --port+=25 case
+  if(arg.find("--") == 0 && (pos=arg.find("+="))!=string::npos) // this is a --port+=25 case
   {
     var=arg.substr(2,pos-2);
     val=arg.substr(pos+2);
     incremental = true;
   }
-  else if(!arg.find("--") && (pos=arg.find("="))!=string::npos)  // this is a --port=25 case
+  else if(arg.find("--") == 0 && (pos=arg.find("="))!=string::npos)  // this is a --port=25 case
   {
     var=arg.substr(2,pos-2);
     val=arg.substr(pos+1);
   }
-  else if(!arg.find("--") && (arg.find("=")==string::npos))  // this is a --daemon case
+  else if(arg.find("--") == 0 && (arg.find("=")==string::npos))  // this is a --daemon case
   {
     var=arg.substr(2);
     val="";
@@ -376,27 +372,24 @@ void ArgvMap::preParse(int &argc, char **argv, const string &arg)
 {
   for(int n=1;n<argc;n++) {
     string varval=argv[n];
-    if(!varval.find("--"+arg))
+    if(varval.find("--"+arg) == 0)
       parseOne(argv[n]);
   }
 }
 
-bool ArgvMap::preParseFile(const char *fname, const string &arg, const string& theDefault)
-{
-  params[arg]=theDefault;
+bool ArgvMap::parseFile(const char *fname, const string& arg, bool lax) {
+  string line;
+  string pline;
+  string::size_type pos;
 
   ifstream f(fname);
   if(!f)
     return false;
 
-  string line;
-  string pline;
-  string::size_type pos;
-
   while(getline(f,pline)) {
     trim_right(pline);
     
-    if(pline[pline.size()-1]=='\\') {
+    if(!pline.empty() && pline[pline.size()-1]=='\\') {
       line+=pline.substr(0,pline.length()-1);
       continue;
     }
@@ -404,8 +397,12 @@ bool ArgvMap::preParseFile(const char *fname, const string &arg, const string& t
       line+=pline;
 
     // strip everything after a #
-    if((pos=line.find("#"))!=string::npos)
-      line=line.substr(0,pos);
+    if((pos=line.find("#"))!=string::npos) {
+      // make sure it's either first char or has whitespace before
+      // fixes issue #354
+      if (pos == 0 || std::isspace(line[pos-1]))
+        line=line.substr(0,pos);
+    }
 
     // strip trailing spaces
     trim_right(line);
@@ -416,13 +413,21 @@ bool ArgvMap::preParseFile(const char *fname, const string &arg, const string& t
 
     // gpgsql-basic-query=sdfsdfs dfsdfsdf sdfsdfsfd
 
-    parseOne( string("--") + line, arg );
+    parseOne( string("--") + line, arg, lax );
     line="";
   }
 
   return true;
 }
 
+
+bool ArgvMap::preParseFile(const char *fname, const string &arg, const string& theDefault)
+{
+  params[arg]=theDefault;
+
+  return parseFile(fname, arg, false);
+}
+
 bool ArgvMap::file(const char *fname, bool lax)
 {
    return file(fname,lax,false);
@@ -430,50 +435,21 @@ bool ArgvMap::file(const char *fname, bool lax)
 
 bool ArgvMap::file(const char *fname, bool lax, bool included)
 {
-  ifstream f(fname);
-  if(!f) {
-    L << Logger::Warning << "Unable to open " << fname << std::endl;
-    return false;
-  }
-
   if (!parmIsset("include-dir"))  // inject include-dir
     set("include-dir","Directory to include configuration files from");
 
-  string line;
-  string pline;
-  string::size_type pos;
-
-  while(getline(f,pline)) {
-    trim_right(pline);
-    if(pline.empty())
-      continue;
-
-    if(pline[pline.size()-1]=='\\') {
-      line+=pline.substr(0,pline.length()-1);
-
-      continue;
-    }
-    else
-      line+=pline;
-
-    // strip everything after a #
-    if((pos=line.find("#"))!=string::npos)
-      line=line.substr(0,pos);
-
-    // strip trailing spaces
-    trim(line);
-
-    parseOne(string("--")+line,"",lax);
-    line="";
+  if(!parseFile(fname, "", lax)) {
+    g_log << Logger::Warning << "Unable to open " << fname << std::endl;
+    return false;
   }
 
   // handle include here (avoid re-include)
   if (!included && !params["include-dir"].empty()) {
     std::vector<std::string> extraConfigs;
     gatherIncludes(extraConfigs); 
-    BOOST_FOREACH(const std::string& fn, extraConfigs) {
+    for(const std::string& fn :  extraConfigs) {
       if (!file(fn.c_str(), lax, true)) {
-        L << Logger::Error << fn << " could not be parsed" << std::endl;
+        g_log << Logger::Error << fn << " could not be parsed" << std::endl;
         throw ArgException(fn + " could not be parsed");
       }
     }
@@ -491,18 +467,18 @@ void ArgvMap::gatherIncludes(std::vector<std::string> &extraConfigs) {
 
     // stat
     if (stat(params["include-dir"].c_str(), &st)) {
-       L << Logger::Error << params["include-dir"] << " does not exist!" << std::endl;
+       g_log << Logger::Error << params["include-dir"] << " does not exist!" << std::endl;
        throw ArgException(params["include-dir"] + " does not exist!");
     }
 
     // wonder if it's accessible directory
     if (!S_ISDIR(st.st_mode)) {
-       L << Logger::Error << params["include-dir"] << " is not a directory" << std::endl;
+       g_log << Logger::Error << params["include-dir"] << " is not a directory" << std::endl;
        throw ArgException(params["include-dir"] + " is not a directory");
     }
 
     if (!(dir = opendir(params["include-dir"].c_str()))) {
-       L << Logger::Error << params["include-dir"] << " is not accessible" << std::endl;
+       g_log << Logger::Error << params["include-dir"] << " is not accessible" << std::endl;
        throw ArgException(params["include-dir"] + " is not accessible");
     }
 
@@ -514,7 +490,8 @@ void ArgvMap::gatherIncludes(std::vector<std::string> &extraConfigs) {
         namebuf << params["include-dir"].c_str() << "/" << ent->d_name; // FIXME: Use some path separator
         // ensure it's readable file
         if (stat(namebuf.str().c_str(), &st) || !S_ISREG(st.st_mode)) {
-          L << Logger::Error << namebuf.str() << " is not a file" << std::endl;
+          g_log << Logger::Error << namebuf.str() << " is not a file" << std::endl;
+          closedir(dir);
           throw ArgException(namebuf.str() + " does not exist!");
         }
         extraConfigs.push_back(namebuf.str());