1 /*****************************************************************************
2 * Written by Chris Dunlap <cdunlap@llnl.gov>.
3 * Copyright (C) 2007-2018 Lawrence Livermore National Security, LLC.
4 * Copyright (C) 2001-2007 The Regents of the University of California.
5 * UCRL-CODE-2002-009.
6 *
7 * This file is part of ConMan: The Console Manager.
8 * For details, see <https://dun.github.io/conman/>.
9 *
10 * ConMan is free software: you can redistribute it and/or modify it under
11 * the terms of the GNU General Public License as published by the Free
12 * Software Foundation, either version 3 of the License, or (at your option)
13 * any later version.
14 *
15 * ConMan is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 * for more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with ConMan. If not, see <http://www.gnu.org/licenses/>.
22 *****************************************************************************/
23
24
25 #if HAVE_CONFIG_H
26 # include <config.h>
27 #endif /* HAVE_CONFIG_H */
28
29 #include <assert.h>
30 #include <errno.h>
31 #include <stdlib.h>
32 #include <termios.h>
33 #include <unistd.h>
34 #include "common.h"
35 #include "log.h"
36 #include "util-str.h"
37 #include "util.h"
38
39
40 const char *conman_license = \
41 "ConMan: The Console Manager\n" \
42 "https://dun.github.io/conman/\n" \
43 "\n" \
44 "Written by Chris Dunlap <cdunlap@llnl.gov>.\n" \
45 "Copyright (C) 2007-2018 Lawrence Livermore National Security, LLC.\n" \
46 "Copyright (C) 2001-2007 The Regents of the University of California.\n" \
47 "\n" \
48 "ConMan is free software: you can redistribute it and/or modify it\n" \
49 "under the terms of the GNU General Public License as published by\n" \
50 "the Free Software Foundation; either version 3 of the License, or\n" \
51 "(at your option) any later version.\n" \
52 "\n";
53
54
55 char *proto_strs[] = {
56 /*
57 * Keep strings in sync w/ common.h:proto_toks enum.
58 * These must be sorted in a case-insensitive manner.
59 */
60 "BROADCAST",
61 "CODE",
62 "CONNECT",
63 "CONSOLE",
64 "ERROR",
65 "FORCE",
66 "HELLO",
67 "JOIN",
68 "MESSAGE",
69 "MONITOR",
70 "OK",
71 "OPTION",
72 "QUERY",
73 "QUIET",
74 "REGEX",
75 "RESET",
76 "TTY",
77 "USER",
78 NULL
79 };
80
81
create_req(void)82 req_t * create_req(void)
83 {
84 /* Creates and returns a request struct.
85 */
86 req_t *req;
87
88 if (!(req = malloc(sizeof(req_t))))
89 out_of_memory();
90 req->sd = -1;
91 req->user = NULL;
92 req->tty = NULL;
93 req->fqdn = NULL;
94 req->host = NULL;
95 req->ip = NULL;
96 req->port = 0;
97 req->consoles = list_create((ListDelF) destroy_string);
98 req->command = CONMAN_CMD_NONE;
99 req->enableBroadcast = 0;
100 req->enableEcho = 0;
101 req->enableForce = 0;
102 req->enableJoin = 0;
103 req->enableQuiet = 0;
104 req->enableRegex = 0;
105 req->enableReset = 0;
106 return(req);
107 }
108
109
destroy_req(req_t * req)110 void destroy_req(req_t *req)
111 {
112 /* Destroys a request struct.
113 */
114 if (!req)
115 return;
116
117 if (req->sd >= 0) {
118 if (close(req->sd) < 0)
119 log_err(errno, "close() failed on fd=%d", req->sd);
120 req->sd = -1;
121 }
122 if (req->user)
123 free(req->user);
124 if (req->tty)
125 free(req->tty);
126 if (req->fqdn)
127 free(req->fqdn);
128 if (req->host)
129 free(req->host);
130 if (req->ip)
131 free(req->ip);
132 if (req->consoles)
133 list_destroy(req->consoles);
134
135 free(req);
136 return;
137 }
138
139
get_tty_mode(struct termios * tty,int fd)140 void get_tty_mode(struct termios *tty, int fd)
141 {
142 /* Gets the tty values associated with 'fd' and stores them in 'tty'.
143 */
144 assert(fd >= 0);
145 assert(tty != NULL);
146
147 if (!isatty(fd))
148 return;
149 if (tcgetattr(fd, tty) < 0)
150 log_err(errno, "tcgetattr() failed on fd=%d", fd);
151 return;
152 }
153
154
set_tty_mode(struct termios * tty,int fd)155 void set_tty_mode(struct termios *tty, int fd)
156 {
157 /* Sets the tty values associated with 'fd' to those stored in 'tty'.
158 *
159 * FIXME: tcsetattr() returns 0 (success) if it is able to perform ANY of the
160 * requested actions. Therefore, after calling tcsetattr(), one must call
161 * tcgetattr() and compare the actual terminal's attributes to the desired
162 * attributes to detect any differences. (APUE2 18.4)
163 */
164 assert(fd >= 0);
165 assert(tty != NULL);
166
167 if (!isatty(fd))
168 return;
169 if (tcsetattr(fd, TCSAFLUSH, tty) < 0)
170 log_err(errno, "tcgetattr() failed on fd=%d", fd);
171 return;
172 }
173
174
get_tty_raw(struct termios * tty,int fd)175 void get_tty_raw(struct termios *tty, int fd)
176 {
177 /* Gets the tty values associated with 'fd' and stores them in 'tty',
178 * adjusting them to reflect the device is operating in "raw" mode.
179 * Note that the 'fd' device is not placed in raw mode by this call;
180 * to do so, invoke set_tty_mode() with the updated termios struct.
181 */
182 assert(tty != NULL);
183
184 get_tty_mode(tty, fd);
185
186 /* Disable SIGINT on BREAK, CR-to-NL, input parity check,
187 * stripping 8th bit on input, and output flow control.
188 */
189 tty->c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
190
191 /* Disable output processing.
192 */
193 tty->c_oflag &= ~(OPOST);
194
195 /* Set 8 bits/char.
196 */
197 tty->c_cflag &= ~CSIZE;
198 tty->c_cflag |= CS8;
199
200 /* Disable parity checking.
201 */
202 tty->c_cflag &= ~PARENB;
203
204 /* Ignore modem status lines for locally attached device.
205 */
206 tty->c_cflag |= CLOCAL;
207
208 /* Disable echo, canonical mode, extended input processing, signal chars.
209 */
210 tty->c_lflag &= ~(ECHO | ECHOCTL | ICANON | IEXTEN | ISIG);
211
212 /* read() does not return until data is present (may block indefinitely).
213 */
214 tty->c_cc[VMIN] = 1;
215 tty->c_cc[VTIME] = 0;
216 return;
217 }
218