maint: update copyright
[gnulib.git] / tests / test-getaddrinfo.c
1 /* Test the getaddrinfo module.
2
3    Copyright (C) 2006-2014 Free Software Foundation, Inc.
4
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18 /* Written by Simon Josefsson.  */
19
20 #include <config.h>
21
22 #include <netdb.h>
23
24 #include "signature.h"
25 SIGNATURE_CHECK (freeaddrinfo, void, (struct addrinfo *));
26 SIGNATURE_CHECK (gai_strerror, char const *, (int));
27 SIGNATURE_CHECK (getaddrinfo, int, (char const *, char const *,
28                                     struct addrinfo const *,
29                                     struct addrinfo **));
30
31 #include <arpa/inet.h>
32 #include <errno.h>
33 #include <netinet/in.h>
34 #include <stdio.h>
35 #include <string.h>
36
37 /* Whether to print debugging messages.  */
38 #define ENABLE_DEBUGGING 0
39
40 #if ENABLE_DEBUGGING
41 # define dbgprintf printf
42 #else
43 # define dbgprintf if (0) printf
44 #endif
45
46 /* BeOS does not have AF_UNSPEC.  */
47 #ifndef AF_UNSPEC
48 # define AF_UNSPEC 0
49 #endif
50
51 #ifndef EAI_SERVICE
52 # define EAI_SERVICE 0
53 #endif
54
55 static int
56 simple (char const *host, char const *service)
57 {
58   char buf[BUFSIZ];
59   static int skip = 0;
60   struct addrinfo hints;
61   struct addrinfo *ai0, *ai;
62   int res;
63   int err;
64
65   /* Once we skipped the test, do not try anything else */
66   if (skip)
67     return 0;
68
69   dbgprintf ("Finding %s service %s...\n", host, service);
70
71   /* This initializes "hints" but does not use it.  Is there a reason
72      for this?  If so, please fix this comment.  */
73   memset (&hints, 0, sizeof (hints));
74   hints.ai_flags = AI_CANONNAME;
75   hints.ai_family = AF_UNSPEC;
76   hints.ai_socktype = SOCK_STREAM;
77
78   res = getaddrinfo (host, service, 0, &ai0);
79   err = errno;
80
81   dbgprintf ("res %d: %s\n", res, gai_strerror (res));
82
83   if (res != 0)
84     {
85       /* EAI_AGAIN is returned if no network is available. Don't fail
86          the test merely because someone is down the country on their
87          in-law's farm. */
88       if (res == EAI_AGAIN)
89         {
90           skip++;
91           fprintf (stderr, "skipping getaddrinfo test: no network?\n");
92           return 77;
93         }
94       /* IRIX reports EAI_NONAME for "https".  Don't fail the test
95          merely because of this.  */
96       if (res == EAI_NONAME)
97         return 0;
98       /* Solaris reports EAI_SERVICE for "http" and "https".  Don't
99          fail the test merely because of this.  */
100       if (res == EAI_SERVICE)
101         return 0;
102 #ifdef EAI_NODATA
103       /* AIX reports EAI_NODATA for "https".  Don't fail the test
104          merely because of this.  */
105       if (res == EAI_NODATA)
106         return 0;
107 #endif
108       /* Provide details if errno was set.  */
109       if (res == EAI_SYSTEM)
110         fprintf (stderr, "system error: %s\n", strerror (err));
111
112       return 1;
113     }
114
115   for (ai = ai0; ai; ai = ai->ai_next)
116     {
117       void *ai_addr = ai->ai_addr;
118       struct sockaddr_in *sock_addr = ai_addr;
119       dbgprintf ("\tflags %x\n", ai->ai_flags);
120       dbgprintf ("\tfamily %x\n", ai->ai_family);
121       dbgprintf ("\tsocktype %x\n", ai->ai_socktype);
122       dbgprintf ("\tprotocol %x\n", ai->ai_protocol);
123       dbgprintf ("\taddrlen %ld: ", (unsigned long) ai->ai_addrlen);
124       dbgprintf ("\tFound %s\n",
125                  inet_ntop (ai->ai_family,
126                             &sock_addr->sin_addr,
127                             buf, sizeof (buf) - 1));
128       if (ai->ai_canonname)
129         dbgprintf ("\tFound %s...\n", ai->ai_canonname);
130
131       {
132         char ipbuf[BUFSIZ];
133         char portbuf[BUFSIZ];
134
135         res = getnameinfo (ai->ai_addr, ai->ai_addrlen,
136                            ipbuf, sizeof (ipbuf) - 1,
137                            portbuf, sizeof (portbuf) - 1,
138                            NI_NUMERICHOST|NI_NUMERICSERV);
139         dbgprintf ("\t\tgetnameinfo %d: %s\n", res, gai_strerror (res));
140         if (res == 0)
141           {
142             dbgprintf ("\t\tip %s\n", ipbuf);
143             dbgprintf ("\t\tport %s\n", portbuf);
144           }
145       }
146
147     }
148
149   freeaddrinfo (ai0);
150
151   return 0;
152 }
153
154 #define HOST1 "www.gnu.org"
155 #define SERV1 "http"
156 #define HOST2 "www.ibm.com"
157 #define SERV2 "https"
158 #define HOST3 "microsoft.com"
159 #define SERV3 "http"
160 #define HOST4 "google.org"
161 #define SERV4 "ldap"
162
163 int main (void)
164 {
165   return simple (HOST1, SERV1)
166     + simple (HOST2, SERV2)
167     + simple (HOST3, SERV3)
168     + simple (HOST4, SERV4);
169 }