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