]>
Commit | Line | Data |
---|---|---|
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 | ||
11 | CDB::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 | ||
29 | CDB::~CDB() { | |
30 | cdb_free(&d_cdb); | |
31 | close(d_fd); | |
32 | } | |
33 | ||
34 | int 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 | ||
43 | bool 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 | ||
58 | void CDB::searchAll() { | |
59 | d_searchType = SearchAll; | |
60 | cdb_seqinit(&d_seqPtr, &d_cdb); | |
61 | } | |
62 | ||
63 | bool 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 | ||
73 | bool 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 | ||
112 | vector<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 | } |