#include <sys/stat.h>
#include <stddef.h>
#include <sys/ioctl.h>
+#include <netdb.h>
#include "macro.h"
#include "util.h"
}
bool socket_ipv6_is_supported(void) {
- char *l = 0;
- bool enabled;
+ _cleanup_free_ char *l = NULL;
if (access("/sys/module/ipv6", F_OK) != 0)
return 0;
return 1;
/* If module was loaded with disable=1 no IPv6 available */
- enabled = l[0] == '0';
- free(l);
-
- return enabled;
+ return l[0] == '0';
}
bool socket_address_matches_fd(const SocketAddress *a, int fd) {
int getpeername_pretty(int fd, char **ret) {
union sockaddr_union sa;
- socklen_t salen;
+ socklen_t salen = sizeof(sa);
int r;
assert(fd >= 0);
assert(ret);
- salen = sizeof(sa);
if (getpeername(fd, &sa.sa, &salen) < 0)
return -errno;
if (sa.sa.sa_family == AF_UNIX) {
- struct ucred ucred;
+ struct ucred ucred = {};
/* UNIX connection sockets are anonymous, so let's use
* PID/UID as pretty credentials instead */
if (r < 0)
return r;
- if (asprintf(ret, "PID %lu/UID %lu", (unsigned long) ucred.pid, (unsigned long) ucred.pid) < 0)
+ if (asprintf(ret, "PID "PID_FMT"/UID "UID_FMT, ucred.pid, ucred.uid) < 0)
return -ENOMEM;
return 0;
int getsockname_pretty(int fd, char **ret) {
union sockaddr_union sa;
- socklen_t salen;
+ socklen_t salen = sizeof(sa);
assert(fd >= 0);
assert(ret);
- salen = sizeof(sa);
if (getsockname(fd, &sa.sa, &salen) < 0)
return -errno;
return sockaddr_pretty(&sa.sa, salen, false, ret);
}
+int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret) {
+ int r;
+ char host[NI_MAXHOST], *ret;
+
+ assert(_ret);
+
+ r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0,
+ NI_IDN|NI_IDN_USE_STD3_ASCII_RULES);
+ if (r != 0) {
+ _cleanup_free_ char *sockname = NULL;
+ int saved_errno = errno;
+
+ r = sockaddr_pretty(&sa->sa, salen, true, &sockname);
+ if (r < 0)
+ log_error("sockadd_pretty() failed: %s", strerror(-r));
+ else
+ log_error("getnameinfo(%s) failed: %s", sockname, strerror(-r));
+ return -saved_errno;
+ }
+
+ ret = strdup(host);
+ if (!ret)
+ return log_oom();
+
+ *_ret = ret;
+ return 0;
+}
+
+int getnameinfo_pretty(int fd, char **ret) {
+ union sockaddr_union sa;
+ socklen_t salen = sizeof(sa);
+
+ assert(fd >= 0);
+ assert(ret);
+
+ if (getsockname(fd, &sa.sa, &salen) < 0) {
+ log_error("getsockname(%d) failed: %m", fd);
+ return -errno;
+ }
+
+ return socknameinfo_pretty(&sa, salen, ret);
+}
+
+int socket_address_unlink(SocketAddress *a) {
+ assert(a);
+
+ if (socket_address_family(a) != AF_UNIX)
+ return 0;
+
+ if (a->sockaddr.un.sun_path[0] == 0)
+ return 0;
+
+ if (unlink(a->sockaddr.un.sun_path) < 0)
+ return -errno;
+
+ return 1;
+}
+
static const char* const netlink_family_table[] = {
[NETLINK_ROUTE] = "route",
[NETLINK_FIREWALL] = "firewall",