]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/console.c
add an additionnal abstract socket to prepare for more commands
[mirror_lxc.git] / src / lxc / console.c
1 /*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
7 * Daniel Lezcano <dlezcano at fr.ibm.com>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24 #include <stdio.h>
25 #include <unistd.h>
26 #include <errno.h>
27 #include <sys/types.h>
28 #include <sys/un.h>
29
30 #include "af_unix.h"
31 #include "error.h"
32
33 #include <lxc/log.h>
34 #include "commands.h"
35
36 lxc_log_define(lxc_console, lxc);
37
38 static int receive_answer(int sock, struct lxc_answer *answer)
39 {
40 int ret;
41
42 ret = lxc_af_unix_recv_fd(sock, &answer->fd, answer, sizeof(*answer));
43 if (ret < 0)
44 ERROR("failed to receive answer for the command");
45
46 return ret;
47 }
48
49 static int send_command(const char *name, struct lxc_command *command)
50 {
51 struct sockaddr_un addr = { 0 };
52 int sock, ret = -1;
53 char *offset = &addr.sun_path[1];
54
55 snprintf(addr.sun_path, sizeof(addr.sun_path), "@%s", name);
56 addr.sun_path[0] = '\0';
57
58 sock = lxc_af_unix_connect(addr.sun_path);
59 if (sock < 0) {
60 WARN("failed to connect to '@%s': %s", offset, strerror(errno));
61 return -1;
62 }
63
64 ret = lxc_af_unix_send_credential(sock, &command->request,
65 sizeof(command->request));
66 if (ret < 0) {
67 SYSERROR("failed to send credentials");
68 goto out_close;
69 }
70
71 if (ret != sizeof(command->request)) {
72 SYSERROR("message only partially sent to '@%s'", offset);
73 goto out_close;
74 }
75
76 ret = receive_answer(sock, &command->answer);
77 if (ret < 0)
78 goto out_close;
79 out:
80 return ret;
81 out_close:
82 close(sock);
83 goto out;
84 }
85
86 extern int lxc_console(const char *name, int ttynum, int *fd)
87 {
88 int ret;
89 struct lxc_command command = {
90 .request = { .type = LXC_COMMAND_TTY, .data = ttynum },
91 };
92
93 ret = send_command(name, &command);
94 if (ret < 0) {
95 ERROR("failed to send command");
96 return -1;
97 }
98
99 if (!ret) {
100 ERROR("console denied by '%s'", name);
101 return -1;
102 }
103
104 *fd = command.answer.fd;
105 if (*fd <0) {
106 ERROR("unable to allocate fd for tty %d", ttynum);
107 return -1;
108 }
109
110 INFO("tty %d allocated", ttynum);
111 return 0;
112 }