~ubuntu-branches/ubuntu/maverick/pdns/maverick-updates

« back to all changes in this revision

Viewing changes to pdns/rcpgenerator.cc

  • Committer: Bazaar Package Importer
  • Author(s): Matthijs Mohlmann, Matthijs Mohlmann, Christoph Haas
  • Date: 2007-04-15 23:23:39 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070415232339-5x3scc8gx04e50um
Tags: 2.9.21-1
[ Matthijs Mohlmann ]
* New upstream release. (Closes: #420294)
* Remove meta pdns package.
* Added new sqlite3 backend package.
* Months and minutes where mixed up. (Closes: #406462)
* Case sensitivity in bind backend caused PowerDNS to not serve a certain
  zone. (Closes: #406461)
* Bind backend forgot about zones on a notify. (Closes: #398213)

[ Christoph Haas ]
* Documented incorporated backend bind. (Closes: #415471)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
    PowerDNS Versatile Database Driven Nameserver
3
 
    Copyright (C) 2005  PowerDNS.COM BV
 
3
    Copyright (C) 2005 - 2007 PowerDNS.COM BV
4
4
 
5
5
    This program is free software; you can redistribute it and/or modify
6
6
    it under the terms of the GNU General Public License version 2 as 
13
13
 
14
14
    You should have received a copy of the GNU General Public License
15
15
    along with this program; if not, write to the Free Software
16
 
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
17
*/
18
18
 
19
19
#include "rcpgenerator.hh"
57
57
  tm.tm_year-=1900;
58
58
  tm.tm_min-=1;
59
59
  
60
 
  val=mktime(&tm);
 
60
  val=(uint32_t)mktime(&tm);
61
61
}
62
62
 
63
63
void RecordTextReader::xfrIP(uint32_t &val)
65
65
  skipSpaces();
66
66
 
67
67
  if(!isdigit(d_string.at(d_pos)))
68
 
    throw RecordTextException("expected digits at position "+lexical_cast<string>(d_pos)+" in '"+d_string+"'");
 
68
    throw RecordTextException("while parsing IP address, expected digits at position "+lexical_cast<string>(d_pos)+" in '"+d_string+"'");
 
69
 
 
70
  uint32_t octet=0;
 
71
  val=0;
 
72
  char count=0;
69
73
  
70
 
  string ip;
71
 
  xfrLabel(ip);
72
 
  if(!IpToU32(ip, &val))
73
 
    throw RecordTextException("unable to parse IP address '"+ip+"'");
 
74
  for(;;) {
 
75
    if(d_string.at(d_pos)=='.') {
 
76
      val<<=8;
 
77
      val+=octet;
 
78
      octet=0;
 
79
      count++;
 
80
      if(count > 3)
 
81
        break;
 
82
    }
 
83
    else if(isdigit(d_string.at(d_pos))) {
 
84
      octet*=10;
 
85
      octet+=d_string.at(d_pos) - '0';
 
86
      if(octet > 255)
 
87
        throw RecordTextException("unable to parse IP address");
 
88
    }
 
89
    else if(dns_isspace(d_string.at(d_pos))) 
 
90
      break;
 
91
    else
 
92
      throw RecordTextException("unable to parse IP address, strange character: "+d_string.at(d_pos));
 
93
 
 
94
    d_pos++;
 
95
    if(d_pos == d_string.length())
 
96
      break;
 
97
  }
 
98
  if(count<=3) {
 
99
    val<<=8;
 
100
    val+=octet;
 
101
  }
 
102
  val=ntohl(val);
74
103
}
75
104
 
76
105
 
97
126
    throw RecordTextException("Overflow reading 8 bit integer from record content"); // fixme improve
98
127
}
99
128
 
100
 
 
101
 
void RecordTextReader::xfrLabel(string& val, bool)
 
129
void RecordTextReader::xfrLabel(string& val, bool) 
102
130
{
103
131
  skipSpaces();
104
 
 
105
132
  val.clear();
106
133
  val.reserve(d_end - d_pos);
107
134
 
 
135
  const char* strptr=d_string.c_str();
108
136
  while(d_pos < d_end) {
109
 
    if(dns_isspace(d_string[d_pos]))
 
137
    if(dns_isspace(strptr[d_pos]))
110
138
      break;
111
139
 
112
 
    if(d_string[d_pos]=='\\' && d_pos < d_end - 1) 
 
140
    if(strptr[d_pos]=='\\' && d_pos < d_end - 1 && strptr[d_pos+1]!='.')  // leave the \. escape around
113
141
      d_pos++;
114
142
 
115
 
    val.append(1, d_string[d_pos]);      
 
143
    val.append(1, strptr[d_pos]);      
116
144
    d_pos++;
117
145
  }
118
146
 
131
159
void RecordTextReader::xfrBlob(string& val)
132
160
{
133
161
  skipSpaces();
134
 
  int pos=d_pos;
135
 
  while(d_pos < d_end && !dns_isspace(d_string[d_pos]))
 
162
  int pos=(int)d_pos;
 
163
  const char* strptr=d_string.c_str();
 
164
  while(d_pos < d_end && !dns_isspace(strptr[d_pos]))
136
165
    d_pos++;
137
166
 
138
167
  string tmp;
141
170
  B64Decode(tmp, val);
142
171
}
143
172
 
144
 
void RecordTextReader::xfrText(string& val)
 
173
 
 
174
static inline uint8_t hextodec(uint8_t val)
 
175
{
 
176
  if(val >= '0' && val<='9')
 
177
    return val-'0';
 
178
  else if(val >= 'A' && val<='F')
 
179
    return 10+(val-'A');
 
180
  else if(val >= 'a' && val<='f')
 
181
    return 10+(val-'a');
 
182
  else
 
183
    throw RecordTextException("Unknown hexadecimal character '"+lexical_cast<string>(val)+"'");
 
184
}
 
185
 
 
186
 
 
187
void HEXDecode(const char* begin, const char* end, string& val)
 
188
{
 
189
  if((end - begin)%2)
 
190
    throw RecordTextException("Hexadecimal blob with odd number of characters");
 
191
 
 
192
  int limit=(int)(end-begin)/2;
 
193
  val.resize(limit);
 
194
  for(int n=0; n < limit; ++n) {
 
195
    val[n] = hextodec(begin[2*n])*16 + hextodec(begin[2*n+1]); 
 
196
  }
 
197
}
 
198
 
 
199
void RecordTextReader::xfrHexBlob(string& val)
145
200
{
146
201
  skipSpaces();
147
 
  if(d_string[d_pos]!='"')
148
 
    throw RecordTextException("Data field in DNS should start with quote (\") at position "+lexical_cast<string>(d_pos)+" of '"+d_string+"'");
149
 
 
 
202
  int pos=(int)d_pos;
 
203
  while(d_pos < d_end && !dns_isspace(d_string[d_pos]))
 
204
    d_pos++;
 
205
 
 
206
  HEXDecode(d_string.c_str()+pos, d_string.c_str() + d_pos, val);
 
207
}
 
208
 
 
209
void RecordTextReader::xfrText(string& val, bool multi)
 
210
{
150
211
  val.clear();
151
212
  val.reserve(d_end - d_pos);
152
 
  
153
 
  while(++d_pos < d_end && d_string[d_pos]!='"') {
154
 
    if(d_string[d_pos]=='\\' && d_pos+1!=d_end) {
155
 
      ++d_pos;
 
213
 
 
214
  while(d_pos != d_end) {
 
215
    if(!val.empty())
 
216
      val.append(1, ' ');
 
217
 
 
218
    skipSpaces();
 
219
    if(d_string[d_pos]!='"')
 
220
      throw RecordTextException("Data field in DNS should start with quote (\") at position "+lexical_cast<string>(d_pos)+" of '"+d_string+"'");
 
221
 
 
222
    val.append(1, '"');
 
223
    while(++d_pos < d_end && d_string[d_pos]!='"') {
 
224
      if(d_string[d_pos]=='\\' && d_pos+1!=d_end) {
 
225
        val.append(1, d_string[d_pos++]);
 
226
      }
 
227
      val.append(1, d_string[d_pos]);
156
228
    }
157
 
    val.append(1, d_string[d_pos]);
 
229
    val.append(1,'"');
 
230
    if(d_pos == d_end)
 
231
      throw RecordTextException("Data field in DNS should end on a quote (\") in '"+d_string+"'");
 
232
    d_pos++;
 
233
    if(!multi)
 
234
      break;
158
235
  }
159
 
  if(d_pos == d_end)
160
 
    throw RecordTextException("Data field in DNS should end on a quote (\") in '"+d_string+"'");
161
 
  d_pos++;
162
236
}
163
237
 
164
238
void RecordTextReader::xfrType(uint16_t& val)
165
239
{
166
240
  skipSpaces();
167
 
  int pos=d_pos;
 
241
  int pos=(int)d_pos;
168
242
  while(d_pos < d_end && !dns_isspace(d_string[d_pos]))
169
243
    d_pos++;
170
244
 
177
251
 
178
252
void RecordTextReader::skipSpaces()
179
253
{
180
 
  while(d_pos < d_end && dns_isspace(d_string[d_pos]))
 
254
  const char* strptr = d_string.c_str();
 
255
  while(d_pos < d_end && dns_isspace(strptr[d_pos]))
181
256
    d_pos++;
182
 
 
183
257
  if(d_pos == d_end)
184
258
    throw RecordTextException("missing field at the end of record content '"+d_string+"'");
185
259
}
213
287
    d_string.append(1,' ');
214
288
 
215
289
  char tmp[17];
216
 
  snprintf(tmp, sizeof(tmp)-1, "%u.%u.%u.%u", 
217
 
           (val >> 24)&0xff,
218
 
           (val >> 16)&0xff,
219
 
           (val >>  8)&0xff,
220
 
           (val      )&0xff);
221
 
  
222
 
  d_string+=tmp;
 
290
  uint32_t ip=htonl(val);
 
291
  uint8_t vals[4];
 
292
 
 
293
  memcpy(&vals[0], &ip, sizeof(ip));
 
294
 
 
295
  char *pos=tmp;
 
296
 
 
297
  for(int n=0; n < 4; ++n) {
 
298
    if(vals[n]<10) {
 
299
      *(pos++)=vals[n]+'0';
 
300
    } else if(vals[n] < 100) {
 
301
      *(pos++)=(vals[n]/10) +'0';
 
302
      *(pos++)=(vals[n]%10) +'0';
 
303
    } else {
 
304
      *(pos++)=(vals[n]/100) +'0';
 
305
      vals[n]%=100;
 
306
      *(pos++)=(vals[n]/10) +'0';
 
307
      *(pos++)=(vals[n]%10) +'0';
 
308
    }
 
309
    if(n!=3)
 
310
      *(pos++)='.';
 
311
  }
 
312
  *pos=0;
 
313
  d_string.append(tmp, pos);
223
314
}
224
315
 
225
316
 
230
321
  
231
322
  struct tm tm;
232
323
  time_t time=val; // Y2038 bug!
 
324
#ifndef WIN32
233
325
  gmtime_r(&time, &tm);
 
326
#else
 
327
  struct tm* tmptr;
 
328
  tmptr=gmtime(&time);
 
329
  if(!tmptr)
 
330
    throw RecordTextException("Unable to convert timestamp into pretty printable time");
 
331
  tm=*tmptr;
 
332
#endif
234
333
  
235
334
  char tmp[16];
236
335
  snprintf(tmp,sizeof(tmp)-1, "%04d%02d%02d" "%02d%02d%02d", 
268
367
      else
269
368
        d_string.append(1,val[pos]);
270
369
  }
271
 
  d_string.append(1,'.');
 
370
  //  d_string.append(1,'.');
272
371
}
273
372
 
274
373
void RecordTextWriter::xfrBlob(const string& val)
279
378
  d_string+=Base64Encode(val);
280
379
}
281
380
 
282
 
void RecordTextWriter::xfrText(const string& val)
 
381
void RecordTextWriter::xfrHexBlob(const string& val)
283
382
{
284
383
  if(!d_string.empty())
285
384
    d_string.append(1,' ');
286
 
  d_string.append(1,'"');
287
385
 
288
 
  if(val.find_first_of("\\\"") == string::npos)
289
 
    d_string+=val;
290
 
  else {
291
 
    string::size_type end=val.size();
292
 
    
293
 
    for(string::size_type pos=0; pos < end; ++pos) {
294
 
      if(val[pos]=='\'' || val[pos]=='"')
295
 
        d_string.append(1,'\\');
296
 
      d_string.append(1, val[pos]);
297
 
    }
 
386
  string::size_type limit=val.size();
 
387
  char tmp[5];
 
388
  for(string::size_type n = 0; n < limit; ++n) {
 
389
    snprintf(tmp, sizeof(tmp)-1, "%02x", (unsigned char)val[n]);
 
390
    d_string+=tmp;
298
391
  }
299
 
 
300
 
  d_string.append(1,'"');
 
392
}
 
393
 
 
394
void RecordTextWriter::xfrText(const string& val, bool multi)
 
395
{
 
396
  if(!d_string.empty())
 
397
    d_string.append(1,' ');
 
398
 
 
399
  d_string.append(val);
301
400
}
302
401
 
303
402