X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Fsocket-util.c;h=7e65f8a691871218afe9a253068147cde8927460;hb=e627440b41bb0284e4892f7aa9d84c77972487e2;hp=acc4d33372badb098b8f7713e7608537b083c6f1;hpb=d7832d2c6e0ef5f2839a2296c1cc2fc85c7d9632;p=elogind.git diff --git a/src/shared/socket-util.c b/src/shared/socket-util.c index acc4d3337..7e65f8a69 100644 --- a/src/shared/socket-util.c +++ b/src/shared/socket-util.c @@ -6,16 +6,16 @@ Copyright 2010 Lennart Poettering systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. systemd is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. + Lesser General Public License for more details. - You should have received a copy of the GNU General Public License + You should have received a copy of the GNU Lesser General Public License along with systemd; If not, see . ***/ @@ -34,9 +34,10 @@ #include "macro.h" #include "util.h" +#include "mkdir.h" +#include "path-util.h" #include "socket-util.h" #include "missing.h" -#include "label.h" int socket_address_parse(SocketAddress *a, const char *s) { int r; @@ -383,109 +384,6 @@ int socket_address_print(const SocketAddress *a, char **p) { } } -int socket_address_listen( - const SocketAddress *a, - int backlog, - SocketAddressBindIPv6Only only, - const char *bind_to_device, - bool free_bind, - bool transparent, - mode_t directory_mode, - mode_t socket_mode, - const char *label, - int *ret) { - - int r, fd, one; - assert(a); - assert(ret); - - if ((r = socket_address_verify(a)) < 0) - return r; - - if (socket_address_family(a) == AF_INET6 && !socket_ipv6_is_supported()) - return -EAFNOSUPPORT; - - r = label_socket_set(label); - if (r < 0) - return r; - - fd = socket(socket_address_family(a), a->type | SOCK_NONBLOCK | SOCK_CLOEXEC, a->protocol); - r = fd < 0 ? -errno : 0; - - label_socket_clear(); - - if (r < 0) - return r; - - if (socket_address_family(a) == AF_INET6 && only != SOCKET_ADDRESS_DEFAULT) { - int flag = only == SOCKET_ADDRESS_IPV6_ONLY; - - if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag)) < 0) - goto fail; - } - - if (socket_address_family(a) == AF_INET || socket_address_family(a) == AF_INET6) { - if (bind_to_device) - if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, bind_to_device, strlen(bind_to_device)+1) < 0) - goto fail; - - if (free_bind) { - one = 1; - if (setsockopt(fd, IPPROTO_IP, IP_FREEBIND, &one, sizeof(one)) < 0) - log_warning("IP_FREEBIND failed: %m"); - } - - if (transparent) { - one = 1; - if (setsockopt(fd, IPPROTO_IP, IP_TRANSPARENT, &one, sizeof(one)) < 0) - log_warning("IP_TRANSPARENT failed: %m"); - } - } - - one = 1; - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) - goto fail; - - if (socket_address_family(a) == AF_UNIX && a->sockaddr.un.sun_path[0] != 0) { - mode_t old_mask; - - /* Create parents */ - mkdir_parents(a->sockaddr.un.sun_path, directory_mode); - - /* Enforce the right access mode for the socket*/ - old_mask = umask(~ socket_mode); - - /* Include the original umask in our mask */ - umask(~socket_mode | old_mask); - - r = label_bind(fd, &a->sockaddr.sa, a->size); - - if (r < 0 && errno == EADDRINUSE) { - /* Unlink and try again */ - unlink(a->sockaddr.un.sun_path); - r = bind(fd, &a->sockaddr.sa, a->size); - } - - umask(old_mask); - } else - r = bind(fd, &a->sockaddr.sa, a->size); - - if (r < 0) - goto fail; - - if (socket_address_can_accept(a)) - if (listen(fd, backlog) < 0) - goto fail; - - *ret = fd; - return 0; - -fail: - r = -errno; - close_nointr_nofail(fd); - return r; -} - bool socket_address_can_accept(const SocketAddress *a) { assert(a);