root/trunk/pdns/pdns/misc.cc @ 124

Revision 124, 6.6 KB (checked in by ahu, 10 years ago)

oops

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