]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/misc.hh
rest of the big whitespace/tab cleanup
[thirdparty/pdns.git] / pdns / misc.hh
CommitLineData
12c86877
BH
1/*
2 PowerDNS Versatile Database Driven Nameserver
ec6480f3 3 Copyright (C) 2002-2009 PowerDNS.COM BV
12c86877
BH
4
5 This program is free software; you can redistribute it and/or modify
22dc646a
BH
6 it under the terms of the GNU General Public License version 2
7 as published by the Free Software Foundation
8
12c86877
BH
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
06bd9ccf 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12c86877
BH
18*/
19#ifndef MISC_HH
20#define MISC_HH
61b26744 21#include <inttypes.h>
8b3cfcd3 22#include <cstring>
f9822705 23#include <cstdio>
ec6480f3 24#include <boost/algorithm/string.hpp>
4b8b58e1 25#if 0
eff65ff8
BH
26#include <iostream>
27using std::cout;
28using std::endl;
29
30struct TSCTimer
31{
32 TSCTimer()
33 {
34 RDTSC(d_tsc1);
35 }
36 ~TSCTimer()
37 {
38 uint64_t tsc2;
39 RDTSC(tsc2);
40 cout<<"Timer: "<< (tsc2 - d_tsc1)/3000.0 << endl;
41 }
42 uint64_t d_tsc1;
43};
44#endif
12c86877
BH
45
46#include "utility.hh"
e67e250f 47#include "dns.hh"
12c86877
BH
48#ifndef WIN32
49# include <sys/time.h>
50# include <sys/types.h>
51# include <sys/socket.h>
cc3afe25 52# include <time.h>
6e2514e4 53# include <syslog.h>
cc3afe25 54#else
cc3afe25
BH
55# define WINDOWS_LEAN_AND_MEAN
56# include <windows.h>
57# include "utility.hh"
cc3afe25 58#endif // WIN32
3de83124 59#include <deque>
a640a9d4 60#include <stdexcept>
12c86877
BH
61#include <string>
62#include <ctype.h>
e67e250f 63#include <vector>
6e2514e4 64#include <boost/optional.hpp>
e67e250f 65
12c86877 66using namespace std;
728485ca 67bool chopOff(string &domain);
7738a23f
BH
68bool chopOffDotted(string &domain);
69
728485ca 70bool endsOn(const string &domain, const string &suffix);
7738a23f 71bool dottedEndsOn(const string &domain, const string &suffix);
cc3afe25 72string nowTime();
1d329048 73const string unquotify(const string &item);
12c86877
BH
74string humanDuration(time_t passed);
75void chomp(string &line, const string &delim);
f2c11a48 76bool stripDomainSuffix(string *qname, const string &domain);
12c86877
BH
77void stripLine(string &line);
78string getHostname();
79string urlEncode(const string &text);
a7d50153 80int waitForData(int fd, int seconds, int useconds=0);
6a3e5d1a 81int waitForRWData(int fd, bool waitForRead, int seconds, int useconds);
092f210a
BH
82uint16_t getShort(const unsigned char *p);
83uint16_t getShort(const char *p);
84uint32_t getLong(const unsigned char *p);
85uint32_t getLong(const char *p);
6e2514e4 86boost::optional<int> logFacilityToLOG(unsigned int facility);
bbce5bf0 87
092f210a 88inline void putLong(unsigned char* p, uint32_t val)
7bf26383
BH
89{
90 *p++=(val>>24)&0xff;
91 *p++=(val>>16)&0xff;
92 *p++=(val>>8)&0xff;
93 *p++=(val )&0xff;
94
95}
092f210a 96inline void putLong(char* p, uint32_t val)
7bf26383
BH
97{
98 putLong((unsigned char *)p,val);
99}
12c86877 100
7b35aa49 101
092f210a 102inline uint32_t getLong(unsigned char *p)
7b35aa49
BH
103{
104 return (p[0]<<24)+(p[1]<<16)+(p[2]<<8)+p[3];
105}
106
12c86877
BH
107
108struct ServiceTuple
109{
110 string host;
092f210a 111 uint16_t port;
12c86877
BH
112};
113void parseService(const string &descr, ServiceTuple &st);
114
115template <typename Container>
116void
117stringtok (Container &container, string const &in,
118 const char * const delimiters = " \t\n")
119{
120 const string::size_type len = in.length();
121 string::size_type i = 0;
122
123 while (i<len) {
124 // eat leading whitespace
125 i = in.find_first_not_of (delimiters, i);
126 if (i == string::npos)
127 return; // nothing left but white space
128
129 // find the end of the token
130 string::size_type j = in.find_first_of (delimiters, i);
131
132 // push token
133 if (j == string::npos) {
134 container.push_back (in.substr(i));
135 return;
136 } else
137 container.push_back (in.substr(i, j-i));
138
139 // set up for next loop
140 i = j + 1;
141 }
142}
8c3149f2
BH
143
144template <typename Container>
145void
146vstringtok (Container &container, string const &in,
147 const char * const delimiters = " \t\n")
148{
149 const string::size_type len = in.length();
150 string::size_type i = 0;
151
152 while (i<len) {
153 // eat leading whitespace
154 i = in.find_first_not_of (delimiters, i);
155 if (i == string::npos)
156 return; // nothing left but white space
157
158 // find the end of the token
159 string::size_type j = in.find_first_of (delimiters, i);
160
161 // push token
162 if (j == string::npos) {
163 container.push_back (make_pair(i, len));
164 return;
165 } else
166 container.push_back (make_pair(i, j));
167
168 // set up for next loop
169 i = j + 1;
170 }
171}
172
040712e0
BH
173int writen2(int fd, const void *buf, size_t count);
174inline int writen2(int fd, const std::string &s) { return writen2(fd, s.data(), s.size()); }
175
176
c3d9d009 177const string toLower(const string &upper);
b0d4fb45 178const string toLowerCanonic(const string &upper);
092f210a 179bool IpToU32(const string &str, uint32_t *ip);
5730f30c 180string U32ToIP(uint32_t);
12c86877 181string stringerror();
d3b4137e 182string netstringerror();
12c86877 183string itoa(int i);
22c9c86a 184string uitoa(unsigned int i);
12c86877
BH
185
186void dropPrivs(int uid, int gid);
187int makeGidNumeric(const string &group);
188int makeUidNumeric(const string &user);
189void cleanSlashes(string &str);
190
191/** The DTime class can be used for timing statistics with microsecond resolution.
192On 32 bits systems this means that 2147 seconds is the longest time that can be measured. */
193class DTime
194{
195public:
eefd15f9 196 DTime(); //!< Does not set the timer for you! Saves lots of gettimeofday() calls
12c86877
BH
197 DTime(const DTime &dt);
198 time_t time();
199 inline void set(); //!< Reset the timer
200 inline int udiff(); //!< Return the number of microseconds since the timer was last set.
88358c9b
BH
201 void setTimeval(const struct timeval& tv)
202 {
203 d_set=tv;
204 }
205 struct timeval getTimeval()
206 {
207 return d_set;
208 }
12c86877
BH
209private:
210 struct timeval d_set;
211};
37d3f960 212const string sockAddrToString(struct sockaddr_in *remote);
12c86877
BH
213int sendData(const char *buffer, int replen, int outsock);
214
12c86877
BH
215inline void DTime::set()
216{
d3b729e8 217 Utility::gettimeofday(&d_set,0);
12c86877
BH
218}
219
220inline int DTime::udiff()
221{
222 struct timeval now;
12c86877 223
d3b729e8 224 Utility::gettimeofday(&now,0);
fe213470
BH
225 int ret=1000000*(now.tv_sec-d_set.tv_sec)+(now.tv_usec-d_set.tv_usec);
226 d_set=now;
227 return ret;
12c86877
BH
228}
229
f5be3a1e
BH
230inline bool dns_isspace(char c)
231{
232 return c==' ' || c=='\t' || c=='\r' || c=='\n';
233}
234
8b3cfcd3 235inline char dns_tolower(char c)
f5be3a1e
BH
236{
237 if(c>='A' && c<='Z')
238 c+='a'-'A';
239 return c;
240}
241
c3d9d009 242inline const string toLower(const string &upper)
12c86877
BH
243{
244 string reply(upper);
c536ca8d
BH
245 char c;
246 for(unsigned int i = 0; i < reply.length(); i++) {
e3cacd48
BH
247 c = dns_tolower(upper[i]);
248 if( c != upper[i])
c536ca8d
BH
249 reply[i] = c;
250 }
12c86877
BH
251 return reply;
252}
253
b0d4fb45
BH
254inline const string toLowerCanonic(const string &upper)
255{
256 string reply(upper);
257 if(!upper.empty()) {
705f31ae 258 unsigned int i, limit= ( unsigned int ) reply.length();
c536ca8d
BH
259 char c;
260 for(i = 0; i < limit ; i++) {
e3cacd48
BH
261 c = dns_tolower(upper[i]);
262 if(c != upper[i])
c536ca8d
BH
263 reply[i] = c;
264 }
e3cacd48 265 if(upper[i-1]=='.')
b0d4fb45
BH
266 reply.resize(i-1);
267 }
268
269 return reply;
270}
271
272
12c86877 273
52936200
BH
274// Make s uppercase:
275inline string toUpper( const string& s )
276{
277 string r(s);
278 for( unsigned int i = 0; i < s.length(); i++ ) {
279 r[i] = toupper( r[i] );
280 }
281 return r;
282}
283
a6d7640a
BH
284inline double getTime()
285{
286 struct timeval now;
287 Utility::gettimeofday(&now,0);
288
289 return now.tv_sec+now.tv_usec/1000000.0;
290}
291
a640a9d4
BH
292inline void unixDie(const string &why)
293{
294 throw runtime_error(why+": "+strerror(errno));
295}
296
2db9c30e 297string makeHexDump(const string& str);
e67e250f 298void shuffle(vector<DNSResourceRecord>& rrs);
88358c9b
BH
299
300void normalizeTV(struct timeval& tv);
301const struct timeval operator+(const struct timeval& lhs, const struct timeval& rhs);
302const struct timeval operator-(const struct timeval& lhs, const struct timeval& rhs);
303inline float makeFloat(const struct timeval& tv)
304{
705f31ae 305 return tv.tv_sec + tv.tv_usec/1000000.0f;
88358c9b 306}
5b0ddd18
BH
307
308inline bool operator<(const struct timeval& lhs, const struct timeval& rhs)
309{
310 return make_pair(lhs.tv_sec, lhs.tv_usec) < make_pair(rhs.tv_sec, rhs.tv_usec);
311}
312
ec6480f3
BH
313inline bool pdns_ilexicographical_compare(const std::string& a, const std::string& b) __attribute__((pure));
314inline bool pdns_ilexicographical_compare(const std::string& a, const std::string& b)
7738a23f 315{
ec6480f3
BH
316 string::size_type aLen = a.length(), bLen = b.length(), n;
317 const char *aPtr = a.c_str(), *bPtr = b.c_str();
318 int result;
319
320 for(n = 0 ; n < aLen && n < bLen ; ++n) {
321 if((result = dns_tolower(*aPtr++) - dns_tolower(*bPtr++))) {
322 return result < 0;
323 }
7738a23f 324 }
ec6480f3
BH
325 if(n == aLen && n == bLen) // strings are equal (in length)
326 return 0;
327 if(n == aLen) // first string was shorter
328 return true;
329 return false;
330}
eff65ff8 331
ec6480f3
BH
332inline bool pdns_iequals(const std::string& a, const std::string& b) __attribute__((pure));
333
334inline bool pdns_iequals(const std::string& a, const std::string& b)
335{
336 string::size_type aLen = a.length(), bLen = b.length(), n;
337 const char *aPtr = a.c_str(), *bPtr = b.c_str();
338
339 for(n = 0 ; n < aLen && n < bLen ; ++n) {
340 if(dns_tolower(*aPtr++) != dns_tolower(*bPtr++))
341 return false;
eff65ff8 342 }
ec6480f3
BH
343 return aLen == bLen; // strings are equal (in length)
344}
345
eff65ff8 346
ec6480f3
BH
347struct CIStringCompare: public binary_function<string, string, bool>
348{
349 bool operator()(const string& a, const string& b) const
eff65ff8 350 {
ec6480f3 351 return pdns_ilexicographical_compare(a, b);
eff65ff8 352 }
7738a23f 353};
eff65ff8 354
50c79a76 355pair<string, string> splitField(const string& inp, char sepa);
26cd1b3f
BH
356
357inline bool isCanonical(const string& dom)
358{
359 if(dom.empty())
360 return false;
361 return dom[dom.size()-1]=='.';
362}
363
364inline string toCanonic(const string& zone, const string& domain)
365{
366 if(isCanonical(domain))
367 return domain;
368 string ret=domain;
369 ret.append(1,'.');
4d2c97aa
BH
370 if(!zone.empty() && zone[0]!='.')
371 ret.append(zone);
26cd1b3f
BH
372 return ret;
373}
da042e6e 374
f8c44754
BH
375inline void setSocketReusable(int fd)
376{
377 int tmp=1;
378 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&tmp, static_cast<unsigned>(sizeof tmp));
379}
380
da042e6e 381string stripDot(const string& dom);
a28a204a 382void seedRandom(const string& source);
12c86877 383#endif