/*
- * "$Id: listen.c 6788 2007-08-13 17:20:14Z mike $"
+ * "$Id$"
*
- * Server listening routines for the Common UNIX Printing System (CUPS)
- * scheduler.
+ * Server listening routines for the CUPS scheduler.
*
- * Copyright 2007 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? */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStartListening: %d Listeners",
cupsArrayCount(Listeners));
- /*
- * Get the server's IP address...
- */
-
- if (ServerAddrs)
- httpAddrFreeList(ServerAddrs);
-
- if ((ServerAddrs = httpAddrGetList(ServerName, AF_UNSPEC, NULL)) == NULL)
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to find IP address for server name \"%s\"!\n",
- ServerName);
-
/*
* Setup socket listeners...
*/
lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
{
httpAddrString(&(lis->address), s, sizeof(s));
-
-#ifdef AF_INET6
- if (lis->address.addr.sa_family == AF_INET6)
- p = ntohs(lis->address.ipv6.sin6_port);
- else
-#endif /* AF_INET6 */
-#ifdef AF_LOCAL
- if (lis->address.addr.sa_family == AF_LOCAL)
- p = 0;
- else
-#endif /* AF_LOCAL */
- p = ntohs(lis->address.ipv4.sin_port);
+ p = httpAddrPort(&(lis->address));
/*
* If needed, create a socket for listening...
* 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)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Unable to open listen socket for address %s:%d - %s.",
s, p, strerror(errno));
- 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.
+ * IPv6 is often disabled while DNS returns IPv6 addresses...
*/
- 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
+ if (lis->address.addr.sa_family != AF_INET6 &&
+ (FatalErrors & CUPSD_FATAL_LISTEN))
+ cupsdEndProcess(getpid(), 0);
+#else
+ if (FatalErrors & CUPSD_FATAL_LISTEN)
+ cupsdEndProcess(getpid(), 0);
#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 curent umask and set it to 0...
- */
-
- 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;
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));
- exit(errno);
- }
}
- 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.");
- /*
- * Commit suicide...
- */
-
- cupsdEndProcess(getpid(), 0);
+ 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;
}
}
}
/*
- * End of "$Id: listen.c 6788 2007-08-13 17:20:14Z mike $".
+ * End of "$Id$".
*/