xref: /aosp_15_r20/external/libcups/cups/http-addr.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker  * HTTP address routines for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker  *
4*5e7646d2SAndroid Build Coastguard Worker  * Copyright 2007-2019 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker  * Copyright 1997-2006 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 #include <sys/stat.h>
18*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_RESOLV_H
19*5e7646d2SAndroid Build Coastguard Worker #  include <resolv.h>
20*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_RESOLV_H */
21*5e7646d2SAndroid Build Coastguard Worker #ifdef __APPLE__
22*5e7646d2SAndroid Build Coastguard Worker #  include <CoreFoundation/CoreFoundation.h>
23*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME
24*5e7646d2SAndroid Build Coastguard Worker #    include <SystemConfiguration/SystemConfiguration.h>
25*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME */
26*5e7646d2SAndroid Build Coastguard Worker #endif /* __APPLE__ */
27*5e7646d2SAndroid Build Coastguard Worker 
28*5e7646d2SAndroid Build Coastguard Worker 
29*5e7646d2SAndroid Build Coastguard Worker /*
30*5e7646d2SAndroid Build Coastguard Worker  * 'httpAddrAny()' - Check for the "any" address.
31*5e7646d2SAndroid Build Coastguard Worker  *
32*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 1.2/macOS 10.5@
33*5e7646d2SAndroid Build Coastguard Worker  */
34*5e7646d2SAndroid Build Coastguard Worker 
35*5e7646d2SAndroid Build Coastguard Worker int					/* O - 1 if "any", 0 otherwise */
httpAddrAny(const http_addr_t * addr)36*5e7646d2SAndroid Build Coastguard Worker httpAddrAny(const http_addr_t *addr)	/* I - Address to check */
37*5e7646d2SAndroid Build Coastguard Worker {
38*5e7646d2SAndroid Build Coastguard Worker   if (!addr)
39*5e7646d2SAndroid Build Coastguard Worker     return (0);
40*5e7646d2SAndroid Build Coastguard Worker 
41*5e7646d2SAndroid Build Coastguard Worker #ifdef AF_INET6
42*5e7646d2SAndroid Build Coastguard Worker   if (addr->addr.sa_family == AF_INET6 &&
43*5e7646d2SAndroid Build Coastguard Worker       IN6_IS_ADDR_UNSPECIFIED(&(addr->ipv6.sin6_addr)))
44*5e7646d2SAndroid Build Coastguard Worker     return (1);
45*5e7646d2SAndroid Build Coastguard Worker #endif /* AF_INET6 */
46*5e7646d2SAndroid Build Coastguard Worker 
47*5e7646d2SAndroid Build Coastguard Worker   if (addr->addr.sa_family == AF_INET &&
48*5e7646d2SAndroid Build Coastguard Worker       ntohl(addr->ipv4.sin_addr.s_addr) == 0x00000000)
49*5e7646d2SAndroid Build Coastguard Worker     return (1);
50*5e7646d2SAndroid Build Coastguard Worker 
51*5e7646d2SAndroid Build Coastguard Worker   return (0);
52*5e7646d2SAndroid Build Coastguard Worker }
53*5e7646d2SAndroid Build Coastguard Worker 
54*5e7646d2SAndroid Build Coastguard Worker 
55*5e7646d2SAndroid Build Coastguard Worker /*
56*5e7646d2SAndroid Build Coastguard Worker  * 'httpAddrClose()' - Close a socket created by @link httpAddrConnect@ or
57*5e7646d2SAndroid Build Coastguard Worker  *                     @link httpAddrListen@.
58*5e7646d2SAndroid Build Coastguard Worker  *
59*5e7646d2SAndroid Build Coastguard Worker  * Pass @code NULL@ for sockets created with @link httpAddrConnect2@ and the
60*5e7646d2SAndroid Build Coastguard Worker  * listen address for sockets created with @link httpAddrListen@.  This function
61*5e7646d2SAndroid Build Coastguard Worker  * ensures that domain sockets are removed when closed.
62*5e7646d2SAndroid Build Coastguard Worker  *
63*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 2.0/OS 10.10@
64*5e7646d2SAndroid Build Coastguard Worker  */
65*5e7646d2SAndroid Build Coastguard Worker 
66*5e7646d2SAndroid Build Coastguard Worker int						/* O - 0 on success, -1 on failure */
httpAddrClose(http_addr_t * addr,int fd)67*5e7646d2SAndroid Build Coastguard Worker httpAddrClose(http_addr_t *addr,		/* I - Listen address or @code NULL@ */
68*5e7646d2SAndroid Build Coastguard Worker               int         fd)			/* I - Socket file descriptor */
69*5e7646d2SAndroid Build Coastguard Worker {
70*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
71*5e7646d2SAndroid Build Coastguard Worker   if (closesocket(fd))
72*5e7646d2SAndroid Build Coastguard Worker #else
73*5e7646d2SAndroid Build Coastguard Worker   if (close(fd))
74*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
75*5e7646d2SAndroid Build Coastguard Worker     return (-1);
76*5e7646d2SAndroid Build Coastguard Worker 
77*5e7646d2SAndroid Build Coastguard Worker #ifdef AF_LOCAL
78*5e7646d2SAndroid Build Coastguard Worker   if (addr && addr->addr.sa_family == AF_LOCAL)
79*5e7646d2SAndroid Build Coastguard Worker     return (unlink(addr->un.sun_path));
80*5e7646d2SAndroid Build Coastguard Worker #endif /* AF_LOCAL */
81*5e7646d2SAndroid Build Coastguard Worker 
82*5e7646d2SAndroid Build Coastguard Worker   return (0);
83*5e7646d2SAndroid Build Coastguard Worker }
84*5e7646d2SAndroid Build Coastguard Worker 
85*5e7646d2SAndroid Build Coastguard Worker 
86*5e7646d2SAndroid Build Coastguard Worker /*
87*5e7646d2SAndroid Build Coastguard Worker  * 'httpAddrEqual()' - Compare two addresses.
88*5e7646d2SAndroid Build Coastguard Worker  *
89*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 1.2/macOS 10.5@
90*5e7646d2SAndroid Build Coastguard Worker  */
91*5e7646d2SAndroid Build Coastguard Worker 
92*5e7646d2SAndroid Build Coastguard Worker int						/* O - 1 if equal, 0 if not */
httpAddrEqual(const http_addr_t * addr1,const http_addr_t * addr2)93*5e7646d2SAndroid Build Coastguard Worker httpAddrEqual(const http_addr_t *addr1,		/* I - First address */
94*5e7646d2SAndroid Build Coastguard Worker               const http_addr_t *addr2)		/* I - Second address */
95*5e7646d2SAndroid Build Coastguard Worker {
96*5e7646d2SAndroid Build Coastguard Worker   if (!addr1 && !addr2)
97*5e7646d2SAndroid Build Coastguard Worker     return (1);
98*5e7646d2SAndroid Build Coastguard Worker 
99*5e7646d2SAndroid Build Coastguard Worker   if (!addr1 || !addr2)
100*5e7646d2SAndroid Build Coastguard Worker     return (0);
101*5e7646d2SAndroid Build Coastguard Worker 
102*5e7646d2SAndroid Build Coastguard Worker   if (addr1->addr.sa_family != addr2->addr.sa_family)
103*5e7646d2SAndroid Build Coastguard Worker     return (0);
104*5e7646d2SAndroid Build Coastguard Worker 
105*5e7646d2SAndroid Build Coastguard Worker #ifdef AF_LOCAL
106*5e7646d2SAndroid Build Coastguard Worker   if (addr1->addr.sa_family == AF_LOCAL)
107*5e7646d2SAndroid Build Coastguard Worker     return (!strcmp(addr1->un.sun_path, addr2->un.sun_path));
108*5e7646d2SAndroid Build Coastguard Worker #endif /* AF_LOCAL */
109*5e7646d2SAndroid Build Coastguard Worker 
110*5e7646d2SAndroid Build Coastguard Worker #ifdef AF_INET6
111*5e7646d2SAndroid Build Coastguard Worker   if (addr1->addr.sa_family == AF_INET6)
112*5e7646d2SAndroid Build Coastguard Worker     return (!memcmp(&(addr1->ipv6.sin6_addr), &(addr2->ipv6.sin6_addr), 16));
113*5e7646d2SAndroid Build Coastguard Worker #endif /* AF_INET6 */
114*5e7646d2SAndroid Build Coastguard Worker 
115*5e7646d2SAndroid Build Coastguard Worker   return (addr1->ipv4.sin_addr.s_addr == addr2->ipv4.sin_addr.s_addr);
116*5e7646d2SAndroid Build Coastguard Worker }
117*5e7646d2SAndroid Build Coastguard Worker 
118*5e7646d2SAndroid Build Coastguard Worker 
119*5e7646d2SAndroid Build Coastguard Worker /*
120*5e7646d2SAndroid Build Coastguard Worker  * 'httpAddrLength()' - Return the length of the address in bytes.
121*5e7646d2SAndroid Build Coastguard Worker  *
122*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 1.2/macOS 10.5@
123*5e7646d2SAndroid Build Coastguard Worker  */
124*5e7646d2SAndroid Build Coastguard Worker 
125*5e7646d2SAndroid Build Coastguard Worker int					/* O - Length in bytes */
httpAddrLength(const http_addr_t * addr)126*5e7646d2SAndroid Build Coastguard Worker httpAddrLength(const http_addr_t *addr)	/* I - Address */
127*5e7646d2SAndroid Build Coastguard Worker {
128*5e7646d2SAndroid Build Coastguard Worker   if (!addr)
129*5e7646d2SAndroid Build Coastguard Worker     return (0);
130*5e7646d2SAndroid Build Coastguard Worker 
131*5e7646d2SAndroid Build Coastguard Worker #ifdef AF_INET6
132*5e7646d2SAndroid Build Coastguard Worker   if (addr->addr.sa_family == AF_INET6)
133*5e7646d2SAndroid Build Coastguard Worker     return (sizeof(addr->ipv6));
134*5e7646d2SAndroid Build Coastguard Worker   else
135*5e7646d2SAndroid Build Coastguard Worker #endif /* AF_INET6 */
136*5e7646d2SAndroid Build Coastguard Worker #ifdef AF_LOCAL
137*5e7646d2SAndroid Build Coastguard Worker   if (addr->addr.sa_family == AF_LOCAL)
138*5e7646d2SAndroid Build Coastguard Worker     return ((int)(offsetof(struct sockaddr_un, sun_path) + strlen(addr->un.sun_path) + 1));
139*5e7646d2SAndroid Build Coastguard Worker   else
140*5e7646d2SAndroid Build Coastguard Worker #endif /* AF_LOCAL */
141*5e7646d2SAndroid Build Coastguard Worker   if (addr->addr.sa_family == AF_INET)
142*5e7646d2SAndroid Build Coastguard Worker     return (sizeof(addr->ipv4));
143*5e7646d2SAndroid Build Coastguard Worker   else
144*5e7646d2SAndroid Build Coastguard Worker     return (0);
145*5e7646d2SAndroid Build Coastguard Worker 
146*5e7646d2SAndroid Build Coastguard Worker }
147*5e7646d2SAndroid Build Coastguard Worker 
148*5e7646d2SAndroid Build Coastguard Worker 
149*5e7646d2SAndroid Build Coastguard Worker /*
150*5e7646d2SAndroid Build Coastguard Worker  * 'httpAddrListen()' - Create a listening socket bound to the specified
151*5e7646d2SAndroid Build Coastguard Worker  *                      address and port.
152*5e7646d2SAndroid Build Coastguard Worker  *
153*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 1.7/macOS 10.9@
154*5e7646d2SAndroid Build Coastguard Worker  */
155*5e7646d2SAndroid Build Coastguard Worker 
156*5e7646d2SAndroid Build Coastguard Worker int					/* O - Socket or -1 on error */
httpAddrListen(http_addr_t * addr,int port)157*5e7646d2SAndroid Build Coastguard Worker httpAddrListen(http_addr_t *addr,	/* I - Address to bind to */
158*5e7646d2SAndroid Build Coastguard Worker                int         port)	/* I - Port number to bind to */
159*5e7646d2SAndroid Build Coastguard Worker {
160*5e7646d2SAndroid Build Coastguard Worker   int		fd = -1,		/* Socket */
161*5e7646d2SAndroid Build Coastguard Worker 		val,			/* Socket value */
162*5e7646d2SAndroid Build Coastguard Worker                 status;			/* Bind status */
163*5e7646d2SAndroid Build Coastguard Worker 
164*5e7646d2SAndroid Build Coastguard Worker 
165*5e7646d2SAndroid Build Coastguard Worker  /*
166*5e7646d2SAndroid Build Coastguard Worker   * Range check input...
167*5e7646d2SAndroid Build Coastguard Worker   */
168*5e7646d2SAndroid Build Coastguard Worker 
169*5e7646d2SAndroid Build Coastguard Worker   if (!addr || port < 0)
170*5e7646d2SAndroid Build Coastguard Worker     return (-1);
171*5e7646d2SAndroid Build Coastguard Worker 
172*5e7646d2SAndroid Build Coastguard Worker  /*
173*5e7646d2SAndroid Build Coastguard Worker   * Create the socket and set options...
174*5e7646d2SAndroid Build Coastguard Worker   */
175*5e7646d2SAndroid Build Coastguard Worker 
176*5e7646d2SAndroid Build Coastguard Worker   if ((fd = socket(addr->addr.sa_family, SOCK_STREAM, 0)) < 0)
177*5e7646d2SAndroid Build Coastguard Worker   {
178*5e7646d2SAndroid Build Coastguard Worker     _cupsSetHTTPError(HTTP_STATUS_ERROR);
179*5e7646d2SAndroid Build Coastguard Worker     return (-1);
180*5e7646d2SAndroid Build Coastguard Worker   }
181*5e7646d2SAndroid Build Coastguard Worker 
182*5e7646d2SAndroid Build Coastguard Worker   val = 1;
183*5e7646d2SAndroid Build Coastguard Worker   setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, CUPS_SOCAST &val, sizeof(val));
184*5e7646d2SAndroid Build Coastguard Worker 
185*5e7646d2SAndroid Build Coastguard Worker #ifdef IPV6_V6ONLY
186*5e7646d2SAndroid Build Coastguard Worker   if (addr->addr.sa_family == AF_INET6)
187*5e7646d2SAndroid Build Coastguard Worker     setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, CUPS_SOCAST &val, sizeof(val));
188*5e7646d2SAndroid Build Coastguard Worker #endif /* IPV6_V6ONLY */
189*5e7646d2SAndroid Build Coastguard Worker 
190*5e7646d2SAndroid Build Coastguard Worker  /*
191*5e7646d2SAndroid Build Coastguard Worker   * Bind the socket...
192*5e7646d2SAndroid Build Coastguard Worker   */
193*5e7646d2SAndroid Build Coastguard Worker 
194*5e7646d2SAndroid Build Coastguard Worker #ifdef AF_LOCAL
195*5e7646d2SAndroid Build Coastguard Worker   if (addr->addr.sa_family == AF_LOCAL)
196*5e7646d2SAndroid Build Coastguard Worker   {
197*5e7646d2SAndroid Build Coastguard Worker     mode_t	mask;			/* Umask setting */
198*5e7646d2SAndroid Build Coastguard Worker 
199*5e7646d2SAndroid Build Coastguard Worker    /*
200*5e7646d2SAndroid Build Coastguard Worker     * Remove any existing domain socket file...
201*5e7646d2SAndroid Build Coastguard Worker     */
202*5e7646d2SAndroid Build Coastguard Worker 
203*5e7646d2SAndroid Build Coastguard Worker     unlink(addr->un.sun_path);
204*5e7646d2SAndroid Build Coastguard Worker 
205*5e7646d2SAndroid Build Coastguard Worker    /*
206*5e7646d2SAndroid Build Coastguard Worker     * Save the current umask and set it to 0 so that all users can access
207*5e7646d2SAndroid Build Coastguard Worker     * the domain socket...
208*5e7646d2SAndroid Build Coastguard Worker     */
209*5e7646d2SAndroid Build Coastguard Worker 
210*5e7646d2SAndroid Build Coastguard Worker     mask = umask(0);
211*5e7646d2SAndroid Build Coastguard Worker 
212*5e7646d2SAndroid Build Coastguard Worker    /*
213*5e7646d2SAndroid Build Coastguard Worker     * Bind the domain socket...
214*5e7646d2SAndroid Build Coastguard Worker     */
215*5e7646d2SAndroid Build Coastguard Worker 
216*5e7646d2SAndroid Build Coastguard Worker     status = bind(fd, (struct sockaddr *)addr, (socklen_t)httpAddrLength(addr));
217*5e7646d2SAndroid Build Coastguard Worker 
218*5e7646d2SAndroid Build Coastguard Worker    /*
219*5e7646d2SAndroid Build Coastguard Worker     * Restore the umask and fix permissions...
220*5e7646d2SAndroid Build Coastguard Worker     */
221*5e7646d2SAndroid Build Coastguard Worker 
222*5e7646d2SAndroid Build Coastguard Worker     umask(mask);
223*5e7646d2SAndroid Build Coastguard Worker     chmod(addr->un.sun_path, 0140777);
224*5e7646d2SAndroid Build Coastguard Worker   }
225*5e7646d2SAndroid Build Coastguard Worker   else
226*5e7646d2SAndroid Build Coastguard Worker #endif /* AF_LOCAL */
227*5e7646d2SAndroid Build Coastguard Worker   {
228*5e7646d2SAndroid Build Coastguard Worker     _httpAddrSetPort(addr, port);
229*5e7646d2SAndroid Build Coastguard Worker 
230*5e7646d2SAndroid Build Coastguard Worker     status = bind(fd, (struct sockaddr *)addr, (socklen_t)httpAddrLength(addr));
231*5e7646d2SAndroid Build Coastguard Worker   }
232*5e7646d2SAndroid Build Coastguard Worker 
233*5e7646d2SAndroid Build Coastguard Worker   if (status)
234*5e7646d2SAndroid Build Coastguard Worker   {
235*5e7646d2SAndroid Build Coastguard Worker     _cupsSetHTTPError(HTTP_STATUS_ERROR);
236*5e7646d2SAndroid Build Coastguard Worker 
237*5e7646d2SAndroid Build Coastguard Worker     close(fd);
238*5e7646d2SAndroid Build Coastguard Worker 
239*5e7646d2SAndroid Build Coastguard Worker     return (-1);
240*5e7646d2SAndroid Build Coastguard Worker   }
241*5e7646d2SAndroid Build Coastguard Worker 
242*5e7646d2SAndroid Build Coastguard Worker  /*
243*5e7646d2SAndroid Build Coastguard Worker   * Listen...
244*5e7646d2SAndroid Build Coastguard Worker   */
245*5e7646d2SAndroid Build Coastguard Worker 
246*5e7646d2SAndroid Build Coastguard Worker   if (listen(fd, 128))
247*5e7646d2SAndroid Build Coastguard Worker   {
248*5e7646d2SAndroid Build Coastguard Worker     _cupsSetHTTPError(HTTP_STATUS_ERROR);
249*5e7646d2SAndroid Build Coastguard Worker 
250*5e7646d2SAndroid Build Coastguard Worker     close(fd);
251*5e7646d2SAndroid Build Coastguard Worker 
252*5e7646d2SAndroid Build Coastguard Worker     return (-1);
253*5e7646d2SAndroid Build Coastguard Worker   }
254*5e7646d2SAndroid Build Coastguard Worker 
255*5e7646d2SAndroid Build Coastguard Worker  /*
256*5e7646d2SAndroid Build Coastguard Worker   * Close on exec...
257*5e7646d2SAndroid Build Coastguard Worker   */
258*5e7646d2SAndroid Build Coastguard Worker 
259*5e7646d2SAndroid Build Coastguard Worker #ifndef _WIN32
260*5e7646d2SAndroid Build Coastguard Worker   fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
261*5e7646d2SAndroid Build Coastguard Worker #endif /* !_WIN32 */
262*5e7646d2SAndroid Build Coastguard Worker 
263*5e7646d2SAndroid Build Coastguard Worker #ifdef SO_NOSIGPIPE
264*5e7646d2SAndroid Build Coastguard Worker  /*
265*5e7646d2SAndroid Build Coastguard Worker   * Disable SIGPIPE for this socket.
266*5e7646d2SAndroid Build Coastguard Worker   */
267*5e7646d2SAndroid Build Coastguard Worker 
268*5e7646d2SAndroid Build Coastguard Worker   val = 1;
269*5e7646d2SAndroid Build Coastguard Worker   setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, CUPS_SOCAST &val, sizeof(val));
270*5e7646d2SAndroid Build Coastguard Worker #endif /* SO_NOSIGPIPE */
271*5e7646d2SAndroid Build Coastguard Worker 
272*5e7646d2SAndroid Build Coastguard Worker   return (fd);
273*5e7646d2SAndroid Build Coastguard Worker }
274*5e7646d2SAndroid Build Coastguard Worker 
275*5e7646d2SAndroid Build Coastguard Worker 
276*5e7646d2SAndroid Build Coastguard Worker /*
277*5e7646d2SAndroid Build Coastguard Worker  * 'httpAddrLocalhost()' - Check for the local loopback address.
278*5e7646d2SAndroid Build Coastguard Worker  *
279*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 1.2/macOS 10.5@
280*5e7646d2SAndroid Build Coastguard Worker  */
281*5e7646d2SAndroid Build Coastguard Worker 
282*5e7646d2SAndroid Build Coastguard Worker int					/* O - 1 if local host, 0 otherwise */
httpAddrLocalhost(const http_addr_t * addr)283*5e7646d2SAndroid Build Coastguard Worker httpAddrLocalhost(
284*5e7646d2SAndroid Build Coastguard Worker     const http_addr_t *addr)		/* I - Address to check */
285*5e7646d2SAndroid Build Coastguard Worker {
286*5e7646d2SAndroid Build Coastguard Worker   if (!addr)
287*5e7646d2SAndroid Build Coastguard Worker     return (1);
288*5e7646d2SAndroid Build Coastguard Worker 
289*5e7646d2SAndroid Build Coastguard Worker #ifdef AF_INET6
290*5e7646d2SAndroid Build Coastguard Worker   if (addr->addr.sa_family == AF_INET6 &&
291*5e7646d2SAndroid Build Coastguard Worker       IN6_IS_ADDR_LOOPBACK(&(addr->ipv6.sin6_addr)))
292*5e7646d2SAndroid Build Coastguard Worker     return (1);
293*5e7646d2SAndroid Build Coastguard Worker #endif /* AF_INET6 */
294*5e7646d2SAndroid Build Coastguard Worker 
295*5e7646d2SAndroid Build Coastguard Worker #ifdef AF_LOCAL
296*5e7646d2SAndroid Build Coastguard Worker   if (addr->addr.sa_family == AF_LOCAL)
297*5e7646d2SAndroid Build Coastguard Worker     return (1);
298*5e7646d2SAndroid Build Coastguard Worker #endif /* AF_LOCAL */
299*5e7646d2SAndroid Build Coastguard Worker 
300*5e7646d2SAndroid Build Coastguard Worker   if (addr->addr.sa_family == AF_INET &&
301*5e7646d2SAndroid Build Coastguard Worker       (ntohl(addr->ipv4.sin_addr.s_addr) & 0xff000000) == 0x7f000000)
302*5e7646d2SAndroid Build Coastguard Worker     return (1);
303*5e7646d2SAndroid Build Coastguard Worker 
304*5e7646d2SAndroid Build Coastguard Worker   return (0);
305*5e7646d2SAndroid Build Coastguard Worker }
306*5e7646d2SAndroid Build Coastguard Worker 
307*5e7646d2SAndroid Build Coastguard Worker 
308*5e7646d2SAndroid Build Coastguard Worker /*
309*5e7646d2SAndroid Build Coastguard Worker  * 'httpAddrLookup()' - Lookup the hostname associated with the address.
310*5e7646d2SAndroid Build Coastguard Worker  *
311*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 1.2/macOS 10.5@
312*5e7646d2SAndroid Build Coastguard Worker  */
313*5e7646d2SAndroid Build Coastguard Worker 
314*5e7646d2SAndroid Build Coastguard Worker char *					/* O - Host name */
httpAddrLookup(const http_addr_t * addr,char * name,int namelen)315*5e7646d2SAndroid Build Coastguard Worker httpAddrLookup(
316*5e7646d2SAndroid Build Coastguard Worker     const http_addr_t *addr,		/* I - Address to lookup */
317*5e7646d2SAndroid Build Coastguard Worker     char              *name,		/* I - Host name buffer */
318*5e7646d2SAndroid Build Coastguard Worker     int               namelen)		/* I - Size of name buffer */
319*5e7646d2SAndroid Build Coastguard Worker {
320*5e7646d2SAndroid Build Coastguard Worker   _cups_globals_t	*cg = _cupsGlobals();
321*5e7646d2SAndroid Build Coastguard Worker 					/* Global data */
322*5e7646d2SAndroid Build Coastguard Worker 
323*5e7646d2SAndroid Build Coastguard Worker 
324*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("httpAddrLookup(addr=%p, name=%p, namelen=%d)", (void *)addr, (void *)name, namelen));
325*5e7646d2SAndroid Build Coastguard Worker 
326*5e7646d2SAndroid Build Coastguard Worker  /*
327*5e7646d2SAndroid Build Coastguard Worker   * Range check input...
328*5e7646d2SAndroid Build Coastguard Worker   */
329*5e7646d2SAndroid Build Coastguard Worker 
330*5e7646d2SAndroid Build Coastguard Worker   if (!addr || !name || namelen <= 2)
331*5e7646d2SAndroid Build Coastguard Worker   {
332*5e7646d2SAndroid Build Coastguard Worker     if (name && namelen >= 1)
333*5e7646d2SAndroid Build Coastguard Worker       *name = '\0';
334*5e7646d2SAndroid Build Coastguard Worker 
335*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
336*5e7646d2SAndroid Build Coastguard Worker   }
337*5e7646d2SAndroid Build Coastguard Worker 
338*5e7646d2SAndroid Build Coastguard Worker #ifdef AF_LOCAL
339*5e7646d2SAndroid Build Coastguard Worker   if (addr->addr.sa_family == AF_LOCAL)
340*5e7646d2SAndroid Build Coastguard Worker   {
341*5e7646d2SAndroid Build Coastguard Worker     strlcpy(name, addr->un.sun_path, (size_t)namelen);
342*5e7646d2SAndroid Build Coastguard Worker     return (name);
343*5e7646d2SAndroid Build Coastguard Worker   }
344*5e7646d2SAndroid Build Coastguard Worker #endif /* AF_LOCAL */
345*5e7646d2SAndroid Build Coastguard Worker 
346*5e7646d2SAndroid Build Coastguard Worker  /*
347*5e7646d2SAndroid Build Coastguard Worker   * Optimize lookups for localhost/loopback addresses...
348*5e7646d2SAndroid Build Coastguard Worker   */
349*5e7646d2SAndroid Build Coastguard Worker 
350*5e7646d2SAndroid Build Coastguard Worker   if (httpAddrLocalhost(addr))
351*5e7646d2SAndroid Build Coastguard Worker   {
352*5e7646d2SAndroid Build Coastguard Worker     strlcpy(name, "localhost", (size_t)namelen);
353*5e7646d2SAndroid Build Coastguard Worker     return (name);
354*5e7646d2SAndroid Build Coastguard Worker   }
355*5e7646d2SAndroid Build Coastguard Worker 
356*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_RES_INIT
357*5e7646d2SAndroid Build Coastguard Worker  /*
358*5e7646d2SAndroid Build Coastguard Worker   * STR #2920: Initialize resolver after failure in cups-polld
359*5e7646d2SAndroid Build Coastguard Worker   *
360*5e7646d2SAndroid Build Coastguard Worker   * If the previous lookup failed, re-initialize the resolver to prevent
361*5e7646d2SAndroid Build Coastguard Worker   * temporary network errors from persisting.  This *should* be handled by
362*5e7646d2SAndroid Build Coastguard Worker   * the resolver libraries, but apparently the glibc folks do not agree.
363*5e7646d2SAndroid Build Coastguard Worker   *
364*5e7646d2SAndroid Build Coastguard Worker   * We set a flag at the end of this function if we encounter an error that
365*5e7646d2SAndroid Build Coastguard Worker   * requires reinitialization of the resolver functions.  We then call
366*5e7646d2SAndroid Build Coastguard Worker   * res_init() if the flag is set on the next call here or in httpAddrLookup().
367*5e7646d2SAndroid Build Coastguard Worker   */
368*5e7646d2SAndroid Build Coastguard Worker 
369*5e7646d2SAndroid Build Coastguard Worker   if (cg->need_res_init)
370*5e7646d2SAndroid Build Coastguard Worker   {
371*5e7646d2SAndroid Build Coastguard Worker     res_init();
372*5e7646d2SAndroid Build Coastguard Worker 
373*5e7646d2SAndroid Build Coastguard Worker     cg->need_res_init = 0;
374*5e7646d2SAndroid Build Coastguard Worker   }
375*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_RES_INIT */
376*5e7646d2SAndroid Build Coastguard Worker 
377*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_GETNAMEINFO
378*5e7646d2SAndroid Build Coastguard Worker   {
379*5e7646d2SAndroid Build Coastguard Worker    /*
380*5e7646d2SAndroid Build Coastguard Worker     * STR #2486: httpAddrLookup() fails when getnameinfo() returns EAI_AGAIN
381*5e7646d2SAndroid Build Coastguard Worker     *
382*5e7646d2SAndroid Build Coastguard Worker     * FWIW, I think this is really a bug in the implementation of
383*5e7646d2SAndroid Build Coastguard Worker     * getnameinfo(), but falling back on httpAddrString() is easy to
384*5e7646d2SAndroid Build Coastguard Worker     * do...
385*5e7646d2SAndroid Build Coastguard Worker     */
386*5e7646d2SAndroid Build Coastguard Worker 
387*5e7646d2SAndroid Build Coastguard Worker     int error = getnameinfo(&addr->addr, (socklen_t)httpAddrLength(addr), name, (socklen_t)namelen, NULL, 0, 0);
388*5e7646d2SAndroid Build Coastguard Worker 
389*5e7646d2SAndroid Build Coastguard Worker     if (error)
390*5e7646d2SAndroid Build Coastguard Worker     {
391*5e7646d2SAndroid Build Coastguard Worker       if (error == EAI_FAIL)
392*5e7646d2SAndroid Build Coastguard Worker         cg->need_res_init = 1;
393*5e7646d2SAndroid Build Coastguard Worker 
394*5e7646d2SAndroid Build Coastguard Worker       return (httpAddrString(addr, name, namelen));
395*5e7646d2SAndroid Build Coastguard Worker     }
396*5e7646d2SAndroid Build Coastguard Worker   }
397*5e7646d2SAndroid Build Coastguard Worker #else
398*5e7646d2SAndroid Build Coastguard Worker   {
399*5e7646d2SAndroid Build Coastguard Worker     struct hostent	*host;			/* Host from name service */
400*5e7646d2SAndroid Build Coastguard Worker 
401*5e7646d2SAndroid Build Coastguard Worker 
402*5e7646d2SAndroid Build Coastguard Worker #  ifdef AF_INET6
403*5e7646d2SAndroid Build Coastguard Worker     if (addr->addr.sa_family == AF_INET6)
404*5e7646d2SAndroid Build Coastguard Worker       host = gethostbyaddr((char *)&(addr->ipv6.sin6_addr),
405*5e7646d2SAndroid Build Coastguard Worker                 	   sizeof(struct in_addr), AF_INET6);
406*5e7646d2SAndroid Build Coastguard Worker     else
407*5e7646d2SAndroid Build Coastguard Worker #  endif /* AF_INET6 */
408*5e7646d2SAndroid Build Coastguard Worker     host = gethostbyaddr((char *)&(addr->ipv4.sin_addr),
409*5e7646d2SAndroid Build Coastguard Worker                 	 sizeof(struct in_addr), AF_INET);
410*5e7646d2SAndroid Build Coastguard Worker 
411*5e7646d2SAndroid Build Coastguard Worker     if (host == NULL)
412*5e7646d2SAndroid Build Coastguard Worker     {
413*5e7646d2SAndroid Build Coastguard Worker      /*
414*5e7646d2SAndroid Build Coastguard Worker       * No hostname, so return the raw address...
415*5e7646d2SAndroid Build Coastguard Worker       */
416*5e7646d2SAndroid Build Coastguard Worker 
417*5e7646d2SAndroid Build Coastguard Worker       if (h_errno == NO_RECOVERY)
418*5e7646d2SAndroid Build Coastguard Worker         cg->need_res_init = 1;
419*5e7646d2SAndroid Build Coastguard Worker 
420*5e7646d2SAndroid Build Coastguard Worker       return (httpAddrString(addr, name, namelen));
421*5e7646d2SAndroid Build Coastguard Worker     }
422*5e7646d2SAndroid Build Coastguard Worker 
423*5e7646d2SAndroid Build Coastguard Worker     strlcpy(name, host->h_name, (size_t)namelen);
424*5e7646d2SAndroid Build Coastguard Worker   }
425*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_GETNAMEINFO */
426*5e7646d2SAndroid Build Coastguard Worker 
427*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("1httpAddrLookup: returning \"%s\"...", name));
428*5e7646d2SAndroid Build Coastguard Worker 
429*5e7646d2SAndroid Build Coastguard Worker   return (name);
430*5e7646d2SAndroid Build Coastguard Worker }
431*5e7646d2SAndroid Build Coastguard Worker 
432*5e7646d2SAndroid Build Coastguard Worker 
433*5e7646d2SAndroid Build Coastguard Worker /*
434*5e7646d2SAndroid Build Coastguard Worker  * 'httpAddrFamily()' - Get the address family of an address.
435*5e7646d2SAndroid Build Coastguard Worker  */
436*5e7646d2SAndroid Build Coastguard Worker 
437*5e7646d2SAndroid Build Coastguard Worker int					/* O - Address family */
httpAddrFamily(http_addr_t * addr)438*5e7646d2SAndroid Build Coastguard Worker httpAddrFamily(http_addr_t *addr)	/* I - Address */
439*5e7646d2SAndroid Build Coastguard Worker {
440*5e7646d2SAndroid Build Coastguard Worker   if (addr)
441*5e7646d2SAndroid Build Coastguard Worker     return (addr->addr.sa_family);
442*5e7646d2SAndroid Build Coastguard Worker   else
443*5e7646d2SAndroid Build Coastguard Worker     return (0);
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  * 'httpAddrPort()' - Get the port number associated with an address.
449*5e7646d2SAndroid Build Coastguard Worker  *
450*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 1.7/macOS 10.9@
451*5e7646d2SAndroid Build Coastguard Worker  */
452*5e7646d2SAndroid Build Coastguard Worker 
453*5e7646d2SAndroid Build Coastguard Worker int					/* O - Port number */
httpAddrPort(http_addr_t * addr)454*5e7646d2SAndroid Build Coastguard Worker httpAddrPort(http_addr_t *addr)		/* I - Address */
455*5e7646d2SAndroid Build Coastguard Worker {
456*5e7646d2SAndroid Build Coastguard Worker   if (!addr)
457*5e7646d2SAndroid Build Coastguard Worker     return (-1);
458*5e7646d2SAndroid Build Coastguard Worker #ifdef AF_INET6
459*5e7646d2SAndroid Build Coastguard Worker   else if (addr->addr.sa_family == AF_INET6)
460*5e7646d2SAndroid Build Coastguard Worker     return (ntohs(addr->ipv6.sin6_port));
461*5e7646d2SAndroid Build Coastguard Worker #endif /* AF_INET6 */
462*5e7646d2SAndroid Build Coastguard Worker   else if (addr->addr.sa_family == AF_INET)
463*5e7646d2SAndroid Build Coastguard Worker     return (ntohs(addr->ipv4.sin_port));
464*5e7646d2SAndroid Build Coastguard Worker   else
465*5e7646d2SAndroid Build Coastguard Worker     return (0);
466*5e7646d2SAndroid Build Coastguard Worker }
467*5e7646d2SAndroid Build Coastguard Worker 
468*5e7646d2SAndroid Build Coastguard Worker 
469*5e7646d2SAndroid Build Coastguard Worker /*
470*5e7646d2SAndroid Build Coastguard Worker  * '_httpAddrSetPort()' - Set the port number associated with an address.
471*5e7646d2SAndroid Build Coastguard Worker  */
472*5e7646d2SAndroid Build Coastguard Worker 
473*5e7646d2SAndroid Build Coastguard Worker void
_httpAddrSetPort(http_addr_t * addr,int port)474*5e7646d2SAndroid Build Coastguard Worker _httpAddrSetPort(http_addr_t *addr,	/* I - Address */
475*5e7646d2SAndroid Build Coastguard Worker                  int         port)	/* I - Port */
476*5e7646d2SAndroid Build Coastguard Worker {
477*5e7646d2SAndroid Build Coastguard Worker   if (!addr || port <= 0)
478*5e7646d2SAndroid Build Coastguard Worker     return;
479*5e7646d2SAndroid Build Coastguard Worker 
480*5e7646d2SAndroid Build Coastguard Worker #ifdef AF_INET6
481*5e7646d2SAndroid Build Coastguard Worker   if (addr->addr.sa_family == AF_INET6)
482*5e7646d2SAndroid Build Coastguard Worker     addr->ipv6.sin6_port = htons(port);
483*5e7646d2SAndroid Build Coastguard Worker   else
484*5e7646d2SAndroid Build Coastguard Worker #endif /* AF_INET6 */
485*5e7646d2SAndroid Build Coastguard Worker   if (addr->addr.sa_family == AF_INET)
486*5e7646d2SAndroid Build Coastguard Worker     addr->ipv4.sin_port = htons(port);
487*5e7646d2SAndroid Build Coastguard Worker }
488*5e7646d2SAndroid Build Coastguard Worker 
489*5e7646d2SAndroid Build Coastguard Worker 
490*5e7646d2SAndroid Build Coastguard Worker /*
491*5e7646d2SAndroid Build Coastguard Worker  * 'httpAddrString()' - Convert an address to a numeric string.
492*5e7646d2SAndroid Build Coastguard Worker  *
493*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 1.2/macOS 10.5@
494*5e7646d2SAndroid Build Coastguard Worker  */
495*5e7646d2SAndroid Build Coastguard Worker 
496*5e7646d2SAndroid Build Coastguard Worker char *					/* O - Numeric address string */
httpAddrString(const http_addr_t * addr,char * s,int slen)497*5e7646d2SAndroid Build Coastguard Worker httpAddrString(const http_addr_t *addr,	/* I - Address to convert */
498*5e7646d2SAndroid Build Coastguard Worker                char              *s,	/* I - String buffer */
499*5e7646d2SAndroid Build Coastguard Worker 	       int               slen)	/* I - Length of string */
500*5e7646d2SAndroid Build Coastguard Worker {
501*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("httpAddrString(addr=%p, s=%p, slen=%d)", (void *)addr, (void *)s, slen));
502*5e7646d2SAndroid Build Coastguard Worker 
503*5e7646d2SAndroid Build Coastguard Worker  /*
504*5e7646d2SAndroid Build Coastguard Worker   * Range check input...
505*5e7646d2SAndroid Build Coastguard Worker   */
506*5e7646d2SAndroid Build Coastguard Worker 
507*5e7646d2SAndroid Build Coastguard Worker   if (!addr || !s || slen <= 2)
508*5e7646d2SAndroid Build Coastguard Worker   {
509*5e7646d2SAndroid Build Coastguard Worker     if (s && slen >= 1)
510*5e7646d2SAndroid Build Coastguard Worker       *s = '\0';
511*5e7646d2SAndroid Build Coastguard Worker 
512*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
513*5e7646d2SAndroid Build Coastguard Worker   }
514*5e7646d2SAndroid Build Coastguard Worker 
515*5e7646d2SAndroid Build Coastguard Worker #ifdef AF_LOCAL
516*5e7646d2SAndroid Build Coastguard Worker   if (addr->addr.sa_family == AF_LOCAL)
517*5e7646d2SAndroid Build Coastguard Worker   {
518*5e7646d2SAndroid Build Coastguard Worker     if (addr->un.sun_path[0] == '/')
519*5e7646d2SAndroid Build Coastguard Worker       strlcpy(s, addr->un.sun_path, (size_t)slen);
520*5e7646d2SAndroid Build Coastguard Worker     else
521*5e7646d2SAndroid Build Coastguard Worker       strlcpy(s, "localhost", (size_t)slen);
522*5e7646d2SAndroid Build Coastguard Worker   }
523*5e7646d2SAndroid Build Coastguard Worker   else
524*5e7646d2SAndroid Build Coastguard Worker #endif /* AF_LOCAL */
525*5e7646d2SAndroid Build Coastguard Worker   if (addr->addr.sa_family == AF_INET)
526*5e7646d2SAndroid Build Coastguard Worker   {
527*5e7646d2SAndroid Build Coastguard Worker     unsigned temp;			/* Temporary address */
528*5e7646d2SAndroid Build Coastguard Worker 
529*5e7646d2SAndroid Build Coastguard Worker     temp = ntohl(addr->ipv4.sin_addr.s_addr);
530*5e7646d2SAndroid Build Coastguard Worker 
531*5e7646d2SAndroid Build Coastguard Worker     snprintf(s, (size_t)slen, "%d.%d.%d.%d", (temp >> 24) & 255,
532*5e7646d2SAndroid Build Coastguard Worker              (temp >> 16) & 255, (temp >> 8) & 255, temp & 255);
533*5e7646d2SAndroid Build Coastguard Worker   }
534*5e7646d2SAndroid Build Coastguard Worker #ifdef AF_INET6
535*5e7646d2SAndroid Build Coastguard Worker   else if (addr->addr.sa_family == AF_INET6)
536*5e7646d2SAndroid Build Coastguard Worker   {
537*5e7646d2SAndroid Build Coastguard Worker     char	*sptr,			/* Pointer into string */
538*5e7646d2SAndroid Build Coastguard Worker 		temps[64];		/* Temporary string for address */
539*5e7646d2SAndroid Build Coastguard Worker 
540*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_GETNAMEINFO
541*5e7646d2SAndroid Build Coastguard Worker     if (getnameinfo(&addr->addr, (socklen_t)httpAddrLength(addr), temps, sizeof(temps), NULL, 0, NI_NUMERICHOST))
542*5e7646d2SAndroid Build Coastguard Worker     {
543*5e7646d2SAndroid Build Coastguard Worker      /*
544*5e7646d2SAndroid Build Coastguard Worker       * If we get an error back, then the address type is not supported
545*5e7646d2SAndroid Build Coastguard Worker       * and we should zero out the buffer...
546*5e7646d2SAndroid Build Coastguard Worker       */
547*5e7646d2SAndroid Build Coastguard Worker 
548*5e7646d2SAndroid Build Coastguard Worker       s[0] = '\0';
549*5e7646d2SAndroid Build Coastguard Worker 
550*5e7646d2SAndroid Build Coastguard Worker       return (NULL);
551*5e7646d2SAndroid Build Coastguard Worker     }
552*5e7646d2SAndroid Build Coastguard Worker     else if ((sptr = strchr(temps, '%')) != NULL)
553*5e7646d2SAndroid Build Coastguard Worker     {
554*5e7646d2SAndroid Build Coastguard Worker      /*
555*5e7646d2SAndroid Build Coastguard Worker       * Convert "%zone" to "+zone" to match URI form...
556*5e7646d2SAndroid Build Coastguard Worker       */
557*5e7646d2SAndroid Build Coastguard Worker 
558*5e7646d2SAndroid Build Coastguard Worker       *sptr = '+';
559*5e7646d2SAndroid Build Coastguard Worker     }
560*5e7646d2SAndroid Build Coastguard Worker 
561*5e7646d2SAndroid Build Coastguard Worker #  else
562*5e7646d2SAndroid Build Coastguard Worker     int		i;			/* Looping var */
563*5e7646d2SAndroid Build Coastguard Worker     unsigned	temp;			/* Current value */
564*5e7646d2SAndroid Build Coastguard Worker     const char	*prefix;		/* Prefix for address */
565*5e7646d2SAndroid Build Coastguard Worker 
566*5e7646d2SAndroid Build Coastguard Worker 
567*5e7646d2SAndroid Build Coastguard Worker     prefix = "";
568*5e7646d2SAndroid Build Coastguard Worker     for (sptr = temps, i = 0; i < 4 && addr->ipv6.sin6_addr.s6_addr32[i]; i ++)
569*5e7646d2SAndroid Build Coastguard Worker     {
570*5e7646d2SAndroid Build Coastguard Worker       temp = ntohl(addr->ipv6.sin6_addr.s6_addr32[i]);
571*5e7646d2SAndroid Build Coastguard Worker 
572*5e7646d2SAndroid Build Coastguard Worker       snprintf(sptr, sizeof(temps) - (size_t)(sptr - temps), "%s%x", prefix, (temp >> 16) & 0xffff);
573*5e7646d2SAndroid Build Coastguard Worker       prefix = ":";
574*5e7646d2SAndroid Build Coastguard Worker       sptr += strlen(sptr);
575*5e7646d2SAndroid Build Coastguard Worker 
576*5e7646d2SAndroid Build Coastguard Worker       temp &= 0xffff;
577*5e7646d2SAndroid Build Coastguard Worker 
578*5e7646d2SAndroid Build Coastguard Worker       if (temp || i == 3 || addr->ipv6.sin6_addr.s6_addr32[i + 1])
579*5e7646d2SAndroid Build Coastguard Worker       {
580*5e7646d2SAndroid Build Coastguard Worker         snprintf(sptr, sizeof(temps) - (size_t)(sptr - temps), "%s%x", prefix, temp);
581*5e7646d2SAndroid Build Coastguard Worker 	sptr += strlen(sptr);
582*5e7646d2SAndroid Build Coastguard Worker       }
583*5e7646d2SAndroid Build Coastguard Worker     }
584*5e7646d2SAndroid Build Coastguard Worker 
585*5e7646d2SAndroid Build Coastguard Worker     if (i < 4)
586*5e7646d2SAndroid Build Coastguard Worker     {
587*5e7646d2SAndroid Build Coastguard Worker       while (i < 4 && !addr->ipv6.sin6_addr.s6_addr32[i])
588*5e7646d2SAndroid Build Coastguard Worker 	i ++;
589*5e7646d2SAndroid Build Coastguard Worker 
590*5e7646d2SAndroid Build Coastguard Worker       if (i < 4)
591*5e7646d2SAndroid Build Coastguard Worker       {
592*5e7646d2SAndroid Build Coastguard Worker         snprintf(sptr, sizeof(temps) - (size_t)(sptr - temps), "%s:", prefix);
593*5e7646d2SAndroid Build Coastguard Worker 	prefix = ":";
594*5e7646d2SAndroid Build Coastguard Worker 	sptr += strlen(sptr);
595*5e7646d2SAndroid Build Coastguard Worker 
596*5e7646d2SAndroid Build Coastguard Worker 	for (; i < 4; i ++)
597*5e7646d2SAndroid Build Coastguard Worker 	{
598*5e7646d2SAndroid Build Coastguard Worker           temp = ntohl(addr->ipv6.sin6_addr.s6_addr32[i]);
599*5e7646d2SAndroid Build Coastguard Worker 
600*5e7646d2SAndroid Build Coastguard Worker           if ((temp & 0xffff0000) ||
601*5e7646d2SAndroid Build Coastguard Worker 	      (i > 0 && addr->ipv6.sin6_addr.s6_addr32[i - 1]))
602*5e7646d2SAndroid Build Coastguard Worker 	  {
603*5e7646d2SAndroid Build Coastguard Worker             snprintf(sptr, sizeof(temps) - (size_t)(sptr - temps), "%s%x", prefix, (temp >> 16) & 0xffff);
604*5e7646d2SAndroid Build Coastguard Worker 	    sptr += strlen(sptr);
605*5e7646d2SAndroid Build Coastguard Worker           }
606*5e7646d2SAndroid Build Coastguard Worker 
607*5e7646d2SAndroid Build Coastguard Worker           snprintf(sptr, sizeof(temps) - (size_t)(sptr - temps), "%s%x", prefix, temp & 0xffff);
608*5e7646d2SAndroid Build Coastguard Worker 	  sptr += strlen(sptr);
609*5e7646d2SAndroid Build Coastguard Worker 	}
610*5e7646d2SAndroid Build Coastguard Worker       }
611*5e7646d2SAndroid Build Coastguard Worker       else if (sptr == s)
612*5e7646d2SAndroid Build Coastguard Worker       {
613*5e7646d2SAndroid Build Coastguard Worker        /*
614*5e7646d2SAndroid Build Coastguard Worker         * Empty address...
615*5e7646d2SAndroid Build Coastguard Worker 	*/
616*5e7646d2SAndroid Build Coastguard Worker 
617*5e7646d2SAndroid Build Coastguard Worker         strlcpy(temps, "::", sizeof(temps));
618*5e7646d2SAndroid Build Coastguard Worker       }
619*5e7646d2SAndroid Build Coastguard Worker       else
620*5e7646d2SAndroid Build Coastguard Worker       {
621*5e7646d2SAndroid Build Coastguard Worker        /*
622*5e7646d2SAndroid Build Coastguard Worker 	* Empty at end...
623*5e7646d2SAndroid Build Coastguard Worker 	*/
624*5e7646d2SAndroid Build Coastguard Worker 
625*5e7646d2SAndroid Build Coastguard Worker         strlcpy(sptr, "::", sizeof(temps) - (size_t)(sptr - temps));
626*5e7646d2SAndroid Build Coastguard Worker       }
627*5e7646d2SAndroid Build Coastguard Worker     }
628*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_GETNAMEINFO */
629*5e7646d2SAndroid Build Coastguard Worker 
630*5e7646d2SAndroid Build Coastguard Worker    /*
631*5e7646d2SAndroid Build Coastguard Worker     * Add "[v1." and "]" around IPv6 address to convert to URI form.
632*5e7646d2SAndroid Build Coastguard Worker     */
633*5e7646d2SAndroid Build Coastguard Worker 
634*5e7646d2SAndroid Build Coastguard Worker     snprintf(s, (size_t)slen, "[v1.%s]", temps);
635*5e7646d2SAndroid Build Coastguard Worker   }
636*5e7646d2SAndroid Build Coastguard Worker #endif /* AF_INET6 */
637*5e7646d2SAndroid Build Coastguard Worker   else
638*5e7646d2SAndroid Build Coastguard Worker     strlcpy(s, "UNKNOWN", (size_t)slen);
639*5e7646d2SAndroid Build Coastguard Worker 
640*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("1httpAddrString: returning \"%s\"...", s));
641*5e7646d2SAndroid Build Coastguard Worker 
642*5e7646d2SAndroid Build Coastguard Worker   return (s);
643*5e7646d2SAndroid Build Coastguard Worker }
644*5e7646d2SAndroid Build Coastguard Worker 
645*5e7646d2SAndroid Build Coastguard Worker 
646*5e7646d2SAndroid Build Coastguard Worker /*
647*5e7646d2SAndroid Build Coastguard Worker  * 'httpGetAddress()' - Get the address of the connected peer of a connection.
648*5e7646d2SAndroid Build Coastguard Worker  *
649*5e7646d2SAndroid Build Coastguard Worker  * For connections created with @link httpConnect2@, the address is for the
650*5e7646d2SAndroid Build Coastguard Worker  * server.  For connections created with @link httpAccept@, the address is for
651*5e7646d2SAndroid Build Coastguard Worker  * the client.
652*5e7646d2SAndroid Build Coastguard Worker  *
653*5e7646d2SAndroid Build Coastguard Worker  * Returns @code NULL@ if the socket is currently unconnected.
654*5e7646d2SAndroid Build Coastguard Worker  *
655*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 2.0/OS 10.10@
656*5e7646d2SAndroid Build Coastguard Worker  */
657*5e7646d2SAndroid Build Coastguard Worker 
658*5e7646d2SAndroid Build Coastguard Worker http_addr_t *				/* O - Connected address or @code NULL@ */
httpGetAddress(http_t * http)659*5e7646d2SAndroid Build Coastguard Worker httpGetAddress(http_t *http)		/* I - HTTP connection */
660*5e7646d2SAndroid Build Coastguard Worker {
661*5e7646d2SAndroid Build Coastguard Worker   if (http)
662*5e7646d2SAndroid Build Coastguard Worker     return (http->hostaddr);
663*5e7646d2SAndroid Build Coastguard Worker   else
664*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
665*5e7646d2SAndroid Build Coastguard Worker }
666*5e7646d2SAndroid Build Coastguard Worker 
667*5e7646d2SAndroid Build Coastguard Worker 
668*5e7646d2SAndroid Build Coastguard Worker /*
669*5e7646d2SAndroid Build Coastguard Worker  * 'httpGetHostByName()' - Lookup a hostname or IPv4 address, and return
670*5e7646d2SAndroid Build Coastguard Worker  *                         address records for the specified name.
671*5e7646d2SAndroid Build Coastguard Worker  *
672*5e7646d2SAndroid Build Coastguard Worker  * @deprecated@ @exclude all@
673*5e7646d2SAndroid Build Coastguard Worker  */
674*5e7646d2SAndroid Build Coastguard Worker 
675*5e7646d2SAndroid Build Coastguard Worker struct hostent *			/* O - Host entry */
httpGetHostByName(const char * name)676*5e7646d2SAndroid Build Coastguard Worker httpGetHostByName(const char *name)	/* I - Hostname or IP address */
677*5e7646d2SAndroid Build Coastguard Worker {
678*5e7646d2SAndroid Build Coastguard Worker   const char		*nameptr;	/* Pointer into name */
679*5e7646d2SAndroid Build Coastguard Worker   unsigned		ip[4];		/* IP address components */
680*5e7646d2SAndroid Build Coastguard Worker   _cups_globals_t	*cg = _cupsGlobals();
681*5e7646d2SAndroid Build Coastguard Worker   					/* Pointer to library globals */
682*5e7646d2SAndroid Build Coastguard Worker 
683*5e7646d2SAndroid Build Coastguard Worker 
684*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("httpGetHostByName(name=\"%s\")", name));
685*5e7646d2SAndroid Build Coastguard Worker 
686*5e7646d2SAndroid Build Coastguard Worker  /*
687*5e7646d2SAndroid Build Coastguard Worker   * Avoid lookup delays and configuration problems when connecting
688*5e7646d2SAndroid Build Coastguard Worker   * to the localhost address...
689*5e7646d2SAndroid Build Coastguard Worker   */
690*5e7646d2SAndroid Build Coastguard Worker 
691*5e7646d2SAndroid Build Coastguard Worker   if (!strcmp(name, "localhost"))
692*5e7646d2SAndroid Build Coastguard Worker     name = "127.0.0.1";
693*5e7646d2SAndroid Build Coastguard Worker 
694*5e7646d2SAndroid Build Coastguard Worker  /*
695*5e7646d2SAndroid Build Coastguard Worker   * This function is needed because some operating systems have a
696*5e7646d2SAndroid Build Coastguard Worker   * buggy implementation of gethostbyname() that does not support
697*5e7646d2SAndroid Build Coastguard Worker   * IP addresses.  If the first character of the name string is a
698*5e7646d2SAndroid Build Coastguard Worker   * number, then sscanf() is used to extract the IP components.
699*5e7646d2SAndroid Build Coastguard Worker   * We then pack the components into an IPv4 address manually,
700*5e7646d2SAndroid Build Coastguard Worker   * since the inet_aton() function is deprecated.  We use the
701*5e7646d2SAndroid Build Coastguard Worker   * htonl() macro to get the right byte order for the address.
702*5e7646d2SAndroid Build Coastguard Worker   *
703*5e7646d2SAndroid Build Coastguard Worker   * We also support domain sockets when supported by the underlying
704*5e7646d2SAndroid Build Coastguard Worker   * OS...
705*5e7646d2SAndroid Build Coastguard Worker   */
706*5e7646d2SAndroid Build Coastguard Worker 
707*5e7646d2SAndroid Build Coastguard Worker #ifdef AF_LOCAL
708*5e7646d2SAndroid Build Coastguard Worker   if (name[0] == '/')
709*5e7646d2SAndroid Build Coastguard Worker   {
710*5e7646d2SAndroid Build Coastguard Worker    /*
711*5e7646d2SAndroid Build Coastguard Worker     * A domain socket address, so make an AF_LOCAL entry and return it...
712*5e7646d2SAndroid Build Coastguard Worker     */
713*5e7646d2SAndroid Build Coastguard Worker 
714*5e7646d2SAndroid Build Coastguard Worker     cg->hostent.h_name      = (char *)name;
715*5e7646d2SAndroid Build Coastguard Worker     cg->hostent.h_aliases   = NULL;
716*5e7646d2SAndroid Build Coastguard Worker     cg->hostent.h_addrtype  = AF_LOCAL;
717*5e7646d2SAndroid Build Coastguard Worker     cg->hostent.h_length    = (int)strlen(name) + 1;
718*5e7646d2SAndroid Build Coastguard Worker     cg->hostent.h_addr_list = cg->ip_ptrs;
719*5e7646d2SAndroid Build Coastguard Worker     cg->ip_ptrs[0]          = (char *)name;
720*5e7646d2SAndroid Build Coastguard Worker     cg->ip_ptrs[1]          = NULL;
721*5e7646d2SAndroid Build Coastguard Worker 
722*5e7646d2SAndroid Build Coastguard Worker     DEBUG_puts("1httpGetHostByName: returning domain socket address...");
723*5e7646d2SAndroid Build Coastguard Worker 
724*5e7646d2SAndroid Build Coastguard Worker     return (&cg->hostent);
725*5e7646d2SAndroid Build Coastguard Worker   }
726*5e7646d2SAndroid Build Coastguard Worker #endif /* AF_LOCAL */
727*5e7646d2SAndroid Build Coastguard Worker 
728*5e7646d2SAndroid Build Coastguard Worker   for (nameptr = name; isdigit(*nameptr & 255) || *nameptr == '.'; nameptr ++);
729*5e7646d2SAndroid Build Coastguard Worker 
730*5e7646d2SAndroid Build Coastguard Worker   if (!*nameptr)
731*5e7646d2SAndroid Build Coastguard Worker   {
732*5e7646d2SAndroid Build Coastguard Worker    /*
733*5e7646d2SAndroid Build Coastguard Worker     * We have an IPv4 address; break it up and provide the host entry
734*5e7646d2SAndroid Build Coastguard Worker     * to the caller.
735*5e7646d2SAndroid Build Coastguard Worker     */
736*5e7646d2SAndroid Build Coastguard Worker 
737*5e7646d2SAndroid Build Coastguard Worker     if (sscanf(name, "%u.%u.%u.%u", ip, ip + 1, ip + 2, ip + 3) != 4)
738*5e7646d2SAndroid Build Coastguard Worker       return (NULL);			/* Must have 4 numbers */
739*5e7646d2SAndroid Build Coastguard Worker 
740*5e7646d2SAndroid Build Coastguard Worker     if (ip[0] > 255 || ip[1] > 255 || ip[2] > 255 || ip[3] > 255)
741*5e7646d2SAndroid Build Coastguard Worker       return (NULL);			/* Invalid byte ranges! */
742*5e7646d2SAndroid Build Coastguard Worker 
743*5e7646d2SAndroid Build Coastguard Worker     cg->ip_addr = htonl((((((((unsigned)ip[0] << 8) | (unsigned)ip[1]) << 8) |
744*5e7646d2SAndroid Build Coastguard Worker                            (unsigned)ip[2]) << 8) |
745*5e7646d2SAndroid Build Coastguard Worker                          (unsigned)ip[3]));
746*5e7646d2SAndroid Build Coastguard Worker 
747*5e7646d2SAndroid Build Coastguard Worker    /*
748*5e7646d2SAndroid Build Coastguard Worker     * Fill in the host entry and return it...
749*5e7646d2SAndroid Build Coastguard Worker     */
750*5e7646d2SAndroid Build Coastguard Worker 
751*5e7646d2SAndroid Build Coastguard Worker     cg->hostent.h_name      = (char *)name;
752*5e7646d2SAndroid Build Coastguard Worker     cg->hostent.h_aliases   = NULL;
753*5e7646d2SAndroid Build Coastguard Worker     cg->hostent.h_addrtype  = AF_INET;
754*5e7646d2SAndroid Build Coastguard Worker     cg->hostent.h_length    = 4;
755*5e7646d2SAndroid Build Coastguard Worker     cg->hostent.h_addr_list = cg->ip_ptrs;
756*5e7646d2SAndroid Build Coastguard Worker     cg->ip_ptrs[0]          = (char *)&(cg->ip_addr);
757*5e7646d2SAndroid Build Coastguard Worker     cg->ip_ptrs[1]          = NULL;
758*5e7646d2SAndroid Build Coastguard Worker 
759*5e7646d2SAndroid Build Coastguard Worker     DEBUG_puts("1httpGetHostByName: returning IPv4 address...");
760*5e7646d2SAndroid Build Coastguard Worker 
761*5e7646d2SAndroid Build Coastguard Worker     return (&cg->hostent);
762*5e7646d2SAndroid Build Coastguard Worker   }
763*5e7646d2SAndroid Build Coastguard Worker   else
764*5e7646d2SAndroid Build Coastguard Worker   {
765*5e7646d2SAndroid Build Coastguard Worker    /*
766*5e7646d2SAndroid Build Coastguard Worker     * Use the gethostbyname() function to get the IPv4 address for
767*5e7646d2SAndroid Build Coastguard Worker     * the name...
768*5e7646d2SAndroid Build Coastguard Worker     */
769*5e7646d2SAndroid Build Coastguard Worker 
770*5e7646d2SAndroid Build Coastguard Worker     DEBUG_puts("1httpGetHostByName: returning domain lookup address(es)...");
771*5e7646d2SAndroid Build Coastguard Worker 
772*5e7646d2SAndroid Build Coastguard Worker     return (gethostbyname(name));
773*5e7646d2SAndroid Build Coastguard Worker   }
774*5e7646d2SAndroid Build Coastguard Worker }
775*5e7646d2SAndroid Build Coastguard Worker 
776*5e7646d2SAndroid Build Coastguard Worker 
777*5e7646d2SAndroid Build Coastguard Worker /*
778*5e7646d2SAndroid Build Coastguard Worker  * 'httpGetHostname()' - Get the FQDN for the connection or local system.
779*5e7646d2SAndroid Build Coastguard Worker  *
780*5e7646d2SAndroid Build Coastguard Worker  * When "http" points to a connected socket, return the hostname or
781*5e7646d2SAndroid Build Coastguard Worker  * address that was used in the call to httpConnect() or httpConnectEncrypt(),
782*5e7646d2SAndroid Build Coastguard Worker  * or the address of the client for the connection from httpAcceptConnection().
783*5e7646d2SAndroid Build Coastguard Worker  * Otherwise, return the FQDN for the local system using both gethostname()
784*5e7646d2SAndroid Build Coastguard Worker  * and gethostbyname() to get the local hostname with domain.
785*5e7646d2SAndroid Build Coastguard Worker  *
786*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 1.2/macOS 10.5@
787*5e7646d2SAndroid Build Coastguard Worker  */
788*5e7646d2SAndroid Build Coastguard Worker 
789*5e7646d2SAndroid Build Coastguard Worker const char *				/* O - FQDN for connection or system */
httpGetHostname(http_t * http,char * s,int slen)790*5e7646d2SAndroid Build Coastguard Worker httpGetHostname(http_t *http,		/* I - HTTP connection or NULL */
791*5e7646d2SAndroid Build Coastguard Worker                 char   *s,		/* I - String buffer for name */
792*5e7646d2SAndroid Build Coastguard Worker                 int    slen)		/* I - Size of buffer */
793*5e7646d2SAndroid Build Coastguard Worker {
794*5e7646d2SAndroid Build Coastguard Worker   if (http)
795*5e7646d2SAndroid Build Coastguard Worker   {
796*5e7646d2SAndroid Build Coastguard Worker     if (!s || slen <= 1)
797*5e7646d2SAndroid Build Coastguard Worker     {
798*5e7646d2SAndroid Build Coastguard Worker       if (http->hostname[0] == '/')
799*5e7646d2SAndroid Build Coastguard Worker 	return ("localhost");
800*5e7646d2SAndroid Build Coastguard Worker       else
801*5e7646d2SAndroid Build Coastguard Worker 	return (http->hostname);
802*5e7646d2SAndroid Build Coastguard Worker     }
803*5e7646d2SAndroid Build Coastguard Worker     else if (http->hostname[0] == '/')
804*5e7646d2SAndroid Build Coastguard Worker       strlcpy(s, "localhost", (size_t)slen);
805*5e7646d2SAndroid Build Coastguard Worker     else
806*5e7646d2SAndroid Build Coastguard Worker       strlcpy(s, http->hostname, (size_t)slen);
807*5e7646d2SAndroid Build Coastguard Worker   }
808*5e7646d2SAndroid Build Coastguard Worker   else
809*5e7646d2SAndroid Build Coastguard Worker   {
810*5e7646d2SAndroid Build Coastguard Worker    /*
811*5e7646d2SAndroid Build Coastguard Worker     * Get the hostname...
812*5e7646d2SAndroid Build Coastguard Worker     */
813*5e7646d2SAndroid Build Coastguard Worker 
814*5e7646d2SAndroid Build Coastguard Worker     if (!s || slen <= 1)
815*5e7646d2SAndroid Build Coastguard Worker       return (NULL);
816*5e7646d2SAndroid Build Coastguard Worker 
817*5e7646d2SAndroid Build Coastguard Worker     if (gethostname(s, (size_t)slen) < 0)
818*5e7646d2SAndroid Build Coastguard Worker       strlcpy(s, "localhost", (size_t)slen);
819*5e7646d2SAndroid Build Coastguard Worker 
820*5e7646d2SAndroid Build Coastguard Worker     if (!strchr(s, '.'))
821*5e7646d2SAndroid Build Coastguard Worker     {
822*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME
823*5e7646d2SAndroid Build Coastguard Worker      /*
824*5e7646d2SAndroid Build Coastguard Worker       * The hostname is not a FQDN, so use the local hostname from the
825*5e7646d2SAndroid Build Coastguard Worker       * SystemConfiguration framework...
826*5e7646d2SAndroid Build Coastguard Worker       */
827*5e7646d2SAndroid Build Coastguard Worker 
828*5e7646d2SAndroid Build Coastguard Worker       SCDynamicStoreRef	sc = SCDynamicStoreCreate(kCFAllocatorDefault,
829*5e7646d2SAndroid Build Coastguard Worker                                                   CFSTR("libcups"), NULL, NULL);
830*5e7646d2SAndroid Build Coastguard Worker 					/* System configuration data */
831*5e7646d2SAndroid Build Coastguard Worker       CFStringRef	local = sc ? SCDynamicStoreCopyLocalHostName(sc) : NULL;
832*5e7646d2SAndroid Build Coastguard Worker 					/* Local host name */
833*5e7646d2SAndroid Build Coastguard Worker       char		localStr[1024];	/* Local host name C string */
834*5e7646d2SAndroid Build Coastguard Worker 
835*5e7646d2SAndroid Build Coastguard Worker       if (local && CFStringGetCString(local, localStr, sizeof(localStr),
836*5e7646d2SAndroid Build Coastguard Worker                                       kCFStringEncodingUTF8))
837*5e7646d2SAndroid Build Coastguard Worker       {
838*5e7646d2SAndroid Build Coastguard Worker        /*
839*5e7646d2SAndroid Build Coastguard Worker         * Append ".local." to the hostname we get...
840*5e7646d2SAndroid Build Coastguard Worker 	*/
841*5e7646d2SAndroid Build Coastguard Worker 
842*5e7646d2SAndroid Build Coastguard Worker         snprintf(s, (size_t)slen, "%s.local.", localStr);
843*5e7646d2SAndroid Build Coastguard Worker       }
844*5e7646d2SAndroid Build Coastguard Worker 
845*5e7646d2SAndroid Build Coastguard Worker       if (local)
846*5e7646d2SAndroid Build Coastguard Worker         CFRelease(local);
847*5e7646d2SAndroid Build Coastguard Worker       if (sc)
848*5e7646d2SAndroid Build Coastguard Worker         CFRelease(sc);
849*5e7646d2SAndroid Build Coastguard Worker 
850*5e7646d2SAndroid Build Coastguard Worker #else
851*5e7646d2SAndroid Build Coastguard Worker      /*
852*5e7646d2SAndroid Build Coastguard Worker       * The hostname is not a FQDN, so look it up...
853*5e7646d2SAndroid Build Coastguard Worker       */
854*5e7646d2SAndroid Build Coastguard Worker 
855*5e7646d2SAndroid Build Coastguard Worker       struct hostent	*host;		/* Host entry to get FQDN */
856*5e7646d2SAndroid Build Coastguard Worker 
857*5e7646d2SAndroid Build Coastguard Worker       if ((host = gethostbyname(s)) != NULL && host->h_name)
858*5e7646d2SAndroid Build Coastguard Worker       {
859*5e7646d2SAndroid Build Coastguard Worker        /*
860*5e7646d2SAndroid Build Coastguard Worker         * Use the resolved hostname...
861*5e7646d2SAndroid Build Coastguard Worker 	*/
862*5e7646d2SAndroid Build Coastguard Worker 
863*5e7646d2SAndroid Build Coastguard Worker 	strlcpy(s, host->h_name, (size_t)slen);
864*5e7646d2SAndroid Build Coastguard Worker       }
865*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME */
866*5e7646d2SAndroid Build Coastguard Worker     }
867*5e7646d2SAndroid Build Coastguard Worker 
868*5e7646d2SAndroid Build Coastguard Worker    /*
869*5e7646d2SAndroid Build Coastguard Worker     * Make sure .local hostnames end with a period...
870*5e7646d2SAndroid Build Coastguard Worker     */
871*5e7646d2SAndroid Build Coastguard Worker 
872*5e7646d2SAndroid Build Coastguard Worker     if (strlen(s) > 6 && !strcmp(s + strlen(s) - 6, ".local"))
873*5e7646d2SAndroid Build Coastguard Worker       strlcat(s, ".", (size_t)slen);
874*5e7646d2SAndroid Build Coastguard Worker   }
875*5e7646d2SAndroid Build Coastguard Worker 
876*5e7646d2SAndroid Build Coastguard Worker  /*
877*5e7646d2SAndroid Build Coastguard Worker   * Convert the hostname to lowercase as needed...
878*5e7646d2SAndroid Build Coastguard Worker   */
879*5e7646d2SAndroid Build Coastguard Worker 
880*5e7646d2SAndroid Build Coastguard Worker   if (s[0] != '/')
881*5e7646d2SAndroid Build Coastguard Worker   {
882*5e7646d2SAndroid Build Coastguard Worker     char	*ptr;			/* Pointer into string */
883*5e7646d2SAndroid Build Coastguard Worker 
884*5e7646d2SAndroid Build Coastguard Worker     for (ptr = s; *ptr; ptr ++)
885*5e7646d2SAndroid Build Coastguard Worker       *ptr = (char)_cups_tolower((int)*ptr);
886*5e7646d2SAndroid Build Coastguard Worker   }
887*5e7646d2SAndroid Build Coastguard Worker 
888*5e7646d2SAndroid Build Coastguard Worker  /*
889*5e7646d2SAndroid Build Coastguard Worker   * Return the hostname with as much domain info as we have...
890*5e7646d2SAndroid Build Coastguard Worker   */
891*5e7646d2SAndroid Build Coastguard Worker 
892*5e7646d2SAndroid Build Coastguard Worker   return (s);
893*5e7646d2SAndroid Build Coastguard Worker }
894*5e7646d2SAndroid Build Coastguard Worker 
895*5e7646d2SAndroid Build Coastguard Worker 
896*5e7646d2SAndroid Build Coastguard Worker /*
897*5e7646d2SAndroid Build Coastguard Worker  * 'httpResolveHostname()' - Resolve the hostname of the HTTP connection
898*5e7646d2SAndroid Build Coastguard Worker  *                           address.
899*5e7646d2SAndroid Build Coastguard Worker  *
900*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 2.0/OS 10.10@
901*5e7646d2SAndroid Build Coastguard Worker  */
902*5e7646d2SAndroid Build Coastguard Worker 
903*5e7646d2SAndroid Build Coastguard Worker const char *				/* O - Resolved hostname or @code NULL@ */
httpResolveHostname(http_t * http,char * buffer,size_t bufsize)904*5e7646d2SAndroid Build Coastguard Worker httpResolveHostname(http_t *http,	/* I - HTTP connection */
905*5e7646d2SAndroid Build Coastguard Worker                     char   *buffer,	/* I - Hostname buffer */
906*5e7646d2SAndroid Build Coastguard Worker                     size_t bufsize)	/* I - Size of buffer */
907*5e7646d2SAndroid Build Coastguard Worker {
908*5e7646d2SAndroid Build Coastguard Worker   if (!http)
909*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
910*5e7646d2SAndroid Build Coastguard Worker 
911*5e7646d2SAndroid Build Coastguard Worker   if (isdigit(http->hostname[0] & 255) || http->hostname[0] == '[')
912*5e7646d2SAndroid Build Coastguard Worker   {
913*5e7646d2SAndroid Build Coastguard Worker     char	temp[1024];		/* Temporary string */
914*5e7646d2SAndroid Build Coastguard Worker 
915*5e7646d2SAndroid Build Coastguard Worker     if (httpAddrLookup(http->hostaddr, temp, sizeof(temp)))
916*5e7646d2SAndroid Build Coastguard Worker       strlcpy(http->hostname, temp, sizeof(http->hostname));
917*5e7646d2SAndroid Build Coastguard Worker     else
918*5e7646d2SAndroid Build Coastguard Worker       return (NULL);
919*5e7646d2SAndroid Build Coastguard Worker   }
920*5e7646d2SAndroid Build Coastguard Worker 
921*5e7646d2SAndroid Build Coastguard Worker   if (buffer)
922*5e7646d2SAndroid Build Coastguard Worker   {
923*5e7646d2SAndroid Build Coastguard Worker     if (http->hostname[0] == '/')
924*5e7646d2SAndroid Build Coastguard Worker       strlcpy(buffer, "localhost", bufsize);
925*5e7646d2SAndroid Build Coastguard Worker     else
926*5e7646d2SAndroid Build Coastguard Worker       strlcpy(buffer, http->hostname, bufsize);
927*5e7646d2SAndroid Build Coastguard Worker 
928*5e7646d2SAndroid Build Coastguard Worker     return (buffer);
929*5e7646d2SAndroid Build Coastguard Worker   }
930*5e7646d2SAndroid Build Coastguard Worker   else if (http->hostname[0] == '/')
931*5e7646d2SAndroid Build Coastguard Worker     return ("localhost");
932*5e7646d2SAndroid Build Coastguard Worker   else
933*5e7646d2SAndroid Build Coastguard Worker     return (http->hostname);
934*5e7646d2SAndroid Build Coastguard Worker }
935