/[cvs]/ccvs/lib/getaddrinfo.c
ViewVC logotype

Diff of /ccvs/lib/getaddrinfo.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.4 by dprice, Tue Sep 20 16:57:24 2005 UTC revision 1.5 by dprice, Tue Oct 4 02:34:53 2005 UTC
# Line 22  Line 22 
22    
23  #include "getaddrinfo.h"  #include "getaddrinfo.h"
24    
25    #if HAVE_NETINET_IN_H
26    # include <netinet/in.h>
27    #endif
28    
29  /* Get calloc. */  /* Get calloc. */
30  #include <stdlib.h>  #include <stdlib.h>
31    
# Line 62  getaddrinfo (const char *restrict nodena Line 66  getaddrinfo (const char *restrict nodena
66               struct addrinfo **restrict res)               struct addrinfo **restrict res)
67  {  {
68    struct addrinfo *tmp;    struct addrinfo *tmp;
69    struct servent *se;    struct servent *se = NULL;
70    struct hostent *he;    struct hostent *he;
71    size_t sinlen;    void *storage;
72      size_t size;
73    #if HAVE_IPV6
74      struct v6_pair {
75        struct addrinfo addrinfo;
76        struct sockaddr_in6 sockaddr_in6;
77      };
78    #endif
79    #if HAVE_IPV4
80      struct v4_pair {
81        struct addrinfo addrinfo;
82        struct sockaddr_in sockaddr_in;
83      };
84    #endif
85    
86    if (hints && (hints->ai_flags & ~AI_CANONNAME))    if (hints && (hints->ai_flags & ~AI_CANONNAME))
87      /* FIXME: Support more flags. */      /* FIXME: Support more flags. */
# Line 103  getaddrinfo (const char *restrict nodena Line 120  getaddrinfo (const char *restrict nodena
120      {      {
121  #if HAVE_IPV6  #if HAVE_IPV6
122      case PF_INET6:      case PF_INET6:
123        sinlen = sizeof (struct sockaddr_in6);        size = sizeof (struct v6_pair);
124        break;        break;
125  #endif  #endif
126    
127  #if HAVE_IPV4  #if HAVE_IPV4
128      case PF_INET:      case PF_INET:
129        sinlen = sizeof (struct sockaddr_in);        size = sizeof (struct v4_pair);
130        break;        break;
131  #endif  #endif
132    
# Line 117  getaddrinfo (const char *restrict nodena Line 134  getaddrinfo (const char *restrict nodena
134        return EAI_NODATA;        return EAI_NODATA;
135      }      }
136    
137    tmp = calloc (1, sizeof (*tmp) + sinlen);    storage = calloc (1, size);
138    if (!tmp)    if (!storage)
139      return EAI_MEMORY;      return EAI_MEMORY;
140    
141    switch (he->h_addrtype)    switch (he->h_addrtype)
# Line 126  getaddrinfo (const char *restrict nodena Line 143  getaddrinfo (const char *restrict nodena
143  #if HAVE_IPV6  #if HAVE_IPV6
144      case PF_INET6:      case PF_INET6:
145        {        {
146          struct sockaddr_in6 *sinp = (char *) tmp + sizeof (*tmp);          struct v6_pair *p = storage;
147            struct sockaddr_in6 *sinp = &p->sockaddr_in6;
148            tmp = &p->addrinfo;
149    
150          if (se)          if (se)
151            sinp->sin6_port = se->s_port;            sinp->sin6_port = se->s_port;
152    
153          if (he->h_length != sizeof (sinp->sin6_addr))          if (he->h_length != sizeof (sinp->sin6_addr))
154            return EAI_SYSTEM; /* FIXME: Better return code?  Set errno? */            {
155                free (storage);
156                return EAI_SYSTEM; /* FIXME: Better return code?  Set errno? */
157              }
158    
159          memcpy (&sinp->sin6_addr, he->h_addr_list[0], he->h_length);          memcpy (&sinp->sin6_addr, he->h_addr_list[0], sizeof sinp->sin6_addr);
160    
161          tmp->ai_addr = (struct sockaddr *) sinp;          tmp->ai_addr = (struct sockaddr *) sinp;
162          tmp->ai_addrlen = sinlen;          tmp->ai_addrlen = sizeof *sinp;
163        }        }
164        break;        break;
165  #endif  #endif
# Line 145  getaddrinfo (const char *restrict nodena Line 167  getaddrinfo (const char *restrict nodena
167  #if HAVE_IPV4  #if HAVE_IPV4
168      case PF_INET:      case PF_INET:
169        {        {
170          struct sockaddr_in *sinp = (char *) tmp + sizeof (*tmp);          struct v4_pair *p = storage;
171            struct sockaddr_in *sinp = &p->sockaddr_in;
172            tmp = &p->addrinfo;
173    
174          if (se)          if (se)
175            sinp->sin_port = se->s_port;            sinp->sin_port = se->s_port;
176    
177          if (he->h_length != sizeof (sinp->sin_addr))          if (he->h_length != sizeof (sinp->sin_addr))
178            return EAI_SYSTEM; /* FIXME: Better return code?  Set errno? */            {
179                free (storage);
180                return EAI_SYSTEM; /* FIXME: Better return code?  Set errno? */
181              }
182    
183          memcpy (&sinp->sin_addr, he->h_addr_list[0], he->h_length);          memcpy (&sinp->sin_addr, he->h_addr_list[0], sizeof sinp->sin_addr);
184    
185          tmp->ai_addr = (struct sockaddr *) sinp;          tmp->ai_addr = (struct sockaddr *) sinp;
186          tmp->ai_addrlen = sinlen;          tmp->ai_addrlen = sizeof *sinp;
187        }        }
188        break;        break;
189  #endif  #endif
190    
191      default:      default:
192        free (tmp);        free (storage);
193        return EAI_NODATA;        return EAI_NODATA;
194      }      }
195    
# Line 177  getaddrinfo (const char *restrict nodena Line 204  getaddrinfo (const char *restrict nodena
204        tmp->ai_canonname = strdup (cn);        tmp->ai_canonname = strdup (cn);
205        if (!tmp->ai_canonname)        if (!tmp->ai_canonname)
206          {          {
207            free (tmp);            free (storage);
208            return EAI_MEMORY;            return EAI_MEMORY;
209          }          }
210      }      }

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.5

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26