tools: move lxc-execute to API symbols only

Closes #2073. Signed-off-by: 's avatarChristian Brauner <christian.brauner@ubuntu.com>
parent 23500ef5
......@@ -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
......
......@@ -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>
......@@ -32,10 +33,10 @@
#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)
......
......@@ -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>
......@@ -35,19 +36,15 @@
#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);
......
......@@ -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);
}
}
......@@ -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 */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment