gethostent.c revision e37190e5b4531a897e4191a30b8f41678b582e25
/*
* 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 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* files/gethostent.c -- "files" backend for nsswitch "hosts" database
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <netdb.h>
#include "files_common.h"
#include <string.h>
#include <strings.h>
#include <stddef.h>
#include <stdlib.h>
#include <ctype.h>
static int check_name(nss_XbyY_args_t *, const char *, int,
int, const char **, int *, void *, int *);
static char *do_aliases();
int __nss_files_2herrno();
static int __nss_files_get_addr(int, const char *, int,
void *, int, int *);
static int
{
/* Address */
if (*linep == ':')
v6flag++;
linep++;
}
/* skip the delimiting spaces */
linep++;
/* Canonical name */
keyp++;
linep++;
}
return (1);
}
}
linep++;
/* Aliases */
/* skip the delimiting spaces */
linep++;
/* compare name (case insensitive) */
keyp++;
linep++;
}
/* skip remainder of alias, if any */
linep++;
}
return (0);
}
static nss_status_t
void *a;
{
if (res != NSS_SUCCESS)
return (res);
}
static int
{
return (0);
return (0);
if (v6flag) {
return (0);
} else {
0xffffffffU)
return (0);
}
} else {
return (0);
}
return (1);
}
int
int linelen)
{
char *h_addrp;
/* Compare the address type */
return (0);
/* Retrieve the address */
else
if (*linep == ':')
v6flag++;
linep++;
}
return (0);
/* Compare the address */
}
static int
{
}
static nss_status_t
void *a;
{
if (res != NSS_SUCCESS)
return (res);
}
/*
* filter_ipv6
*
* Return - NSS_STR_PARSE_SUCCESS: An IPv4 address
* NSS_STR_PARSE_PARSE: An IPv6 address or other errors
*/
static int
int rc;
p = instr;
addrstart = p;
/* parse IP address */
if (*p == ':')
/* IPv6 */
return (NSS_STR_PARSE_PARSE);
else
p++;
}
if (p >= limit)
/* invalid IP */
return (NSS_STR_PARSE_PARSE);
/* extract IP address */
c = *p;
*p = '\0';
*p = c;
if (rc == 0)
/* invalid IP */
return (NSS_STR_PARSE_PARSE);
else
/* IPv4 */
return (NSS_STR_PARSE_SUCCESS);
}
static nss_status_t
{
} else {
/*
* Called by nscd
*/
/*CONSTCOND*/
while (1) {
/*
* NSS_NOTFOUND, end of file or other errors.
*/
if (rc != NSS_SUCCESS)
break;
/*
* These addresses have to be filtered.
*/
break;
/*
* The entry is an IPv6 address or other errors.
* Skip it and continue to find next one.
*/
}
return (rc);
}
}
static files_backend_op_t host_ops[] = {
};
/*ARGSUSED*/
{
return (_nss_files_constr(host_ops,
NULL));
}
/*
* XXX - this duplicates code from files_common.c because we need to keep
* going after we've found a match to satisfy the multihomed host case.
*/
const char *filter; /* hint for name string */
int type;
{
const char *namep;
char *h_name;
void *addrp;
return (NSS_UNAVAIL);
}
if (be->f == 0) {
return (res);
}
return (NSS_UNAVAIL);
} else {
return (NSS_UNAVAIL);
}
res = NSS_NOTFOUND;
h_namelen = 0;
for (;;) {
int linelen;
break; /* EOF */
}
/*
* This check avoids a malloc()/free() for the common
* case. Also, if we're trying to match an alias and an
* already matched entry doesn't share a canonical name
* with the current one, bail.
*/
continue;
}
*last-- = '\0';
;
/* Ignore blank and comment lines */
if (*first == '\0')
continue;
--last;
/* Bail out if the canonical name does not match */
continue;
}
/*
* Still need to check, strcasestr() above is just a hint.
*/
addrp, &i)) {
/*
* If we've already matched once and have a possible
* match on this line, copy the aliases where they're
* safe from being overwritten when we look at the
* next entry. They're saved as a string of blank
* separated names for the alias parser. On errors,
* we return failure whether or not we have already
* obtained a valid address.
*/
res = NSS_NOTFOUND;
break;
}
res = NSS_UNAVAIL;
break;
}
abuf_start = abuf;
*abuf = '\0';
res = NSS_NOTFOUND;
break;
}
}
/* inside the application */
if (parsestat != NSS_STR_PARSE_SUCCESS) {
if (parsestat == NSS_STR_PARSE_ERANGE)
continue;
}
} else {
/* inside nscd */
char *ap;
/* Add alias to the first line if any */
if (nhosts > 0) {
/* get to the start of alias */
/* see if there's any alias */
alen = 0;
else
erange = 1;
/* make room for the alias */
/* copy in the alias */
}
/* Add delimiter to the buffer */
*buffer++ = '\n';
buflen--;
}
/* copy just the addr if not first one */
else
if (nhosts > 0) {
*(--buffer) = '\0';
buflen++;
}
continue;
}
/* Adjust buffer */
*buffer = '\0';
}
/*
* If this is the first one, save the canonical
* name for future matches and continue.
*/
if (++nhosts == 1) {
res = NSS_UNAVAIL;
break;
}
res = NSS_SUCCESS;
if (hp)
else
continue;
}
/* Extend the array */
ntaddr *= 2;
res = NSS_UNAVAIL;
break;
}
} else {
res = NSS_UNAVAIL;
break;
}
}
}
/*
* For non-nscd, save aliases in a temporary buffer
* Don't have to do this for nscd as 'buffer' already
* contains the required data in the appropriate
* format
*/
if (hp) {
res = NSS_NOTFOUND;
break;
}
}
/*
* This line didn't have the requested name but
* is part of the same multihomed host (i.e. it
* has the same canonical name as the previous
* line), so march on...
*/
continue;
} else if (nhosts) {
continue;
}
}
/* abuf != NULL implies hp and abuf_start != NULL */
((nhosts + 1) * sizeof (char *) +
}
} else {
sizeof (*addrp6)));
((nhosts + 1) * sizeof (char *) +
sizeof (struct in6_addr));
}
}
res = NSS_NOTFOUND;
} else {
}
}
/*
* stayopen is set to 0 by default in order to close the opened
* file. Some applications may break if it is set to 1.
*/
(void) _nss_files_endent(be, 0);
if (taddr)
if (taddr6)
if (h_name)
if (abuf_start)
return (res);
}
/*
* A case-insensitive version of strstr().
*/
static char *
{
int c2;
register const char *tptr;
return (0);
while (*s1) {
;
if (c2 == 0)
return ((char *)tptr - 1);
}
}
return (0);
}
static char *
{
char **cp;
return (abuf);
return (NULL);
}
*abuf++ = ' ';
}
*abuf = '\0';
return (abuf);
}
/*
* This is a copy of a routine in libnsl/nss/netdir_inet.c. It is
* here because /etc/lib/nss_files.so.1 cannot call routines
* in libnsl. Care should be taken to keep the two copies in sync.
*/
int
{
switch (nsstat) {
case NSS_SUCCESS:
/* no macro-defined success code for h_errno */
return (0);
case NSS_NOTFOUND:
return (HOST_NOT_FOUND);
case NSS_TRYAGAIN:
return (TRY_AGAIN);
case NSS_UNAVAIL:
return (NO_RECOVERY);
}
/* anything else */
return (NO_RECOVERY);
}