1 /**************************************************************************************************
2 	$Id: rr.c,v 1.65 2005/04/29 16:10:27 bboy Exp $
3 
4 	Copyright (C) 2002-2005  Don Moore <bboy@bboy.net>
5 
6 	This program is free software; you can redistribute it and/or modify
7 	it under the terms of the GNU General Public License as published by
8 	the Free Software Foundation; either version 2 of the License, or
9 	(at Your option) any later version.
10 
11 	This program is distributed in the hope that it will be useful,
12 	but WITHOUT ANY WARRANTY; without even the implied warranty of
13 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 	GNU General Public License for more details.
15 
16 	You should have received a copy of the GNU General Public License
17 	along with this program; if not, write to the Free Software
18 	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 **************************************************************************************************/
20 
21 #include "mydns.h"
22 
23 #define __MYDNS_RR_NAME(__rrp)			((__rrp)->_name)
24 #define __MYDNS_RR_DATA(__rrp)			((__rrp)->_data)
25 #define __MYDNS_RR_DATA_LENGTH(__rrp)		((__rrp)->_data.len)
26 #define __MYDNS_RR_DATA_VALUE(__rrp)		((__rrp)->_data.value)
27 #define __MYDNS_RR_SRV_WEIGHT(__rrp)		((__rrp)->recData.srv.weight)
28 #define __MYDNS_RR_SRV_PORT(__rrp)		((__rrp)->recData.srv.port)
29 #define __MYDNS_RR_RP_TXT(__rrp)		((__rrp)->recData._rp_txt)
30 #define __MYDNS_RR_NAPTR_ORDER(__rrp)		((__rrp)->recData.naptr.order)
31 #define __MYDNS_RR_NAPTR_PREF(__rrp)		((__rrp)->recData.naptr.pref)
32 #define __MYDNS_RR_NAPTR_FLAGS(__rrp)		((__rrp)->recData.naptr.flags)
33 #define __MYDNS_RR_NAPTR_SERVICE(__rrp)		((__rrp)->recData.naptr._service)
34 #define __MYDNS_RR_NAPTR_REGEX(__rrp)		((__rrp)->recData.naptr._regex)
35 #define __MYDNS_RR_NAPTR_REPLACEMENT(__rrp)	((__rrp)->recData.naptr._replacement)
36 
37 char *mydns_rr_table_name = NULL;
38 char *mydns_rr_where_clause = NULL;
39 
40 size_t mydns_rr_data_length = DNS_DATALEN;
41 
42 /* Optional columns */
43 int mydns_rr_extended_data = 0;
44 int mydns_rr_use_active = 0;
45 int mydns_rr_use_stamp = 0;
46 int mydns_rr_use_serial = 0;
47 
48 char *mydns_rr_active_types[] = { (char*)"Y", (char*)"N", (char*)"D" };
49 
50 /* Make this nonzero to enable debugging within this source file */
51 #define	DEBUG_LIB_RR	1
52 
53 #if DEBUG_ENABLED
54 void *
__mydns_rr_assert_pointer(void * ptr,const char * fieldname,const char * filename,int linenumber)55 __mydns_rr_assert_pointer(void *ptr, const char *fieldname, const char *filename, int linenumber) {
56 #if DEBUG_ENABLED && DEBUG_LIB_RR
57   DebugX("lib-rr", 1, _("mydns_rr_assert_pointer() called for field=%s from %s:%d"),
58 	 fieldname, filename, linenumber);
59 #endif
60   if (ptr != NULL) return ptr;
61   DebugX("lib-rr", 1, _("%s Pointer is NULL at %s:%d"),
62 	 fieldname, filename, linenumber);
63   abort();
64   return ptr;
65 }
66 #endif
67 
68 void
mydns_rr_get_active_types(SQL * sqlConn)69 mydns_rr_get_active_types(SQL *sqlConn) {
70   SQL_RES	*res;
71   SQL_ROW	row;
72   int 		querylen;
73   char		*query;
74 
75   char		*YES = (char*)"Y";
76   char		*NO = (char*)"N";
77   char		*DELETED = (char*)"D";
78 
79   querylen = sql_build_query(&query, "SELECT DISTINCT(active) FROM %s", mydns_rr_table_name);
80 
81   if (!(res = sql_query(sqlConn, query, querylen))) return;
82 
83   RELEASE(query);
84 
85   while ((row = sql_getrow(res, NULL))) {
86     char *VAL = row[0];
87     if (   !strcasecmp(VAL, "yes")
88 	   || !strcasecmp(VAL, "y")
89 	   || !strcasecmp(VAL, "true")
90 	   || !strcasecmp(VAL, "t")
91 	   || !strcasecmp(VAL, "active")
92 	   || !strcasecmp(VAL, "a")
93 	   || !strcasecmp(VAL, "on")
94 	   || !strcmp(VAL, "1") ) { YES = STRDUP(VAL); continue; }
95     if (   !strcasecmp(VAL, "no")
96 	   || !strcasecmp(VAL, "n")
97 	   || !strcasecmp(VAL, "false")
98 	   || !strcasecmp(VAL, "f")
99 	   || !strcasecmp(VAL, "inactive")
100 	   || !strcasecmp(VAL, "i")
101 	   || !strcasecmp(VAL, "off")
102 	   || !strcmp(VAL, "0") ) { NO = STRDUP(VAL); continue; }
103     if (   !strcasecmp(VAL, "d")
104 	   || !strcasecmp(VAL, "deleted")
105 	   || !strcmp(VAL, "2") ) { DELETED = STRDUP(VAL); continue; }
106   }
107 
108   sql_free(res);
109 
110   mydns_rr_active_types[0] = YES;
111   mydns_rr_active_types[1] = NO;
112   mydns_rr_active_types[2] = DELETED;
113 }
114 
115 /**************************************************************************************************
116 	MYDNS_RR_COUNT
117 	Returns the number of records in the rr table.
118 **************************************************************************************************/
119 long
mydns_rr_count(SQL * sqlConn)120 mydns_rr_count(SQL *sqlConn) {
121   return sql_count(sqlConn, "SELECT COUNT(*) FROM %s", mydns_rr_table_name);
122 }
123 /*--- mydns_rr_count() --------------------------------------------------------------------------*/
124 
125 
126 /**************************************************************************************************
127 	MYDNS_SET_RR_TABLE_NAME
128 **************************************************************************************************/
129 void
mydns_set_rr_table_name(const char * name)130 mydns_set_rr_table_name(const char *name) {
131   RELEASE(mydns_rr_table_name);
132   if (!name)
133     mydns_rr_table_name = STRDUP(MYDNS_RR_TABLE);
134   else
135     mydns_rr_table_name = STRDUP(name);
136 }
137 /*--- mydns_set_rr_table_name() -----------------------------------------------------------------*/
138 
139 
140 /**************************************************************************************************
141 	MYDNS_SET_RR_WHERE_CLAUSE
142 **************************************************************************************************/
143 void
mydns_set_rr_where_clause(const char * where)144 mydns_set_rr_where_clause(const char *where) {
145   if (where && strlen(where)) {
146     mydns_rr_where_clause = STRDUP(where);
147   }
148 }
149 /*--- mydns_set_rr_where_clause() ---------------------------------------------------------------*/
150 
151 
152 /**************************************************************************************************
153 	MYDNS_RR_GET_TYPE
154 **************************************************************************************************/
155 inline dns_qtype_t
mydns_rr_get_type(char * type)156 mydns_rr_get_type(char *type) {
157   register char *c;
158 
159   for (c = type; *c; c++)
160     *c = toupper(*c);
161 
162   switch (type[0]) {
163   case 'A':
164     if (!type[1])
165       return DNS_QTYPE_A;
166 
167     if (type[1] == 'A' && type[2] == 'A' && type[3] == 'A' && !type[4])
168       return DNS_QTYPE_AAAA;
169 
170 #if ALIAS_ENABLED
171     if (type[1] == 'L' && type[2] == 'I' && type[3] == 'A' && type[4] == 'S' && !type[5])
172       return DNS_QTYPE_ALIAS;
173 #endif
174     break;
175 
176   case 'C':
177     if (type[1] == 'N' && type[2] == 'A' && type[3] == 'M' && type[4] == 'E' && !type[5])
178       return DNS_QTYPE_CNAME;
179     break;
180 
181   case 'H':
182     if (type[1] == 'I' && type[2] == 'N' && type[3] == 'F' && type[4] == 'O' && !type[5])
183       return DNS_QTYPE_HINFO;
184     break;
185 
186   case 'M':
187     if (type[1] == 'X' && !type[2])
188       return DNS_QTYPE_MX;
189     break;
190 
191   case 'N':
192     if (type[1] == 'S' && !type[2])
193       return DNS_QTYPE_NS;
194     if (type[1] == 'A' && type[2] == 'P' && type[3] == 'T' && type[4] == 'R' && !type[5])
195       return DNS_QTYPE_NAPTR;
196     break;
197 
198   case 'T':
199     if (type[1] == 'X' && type[2] == 'T' && !type[3])
200       return DNS_QTYPE_TXT;
201     break;
202 
203   case 'P':
204     if (type[1] == 'T' && type[2] == 'R' && !type[3])
205       return DNS_QTYPE_PTR;
206     break;
207 
208   case 'R':
209     if (type[1] == 'P' && !type[2])
210       return DNS_QTYPE_RP;
211     break;
212 
213   case 'S':
214     if (type[1] == 'R' && type[2] == 'V' && !type[3])
215       return DNS_QTYPE_SRV;
216     break;
217   }
218   return 0;
219 }
220 /*--- mydns_rr_get_type() -----------------------------------------------------------------------*/
221 
222 
223 /**************************************************************************************************
224 	MYDNS_RR_PARSE_RP
225 	RP contains two names in 'data' -- the mbox and the txt.
226 	NUL-terminate mbox and fill 'rp_txt' with the txt part of the record.
227 **************************************************************************************************/
228 static inline void
mydns_rr_parse_rp(const char * origin,MYDNS_RR * rr)229 mydns_rr_parse_rp(const char *origin, MYDNS_RR *rr) {
230   char *c;
231 
232   /* If no space, set txt to '.' */
233   if (!(c = strchr(__MYDNS_RR_DATA_VALUE(rr), ' '))) {
234     __MYDNS_RR_RP_TXT(rr) = STRDUP(".");
235   } else {
236     int namelen = strlen(&c[1]);
237     if (LASTCHAR(&c[1]) != '.') {
238       namelen += strlen(origin) + 1;
239     }
240     __MYDNS_RR_RP_TXT(rr) = ALLOCATE_N(namelen + 1, sizeof(char), char[]);
241     strncpy(__MYDNS_RR_RP_TXT(rr), &c[1], namelen);
242     if (LASTCHAR(__MYDNS_RR_RP_TXT(rr)) != '.') {
243       strncat(__MYDNS_RR_RP_TXT(rr), ".", namelen);
244       strncat(__MYDNS_RR_RP_TXT(rr), origin, namelen);
245     }
246     *c = '\0';
247     __MYDNS_RR_DATA_VALUE(rr) = REALLOCATE(__MYDNS_RR_DATA_VALUE(rr),
248 					   strlen(__MYDNS_RR_DATA_VALUE(rr))+1,
249 					   char[]);
250     __MYDNS_RR_DATA_LENGTH(rr) = strlen(__MYDNS_RR_DATA_VALUE(rr));
251   }
252 }
253 /*--- mydns_rr_parse_rp() -----------------------------------------------------------------------*/
254 
255 
256 /**************************************************************************************************
257 	MYDNS_RR_PARSE_SRV
258 	SRV records contain two unsigned 16-bit integers in the "data" field before the target,
259 	'srv_weight' and 'srv_port' - parse them and make "data" contain only the target.  Also, make
260 	sure 'aux' fits into 16 bits, clamping values above 65535.
261 **************************************************************************************************/
262 static inline void
mydns_rr_parse_srv(const char * origin,MYDNS_RR * rr)263 mydns_rr_parse_srv(const char *origin, MYDNS_RR *rr) {
264   char *weight, *port, *target;
265 
266   /* Clamp 'aux' if necessary */
267   if (rr->aux > 65535)
268     rr->aux = 65535;
269 
270   /* Parse weight (into srv_weight), port (into srv_port), and target */
271   target = __MYDNS_RR_DATA_VALUE(rr);
272   if ((weight = strsep(&target, " \t"))) {
273     __MYDNS_RR_SRV_WEIGHT(rr) = atoi(weight);
274     if ((port = strsep(&target, " \t")))
275       __MYDNS_RR_SRV_PORT(rr) = atoi(port);
276 
277     /* Strip the leading data off and just hold target */
278     memmove(__MYDNS_RR_DATA_VALUE(rr), target, strlen(target)+1);
279     __MYDNS_RR_DATA_LENGTH(rr) = strlen(__MYDNS_RR_DATA_VALUE(rr));
280     __MYDNS_RR_DATA_VALUE(rr) = REALLOCATE(__MYDNS_RR_DATA_VALUE(rr),
281 					   __MYDNS_RR_DATA_LENGTH(rr) + 1,
282 					   char[]);
283   }
284 }
285 /*--- mydns_rr_parse_srv() ----------------------------------------------------------------------*/
286 
287 
288 /**************************************************************************************************
289 	MYDNS_RR_PARSE_NAPTR
290 	Returns 0 on success, -1 on error.
291 **************************************************************************************************/
292 static inline int
mydns_rr_parse_naptr(const char * origin,MYDNS_RR * rr)293 mydns_rr_parse_naptr(const char *origin, MYDNS_RR *rr) {
294   char 		*int_tmp, *p, *data_copy;
295 
296   data_copy = STRNDUP(__MYDNS_RR_DATA_VALUE(rr), __MYDNS_RR_DATA_LENGTH(rr));
297   p = data_copy;
298 
299   if (!strsep_quotes2(&p, &int_tmp))
300     return (-1);
301   __MYDNS_RR_NAPTR_ORDER(rr) = atoi(int_tmp);
302   RELEASE(int_tmp);
303 
304   if (!strsep_quotes2(&p, &int_tmp))
305     return (-1);
306   __MYDNS_RR_NAPTR_PREF(rr) = atoi(int_tmp);
307   RELEASE(int_tmp);
308 
309   if (!strsep_quotes(&p, __MYDNS_RR_NAPTR_FLAGS(rr), sizeof(__MYDNS_RR_NAPTR_FLAGS(rr))))
310     return (-1);
311 
312   if (!strsep_quotes2(&p, &__MYDNS_RR_NAPTR_SERVICE(rr)))
313     return (-1);
314 
315   if (!strsep_quotes2(&p, &__MYDNS_RR_NAPTR_REGEX(rr)))
316     return (-1);
317 
318   if (!strsep_quotes2(&p, &__MYDNS_RR_NAPTR_REPLACEMENT(rr)))
319     return (-1);
320 
321   //__MYDNS_RR_DATA_LENGTH(rr) = 0;
322 //  RELEASE(__MYDNS_RR_DATA_VALUE(rr));
323 
324   RELEASE(data_copy);
325   return 0;
326 }
327 /*--- mydns_rr_parse_naptr() --------------------------------------------------------------------*/
328 
329 static inline int
mydns_rr_parse_txt(const char * origin,MYDNS_RR * rr)330 mydns_rr_parse_txt(const char *origin, MYDNS_RR *rr) {
331   int datalen = __MYDNS_RR_DATA_LENGTH(rr);
332   char *data = __MYDNS_RR_DATA_VALUE(rr);
333 
334   if (datalen > DNS_MAXTXTLEN) return (-1);
335 
336   while (datalen > 0) {
337     size_t elemlen = strlen(data);
338     if (elemlen > DNS_MAXTXTELEMLEN) return (-1);
339     data = &data[elemlen+1];
340     datalen -= elemlen + 1;
341   }
342 
343   return 0;
344 }
345 
346 static char *
__mydns_rr_append(char * s1,char * s2)347 __mydns_rr_append(char *s1, char *s2) {
348   int s1len = strlen(s1);
349   int s2len = strlen(s2);
350   int newlen = s1len;
351   char *name;
352   if (s1len) newlen += 1;
353   newlen += s2len;
354 
355   name = ALLOCATE(newlen+1, char[]);
356   if (s1len) { strncpy(name, s1, s1len); name[s1len] = '.'; s1len += 1; }
357   strncpy(&name[s1len], s2, s2len);
358   name[newlen] = '\0';
359   return name;
360 }
361 
362 char *
mydns_rr_append_origin(char * str,char * origin)363 mydns_rr_append_origin(char *str, char *origin) {
364   char *res = ((!*str || LASTCHAR(str) != '.')
365 	       ?__mydns_rr_append(str, origin)
366 	       :str);
367   return res;
368 }
369 
370 void
mydns_rr_name_append_origin(MYDNS_RR * rr,char * origin)371 mydns_rr_name_append_origin(MYDNS_RR *rr, char *origin) {
372   char *res = mydns_rr_append_origin(__MYDNS_RR_NAME(rr), origin);
373   if (__MYDNS_RR_NAME(rr) != res) RELEASE(__MYDNS_RR_NAME(rr));
374   __MYDNS_RR_NAME(rr) = res;
375 }
376 
377 void
mydns_rr_data_append_origin(MYDNS_RR * rr,char * origin)378 mydns_rr_data_append_origin(MYDNS_RR *rr, char *origin) {
379   char *res = mydns_rr_append_origin(__MYDNS_RR_DATA_VALUE(rr), origin);
380   if (__MYDNS_RR_DATA_VALUE(rr) != res) RELEASE(__MYDNS_RR_DATA_VALUE(rr));
381   __MYDNS_RR_DATA_VALUE(rr) = res;
382   __MYDNS_RR_DATA_LENGTH(rr) = strlen(__MYDNS_RR_DATA_VALUE(rr));
383 }
384 
385 /**************************************************************************************************
386 	_MYDNS_RR_FREE
387 	Frees the pointed-to structure.	Don't call this function directly, call the macro.
388 **************************************************************************************************/
389 void
_mydns_rr_free(MYDNS_RR * first)390 _mydns_rr_free(MYDNS_RR *first) {
391   register MYDNS_RR *p, *tmp;
392 
393   for (p = first; p; p = tmp) {
394     tmp = p->next;
395     RELEASE(p->stamp);
396     RELEASE(__MYDNS_RR_NAME(p));
397     RELEASE(__MYDNS_RR_DATA_VALUE(p));
398     switch (p->type) {
399     case DNS_QTYPE_NAPTR:
400       RELEASE(__MYDNS_RR_NAPTR_SERVICE(p));
401       RELEASE(__MYDNS_RR_NAPTR_REGEX(p));
402       RELEASE(__MYDNS_RR_NAPTR_REPLACEMENT(p));
403       break;
404     case DNS_QTYPE_RP:
405       RELEASE(__MYDNS_RR_RP_TXT(p));
406       break;
407     default:
408       break;
409     }
410     RELEASE(p);
411   }
412 }
413 /*--- _mydns_rr_free() --------------------------------------------------------------------------*/
414 
415 MYDNS_RR *
mydns_rr_build(uint32_t id,uint32_t zone,dns_qtype_t type,dns_class_t class,uint32_t aux,uint32_t ttl,char * active,timestamp * stamp,uint32_t serial,char * name,char * data,uint16_t datalen,const char * origin)416 mydns_rr_build(uint32_t id,
417 	       uint32_t zone,
418 	       dns_qtype_t type,
419 	       dns_class_t class,
420 	       uint32_t aux,
421 	       uint32_t ttl,
422 	       char *active,
423 #if USE_PGSQL
424 	       timestamp *stamp,
425 #else
426 	       MYSQL_TIME *stamp,
427 #endif
428 	       uint32_t serial,
429 	       char *name,
430 	       char *data,
431 	       uint16_t	datalen,
432 	       const char *origin) {
433   MYDNS_RR	*rr = NULL;
434   uint32_t	namelen;
435 
436 #if DEBUG_ENABLED && DEBUG_LIB_RR
437   DebugX("lib-rr", 1, _("mydns_rr_build(): called for id=%d, zone=%d, type=%d, class=%d, aux=%d, "
438 			"ttl=%d, active='%s', stamp=%p, serial=%d, name='%s', data=%p, datalen=%d, origin='%s'"),
439 	 id, zone, type, class, aux, ttl, active, stamp, serial,
440 	 (name)?name:_("<NULL>"), data, datalen, origin);
441 #endif
442 
443   if ((namelen = (name)?strlen(name):0) > DNS_MAXNAMELEN) {
444     /* Name exceeds permissable length - should report error */
445     goto PARSEFAILED;
446   }
447 
448   rr = (MYDNS_RR *)ALLOCATE(sizeof(MYDNS_RR), MYDNS_RR);
449   memset(rr, '\0', sizeof(MYDNS_RR));
450   rr->next = NULL;
451 
452   rr->id = id;
453   rr->zone = zone;
454 
455   __MYDNS_RR_NAME(rr) = ALLOCATE(namelen+1, char[]);
456   memset(__MYDNS_RR_NAME(rr), 0, namelen+1);
457   if (name) strncpy(__MYDNS_RR_NAME(rr), name, namelen);
458 
459   /* Should store length and buffer rather than handle as a string */
460   __MYDNS_RR_DATA_LENGTH(rr) = datalen;
461   __MYDNS_RR_DATA_VALUE(rr) = ALLOCATE(datalen+1, char[]);
462   memcpy(__MYDNS_RR_DATA_VALUE(rr), data, datalen);
463 
464   rr->class = class;
465   rr->aux = aux;
466   rr->ttl = ttl;
467   rr->type = type;
468 #if ALIAS_ENABLED
469   if (rr->type == DNS_QTYPE_ALIAS) {
470     rr->type = DNS_QTYPE_A;
471     rr->alias = 1;
472   } else
473     rr->alias = 0;
474 #endif
475 
476   /* Find a constant value so we do not have to allocate or free this one */
477   if (active) {
478     int i;
479     for (i = 0; i < 3; i++) {
480       if (!strcasecmp(mydns_rr_active_types[i], active)) { active = mydns_rr_active_types[i]; break; }
481     }
482   }
483   rr->active = active;
484   rr->stamp = stamp;
485   rr->serial = serial;
486 
487   switch (rr->type) {
488 
489   case DNS_QTYPE_TXT:
490     if (mydns_rr_parse_txt(origin, rr) < 0) {
491       goto PARSEFAILED;
492     }
493     break;
494 
495   case DNS_QTYPE_NAPTR:
496     /* Populate special fields for NAPTR records */
497     if (mydns_rr_parse_naptr(origin, rr) < 0) {
498       goto PARSEFAILED;
499     }
500     break;
501 
502   case DNS_QTYPE_RP:
503     /* Populate special fields for RP records */
504     mydns_rr_parse_rp(origin, rr);
505     goto DOORIGIN;
506 
507   case DNS_QTYPE_SRV:
508     mydns_rr_parse_srv(origin, rr);
509     goto DOORIGIN;
510 
511   DOORIGIN:
512 
513   case DNS_QTYPE_CNAME:
514   case DNS_QTYPE_MX:
515   case DNS_QTYPE_NS:
516 
517     /* Append origin to data if it's not there for these types: */
518     if (origin) {
519       datalen = __MYDNS_RR_DATA_LENGTH(rr);
520 #ifdef DN_COLUMN_NAMES
521       datalen += 1;
522       __MYDNS_RR_DATA_LENGTH(rr) = datalen;
523       __MYDNS_RR_DATA_VALUE(rr) = REALLOCATE(__MYDNS_RR_DATA_VALUE(rr), datalen+1, char[]);
524       /* Just append dot for DN */
525       ((char*)__MYDNS_RR_DATA_VALUE(rr))[datalen-1] = '.';
526 #else
527       if (datalen && ((char*)__MYDNS_RR_DATA_VALUE(rr))[datalen-1] != '.') {
528 	datalen = datalen + 1 + strlen(origin);
529 	__MYDNS_RR_DATA_VALUE(rr) = REALLOCATE(__MYDNS_RR_DATA_VALUE(rr), datalen+1, char[]);
530 	((char*)__MYDNS_RR_DATA_VALUE(rr))[__MYDNS_RR_DATA_LENGTH(rr)] = '.';
531 	memcpy(&((char*)__MYDNS_RR_DATA_VALUE(rr))[__MYDNS_RR_DATA_LENGTH(rr)+1], origin, strlen(origin));
532 	__MYDNS_RR_DATA_LENGTH(rr) = datalen;
533       }
534 #endif
535       ((char*)__MYDNS_RR_DATA_VALUE(rr))[__MYDNS_RR_DATA_LENGTH(rr)] = '\0';
536     }
537     break;
538   default:
539     break;
540   }
541 
542 #if DEBUG_ENABLED && DEBUG_LIB_RR
543   DebugX("lib-rr", 1, _("mydns_rr_build(): returning result=%p"), rr);
544 #endif
545   return (rr);
546 
547  PARSEFAILED:
548   mydns_rr_free(rr);
549   return (NULL);
550 }
551 
552 /**************************************************************************************************
553 	MYDNS_RR_PARSE
554 	Given the SQL results with RR data, populates and returns a matching MYDNS_RR structure.
555 	Returns NULL on error.
556 **************************************************************************************************/
557 inline MYDNS_RR *
mydns_rr_parse(SQL_ROW row,unsigned long * lengths,const char * origin)558 mydns_rr_parse(SQL_ROW row, unsigned long *lengths, const char *origin) {
559   dns_qtype_t	type;
560   char		*active = NULL;
561 #if USE_PGSQL
562   timestamp	*stamp = NULL;
563 #else
564   MYSQL_TIME	*stamp = NULL;
565 #endif
566   uint32_t	serial = 0;
567   int		ridx = MYDNS_RR_NUMFIELDS;
568   char		*data;
569   uint16_t	datalen;
570   MYDNS_RR	*rr;
571 
572 #if DEBUG_ENABLED && DEBUG_LIB_RR
573   DebugX("lib-rr", 1, _("mydns_rr_parse(): called for origin %s"), origin);
574 #endif
575 
576 /* #60 */
577 //if (!(type = mydns_rr_get_type(row[6]))) {
578   if (!row[6] || !(type = mydns_rr_get_type(row[6]))) {
579     /* Ignore unknown RR type(s) */
580     return (NULL);
581   }
582 
583   data = row[3];
584   datalen = lengths[3];
585   if (mydns_rr_extended_data) {
586     if (lengths[ridx]) {
587       char *newdata = ALLOCATE(datalen + lengths[ridx], char[]);
588       memcpy(newdata, data, datalen);
589       memcpy(&newdata[datalen], row[ridx], lengths[ridx]);
590       datalen += lengths[ridx];
591       data = newdata;
592     }
593     ridx++;
594   }
595 
596   /* Copy storage? */
597   if (mydns_rr_use_active) active = row[ridx++];
598   if (mydns_rr_use_stamp) {
599 #if USE_PGSQL
600     /* Copy storage? */
601     stamp = row[ridx++];
602 #else
603     stamp = (MYSQL_TIME*)ALLOCATE(sizeof(MYSQL_TIME), MYSQL_TIME);
604     memcpy(stamp, row[ridx++], sizeof(MYSQL_TIME));
605 #endif
606   }
607   if (mydns_rr_use_serial && row[ridx]) {
608     serial = atou(row[ridx++]);
609   }
610 
611   rr = mydns_rr_build(atou(row[0]),
612 		      atou(row[1]),
613 		      type,
614 		      DNS_CLASS_IN,
615 		      atou(row[4]),
616 		      atou(row[5]),
617 		      active,
618 		      stamp,
619 		      serial,
620 		      row[2],
621 		      data,
622 		      datalen,
623 		      origin);
624 
625   if (mydns_rr_extended_data && lengths[MYDNS_RR_NUMFIELDS]) RELEASE(data);
626 
627   return (rr);
628 }
629 /*--- mydns_rr_parse() --------------------------------------------------------------------------*/
630 
631 
632 /**************************************************************************************************
633 	MYDNS_RR_DUP
634 	Make and return a copy of a MYDNS_RR record.  If 'recurse' is specified, copies all records
635 	in the RRset.
636 **************************************************************************************************/
637 MYDNS_RR *
mydns_rr_dup(MYDNS_RR * start,int recurse)638 mydns_rr_dup(MYDNS_RR *start, int recurse) {
639   register MYDNS_RR *first = NULL, *last = NULL, *rr, *s, *tmp;
640 
641   for (s = start; s; s = tmp) {
642     tmp = s->next;
643 
644     rr = (MYDNS_RR *)ALLOCATE(sizeof(MYDNS_RR), MYDNS_RR);
645 
646     memset(rr, '\0', sizeof(MYDNS_RR));
647     rr->id = s->id;
648     rr->zone = s->zone;
649     __MYDNS_RR_NAME(rr) = STRDUP(__MYDNS_RR_NAME(s));
650     rr->type = s->type;
651     rr->class = s->class;
652     __MYDNS_RR_DATA_LENGTH(rr) = __MYDNS_RR_DATA_LENGTH(s);
653     __MYDNS_RR_DATA_VALUE(rr) = ALLOCATE(__MYDNS_RR_DATA_LENGTH(s)+1, char[]);
654     memcpy(__MYDNS_RR_DATA_VALUE(rr), __MYDNS_RR_DATA_VALUE(s), __MYDNS_RR_DATA_LENGTH(s));
655     ((char*)__MYDNS_RR_DATA_VALUE(rr))[__MYDNS_RR_DATA_LENGTH(rr)] = '\0';
656     rr->aux = s->aux;
657     rr->ttl = s->ttl;
658 #if ALIAS_ENABLED
659     rr->alias = s->alias;
660 #endif
661 
662     rr->active = s->active;
663     if (s->stamp) {
664 #if USE_PGSQL
665       rr->stamp = s->stamp;
666 #else
667       rr->stamp = (MYSQL_TIME*)ALLOCATE(sizeof(MYSQL_TIME), MYSQL_TIME);
668       memcpy(rr->stamp, s->stamp, sizeof(MYSQL_TIME));
669 #endif
670     } else
671       rr->stamp = NULL;
672     rr->serial = s->serial;
673 
674     switch (rr->type) {
675     case DNS_QTYPE_SRV:
676       __MYDNS_RR_SRV_WEIGHT(rr) = __MYDNS_RR_SRV_WEIGHT(s);
677       __MYDNS_RR_SRV_PORT(rr) = __MYDNS_RR_SRV_PORT(s);
678       break;
679 
680     case DNS_QTYPE_RP:
681       /* Copy rp_txt only for RP records */
682       __MYDNS_RR_RP_TXT(rr) = STRDUP(__MYDNS_RR_RP_TXT(s));
683       break;
684 
685     case DNS_QTYPE_NAPTR:
686       /* Copy naptr fields only for NAPTR records */
687       __MYDNS_RR_NAPTR_ORDER(rr) = __MYDNS_RR_NAPTR_ORDER(s);
688       __MYDNS_RR_NAPTR_PREF(rr) = __MYDNS_RR_NAPTR_PREF(s);
689       memcpy(__MYDNS_RR_NAPTR_FLAGS(rr), __MYDNS_RR_NAPTR_FLAGS(s), sizeof(__MYDNS_RR_NAPTR_FLAGS(rr)));
690       __MYDNS_RR_NAPTR_SERVICE(rr) = STRDUP(__MYDNS_RR_NAPTR_SERVICE(s));
691       __MYDNS_RR_NAPTR_REGEX(rr) = STRDUP(__MYDNS_RR_NAPTR_REGEX(s));
692       __MYDNS_RR_NAPTR_REPLACEMENT(rr) = STRDUP(__MYDNS_RR_NAPTR_REPLACEMENT(s));
693       break;
694 
695     default:
696       break;
697     }
698 
699     rr->next = NULL;
700     if (recurse) {
701       if (!first) first = rr;
702       if (last) last->next = rr;
703       last = rr;
704     } else
705       return (rr);
706   }
707   return (first);
708 }
709 /*--- mydns_rr_dup() ----------------------------------------------------------------------------*/
710 
711 
712 /**************************************************************************************************
713 	MYDNS_RR_SIZE
714 **************************************************************************************************/
715 inline size_t
mydns_rr_size(MYDNS_RR * first)716 mydns_rr_size(MYDNS_RR *first) {
717   register MYDNS_RR *p;
718   register size_t size = 0;
719 
720   for (p = first; p; p = p->next) {
721     size += sizeof(MYDNS_RR)
722       + (strlen(__MYDNS_RR_NAME(p)) + 1)
723       + (__MYDNS_RR_DATA_LENGTH(p) + 1);
724 #if USE_PGSQL
725 #else
726     size += sizeof(MYSQL_TIME);
727 #endif
728     switch (p->type) {
729     case DNS_QTYPE_NAPTR:
730       size += strlen(__MYDNS_RR_NAPTR_SERVICE(p)) + 1;
731       size += strlen(__MYDNS_RR_NAPTR_REGEX(p)) + 1;
732       size += strlen(__MYDNS_RR_NAPTR_REPLACEMENT(p)) + 1;
733       break;
734 
735     case DNS_QTYPE_RP:
736       size += strlen(__MYDNS_RR_RP_TXT(p)) + 1;
737       break;
738 
739     default:
740       break;
741     }
742   }
743 
744   return (size);
745 }
746 /*--- mydns_rr_size() ---------------------------------------------------------------------------*/
747 
748 
749 /**************************************************************************************************
750 	MYDNS_RR_LOAD
751 	Returns 0 on success or nonzero if an error occurred.
752 	If "name" is NULL, all resource records for the zone will be loaded.
753 **************************************************************************************************/
754 char *
mydns_rr_columns()755 mydns_rr_columns() {
756   char		*columns = NULL;
757   size_t	columnslen = 0;
758 
759   columnslen = sql_build_query(&columns, MYDNS_RR_FIELDS"%s%s%s%s",
760 			       /* Optional columns */
761 			       (mydns_rr_extended_data ? ",edata" : ""),
762 			       (mydns_rr_use_active ? ",active" : ""),
763 			       (mydns_rr_use_stamp  ? ",stamp"  : ""),
764 			       (mydns_rr_use_serial ? ",serial" : ""));
765   return columns;
766 }
767 
768 char *
mydns_rr_prepare_query(uint32_t zone,dns_qtype_t type,const char * name,const char * origin,const char * active,const char * columns,const char * filter)769 mydns_rr_prepare_query(uint32_t zone, dns_qtype_t type, const char *name, const char *origin,
770 		       const char *active, const char *columns, const char *filter) {
771   size_t	querylen;
772   char		*query = NULL;
773   char		*namequery = NULL;
774   const char	*wheretype;
775   const char	*cp;
776 #ifdef DN_COLUMN_NAMES
777   int		originlen = origin ? strlen(origin) : 0;
778   int		namelen = name ? strlen(name) : 0;
779 #endif
780 
781 #if DEBUG_ENABLED && DEBUG_LIB_RR
782   DebugX("lib-rr", 1, _("mydns_rr_prepare_query(zone=%u, type='%s', name='%s', origin='%s')"),
783 	 zone, mydns_qtype_str(type), name ?: _("NULL"), origin ?: _("NULL"));
784 #endif
785 
786   /* Get the type='XX' part of the WHERE clause */
787   switch (type)	{
788 #if ALIAS_ENABLED
789   case DNS_QTYPE_A:		wheretype = " AND (type='A' OR type='ALIAS')"; break;
790 #else
791   case DNS_QTYPE_A:		wheretype = " AND type='A'"; break;
792 #endif
793   case DNS_QTYPE_AAAA:		wheretype = " AND type='AAAA'"; break;
794   case DNS_QTYPE_CNAME:	        wheretype = " AND type='CNAME'"; break;
795   case DNS_QTYPE_HINFO:	        wheretype = " AND type='HINFO'"; break;
796   case DNS_QTYPE_MX:		wheretype = " AND type='MX'"; break;
797   case DNS_QTYPE_NAPTR:	        wheretype = " AND type='NAPTR'"; break;
798   case DNS_QTYPE_NS:		wheretype = " AND type='NS'"; break;
799   case DNS_QTYPE_PTR:		wheretype = " AND type='PTR'"; break;
800   case DNS_QTYPE_SOA:		wheretype = " AND type='SOA'"; break;
801   case DNS_QTYPE_SRV:		wheretype = " AND type='SRV'"; break;
802   case DNS_QTYPE_TXT:		wheretype = " AND type='TXT'"; break;
803   case DNS_QTYPE_ANY:		wheretype = ""; break;
804   default:
805     errno = EINVAL;
806     return (NULL);
807   }
808 
809   /* Make sure 'name' and 'origin' (if present) are valid */
810   if (name) {
811     for (cp = name; *cp; cp++)
812       if (SQL_BADCHAR(*cp))
813 	return (NULL);
814   }
815   if (origin) {
816     for (cp = origin; *cp; cp++)
817       if (SQL_BADCHAR(*cp))
818 	return (NULL);
819   }
820 
821 #ifdef DN_COLUMN_NAMES
822   /* Remove dot from origin and name for DN */
823   if (originlen && origin[originlen - 1] == '.')
824     origin[originlen-1] = '\0';
825   else
826     originlen = 0;
827 
828   if (name) {
829     if (namelen && name[namelen - 1] == '.')
830       name[namelen-1] = '\0';
831     else
832       namelen = 0;
833   }
834 #endif
835 
836   /* Construct query */
837   if (name) {
838     if (origin) {
839       if (!name[0])
840 	sql_build_query(&namequery, "(name='' OR name='%s')", origin);
841       else {
842 #ifdef DN_COLUMN_NAMES
843 	sql_build_query(&namequery, "name='%s'", name);
844 #else
845 	sql_build_query(&namequery, "(name='%s' OR name='%s.%s')", name, name, origin);
846 #endif
847       }
848     }
849     else
850       sql_build_query(&namequery, "name='%s'", name);
851   }
852 
853 #ifdef DN_COLUMN_NAMES
854   if (originlen)
855     origin[originlen - 1] = '.';				/* Re-add dot to origin for DN */
856 
857   if (name) {
858     if (namelen)
859       name[namelen - 1] = '.';
860   }
861 #endif
862 
863   querylen = sql_build_query(&query, "SELECT %s FROM %s WHERE "
864 #ifdef DN_COLUMN_NAMES
865 			     "zone_id=%u%s"
866 #else
867 			     "zone=%u%s"
868 #endif
869 			     "%s%s"
870 			     "%s%s%s"
871 			     "%s%s"
872 			     "%s%s"
873 			     "%s",
874 
875 			     columns,
876 
877 			     /* Fixed data */
878 			     mydns_rr_table_name,
879 			     zone, wheretype,
880 
881 			     /* Name based query */
882 			     (namequery)? " AND " : "",
883 			     (namequery)? namequery : "",
884 
885 			     /* Optional check for active value */
886 			     (mydns_rr_use_active)? " AND active='" : "",
887 			     (mydns_rr_use_active)? active : "",
888 			     (mydns_rr_use_active)? "'" : "",
889 
890 			     /* Optional where clause for rr table */
891 			     (mydns_rr_where_clause)? " AND " : "",
892 			     (mydns_rr_where_clause)? mydns_rr_where_clause : "",
893 
894 			     /* Apply additional filter if requested */
895 			     (filter)? " AND " : "",
896 			     (filter)? filter : "",
897 
898 			     /* Optional sorting */
899 			     (mydns_rr_use_stamp)? " ORDER BY stamp DESC" : "");
900 
901   RELEASE(namequery);
902 
903   return (query);
904 }
905 
__mydns_rr_do_load(SQL * sqlConn,MYDNS_RR ** rptr,const char * query,const char * origin)906 static int __mydns_rr_do_load(SQL *sqlConn, MYDNS_RR **rptr, const char *query, const char *origin) {
907   MYDNS_RR	*first = NULL, *last = NULL;
908   char		*cp;
909   SQL_RES	*res;
910   SQL_ROW	row;
911   unsigned long *lengths;
912 
913 
914 #if DEBUG_ENABLED && DEBUG_LIB_RR
915   DebugX("lib-rr", 1, _("mydns_rr_do_load(query='%s', origin='%s')"), query, origin ? origin : _("NULL"));
916 #endif
917 
918   if (rptr) *rptr = NULL;
919 
920   /* Verify args */
921   if (!sqlConn || !rptr || !query) {
922     errno = EINVAL;
923     return (-1);
924   }
925 
926   /* Submit query */
927   if (!(res = sql_query(sqlConn, query, strlen(query))))
928     return (-1);
929 
930 #if DEBUG_ENABLED && DEBUG_LIB_RR
931   {
932     int numresults = sql_num_rows(res);
933 
934     DebugX("lib-rr", 1, _("RR query: %d row%s: %s"), numresults, S(numresults), query);
935   }
936 #endif
937 
938   RELEASE(query);
939 
940   /* Add results to list */
941   while ((row = sql_getrow(res, &lengths))) {
942     MYDNS_RR *new;
943 
944     if (!(new = mydns_rr_parse(row, lengths, origin)))
945       continue;
946 
947     /* Always trim origin from name (XXX: Why? When did I add this?) */
948     /* Apparently removing this code breaks RRs where the name IS the origin */
949     /* But trim only where the name is exactly the origin */
950     if (origin && (cp = strstr(__MYDNS_RR_NAME(new), origin)) && !(cp - __MYDNS_RR_NAME(new)))
951       *cp = '\0';
952 
953     if (!first) first = new;
954     if (last) last->next = new;
955     last = new;
956   }
957 
958   *rptr = first;
959   sql_free(res);
960   return (0);
961 }
962 
963 static int
__mydns_rr_count(SQL * sqlConn,uint32_t zone,dns_qtype_t type,const char * name,const char * origin,const char * active,const char * filter)964 __mydns_rr_count(SQL *sqlConn, uint32_t zone,
965 		 dns_qtype_t type,
966 		 const char *name, const char *origin, const char *active, const char *filter) {
967   char		*query = NULL;
968   int		result;
969 
970   SQL_RES	*res;
971   SQL_ROW	row;
972 
973   query = mydns_rr_prepare_query(zone, type, name, origin, active, (char*)"COUNT(*)", filter);
974 
975   if (!query || !(res = sql_query(sqlConn, query, strlen(query)))) {
976     WarnSQL(sqlConn, _("error processing count with filter %s"), filter);
977     return (-1);
978   }
979 
980   RELEASE(query);
981 
982   if ((row = sql_getrow(res, NULL)))
983     result = atoi(row[0]);
984   else
985     result = 0;
986 
987   sql_free(res);
988 
989   return result;
990 }
991 
992 static int
__mydns_rr_load(SQL * sqlConn,MYDNS_RR ** rptr,uint32_t zone,dns_qtype_t type,const char * name,const char * origin,const char * active,const char * filter)993 __mydns_rr_load(SQL *sqlConn, MYDNS_RR **rptr, uint32_t zone,
994 		dns_qtype_t type,
995 		const char *name, const char *origin, const char *active, const char *filter) {
996   char		*query = NULL;
997   int		res;
998   char		*columns = NULL;
999 
1000   columns = mydns_rr_columns();
1001 
1002   query = mydns_rr_prepare_query(zone, type, name, origin, active, columns, filter);
1003 
1004   RELEASE(columns);
1005 
1006   res = __mydns_rr_do_load(sqlConn, rptr, query, origin);
1007 
1008   return res;
1009 }
1010 
mydns_rr_load_all(SQL * sqlConn,MYDNS_RR ** rptr,uint32_t zone,dns_qtype_t type,const char * name,const char * origin)1011 int mydns_rr_load_all(SQL *sqlConn, MYDNS_RR **rptr, uint32_t zone,
1012 		      dns_qtype_t type,
1013 		      const char *name, const char *origin) {
1014 
1015   return __mydns_rr_load(sqlConn, rptr, zone, type, name, origin, NULL, NULL);
1016 }
1017 
mydns_rr_load_active(SQL * sqlConn,MYDNS_RR ** rptr,uint32_t zone,dns_qtype_t type,const char * name,const char * origin)1018 int mydns_rr_load_active(SQL *sqlConn, MYDNS_RR **rptr, uint32_t zone,
1019 			 dns_qtype_t type,
1020 			 const char *name, const char *origin) {
1021 
1022   return __mydns_rr_load(sqlConn, rptr, zone, type, name, origin, mydns_rr_active_types[0], NULL);
1023 }
1024 
mydns_rr_load_inactive(SQL * sqlConn,MYDNS_RR ** rptr,uint32_t zone,dns_qtype_t type,const char * name,const char * origin)1025 int mydns_rr_load_inactive(SQL *sqlConn, MYDNS_RR **rptr, uint32_t zone,
1026 			   dns_qtype_t type,
1027 			   const char *name, const char *origin) {
1028 
1029   return __mydns_rr_load(sqlConn, rptr, zone, type, name, origin, mydns_rr_active_types[1], NULL);
1030 }
1031 
mydns_rr_load_deleted(SQL * sqlConn,MYDNS_RR ** rptr,uint32_t zone,dns_qtype_t type,const char * name,const char * origin)1032 int mydns_rr_load_deleted(SQL *sqlConn, MYDNS_RR **rptr, uint32_t zone,
1033 			  dns_qtype_t type,
1034 			  const char *name, const char *origin) {
1035 
1036   return __mydns_rr_load(sqlConn, rptr, zone, type, name, origin, mydns_rr_active_types[2], NULL);
1037 }
1038 
mydns_rr_count_all(SQL * sqlConn,uint32_t zone,dns_qtype_t type,const char * name,const char * origin)1039 int mydns_rr_count_all(SQL *sqlConn, uint32_t zone,
1040 		       dns_qtype_t type,
1041 		       const char *name, const char *origin) {
1042 
1043   return __mydns_rr_count(sqlConn, zone, type, name, origin, mydns_rr_active_types[0], NULL);
1044 }
1045 
mydns_rr_count_active(SQL * sqlConn,uint32_t zone,dns_qtype_t type,const char * name,const char * origin)1046 int mydns_rr_count_active(SQL *sqlConn, uint32_t zone,
1047 			  dns_qtype_t type,
1048 			  const char *name, const char *origin) {
1049 
1050   return __mydns_rr_count(sqlConn, zone, type, name, origin, mydns_rr_active_types[0], NULL);
1051 }
1052 
mydns_rr_count_inactive(SQL * sqlConn,uint32_t zone,dns_qtype_t type,const char * name,const char * origin)1053 int mydns_rr_count_inactive(SQL *sqlConn, uint32_t zone,
1054 			    dns_qtype_t type,
1055 			    const char *name, const char *origin) {
1056 
1057   return __mydns_rr_count(sqlConn, zone, type, name, origin, mydns_rr_active_types[1], NULL);
1058 }
1059 
mydns_rr_count_deleted(SQL * sqlConn,uint32_t zone,dns_qtype_t type,const char * name,const char * origin)1060 int mydns_rr_count_deleted(SQL *sqlConn, uint32_t zone,
1061 			   dns_qtype_t type,
1062 			   const char *name, const char *origin) {
1063 
1064   return __mydns_rr_count(sqlConn, zone, type, name, origin, mydns_rr_active_types[2], NULL);
1065 }
1066 
1067 
mydns_rr_load_all_filtered(SQL * sqlConn,MYDNS_RR ** rptr,uint32_t zone,dns_qtype_t type,const char * name,const char * origin,const char * filter)1068 int mydns_rr_load_all_filtered(SQL *sqlConn, MYDNS_RR **rptr, uint32_t zone,
1069 			       dns_qtype_t type,
1070 			       const char *name, const char *origin, const char *filter) {
1071 
1072   return __mydns_rr_load(sqlConn, rptr, zone, type, name, origin, NULL, filter);
1073 }
1074 
mydns_rr_load_active_filtered(SQL * sqlConn,MYDNS_RR ** rptr,uint32_t zone,dns_qtype_t type,const char * name,const char * origin,const char * filter)1075 int mydns_rr_load_active_filtered(SQL *sqlConn, MYDNS_RR **rptr, uint32_t zone,
1076 				  dns_qtype_t type,
1077 				  const char *name, const char *origin, const char *filter) {
1078 
1079   return __mydns_rr_load(sqlConn, rptr, zone, type, name, origin, mydns_rr_active_types[0], filter);
1080 }
1081 
mydns_rr_load_inactive_filtered(SQL * sqlConn,MYDNS_RR ** rptr,uint32_t zone,dns_qtype_t type,const char * name,const char * origin,const char * filter)1082 int mydns_rr_load_inactive_filtered(SQL *sqlConn, MYDNS_RR **rptr, uint32_t zone,
1083 				    dns_qtype_t type,
1084 				    const char *name, const char *origin, const char *filter) {
1085 
1086   return __mydns_rr_load(sqlConn, rptr, zone, type, name, origin, mydns_rr_active_types[1], filter);
1087 }
1088 
mydns_rr_load_deleted_filtered(SQL * sqlConn,MYDNS_RR ** rptr,uint32_t zone,dns_qtype_t type,const char * name,const char * origin,const char * filter)1089 int mydns_rr_load_deleted_filtered(SQL *sqlConn, MYDNS_RR **rptr, uint32_t zone,
1090 				   dns_qtype_t type,
1091 				   const char *name, const char *origin, const char *filter) {
1092 
1093   return __mydns_rr_load(sqlConn, rptr, zone, type, name, origin, mydns_rr_active_types[2], filter);
1094 }
1095 
mydns_rr_count_all_filtered(SQL * sqlConn,uint32_t zone,dns_qtype_t type,const char * name,const char * origin,const char * filter)1096 int mydns_rr_count_all_filtered(SQL *sqlConn, uint32_t zone,
1097 				dns_qtype_t type,
1098 				const char *name, const char *origin, const char *filter) {
1099 
1100   return __mydns_rr_count(sqlConn, zone, type, name, origin, mydns_rr_active_types[0], filter);
1101 }
1102 
mydns_rr_count_active_filtered(SQL * sqlConn,uint32_t zone,dns_qtype_t type,const char * name,const char * origin,const char * filter)1103 int mydns_rr_count_active_filtered(SQL *sqlConn, uint32_t zone,
1104 				   dns_qtype_t type,
1105 				   const char *name, const char *origin, const char *filter) {
1106 
1107   return __mydns_rr_count(sqlConn, zone, type, name, origin, mydns_rr_active_types[0], filter);
1108 }
1109 
mydns_rr_count_inactive_filtered(SQL * sqlConn,uint32_t zone,dns_qtype_t type,const char * name,const char * origin,const char * filter)1110 int mydns_rr_count_inactive_filtered(SQL *sqlConn, uint32_t zone,
1111 				     dns_qtype_t type,
1112 				     const char *name, const char *origin, const char *filter) {
1113 
1114   return __mydns_rr_count(sqlConn, zone, type, name, origin, mydns_rr_active_types[1], filter);
1115 }
1116 
mydns_rr_count_deleted_filtered(SQL * sqlConn,uint32_t zone,dns_qtype_t type,const char * name,const char * origin,const char * filter)1117 int mydns_rr_count_deleted_filtered(SQL *sqlConn, uint32_t zone,
1118 				    dns_qtype_t type,
1119 				    const char *name, const char *origin, const char *filter) {
1120 
1121   return __mydns_rr_count(sqlConn, zone, type, name, origin, mydns_rr_active_types[2], filter);
1122 }
1123 
1124 /*--- mydns_rr_load() ---------------------------------------------------------------------------*/
1125 
1126 /* vi:set ts=3: */
1127