#ifndef lint
static char copyright[] =
-"$Id: conflex.c,v 1.107 2007/05/19 19:16:24 dhankins Exp $ Copyright (c) 2004-2007 Internet Systems Consortium. All rights reserved.\n";
+"$Id: conflex.c,v 1.108 2007/05/23 15:29:49 shane Exp $ Copyright (c) 2004-2007 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
return ISC_R_NOMEMORY;
memset (tmp, 0, sizeof *tmp);
- tmp -> token = 0;
- tmp -> tlname = name;
- tmp -> lpos = tmp -> line = 1;
- tmp -> cur_line = tmp -> line1;
- tmp -> prev_line = tmp -> line2;
- tmp -> token_line = tmp -> cur_line;
- tmp -> cur_line [0] = tmp -> prev_line [0] = 0;
- tmp -> warnings_occurred = 0;
- tmp -> file = file;
- tmp -> eol_token = eolp;
+ tmp->token = 0;
+ tmp->tlname = name;
+ tmp->lpos = tmp -> line = 1;
+ tmp->cur_line = tmp -> line1;
+ tmp->prev_line = tmp -> line2;
+ tmp->token_line = tmp -> cur_line;
+ tmp->cur_line [0] = tmp -> prev_line [0] = 0;
+ tmp->warnings_occurred = 0;
+ tmp->file = file;
+ tmp->eol_token = eolp;
+
+ tmp->bufix = 0;
- tmp -> bufix = 0;
- tmp -> buflen = buflen;
if (inbuf) {
- tmp -> bufsiz = 0;
- tmp -> inbuf = inbuf;
+ tmp->inbuf = inbuf;
+ tmp->buflen = buflen;
+ tmp->bufsiz = 0;
} else {
- tmp -> inbuf = dmalloc (8192, MDL);
- if (!tmp -> inbuf) {
- dfree (tmp, MDL);
- return ISC_R_NOMEMORY;
+ struct stat sb;
+
+ if (fstat(file, &sb) < 0)
+ return ISC_R_IOERROR;
+
+ tmp->bufsiz = tmp->buflen = (size_t) sb.st_size;
+ tmp->inbuf = mmap(NULL, tmp->bufsiz, PROT_READ, MAP_SHARED,
+ file, 0);
+
+ if (tmp->inbuf == MAP_FAILED) {
+ return ISC_R_IOERROR;
}
- tmp -> bufsiz = 8192;
}
*cfile = tmp;
struct parse **cfile;
{
/* "Memory" config files have no file. */
- if ((*cfile)->file != -1)
+ if ((*cfile)->file != -1) {
+ munmap((*cfile)->inbuf, (*cfile)->bufsiz);
close((*cfile)->file);
-
- if ((*cfile)->bufsiz)
- dfree((*cfile)->inbuf, MDL);
+ }
+
dfree(*cfile, MDL);
*cfile = NULL;
return ISC_R_SUCCESS;
/* My kingdom for WITH... */
int c;
- if (cfile -> bufix == cfile -> buflen) {
- if (cfile -> file != -1) {
- cfile -> buflen =
- read (cfile -> file,
- cfile -> inbuf, cfile -> bufsiz);
- if (cfile -> buflen == 0) {
- c = EOF;
- cfile -> bufix = 0;
- } else if (cfile -> buflen < 0) {
- c = EOF;
- cfile -> bufix = cfile -> buflen = 0;
- } else {
- c = cfile -> inbuf [0];
- cfile -> bufix = 1;
- }
- } else
- c = EOF;
- } else {
- c = cfile -> inbuf [cfile -> bufix];
- cfile -> bufix++;
+ if (cfile->bufix == cfile->buflen)
+ c = EOF;
+ else {
+ c = cfile->inbuf [cfile->bufix];
+ cfile->bufix++;
}
- if (!cfile -> ugflag) {
+ if (!cfile->ugflag) {
if (c == EOL) {
- if (cfile -> cur_line == cfile -> line1) {
- cfile -> cur_line = cfile -> line2;
- cfile -> prev_line = cfile -> line1;
+ if (cfile->cur_line == cfile->line1) {
+ cfile->cur_line = cfile->line2;
+ cfile->prev_line = cfile->line1;
} else {
- cfile -> cur_line = cfile -> line1;
- cfile -> prev_line = cfile -> line2;
+ cfile->cur_line = cfile->line1;
+ cfile->prev_line = cfile->line2;
}
- cfile -> line++;
- cfile -> lpos = 1;
- cfile -> cur_line [0] = 0;
+ cfile->line++;
+ cfile->lpos = 1;
+ cfile->cur_line [0] = 0;
} else if (c != EOF) {
- if (cfile -> lpos <= 80) {
- cfile -> cur_line [cfile -> lpos - 1] = c;
- cfile -> cur_line [cfile -> lpos] = 0;
+ if (cfile->lpos <= 80) {
+ cfile->cur_line [cfile->lpos - 1] = c;
+ cfile->cur_line [cfile->lpos] = 0;
}
- cfile -> lpos++;
+ cfile->lpos++;
}
} else
- cfile -> ugflag = 0;
+ cfile->ugflag = 0;
return c;
}
#ifndef lint
static char copyright[] =
-"$Id: parse.c,v 1.124 2007/05/19 19:16:24 dhankins Exp $ Copyright (c) 2004-2007 Internet Systems Consortium. All rights reserved.\n";
+"$Id: parse.c,v 1.125 2007/05/23 15:29:49 shane Exp $ Copyright (c) 2004-2007 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
Parse an ip address or a hostname. If uniform is zero, put in
an expr_substring node to limit hostnames that evaluate to more
- than one IP address. */
+ than one IP address.
+
+ Note that RFC1123 permits hostnames to consist of all digits,
+ making it difficult to quickly disambiguate them from ip addresses.
+*/
int parse_ip_addr_or_hostname (expr, cfile, uniform)
struct expression **expr;
unsigned len = sizeof addr;
char *name;
struct expression *x = (struct expression *)0;
+ struct parse cfile0;
+ int ipaddr = 0;
token = peek_token (&val, (unsigned *)0, cfile);
- if (is_identifier (token)) {
+
+ if (token == NUMBER) {
+ /*
+ * a hostname may be numeric, but domain names must
+ * start with a letter, so we can disambiguate by
+ * looking ahead a few tokens. we save the parse
+ * context first, and restore it after we know what
+ * we're dealing with.
+ */
+ memcpy(&cfile0, cfile, sizeof(struct parse));
+ (void) next_token(NULL, NULL, cfile);
+ if (next_token(NULL, NULL, cfile) == DOT &&
+ next_token(NULL, NULL, cfile) == NUMBER)
+ ipaddr = 1;
+ memcpy(cfile, &cfile0, sizeof(struct parse));
+
+ if (ipaddr &&
+ parse_numeric_aggregate (cfile, addr, &len, DOT, 10, 8))
+ return make_const_data (expr, addr, len, 0, 1, MDL);
+
+ }
+
+ if (is_identifier (token) || token == NUMBER) {
name = parse_host_name (cfile);
if (!name)
return 0;
expression_dereference (expr, MDL);
*expr = x;
}
- } else if (token == NUMBER) {
- if (!parse_numeric_aggregate (cfile, addr, &len, DOT, 10, 8))
- return 0;
- return make_const_data (expr, addr, len, 0, 1, MDL);
} else {
if (token != RBRACE && token != LBRACE)
token = next_token (&val, (unsigned *)0, cfile);