1 /* $OpenBSD: command.c,v 1.12 2012/07/15 06:55:28 nicm Exp $ */
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>
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 */
47 void pipe_command(void);
48 void connect_command(void);
50 void send_xmodem(void);
59 cmd
= get_input("Local command?");
60 if (cmd
== NULL
|| *cmd
== '\0')
65 switch (pid
= fork()) {
70 fd
= open(_PATH_DEVNULL
, O_RDWR
);
71 if (fd
< 0 || dup2(fd
, STDIN_FILENO
) == -1)
75 if (signal(SIGINT
, SIG_DFL
) == SIG_ERR
)
77 if (signal(SIGQUIT
, SIG_DFL
) == SIG_ERR
)
80 /* attach stdout to line */
81 if (dup2(line_fd
, STDOUT_FILENO
) == -1)
87 closefrom(STDERR_FILENO
+ 1)
94 execl(_PATH_BSHELL
, "sh", "-c", cmd
, (void*)NULL
);
97 while (waitpid(pid
, NULL
, 0) == -1 && errno
== EINTR
)
106 connect_command(void)
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')
124 switch (pid
= fork()) {
129 if (signal(SIGINT
, SIG_DFL
) == SIG_ERR
)
131 if (signal(SIGQUIT
, SIG_DFL
) == SIG_ERR
)
134 /* attach stdout and stdin to line */
135 if (dup2(line_fd
, STDOUT_FILENO
) == -1)
137 if (dup2(line_fd
, STDIN_FILENO
) == -1)
143 closefrom(STDERR_FILENO
+ 1)
150 execl(_PATH_BSHELL
, "sh", "-c", cmd
, (void*)NULL
);
153 while (waitpid(pid
, NULL
, 0) == -1 && errno
== EINTR
)
166 char buf
[BUFSIZ
], *expanded
;
169 file
= get_input("Local file?");
170 if (file
== NULL
|| *file
== '\0')
173 expanded
= tilde_expand(file
);
174 f
= fopen(expanded
, "r");
180 while (!feof(f
) && !ferror(f
)) {
181 len
= fread(buf
, 1, sizeof(buf
), f
);
183 bufferevent_write(line_ev
, buf
, len
);
196 file
= get_input("Local file?");
197 if (file
== NULL
|| *file
== '\0')
200 expanded
= tilde_expand(file
);
201 xmodem_send(expanded
);
208 const char *s
, *errstr
;
211 s
= get_input("New speed?");
212 if (s
== NULL
|| *s
== '\0')
215 speed
= strtonum(s
, 0, UINT_MAX
, &errstr
);
216 if (errstr
!= NULL
) {
217 cu_warnx("speed is %s: %s", errstr
, s
);
221 if (set_line(speed
) != 0)
222 cu_warn("tcsetattr");
230 if (record_file
!= NULL
) {
235 file
= get_input("Record file?");
236 if (file
== NULL
|| *file
== '\0')
239 record_file
= fopen(file
, "a");
240 if (record_file
== NULL
)
241 cu_warnx("%s", file
);
249 case '\004': /* ^D */
250 event_loopexit(NULL
);
252 case '\032': /* ^Z */
254 kill(getpid(), SIGTSTP
);
260 #if defined(TIOCCDTR)
262 ioctl(line_fd
, TIOCCDTR
, NULL
);
264 ioctl(line_fd
, TIOCSDTR
, NULL
);
283 ioctl(line_fd
, TIOCSBRK
, NULL
);
285 ioctl(line_fd
, TIOCCBRK
, NULL
);
288 bufferevent_write(line_ev
, "~", 1);
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"
299 "~R start recording to file\r\n"
301 "~X send file with XMODEM\r\n"
302 "~? get this summary\r\n"