]>
Commit | Line | Data |
---|---|---|
12c86877 | 1 | /* |
12471842 PL |
2 | * This file is part of PowerDNS or dnsdist. |
3 | * Copyright -- PowerDNS.COM B.V. and its contributors | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify | |
6 | * it under the terms of version 2 of the GNU General Public License as | |
7 | * published by the Free Software Foundation. | |
8 | * | |
9 | * In addition, for the avoidance of any doubt, permission is granted to | |
10 | * link this program with OpenSSL and to (re)distribute the binaries | |
11 | * produced as the result of such linking. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
21 | */ | |
e8c59f2d | 22 | #pragma once |
12c86877 | 23 | #include <map> |
58a57699 | 24 | #include <set> |
12c86877 BH |
25 | #include <string> |
26 | #include <vector> | |
eefd15f9 BH |
27 | #include <fstream> |
28 | #include <iostream> | |
29 | #include "misc.hh" | |
5c409fa2 | 30 | #include "pdnsexception.hh" |
76473b92 KM |
31 | #include <sys/types.h> |
32 | #include <pwd.h> | |
33 | #include <grp.h> | |
12c86877 | 34 | |
10f4eea8 | 35 | #include "namespaces.hh" |
ebaffe64 | 36 | #include "logging.hh" |
12c86877 | 37 | |
bace7695 | 38 | using ArgException = PDNSException; |
12c86877 BH |
39 | |
40 | /** This class helps parsing argc and argv into a map of parameters. We have 3 kinds of formats: | |
41 | ||
42 | ||
43 | -w this leads to a key/value pair of "w"/void | |
44 | ||
45 | --port=25 "port"/"25" | |
46 | ||
47 | --daemon "daemon"/void | |
48 | ||
49 | We do not support "--port 25" syntax. | |
50 | ||
51 | It can also read from a file. This file can contain '#' to delimit comments. | |
52 | ||
53 | Some sample code: | |
54 | ||
55 | \code | |
56 | ||
57 | ArgvMap R; | |
fe6861c2 | 58 | |
12c86877 BH |
59 | R.set("port")="25"; // use this to specify default parameters |
60 | R.file("./default.conf"); // parse configuration file | |
fe6861c2 | 61 | |
12c86877 | 62 | R.parse(argc, argv); // read the arguments from main() |
fe6861c2 | 63 | |
ce6f9349 | 64 | cout<<"Will we be a daemon?: "<<R.isset("daemon")<<endl; |
12c86877 | 65 | cout<<"Our port will be "<<R["port"]<<endl; |
fe6861c2 | 66 | |
12c86877 BH |
67 | map<string,string>::const_iterator i; |
68 | cout<<"via iterator"<<endl; | |
69 | for(i=R.begin();i!=R.end();i++) | |
70 | cout<<i->first<<"="<<i->second<<endl; | |
71 | \endcode | |
72 | */ | |
73 | ||
12c86877 BH |
74 | class ArgvMap |
75 | { | |
76 | public: | |
77 | ArgvMap(); | |
725bf803 OM |
78 | void parse(int& argc, char** argv, bool lax = false); //!< use this to parse from argc and argv |
79 | void laxParse(int& argc, char** argv) //!< use this to parse from argc and argv | |
12c86877 | 80 | { |
725bf803 | 81 | parse(argc, argv, true); |
12c86877 | 82 | } |
725bf803 | 83 | void preParse(int& argc, char** argv, const string& arg); //!< use this to preparse a single var |
9883d3f9 | 84 | bool preParseFile(const string& fname, const string& arg, const string& theDefault = ""); //!< use this to preparse a single var in configuration |
12c86877 | 85 | |
9883d3f9 OM |
86 | bool file(const string& fname, bool lax = false); //!< Parses a file with parameters |
87 | bool file(const string& fname, bool lax, bool included); | |
88 | bool laxFile(const string& fname) | |
12c86877 | 89 | { |
725bf803 | 90 | return file(fname, true); |
12c86877 | 91 | } |
9883d3f9 | 92 | bool parseFile(const string& fname, const string& arg, bool lax); //<! parse one line |
725bf803 OM |
93 | bool parmIsset(const string& var); //!< Checks if a parameter is set to *a* value |
94 | bool mustDo(const string& var); //!< if a switch is given, if we must do something (--help) | |
bace7695 OM |
95 | int asNum(const string& arg, int def = 0); //!< return a variable value as a number or the default if the variable is empty |
96 | mode_t asMode(const string& arg); //!< return value interpreted as octal number | |
97 | uid_t asUid(const string& arg); //!< return user id, resolves if necessary | |
98 | gid_t asGid(const string& arg); //!< return group id, resolves if necessary | |
99 | double asDouble(const string& arg); //!< return a variable value as a number | |
725bf803 OM |
100 | string& set(const string&); //!< Gives a writable reference and allocates space for it |
101 | string& set(const string&, const string&); //!< Does the same but also allows one to specify a help message | |
102 | void setCmd(const string&, const string&); //!< Add a command flag | |
103 | string& setSwitch(const string&, const string&); //!< Add a switch flag | |
104 | string helpstring(string prefix = ""); //!< generates the --help | |
bace7695 | 105 | string configstring(bool running, bool full); //!< generates the --config |
725bf803 | 106 | bool contains(const string& var, const string& val); |
bace7695 | 107 | bool isEmpty(const string& arg); //!< checks if variable has value |
725bf803 | 108 | void setDefault(const string& var, const string& value); |
8864bdf6 | 109 | void setDefaults(); |
12c86877 | 110 | |
725bf803 | 111 | vector<string> list(); |
9883d3f9 OM |
112 | [[nodiscard]] string getHelp(const string& item) const |
113 | { | |
114 | auto iter = helpmap.find(item); | |
115 | return iter == helpmap.end() ? "" : iter->second; | |
116 | } | |
117 | [[nodiscard]] string getDefault(const string& item) const | |
118 | { | |
119 | auto iter = defaultmap.find(item); | |
120 | return iter == defaultmap.end() ? "" : iter->second; | |
121 | } | |
bace7695 OM |
122 | using param_t = map<string, string>; //!< use this if you need to know the content of the map |
123 | ||
124 | param_t::const_iterator begin(); //!< iterator semantics | |
125 | param_t::const_iterator end(); //!< iterator semantics | |
725bf803 OM |
126 | const string& operator[](const string&); //!< iterator semantics |
127 | const vector<string>& getCommands(); | |
9883d3f9 OM |
128 | void gatherIncludes(const std::string& dir, const std::string& suffix, std::vector<std::string>& extraConfigs); |
129 | void warnIfDeprecated(const string& var) const; | |
130 | [[nodiscard]] static string isDeprecated(const string& var); | |
d197c31c | 131 | #ifdef RECURSOR |
d61b8a01 | 132 | void setSLog(Logr::log_t log) |
d197c31c OM |
133 | { |
134 | d_log = log; | |
135 | } | |
136 | #endif | |
12c86877 | 137 | private: |
bace7695 OM |
138 | void parseOne(const string& arg, const string& parseOnly = "", bool lax = false); |
139 | static string formatOne(bool running, bool full, const string& var, const string& help, const string& theDefault, const string& current); | |
725bf803 OM |
140 | map<string, string> d_params; |
141 | map<string, string> d_unknownParams; | |
142 | map<string, string> helpmap; | |
143 | map<string, string> defaultmap; | |
144 | map<string, string> d_typeMap; | |
12c86877 | 145 | vector<string> d_cmds; |
58a57699 | 146 | std::set<string> d_cleared; |
d197c31c OM |
147 | #ifdef RECURSOR |
148 | std::shared_ptr<Logr::Logger> d_log; | |
149 | #endif | |
12c86877 BH |
150 | }; |
151 | ||
725bf803 | 152 | extern ArgvMap& arg(); |