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