]>
Commit | Line | Data |
---|---|---|
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 | |
36 | lxc_log_define(lxc_console, lxc); | |
37 | ||
96fa1ff0 MN |
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) | |
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 | 79 | out: |
b0a33c1e | 80 | return ret; |
be43f17e DL |
81 | out_close: |
82 | close(sock); | |
83 | goto out; | |
b0a33c1e | 84 | } |
96fa1ff0 MN |
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 | } |