+ case AF_UNIX:
+ if (salen <= offsetof(struct sockaddr_un, sun_path)) {
+ p = strdup("<unnamed>");
+ if (!p)
+ return -ENOMEM;
+
+ } else if (sa->un.sun_path[0] == 0) {
+ /* abstract */
+
+ /* FIXME: We assume we can print the
+ * socket path here and that it hasn't
+ * more than one NUL byte. That is
+ * actually an invalid assumption */
+
+ p = new(char, sizeof(sa->un.sun_path)+1);
+ if (!p)
+ return -ENOMEM;
+
+ p[0] = '@';
+ memcpy(p+1, sa->un.sun_path+1, sizeof(sa->un.sun_path)-1);
+ p[sizeof(sa->un.sun_path)] = 0;
+
+ } else {
+ p = strndup(sa->un.sun_path, sizeof(sa->un.sun_path));
+ if (!ret)
+ return -ENOMEM;
+ }
+
+ break;
+
+ default:
+ return -ENOTSUP;
+ }
+
+
+ *ret = p;
+ return 0;
+}
+
+int getpeername_pretty(int fd, char **ret) {
+ union sockaddr_union sa;
+ socklen_t salen = sizeof(sa);
+ int r;
+
+ assert(fd >= 0);
+ assert(ret);
+
+ if (getpeername(fd, &sa.sa, &salen) < 0)
+ return -errno;
+
+ if (sa.sa.sa_family == AF_UNIX) {
+ struct ucred ucred = {};
+
+ /* UNIX connection sockets are anonymous, so let's use
+ * PID/UID as pretty credentials instead */
+
+ r = getpeercred(fd, &ucred);
+ if (r < 0)
+ return r;
+
+ if (asprintf(ret, "PID "PID_FMT"/UID "UID_FMT, ucred.pid, ucred.uid) < 0)
+ return -ENOMEM;
+
+ return 0;