return (rc);
}
+/* Convert the IP address SA to a Unix-domain address SUN. Fail if the
+ * address seems already taken. If DESPARATEP then try cleaning up stale old
+ * sockets.
+ */
+static int encode_unused_inet_addr(struct sockaddr *sa,
+ struct sockaddr_un *sun,
+ int desperatep)
+{
+ address waddr;
+ struct sockaddr_un wsun;
+ int rc;
+ char buf[ADDRBUFSZ];
+
+ snprintf(sun->sun_path, sizeof(sun->sun_path), "%s/%s", sockdir,
+ present_sockaddr(sa, 0, buf, sizeof(buf)));
+ if ((rc = unix_socket_status(sun, !desperatep)) == USED) return (-1);
+ else if (rc == STALE) unlink(sun->sun_path);
+
+ wildcard_address(sa->sa_family, &waddr.sa);
+ port_to_sockaddr(&waddr.sa, port_from_sockaddr(sa));
+ snprintf(wsun.sun_path, sizeof(wsun.sun_path), "%s/%s", sockdir,
+ present_sockaddr(&waddr.sa, 0, buf, sizeof(buf)));
+ if ((rc = unix_socket_status(&wsun, !desperatep)) == USED) return (-1);
+ else if (rc == STALE) unlink(wsun.sun_path);
+
+ return (0);
+}
+
/* Encode the Internet address SA as a Unix-domain address SUN. If WANT is
* WANT_FRESH, and SA's port number is zero, then we pick an arbitrary local
* port. Otherwise we pick the port given. There's an unpleasant hack to
copy_sockaddr(&addr.sa, sa);
for (i = 0; i < 10; i++) {
port_to_sockaddr(&addr.sa, randrange(minautoport, maxautoport));
- snprintf(sun->sun_path, sizeof(sun->sun_path), "%s/%s", sockdir,
- present_sockaddr(&addr.sa, 0, buf, sizeof(buf)));
- if (unix_socket_status(sun, 1) == UNUSED) goto found;
+ if (!encode_unused_inet_addr(&addr.sa, sun, 0)) goto found;
}
for (desperatep = 0; desperatep < 2; desperatep++) {
for (i = minautoport; i <= maxautoport; i++) {
port_to_sockaddr(&addr.sa, i);
- snprintf(sun->sun_path, sizeof(sun->sun_path), "%s/%s", sockdir,
- present_sockaddr(&addr.sa, 0, buf, sizeof(buf)));
- rc = unix_socket_status(sun, !desperatep);
- switch (rc) {
- case STALE: unlink(sun->sun_path);
- case UNUSED: goto found;
- }
+ if (!encode_unused_inet_addr(&addr.sa, sun, 0)) goto found;
}
}
errno = EADDRINUSE;
return;
}
+/* Parse an ACL from an environment variable VAR, attaching it to the list
+ * TAIL.
+ */
+static void parse_acl_env(const char *var, aclnode ***tail)
+{
+ char *p, *q;
+
+ if ((p = getenv(var)) != 0) {
+ p = q = xstrdup(p);
+ parse_acl_line(&q, tail);
+ free(p);
+ }
+}
+
/* Parse the autoports configuration directive. Syntax is MIN - MAX. */
static void parse_autoports(char **pp)
{
return;
}
-/* Parse an ACL from an environment variable VAR, attaching it to the list
- * TAIL. */
-static void parse_acl_env(const char *var, aclnode ***tail)
-{
- char *p, *q;
-
- if ((p = getenv(var)) != 0) {
- p = q = xstrdup(p);
- parse_acl_line(&q, tail);
- free(p);
- }
-}
-
/* Read the configuration from the config file and environment. */
static void readconfig(void)
{