From 2371f5f46a3935def8977c276213d1394370a808 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sat, 26 Dec 2015 14:49:09 +0100 Subject: create socket MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/satd.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 76 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/satd.c b/src/satd.c index fe2200e..414ca58 100644 --- a/src/satd.c +++ b/src/satd.c @@ -22,10 +22,17 @@ #include #include #include +#include +#include +#include +#include #include "daemonise.h" +#define t(...) do { if (__VA_ARGS__) goto fail; } while (0) + + /** * The name of the process. @@ -46,10 +53,69 @@ usage(void) } +/** + * Get the group ID of a group. + * + * @param name The name of the group. + * @param fallback The group ID to return if the group is not found. + * @return The ID of the group, -1 on error. + */ +static gid_t +getgroup(const char* name, gid_t fallback) +{ + struct group *g; + if (!(g = getgrnam(name))) + return errno ? (gid_t)-1 : fallback; + return g->gr_gid; +} + + +/** + * Create the socket. + * + * @param address Output parameter for the socket address. + * @return The file descriptor for the socket, -1 on error. + */ +static int +create_socket(struct sockaddr_un *address) +{ + int fd = -1; + ssize_t len; + char *dir; + gid_t group; + + dir = getenv("XDG_RUNTIME_DIR"), dir = (dir ? dir : "/run") + t (snprintf(NULL, 0, "%s/satd.socket%zn", dir, &len) == -1); + if ((len < 0) || (len >= sizeof(address->sun_path))) { + errno = ENAMETOOLING; + goto fail; + } + sprintf(address->sun_path, "%s/satd.socket", dir) + address->sun_family = AF_UNIX; + /* TODO test flock */ + unlink(address->sun_path); + t ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1); + t (fchmod(fd, S_IRWXU) == -1); + t ((group = getgroup("nobody", 0)) == -1); + t (fchown(fd, getuid(), group) == -1); + t (bind(fd, (struct sockaddr *)address, sizeof(*address)) == -1); + /* TODO flock */ + + return fd; +fail: + saved_errno = errno; + if (fd >= 0) + close(fd); + errno = saved_errno; + return -1; +} + + int main(int argc, char *argv[]) { - int foreground = 0; + struct sockaddr_un address; + int sock = -1, foreground = 0; if (argc > 0) argv0 = argv[0]; @@ -61,14 +127,21 @@ main(int argc, char *argv[]) foreground = 1; } - if (foreground ? 0 : daemonise(0)) - goto fail; + t (foreground ? 0 : daemonise("satd", 0)); + + t (sock = create_socket(&address), sock == -1); + close(sock); + unlink(address.sun_path); undaemonise(); return 0; fail: perror(argv0); + if (sock >= 0) { + close(sock); + unlink(address.sun_path); + } undaemonise(); return 1; } -- cgit v1.2.3-70-g09d2