]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/misc.cc
was very outdated
[thirdparty/pdns.git] / pdns / misc.cc
CommitLineData
12c86877
BH
1/*
2 PowerDNS Versatile Database Driven Nameserver
3 Copyright (C) 2002 PowerDNS.COM BV
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
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
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18*/
19#include "misc.hh"
20#include <vector>
21#include <sstream>
22#include <errno.h>
1258abe0 23#include <cstring>
c4bee46c 24#include <iostream>
1258abe0 25
12c86877 26#include <iomanip>
12c86877
BH
27#include <string.h>
28#include <stdlib.h>
29#include <stdio.h>
52936200 30#include "ahuexception.hh"
c6566265 31#include <sys/types.h>
1258abe0
BH
32
33#ifndef WIN32
c6566265
BH
34# include <sys/param.h>
35# include <netdb.h>
1258abe0
BH
36# include <sys/time.h>
37# include <time.h>
12c86877
BH
38# include <netinet/in.h>
39# include <unistd.h>
05bf052c
BH
40#else
41# include <time.h>
1258abe0 42#endif // WIN32
12c86877
BH
43
44#include "utility.hh"
45
cc3afe25
BH
46string nowTime()
47{
48 time_t now=time(0);
49 string t=ctime(&now);
50 chomp(t,"\n");
51 return t;
52}
12c86877 53
0d8612f2
BH
54u_int16_t getShort(const unsigned char *p)
55{
56 return p[0] * 256 + p[1];
57}
58
59
60u_int16_t getShort(const char *p)
61{
62 return getShort((const unsigned char *)p);
63}
64
b636533b
BH
65u_int32_t getLong(const unsigned char* p)
66{
67 return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3];
68}
69
70u_int32_t getLong(const char* p)
71{
72 return getLong((unsigned char *)p);
73}
74
0d8612f2
BH
75
76
f2c11a48
BH
77/** strips a domain suffix from a domain, returns true if it stripped */
78bool stripDomainSuffix(string *qname, const string &domain)
79{
c4bee46c 80 if(!endsOn(*qname, domain))
f2c11a48
BH
81 return false;
82
c4bee46c 83 if(toLower(*qname)==toLower(domain))
f2c11a48
BH
84 *qname="@";
85 else {
86 if((*qname)[qname->size()-domain.size()-1]!='.')
87 return false;
88
89 qname->resize(qname->size()-domain.size()-1);
90 }
91 return true;
92}
93
728485ca
BH
94/** Chops off the start of a domain, so goes from 'www.ds9a.nl' to 'ds9a.nl' to ''. Return zero on the empty string */
95bool chopOff(string &domain)
96{
97 if(domain.empty())
98 return false;
99
100 string::size_type fdot=domain.find('.');
101
102 if(fdot==string::npos)
103 domain="";
104 else
105 domain=domain.substr(fdot+1);
106 return true;
107}
108
109/** does domain end on suffix? Is smart about "wwwds9a.nl" "ds9a.nl" not matching */
110bool endsOn(const string &domain, const string &suffix)
111{
20177d1d 112 if(toLower(domain)==toLower(suffix) || suffix.empty())
728485ca
BH
113 return true;
114 if(domain.size()<=suffix.size())
115 return false;
20177d1d 116 return (toLower(domain.substr(domain.size()-suffix.size()-1,suffix.size()+1))=="."+toLower(suffix));
728485ca
BH
117}
118
f2c11a48 119
12c86877
BH
120int sendData(const char *buffer, int replen, int outsock)
121{
122 u_int16_t nlen=htons(replen);
123 Utility::iovec iov[2];
124 iov[0].iov_base=(char*)&nlen;
125 iov[0].iov_len=2;
126 iov[1].iov_base=(char*)buffer;
127 iov[1].iov_len=replen;
128 int ret=Utility::writev(outsock,iov,2);
129
130 if(ret<0) {
131 return -1;
132 }
133 if(ret!=replen+2) {
134 return -1;
135 }
136 return 0;
137}
138
139
140void parseService(const string &descr, ServiceTuple &st)
141{
52936200 142
12c86877
BH
143 vector<string>parts;
144 stringtok(parts,descr,":");
52936200
BH
145 if(parts.empty())
146 throw AhuException("Unable to parse '"+descr+"' as a service");
12c86877
BH
147 st.host=parts[0];
148 if(parts.size()>1)
149 st.port=atoi(parts[1].c_str());
150}
151
12c86877
BH
152
153int waitForData(int fd, int seconds)
154{
1258abe0
BH
155 struct timeval tv;
156 int ret;
157
158 tv.tv_sec = seconds;
159 tv.tv_usec = 0;
160
161 fd_set readfds;
162 FD_ZERO( &readfds );
163 FD_SET( fd, &readfds );
164
165 ret = select( fd + 1, &readfds, NULL, NULL, &tv );
166 if ( ret == -1 )
167 {
168 ret = -1;
169 errno = ETIMEDOUT;
170 }
171
12c86877
BH
172 return ret;
173}
174
175
176string humanDuration(time_t passed)
177{
178 ostringstream ret;
179 if(passed<60)
180 ret<<passed<<" seconds";
181 else if(passed<3600)
182 ret<<setprecision(2)<<passed/60.0<<" minutes";
183 else if(passed<86400)
184 ret<<setprecision(3)<<passed/3600.0<<" hours";
185 else if(passed<(86400*30.41))
186 ret<<setprecision(3)<<passed/86400.0<<" days";
187 else
188 ret<<setprecision(3)<<passed/(86400*30.41)<<" months";
189
190 return ret.str();
191}
192
193DTime::DTime()
194{
195// set();
196}
197
198DTime::DTime(const DTime &dt)
199{
200 d_set=dt.d_set;
201}
202
203time_t DTime::time()
204{
205 return d_set.tv_sec;
206}
207
12c86877
BH
208
209void chomp(string &line, const string &delim)
210{
211 string::reverse_iterator i;
212 for( i=line.rbegin();i!=line.rend();++i)
213 if(delim.find(*i)==string::npos)
214 break;
215
216 line.resize(line.rend()-i);
217}
218
219
1d329048
BH
220const string unquotify(const string &item)
221{
222 if(item.size()<2)
223 return item;
224
225 string::size_type bpos=0, epos=item.size();
12c86877 226
c4bee46c 227 if(item[0]=='"')
1d329048 228 bpos=1;
c4bee46c 229
1d329048
BH
230 if(item[epos-1]=='"')
231 epos-=1;
232
c4bee46c 233 return item.substr(bpos,epos-bpos);
1d329048 234}
12c86877
BH
235
236void stripLine(string &line)
237{
bdf40704 238 string::size_type pos=line.find_first_of("\r\n");
12c86877
BH
239 if(pos!=string::npos) {
240 line.resize(pos);
241 }
242}
243
244string urlEncode(const string &text)
245{
246 string ret;
247 for(string::const_iterator i=text.begin();i!=text.end();++i)
248 if(*i==' ')ret.append("%20");
249 else ret.append(1,*i);
250 return ret;
251}
252
253string getHostname()
254{
ac2bb9e7
BH
255#ifdef WIN32
256# define MAXHOSTNAMELEN 1025
257#endif // WIN32
258
12c86877
BH
259 char tmp[MAXHOSTNAMELEN];
260 if(gethostname(tmp, MAXHOSTNAMELEN))
261 return "UNKNOWN";
262
263 return tmp;
264}
265
266string itoa(int i)
267{
268 ostringstream o;
269 o<<i;
270 return o.str();
271}
272
273string stringerror()
274{
275 return strerror(errno);
276}
277
278void cleanSlashes(string &str)
279{
280 string::const_iterator i;
281 string out;
282 for(i=str.begin();i!=str.end();++i) {
283 if(*i=='/' && i!=str.begin() && *(i-1)=='/')
284 continue;
285 out.append(1,*i);
286 }
287 str=out;
288}
289
7b35aa49 290
525b8a7c
BH
291bool IpToU32(const string &str, u_int32_t *ip)
292{
092c9cc4 293 struct in_addr inp;
ebc9a1c2 294 if(Utility::inet_aton(str.c_str(), &inp)) {
092c9cc4
BH
295 *ip=inp.s_addr;
296 return true;
297 }
298 return false;
525b8a7c
BH
299}
300
ac2bb9e7 301const string sockAddrToString(struct sockaddr_in *remote, Utility::socklen_t socklen)
12c86877 302{
7b35aa49
BH
303 if(socklen==sizeof(struct sockaddr_in)) {
304 struct sockaddr_in sip;
305 memcpy(&sip,(struct sockaddr_in*)remote,sizeof(sip));
306 return inet_ntoa(sip.sin_addr);
307 }
1258abe0 308#ifdef HAVE_IPV6
12c86877
BH
309 else {
310 char tmp[128];
311
ac2bb9e7 312 if(!Utility::inet_ntop(AF_INET6, ( const char * ) &((struct sockaddr_in6 *)remote)->sin6_addr, tmp, sizeof(tmp)))
12c86877
BH
313 return "IPv6 untranslateable";
314
315 return tmp;
316 }
1258abe0 317#endif
12c86877
BH
318
319 return "untranslateable";
320}