mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
Add missing Gnulib files; update `.gitignore'.
This files were missing from commit
61cd9dc907
("Use Gnulib's `getaddrinfo'
module.").
This commit is contained in:
parent
55ae00ea73
commit
40ff484d80
5 changed files with 776 additions and 0 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -123,3 +123,7 @@ INSTALL
|
||||||
/module/ice-9/eval.go.stamp
|
/module/ice-9/eval.go.stamp
|
||||||
/doc/ref/standard-library.texi
|
/doc/ref/standard-library.texi
|
||||||
/doc/ref/standard-libraryscmfiles
|
/doc/ref/standard-libraryscmfiles
|
||||||
|
/lib/wchar.h
|
||||||
|
/lib/sys/socket.h
|
||||||
|
/lib/warn-on-use.h
|
||||||
|
/lib/unused-parameter.h
|
||||||
|
|
76
lib/gai_strerror.c
Normal file
76
lib/gai_strerror.c
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
/* Copyright (C) 1997, 2001, 2002, 2004, 2005, 2006, 2008, 2009, 2010 Free
|
||||||
|
Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Philip Blundell <pjb27@cam.ac.uk>, 1997.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
#ifndef _LIBC
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
# include <libintl.h>
|
||||||
|
#else
|
||||||
|
# include "gettext.h"
|
||||||
|
# define _(String) gettext (String)
|
||||||
|
# define N_(String) String
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static struct
|
||||||
|
{
|
||||||
|
int code;
|
||||||
|
const char *msg;
|
||||||
|
}
|
||||||
|
values[] =
|
||||||
|
{
|
||||||
|
{ EAI_ADDRFAMILY, N_("Address family for hostname not supported") },
|
||||||
|
{ EAI_AGAIN, N_("Temporary failure in name resolution") },
|
||||||
|
{ EAI_BADFLAGS, N_("Bad value for ai_flags") },
|
||||||
|
{ EAI_FAIL, N_("Non-recoverable failure in name resolution") },
|
||||||
|
{ EAI_FAMILY, N_("ai_family not supported") },
|
||||||
|
{ EAI_MEMORY, N_("Memory allocation failure") },
|
||||||
|
{ EAI_NODATA, N_("No address associated with hostname") },
|
||||||
|
{ EAI_NONAME, N_("Name or service not known") },
|
||||||
|
{ EAI_SERVICE, N_("Servname not supported for ai_socktype") },
|
||||||
|
{ EAI_SOCKTYPE, N_("ai_socktype not supported") },
|
||||||
|
{ EAI_SYSTEM, N_("System error") },
|
||||||
|
{ EAI_OVERFLOW, N_("Argument buffer too small") },
|
||||||
|
#ifdef EAI_INPROGRESS
|
||||||
|
{ EAI_INPROGRESS, N_("Processing request in progress") },
|
||||||
|
{ EAI_CANCELED, N_("Request canceled") },
|
||||||
|
{ EAI_NOTCANCELED, N_("Request not canceled") },
|
||||||
|
{ EAI_ALLDONE, N_("All requests done") },
|
||||||
|
{ EAI_INTR, N_("Interrupted by a signal") },
|
||||||
|
{ EAI_IDN_ENCODE, N_("Parameter string not correctly encoded") }
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *
|
||||||
|
gai_strerror (int code)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < sizeof (values) / sizeof (values[0]); ++i)
|
||||||
|
if (values[i].code == code)
|
||||||
|
return _(values[i].msg);
|
||||||
|
|
||||||
|
return _("Unknown error");
|
||||||
|
}
|
||||||
|
#ifdef _LIBC
|
||||||
|
libc_hidden_def (gai_strerror)
|
||||||
|
#endif
|
438
lib/getaddrinfo.c
Normal file
438
lib/getaddrinfo.c
Normal file
|
@ -0,0 +1,438 @@
|
||||||
|
/* Get address information (partial implementation).
|
||||||
|
Copyright (C) 1997, 2001-2002, 2004-2010 Free Software Foundation, Inc.
|
||||||
|
Contributed by Simon Josefsson <simon@josefsson.org>.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc
|
||||||
|
optimizes away the sa == NULL test below. */
|
||||||
|
#define _GL_ARG_NONNULL(params)
|
||||||
|
|
||||||
|
#include <netdb.h>
|
||||||
|
|
||||||
|
#if HAVE_NETINET_IN_H
|
||||||
|
# include <netinet/in.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Get inet_ntop. */
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
/* Get calloc. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Get memcpy, strdup. */
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* Get snprintf. */
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "gettext.h"
|
||||||
|
#define _(String) gettext (String)
|
||||||
|
#define N_(String) String
|
||||||
|
|
||||||
|
/* BeOS has AF_INET, but not PF_INET. */
|
||||||
|
#ifndef PF_INET
|
||||||
|
# define PF_INET AF_INET
|
||||||
|
#endif
|
||||||
|
/* BeOS also lacks PF_UNSPEC. */
|
||||||
|
#ifndef PF_UNSPEC
|
||||||
|
# define PF_UNSPEC 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined _WIN32 || defined __WIN32__
|
||||||
|
# define WIN32_NATIVE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WIN32_NATIVE
|
||||||
|
typedef int (WSAAPI *getaddrinfo_func) (const char*, const char*,
|
||||||
|
const struct addrinfo*,
|
||||||
|
struct addrinfo**);
|
||||||
|
typedef void (WSAAPI *freeaddrinfo_func) (struct addrinfo*);
|
||||||
|
typedef int (WSAAPI *getnameinfo_func) (const struct sockaddr*,
|
||||||
|
socklen_t, char*, DWORD,
|
||||||
|
char*, DWORD, int);
|
||||||
|
|
||||||
|
static getaddrinfo_func getaddrinfo_ptr = NULL;
|
||||||
|
static freeaddrinfo_func freeaddrinfo_ptr = NULL;
|
||||||
|
static getnameinfo_func getnameinfo_ptr = NULL;
|
||||||
|
|
||||||
|
static int
|
||||||
|
use_win32_p (void)
|
||||||
|
{
|
||||||
|
static int done = 0;
|
||||||
|
HMODULE h;
|
||||||
|
|
||||||
|
if (done)
|
||||||
|
return getaddrinfo_ptr ? 1 : 0;
|
||||||
|
|
||||||
|
done = 1;
|
||||||
|
|
||||||
|
h = GetModuleHandle ("ws2_32.dll");
|
||||||
|
|
||||||
|
if (h)
|
||||||
|
{
|
||||||
|
getaddrinfo_ptr = (getaddrinfo_func) GetProcAddress (h, "getaddrinfo");
|
||||||
|
freeaddrinfo_ptr = (freeaddrinfo_func) GetProcAddress (h, "freeaddrinfo");
|
||||||
|
getnameinfo_ptr = (getnameinfo_func) GetProcAddress (h, "getnameinfo");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If either is missing, something is odd. */
|
||||||
|
if (!getaddrinfo_ptr || !freeaddrinfo_ptr || !getnameinfo_ptr)
|
||||||
|
{
|
||||||
|
getaddrinfo_ptr = NULL;
|
||||||
|
freeaddrinfo_ptr = NULL;
|
||||||
|
getnameinfo_ptr = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
validate_family (int family)
|
||||||
|
{
|
||||||
|
/* FIXME: Support more families. */
|
||||||
|
#if HAVE_IPV4
|
||||||
|
if (family == PF_INET)
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
#if HAVE_IPV6
|
||||||
|
if (family == PF_INET6)
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
if (family == PF_UNSPEC)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Translate name of a service location and/or a service name to set of
|
||||||
|
socket addresses. */
|
||||||
|
int
|
||||||
|
getaddrinfo (const char *restrict nodename,
|
||||||
|
const char *restrict servname,
|
||||||
|
const struct addrinfo *restrict hints,
|
||||||
|
struct addrinfo **restrict res)
|
||||||
|
{
|
||||||
|
struct addrinfo *tmp;
|
||||||
|
int port = 0;
|
||||||
|
struct hostent *he;
|
||||||
|
void *storage;
|
||||||
|
size_t size;
|
||||||
|
#if HAVE_IPV6
|
||||||
|
struct v6_pair {
|
||||||
|
struct addrinfo addrinfo;
|
||||||
|
struct sockaddr_in6 sockaddr_in6;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
#if HAVE_IPV4
|
||||||
|
struct v4_pair {
|
||||||
|
struct addrinfo addrinfo;
|
||||||
|
struct sockaddr_in sockaddr_in;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WIN32_NATIVE
|
||||||
|
if (use_win32_p ())
|
||||||
|
return getaddrinfo_ptr (nodename, servname, hints, res);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (hints && (hints->ai_flags & ~(AI_CANONNAME|AI_PASSIVE)))
|
||||||
|
/* FIXME: Support more flags. */
|
||||||
|
return EAI_BADFLAGS;
|
||||||
|
|
||||||
|
if (hints && !validate_family (hints->ai_family))
|
||||||
|
return EAI_FAMILY;
|
||||||
|
|
||||||
|
if (hints &&
|
||||||
|
hints->ai_socktype != SOCK_STREAM && hints->ai_socktype != SOCK_DGRAM)
|
||||||
|
/* FIXME: Support other socktype. */
|
||||||
|
return EAI_SOCKTYPE; /* FIXME: Better return code? */
|
||||||
|
|
||||||
|
if (!nodename)
|
||||||
|
{
|
||||||
|
if (!(hints->ai_flags & AI_PASSIVE))
|
||||||
|
return EAI_NONAME;
|
||||||
|
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
nodename = (hints->ai_family == AF_INET6) ? "::" : "0.0.0.0";
|
||||||
|
#else
|
||||||
|
nodename = "0.0.0.0";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (servname)
|
||||||
|
{
|
||||||
|
struct servent *se = NULL;
|
||||||
|
const char *proto =
|
||||||
|
(hints && hints->ai_socktype == SOCK_DGRAM) ? "udp" : "tcp";
|
||||||
|
|
||||||
|
if (hints == NULL || !(hints->ai_flags & AI_NUMERICSERV))
|
||||||
|
/* FIXME: Use getservbyname_r if available. */
|
||||||
|
se = getservbyname (servname, proto);
|
||||||
|
|
||||||
|
if (!se)
|
||||||
|
{
|
||||||
|
char *c;
|
||||||
|
if (!(*servname >= '0' && *servname <= '9'))
|
||||||
|
return EAI_NONAME;
|
||||||
|
port = strtoul (servname, &c, 10);
|
||||||
|
if (*c || port > 0xffff)
|
||||||
|
return EAI_NONAME;
|
||||||
|
port = htons (port);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
port = se->s_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: Use gethostbyname_r if available. */
|
||||||
|
he = gethostbyname (nodename);
|
||||||
|
if (!he || he->h_addr_list[0] == NULL)
|
||||||
|
return EAI_NONAME;
|
||||||
|
|
||||||
|
switch (he->h_addrtype)
|
||||||
|
{
|
||||||
|
#if HAVE_IPV6
|
||||||
|
case PF_INET6:
|
||||||
|
size = sizeof (struct v6_pair);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_IPV4
|
||||||
|
case PF_INET:
|
||||||
|
size = sizeof (struct v4_pair);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
return EAI_NODATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
storage = calloc (1, size);
|
||||||
|
if (!storage)
|
||||||
|
return EAI_MEMORY;
|
||||||
|
|
||||||
|
switch (he->h_addrtype)
|
||||||
|
{
|
||||||
|
#if HAVE_IPV6
|
||||||
|
case PF_INET6:
|
||||||
|
{
|
||||||
|
struct v6_pair *p = storage;
|
||||||
|
struct sockaddr_in6 *sinp = &p->sockaddr_in6;
|
||||||
|
tmp = &p->addrinfo;
|
||||||
|
|
||||||
|
if (port)
|
||||||
|
sinp->sin6_port = port;
|
||||||
|
|
||||||
|
if (he->h_length != sizeof (sinp->sin6_addr))
|
||||||
|
{
|
||||||
|
free (storage);
|
||||||
|
return EAI_SYSTEM; /* FIXME: Better return code? Set errno? */
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy (&sinp->sin6_addr, he->h_addr_list[0], sizeof sinp->sin6_addr);
|
||||||
|
|
||||||
|
tmp->ai_addr = (struct sockaddr *) sinp;
|
||||||
|
tmp->ai_addrlen = sizeof *sinp;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_IPV4
|
||||||
|
case PF_INET:
|
||||||
|
{
|
||||||
|
struct v4_pair *p = storage;
|
||||||
|
struct sockaddr_in *sinp = &p->sockaddr_in;
|
||||||
|
tmp = &p->addrinfo;
|
||||||
|
|
||||||
|
if (port)
|
||||||
|
sinp->sin_port = port;
|
||||||
|
|
||||||
|
if (he->h_length != sizeof (sinp->sin_addr))
|
||||||
|
{
|
||||||
|
free (storage);
|
||||||
|
return EAI_SYSTEM; /* FIXME: Better return code? Set errno? */
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy (&sinp->sin_addr, he->h_addr_list[0], sizeof sinp->sin_addr);
|
||||||
|
|
||||||
|
tmp->ai_addr = (struct sockaddr *) sinp;
|
||||||
|
tmp->ai_addrlen = sizeof *sinp;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
free (storage);
|
||||||
|
return EAI_NODATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hints && hints->ai_flags & AI_CANONNAME)
|
||||||
|
{
|
||||||
|
const char *cn;
|
||||||
|
if (he->h_name)
|
||||||
|
cn = he->h_name;
|
||||||
|
else
|
||||||
|
cn = nodename;
|
||||||
|
|
||||||
|
tmp->ai_canonname = strdup (cn);
|
||||||
|
if (!tmp->ai_canonname)
|
||||||
|
{
|
||||||
|
free (storage);
|
||||||
|
return EAI_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp->ai_protocol = (hints) ? hints->ai_protocol : 0;
|
||||||
|
tmp->ai_socktype = (hints) ? hints->ai_socktype : 0;
|
||||||
|
tmp->ai_addr->sa_family = he->h_addrtype;
|
||||||
|
tmp->ai_family = he->h_addrtype;
|
||||||
|
|
||||||
|
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
|
||||||
|
switch (he->h_addrtype)
|
||||||
|
{
|
||||||
|
#if HAVE_IPV4
|
||||||
|
case AF_INET:
|
||||||
|
tmp->ai_addr->sa_len = sizeof (struct sockaddr_in);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if HAVE_IPV6
|
||||||
|
case AF_INET6:
|
||||||
|
tmp->ai_addr->sa_len = sizeof (struct sockaddr_in6);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* FIXME: If more than one address, create linked list of addrinfo's. */
|
||||||
|
|
||||||
|
*res = tmp;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free `addrinfo' structure AI including associated storage. */
|
||||||
|
void
|
||||||
|
freeaddrinfo (struct addrinfo *ai)
|
||||||
|
{
|
||||||
|
#ifdef WIN32_NATIVE
|
||||||
|
if (use_win32_p ())
|
||||||
|
{
|
||||||
|
freeaddrinfo_ptr (ai);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while (ai)
|
||||||
|
{
|
||||||
|
struct addrinfo *cur;
|
||||||
|
|
||||||
|
cur = ai;
|
||||||
|
ai = ai->ai_next;
|
||||||
|
|
||||||
|
free (cur->ai_canonname);
|
||||||
|
free (cur);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen,
|
||||||
|
char *restrict node, socklen_t nodelen,
|
||||||
|
char *restrict service, socklen_t servicelen,
|
||||||
|
int flags)
|
||||||
|
{
|
||||||
|
#ifdef WIN32_NATIVE
|
||||||
|
if (use_win32_p ())
|
||||||
|
return getnameinfo_ptr (sa, salen, node, nodelen,
|
||||||
|
service, servicelen, flags);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* FIXME: Support other flags. */
|
||||||
|
if ((node && nodelen > 0 && !(flags & NI_NUMERICHOST)) ||
|
||||||
|
(service && servicelen > 0 && !(flags & NI_NUMERICHOST)) ||
|
||||||
|
(flags & ~(NI_NUMERICHOST|NI_NUMERICSERV)))
|
||||||
|
return EAI_BADFLAGS;
|
||||||
|
|
||||||
|
if (sa == NULL || salen < sizeof (sa->sa_family))
|
||||||
|
return EAI_FAMILY;
|
||||||
|
|
||||||
|
switch (sa->sa_family)
|
||||||
|
{
|
||||||
|
#if HAVE_IPV4
|
||||||
|
case AF_INET:
|
||||||
|
if (salen < sizeof (struct sockaddr_in))
|
||||||
|
return EAI_FAMILY;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if HAVE_IPV6
|
||||||
|
case AF_INET6:
|
||||||
|
if (salen < sizeof (struct sockaddr_in6))
|
||||||
|
return EAI_FAMILY;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return EAI_FAMILY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node && nodelen > 0 && flags & NI_NUMERICHOST)
|
||||||
|
{
|
||||||
|
switch (sa->sa_family)
|
||||||
|
{
|
||||||
|
#if HAVE_IPV4
|
||||||
|
case AF_INET:
|
||||||
|
if (!inet_ntop (AF_INET,
|
||||||
|
&(((const struct sockaddr_in *) sa)->sin_addr),
|
||||||
|
node, nodelen))
|
||||||
|
return EAI_SYSTEM;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_IPV6
|
||||||
|
case AF_INET6:
|
||||||
|
if (!inet_ntop (AF_INET6,
|
||||||
|
&(((const struct sockaddr_in6 *) sa)->sin6_addr),
|
||||||
|
node, nodelen))
|
||||||
|
return EAI_SYSTEM;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
return EAI_FAMILY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (service && servicelen > 0 && flags & NI_NUMERICSERV)
|
||||||
|
switch (sa->sa_family)
|
||||||
|
{
|
||||||
|
#if HAVE_IPV4
|
||||||
|
case AF_INET:
|
||||||
|
#endif
|
||||||
|
#if HAVE_IPV6
|
||||||
|
case AF_INET6:
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
unsigned short int port
|
||||||
|
= ntohs (((const struct sockaddr_in *) sa)->sin_port);
|
||||||
|
if (servicelen <= snprintf (service, servicelen, "%u", port))
|
||||||
|
return EAI_OVERFLOW;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
186
lib/netdb.in.h
Normal file
186
lib/netdb.in.h
Normal file
|
@ -0,0 +1,186 @@
|
||||||
|
/* Provide a netdb.h header file for systems lacking it (read: MinGW).
|
||||||
|
Copyright (C) 2008-2010 Free Software Foundation, Inc.
|
||||||
|
Written by Simon Josefsson.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
/* This file is supposed to be used on platforms that lack <netdb.h>.
|
||||||
|
It is intended to provide definitions and prototypes needed by an
|
||||||
|
application. */
|
||||||
|
|
||||||
|
#ifndef _GL_NETDB_H
|
||||||
|
|
||||||
|
#if @HAVE_NETDB_H@
|
||||||
|
|
||||||
|
# if __GNUC__ >= 3
|
||||||
|
@PRAGMA_SYSTEM_HEADER@
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* The include_next requires a split double-inclusion guard. */
|
||||||
|
# @INCLUDE_NEXT@ @NEXT_NETDB_H@
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _GL_NETDB_H
|
||||||
|
#define _GL_NETDB_H
|
||||||
|
|
||||||
|
/* Get netdb.h definitions such as struct hostent for MinGW. */
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
/* The definition of _GL_ARG_NONNULL is copied here. */
|
||||||
|
|
||||||
|
/* Declarations for a platform that lacks <netdb.h>, or where it is
|
||||||
|
incomplete. */
|
||||||
|
|
||||||
|
#if @GNULIB_GETADDRINFO@
|
||||||
|
|
||||||
|
# if !@HAVE_STRUCT_ADDRINFO@
|
||||||
|
|
||||||
|
/* Structure to contain information about address of a service provider. */
|
||||||
|
struct addrinfo
|
||||||
|
{
|
||||||
|
int ai_flags; /* Input flags. */
|
||||||
|
int ai_family; /* Protocol family for socket. */
|
||||||
|
int ai_socktype; /* Socket type. */
|
||||||
|
int ai_protocol; /* Protocol for socket. */
|
||||||
|
socklen_t ai_addrlen; /* Length of socket address. */
|
||||||
|
struct sockaddr *ai_addr; /* Socket address for socket. */
|
||||||
|
char *ai_canonname; /* Canonical name for service location. */
|
||||||
|
struct addrinfo *ai_next; /* Pointer to next in list. */
|
||||||
|
};
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* Possible values for `ai_flags' field in `addrinfo' structure. */
|
||||||
|
# ifndef AI_PASSIVE
|
||||||
|
# define AI_PASSIVE 0x0001 /* Socket address is intended for `bind'. */
|
||||||
|
# endif
|
||||||
|
# ifndef AI_CANONNAME
|
||||||
|
# define AI_CANONNAME 0x0002 /* Request for canonical name. */
|
||||||
|
# endif
|
||||||
|
# ifndef AI_NUMERICSERV
|
||||||
|
# define AI_NUMERICSERV 0x0400 /* Don't use name resolution. */
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if 0
|
||||||
|
/* The commented out definitions below are not yet implemented in the
|
||||||
|
GNULIB getaddrinfo() replacement, so are not yet needed and may, in fact,
|
||||||
|
cause conflicts on systems with a getaddrinfo() function which does not
|
||||||
|
define them.
|
||||||
|
|
||||||
|
If they are restored, be sure to protect the definitions with #ifndef. */
|
||||||
|
# define AI_NUMERICHOST 0x0004 /* Don't use name resolution. */
|
||||||
|
# define AI_V4MAPPED 0x0008 /* IPv4 mapped addresses are acceptable. */
|
||||||
|
# define AI_ALL 0x0010 /* Return IPv4 mapped and IPv6 addresses. */
|
||||||
|
# define AI_ADDRCONFIG 0x0020 /* Use configuration of this host to choose
|
||||||
|
returned address type.. */
|
||||||
|
# endif /* 0 */
|
||||||
|
|
||||||
|
/* Error values for `getaddrinfo' function. */
|
||||||
|
# ifndef EAI_BADFLAGS
|
||||||
|
# define EAI_BADFLAGS -1 /* Invalid value for `ai_flags' field. */
|
||||||
|
# define EAI_NONAME -2 /* NAME or SERVICE is unknown. */
|
||||||
|
# define EAI_AGAIN -3 /* Temporary failure in name resolution. */
|
||||||
|
# define EAI_FAIL -4 /* Non-recoverable failure in name res. */
|
||||||
|
# define EAI_NODATA -5 /* No address associated with NAME. */
|
||||||
|
# define EAI_FAMILY -6 /* `ai_family' not supported. */
|
||||||
|
# define EAI_SOCKTYPE -7 /* `ai_socktype' not supported. */
|
||||||
|
# define EAI_SERVICE -8 /* SERVICE not supported for `ai_socktype'. */
|
||||||
|
# define EAI_MEMORY -10 /* Memory allocation failure. */
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* Since EAI_NODATA is deprecated by RFC3493, some systems (at least
|
||||||
|
FreeBSD, which does define EAI_BADFLAGS) have removed the definition
|
||||||
|
in favor of EAI_NONAME. */
|
||||||
|
# if !defined EAI_NODATA && defined EAI_NONAME
|
||||||
|
# define EAI_NODATA EAI_NONAME
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifndef EAI_OVERFLOW
|
||||||
|
/* Not defined on mingw32 and Haiku. */
|
||||||
|
# define EAI_OVERFLOW -12 /* Argument buffer overflow. */
|
||||||
|
# endif
|
||||||
|
# ifndef EAI_ADDRFAMILY
|
||||||
|
/* Not defined on mingw32. */
|
||||||
|
# define EAI_ADDRFAMILY -9 /* Address family for NAME not supported. */
|
||||||
|
# endif
|
||||||
|
# ifndef EAI_SYSTEM
|
||||||
|
/* Not defined on mingw32. */
|
||||||
|
# define EAI_SYSTEM -11 /* System error returned in `errno'. */
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if 0
|
||||||
|
/* The commented out definitions below are not yet implemented in the
|
||||||
|
GNULIB getaddrinfo() replacement, so are not yet needed.
|
||||||
|
|
||||||
|
If they are restored, be sure to protect the definitions with #ifndef. */
|
||||||
|
# ifndef EAI_INPROGRESS
|
||||||
|
# define EAI_INPROGRESS -100 /* Processing request in progress. */
|
||||||
|
# define EAI_CANCELED -101 /* Request canceled. */
|
||||||
|
# define EAI_NOTCANCELED -102 /* Request not canceled. */
|
||||||
|
# define EAI_ALLDONE -103 /* All requests done. */
|
||||||
|
# define EAI_INTR -104 /* Interrupted by a signal. */
|
||||||
|
# define EAI_IDN_ENCODE -105 /* IDN encoding failed. */
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if !@HAVE_DECL_GETADDRINFO@
|
||||||
|
/* Translate name of a service location and/or a service name to set of
|
||||||
|
socket addresses.
|
||||||
|
For more details, see the POSIX:2001 specification
|
||||||
|
<http://www.opengroup.org/susv3xsh/getaddrinfo.html>. */
|
||||||
|
extern int getaddrinfo (const char *restrict nodename,
|
||||||
|
const char *restrict servname,
|
||||||
|
const struct addrinfo *restrict hints,
|
||||||
|
struct addrinfo **restrict res)
|
||||||
|
_GL_ARG_NONNULL ((4));
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if !@HAVE_DECL_FREEADDRINFO@
|
||||||
|
/* Free `addrinfo' structure AI including associated storage.
|
||||||
|
For more details, see the POSIX:2001 specification
|
||||||
|
<http://www.opengroup.org/susv3xsh/getaddrinfo.html>. */
|
||||||
|
extern void freeaddrinfo (struct addrinfo *ai) _GL_ARG_NONNULL ((1));
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if !@HAVE_DECL_GAI_STRERROR@
|
||||||
|
/* Convert error return from getaddrinfo() to a string.
|
||||||
|
For more details, see the POSIX:2001 specification
|
||||||
|
<http://www.opengroup.org/susv3xsh/gai_strerror.html>. */
|
||||||
|
extern const char *gai_strerror (int ecode);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if !@HAVE_DECL_GETNAMEINFO@
|
||||||
|
/* Convert socket address to printable node and service names.
|
||||||
|
For more details, see the POSIX:2001 specification
|
||||||
|
<http://www.opengroup.org/susv3xsh/getnameinfo.html>. */
|
||||||
|
extern int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen,
|
||||||
|
char *restrict node, socklen_t nodelen,
|
||||||
|
char *restrict service, socklen_t servicelen,
|
||||||
|
int flags)
|
||||||
|
_GL_ARG_NONNULL ((1));
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* Possible flags for getnameinfo. */
|
||||||
|
# ifndef NI_NUMERICHOST
|
||||||
|
# define NI_NUMERICHOST 1
|
||||||
|
# endif
|
||||||
|
# ifndef NI_NUMERICSERV
|
||||||
|
# define NI_NUMERICSERV 2
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#endif /* @GNULIB_GETADDRINFO@ */
|
||||||
|
|
||||||
|
#endif /* _GL_NETDB_H */
|
||||||
|
#endif /* _GL_NETDB_H */
|
72
lib/snprintf.c
Normal file
72
lib/snprintf.c
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
/* Formatted output to strings.
|
||||||
|
Copyright (C) 2004, 2006-2010 Free Software Foundation, Inc.
|
||||||
|
Written by Simon Josefsson and Paul Eggert.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
/* Specification. */
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "vasnprintf.h"
|
||||||
|
|
||||||
|
/* Print formatted output to string STR. Similar to sprintf, but
|
||||||
|
additional length SIZE limit how much is written into STR. Returns
|
||||||
|
string length of formatted string (which may be larger than SIZE).
|
||||||
|
STR may be NULL, in which case nothing will be written. On error,
|
||||||
|
return a negative value. */
|
||||||
|
int
|
||||||
|
snprintf (char *str, size_t size, const char *format, ...)
|
||||||
|
{
|
||||||
|
char *output;
|
||||||
|
size_t len;
|
||||||
|
size_t lenbuf = size;
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start (args, format);
|
||||||
|
output = vasnprintf (str, &lenbuf, format, args);
|
||||||
|
len = lenbuf;
|
||||||
|
va_end (args);
|
||||||
|
|
||||||
|
if (!output)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (output != str)
|
||||||
|
{
|
||||||
|
if (size)
|
||||||
|
{
|
||||||
|
size_t pruned_len = (len < size ? len : size - 1);
|
||||||
|
memcpy (str, output, pruned_len);
|
||||||
|
str[pruned_len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
free (output);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (INT_MAX < len)
|
||||||
|
{
|
||||||
|
errno = EOVERFLOW;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue