• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PowerDNS / pdns / 12321902803

13 Dec 2024 07:34PM UTC coverage: 66.359% (+1.6%) from 64.78%
12321902803

Pull #14970

github

web-flow
Merge e3a7df61c into 3dfd8e317
Pull Request #14970: boost > std optional

26084 of 54744 branches covered (47.65%)

Branch coverage included in aggregate %.

14 of 15 new or added lines in 2 files covered. (93.33%)

1863 existing lines in 52 files now uncovered.

85857 of 113946 relevant lines covered (75.35%)

4412729.59 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

34.95
/pdns/cdb.cc
1
/*
2
 * This file is part of PowerDNS or dnsdist.
3
 * Copyright -- PowerDNS.COM B.V. and its contributors
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of version 2 of the GNU General Public License as
7
 * published by the Free Software Foundation.
8
 *
9
 * In addition, for the avoidance of any doubt, permission is granted to
10
 * link this program with OpenSSL and to (re)distribute the binaries
11
 * produced as the result of such linking.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
 */
22
#ifdef HAVE_CONFIG_H
23
#include "config.h"
24
#endif
25

26
#include <sys/types.h>
27
#include <sys/stat.h>
28
#include <fcntl.h>
29
#include <unistd.h>
30

31
#include "cdb.hh"
32

33
CDB::CDB(const string &cdbfile)
34
{
214✔
35
  d_fd = open(cdbfile.c_str(), O_RDONLY);
214✔
36
  if (d_fd < 0)
214!
37
  {
×
38
    throw std::runtime_error("Failed to open cdb database file '"+cdbfile+"': " + stringerror());
×
39
  }
×
40

41
  memset(&d_cdbf,0,sizeof(struct cdb_find));
214✔
42
  int cdbinit = cdb_init(&d_cdb, d_fd);
214✔
43
  if (cdbinit < 0)
214!
44
  {
×
45
    close(d_fd);
×
46
    d_fd = -1;
×
47
    throw std::runtime_error("Failed to initialize cdb structure for database '+cdbfile+': '" + std::to_string(cdbinit) + "'");
×
48
  }
×
49
}
214✔
50

51
CDB::~CDB() {
214✔
52
  cdb_free(&d_cdb);
214✔
53
  close(d_fd);
214✔
54
}
214✔
55

56
int CDB::searchKey(const string &key) {
213✔
57
  d_searchType = SearchKey;
213✔
58

59
  // A 'bug' in tinycdb (the lib used for reading the CDB files) means we have to copy the key because the cdb_find struct
60
  // keeps a pointer to it.
61
  d_key = key;
213✔
62
  return cdb_findinit(&d_cdbf, &d_cdb, d_key.c_str(), d_key.size());
213✔
63
}
213✔
64

65
bool CDB::searchSuffix(const string &key) {
×
66
  d_searchType = SearchSuffix;
×
67

68
  //See CDB::searchKey()
69
  d_key = key;
×
70

71
  // We are ok with a search on things, but we do want to know if a record with that key exists.........
72
  bool hasDomain = (cdb_find(&d_cdb, d_key.c_str(), d_key.size()) == 1);
×
73
  if (hasDomain) {
×
74
    cdb_seqinit(&d_seqPtr, &d_cdb);
×
75
  }
×
76

77
  return hasDomain;
×
78
}
×
79

80
void CDB::searchAll() {
1✔
81
  d_searchType = SearchAll;
1✔
82
  cdb_seqinit(&d_seqPtr, &d_cdb);
1✔
83
}
1✔
84

85
bool CDB::moveToNext() {
20,834✔
86
  int hasNext = 0;
20,834✔
87
  if (d_searchType == SearchKey) {
20,834✔
88
    hasNext = cdb_findnext(&d_cdbf);
504✔
89
  } else {
20,330✔
90
    hasNext = cdb_seqnext(&d_seqPtr, &d_cdb);
20,330✔
91
  }
20,330✔
92
  return (hasNext > 0);
20,834✔
93
}
20,834✔
94

