nss-myhostname.c revision 1d050e1e0a7082e23ee9b31fa0b819cb332b3444
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2008-2011 Lennart Poettering
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <limits.h>
#include <nss.h>
#include <netdb.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include "local-addresses.h"
#include "macro.h"
#include "nss-util.h"
#include "util.h"
/* We use 127.0.0.2 as IPv4 address. This has the advantage over
* 127.0.0.1 that it can be translated back to the local hostname. For
* IPv6 we use ::1 which unfortunately will not translate back to the
* hostname but instead something like "localhost6" or so. */
#define LOCALADDRESS_IPV6 &in6addr_loopback
#define LOOPBACK_INTERFACE "lo"
const char *name,
struct gaih_addrtuple **pat,
int n_addresses = 0, lo_ifi;
struct local_address *a;
char *r_name;
unsigned n;
if (is_localhost(name)) {
* is optional */
canonical = "localhost";
if (n_addresses <= 0) {
return NSS_STATUS_NOTFOUND;
}
canonical = "gateway";
} else {
hn = gethostname_malloc();
if (!hn) {
*h_errnop = NO_RECOVERY;
return NSS_STATUS_TRYAGAIN;
}
/* We respond to our local host name, our our hostname suffixed with a single dot. */
return NSS_STATUS_NOTFOUND;
}
if (n_addresses < 0)
n_addresses = 0;
}
/* If this call fails we fill in 0 as scope. Which is fine */
*h_errnop = NO_RECOVERY;
return NSS_STATUS_TRYAGAIN;
}
/* First, fill in hostname */
if (n_addresses <= 0) {
/* Second, fill in IPv6 tuple */
/* Third, fill in IPv4 tuple */
}
/* Fourth, fill actual addresses in, but in backwards order */
}
/* Verify the size matches */
/* Nscd expects us to store the first record in **pat. */
if (*pat)
**pat = *r_tuple_prev;
else
*pat = r_tuple_prev;
if (ttlp)
*ttlp = 0;
/* Explicitly reset all error variables */
*errnop = 0;
h_errno = 0;
return NSS_STATUS_SUCCESS;
}
static enum nss_status fill_in_hostent(
const char *canonical, const char *additional,
int af,
char **canonp) {
struct local_address *a;
unsigned n, c;
for (a = addresses, n = 0, c = 0; n < n_addresses; a++, n++)
c++;
sizeof(char*) +
(additional ? sizeof(char*) : 0) +
(c > 0 ? c+1 : 2) * sizeof(char*);
*h_errnop = NO_RECOVERY;
return NSS_STATUS_TRYAGAIN;
}
/* First, fill in hostnames */
if (additional) {
}
/* Second, create aliases array */
if (additional) {
idx += 2*sizeof(char*);
} else {
idx += sizeof(char*);
}
/* Third, add addresses */
if (c > 0) {
unsigned i = 0;
for (a = addresses, n = 0; n < n_addresses; a++, n++) {
continue;
i++;
}
assert(i == c);
} else {
else
}
/* Fourth, add address pointer array */
if (c > 0) {
unsigned i;
for (i = 0; i < c; i++)
((char**) r_addr_list)[i] = NULL;
idx += (c+1) * sizeof(char*);
} else {
((char**) r_addr_list)[0] = r_addr;
idx += 2 * sizeof(char*);
}
/* Verify the size matches */
if (ttlp)
*ttlp = 0;
if (canonp)
/* Explicitly reset all error variables */
*errnop = 0;
h_errno = 0;
return NSS_STATUS_SUCCESS;
}
const char *name,
int af,
char **canonp) {
int n_addresses = 0;
*errnop = EAFNOSUPPORT;
return NSS_STATUS_UNAVAIL;
}
if (is_localhost(name)) {
canonical = "localhost";
if (n_addresses <= 0) {
return NSS_STATUS_NOTFOUND;
}
canonical = "gateway";
} else {
hn = gethostname_malloc();
if (!hn) {
*h_errnop = NO_RECOVERY;
return NSS_STATUS_TRYAGAIN;
}
return NSS_STATUS_NOTFOUND;
}
if (n_addresses < 0)
n_addresses = 0;
}
return fill_in_hostent(
af,
host,
ttlp,
canonp);
}
int af,
int n_addresses = 0;
struct local_address *a;
unsigned n;
*errnop = EAFNOSUPPORT;
return NSS_STATUS_UNAVAIL;
}
*h_errnop = NO_RECOVERY;
return NSS_STATUS_UNAVAIL;
}
goto found;
canonical = "localhost";
goto found;
}
} else {
additional = "localhost";
goto found;
}
}
if (n_addresses > 0) {
for (a = addresses, n = 0; (int) n < n_addresses; n++, a++) {
continue;
hn = gethostname_malloc();
if (!hn) {
*h_errnop = NO_RECOVERY;
return NSS_STATUS_TRYAGAIN;
}
goto found;
}
}
}
if (n_addresses > 0) {
for (a = addresses, n = 0; (int) n < n_addresses; n++, a++) {
continue;
canonical = "gateway";
goto found;
}
}
}
return NSS_STATUS_NOTFOUND;
return fill_in_hostent(
af,
host,
ttlp,
NULL);
}