Fix unused parameter warnings
[cu.git] / command.c
blob13dca5893f5b4881e5fbd6d9b9ce17243771efa3
1 /* $OpenBSD: command.c,v 1.12 2012/07/15 06:55:28 nicm Exp $ */
3 /*
4 * Copyright (c) 2012 Nicholas Marriott <nicm@openbsd.org>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <sys/types.h>
20 #include <sys/ioctl.h>
21 #include <sys/wait.h>
23 #include <event.h>
24 #include <errno.h>
25 #include <fcntl.h>
26 #include <limits.h>
27 #include <paths.h>
28 #include <signal.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <unistd.h>
33 #include "cu.h"
35 /* OpenBSD implementation of closeret() returns int,
36 while FreeBSD and Linux libbsd are void instead */
37 //#define CLOSEFROM_INTRET 1
39 /* closefrom() is implemented in bsd.c */
40 #if CLOSEFROM_INTRET
41 int
42 #else
43 void
44 #endif
45 closefrom(int start);
47 void pipe_command(void);
48 void connect_command(void);
49 void send_file(void);
50 void send_xmodem(void);
52 void
53 pipe_command(void)
55 const char *cmd;
56 pid_t pid;
57 int fd;
59 cmd = get_input("Local command?");
60 if (cmd == NULL || *cmd == '\0')
61 return;
63 restore_termios();
65 switch (pid = fork()) {
66 case -1:
67 cu_err(1, "fork");
68 _exit(1);
69 case 0:
70 fd = open(_PATH_DEVNULL, O_RDWR);
71 if (fd < 0 || dup2(fd, STDIN_FILENO) == -1)
72 _exit(1);
73 close(fd);
75 if (signal(SIGINT, SIG_DFL) == SIG_ERR)
76 _exit(1);
77 if (signal(SIGQUIT, SIG_DFL) == SIG_ERR)
78 _exit(1);
80 /* attach stdout to line */
81 if (dup2(line_fd, STDOUT_FILENO) == -1)
82 _exit(1);
84 #if CLOSEFROM_INTRET
85 if (
86 #endif
87 closefrom(STDERR_FILENO + 1)
88 #if CLOSEFROM_INTRET
89 != 0)
90 _exit(1)
91 #endif
94 execl(_PATH_BSHELL, "sh", "-c", cmd, (void*)NULL);
95 _exit(1);
96 default:
97 while (waitpid(pid, NULL, 0) == -1 && errno == EINTR)
98 /* nothing */;
99 break;
102 set_termios();
105 void
106 connect_command(void)
108 const char *cmd;
109 pid_t pid;
112 * Fork a program with:
113 * 0 <-> remote tty in
114 * 1 <-> remote tty out
115 * 2 <-> local tty stderr
118 cmd = get_input("Local command?");
119 if (cmd == NULL || *cmd == '\0')
120 return;
122 restore_termios();
124 switch (pid = fork()) {
125 case -1:
126 cu_err(1, "fork");
127 _exit(1);
128 case 0:
129 if (signal(SIGINT, SIG_DFL) == SIG_ERR)
130 _exit(1);
131 if (signal(SIGQUIT, SIG_DFL) == SIG_ERR)
132 _exit(1);
134 /* attach stdout and stdin to line */
135 if (dup2(line_fd, STDOUT_FILENO) == -1)
136 _exit(1);
137 if (dup2(line_fd, STDIN_FILENO) == -1)
138 _exit(1);
140 #if CLOSEFROM_INTRET
141 if (
142 #endif
143 closefrom(STDERR_FILENO + 1)
144 #if CLOSEFROM_INTRET
145 != 0)
146 _exit(1)
147 #endif
150 execl(_PATH_BSHELL, "sh", "-c", cmd, (void*)NULL);
151 _exit(1);
152 default:
153 while (waitpid(pid, NULL, 0) == -1 && errno == EINTR)
154 /* nothing */;
155 break;
158 set_termios();
161 void
162 send_file(void)
164 const char *file;
165 FILE *f;
166 char buf[BUFSIZ], *expanded;
167 size_t len;
169 file = get_input("Local file?");
170 if (file == NULL || *file == '\0')
171 return;
173 expanded = tilde_expand(file);
174 f = fopen(expanded, "r");
175 if (f == NULL) {
176 cu_warn("%s", file);
177 return;
180 while (!feof(f) && !ferror(f)) {
181 len = fread(buf, 1, sizeof(buf), f);
182 if (len != 0)
183 bufferevent_write(line_ev, buf, len);
186 fclose(f);
187 free(expanded);
190 void
191 send_xmodem(void)
193 const char *file;
194 char *expanded;
196 file = get_input("Local file?");
197 if (file == NULL || *file == '\0')
198 return;
200 expanded = tilde_expand(file);
201 xmodem_send(expanded);
202 free(expanded);
205 void
206 set_speed(void)
208 const char *s, *errstr;
209 int speed;
211 s = get_input("New speed?");
212 if (s == NULL || *s == '\0')
213 return;
215 speed = strtonum(s, 0, UINT_MAX, &errstr);
216 if (errstr != NULL) {
217 cu_warnx("speed is %s: %s", errstr, s);
218 return;
221 if (set_line(speed) != 0)
222 cu_warn("tcsetattr");
225 void
226 start_record(void)
228 const char *file;
230 if (record_file != NULL) {
231 fclose(record_file);
232 record_file = NULL;
235 file = get_input("Record file?");
236 if (file == NULL || *file == '\0')
237 return;
239 record_file = fopen(file, "a");
240 if (record_file == NULL)
241 cu_warnx("%s", file);
244 void
245 do_command(char c)
247 switch (c) {
248 case '.':
249 case '\004': /* ^D */
250 event_loopexit(NULL);
251 break;
252 case '\032': /* ^Z */
253 restore_termios();
254 kill(getpid(), SIGTSTP);
255 set_termios();
256 break;
257 case 'C':
258 connect_command();
259 break;
260 #if defined(TIOCCDTR)
261 case 'D':
262 ioctl(line_fd, TIOCCDTR, NULL);
263 sleep(1);
264 ioctl(line_fd, TIOCSDTR, NULL);
265 break;
266 #endif
267 case 'R':
268 start_record();
269 break;
270 case 'S':
271 set_speed();
272 break;
273 case 'X':
274 send_xmodem();
275 break;
276 case '$':
277 pipe_command();
278 break;
279 case '>':
280 send_file();
281 break;
282 case '#':
283 ioctl(line_fd, TIOCSBRK, NULL);
284 sleep(1);
285 ioctl(line_fd, TIOCCBRK, NULL);
286 break;
287 case '~':
288 bufferevent_write(line_ev, "~", 1);
289 break;
290 case '?':
291 printf("\r\n"
292 "~# send break\r\n"
293 "~$ pipe local command to remote host\r\n"
294 "~> send file to remote host\r\n"
295 "~C connect program to remote host\r\n"
296 #if defined(TIOCCDTR)
297 "~D de-assert DTR line briefly\r\n"
298 #endif
299 "~R start recording to file\r\n"
300 "~S set speed\r\n"
301 "~X send file with XMODEM\r\n"
302 "~? get this summary\r\n"
304 break;