/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI" /* SMI4.1 1.7 */
#include <stdio.h>
#include <ndbm.h>
#include <netdb.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
/*
*/
/*
* Size of buffer for input lines. Add two bytes on input for newline
* and terminating NULL. Note that the practical limit for data
* storage in ndbm is (PBLKSIZ - 3 * sizeof (short)). Though this
* differs from spec 1170 the common industry implementation does
* conform to this slightly lower limit.
*/
static char *cmd;
int warning = 0;
void
usage()
{
exit(1);
}
int
char **argv;
{
char *trailer;
int c;
++cmd;
else
switch (c) {
case 'w': /* Send warning messages to stderr */
warning = 1;
break;
case 'n':
ipv4 = 0;
break;
default:
usage();
exit(1);
}
}
exit(1);
}
} else
while (!endoffile &&
lineno++;
/* Check for comments */
/*
* Discard the remainder of the line
* until the newline or EOF, then
* continue to parse the line. Use
* adr[] rather then line[] to
* preserve the contents of line[].
*/
break;
}
endoffile = 1;
}
/* Terminate line[] at the comment character */
*commentp = '\0';
/*
* Catch long lines but not if this is a short
* line with no '\n' at the end of the input.
*/
if (warning)
"%s: Warning: more than %d "
"bytes on line %d, ignored\n",
/*
* Discard the remaining lines until the
* newline or EOF.
*/
break;
endoffile = 1;
continue;
}
continue;
}
if (warning)
"%s: Warning: no host names on line %d, "
continue;
}
/*
* check for valid addresses
*
* Attempt an ipv4 conversion, this accepts all valid
* ipv4 addresses including:
* d
* d.d
* d.d.d
* Unfortunately inet_pton() doesn't recognise these.
*/
/*
* It's safe not to check return of NULL as
* nadrp is checked for validity later.
*/
} else {
}
}
if (warning)
"%s: Warning: malformed"
" address on"
" line %d, ignored\n",
continue;
} else if (ipv4) {
continue; /* Ignore valid IPv6 */
}
}
} /* while */
return (0);
/* NOTREACHED */
}
/*
* verify_and_output
*
* Builds and verifies the output key and value string
*
* It makes sure these rules are followed:
* key + separator + value <= OUTPUTSIZ (for ndbm)
* names <= MAXALIASES + 1, ie one canonical name + MAXALIASES aliases
* It will also ignore everything after a '#' comment character
*/
static void
{
char *p; /* General char pointer */
int n = 0; /* Length of output */
if (key) { /* Just in case key is NULL */
if (n > OUTPUTSIZ) {
if (warning)
"%s: address too long on "
"line %d, line discarded\n",
return;
}
tmpbufp += n;
}
if (value) { /* Just in case value is NULL */
p = value;
do {
/*
* Skip white space. Type conversion is
* necessary to avoid unfortunate effects of
* 8-bit characters appearing negative.
*/
p++;
if (p == endp) /* End of the string */
break;
names++;
if (warning)
"%s: Warning: too many "
"host names on line %d, "
"truncating\n",
break;
}
namep = p;
p++;
*p = '\0'; /* Terminate the name string */
if (n > OUTPUTSIZ) {
if (warning)
"%s: Warning: %d byte ndbm limit "
"reached on line %d, truncating\n",
break;
}
*tmpbufp++ = '\t';
else
*tmpbufp++ = ' ';
if (p < endp)
p++; /* Skip the added NULL */
} while (p < endp);
}
if (names > 0) {
} else {
if (warning)
"%s: Warning: no host names on line %d, "
}
}