+/* Return the status of Unix-domain socket address SUN. Returns: UNUSED if
+ * the socket doesn't exist; USED if the path refers to an active socket, or
+ * isn't really a socket at all, or we can't tell without a careful search
+ * and QUICKP is set; or STALE if the file refers to a socket which isn't
+ * being used any more.
+ */
+static int unix_socket_status(struct sockaddr_un *sun, int quickp)
+{
+ struct stat st;
+ FILE *fp = 0;
+ size_t len, n;
+ int rc;
+ char buf[256];
+
+ if (stat(sun->sun_path, &st))
+ return (errno == ENOENT ? UNUSED : USED);
+ if (!S_ISSOCK(st.st_mode) || quickp)
+ return (USED);
+ rc = USED;
+ if ((fp = fopen("/proc/net/unix", "r")) == 0)
+ goto done;
+ if (!fgets(buf, sizeof(buf), fp)) goto done; /* skip header */
+ len = strlen(sun->sun_path);
+ while (fgets(buf, sizeof(buf), fp)) {
+ n = strlen(buf);
+ if (n >= len + 2 && buf[n - len - 2] == ' ' && buf[n - 1] == '\n' &&
+ memcmp(buf + n - len - 1, sun->sun_path, len) == 0)
+ goto done;
+ }
+ if (ferror(fp))
+ goto done;
+ rc = STALE;
+done:
+ if (fp) fclose(fp);
+ return (rc);
+}
+
+/* Encode the Internet address SIN as a Unix-domain address SUN. If WANT is
+ * WANT_FRESH, and SIN->sin_port is zero, then we pick an arbitrary local
+ * port. Otherwise we pick the port given. There's an unpleasant hack to
+ * find servers bound to INADDR_ANY. Returns zero on success; -1 on failure.
+ */