]> git.ipfire.org Git - thirdparty/pdns.git/blame - modules/tinydnsbackend/cdb.cc
Include config.h only in .cc files
[thirdparty/pdns.git] / modules / tinydnsbackend / cdb.cc
CommitLineData
870a0fe4
AT
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
ddee6d08
PD
4#include "cdb.hh"
5#include <cdb.h>
21e99384
RK
6#include "pdns/misc.hh"
7#include "pdns/iputils.hh"
ddee6d08
PD
8#include <utility>
9
10
11CDB::CDB(const string &cdbfile)
12{
13
14 d_fd = open(cdbfile.c_str(), O_RDONLY);
15 if (d_fd < 0)
16 {
17 L<<Logger::Error<<"Failed to open cdb database file '"<<cdbfile<<"'. Error: "<<stringerror()<<endl;
3f81d239 18 throw new PDNSException("Failed to open cdb database file '"+cdbfile+"'. Error: " + stringerror());
ddee6d08
PD
19 }
20
21 int cdbinit = cdb_init(&d_cdb, d_fd);
22 if (cdbinit < 0)
23 {
24 L<<Logger::Error<<"Failed to initialize cdb structure. ErrorNr: '"<<cdbinit<<endl;
3f81d239 25 throw new PDNSException("Failed to initialize cdb structure.");
ddee6d08
PD
26 }
27}
28
29CDB::~CDB() {
30 cdb_free(&d_cdb);
31 close(d_fd);
32}
33
34int CDB::searchKey(const string &key) {
35 d_searchType = SearchKey;
36
37 // A 'bug' in tinycdb (the lib used for reading the CDB files) means we have to copy the key because the cdb_find struct
38 // keeps a pointer to it.
39 d_key = strdup(key.c_str());
40 return cdb_findinit(&d_cdbf, &d_cdb, d_key, key.size());
41}
42
43bool CDB::searchSuffix(const string &key) {
44 d_searchType = SearchSuffix;
45
46 //See CDB::searchKey()
47 d_key = strdup(key.c_str());
48
7c696097 49 // We are ok with a search on things, but we do want to know if a record with that key exists.........
ddee6d08
PD
50 bool hasDomain = (cdb_find(&d_cdb, key.c_str(), key.size()) == 1);
51 if (hasDomain) {
52 cdb_seqinit(&d_seqPtr, &d_cdb);
53 }
54
55 return hasDomain;
56}
57
58void CDB::searchAll() {
59 d_searchType = SearchAll;
60 cdb_seqinit(&d_seqPtr, &d_cdb);
61}
62
63bool CDB::moveToNext() {
64 int hasNext = 0;
65 if (d_searchType == SearchKey) {
66 hasNext = cdb_findnext(&d_cdbf);
67 } else {
68 hasNext = cdb_seqnext(&d_seqPtr, &d_cdb);
69 }
70 return (hasNext > 0);
71}
72
73bool CDB::readNext(pair<string, string> &value) {
74 while (moveToNext()) {
75 unsigned int pos;
76 unsigned int len;
77
78 pos = cdb_keypos(&d_cdb);
79 len = cdb_keylen(&d_cdb);
80
81 char *key = (char *)malloc(len);
82 cdb_read(&d_cdb, key, len, pos);
83
84 if (d_searchType == SearchSuffix) {
85 char *p = strstr(key, d_key);
86 if (p == NULL) {
87 free(key);
88 continue;
89 }
90 }
91 string skey(key, len);
92 free(key);
93
94 pos = cdb_datapos(&d_cdb);
95 len = cdb_datalen(&d_cdb);
96 char *val = (char *)malloc(len);
97 cdb_read(&d_cdb, val, len, pos);
98 string sval(val, len);
99 free(val);
100
101 value = make_pair(skey, sval);
102 return true;
103 }
104 // We're done searching, so we can clean up d_key
105 if (d_searchType != SearchAll) {
106 free(d_key);
107 }
108 return false;
109}
110
111
112vector<string> CDB::findall(string &key)
113{
114 vector<string> ret;
115 struct cdb_find cdbf;
116
117 cdb_findinit(&cdbf, &d_cdb, key.c_str(), key.size());
118 int x=0;
119 while(cdb_findnext(&cdbf) > 0) {
120 x++;
121 unsigned int vpos = cdb_datapos(&d_cdb);
122 unsigned int vlen = cdb_datalen(&d_cdb);
123 char *val = (char *)malloc(vlen);
124 cdb_read(&d_cdb, val, vlen, vpos);
125 string sval(val, vlen);
126 ret.push_back(sval);
127 free(val);
128 }
129 return ret;
130}