]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/tools/lxc_console.c
tree-wide: fix lxc header inclusion
[mirror_lxc.git] / src / lxc / tools / lxc_console.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #ifndef _GNU_SOURCE
4 #define _GNU_SOURCE 1
5 #endif
6 #include <errno.h>
7 #include <fcntl.h>
8 #include <libgen.h>
9 #include <poll.h>
10 #include <signal.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <sys/ioctl.h>
15 #include <sys/param.h>
16 #include <sys/stat.h>
17 #include <sys/types.h>
18 #include <unistd.h>
19
20 #include "lxc.h"
21
22 #include "arguments.h"
23 #include "config.h"
24 #include "log.h"
25 #include "utils.h"
26
27 lxc_log_define(lxc_console, lxc);
28
29 static int my_parser(struct lxc_arguments *args, int c, char *arg);
30 static char etoc(const char *expr);
31
32 static const struct option my_longopts[] = {
33 {"tty", required_argument, 0, 't'},
34 {"escape", required_argument, 0, 'e'},
35 LXC_COMMON_OPTIONS
36 };
37
38 static struct lxc_arguments my_args = {
39 .progname = "lxc-console",
40 .help = "\
41 --name=NAME [--tty NUMBER]\n\
42 \n\
43 lxc-console logs on the container with the identifier NAME\n\
44 \n\
45 Options :\n\
46 -n, --name=NAME NAME of the container\n\
47 -t, --tty=NUMBER console tty number\n\
48 -e, --escape=PREFIX prefix for escape command\n\
49 --rcfile=FILE Load configuration file FILE\n",
50 .options = my_longopts,
51 .parser = my_parser,
52 .checker = NULL,
53 .log_priority = "ERROR",
54 .log_file = "none",
55 .ttynum = -1,
56 .escape = 1,
57 };
58
59 static int my_parser(struct lxc_arguments *args, int c, char *arg)
60 {
61 switch (c) {
62 case 't':
63 if (lxc_safe_uint(arg, &args->ttynum) < 0)
64 return -1;
65 break;
66 case 'e':
67 args->escape = etoc(arg);
68 break;
69 }
70
71 return 0;
72 }
73
74 static char etoc(const char *expr)
75 {
76 /* returns "control code" of given expression */
77 char c = expr[0] == '^' ? expr[1] : expr[0];
78
79 return 1 + ((c > 'Z') ? (c - 'a') : (c - 'Z'));
80 }
81
82 int main(int argc, char *argv[])
83 {
84 int ret;
85 struct lxc_container *c;
86 struct lxc_log log;
87
88 if (lxc_arguments_parse(&my_args, argc, argv))
89 exit(EXIT_FAILURE);
90
91 log.name = my_args.name;
92 log.file = my_args.log_file;
93 log.level = my_args.log_priority;
94 log.prefix = my_args.progname;
95 log.quiet = my_args.quiet;
96 log.lxcpath = my_args.lxcpath[0];
97
98 if (lxc_log_init(&log))
99 exit(EXIT_FAILURE);
100
101 c = lxc_container_new(my_args.name, my_args.lxcpath[0]);
102 if (!c) {
103 ERROR("System error loading container");
104 exit(EXIT_FAILURE);
105 }
106
107 if (my_args.rcfile) {
108 c->clear_config(c);
109
110 if (!c->load_config(c, my_args.rcfile)) {
111 ERROR("Failed to load rcfile");
112 lxc_container_put(c);
113 exit(EXIT_FAILURE);
114 }
115
116 c->configfile = strdup(my_args.rcfile);
117 if (!c->configfile) {
118 ERROR("Out of memory setting new config filename");
119 lxc_container_put(c);
120 exit(EXIT_FAILURE);
121 }
122 }
123
124 if (!c->may_control(c)) {
125 ERROR("Insufficent privileges to control %s", my_args.name);
126 lxc_container_put(c);
127 exit(EXIT_FAILURE);
128 }
129
130 if (!c->is_running(c)) {
131 ERROR("%s is not running", my_args.name);
132 lxc_container_put(c);
133 exit(EXIT_FAILURE);
134 }
135
136 ret = c->console(c, my_args.ttynum, 0, 1, 2, my_args.escape);
137 if (ret < 0) {
138 lxc_container_put(c);
139 exit(EXIT_FAILURE);
140 }
141
142 lxc_container_put(c);
143 exit(EXIT_SUCCESS);
144 }