]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/console.c
add an additionnal abstract socket to prepare for more commands
[mirror_lxc.git] / src / lxc / console.c
CommitLineData
b0a33c1e 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
b0a33c1e 30#include "af_unix.h"
31#include "error.h"
32
36eb9bde 33#include <lxc/log.h>
96fa1ff0 34#include "commands.h"
36eb9bde
CLG
35
36lxc_log_define(lxc_console, lxc);
37
96fa1ff0
MN
38static 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
49static int send_command(const char *name, struct lxc_command *command)
b0a33c1e 50{
51 struct sockaddr_un addr = { 0 };
2ea004b8 52 int sock, ret = -1;
96fa1ff0 53 char *offset = &addr.sun_path[1];
b0a33c1e 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) {
96fa1ff0
MN
60 WARN("failed to connect to '@%s': %s", offset, strerror(errno));
61 return -1;
b0a33c1e 62 }
63
96fa1ff0
MN
64 ret = lxc_af_unix_send_credential(sock, &command->request,
65 sizeof(command->request));
b0a33c1e 66 if (ret < 0) {
36eb9bde 67 SYSERROR("failed to send credentials");
be43f17e 68 goto out_close;
b0a33c1e 69 }
70
96fa1ff0
MN
71 if (ret != sizeof(command->request)) {
72 SYSERROR("message only partially sent to '@%s'", offset);
be43f17e 73 goto out_close;
b0a33c1e 74 }
75
96fa1ff0
MN
76 ret = receive_answer(sock, &command->answer);
77 if (ret < 0)
be43f17e 78 goto out_close;
be43f17e 79out:
b0a33c1e 80 return ret;
be43f17e
DL
81out_close:
82 close(sock);
83 goto out;
b0a33c1e 84}
96fa1ff0
MN
85
86extern 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}