if (errno != EADDRINUSE)
{
-# ifdef WIN32
- closesocket(fd);
-# else
- close(fd);
-# endif /* WIN32 */
+ httpAddrClose(NULL, fd);
return (-1);
}
if (mode == 's')
{
- if (closesocket(fd) < 0)
+ if (httpAddrClose(NULL, fd) < 0)
status = -1;
}
else if (!is_stdio)
if ((fp = cupsFileOpenFd(fd, mode)) == NULL)
{
if (*mode == 's')
- closesocket(fd);
+ httpAddrClose(NULL, fd);
else
close(fd);
}
*/
#include "cups-private.h"
+#include <sys/stat.h>
#ifdef HAVE_RESOLV_H
# include <resolv.h>
#endif /* HAVE_RESOLV_H */
}
+/*
+ * 'httpAddrClose()' - Close a socket created by @link httpAddrConnect@ or
+ * @link httpAddrListen@.
+ *
+ * Pass @code NULL@ for sockets created with @link httpAddrConnect@ and the
+ * listen address for sockets created with @link httpAddrListen@. This will
+ * ensure that domain sockets are removed when closed.
+ *
+ * @since CUPS 2.0@
+ */
+
+int /* O - 0 on success, -1 on failure */
+httpAddrClose(http_addr_t *addr, /* I - Listen address or @code NULL@ */
+ int fd) /* I - Socket file descriptor */
+{
+#ifdef WIN32
+ if (closesocket(fd))
+#else
+ if (close(fd))
+#endif /* WIN32 */
+ return (-1);
+
+#ifdef AF_LOCAL
+ if (addr && addr->addr.sa_family == AF_LOCAL)
+ return (unlink(addr->un.sun_path));
+#endif /* AF_LOCAL */
+
+ return (0);
+}
+
+
/*
* 'httpAddrEqual()' - Compare two addresses.
*
int port) /* I - Port number to bind to */
{
int fd = -1, /* Socket */
- val; /* Socket value */
+ val, /* Socket value */
+ status; /* Bind status */
/*
* Range check input...
*/
- if (!addr || port <= 0)
+ if (!addr || port < 0)
return (-1);
+ /*
+ * Create the socket and set options...
+ */
+
if ((fd = socket(addr->addr.sa_family, SOCK_STREAM, 0)) < 0)
{
_cupsSetHTTPError(HTTP_STATUS_ERROR);
setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, CUPS_SOCAST &val, sizeof(val));
#endif /* IPV6_V6ONLY */
- _httpAddrSetPort(addr, port);
+ /*
+ * Bind the socket...
+ */
+
+#ifdef AF_LOCAL
+ if (addr->addr.sa_family == AF_LOCAL)
+ {
+ mode_t mask; /* Umask setting */
+
+ /*
+ * Remove any existing domain socket file...
+ */
+
+ unlink(addr->un.sun_path);
+
+ /*
+ * Save the current umask and set it to 0 so that all users can access
+ * the domain socket...
+ */
+
+ mask = umask(0);
+
+ /*
+ * Bind the domain socket...
+ */
+
+ status = bind(fd, (struct sockaddr *)addr, httpAddrLength(addr));
+
+ /*
+ * Restore the umask and fix permissions...
+ */
- if (bind(fd, (struct sockaddr *)addr, httpAddrLength(addr)))
+ umask(mask);
+ chmod(addr->un.sun_path, 0140777);
+ }
+ else
+#endif /* AF_LOCAL */
+ {
+ _httpAddrSetPort(addr, port);
+
+ status = bind(fd, (struct sockaddr *)addr, httpAddrLength(addr));
+ }
+
+ if (status)
{
_cupsSetHTTPError(HTTP_STATUS_ERROR);
return (-1);
}
+ /*
+ * Listen...
+ */
+
if (listen(fd, 5))
{
_cupsSetHTTPError(HTTP_STATUS_ERROR);
return (-1);
}
+ /*
+ * Close on exec...
+ */
+
+#ifndef WIN32
+ fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+#endif /* !WIN32 */
+
#ifdef SO_NOSIGPIPE
/*
* Disable SIGPIPE for this socket.
DEBUG_puts("1httpAddrConnect2: Canceled connect()");
-# ifdef WIN32
- closesocket(*sock);
-# else
- close(*sock);
-# endif /* WIN32 */
+ httpAddrClose(NULL, *sock);
*sock = -1;
* Close this socket and move to the next address...
*/
-#ifdef WIN32
- closesocket(*sock);
-#else
- close(*sock);
-#endif /* WIN32 */
+ httpAddrClose(NULL, *sock);
*sock = -1;
addrlist = addrlist->next;
# include <unistd.h>
# include <fcntl.h>
# include <sys/socket.h>
-# define closesocket(f) close(f)
# define CUPS_SOCAST
# endif /* WIN32 */
http_shutdown_ssl(http);
#endif /* HAVE_SSL */
-#ifdef WIN32
- closesocket(http->fd);
-#else
- close(http->fd);
-#endif /* WIN32 */
+ httpAddrClose(NULL, http->fd);
http->fd = -1;
}
http_shutdown_ssl(http);
#endif /* HAVE_SSL */
-#ifdef WIN32
- closesocket(http->fd);
-#else
- close(http->fd);
-#endif /* WIN32 */
+ httpAddrClose(NULL, http->fd);
http->fd = -1;
}
{
DEBUG_printf(("2httpReconnect2: Closing socket %d...", http->fd));
-#ifdef WIN32
- closesocket(http->fd);
-#else
- close(http->fd);
-#endif /* WIN32 */
+ httpAddrClose(NULL, http->fd);
http->fd = -1;
}
if (http_setup_ssl(http) != 0)
{
-# ifdef WIN32
- closesocket(http->fd);
-# else
- close(http->fd);
-# endif /* WIN32 */
+ httpAddrClose(NULL, http->fd);
return (-1);
}
{
if (http_setup_ssl(http) != 0)
{
-# ifdef WIN32
- closesocket(http->fd);
-# else
- close(http->fd);
-# endif /* WIN32 */
+ httpAddrClose(NULL, http->fd);
*status = http->status = HTTP_STATUS_ERROR;
return (0);
DEBUG_puts("8http_upgrade: Server does not support HTTP upgrade!");
-# ifdef WIN32
- closesocket(http->fd);
-# else
- close(http->fd);
-# endif
+ httpAddrClose(NULL, http->fd);
http->fd = -1;
/**** New in CUPS 2.0 ****/
+extern int httpAddrClose(http_addr_t *addr, int fd) _CUPS_API_2_0;
extern int httpAddrFamily(http_addr_t *addr) _CUPS_API_2_0;
extern http_field_t httpFieldValue(const char *name) _CUPS_API_2_0;
extern time_t httpGetActivity(http_t *http) _CUPS_API_2_0;
/*
* "$Id$"
*
- * SNMP functions for CUPS.
+ * SNMP functions for CUPS.
*
- * Copyright 2007-2011 by Apple Inc.
- * Copyright 2006-2007 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2013 by Apple Inc.
+ * Copyright 2006-2007 by Easy Software Products, all rights reserved.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * "LICENSE" which should have been included with this file. If this
- * file is missing or damaged, see the license at "http://www.cups.org/".
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * "LICENSE" which should have been included with this file. If this
+ * file is missing or damaged, see the license at "http://www.cups.org/".
*
- * This file is subject to the Apple OS-Developed Software exception.
- *
- * Contents:
- *
- * _cupsSNMPClose() - Close a SNMP socket.
- * _cupsSNMPCopyOID() - Copy an OID.
- * _cupsSNMPDefaultCommunity() - Get the default SNMP community name.
- * _cupsSNMPIsOID() - Test whether a SNMP response contains the
- * specified OID.
- * _cupsSNMPIsOIDPrefixed() - Test whether a SNMP response uses the
- * specified OID prefix.
- * _cupsSNMPOIDToString() - Convert an OID to a string.
- * _cupsSNMPOpen() - Open a SNMP socket.
- * _cupsSNMPRead() - Read and parse a SNMP response.
- * _cupsSNMPSetDebug() - Enable/disable debug logging to stderr.
- * _cupsSNMPStringToOID() - Convert a numeric OID string to an OID array.
- * _cupsSNMPWalk() - Enumerate a group of OIDs.
- * _cupsSNMPWrite() - Send an SNMP query packet.
- * asn1_debug() - Decode an ASN1-encoded message.
- * asn1_decode_snmp() - Decode a SNMP packet.
- * asn1_encode_snmp() - Encode a SNMP packet.
- * asn1_get_integer() - Get an integer value.
- * asn1_get_length() - Get a value length.
- * asn1_get_oid() - Get an OID value.
- * asn1_get_packed() - Get a packed integer value.
- * asn1_get_string() - Get a string value.
- * asn1_get_type() - Get a value type.
- * asn1_set_integer() - Set an integer value.
- * asn1_set_length() - Set a value length.
- * asn1_set_oid() - Set an OID value.
- * asn1_set_packed() - Set a packed integer value.
- * asn1_size_integer() - Figure out the number of bytes needed for an
- * integer value.
- * asn1_size_length() - Figure out the number of bytes needed for a
- * length value.
- * asn1_size_oid() - Figure out the numebr of bytes needed for an
- * OID value.
- * asn1_size_packed() - Figure out the number of bytes needed for a
- * packed integer value.
- * snmp_set_error() - Set the localized error for a packet.
+ * This file is subject to the Apple OS-Developed Software exception.
*/
/*
{
DEBUG_printf(("4_cupsSNMPClose(fd=%d)", fd));
-#ifdef WIN32
- closesocket(fd);
-#else
- close(fd);
-#endif /* WIN32 */
+ httpAddrClose(NULL, fd);
}
/*
* "$Id$"
*
- * Server listening routines for the CUPS scheduler.
+ * Server listening routines for the CUPS scheduler.
*
- * Copyright 2007-2010 by Apple Inc.
- * Copyright 1997-2006 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2013 by Apple Inc.
+ * Copyright 1997-2006 by Easy Software Products, all rights reserved.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * Contents:
- *
- * cupsdDeleteAllListeners() - Delete all listeners.
- * cupsdPauseListening() - Clear input polling on all listening sockets...
- * cupsdResumeListening() - Set input polling on all listening sockets...
- * cupsdStartListening() - Create all listening sockets...
- * cupsdStopListening() - Close all listening sockets...
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file. If this file is
+ * file is missing or damaged, see the license at "http://www.cups.org/".
*/
/*
void
cupsdStartListening(void)
{
- int status; /* Bind result */
- int p, /* Port number */
- val; /* Parameter value */
+ int p; /* Port number */
cupsd_listener_t *lis; /* Current listening socket */
char s[256]; /* String addresss */
const char *have_domain; /* Have a domain socket? */
* Create a socket for listening...
*/
- lis->fd = socket(lis->address.addr.sa_family, SOCK_STREAM, 0);
+ lis->fd = httpAddrListen(&(lis->address), p);
if (lis->fd == -1)
{
continue;
}
-
- /*
- * Set things up to reuse the local address for this port.
- */
-
- val = 1;
-#ifdef __sun
- setsockopt(lis->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
-#else
- setsockopt(lis->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
-#endif /* __sun */
-
- /*
- * Bind to the port we found...
- */
-
-#ifdef AF_INET6
- if (lis->address.addr.sa_family == AF_INET6)
- {
-# ifdef IPV6_V6ONLY
- /*
- * Accept only IPv6 connections on this socket, to avoid
- * potential security issues and to make all platforms behave
- * the same.
- */
-
- val = 1;
-# ifdef __sun
- setsockopt(lis->fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&val, sizeof(val));
-# else
- setsockopt(lis->fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val));
-# endif /* __sun */
-# endif /* IPV6_V6ONLY */
-
- status = bind(lis->fd, (struct sockaddr *)&(lis->address),
- httpAddrLength(&(lis->address)));
- }
- else
-#endif /* AF_INET6 */
-#ifdef AF_LOCAL
- if (lis->address.addr.sa_family == AF_LOCAL)
- {
- mode_t mask; /* Umask setting */
-
-
- /*
- * Remove any existing domain socket file...
- */
-
- unlink(lis->address.un.sun_path);
-
- /*
- * Save the current umask and set it to 0 so that all users can access
- * the domain socket...
- */
-
- mask = umask(0);
-
- /*
- * Bind the domain socket...
- */
-
- status = bind(lis->fd, (struct sockaddr *)&(lis->address),
- httpAddrLength(&(lis->address)));
-
- /*
- * Restore the umask...
- */
-
- umask(mask);
- }
- else
-#endif /* AF_LOCAL */
- status = bind(lis->fd, (struct sockaddr *)&(lis->address),
- sizeof(lis->address.ipv4));
-
- if (status < 0)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to bind socket for address %s:%d - %s.",
- s, p, strerror(errno));
- close(lis->fd);
- lis->fd = -1;
-
- if (FatalErrors & CUPSD_FATAL_LISTEN)
- cupsdEndProcess(getpid(), 0);
-
- continue;
- }
-
- /*
- * Listen for new clients.
- */
-
- if (listen(lis->fd, ListenBackLog) < 0)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to listen for clients on address %s:%d - %s.",
- s, p, strerror(errno));
-
- close(lis->fd);
- lis->fd = -1;
-
- if (FatalErrors & CUPSD_FATAL_LISTEN)
- cupsdEndProcess(getpid(), 0);
-
- continue;
- }
}
- fcntl(lis->fd, F_SETFD, fcntl(lis->fd, F_GETFD) | FD_CLOEXEC);
-
if (p)
cupsdLogMessage(CUPSD_LOG_INFO, "Listening to %s:%d on fd %d...",
s, p, lis->fd);
else
- {
cupsdLogMessage(CUPSD_LOG_INFO, "Listening to %s on fd %d...",
s, lis->fd);
- if (chmod(s, 0140777))
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to change permisssions on domain socket "
- "\"%s\" - %s", s, strerror(errno));
- }
-
/*
* Save the first port that is bound to the local loopback or
* "any" address...
{
cupsdLogMessage(CUPSD_LOG_EMERG,
"No Listen or Port lines were found to allow access via "
- "localhost!");
+ "localhost.");
if (FatalErrors & (CUPSD_FATAL_CONFIG | CUPSD_FATAL_LISTEN))
cupsdEndProcess(getpid(), 0);
{
if (lis->fd != -1)
{
-#ifdef WIN32
- closesocket(lis->fd);
+#ifdef HAVE_LAUNCH_H
+ httpAddrClose(NULL, lis->fd);
#else
- close(lis->fd);
-#endif /* WIN32 */
+ httpAddrClose(&(lis->address), lis->fd);
+#endif /* HAVE_LAUNCH */
-#ifdef AF_LOCAL
- /*
- * Remove domain sockets...
- */
-
-# ifdef HAVE_LAUNCH_H
- if (lis->address.addr.sa_family == AF_LOCAL && !Launchd)
-# else
- if (lis->address.addr.sa_family == AF_LOCAL)
-# endif /* HAVE_LAUNCH_H */
- unlink(lis->address.un.sun_path);
-#endif /* AF_LOCAL */
+ lis->fd = -1;
}
}
}
_cupsLangPrintf(stdout, "%s available", service->uri);
httpAddrFreeList(addrlist);
-#ifdef WIN32
- closesocket(sock);
-#else
- close(sock);
-#endif /* WIN32 */
+ httpAddrClose(NULL, sock);
}
else
{