Annotation of src/usr.bin/cu/command.c, Revision 1.8
1.8 ! nicm 1: /* $OpenBSD: command.c,v 1.7 2012/07/10 10:56:12 nicm Exp $ */
1.1 nicm 2:
3: /*
4: * Copyright (c) 2012 Nicholas Marriott <nicm@openbsd.org>
5: *
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.
9: *
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.
17: */
18:
19: #include <sys/types.h>
20: #include <sys/ioctl.h>
21: #include <sys/wait.h>
22:
23: #include <event.h>
24: #include <errno.h>
25: #include <fcntl.h>
1.7 nicm 26: #include <limits.h>
1.1 nicm 27: #include <paths.h>
28: #include <signal.h>
29: #include <stdlib.h>
30: #include <stdio.h>
31: #include <unistd.h>
32:
33: #include "cu.h"
34:
35: void pipe_command(void);
1.4 nicm 36: void connect_command(void);
1.1 nicm 37: void send_file(void);
1.8 ! nicm 38: void send_xmodem(void);
1.1 nicm 39:
40: void
41: pipe_command(void)
42: {
43: const char *cmd;
44: pid_t pid;
45: int fd;
46:
47: cmd = get_input("Local command?");
48: if (cmd == NULL || *cmd == '\0')
49: return;
50:
1.3 nicm 51: restore_termios();
52:
1.1 nicm 53: switch (pid = fork()) {
54: case -1:
1.6 nicm 55: cu_err(1, "fork");
1.1 nicm 56: case 0:
57: fd = open(_PATH_DEVNULL, O_RDWR);
58: if (fd < 0 || dup2(fd, STDIN_FILENO) == -1)
59: _exit(1);
60: close(fd);
61:
1.3 nicm 62: if (signal(SIGINT, SIG_DFL) == SIG_ERR)
63: _exit(1);
64: if (signal(SIGQUIT, SIG_DFL) == SIG_ERR)
65: _exit(1);
66:
1.1 nicm 67: /* attach stdout to line */
68: if (dup2(line_fd, STDOUT_FILENO) == -1)
69: _exit(1);
70:
1.5 nicm 71: if (closefrom(STDERR_FILENO + 1) != 0)
1.1 nicm 72: _exit(1);
73:
74: execl(_PATH_BSHELL, "sh", "-c", cmd, (void*)NULL);
75: _exit(1);
76: default:
77: while (waitpid(pid, NULL, 0) == -1 && errno == EINTR)
78: /* nothing */;
79: break;
80: }
1.3 nicm 81:
82: set_termios();
1.1 nicm 83: }
84:
85: void
1.4 nicm 86: connect_command(void)
87: {
88: const char *cmd;
89: pid_t pid;
90:
91: /*
92: * Fork a program with:
93: * 0 <-> remote tty in
94: * 1 <-> remote tty out
95: * 2 <-> local tty stderr
96: */
97:
98: cmd = get_input("Local command?");
99: if (cmd == NULL || *cmd == '\0')
100: return;
101:
102: restore_termios();
103:
104: switch (pid = fork()) {
105: case -1:
1.6 nicm 106: cu_err(1, "fork");
1.4 nicm 107: case 0:
108: if (signal(SIGINT, SIG_DFL) == SIG_ERR)
109: _exit(1);
110: if (signal(SIGQUIT, SIG_DFL) == SIG_ERR)
111: _exit(1);
112:
113: /* attach stdout and stdin to line */
114: if (dup2(line_fd, STDOUT_FILENO) == -1)
115: _exit(1);
116: if (dup2(line_fd, STDIN_FILENO) == -1)
117: _exit(1);
118:
1.5 nicm 119: if (closefrom(STDERR_FILENO + 1) != 0)
1.4 nicm 120: _exit(1);
121:
122: execl(_PATH_BSHELL, "sh", "-c", cmd, (void*)NULL);
123: _exit(1);
124: default:
125: while (waitpid(pid, NULL, 0) == -1 && errno == EINTR)
126: /* nothing */;
127: break;
128: }
129:
130: set_termios();
131: }
132:
133: void
1.1 nicm 134: send_file(void)
135: {
136: const char *file;
137: FILE *f;
138: char buf[BUFSIZ], *expanded;
139: size_t len;
140:
141: file = get_input("Local file?");
142: if (file == NULL || *file == '\0')
143: return;
144:
145: expanded = tilde_expand(file);
146: f = fopen(expanded, "r");
147: if (f == NULL) {
1.6 nicm 148: cu_warn("%s", file);
1.1 nicm 149: return;
150: }
151:
152: while (!feof(f) && !ferror(f)) {
153: len = fread(buf, 1, sizeof(buf), f);
154: if (len != 0)
155: bufferevent_write(line_ev, buf, len);
156: }
157:
158: fclose(f);
159: free(expanded);
160: }
161:
162: void
1.8 ! nicm 163: send_xmodem(void)
! 164: {
! 165: const char *file;
! 166: char *expanded;
! 167:
! 168: file = get_input("Local file?");
! 169: if (file == NULL || *file == '\0')
! 170: return;
! 171:
! 172: expanded = tilde_expand(file);
! 173: xmodem_send(expanded);
! 174: free(expanded);
! 175: }
! 176:
! 177: void
1.2 nicm 178: set_speed(void)
179: {
180: const char *s, *errstr;
181: int speed;
182:
183: s = get_input("New speed?");
184: if (s == NULL || *s == '\0')
185: return;
186:
187: speed = strtonum(s, 0, UINT_MAX, &errstr);
188: if (errstr != NULL) {
1.6 nicm 189: cu_warnx("speed is %s: %s", errstr, s);
1.2 nicm 190: return;
191: }
192:
1.6 nicm 193: if (set_line(speed) != 0)
194: cu_warn("tcsetattr");
1.2 nicm 195: }
196:
197: void
1.1 nicm 198: do_command(char c)
199: {
200: switch (c) {
201: case '.':
202: case '\004': /* ^D */
203: event_loopexit(NULL);
204: break;
205: case '\032': /* ^Z */
206: restore_termios();
207: kill(getpid(), SIGTSTP);
208: set_termios();
209: break;
1.4 nicm 210: case 'C':
211: connect_command();
212: break;
1.2 nicm 213: case 'S':
214: set_speed();
1.8 ! nicm 215: break;
! 216: case 'X':
! 217: send_xmodem();
1.2 nicm 218: break;
1.1 nicm 219: case '$':
220: pipe_command();
221: break;
222: case '>':
223: send_file();
224: break;
225: case '#':
226: ioctl(line_fd, TIOCSBRK, NULL);
227: sleep(1);
228: ioctl(line_fd, TIOCCBRK, NULL);
229: break;
230: case '?':
231: printf("\r\n"
1.2 nicm 232: "~# send break\r\n"
233: "~$ pipe local command to remote host\r\n"
1.1 nicm 234: "~> send file to remote host\r\n"
1.4 nicm 235: "~C connect program to remote host\r\n"
1.2 nicm 236: "~S set speed\r\n"
1.1 nicm 237: "~? get this summary\r\n"
1.2 nicm 238: );
1.1 nicm 239: break;
240: }
241: }