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