xref: /aosp_15_r20/external/libcups/cups/http-addrlist.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker  * HTTP address list routines for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker  *
4*5e7646d2SAndroid Build Coastguard Worker  * Copyright 2007-2018 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker  * Copyright 1997-2007 by Easy Software Products, all rights reserved.
6*5e7646d2SAndroid Build Coastguard Worker  *
7*5e7646d2SAndroid Build Coastguard Worker  * Licensed under Apache License v2.0.  See the file "LICENSE" for more
8*5e7646d2SAndroid Build Coastguard Worker  * information.
9*5e7646d2SAndroid Build Coastguard Worker  */
10*5e7646d2SAndroid Build Coastguard Worker 
11*5e7646d2SAndroid Build Coastguard Worker /*
12*5e7646d2SAndroid Build Coastguard Worker  * Include necessary headers...
13*5e7646d2SAndroid Build Coastguard Worker  */
14*5e7646d2SAndroid Build Coastguard Worker 
15*5e7646d2SAndroid Build Coastguard Worker #include "cups-private.h"
16*5e7646d2SAndroid Build Coastguard Worker #include "debug-internal.h"
17*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_RESOLV_H
18*5e7646d2SAndroid Build Coastguard Worker #  include <resolv.h>
19*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_RESOLV_H */
20*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_POLL
21*5e7646d2SAndroid Build Coastguard Worker #  include <poll.h>
22*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_POLL */
23*5e7646d2SAndroid Build Coastguard Worker #ifndef _WIN32
24*5e7646d2SAndroid Build Coastguard Worker #  include <fcntl.h>
25*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
26*5e7646d2SAndroid Build Coastguard Worker 
27*5e7646d2SAndroid Build Coastguard Worker 
28*5e7646d2SAndroid Build Coastguard Worker /*
29*5e7646d2SAndroid Build Coastguard Worker  * 'httpAddrConnect()' - Connect to any of the addresses in the list.
30*5e7646d2SAndroid Build Coastguard Worker  *
31*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 1.2/macOS 10.5@ @exclude all@
32*5e7646d2SAndroid Build Coastguard Worker  */
33*5e7646d2SAndroid Build Coastguard Worker 
34*5e7646d2SAndroid Build Coastguard Worker http_addrlist_t *			/* O - Connected address or NULL on failure */
httpAddrConnect(http_addrlist_t * addrlist,int * sock)35*5e7646d2SAndroid Build Coastguard Worker httpAddrConnect(
36*5e7646d2SAndroid Build Coastguard Worker     http_addrlist_t *addrlist,		/* I - List of potential addresses */
37*5e7646d2SAndroid Build Coastguard Worker     int             *sock)		/* O - Socket */
38*5e7646d2SAndroid Build Coastguard Worker {
39*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("httpAddrConnect(addrlist=%p, sock=%p)", (void *)addrlist, (void *)sock));
40*5e7646d2SAndroid Build Coastguard Worker 
41*5e7646d2SAndroid Build Coastguard Worker   return (httpAddrConnect2(addrlist, sock, 30000, NULL));
42*5e7646d2SAndroid Build Coastguard Worker }
43*5e7646d2SAndroid Build Coastguard Worker 
44*5e7646d2SAndroid Build Coastguard Worker 
45*5e7646d2SAndroid Build Coastguard Worker /*
46*5e7646d2SAndroid Build Coastguard Worker  * 'httpAddrConnect2()' - Connect to any of the addresses in the list with a
47*5e7646d2SAndroid Build Coastguard Worker  *                        timeout and optional cancel.
48*5e7646d2SAndroid Build Coastguard Worker  *
49*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 1.7/macOS 10.9@
50*5e7646d2SAndroid Build Coastguard Worker  */
51*5e7646d2SAndroid Build Coastguard Worker 
52*5e7646d2SAndroid Build Coastguard Worker http_addrlist_t *			/* O - Connected address or NULL on failure */
httpAddrConnect2(http_addrlist_t * addrlist,int * sock,int msec,int * cancel)53*5e7646d2SAndroid Build Coastguard Worker httpAddrConnect2(
54*5e7646d2SAndroid Build Coastguard Worker     http_addrlist_t *addrlist,		/* I - List of potential addresses */
55*5e7646d2SAndroid Build Coastguard Worker     int             *sock,		/* O - Socket */
56*5e7646d2SAndroid Build Coastguard Worker     int             msec,		/* I - Timeout in milliseconds */
57*5e7646d2SAndroid Build Coastguard Worker     int             *cancel)		/* I - Pointer to "cancel" variable */
58*5e7646d2SAndroid Build Coastguard Worker {
59*5e7646d2SAndroid Build Coastguard Worker   int			val;		/* Socket option value */
60*5e7646d2SAndroid Build Coastguard Worker #ifndef _WIN32
61*5e7646d2SAndroid Build Coastguard Worker   int			i, j,		/* Looping vars */
62*5e7646d2SAndroid Build Coastguard Worker 			flags,		/* Socket flags */
63*5e7646d2SAndroid Build Coastguard Worker 			result;		/* Result from select() or poll() */
64*5e7646d2SAndroid Build Coastguard Worker #endif /* !_WIN32 */
65*5e7646d2SAndroid Build Coastguard Worker   int			remaining;	/* Remaining timeout */
66*5e7646d2SAndroid Build Coastguard Worker   int			nfds,		/* Number of file descriptors */
67*5e7646d2SAndroid Build Coastguard Worker 			fds[100];	/* Socket file descriptors */
68*5e7646d2SAndroid Build Coastguard Worker   http_addrlist_t	*addrs[100];	/* Addresses */
69*5e7646d2SAndroid Build Coastguard Worker #ifndef HAVE_POLL
70*5e7646d2SAndroid Build Coastguard Worker   int			max_fd = -1;	/* Highest file descriptor */
71*5e7646d2SAndroid Build Coastguard Worker #endif /* !HAVE_POLL */
72*5e7646d2SAndroid Build Coastguard Worker #ifdef O_NONBLOCK
73*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_POLL
74*5e7646d2SAndroid Build Coastguard Worker   struct pollfd		pfds[100];	/* Polled file descriptors */
75*5e7646d2SAndroid Build Coastguard Worker #  else
76*5e7646d2SAndroid Build Coastguard Worker   fd_set		input_set,	/* select() input set */
77*5e7646d2SAndroid Build Coastguard Worker 			output_set,	/* select() output set */
78*5e7646d2SAndroid Build Coastguard Worker 			error_set;	/* select() error set */
79*5e7646d2SAndroid Build Coastguard Worker   struct timeval	timeout;	/* Timeout */
80*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_POLL */
81*5e7646d2SAndroid Build Coastguard Worker #endif /* O_NONBLOCK */
82*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
83*5e7646d2SAndroid Build Coastguard Worker #  ifndef _WIN32
84*5e7646d2SAndroid Build Coastguard Worker   socklen_t		len;		/* Length of value */
85*5e7646d2SAndroid Build Coastguard Worker   http_addr_t		peer;		/* Peer address */
86*5e7646d2SAndroid Build Coastguard Worker #  endif /* !_WIN32 */
87*5e7646d2SAndroid Build Coastguard Worker   char			temp[256];	/* Temporary address string */
88*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
89*5e7646d2SAndroid Build Coastguard Worker 
90*5e7646d2SAndroid Build Coastguard Worker 
91*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("httpAddrConnect2(addrlist=%p, sock=%p, msec=%d, cancel=%p)", (void *)addrlist, (void *)sock, msec, (void *)cancel));
92*5e7646d2SAndroid Build Coastguard Worker 
93*5e7646d2SAndroid Build Coastguard Worker   if (!sock)
94*5e7646d2SAndroid Build Coastguard Worker   {
95*5e7646d2SAndroid Build Coastguard Worker     errno = EINVAL;
96*5e7646d2SAndroid Build Coastguard Worker     _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
97*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
98*5e7646d2SAndroid Build Coastguard Worker   }
99*5e7646d2SAndroid Build Coastguard Worker 
100*5e7646d2SAndroid Build Coastguard Worker   if (cancel && *cancel)
101*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
102*5e7646d2SAndroid Build Coastguard Worker 
103*5e7646d2SAndroid Build Coastguard Worker   if (msec <= 0)
104*5e7646d2SAndroid Build Coastguard Worker     msec = INT_MAX;
105*5e7646d2SAndroid Build Coastguard Worker 
106*5e7646d2SAndroid Build Coastguard Worker  /*
107*5e7646d2SAndroid Build Coastguard Worker   * Loop through each address until we connect or run out of addresses...
108*5e7646d2SAndroid Build Coastguard Worker   */
109*5e7646d2SAndroid Build Coastguard Worker 
110*5e7646d2SAndroid Build Coastguard Worker   nfds      = 0;
111*5e7646d2SAndroid Build Coastguard Worker   remaining = msec;
112*5e7646d2SAndroid Build Coastguard Worker 
113*5e7646d2SAndroid Build Coastguard Worker   while (remaining > 0)
114*5e7646d2SAndroid Build Coastguard Worker   {
115*5e7646d2SAndroid Build Coastguard Worker     if (cancel && *cancel)
116*5e7646d2SAndroid Build Coastguard Worker     {
117*5e7646d2SAndroid Build Coastguard Worker       while (nfds > 0)
118*5e7646d2SAndroid Build Coastguard Worker       {
119*5e7646d2SAndroid Build Coastguard Worker         nfds --;
120*5e7646d2SAndroid Build Coastguard Worker 	httpAddrClose(NULL, fds[nfds]);
121*5e7646d2SAndroid Build Coastguard Worker       }
122*5e7646d2SAndroid Build Coastguard Worker 
123*5e7646d2SAndroid Build Coastguard Worker       return (NULL);
124*5e7646d2SAndroid Build Coastguard Worker     }
125*5e7646d2SAndroid Build Coastguard Worker 
126*5e7646d2SAndroid Build Coastguard Worker     if (addrlist && nfds < (int)(sizeof(fds) / sizeof(fds[0])))
127*5e7646d2SAndroid Build Coastguard Worker     {
128*5e7646d2SAndroid Build Coastguard Worker      /*
129*5e7646d2SAndroid Build Coastguard Worker       * Create the socket...
130*5e7646d2SAndroid Build Coastguard Worker       */
131*5e7646d2SAndroid Build Coastguard Worker 
132*5e7646d2SAndroid Build Coastguard Worker       DEBUG_printf(("2httpAddrConnect2: Trying %s:%d...", httpAddrString(&(addrlist->addr), temp, sizeof(temp)), httpAddrPort(&(addrlist->addr))));
133*5e7646d2SAndroid Build Coastguard Worker 
134*5e7646d2SAndroid Build Coastguard Worker       if ((fds[nfds] = (int)socket(httpAddrFamily(&(addrlist->addr)), SOCK_STREAM, 0)) < 0)
135*5e7646d2SAndroid Build Coastguard Worker       {
136*5e7646d2SAndroid Build Coastguard Worker        /*
137*5e7646d2SAndroid Build Coastguard Worker 	* Don't abort yet, as this could just be an issue with the local
138*5e7646d2SAndroid Build Coastguard Worker 	* system not being configured with IPv4/IPv6/domain socket enabled.
139*5e7646d2SAndroid Build Coastguard Worker 	*
140*5e7646d2SAndroid Build Coastguard Worker 	* Just skip this address...
141*5e7646d2SAndroid Build Coastguard Worker 	*/
142*5e7646d2SAndroid Build Coastguard Worker 
143*5e7646d2SAndroid Build Coastguard Worker         addrlist = addrlist->next;
144*5e7646d2SAndroid Build Coastguard Worker 	continue;
145*5e7646d2SAndroid Build Coastguard Worker       }
146*5e7646d2SAndroid Build Coastguard Worker 
147*5e7646d2SAndroid Build Coastguard Worker      /*
148*5e7646d2SAndroid Build Coastguard Worker       * Set options...
149*5e7646d2SAndroid Build Coastguard Worker       */
150*5e7646d2SAndroid Build Coastguard Worker 
151*5e7646d2SAndroid Build Coastguard Worker       val = 1;
152*5e7646d2SAndroid Build Coastguard Worker       setsockopt(fds[nfds], SOL_SOCKET, SO_REUSEADDR, CUPS_SOCAST &val, sizeof(val));
153*5e7646d2SAndroid Build Coastguard Worker 
154*5e7646d2SAndroid Build Coastguard Worker #ifdef SO_REUSEPORT
155*5e7646d2SAndroid Build Coastguard Worker       val = 1;
156*5e7646d2SAndroid Build Coastguard Worker       setsockopt(fds[nfds], SOL_SOCKET, SO_REUSEPORT, CUPS_SOCAST &val, sizeof(val));
157*5e7646d2SAndroid Build Coastguard Worker #endif /* SO_REUSEPORT */
158*5e7646d2SAndroid Build Coastguard Worker 
159*5e7646d2SAndroid Build Coastguard Worker #ifdef SO_NOSIGPIPE
160*5e7646d2SAndroid Build Coastguard Worker       val = 1;
161*5e7646d2SAndroid Build Coastguard Worker       setsockopt(fds[nfds], SOL_SOCKET, SO_NOSIGPIPE, CUPS_SOCAST &val, sizeof(val));
162*5e7646d2SAndroid Build Coastguard Worker #endif /* SO_NOSIGPIPE */
163*5e7646d2SAndroid Build Coastguard Worker 
164*5e7646d2SAndroid Build Coastguard Worker      /*
165*5e7646d2SAndroid Build Coastguard Worker       * Using TCP_NODELAY improves responsiveness, especially on systems
166*5e7646d2SAndroid Build Coastguard Worker       * with a slow loopback interface...
167*5e7646d2SAndroid Build Coastguard Worker       */
168*5e7646d2SAndroid Build Coastguard Worker 
169*5e7646d2SAndroid Build Coastguard Worker       val = 1;
170*5e7646d2SAndroid Build Coastguard Worker       setsockopt(fds[nfds], IPPROTO_TCP, TCP_NODELAY, CUPS_SOCAST &val, sizeof(val));
171*5e7646d2SAndroid Build Coastguard Worker 
172*5e7646d2SAndroid Build Coastguard Worker #ifdef FD_CLOEXEC
173*5e7646d2SAndroid Build Coastguard Worker      /*
174*5e7646d2SAndroid Build Coastguard Worker       * Close this socket when starting another process...
175*5e7646d2SAndroid Build Coastguard Worker       */
176*5e7646d2SAndroid Build Coastguard Worker 
177*5e7646d2SAndroid Build Coastguard Worker       fcntl(fds[nfds], F_SETFD, FD_CLOEXEC);
178*5e7646d2SAndroid Build Coastguard Worker #endif /* FD_CLOEXEC */
179*5e7646d2SAndroid Build Coastguard Worker 
180*5e7646d2SAndroid Build Coastguard Worker #ifdef O_NONBLOCK
181*5e7646d2SAndroid Build Coastguard Worker      /*
182*5e7646d2SAndroid Build Coastguard Worker       * Do an asynchronous connect by setting the socket non-blocking...
183*5e7646d2SAndroid Build Coastguard Worker       */
184*5e7646d2SAndroid Build Coastguard Worker 
185*5e7646d2SAndroid Build Coastguard Worker       DEBUG_printf(("httpAddrConnect2: Setting non-blocking connect()"));
186*5e7646d2SAndroid Build Coastguard Worker 
187*5e7646d2SAndroid Build Coastguard Worker       flags = fcntl(fds[nfds], F_GETFL, 0);
188*5e7646d2SAndroid Build Coastguard Worker       fcntl(fds[nfds], F_SETFL, flags | O_NONBLOCK);
189*5e7646d2SAndroid Build Coastguard Worker #endif /* O_NONBLOCK */
190*5e7646d2SAndroid Build Coastguard Worker 
191*5e7646d2SAndroid Build Coastguard Worker      /*
192*5e7646d2SAndroid Build Coastguard Worker       * Then connect...
193*5e7646d2SAndroid Build Coastguard Worker       */
194*5e7646d2SAndroid Build Coastguard Worker 
195*5e7646d2SAndroid Build Coastguard Worker       if (!connect(fds[nfds], &(addrlist->addr.addr), (socklen_t)httpAddrLength(&(addrlist->addr))))
196*5e7646d2SAndroid Build Coastguard Worker       {
197*5e7646d2SAndroid Build Coastguard Worker 	DEBUG_printf(("1httpAddrConnect2: Connected to %s:%d...", httpAddrString(&(addrlist->addr), temp, sizeof(temp)), httpAddrPort(&(addrlist->addr))));
198*5e7646d2SAndroid Build Coastguard Worker 
199*5e7646d2SAndroid Build Coastguard Worker #ifdef O_NONBLOCK
200*5e7646d2SAndroid Build Coastguard Worker 	fcntl(fds[nfds], F_SETFL, flags);
201*5e7646d2SAndroid Build Coastguard Worker #endif /* O_NONBLOCK */
202*5e7646d2SAndroid Build Coastguard Worker 
203*5e7646d2SAndroid Build Coastguard Worker 	*sock = fds[nfds];
204*5e7646d2SAndroid Build Coastguard Worker 
205*5e7646d2SAndroid Build Coastguard Worker 	while (nfds > 0)
206*5e7646d2SAndroid Build Coastguard Worker 	{
207*5e7646d2SAndroid Build Coastguard Worker 	  nfds --;
208*5e7646d2SAndroid Build Coastguard Worker 	  httpAddrClose(NULL, fds[nfds]);
209*5e7646d2SAndroid Build Coastguard Worker 	}
210*5e7646d2SAndroid Build Coastguard Worker 
211*5e7646d2SAndroid Build Coastguard Worker 	return (addrlist);
212*5e7646d2SAndroid Build Coastguard Worker       }
213*5e7646d2SAndroid Build Coastguard Worker 
214*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
215*5e7646d2SAndroid Build Coastguard Worker       if (WSAGetLastError() != WSAEINPROGRESS && WSAGetLastError() != WSAEWOULDBLOCK)
216*5e7646d2SAndroid Build Coastguard Worker #else
217*5e7646d2SAndroid Build Coastguard Worker       if (errno != EINPROGRESS && errno != EWOULDBLOCK)
218*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
219*5e7646d2SAndroid Build Coastguard Worker       {
220*5e7646d2SAndroid Build Coastguard Worker 	DEBUG_printf(("1httpAddrConnect2: Unable to connect to %s:%d: %s", httpAddrString(&(addrlist->addr), temp, sizeof(temp)), httpAddrPort(&(addrlist->addr)), strerror(errno)));
221*5e7646d2SAndroid Build Coastguard Worker 	httpAddrClose(NULL, fds[nfds]);
222*5e7646d2SAndroid Build Coastguard Worker 	addrlist = addrlist->next;
223*5e7646d2SAndroid Build Coastguard Worker 	continue;
224*5e7646d2SAndroid Build Coastguard Worker       }
225*5e7646d2SAndroid Build Coastguard Worker 
226*5e7646d2SAndroid Build Coastguard Worker #ifndef _WIN32
227*5e7646d2SAndroid Build Coastguard Worker       fcntl(fds[nfds], F_SETFL, flags);
228*5e7646d2SAndroid Build Coastguard Worker #endif /* !_WIN32 */
229*5e7646d2SAndroid Build Coastguard Worker 
230*5e7646d2SAndroid Build Coastguard Worker #ifndef HAVE_POLL
231*5e7646d2SAndroid Build Coastguard Worker       if (fds[nfds] > max_fd)
232*5e7646d2SAndroid Build Coastguard Worker 	max_fd = fds[nfds];
233*5e7646d2SAndroid Build Coastguard Worker #endif /* !HAVE_POLL */
234*5e7646d2SAndroid Build Coastguard Worker 
235*5e7646d2SAndroid Build Coastguard Worker       addrs[nfds] = addrlist;
236*5e7646d2SAndroid Build Coastguard Worker       nfds ++;
237*5e7646d2SAndroid Build Coastguard Worker       addrlist = addrlist->next;
238*5e7646d2SAndroid Build Coastguard Worker     }
239*5e7646d2SAndroid Build Coastguard Worker 
240*5e7646d2SAndroid Build Coastguard Worker     if (!addrlist && nfds == 0)
241*5e7646d2SAndroid Build Coastguard Worker     {
242*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
243*5e7646d2SAndroid Build Coastguard Worker       errno = WSAEHOSTDOWN;
244*5e7646d2SAndroid Build Coastguard Worker #else
245*5e7646d2SAndroid Build Coastguard Worker       errno = EHOSTDOWN;
246*5e7646d2SAndroid Build Coastguard Worker #endif // _WIN32
247*5e7646d2SAndroid Build Coastguard Worker       break;
248*5e7646d2SAndroid Build Coastguard Worker     }
249*5e7646d2SAndroid Build Coastguard Worker 
250*5e7646d2SAndroid Build Coastguard Worker    /*
251*5e7646d2SAndroid Build Coastguard Worker     * See if we can connect to any of the addresses so far...
252*5e7646d2SAndroid Build Coastguard Worker     */
253*5e7646d2SAndroid Build Coastguard Worker 
254*5e7646d2SAndroid Build Coastguard Worker #ifdef O_NONBLOCK
255*5e7646d2SAndroid Build Coastguard Worker     DEBUG_puts("1httpAddrConnect2: Finishing async connect()");
256*5e7646d2SAndroid Build Coastguard Worker 
257*5e7646d2SAndroid Build Coastguard Worker     do
258*5e7646d2SAndroid Build Coastguard Worker     {
259*5e7646d2SAndroid Build Coastguard Worker       if (cancel && *cancel)
260*5e7646d2SAndroid Build Coastguard Worker       {
261*5e7646d2SAndroid Build Coastguard Worker        /*
262*5e7646d2SAndroid Build Coastguard Worker 	* Close this socket and return...
263*5e7646d2SAndroid Build Coastguard Worker 	*/
264*5e7646d2SAndroid Build Coastguard Worker 
265*5e7646d2SAndroid Build Coastguard Worker 	DEBUG_puts("1httpAddrConnect2: Canceled connect()");
266*5e7646d2SAndroid Build Coastguard Worker 
267*5e7646d2SAndroid Build Coastguard Worker 	while (nfds > 0)
268*5e7646d2SAndroid Build Coastguard Worker 	{
269*5e7646d2SAndroid Build Coastguard Worker 	  nfds --;
270*5e7646d2SAndroid Build Coastguard Worker 	  httpAddrClose(NULL, fds[nfds]);
271*5e7646d2SAndroid Build Coastguard Worker 	}
272*5e7646d2SAndroid Build Coastguard Worker 
273*5e7646d2SAndroid Build Coastguard Worker 	*sock = -1;
274*5e7646d2SAndroid Build Coastguard Worker 
275*5e7646d2SAndroid Build Coastguard Worker 	return (NULL);
276*5e7646d2SAndroid Build Coastguard Worker       }
277*5e7646d2SAndroid Build Coastguard Worker 
278*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_POLL
279*5e7646d2SAndroid Build Coastguard Worker       for (i = 0; i < nfds; i ++)
280*5e7646d2SAndroid Build Coastguard Worker       {
281*5e7646d2SAndroid Build Coastguard Worker 	pfds[i].fd     = fds[i];
282*5e7646d2SAndroid Build Coastguard Worker 	pfds[i].events = POLLIN | POLLOUT;
283*5e7646d2SAndroid Build Coastguard Worker       }
284*5e7646d2SAndroid Build Coastguard Worker 
285*5e7646d2SAndroid Build Coastguard Worker       result = poll(pfds, (nfds_t)nfds, addrlist ? 100 : remaining > 250 ? 250 : remaining);
286*5e7646d2SAndroid Build Coastguard Worker 
287*5e7646d2SAndroid Build Coastguard Worker       DEBUG_printf(("1httpAddrConnect2: poll() returned %d (%d)", result, errno));
288*5e7646d2SAndroid Build Coastguard Worker 
289*5e7646d2SAndroid Build Coastguard Worker #  else
290*5e7646d2SAndroid Build Coastguard Worker       FD_ZERO(&input_set);
291*5e7646d2SAndroid Build Coastguard Worker       for (i = 0; i < nfds; i ++)
292*5e7646d2SAndroid Build Coastguard Worker 	FD_SET(fds[i], &input_set);
293*5e7646d2SAndroid Build Coastguard Worker       output_set = input_set;
294*5e7646d2SAndroid Build Coastguard Worker       error_set  = input_set;
295*5e7646d2SAndroid Build Coastguard Worker 
296*5e7646d2SAndroid Build Coastguard Worker       timeout.tv_sec  = 0;
297*5e7646d2SAndroid Build Coastguard Worker       timeout.tv_usec = (addrlist ? 100 : remaining > 250 ? 250 : remaining) * 1000;
298*5e7646d2SAndroid Build Coastguard Worker 
299*5e7646d2SAndroid Build Coastguard Worker       result = select(max_fd + 1, &input_set, &output_set, &error_set, &timeout);
300*5e7646d2SAndroid Build Coastguard Worker 
301*5e7646d2SAndroid Build Coastguard Worker       DEBUG_printf(("1httpAddrConnect2: select() returned %d (%d)", result, errno));
302*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_POLL */
303*5e7646d2SAndroid Build Coastguard Worker     }
304*5e7646d2SAndroid Build Coastguard Worker #  ifdef _WIN32
305*5e7646d2SAndroid Build Coastguard Worker     while (result < 0 && (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEWOULDBLOCK));
306*5e7646d2SAndroid Build Coastguard Worker #  else
307*5e7646d2SAndroid Build Coastguard Worker     while (result < 0 && (errno == EINTR || errno == EAGAIN));
308*5e7646d2SAndroid Build Coastguard Worker #  endif /* _WIN32 */
309*5e7646d2SAndroid Build Coastguard Worker 
310*5e7646d2SAndroid Build Coastguard Worker     if (result > 0)
311*5e7646d2SAndroid Build Coastguard Worker     {
312*5e7646d2SAndroid Build Coastguard Worker       http_addrlist_t *connaddr = NULL;	/* Connected address, if any */
313*5e7646d2SAndroid Build Coastguard Worker 
314*5e7646d2SAndroid Build Coastguard Worker       for (i = 0; i < nfds; i ++)
315*5e7646d2SAndroid Build Coastguard Worker       {
316*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_POLL
317*5e7646d2SAndroid Build Coastguard Worker 	DEBUG_printf(("pfds[%d].revents=%x\n", i, pfds[i].revents));
318*5e7646d2SAndroid Build Coastguard Worker 	if (pfds[i].revents && !(pfds[i].revents & (POLLERR | POLLHUP)))
319*5e7646d2SAndroid Build Coastguard Worker #  else
320*5e7646d2SAndroid Build Coastguard Worker 	if (FD_ISSET(fds[i], &input_set) && !FD_ISSET(fds[i], &error_set))
321*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_POLL */
322*5e7646d2SAndroid Build Coastguard Worker 	{
323*5e7646d2SAndroid Build Coastguard Worker 	  *sock    = fds[i];
324*5e7646d2SAndroid Build Coastguard Worker 	  connaddr = addrs[i];
325*5e7646d2SAndroid Build Coastguard Worker 
326*5e7646d2SAndroid Build Coastguard Worker #  ifdef DEBUG
327*5e7646d2SAndroid Build Coastguard Worker 	  len   = sizeof(peer);
328*5e7646d2SAndroid Build Coastguard Worker 	  if (!getpeername(fds[i], (struct sockaddr *)&peer, &len))
329*5e7646d2SAndroid Build Coastguard Worker 	    DEBUG_printf(("1httpAddrConnect2: Connected to %s:%d...", httpAddrString(&peer, temp, sizeof(temp)), httpAddrPort(&peer)));
330*5e7646d2SAndroid Build Coastguard Worker #  endif /* DEBUG */
331*5e7646d2SAndroid Build Coastguard Worker 
332*5e7646d2SAndroid Build Coastguard Worker           break;
333*5e7646d2SAndroid Build Coastguard Worker 	}
334*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_POLL
335*5e7646d2SAndroid Build Coastguard Worker 	else if (pfds[i].revents & (POLLERR | POLLHUP))
336*5e7646d2SAndroid Build Coastguard Worker #  else
337*5e7646d2SAndroid Build Coastguard Worker 	else if (FD_ISSET(fds[i], &error_set))
338*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_POLL */
339*5e7646d2SAndroid Build Coastguard Worker         {
340*5e7646d2SAndroid Build Coastguard Worker          /*
341*5e7646d2SAndroid Build Coastguard Worker           * Error on socket, remove from the "pool"...
342*5e7646d2SAndroid Build Coastguard Worker           */
343*5e7646d2SAndroid Build Coastguard Worker 
344*5e7646d2SAndroid Build Coastguard Worker 	  httpAddrClose(NULL, fds[i]);
345*5e7646d2SAndroid Build Coastguard Worker           nfds --;
346*5e7646d2SAndroid Build Coastguard Worker           if (i < nfds)
347*5e7646d2SAndroid Build Coastguard Worker           {
348*5e7646d2SAndroid Build Coastguard Worker             memmove(fds + i, fds + i + 1, (size_t)(nfds - i) * (sizeof(fds[0])));
349*5e7646d2SAndroid Build Coastguard Worker             memmove(addrs + i, addrs + i + 1, (size_t)(nfds - i) * (sizeof(addrs[0])));
350*5e7646d2SAndroid Build Coastguard Worker           }
351*5e7646d2SAndroid Build Coastguard Worker           i --;
352*5e7646d2SAndroid Build Coastguard Worker         }
353*5e7646d2SAndroid Build Coastguard Worker       }
354*5e7646d2SAndroid Build Coastguard Worker 
355*5e7646d2SAndroid Build Coastguard Worker       if (connaddr)
356*5e7646d2SAndroid Build Coastguard Worker       {
357*5e7646d2SAndroid Build Coastguard Worker        /*
358*5e7646d2SAndroid Build Coastguard Worker         * Connected on one address, close all of the other sockets we have so
359*5e7646d2SAndroid Build Coastguard Worker         * far and return...
360*5e7646d2SAndroid Build Coastguard Worker         */
361*5e7646d2SAndroid Build Coastguard Worker 
362*5e7646d2SAndroid Build Coastguard Worker         for (j = 0; j < i; j ++)
363*5e7646d2SAndroid Build Coastguard Worker           httpAddrClose(NULL, fds[j]);
364*5e7646d2SAndroid Build Coastguard Worker 
365*5e7646d2SAndroid Build Coastguard Worker         for (j ++; j < nfds; j ++)
366*5e7646d2SAndroid Build Coastguard Worker           httpAddrClose(NULL, fds[j]);
367*5e7646d2SAndroid Build Coastguard Worker 
368*5e7646d2SAndroid Build Coastguard Worker         return (connaddr);
369*5e7646d2SAndroid Build Coastguard Worker       }
370*5e7646d2SAndroid Build Coastguard Worker     }
371*5e7646d2SAndroid Build Coastguard Worker #endif /* O_NONBLOCK */
372*5e7646d2SAndroid Build Coastguard Worker 
373*5e7646d2SAndroid Build Coastguard Worker     if (addrlist)
374*5e7646d2SAndroid Build Coastguard Worker       remaining -= 100;
375*5e7646d2SAndroid Build Coastguard Worker     else
376*5e7646d2SAndroid Build Coastguard Worker       remaining -= 250;
377*5e7646d2SAndroid Build Coastguard Worker   }
378*5e7646d2SAndroid Build Coastguard Worker 
379*5e7646d2SAndroid Build Coastguard Worker   if (remaining <= 0)
380*5e7646d2SAndroid Build Coastguard Worker     errno = ETIMEDOUT;
381*5e7646d2SAndroid Build Coastguard Worker 
382*5e7646d2SAndroid Build Coastguard Worker   while (nfds > 0)
383*5e7646d2SAndroid Build Coastguard Worker   {
384*5e7646d2SAndroid Build Coastguard Worker     nfds --;
385*5e7646d2SAndroid Build Coastguard Worker     httpAddrClose(NULL, fds[nfds]);
386*5e7646d2SAndroid Build Coastguard Worker   }
387*5e7646d2SAndroid Build Coastguard Worker 
388*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
389*5e7646d2SAndroid Build Coastguard Worker   _cupsSetError(IPP_STATUS_ERROR_SERVICE_UNAVAILABLE, "Connection failed", 0);
390*5e7646d2SAndroid Build Coastguard Worker #else
391*5e7646d2SAndroid Build Coastguard Worker   _cupsSetError(IPP_STATUS_ERROR_SERVICE_UNAVAILABLE, strerror(errno), 0);
392*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
393*5e7646d2SAndroid Build Coastguard Worker 
394*5e7646d2SAndroid Build Coastguard Worker   return (NULL);
395*5e7646d2SAndroid Build Coastguard Worker }
396*5e7646d2SAndroid Build Coastguard Worker 
397*5e7646d2SAndroid Build Coastguard Worker 
398*5e7646d2SAndroid Build Coastguard Worker /*
399*5e7646d2SAndroid Build Coastguard Worker  * 'httpAddrCopyList()' - Copy an address list.
400*5e7646d2SAndroid Build Coastguard Worker  *
401*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 1.7/macOS 10.9@
402*5e7646d2SAndroid Build Coastguard Worker  */
403*5e7646d2SAndroid Build Coastguard Worker 
404*5e7646d2SAndroid Build Coastguard Worker http_addrlist_t	*			/* O - New address list or @code NULL@ on error */
httpAddrCopyList(http_addrlist_t * src)405*5e7646d2SAndroid Build Coastguard Worker httpAddrCopyList(
406*5e7646d2SAndroid Build Coastguard Worker     http_addrlist_t *src)		/* I - Source address list */
407*5e7646d2SAndroid Build Coastguard Worker {
408*5e7646d2SAndroid Build Coastguard Worker   http_addrlist_t	*dst = NULL,	/* First list entry */
409*5e7646d2SAndroid Build Coastguard Worker 			*prev = NULL,	/* Previous list entry */
410*5e7646d2SAndroid Build Coastguard Worker 			*current = NULL;/* Current list entry */
411*5e7646d2SAndroid Build Coastguard Worker 
412*5e7646d2SAndroid Build Coastguard Worker 
413*5e7646d2SAndroid Build Coastguard Worker   while (src)
414*5e7646d2SAndroid Build Coastguard Worker   {
415*5e7646d2SAndroid Build Coastguard Worker     if ((current = malloc(sizeof(http_addrlist_t))) == NULL)
416*5e7646d2SAndroid Build Coastguard Worker     {
417*5e7646d2SAndroid Build Coastguard Worker       current = dst;
418*5e7646d2SAndroid Build Coastguard Worker 
419*5e7646d2SAndroid Build Coastguard Worker       while (current)
420*5e7646d2SAndroid Build Coastguard Worker       {
421*5e7646d2SAndroid Build Coastguard Worker         prev    = current;
422*5e7646d2SAndroid Build Coastguard Worker         current = current->next;
423*5e7646d2SAndroid Build Coastguard Worker 
424*5e7646d2SAndroid Build Coastguard Worker         free(prev);
425*5e7646d2SAndroid Build Coastguard Worker       }
426*5e7646d2SAndroid Build Coastguard Worker 
427*5e7646d2SAndroid Build Coastguard Worker       return (NULL);
428*5e7646d2SAndroid Build Coastguard Worker     }
429*5e7646d2SAndroid Build Coastguard Worker 
430*5e7646d2SAndroid Build Coastguard Worker     memcpy(current, src, sizeof(http_addrlist_t));
431*5e7646d2SAndroid Build Coastguard Worker 
432*5e7646d2SAndroid Build Coastguard Worker     current->next = NULL;
433*5e7646d2SAndroid Build Coastguard Worker 
434*5e7646d2SAndroid Build Coastguard Worker     if (prev)
435*5e7646d2SAndroid Build Coastguard Worker       prev->next = current;
436*5e7646d2SAndroid Build Coastguard Worker     else
437*5e7646d2SAndroid Build Coastguard Worker       dst = current;
438*5e7646d2SAndroid Build Coastguard Worker 
439*5e7646d2SAndroid Build Coastguard Worker     prev = current;
440*5e7646d2SAndroid Build Coastguard Worker     src  = src->next;
441*5e7646d2SAndroid Build Coastguard Worker   }
442*5e7646d2SAndroid Build Coastguard Worker 
443*5e7646d2SAndroid Build Coastguard Worker   return (dst);
444*5e7646d2SAndroid Build Coastguard Worker }
445*5e7646d2SAndroid Build Coastguard Worker 
446*5e7646d2SAndroid Build Coastguard Worker 
447*5e7646d2SAndroid Build Coastguard Worker /*
448*5e7646d2SAndroid Build Coastguard Worker  * 'httpAddrFreeList()' - Free an address list.
449*5e7646d2SAndroid Build Coastguard Worker  *
450*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 1.2/macOS 10.5@
451*5e7646d2SAndroid Build Coastguard Worker  */
452*5e7646d2SAndroid Build Coastguard Worker 
453*5e7646d2SAndroid Build Coastguard Worker void
httpAddrFreeList(http_addrlist_t * addrlist)454*5e7646d2SAndroid Build Coastguard Worker httpAddrFreeList(
455*5e7646d2SAndroid Build Coastguard Worker     http_addrlist_t *addrlist)		/* I - Address list to free */
456*5e7646d2SAndroid Build Coastguard Worker {
457*5e7646d2SAndroid Build Coastguard Worker   http_addrlist_t	*next;		/* Next address in list */
458*5e7646d2SAndroid Build Coastguard Worker 
459*5e7646d2SAndroid Build Coastguard Worker 
460*5e7646d2SAndroid Build Coastguard Worker  /*
461*5e7646d2SAndroid Build Coastguard Worker   * Free each address in the list...
462*5e7646d2SAndroid Build Coastguard Worker   */
463*5e7646d2SAndroid Build Coastguard Worker 
464*5e7646d2SAndroid Build Coastguard Worker   while (addrlist)
465*5e7646d2SAndroid Build Coastguard Worker   {
466*5e7646d2SAndroid Build Coastguard Worker     next = addrlist->next;
467*5e7646d2SAndroid Build Coastguard Worker 
468*5e7646d2SAndroid Build Coastguard Worker     free(addrlist);
469*5e7646d2SAndroid Build Coastguard Worker 
470*5e7646d2SAndroid Build Coastguard Worker     addrlist = next;
471*5e7646d2SAndroid Build Coastguard Worker   }
472*5e7646d2SAndroid Build Coastguard Worker }
473*5e7646d2SAndroid Build Coastguard Worker 
474*5e7646d2SAndroid Build Coastguard Worker 
475*5e7646d2SAndroid Build Coastguard Worker /*
476*5e7646d2SAndroid Build Coastguard Worker  * 'httpAddrGetList()' - Get a list of addresses for a hostname.
477*5e7646d2SAndroid Build Coastguard Worker  *
478*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 1.2/macOS 10.5@
479*5e7646d2SAndroid Build Coastguard Worker  */
480*5e7646d2SAndroid Build Coastguard Worker 
481*5e7646d2SAndroid Build Coastguard Worker http_addrlist_t	*			/* O - List of addresses or NULL */
httpAddrGetList(const char * hostname,int family,const char * service)482*5e7646d2SAndroid Build Coastguard Worker httpAddrGetList(const char *hostname,	/* I - Hostname, IP address, or NULL for passive listen address */
483*5e7646d2SAndroid Build Coastguard Worker                 int        family,	/* I - Address family or AF_UNSPEC */
484*5e7646d2SAndroid Build Coastguard Worker 		const char *service)	/* I - Service name or port number */
485*5e7646d2SAndroid Build Coastguard Worker {
486*5e7646d2SAndroid Build Coastguard Worker   http_addrlist_t	*first,		/* First address in list */
487*5e7646d2SAndroid Build Coastguard Worker 			*addr,		/* Current address in list */
488*5e7646d2SAndroid Build Coastguard Worker 			*temp;		/* New address */
489*5e7646d2SAndroid Build Coastguard Worker   _cups_globals_t	*cg = _cupsGlobals();
490*5e7646d2SAndroid Build Coastguard Worker 					/* Global data */
491*5e7646d2SAndroid Build Coastguard Worker 
492*5e7646d2SAndroid Build Coastguard Worker 
493*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
494*5e7646d2SAndroid Build Coastguard Worker   _cups_debug_printf("httpAddrGetList(hostname=\"%s\", family=AF_%s, "
495*5e7646d2SAndroid Build Coastguard Worker                      "service=\"%s\")\n",
496*5e7646d2SAndroid Build Coastguard Worker 		     hostname ? hostname : "(nil)",
497*5e7646d2SAndroid Build Coastguard Worker 		     family == AF_UNSPEC ? "UNSPEC" :
498*5e7646d2SAndroid Build Coastguard Worker #  ifdef AF_LOCAL
499*5e7646d2SAndroid Build Coastguard Worker 	                 family == AF_LOCAL ? "LOCAL" :
500*5e7646d2SAndroid Build Coastguard Worker #  endif /* AF_LOCAL */
501*5e7646d2SAndroid Build Coastguard Worker #  ifdef AF_INET6
502*5e7646d2SAndroid Build Coastguard Worker 	                 family == AF_INET6 ? "INET6" :
503*5e7646d2SAndroid Build Coastguard Worker #  endif /* AF_INET6 */
504*5e7646d2SAndroid Build Coastguard Worker 	                 family == AF_INET ? "INET" : "???", service);
505*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
506*5e7646d2SAndroid Build Coastguard Worker 
507*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_RES_INIT
508*5e7646d2SAndroid Build Coastguard Worker  /*
509*5e7646d2SAndroid Build Coastguard Worker   * STR #2920: Initialize resolver after failure in cups-polld
510*5e7646d2SAndroid Build Coastguard Worker   *
511*5e7646d2SAndroid Build Coastguard Worker   * If the previous lookup failed, re-initialize the resolver to prevent
512*5e7646d2SAndroid Build Coastguard Worker   * temporary network errors from persisting.  This *should* be handled by
513*5e7646d2SAndroid Build Coastguard Worker   * the resolver libraries, but apparently the glibc folks do not agree.
514*5e7646d2SAndroid Build Coastguard Worker   *
515*5e7646d2SAndroid Build Coastguard Worker   * We set a flag at the end of this function if we encounter an error that
516*5e7646d2SAndroid Build Coastguard Worker   * requires reinitialization of the resolver functions.  We then call
517*5e7646d2SAndroid Build Coastguard Worker   * res_init() if the flag is set on the next call here or in httpAddrLookup().
518*5e7646d2SAndroid Build Coastguard Worker   */
519*5e7646d2SAndroid Build Coastguard Worker 
520*5e7646d2SAndroid Build Coastguard Worker   if (cg->need_res_init)
521*5e7646d2SAndroid Build Coastguard Worker   {
522*5e7646d2SAndroid Build Coastguard Worker     res_init();
523*5e7646d2SAndroid Build Coastguard Worker 
524*5e7646d2SAndroid Build Coastguard Worker     cg->need_res_init = 0;
525*5e7646d2SAndroid Build Coastguard Worker   }
526*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_RES_INIT */
527*5e7646d2SAndroid Build Coastguard Worker 
528*5e7646d2SAndroid Build Coastguard Worker  /*
529*5e7646d2SAndroid Build Coastguard Worker   * Lookup the address the best way we can...
530*5e7646d2SAndroid Build Coastguard Worker   */
531*5e7646d2SAndroid Build Coastguard Worker 
532*5e7646d2SAndroid Build Coastguard Worker   first = addr = NULL;
533*5e7646d2SAndroid Build Coastguard Worker 
534*5e7646d2SAndroid Build Coastguard Worker #ifdef AF_LOCAL
535*5e7646d2SAndroid Build Coastguard Worker   if (hostname && hostname[0] == '/')
536*5e7646d2SAndroid Build Coastguard Worker   {
537*5e7646d2SAndroid Build Coastguard Worker    /*
538*5e7646d2SAndroid Build Coastguard Worker     * Domain socket address...
539*5e7646d2SAndroid Build Coastguard Worker     */
540*5e7646d2SAndroid Build Coastguard Worker 
541*5e7646d2SAndroid Build Coastguard Worker     if ((first = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t))) != NULL)
542*5e7646d2SAndroid Build Coastguard Worker     {
543*5e7646d2SAndroid Build Coastguard Worker       addr = first;
544*5e7646d2SAndroid Build Coastguard Worker       first->addr.un.sun_family = AF_LOCAL;
545*5e7646d2SAndroid Build Coastguard Worker       strlcpy(first->addr.un.sun_path, hostname, sizeof(first->addr.un.sun_path));
546*5e7646d2SAndroid Build Coastguard Worker     }
547*5e7646d2SAndroid Build Coastguard Worker   }
548*5e7646d2SAndroid Build Coastguard Worker   else
549*5e7646d2SAndroid Build Coastguard Worker #endif /* AF_LOCAL */
550*5e7646d2SAndroid Build Coastguard Worker   if (!hostname || _cups_strcasecmp(hostname, "localhost"))
551*5e7646d2SAndroid Build Coastguard Worker   {
552*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_GETADDRINFO
553*5e7646d2SAndroid Build Coastguard Worker     struct addrinfo	hints,		/* Address lookup hints */
554*5e7646d2SAndroid Build Coastguard Worker 			*results,	/* Address lookup results */
555*5e7646d2SAndroid Build Coastguard Worker 			*current;	/* Current result */
556*5e7646d2SAndroid Build Coastguard Worker     char		ipv6[64],	/* IPv6 address */
557*5e7646d2SAndroid Build Coastguard Worker 			*ipv6zone;	/* Pointer to zone separator */
558*5e7646d2SAndroid Build Coastguard Worker     int			ipv6len;	/* Length of IPv6 address */
559*5e7646d2SAndroid Build Coastguard Worker     int			error;		/* getaddrinfo() error */
560*5e7646d2SAndroid Build Coastguard Worker 
561*5e7646d2SAndroid Build Coastguard Worker 
562*5e7646d2SAndroid Build Coastguard Worker    /*
563*5e7646d2SAndroid Build Coastguard Worker     * Lookup the address as needed...
564*5e7646d2SAndroid Build Coastguard Worker     */
565*5e7646d2SAndroid Build Coastguard Worker 
566*5e7646d2SAndroid Build Coastguard Worker     memset(&hints, 0, sizeof(hints));
567*5e7646d2SAndroid Build Coastguard Worker     hints.ai_family   = family;
568*5e7646d2SAndroid Build Coastguard Worker     hints.ai_flags    = hostname ? 0 : AI_PASSIVE;
569*5e7646d2SAndroid Build Coastguard Worker     hints.ai_socktype = SOCK_STREAM;
570*5e7646d2SAndroid Build Coastguard Worker 
571*5e7646d2SAndroid Build Coastguard Worker     if (hostname && *hostname == '[')
572*5e7646d2SAndroid Build Coastguard Worker     {
573*5e7646d2SAndroid Build Coastguard Worker      /*
574*5e7646d2SAndroid Build Coastguard Worker       * Remove brackets from numeric IPv6 address...
575*5e7646d2SAndroid Build Coastguard Worker       */
576*5e7646d2SAndroid Build Coastguard Worker 
577*5e7646d2SAndroid Build Coastguard Worker       if (!strncmp(hostname, "[v1.", 4))
578*5e7646d2SAndroid Build Coastguard Worker       {
579*5e7646d2SAndroid Build Coastguard Worker        /*
580*5e7646d2SAndroid Build Coastguard Worker         * Copy the newer address format which supports link-local addresses...
581*5e7646d2SAndroid Build Coastguard Worker 	*/
582*5e7646d2SAndroid Build Coastguard Worker 
583*5e7646d2SAndroid Build Coastguard Worker 	strlcpy(ipv6, hostname + 4, sizeof(ipv6));
584*5e7646d2SAndroid Build Coastguard Worker 	if ((ipv6len = (int)strlen(ipv6) - 1) >= 0 && ipv6[ipv6len] == ']')
585*5e7646d2SAndroid Build Coastguard Worker 	{
586*5e7646d2SAndroid Build Coastguard Worker           ipv6[ipv6len] = '\0';
587*5e7646d2SAndroid Build Coastguard Worker 	  hostname      = ipv6;
588*5e7646d2SAndroid Build Coastguard Worker 
589*5e7646d2SAndroid Build Coastguard Worker          /*
590*5e7646d2SAndroid Build Coastguard Worker 	  * Convert "+zone" in address to "%zone"...
591*5e7646d2SAndroid Build Coastguard Worker 	  */
592*5e7646d2SAndroid Build Coastguard Worker 
593*5e7646d2SAndroid Build Coastguard Worker           if ((ipv6zone = strrchr(ipv6, '+')) != NULL)
594*5e7646d2SAndroid Build Coastguard Worker 	    *ipv6zone = '%';
595*5e7646d2SAndroid Build Coastguard Worker 	}
596*5e7646d2SAndroid Build Coastguard Worker       }
597*5e7646d2SAndroid Build Coastguard Worker       else
598*5e7646d2SAndroid Build Coastguard Worker       {
599*5e7646d2SAndroid Build Coastguard Worker        /*
600*5e7646d2SAndroid Build Coastguard Worker         * Copy the regular non-link-local IPv6 address...
601*5e7646d2SAndroid Build Coastguard Worker 	*/
602*5e7646d2SAndroid Build Coastguard Worker 
603*5e7646d2SAndroid Build Coastguard Worker 	strlcpy(ipv6, hostname + 1, sizeof(ipv6));
604*5e7646d2SAndroid Build Coastguard Worker 	if ((ipv6len = (int)strlen(ipv6) - 1) >= 0 && ipv6[ipv6len] == ']')
605*5e7646d2SAndroid Build Coastguard Worker 	{
606*5e7646d2SAndroid Build Coastguard Worker           ipv6[ipv6len] = '\0';
607*5e7646d2SAndroid Build Coastguard Worker 	  hostname      = ipv6;
608*5e7646d2SAndroid Build Coastguard Worker 	}
609*5e7646d2SAndroid Build Coastguard Worker       }
610*5e7646d2SAndroid Build Coastguard Worker     }
611*5e7646d2SAndroid Build Coastguard Worker 
612*5e7646d2SAndroid Build Coastguard Worker     if ((error = getaddrinfo(hostname, service, &hints, &results)) == 0)
613*5e7646d2SAndroid Build Coastguard Worker     {
614*5e7646d2SAndroid Build Coastguard Worker      /*
615*5e7646d2SAndroid Build Coastguard Worker       * Copy the results to our own address list structure...
616*5e7646d2SAndroid Build Coastguard Worker       */
617*5e7646d2SAndroid Build Coastguard Worker 
618*5e7646d2SAndroid Build Coastguard Worker       for (current = results; current; current = current->ai_next)
619*5e7646d2SAndroid Build Coastguard Worker         if (current->ai_family == AF_INET || current->ai_family == AF_INET6)
620*5e7646d2SAndroid Build Coastguard Worker 	{
621*5e7646d2SAndroid Build Coastguard Worker 	 /*
622*5e7646d2SAndroid Build Coastguard Worker           * Copy the address over...
623*5e7646d2SAndroid Build Coastguard Worker 	  */
624*5e7646d2SAndroid Build Coastguard Worker 
625*5e7646d2SAndroid Build Coastguard Worker 	  temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t));
626*5e7646d2SAndroid Build Coastguard Worker 	  if (!temp)
627*5e7646d2SAndroid Build Coastguard Worker 	  {
628*5e7646d2SAndroid Build Coastguard Worker 	    httpAddrFreeList(first);
629*5e7646d2SAndroid Build Coastguard Worker 	    freeaddrinfo(results);
630*5e7646d2SAndroid Build Coastguard Worker 	    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
631*5e7646d2SAndroid Build Coastguard Worker 	    return (NULL);
632*5e7646d2SAndroid Build Coastguard Worker 	  }
633*5e7646d2SAndroid Build Coastguard Worker 
634*5e7646d2SAndroid Build Coastguard Worker           if (current->ai_family == AF_INET6)
635*5e7646d2SAndroid Build Coastguard Worker 	    memcpy(&(temp->addr.ipv6), current->ai_addr,
636*5e7646d2SAndroid Build Coastguard Worker 	           sizeof(temp->addr.ipv6));
637*5e7646d2SAndroid Build Coastguard Worker 	  else
638*5e7646d2SAndroid Build Coastguard Worker 	    memcpy(&(temp->addr.ipv4), current->ai_addr,
639*5e7646d2SAndroid Build Coastguard Worker 	           sizeof(temp->addr.ipv4));
640*5e7646d2SAndroid Build Coastguard Worker 
641*5e7646d2SAndroid Build Coastguard Worker          /*
642*5e7646d2SAndroid Build Coastguard Worker 	  * Append the address to the list...
643*5e7646d2SAndroid Build Coastguard Worker 	  */
644*5e7646d2SAndroid Build Coastguard Worker 
645*5e7646d2SAndroid Build Coastguard Worker 	  if (!first)
646*5e7646d2SAndroid Build Coastguard Worker 	    first = temp;
647*5e7646d2SAndroid Build Coastguard Worker 
648*5e7646d2SAndroid Build Coastguard Worker 	  if (addr)
649*5e7646d2SAndroid Build Coastguard Worker 	    addr->next = temp;
650*5e7646d2SAndroid Build Coastguard Worker 
651*5e7646d2SAndroid Build Coastguard Worker 	  addr = temp;
652*5e7646d2SAndroid Build Coastguard Worker 	}
653*5e7646d2SAndroid Build Coastguard Worker 
654*5e7646d2SAndroid Build Coastguard Worker      /*
655*5e7646d2SAndroid Build Coastguard Worker       * Free the results from getaddrinfo()...
656*5e7646d2SAndroid Build Coastguard Worker       */
657*5e7646d2SAndroid Build Coastguard Worker 
658*5e7646d2SAndroid Build Coastguard Worker       freeaddrinfo(results);
659*5e7646d2SAndroid Build Coastguard Worker     }
660*5e7646d2SAndroid Build Coastguard Worker     else
661*5e7646d2SAndroid Build Coastguard Worker     {
662*5e7646d2SAndroid Build Coastguard Worker       if (error == EAI_FAIL)
663*5e7646d2SAndroid Build Coastguard Worker         cg->need_res_init = 1;
664*5e7646d2SAndroid Build Coastguard Worker 
665*5e7646d2SAndroid Build Coastguard Worker #  ifdef _WIN32 /* Really, Microsoft?!? */
666*5e7646d2SAndroid Build Coastguard Worker       _cupsSetError(IPP_STATUS_ERROR_INTERNAL, gai_strerrorA(error), 0);
667*5e7646d2SAndroid Build Coastguard Worker #  else
668*5e7646d2SAndroid Build Coastguard Worker       _cupsSetError(IPP_STATUS_ERROR_INTERNAL, gai_strerror(error), 0);
669*5e7646d2SAndroid Build Coastguard Worker #  endif /* _WIN32 */
670*5e7646d2SAndroid Build Coastguard Worker     }
671*5e7646d2SAndroid Build Coastguard Worker 
672*5e7646d2SAndroid Build Coastguard Worker #else
673*5e7646d2SAndroid Build Coastguard Worker     if (hostname)
674*5e7646d2SAndroid Build Coastguard Worker     {
675*5e7646d2SAndroid Build Coastguard Worker       int		i;		/* Looping vars */
676*5e7646d2SAndroid Build Coastguard Worker       unsigned		ip[4];		/* IPv4 address components */
677*5e7646d2SAndroid Build Coastguard Worker       const char	*ptr;		/* Pointer into hostname */
678*5e7646d2SAndroid Build Coastguard Worker       struct hostent	*host;		/* Result of lookup */
679*5e7646d2SAndroid Build Coastguard Worker       struct servent	*port;		/* Port number for service */
680*5e7646d2SAndroid Build Coastguard Worker       int		portnum;	/* Port number */
681*5e7646d2SAndroid Build Coastguard Worker 
682*5e7646d2SAndroid Build Coastguard Worker 
683*5e7646d2SAndroid Build Coastguard Worker      /*
684*5e7646d2SAndroid Build Coastguard Worker       * Lookup the service...
685*5e7646d2SAndroid Build Coastguard Worker       */
686*5e7646d2SAndroid Build Coastguard Worker 
687*5e7646d2SAndroid Build Coastguard Worker       if (!service)
688*5e7646d2SAndroid Build Coastguard Worker 	portnum = 0;
689*5e7646d2SAndroid Build Coastguard Worker       else if (isdigit(*service & 255))
690*5e7646d2SAndroid Build Coastguard Worker 	portnum = atoi(service);
691*5e7646d2SAndroid Build Coastguard Worker       else if ((port = getservbyname(service, NULL)) != NULL)
692*5e7646d2SAndroid Build Coastguard Worker 	portnum = ntohs(port->s_port);
693*5e7646d2SAndroid Build Coastguard Worker       else if (!strcmp(service, "http"))
694*5e7646d2SAndroid Build Coastguard Worker         portnum = 80;
695*5e7646d2SAndroid Build Coastguard Worker       else if (!strcmp(service, "https"))
696*5e7646d2SAndroid Build Coastguard Worker         portnum = 443;
697*5e7646d2SAndroid Build Coastguard Worker       else if (!strcmp(service, "ipp") || !strcmp(service, "ipps"))
698*5e7646d2SAndroid Build Coastguard Worker         portnum = 631;
699*5e7646d2SAndroid Build Coastguard Worker       else if (!strcmp(service, "lpd"))
700*5e7646d2SAndroid Build Coastguard Worker         portnum = 515;
701*5e7646d2SAndroid Build Coastguard Worker       else if (!strcmp(service, "socket"))
702*5e7646d2SAndroid Build Coastguard Worker         portnum = 9100;
703*5e7646d2SAndroid Build Coastguard Worker       else
704*5e7646d2SAndroid Build Coastguard Worker 	return (NULL);
705*5e7646d2SAndroid Build Coastguard Worker 
706*5e7646d2SAndroid Build Coastguard Worker      /*
707*5e7646d2SAndroid Build Coastguard Worker       * This code is needed because some operating systems have a
708*5e7646d2SAndroid Build Coastguard Worker       * buggy implementation of gethostbyname() that does not support
709*5e7646d2SAndroid Build Coastguard Worker       * IPv4 addresses.  If the hostname string is an IPv4 address, then
710*5e7646d2SAndroid Build Coastguard Worker       * sscanf() is used to extract the IPv4 components.  We then pack
711*5e7646d2SAndroid Build Coastguard Worker       * the components into an IPv4 address manually, since the
712*5e7646d2SAndroid Build Coastguard Worker       * inet_aton() function is deprecated.  We use the htonl() macro
713*5e7646d2SAndroid Build Coastguard Worker       * to get the right byte order for the address.
714*5e7646d2SAndroid Build Coastguard Worker       */
715*5e7646d2SAndroid Build Coastguard Worker 
716*5e7646d2SAndroid Build Coastguard Worker       for (ptr = hostname; isdigit(*ptr & 255) || *ptr == '.'; ptr ++);
717*5e7646d2SAndroid Build Coastguard Worker 
718*5e7646d2SAndroid Build Coastguard Worker       if (!*ptr)
719*5e7646d2SAndroid Build Coastguard Worker       {
720*5e7646d2SAndroid Build Coastguard Worker        /*
721*5e7646d2SAndroid Build Coastguard Worker 	* We have an IPv4 address; break it up and create an IPv4 address...
722*5e7646d2SAndroid Build Coastguard Worker 	*/
723*5e7646d2SAndroid Build Coastguard Worker 
724*5e7646d2SAndroid Build Coastguard Worker 	if (sscanf(hostname, "%u.%u.%u.%u", ip, ip + 1, ip + 2, ip + 3) == 4 &&
725*5e7646d2SAndroid Build Coastguard Worker             ip[0] <= 255 && ip[1] <= 255 && ip[2] <= 255 && ip[3] <= 255)
726*5e7646d2SAndroid Build Coastguard Worker 	{
727*5e7646d2SAndroid Build Coastguard Worker 	  first = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t));
728*5e7646d2SAndroid Build Coastguard Worker 	  if (!first)
729*5e7646d2SAndroid Build Coastguard Worker 	    return (NULL);
730*5e7646d2SAndroid Build Coastguard Worker 
731*5e7646d2SAndroid Build Coastguard Worker           first->addr.ipv4.sin_family = AF_INET;
732*5e7646d2SAndroid Build Coastguard Worker           first->addr.ipv4.sin_addr.s_addr = htonl((((((((unsigned)ip[0] << 8) |
733*5e7646d2SAndroid Build Coastguard Worker 	                                               (unsigned)ip[1]) << 8) |
734*5e7646d2SAndroid Build Coastguard Worker 						     (unsigned)ip[2]) << 8) |
735*5e7646d2SAndroid Build Coastguard Worker 						   (unsigned)ip[3]));
736*5e7646d2SAndroid Build Coastguard Worker           first->addr.ipv4.sin_port = htons(portnum);
737*5e7646d2SAndroid Build Coastguard Worker 	}
738*5e7646d2SAndroid Build Coastguard Worker       }
739*5e7646d2SAndroid Build Coastguard Worker       else if ((host = gethostbyname(hostname)) != NULL &&
740*5e7646d2SAndroid Build Coastguard Worker #  ifdef AF_INET6
741*5e7646d2SAndroid Build Coastguard Worker                (host->h_addrtype == AF_INET || host->h_addrtype == AF_INET6))
742*5e7646d2SAndroid Build Coastguard Worker #  else
743*5e7646d2SAndroid Build Coastguard Worker                host->h_addrtype == AF_INET)
744*5e7646d2SAndroid Build Coastguard Worker #  endif /* AF_INET6 */
745*5e7646d2SAndroid Build Coastguard Worker       {
746*5e7646d2SAndroid Build Coastguard Worker 	for (i = 0; host->h_addr_list[i]; i ++)
747*5e7646d2SAndroid Build Coastguard Worker 	{
748*5e7646d2SAndroid Build Coastguard Worker 	 /*
749*5e7646d2SAndroid Build Coastguard Worker           * Copy the address over...
750*5e7646d2SAndroid Build Coastguard Worker 	  */
751*5e7646d2SAndroid Build Coastguard Worker 
752*5e7646d2SAndroid Build Coastguard Worker 	  temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t));
753*5e7646d2SAndroid Build Coastguard Worker 	  if (!temp)
754*5e7646d2SAndroid Build Coastguard Worker 	  {
755*5e7646d2SAndroid Build Coastguard Worker 	    httpAddrFreeList(first);
756*5e7646d2SAndroid Build Coastguard Worker 	    return (NULL);
757*5e7646d2SAndroid Build Coastguard Worker 	  }
758*5e7646d2SAndroid Build Coastguard Worker 
759*5e7646d2SAndroid Build Coastguard Worker #  ifdef AF_INET6
760*5e7646d2SAndroid Build Coastguard Worker           if (host->h_addrtype == AF_INET6)
761*5e7646d2SAndroid Build Coastguard Worker 	  {
762*5e7646d2SAndroid Build Coastguard Worker             temp->addr.ipv6.sin6_family = AF_INET6;
763*5e7646d2SAndroid Build Coastguard Worker 	    memcpy(&(temp->addr.ipv6.sin6_addr), host->h_addr_list[i],
764*5e7646d2SAndroid Build Coastguard Worker 	           sizeof(temp->addr.ipv6));
765*5e7646d2SAndroid Build Coastguard Worker             temp->addr.ipv6.sin6_port = htons(portnum);
766*5e7646d2SAndroid Build Coastguard Worker 	  }
767*5e7646d2SAndroid Build Coastguard Worker 	  else
768*5e7646d2SAndroid Build Coastguard Worker #  endif /* AF_INET6 */
769*5e7646d2SAndroid Build Coastguard Worker 	  {
770*5e7646d2SAndroid Build Coastguard Worker             temp->addr.ipv4.sin_family = AF_INET;
771*5e7646d2SAndroid Build Coastguard Worker 	    memcpy(&(temp->addr.ipv4.sin_addr), host->h_addr_list[i],
772*5e7646d2SAndroid Build Coastguard Worker 	           sizeof(temp->addr.ipv4));
773*5e7646d2SAndroid Build Coastguard Worker             temp->addr.ipv4.sin_port = htons(portnum);
774*5e7646d2SAndroid Build Coastguard Worker           }
775*5e7646d2SAndroid Build Coastguard Worker 
776*5e7646d2SAndroid Build Coastguard Worker 	 /*
777*5e7646d2SAndroid Build Coastguard Worker 	  * Append the address to the list...
778*5e7646d2SAndroid Build Coastguard Worker 	  */
779*5e7646d2SAndroid Build Coastguard Worker 
780*5e7646d2SAndroid Build Coastguard Worker 	  if (!first)
781*5e7646d2SAndroid Build Coastguard Worker 	    first = temp;
782*5e7646d2SAndroid Build Coastguard Worker 
783*5e7646d2SAndroid Build Coastguard Worker 	  if (addr)
784*5e7646d2SAndroid Build Coastguard Worker 	    addr->next = temp;
785*5e7646d2SAndroid Build Coastguard Worker 
786*5e7646d2SAndroid Build Coastguard Worker 	  addr = temp;
787*5e7646d2SAndroid Build Coastguard Worker 	}
788*5e7646d2SAndroid Build Coastguard Worker       }
789*5e7646d2SAndroid Build Coastguard Worker       else
790*5e7646d2SAndroid Build Coastguard Worker       {
791*5e7646d2SAndroid Build Coastguard Worker         if (h_errno == NO_RECOVERY)
792*5e7646d2SAndroid Build Coastguard Worker           cg->need_res_init = 1;
793*5e7646d2SAndroid Build Coastguard Worker 
794*5e7646d2SAndroid Build Coastguard Worker 	_cupsSetError(IPP_STATUS_ERROR_INTERNAL, hstrerror(h_errno), 0);
795*5e7646d2SAndroid Build Coastguard Worker       }
796*5e7646d2SAndroid Build Coastguard Worker     }
797*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_GETADDRINFO */
798*5e7646d2SAndroid Build Coastguard Worker   }
799*5e7646d2SAndroid Build Coastguard Worker 
800*5e7646d2SAndroid Build Coastguard Worker  /*
801*5e7646d2SAndroid Build Coastguard Worker   * Detect some common errors and handle them sanely...
802*5e7646d2SAndroid Build Coastguard Worker   */
803*5e7646d2SAndroid Build Coastguard Worker 
804*5e7646d2SAndroid Build Coastguard Worker   if (!addr && (!hostname || !_cups_strcasecmp(hostname, "localhost")))
805*5e7646d2SAndroid Build Coastguard Worker   {
806*5e7646d2SAndroid Build Coastguard Worker     struct servent	*port;		/* Port number for service */
807*5e7646d2SAndroid Build Coastguard Worker     int			portnum;	/* Port number */
808*5e7646d2SAndroid Build Coastguard Worker 
809*5e7646d2SAndroid Build Coastguard Worker 
810*5e7646d2SAndroid Build Coastguard Worker    /*
811*5e7646d2SAndroid Build Coastguard Worker     * Lookup the service...
812*5e7646d2SAndroid Build Coastguard Worker     */
813*5e7646d2SAndroid Build Coastguard Worker 
814*5e7646d2SAndroid Build Coastguard Worker     if (!service)
815*5e7646d2SAndroid Build Coastguard Worker       portnum = 0;
816*5e7646d2SAndroid Build Coastguard Worker     else if (isdigit(*service & 255))
817*5e7646d2SAndroid Build Coastguard Worker       portnum = atoi(service);
818*5e7646d2SAndroid Build Coastguard Worker     else if ((port = getservbyname(service, NULL)) != NULL)
819*5e7646d2SAndroid Build Coastguard Worker       portnum = ntohs(port->s_port);
820*5e7646d2SAndroid Build Coastguard Worker     else if (!strcmp(service, "http"))
821*5e7646d2SAndroid Build Coastguard Worker       portnum = 80;
822*5e7646d2SAndroid Build Coastguard Worker     else if (!strcmp(service, "https"))
823*5e7646d2SAndroid Build Coastguard Worker       portnum = 443;
824*5e7646d2SAndroid Build Coastguard Worker     else if (!strcmp(service, "ipp") || !strcmp(service, "ipps"))
825*5e7646d2SAndroid Build Coastguard Worker       portnum = 631;
826*5e7646d2SAndroid Build Coastguard Worker     else if (!strcmp(service, "lpd"))
827*5e7646d2SAndroid Build Coastguard Worker       portnum = 515;
828*5e7646d2SAndroid Build Coastguard Worker     else if (!strcmp(service, "socket"))
829*5e7646d2SAndroid Build Coastguard Worker       portnum = 9100;
830*5e7646d2SAndroid Build Coastguard Worker     else
831*5e7646d2SAndroid Build Coastguard Worker     {
832*5e7646d2SAndroid Build Coastguard Worker       httpAddrFreeList(first);
833*5e7646d2SAndroid Build Coastguard Worker 
834*5e7646d2SAndroid Build Coastguard Worker       _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unknown service name."), 1);
835*5e7646d2SAndroid Build Coastguard Worker       return (NULL);
836*5e7646d2SAndroid Build Coastguard Worker     }
837*5e7646d2SAndroid Build Coastguard Worker 
838*5e7646d2SAndroid Build Coastguard Worker     if (hostname && !_cups_strcasecmp(hostname, "localhost"))
839*5e7646d2SAndroid Build Coastguard Worker     {
840*5e7646d2SAndroid Build Coastguard Worker      /*
841*5e7646d2SAndroid Build Coastguard Worker       * Unfortunately, some users ignore all of the warnings in the
842*5e7646d2SAndroid Build Coastguard Worker       * /etc/hosts file and delete "localhost" from it. If we get here
843*5e7646d2SAndroid Build Coastguard Worker       * then we were unable to resolve the name, so use the IPv6 and/or
844*5e7646d2SAndroid Build Coastguard Worker       * IPv4 loopback interface addresses...
845*5e7646d2SAndroid Build Coastguard Worker       */
846*5e7646d2SAndroid Build Coastguard Worker 
847*5e7646d2SAndroid Build Coastguard Worker #ifdef AF_INET6
848*5e7646d2SAndroid Build Coastguard Worker       if (family != AF_INET)
849*5e7646d2SAndroid Build Coastguard Worker       {
850*5e7646d2SAndroid Build Coastguard Worker        /*
851*5e7646d2SAndroid Build Coastguard Worker         * Add [::1] to the address list...
852*5e7646d2SAndroid Build Coastguard Worker 	*/
853*5e7646d2SAndroid Build Coastguard Worker 
854*5e7646d2SAndroid Build Coastguard Worker 	temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t));
855*5e7646d2SAndroid Build Coastguard Worker 	if (!temp)
856*5e7646d2SAndroid Build Coastguard Worker 	{
857*5e7646d2SAndroid Build Coastguard Worker 	  _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
858*5e7646d2SAndroid Build Coastguard Worker 	  httpAddrFreeList(first);
859*5e7646d2SAndroid Build Coastguard Worker 	  return (NULL);
860*5e7646d2SAndroid Build Coastguard Worker 	}
861*5e7646d2SAndroid Build Coastguard Worker 
862*5e7646d2SAndroid Build Coastguard Worker         temp->addr.ipv6.sin6_family            = AF_INET6;
863*5e7646d2SAndroid Build Coastguard Worker 	temp->addr.ipv6.sin6_port              = htons(portnum);
864*5e7646d2SAndroid Build Coastguard Worker #  ifdef _WIN32
865*5e7646d2SAndroid Build Coastguard Worker 	temp->addr.ipv6.sin6_addr.u.Byte[15]   = 1;
866*5e7646d2SAndroid Build Coastguard Worker #  else
867*5e7646d2SAndroid Build Coastguard Worker 	temp->addr.ipv6.sin6_addr.s6_addr32[3] = htonl(1);
868*5e7646d2SAndroid Build Coastguard Worker #  endif /* _WIN32 */
869*5e7646d2SAndroid Build Coastguard Worker 
870*5e7646d2SAndroid Build Coastguard Worker         if (!first)
871*5e7646d2SAndroid Build Coastguard Worker           first = temp;
872*5e7646d2SAndroid Build Coastguard Worker 
873*5e7646d2SAndroid Build Coastguard Worker         addr = temp;
874*5e7646d2SAndroid Build Coastguard Worker       }
875*5e7646d2SAndroid Build Coastguard Worker 
876*5e7646d2SAndroid Build Coastguard Worker       if (family != AF_INET6)
877*5e7646d2SAndroid Build Coastguard Worker #endif /* AF_INET6 */
878*5e7646d2SAndroid Build Coastguard Worker       {
879*5e7646d2SAndroid Build Coastguard Worker        /*
880*5e7646d2SAndroid Build Coastguard Worker         * Add 127.0.0.1 to the address list...
881*5e7646d2SAndroid Build Coastguard Worker 	*/
882*5e7646d2SAndroid Build Coastguard Worker 
883*5e7646d2SAndroid Build Coastguard Worker 	temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t));
884*5e7646d2SAndroid Build Coastguard Worker 	if (!temp)
885*5e7646d2SAndroid Build Coastguard Worker 	{
886*5e7646d2SAndroid Build Coastguard Worker 	  _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
887*5e7646d2SAndroid Build Coastguard Worker 	  httpAddrFreeList(first);
888*5e7646d2SAndroid Build Coastguard Worker 	  return (NULL);
889*5e7646d2SAndroid Build Coastguard Worker 	}
890*5e7646d2SAndroid Build Coastguard Worker 
891*5e7646d2SAndroid Build Coastguard Worker         temp->addr.ipv4.sin_family      = AF_INET;
892*5e7646d2SAndroid Build Coastguard Worker 	temp->addr.ipv4.sin_port        = htons(portnum);
893*5e7646d2SAndroid Build Coastguard Worker 	temp->addr.ipv4.sin_addr.s_addr = htonl(0x7f000001);
894*5e7646d2SAndroid Build Coastguard Worker 
895*5e7646d2SAndroid Build Coastguard Worker         if (!first)
896*5e7646d2SAndroid Build Coastguard Worker           first = temp;
897*5e7646d2SAndroid Build Coastguard Worker 
898*5e7646d2SAndroid Build Coastguard Worker         if (addr)
899*5e7646d2SAndroid Build Coastguard Worker 	  addr->next = temp;
900*5e7646d2SAndroid Build Coastguard Worker       }
901*5e7646d2SAndroid Build Coastguard Worker     }
902*5e7646d2SAndroid Build Coastguard Worker     else if (!hostname)
903*5e7646d2SAndroid Build Coastguard Worker     {
904*5e7646d2SAndroid Build Coastguard Worker      /*
905*5e7646d2SAndroid Build Coastguard Worker       * Provide one or more passive listening addresses...
906*5e7646d2SAndroid Build Coastguard Worker       */
907*5e7646d2SAndroid Build Coastguard Worker 
908*5e7646d2SAndroid Build Coastguard Worker #ifdef AF_INET6
909*5e7646d2SAndroid Build Coastguard Worker       if (family != AF_INET)
910*5e7646d2SAndroid Build Coastguard Worker       {
911*5e7646d2SAndroid Build Coastguard Worker        /*
912*5e7646d2SAndroid Build Coastguard Worker         * Add [::] to the address list...
913*5e7646d2SAndroid Build Coastguard Worker 	*/
914*5e7646d2SAndroid Build Coastguard Worker 
915*5e7646d2SAndroid Build Coastguard Worker 	temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t));
916*5e7646d2SAndroid Build Coastguard Worker 	if (!temp)
917*5e7646d2SAndroid Build Coastguard Worker 	{
918*5e7646d2SAndroid Build Coastguard Worker 	  _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
919*5e7646d2SAndroid Build Coastguard Worker 	  httpAddrFreeList(first);
920*5e7646d2SAndroid Build Coastguard Worker 	  return (NULL);
921*5e7646d2SAndroid Build Coastguard Worker 	}
922*5e7646d2SAndroid Build Coastguard Worker 
923*5e7646d2SAndroid Build Coastguard Worker         temp->addr.ipv6.sin6_family = AF_INET6;
924*5e7646d2SAndroid Build Coastguard Worker 	temp->addr.ipv6.sin6_port   = htons(portnum);
925*5e7646d2SAndroid Build Coastguard Worker 
926*5e7646d2SAndroid Build Coastguard Worker         if (!first)
927*5e7646d2SAndroid Build Coastguard Worker           first = temp;
928*5e7646d2SAndroid Build Coastguard Worker 
929*5e7646d2SAndroid Build Coastguard Worker         addr = temp;
930*5e7646d2SAndroid Build Coastguard Worker       }
931*5e7646d2SAndroid Build Coastguard Worker 
932*5e7646d2SAndroid Build Coastguard Worker       if (family != AF_INET6)
933*5e7646d2SAndroid Build Coastguard Worker #endif /* AF_INET6 */
934*5e7646d2SAndroid Build Coastguard Worker       {
935*5e7646d2SAndroid Build Coastguard Worker        /*
936*5e7646d2SAndroid Build Coastguard Worker         * Add 0.0.0.0 to the address list...
937*5e7646d2SAndroid Build Coastguard Worker 	*/
938*5e7646d2SAndroid Build Coastguard Worker 
939*5e7646d2SAndroid Build Coastguard Worker 	temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t));
940*5e7646d2SAndroid Build Coastguard Worker 	if (!temp)
941*5e7646d2SAndroid Build Coastguard Worker 	{
942*5e7646d2SAndroid Build Coastguard Worker 	  _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
943*5e7646d2SAndroid Build Coastguard Worker 	  httpAddrFreeList(first);
944*5e7646d2SAndroid Build Coastguard Worker 	  return (NULL);
945*5e7646d2SAndroid Build Coastguard Worker 	}
946*5e7646d2SAndroid Build Coastguard Worker 
947*5e7646d2SAndroid Build Coastguard Worker         temp->addr.ipv4.sin_family = AF_INET;
948*5e7646d2SAndroid Build Coastguard Worker 	temp->addr.ipv4.sin_port   = htons(portnum);
949*5e7646d2SAndroid Build Coastguard Worker 
950*5e7646d2SAndroid Build Coastguard Worker         if (!first)
951*5e7646d2SAndroid Build Coastguard Worker           first = temp;
952*5e7646d2SAndroid Build Coastguard Worker 
953*5e7646d2SAndroid Build Coastguard Worker         if (addr)
954*5e7646d2SAndroid Build Coastguard Worker 	  addr->next = temp;
955*5e7646d2SAndroid Build Coastguard Worker       }
956*5e7646d2SAndroid Build Coastguard Worker     }
957*5e7646d2SAndroid Build Coastguard Worker   }
958*5e7646d2SAndroid Build Coastguard Worker 
959*5e7646d2SAndroid Build Coastguard Worker  /*
960*5e7646d2SAndroid Build Coastguard Worker   * Return the address list...
961*5e7646d2SAndroid Build Coastguard Worker   */
962*5e7646d2SAndroid Build Coastguard Worker 
963*5e7646d2SAndroid Build Coastguard Worker   return (first);
964*5e7646d2SAndroid Build Coastguard Worker }
965