95
bool CDB::readNext(pair<string, string> &value) {
20,834✔
96
  while (moveToNext()) {
20,834✔
97
    unsigned int pos;
20,620✔
98
    unsigned int len;
20,620✔
99

100
    pos = cdb_keypos(&d_cdb);
20,620✔
101
    len = cdb_keylen(&d_cdb);
20,620✔
102

103
    std::string key;
20,620✔
104
    key.resize(len);
20,620✔
105
    int ret = cdb_read(&d_cdb, &key[0], len, pos);
20,620✔
106
    if (ret < 0) {
20,620!
107
      throw std::runtime_error("Error while reading key for key '" + key + "' from CDB database: " + std::to_string(ret));
×
108
    }
×
109

110
    if (d_searchType == SearchSuffix) {
20,620!
111
      char *p = strstr(const_cast<char*>(key.c_str()), d_key.c_str());
×
112
      if (p == nullptr) {
×
113
        continue;
×
114
      }
×
115
    }
×
116

117
    pos = cdb_datapos(&d_cdb);
20,620✔
118
    len = cdb_datalen(&d_cdb);
20,620✔
119
    std::string val;
20,620✔
120
    val.resize(len);
20,620✔
121
    ret = cdb_read(&d_cdb, &val[0], len, pos);
20,620✔
122
    if (ret < 0) {
20,620!
123
      throw std::runtime_error("Error while reading value for key '" + key + "' from CDB database: " + std::to_string(ret));
×
124
    }
×
125

126
    value = {std::move(key), std::move(val)};
20,620✔
127
    return true;
20,620✔
128
  }
20,620✔
129

130
  // We're done searching, so we can clean up d_key
131
  if (d_searchType != SearchAll) {
214✔
132
    d_key.clear();
213✔
133
  }
213✔
134

135
  return false;
214✔
136
}
20,834✔
137

138
vector<string> CDB::findall(string &key)
139
{
×
140
  vector<string> ret;
×
141
  struct cdb_find cdbf;
×
142

143
  int res = cdb_findinit(&cdbf, &d_cdb, key.c_str(), key.size());
×
144
  if (res < 0) {
×
145
    throw std::runtime_error("Error looking up key '" + key + "' from CDB database: " + std::to_string(res));
×
146
  }
×
147

148
  while(cdb_findnext(&cdbf) > 0) {
×
149
    unsigned int vpos = cdb_datapos(&d_cdb);
×
150
    unsigned int vlen = cdb_datalen(&d_cdb);
×
151
    std::string val;
×
152
    val.resize(vlen);
×
153
    res = cdb_read(&d_cdb, &val[0], vlen, vpos);
×
154
    if (res < 0) {
×
155
      throw std::runtime_error("Error while reading value for key '" + key + "' from CDB database: " + std::to_string(res));
×
156
    }
×
157
    ret.push_back(std::move(val));
×
158
  }
×
159

160
  return ret;
×
161
}
×
162

163
bool CDB::keyExists(const string& key)
UNCOV
164
{
×
UNCOV
165
  int ret = cdb_find(&d_cdb, key.c_str(), key.size());
×
UNCOV
166
  if (ret < 0) {
×
167
    throw std::runtime_error("Error while looking up key '" + key + "' from CDB database: " + std::to_string(ret));
×
168
  }
×
UNCOV
169
  if (ret == 0) {
×
170
    /* no such key */
UNCOV
171
    return false;
×
UNCOV
172
  }
×
173

UNCOV
174
  return true;
×
UNCOV
175
}
×
176

177
bool CDB::findOne(const string& key, string& value)
UNCOV
178
{
×
UNCOV
179
  if (!keyExists(key)) {
×
UNCOV
180
    return false;
×
UNCOV
181
  }
×
182

UNCOV
183
  unsigned int vpos = cdb_datapos(&d_cdb);
×
UNCOV
184
  unsigned int vlen = cdb_datalen(&d_cdb);
×
UNCOV
185
  value.resize(vlen);
×
UNCOV
186
  int ret = cdb_read(&d_cdb, &value[0], vlen, vpos);
×
UNCOV
187
  if (ret < 0) {
×
188
    throw std::runtime_error("Error while reading value for key '" + key + "' from CDB database: " + std::to_string(ret));
×
189
  }
×
190

UNCOV
191
  return true;
×
UNCOV
192
}
×
193

194
CDBWriter::CDBWriter(int fd): d_fd(fd)
UNCOV
195
{
×
UNCOV
196
  cdb_make_start(&d_cdbm, d_fd);
×
UNCOV
197
}
×
198

199
CDBWriter::~CDBWriter()
UNCOV
200
{
×
UNCOV
201
  close();
×
UNCOV
202
}
×
203

204
void CDBWriter::close()
UNCOV
205
{
×
UNCOV
206
  if (d_fd >= 0) {
×
UNCOV
207
    cdb_make_finish(&d_cdbm);
×
UNCOV
208
    ::close(d_fd);
×
UNCOV
209
    d_fd = -1;
×
UNCOV
210
  }
×
UNCOV
211
}
×
212

213
bool CDBWriter::addEntry(const std::string& key, const std::string& value)
UNCOV
214
{
×
UNCOV
215
  if (d_fd < 0) {
×
216
    throw std::runtime_error("Can't add an entry to a closed CDB database");
×
217
  }
×
218

UNCOV
219
  int ret = cdb_make_add(&d_cdbm, key.c_str(), key.size(), value.c_str(), value.size());
×
UNCOV
220
  if (ret != 0) {
×
221
    throw std::runtime_error("Error adding key '" + key + "' to CDB database: " + std::to_string(ret));
×
222
  }
×
223

UNCOV
224
  return true;
×
UNCOV
225
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc