]>
Commit | Line | Data |
---|---|---|
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 | { | |
81 | parse(argc, argv, true); | |
82 | } | |
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 | { | |
90 | return file(fname, true); | |
91 | } | |
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 | { | |
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 | } | |
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(); |