]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/activate/activate.c
tree-wide: remove Emacs lines from all files
[thirdparty/systemd.git] / src / activate / activate.c
index 4ece1367c11e9651da10e5b429b726028bf79f4a..d50566c97bd1b8d68eb94c4e0b9c2241c484dc39 100644 (file)
@@ -1,5 +1,3 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
 /***
   This file is part of systemd.
 
 
 #include "sd-daemon.h"
 
+#include "alloc-util.h"
+#include "fd-util.h"
 #include "log.h"
 #include "macro.h"
 #include "signal-util.h"
 #include "socket-util.h"
+#include "string-util.h"
 #include "strv.h"
 
 static char** arg_listen = NULL;
 static bool arg_accept = false;
+static bool arg_datagram = false;
 static char** arg_args = NULL;
 static char** arg_setenv = NULL;
 static const char *arg_fdname = NULL;
@@ -95,7 +97,11 @@ static int open_sockets(int *epoll_fd, bool accept) {
 
         STRV_FOREACH(address, arg_listen) {
 
-                fd = make_socket_fd(LOG_DEBUG, *address, SOCK_STREAM | (arg_accept*SOCK_CLOEXEC));
+                if (arg_datagram)
+                        fd = make_socket_fd(LOG_DEBUG, *address, SOCK_DGRAM, SOCK_CLOEXEC);
+                else
+                        fd = make_socket_fd(LOG_DEBUG, *address, SOCK_STREAM, (arg_accept*SOCK_CLOEXEC));
+
                 if (fd < 0) {
                         log_open();
                         return log_error_errno(fd, "Failed to open '%s': %m", *address);
@@ -143,24 +149,44 @@ static int launch(char* name, char **argv, char **env, int fds) {
                 return log_oom();
 
         STRV_FOREACH(s, arg_setenv) {
-                if (strchr(*s, '='))
-                        envp[n_env++] = *s;
-                else {
+                if (strchr(*s, '=')) {
+                        char *k;
+
+                        k = strdup(*s);
+                        if (!k)
+                                return log_oom();
+
+                        envp[n_env++] = k;
+                } else {
                         _cleanup_free_ char *p;
+                        const char *n;
 
                         p = strappend(*s, "=");
                         if (!p)
                                 return log_oom();
-                        envp[n_env] = strv_find_prefix(env, p);
-                        if (envp[n_env])
-                                n_env ++;
+
+                        n = strv_find_prefix(env, p);
+                        if (!n)
+                                continue;
+
+                        envp[n_env] = strdup(n);
+                        if (!envp[n_env])
+                                return log_oom();
                 }
         }
 
         for (i = 0; i < ELEMENTSOF(tocopy); i++) {
-                envp[n_env] = strv_find_prefix(env, tocopy[i]);
-                if (envp[n_env])
-                        n_env ++;
+                const char *n;
+
+                n = strv_find_prefix(env, tocopy[i]);
+                if (!n)
+                        continue;
+
+                envp[n_env] = strdup(n);
+                if (!envp[n_env])
+                        return log_oom();
+
+                n_env ++;
         }
 
         if ((asprintf((char**)(envp + n_env++), "LISTEN_FDS=%d", fds) < 0) ||
@@ -269,7 +295,7 @@ static int do_accept(const char* name, char **argv, char **envp, int fd) {
         }
 
         getsockname_pretty(fd2, &local);
-        getpeername_pretty(fd2, &peer);
+        getpeername_pretty(fd2, true, &peer);
         log_info("Connection from %s to %s", strna(peer), strna(local));
 
         return launch1(name, argv, envp, fd2);
@@ -301,11 +327,12 @@ static void help(void) {
         printf("%s [OPTIONS...]\n\n"
                "Listen on sockets and launch child on connection.\n\n"
                "Options:\n"
+               "  -h --help                Show this help and exit\n"
+               "     --version             Print version string and exit\n"
                "  -l --listen=ADDR         Listen for raw connections at ADDR\n"
+               "  -d --datagram            Listen on datagram instead of stream socket\n"
                "  -a --accept              Spawn separate child for each connection\n"
-               "  -h --help                Show this help and exit\n"
                "  -E --setenv=NAME[=VALUE] Pass an environment variable to children\n"
-               "  --version                Print version string and exit\n"
                "\n"
                "Note: file descriptors from sd_listen_fds() will be passed through.\n"
                , program_invocation_short_name);
@@ -320,6 +347,7 @@ static int parse_argv(int argc, char *argv[]) {
         static const struct option options[] = {
                 { "help",        no_argument,       NULL, 'h'           },
                 { "version",     no_argument,       NULL, ARG_VERSION   },
+                { "datagram",    no_argument,       NULL, 'd'           },
                 { "listen",      required_argument, NULL, 'l'           },
                 { "accept",      no_argument,       NULL, 'a'           },
                 { "setenv",      required_argument, NULL, 'E'           },
@@ -333,7 +361,7 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "+hl:aE:", options, NULL)) >= 0)
+        while ((c = getopt_long(argc, argv, "+hl:aEd", options, NULL)) >= 0)
                 switch(c) {
                 case 'h':
                         help();
@@ -349,6 +377,10 @@ static int parse_argv(int argc, char *argv[]) {
 
                         break;
 
+                case 'd':
+                        arg_datagram = true;
+                        break;
+
                 case 'a':
                         arg_accept = true;
                         break;
@@ -382,6 +414,12 @@ static int parse_argv(int argc, char *argv[]) {
                 return -EINVAL;
         }
 
+        if (arg_datagram && arg_accept) {
+                log_error("Datagram sockets do not accept connections. "
+                          "The --datagram and --accept options may not be combined.");
+                return -EINVAL;
+        }
+
         arg_args = argv + optind;
 
         return 1 /* work to do */;