/src/pdns/pdns/arguments.hh
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
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 | | */ |
22 | | #pragma once |
23 | | #include <map> |
24 | | #include <set> |
25 | | #include <string> |
26 | | #include <vector> |
27 | | #include <fstream> |
28 | | #include <iostream> |
29 | | #include "misc.hh" |
30 | | #include "pdnsexception.hh" |
31 | | #include <sys/types.h> |
32 | | #include <pwd.h> |
33 | | #include <grp.h> |
34 | | |
35 | | #include "namespaces.hh" |
36 | | #include "logging.hh" |
37 | | |
38 | | using ArgException = PDNSException; |
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; |
58 | | |
59 | | R.set("port")="25"; // use this to specify default parameters |
60 | | R.file("./default.conf"); // parse configuration file |
61 | | |
62 | | R.parse(argc, argv); // read the arguments from main() |
63 | | |
64 | | cout<<"Will we be a daemon?: "<<R.isset("daemon")<<endl; |
65 | | cout<<"Our port will be "<<R["port"]<<endl; |
66 | | |
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 | | |
74 | | class ArgvMap |
75 | | { |
76 | | public: |
77 | | ArgvMap(); |
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 |
80 | 0 | { |
81 | 0 | parse(argc, argv, true); |
82 | 0 | } |
83 | | void preParse(int& argc, char** argv, const string& arg); //!< use this to preparse a single var |
84 | | bool preParseFile(const string& fname, const string& arg, const string& theDefault = ""); //!< use this to preparse a single var in configuration |
85 | | |
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) |
89 | 0 | { |
90 | 0 | return file(fname, true); |
91 | 0 | } |
92 | | bool parseFile(const string& fname, const string& arg, bool lax); //<! parse one line |
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) |
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 |
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 |
105 | | string configstring(bool running, bool full); //!< generates the --config |
106 | | bool contains(const string& var, const string& val); |
107 | | bool isEmpty(const string& arg); //!< checks if variable has value |
108 | | void setDefault(const string& var, const string& value); |
109 | | void setDefaults(); |
110 | | |
111 | | vector<string> list(); |
112 | | [[nodiscard]] string getHelp(const string& item) const |
113 | 0 | { |
114 | 0 | auto iter = helpmap.find(item); |
115 | 0 | return iter == helpmap.end() ? "" : iter->second; |
116 | 0 | } |
117 | | [[nodiscard]] string getDefault(const string& item) const |
118 | 0 | { |
119 | 0 | auto iter = defaultmap.find(item); |
120 | 0 | return iter == defaultmap.end() ? "" : iter->second; |
121 | 0 | } |
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 |
126 | | const string& operator[](const string&); //!< iterator semantics |
127 | | const vector<string>& getCommands(); |
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); |
131 | | #ifdef RECURSOR |
132 | | void setSLog(Logr::log_t log) |
133 | | { |
134 | | d_log = log; |
135 | | } |
136 | | #endif |
137 | | private: |
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); |
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; |
145 | | vector<string> d_cmds; |
146 | | std::set<string> d_cleared; |
147 | | #ifdef RECURSOR |
148 | | std::shared_ptr<Logr::Logger> d_log; |
149 | | #endif |
150 | | }; |
151 | | |
152 | | extern ArgvMap& arg(); |