* Copyright (c) 1986, 1988 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
static char sccsid
[] = "@(#)db_load.c 4.31 (Berkeley) 2/8/89";
* Load data base from ascii backupfile. Format similar to RFC 883.
#include <arpa/nameser.h>
extern int max_cache_ttl
;
* Map class and type names to number
"any", C_ANY
, /* any is a QCLASS, not CLASS */
#define NCLASS (sizeof(m_class)/sizeof(struct map))
"any", T_ANY
, /* any is a QTYPE, not TYPE */
#define NTYPE (sizeof(m_type)/sizeof(struct map))
int lineno
; /* current line number */
* Load the database from 'filename'. Origin is appended to all domain
db_load(filename
, in_origin
, zp
)
char *filename
, *in_origin
;
char tmporigin
[MAXDNAME
];
int class, type
, ttl
, dbflags
, dataflags
;
int read_soa
= 0; /* number of soa's read */
int slineno
, i
, errs
= 0, didinclude
= 0;
fprintf(ddt
,"db_load(%s, %s, %d)\n",
filename
, in_origin
, zp
- zones
);
(void) strcpy(origin
, in_origin
);
if ((fp
= fopen(filename
, "r")) == NULL
) {
if (zp
->z_type
!= Z_SECONDARY
)
syslog(LOG_ERR
, "%s: %m", filename
);
fprintf(ddt
,"db_load: error opening file %s\n", filename
);
if (zp
->z_type
== Z_CACHE
) {
dbflags
= DB_NODATA
| DB_NOHINTS
;
if (fstat(fileno(fp
), &sb
) < 0) {
syslog(LOG_ERR
, "%s: %m", filename
);
sb
.st_mtime
= (int)tt
.tv_sec
;
zp
->z_state
&= ~Z_INCLUDE
;
while ((c
= gettoken(fp
)) != EOF
) {
if (!getword(buf
, sizeof(buf
), fp
)) /* file name */
if (!getword(tmporigin
, sizeof(tmporigin
), fp
))
strcpy(tmporigin
, origin
);
makename(tmporigin
, origin
);
zp
->z_state
|= Z_INCLUDE
;
errs
+= db_load(buf
, tmporigin
, zp
);
(void) strcpy(buf
, origin
);
if (!getword(origin
, sizeof(origin
), fp
))
fprintf(ddt
,"db_load: origin %s, buf %s\n",
fprintf(ddt
,"db_load: origin now %s\n", origin
);
if (!getword(domain
, sizeof(domain
), fp
))
(void) strcat(domain
, ".");
(void) strcat(domain
, origin
);
(void) strcpy(domain
, origin
);
if (!getword(buf
, sizeof(buf
), fp
)) {
n
= n
* 10 + (*cp
++ - '0');
if (zp
->z_type
== Z_CACHE
) {
/* this allows the cache entry to age */
/* while sitting on disk (powered off) */
if (!getword(buf
, sizeof(buf
), fp
))
for (mp
= m_class
; mp
< m_class
+NCLASS
; mp
++)
if (!strcasecmp(buf
, mp
->token
)) {
(void) getword(buf
, sizeof(buf
), fp
);
for (mp
= m_type
; mp
< m_type
+NTYPE
; mp
++)
if (!strcasecmp(buf
, mp
->token
)) {
fprintf(ddt
,"Line %d: Unknown type: %s.\n",
syslog(LOG_ERR
, "Line %d: Unknown type: %s.\n",
/* Don't do anything here for T_UNSPEC...
* read input separately later
if (!getword(buf
, sizeof(buf
), fp
))
"d='%s', c=%d, t=%d, ttl=%d, data='%s'\n",
domain
, class, type
, ttl
, buf
);
* Convert the ascii data 'buf' to the proper format
* based on the type and pack into 'data'.
n
= ntohl((u_long
)inet_addr((char *)buf
));
"%s: line %d: CPU type too long",
bcopy(buf
, (char *)data
+ 1, (int)n
);
if (!getword(buf
, sizeof(buf
), fp
))
"%s: line %d: OS type too long",
bcopy(buf
, data
+ n
+ 1, i
);
(void) strcpy(data
, buf
);
cp
= data
+ strlen(data
) + 1;
if (!getword(cp
, sizeof(data
) - (cp
- data
),fp
)) {
if (getnonblank(fp
) != '(')
zp
->z_serial
= getnum(fp
);
n
= (u_long
) zp
->z_serial
;
zp
->z_refresh
= getnum(fp
);
n
= (u_long
) zp
->z_refresh
;
zp
->z_time
= sb
.st_mtime
+ zp
->z_refresh
;
zp
->z_retry
= getnum(fp
);
n
= (u_long
) zp
->z_retry
;
zp
->z_expire
= getnum(fp
);
n
= (u_long
) zp
->z_expire
;
zp
->z_minimum
= getnum(fp
);
n
= (u_long
) zp
->z_minimum
;
if (getnonblank(fp
) != ')')
n
= n
* 10 + (*cp
++ - '0');
n
= ntohl((u_long
)inet_addr((char *)buf
));
*cp
= getprotocol(fp
, filename
);
n
= sizeof(u_long
) + sizeof(char);
n
= getservices((int)n
, data
, fp
, filename
);
(void) strcpy(data
, buf
);
cp
= (u_char
*)index(buf
, '&');
bzero(data
, sizeof(data
));
(void) strncpy(data
, buf
, cp
- buf
);
(void) strcat(data
, domain
);
(void) strcat(data
, ++cp
);
(void) strcpy(data
, buf
);
n
= n
* 10 + (*cp
++ - '0');
if ((cp
== buf
) || (n
> 64535))
PUTSHORT((u_short
)n
, cp
);
if (!getword(buf
, sizeof(buf
), fp
))
/* get pointer to place in data */
fgets(buf
, sizeof(buf
), fp
);
fprintf(ddt
, "loading T_UNSPEC\n");
if (rcode
= atob(buf
, strlen(buf
), data
, MAXDATA
, &n
)) {
if (rcode
== CONV_OVERFLOW
) {
"Load T_UNSPEC: input buffer overflow\n");
"Load T_UNSPEC: input buffer overflow");
"Load T_UNSPEC: Data in bad atob format\n");
"Load T_UNSPEC: Data in bad atob format");
dp
= savedata(class, type
, (u_long
)ttl
, data
, (int)n
);
if ((c
= db_update(domain
, dp
, dp
, dbflags
,
(zp
->z_type
== Z_CACHE
)? fcachetab
: hashtab
)) < 0) {
if (debug
&& (c
!= DATAEXISTS
))
fprintf(ddt
,"update failed\n");
syslog(LOG_ERR
, "%s: line %d: database format error (%s)",
fprintf(ddt
,"%s: line %d: database format error ('%s', %d)\n",
filename
, lineno
, buf
, n
);
while ((c
= getc(fp
)) != EOF
&& c
!= '\n')
zp
->z_ftime
= sb
.st_mtime
;
zp
->z_lastupdate
= sb
.st_mtime
;
if (zp
->z_type
!= Z_CACHE
&& read_soa
!= 1) {
syslog(LOG_ERR
, "%s: no SOA record", filename
);
syslog(LOG_ERR
, "%s: multiple SOA records", filename
);
if (getword(op
, sizeof(op
), fp
)) {
if (!strcasecmp("include", op
))
if (!strcasecmp("origin", op
))
fprintf(ddt
,"Line %d: Unknown $ option: $%s\n",
syslog(LOG_ERR
,"Line %d: Unknown $ option: $%s\n",
while ((c
= getc(fp
)) != EOF
&& c
!= '\n')
* Get next word, skipping blanks & comments.
for (cp
= buf
; (c
= getc(fp
)) != EOF
; ) {
while ((c
= getc(fp
)) != EOF
&& c
!= '\n')
while (isspace(c
= getc(fp
)) && c
!= '\n')
if (cp
!= buf
) /* Trailing whitespace */
continue; /* Leading whitespace */
while ((c
= getc(fp
)) != EOF
&& c
!= '"' && c
!= '\n') {
if ((c
= getc(fp
)) == EOF
)
if ((c
= getc(fp
)) == EOF
)
for (n
= 0; (c
= getc(fp
)) != EOF
; ) {
while ((c
= getc(fp
)) != EOF
&& c
!= '\n')
if (seendecimal
|| c
!= '.') {
syslog(LOG_ERR
, "line %d: expected a number",
fprintf(ddt
,"line %d: expected a number",
while ( (c
= getc(fp
)) != EOF
) {
while ((c
= getc(fp
)) != EOF
&& c
!= '\n')
syslog(LOG_ERR
, "line %d: unexpected EOF", lineno
);
fprintf(ddt
, "line %d: unexpected EOF", lineno
);
* Take name and fix it according to following rules:
* "@" means current origin.
* "name." means no changes.
* "name" means append origin.
(void) strcpy(name
, origin
);
else if (origin
[0] != '\0') {
(void) strcpy(name
+ n
+ 1, origin
);
(void) getword(b
, sizeof(b
), fp
);
syslog(LOG_ERR
, "%s: line %d: unknown protocol: %s.",
getservices(n
, data
, fp
, src
)
for (j
= 0; j
< MAXPORT
/8; j
++)
while (getword(b
, sizeof(b
), fp
) || bracket
) {
if (feof(fp
) || ferror(fp
))
while ((ch
= getc(fp
)) != EOF
&& ch
!= '\n')
syslog(LOG_WARNING
, "%s: line %d: Unknown service '%s'",
if ((k
< MAXPORT
) && (k
)) {
bm
[k
/8] |= (0x80>>(k
%8));
"%s: line %d: port no. (%d) too big\n",
"%s: line %d: port no. (%d) too big\n",
syslog(LOG_WARNING
, "%s: line %d: missing close paren\n",
register struct netinfo
*ntp
= NULL
;
struct netinfo
*ntip
= NULL
;
extern struct netinfo
*fnettab
;
fprintf(ddt
,"sortlist ");
while (getword(buf
, sizeof(buf
), fp
)) {
ntp
= (struct netinfo
*)malloc(sizeof(struct netinfo
));
ntp
->my_addr
.s_addr
= inet_addr(buf
);
if (ntp
->my_addr
.s_addr
== (unsigned)-1) {
/* resolve name to address - XXX */
ntp
->mask
= net_mask(ntp
->my_addr
);
ntp
->net
= ntp
->my_addr
.s_addr
& ntp
->mask
;
/* Check for duplicates, then add to linked list */
for (tp
= fnettab
; tp
!= NULL
; tp
= tp
->next
) {
if ((ntp
->mask
== tp
->mask
) &&
for (ntp
= fnettab
; ntp
!= NULL
; ntp
= ntp
->next
) {
fprintf(ddt
,"ntp x%x net x%x mask x%x", ntp
,
fprintf(ddt
," my_addr x%x", ntp
->my_addr
);
fprintf(ddt
," %s",inet_ntoa(ntp
->my_addr
));
fprintf(ddt
," next x%x\n", ntp
->next
);
register struct netinfo
*ntp
, *next
;
for (ntp
= fnettab
; ntp
!= NULL
; ntp
= next
) {