]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
tools: move lxc-execute to API symbols only
authorChristian Brauner <christian.brauner@ubuntu.com>
Fri, 12 Jan 2018 14:31:03 +0000 (15:31 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Tue, 6 Feb 2018 20:10:45 +0000 (21:10 +0100)
Closes #2073.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/Makefile.am
src/lxc/tools/arguments.c
src/lxc/tools/lxc_execute.c
src/lxc/tools/tool_utils.c
src/lxc/tools/tool_utils.h

index d7043e01b509a764fd79ca410d17ec3f7490ff1e..7908f20cacf9e7b13d0e02e9fab97a677aaa286c 100644 (file)
@@ -269,13 +269,13 @@ endif
 LDADD=liblxc.la @CAP_LIBS@ @SELINUX_LIBS@ @SECCOMP_LIBS@
 
 lxc_attach_SOURCES = tools/lxc_attach.c tools/arguments.c tools/tool_utils.c
-lxc_autostart_SOURCES = tools/lxc_autostart.c tools/arguments.c
-lxc_cgroup_SOURCES = tools/lxc_cgroup.c tools/arguments.c
-lxc_config_SOURCES = tools/lxc_config.c tools/arguments.c
-lxc_console_SOURCES = tools/lxc_console.c tools/arguments.c
-lxc_destroy_SOURCES = tools/lxc_destroy.c tools/arguments.c
-lxc_device_SOURCES = tools/lxc_device.c tools/arguments.c
-lxc_execute_SOURCES = tools/lxc_execute.c tools/arguments.c
+lxc_autostart_SOURCES = tools/lxc_autostart.c tools/arguments.c tools/tool_utils.c
+lxc_cgroup_SOURCES = tools/lxc_cgroup.c tools/arguments.c tools/tool_utils.c
+lxc_config_SOURCES = tools/lxc_config.c tools/arguments.c tools/tool_utils.c
+lxc_console_SOURCES = tools/lxc_console.c tools/arguments.c tools/tool_utils.c
+lxc_destroy_SOURCES = tools/lxc_destroy.c tools/arguments.c tools/tool_utils.c
+lxc_device_SOURCES = tools/lxc_device.c tools/arguments.c tools/tool_utils.c
+lxc_execute_SOURCES = tools/lxc_execute.c tools/arguments.c tools/tool_utils.c
 lxc_freeze_SOURCES = tools/lxc_freeze.c tools/arguments.c
 lxc_info_SOURCES = tools/lxc_info.c tools/arguments.c
 lxc_monitor_SOURCES = tools/lxc_monitor.c tools/arguments.c
index f98053feca219222a2220869d58359e4a8aa80ab..1be7eba58d50d8bc26ae49db4da9c67c8e515464 100644 (file)
@@ -22,6 +22,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#define _GNU_SOURCE
 #include <ctype.h>
 #include <errno.h>
 #include <limits.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 
+#include <lxc/version.h>
+
 #include "arguments.h"
-#include "utils.h"
-#include "version.h"
-#include "namespace.h"
+#include "tool_utils.h"
 
 static int build_shortopts(const struct option *a_options, char *a_shortopts,
                           size_t a_size)
index 3348d7c1c291d625aebeddec6ef0526b6041ab24..dd58aed706d86dbd6c8c1a3038d339a7accc40f7 100644 (file)
@@ -20,6 +20,7 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
+
 #define _GNU_SOURCE
 #include <errno.h>
 #include <libgen.h>
 #include <lxc/lxccontainer.h>
 
 #include "arguments.h"
-#include "caps.h"
-#include "conf.h"
-#include "config.h"
-#include "confile.h"
-#include "log.h"
-#include "lxc.h"
-#include "start.h"
-#include "utils.h"
+#include "tool_list.h"
+#include "tool_utils.h"
 
 static struct lxc_list defines;
 
 static int my_parser(struct lxc_arguments* args, int c, char* arg)
 {
+       int ret;
+
        switch (c) {
        case 'd':
                args->daemonize = 1;
@@ -56,7 +53,9 @@ static int my_parser(struct lxc_arguments* args, int c, char* arg)
                args->rcfile = arg;
                break;
        case 's':
-               return lxc_config_define_add(&defines, arg);
+               ret = lxc_config_define_add(&defines, arg);
+               if (ret < 0)
+                       lxc_config_define_free(&defines);
                break;
        case 'u':
                if (lxc_safe_uint(arg, &args->uid) < 0)
@@ -114,14 +113,17 @@ Options :\n\
        .daemonize = 0,
 };
 
-static bool set_argv(struct lxc_conf *conf, struct lxc_arguments *args)
+static bool set_argv(struct lxc_container *c, struct lxc_arguments *args)
 {
+       int ret;
+       char buf[TOOL_MAXPATHLEN];
        char **components, **p;
 
-       if (!conf->execute_cmd)
+       ret = c->get_config_item(c, "lxc.execute.cmd", buf, TOOL_MAXPATHLEN);
+       if (ret < 0)
                return false;
 
-       components = lxc_string_split_quoted(conf->execute_cmd);
+       components = lxc_string_split_quoted(buf);
        if (!components)
                return false;
 
@@ -156,7 +158,6 @@ int main(int argc, char *argv[])
 
        if (lxc_log_init(&log))
                exit(EXIT_FAILURE);
-       lxc_log_options_no_override();
 
        /* REMOVE IN LXC 3.0 */
        setenv("LXC_UPDATE_CONFIG_FORMAT", "1", 0);
@@ -189,24 +190,50 @@ int main(int argc, char *argv[])
        }
 
        if (my_args.argc == 0) {
-               if (!set_argv(c->lxc_conf, &my_args)) {
+               if (!set_argv(c, &my_args)) {
                        fprintf(stderr, "missing command to execute!\n");
                        lxc_container_put(c);
                        exit(EXIT_FAILURE);
                }
        }
 
-       ret = lxc_config_define_load(&defines, c->lxc_conf);
+       ret = lxc_config_define_load(&defines, c);
        if (ret) {
                lxc_container_put(c);
                exit(EXIT_FAILURE);
        }
 
-       if (my_args.uid)
-               c->lxc_conf->init_uid = my_args.uid;
+       if (my_args.uid) {
+               char buf[256];
+
+               ret = snprintf(buf, 256, "%d", my_args.uid);
+               if (ret < 0 || (size_t)ret >= 256) {
+                       lxc_container_put(c);
+                       exit(EXIT_FAILURE);
+               }
+
+               ret = c->set_config_item(c, "lxc.init.uid", buf);
+               if (ret < 0) {
+                       lxc_container_put(c);
+                       exit(EXIT_FAILURE);
+               }
+       }
+
+       if (my_args.gid) {
+               char buf[256];
 
-       if (my_args.gid)
-               c->lxc_conf->init_gid = my_args.gid;
+               ret = snprintf(buf, 256, "%d", my_args.gid);
+               if (ret < 0 || (size_t)ret >= 256) {
+                       lxc_container_put(c);
+                       exit(EXIT_FAILURE);
+               }
+
+               ret = c->set_config_item(c, "lxc.init.gid", buf);
+               if (ret < 0) {
+                       lxc_container_put(c);
+                       exit(EXIT_FAILURE);
+               }
+       }
 
        if (!lxc_setup_shared_ns(&my_args, c)) {
                lxc_container_put(c);
index 42be4d2496885ab3b6c5c621829a0edf0753d202..b1557a18e56aacc3fa7397ee0837dfb6a17ec22d 100644 (file)
@@ -131,17 +131,6 @@ signed long lxc_config_parse_arch(const char *arch)
        return -1;
 }
 
-enum {
-       LXC_NS_USER,
-       LXC_NS_MNT,
-       LXC_NS_PID,
-       LXC_NS_UTS,
-       LXC_NS_IPC,
-       LXC_NS_NET,
-       LXC_NS_CGROUP,
-       LXC_NS_MAX
-};
-
 const static struct ns_info {
        const char *proc_name;
        int clone_flag;
@@ -630,3 +619,207 @@ bool switch_to_ns(pid_t pid, const char *ns) {
        close(fd);
        return true;
 }
+
+static bool complete_word(char ***result, char *start, char *end, size_t *cap, size_t *cnt)
+{
+       int r;
+
+       r = lxc_grow_array((void ***)result, cap, 2 + *cnt, 16);
+       if (r < 0)
+               return false;
+       (*result)[*cnt] = strndup(start, end - start);
+       if (!(*result)[*cnt])
+               return false;
+       (*cnt)++;
+
+       return true;
+}
+
+/*
+ * Given a a string 'one two "three four"', split into three words,
+ * one, two, and "three four"
+ */
+char **lxc_string_split_quoted(char *string)
+{
+       char *nextword = string, *p, state;
+       char **result = NULL;
+       size_t result_capacity = 0;
+       size_t result_count = 0;
+
+       if (!string || !*string)
+               return calloc(1, sizeof(char *));
+
+       // TODO I'm *not* handling escaped quote
+       state = ' ';
+       for (p = string; *p; p++) {
+               switch(state) {
+               case ' ':
+                       if (isspace(*p))
+                               continue;
+                       else if (*p == '"' || *p == '\'') {
+                               nextword = p;
+                               state = *p;
+                               continue;
+                       }
+                       nextword = p;
+                       state = 'a';
+                       continue;
+               case 'a':
+                       if (isspace(*p)) {
+                               complete_word(&result, nextword, p, &result_capacity, &result_count);
+                               state = ' ';
+                               continue;
+                       }
+                       continue;
+               case '"':
+               case '\'':
+                       if (*p == state) {
+                               complete_word(&result, nextword+1, p, &result_capacity, &result_count);
+                               state = ' ';
+                               continue;
+                       }
+                       continue;
+               }
+       }
+
+       if (state == 'a')
+               complete_word(&result, nextword, p, &result_capacity, &result_count);
+
+       return realloc(result, (result_count + 1) * sizeof(char *));
+}
+
+int lxc_char_left_gc(const char *buffer, size_t len)
+{
+       size_t i;
+       for (i = 0; i < len; i++) {
+               if (buffer[i] == ' ' ||
+                   buffer[i] == '\t')
+                       continue;
+               return i;
+       }
+       return 0;
+}
+
+int lxc_char_right_gc(const char *buffer, size_t len)
+{
+       int i;
+       for (i = len - 1; i >= 0; i--) {
+               if (buffer[i] == ' '  ||
+                   buffer[i] == '\t' ||
+                   buffer[i] == '\n' ||
+                   buffer[i] == '\0')
+                       continue;
+               return i + 1;
+       }
+       return 0;
+}
+
+struct new_config_item *parse_line(char *buffer)
+{
+       char *dot, *key, *line, *linep, *value;
+       int ret = 0;
+       char *dup = buffer;
+    struct new_config_item *new = NULL;
+
+       linep = line = strdup(dup);
+       if (!line)
+               return NULL;
+
+       line += lxc_char_left_gc(line, strlen(line));
+
+       /* martian option - don't add it to the config itself */
+       if (strncmp(line, "lxc.", 4))
+               goto on_error;
+
+       ret = -1;
+       dot = strchr(line, '=');
+       if (!dot) {
+               fprintf(stderr, "Invalid configuration item: %s\n", line);
+               goto on_error;
+       }
+
+       *dot = '\0';
+       value = dot + 1;
+
+       key = line;
+       key[lxc_char_right_gc(key, strlen(key))] = '\0';
+
+       value += lxc_char_left_gc(value, strlen(value));
+       value[lxc_char_right_gc(value, strlen(value))] = '\0';
+
+       if (*value == '\'' || *value == '\"') {
+               size_t len;
+
+               len = strlen(value);
+               if (len > 1 && value[len - 1] == *value) {
+                       value[len - 1] = '\0';
+                       value++;
+               }
+       }
+
+    ret = -1;
+    new = malloc(sizeof(struct new_config_item));
+    if (!new)
+            goto on_error;
+
+    new->key = strdup(key);
+    new->val = strdup(value);
+    if (!new->val || !new->key)
+            goto on_error;
+    ret = 0;
+
+on_error:
+       free(linep);
+    if (ret < 0 && new) {
+            free(new->key);
+            free(new->val);
+            free(new);
+            new = NULL;
+    }
+
+       return new;
+}
+
+int lxc_config_define_add(struct lxc_list *defines, char *arg)
+{
+       struct lxc_list *dent;
+
+       dent = malloc(sizeof(struct lxc_list));
+       if (!dent)
+               return -1;
+
+       dent->elem = parse_line(arg);
+       if (!dent->elem)
+               return -1;
+       lxc_list_add_tail(defines, dent);
+       return 0;
+}
+
+int lxc_config_define_load(struct lxc_list *defines, struct lxc_container *c)
+{
+       struct lxc_list *it;
+       int ret = 0;
+
+       lxc_list_for_each(it, defines) {
+               struct new_config_item *new_item = it->elem;
+               ret = c->set_config_item(c, new_item->key, new_item->val);
+               if (ret < 0)
+                       break;
+       }
+
+       lxc_config_define_free(defines);
+       return ret;
+}
+
+void lxc_config_define_free(struct lxc_list *defines)
+{
+       struct lxc_list *it, *next;
+
+       lxc_list_for_each_safe(it, defines, next) {
+               struct new_config_item *new_item = it->elem;
+               free(new_item->key);
+               free(new_item->val);
+               lxc_list_del(it);
+               free(it);
+       }
+}
index e6d922f3ae42209f1894498f7e3daef984f0527b..5d1e8d3e3bcac94a86a85303888e5194fecad3ff 100644 (file)
@@ -138,6 +138,7 @@ extern char **lxc_string_split(const char *string, char _sep);
 extern char **lxc_normalize_path(const char *path);
 extern char *lxc_string_join(const char *sep, const char **parts,
                             bool use_as_prefix);
+extern char **lxc_string_split_quoted(char *string);
 
 extern int mkdir_p(const char *dir, mode_t mode);
 extern bool file_exists(const char *f);
@@ -147,4 +148,17 @@ extern char *get_template_path(const char *t);
 
 extern bool switch_to_ns(pid_t pid, const char *ns);
 
+extern int lxc_config_define_add(struct lxc_list *defines, char *arg);
+extern int lxc_config_define_load(struct lxc_list *defines,
+                                 struct lxc_container *c);
+extern void lxc_config_define_free(struct lxc_list *defines);
+extern int lxc_char_left_gc(const char *buffer, size_t len);
+extern int lxc_char_right_gc(const char *buffer, size_t len);
+
+struct new_config_item {
+        char *key;
+        char *val;
+};
+extern struct new_config_item *parse_line(char *buffer);
+
 #endif /* __LXC_UTILS_H */