aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-06-20 15:23:03 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-06-20 15:23:03 +0000
commit14923db72fe6e97d9c596236841a9eb6338231db (patch)
treead221dd5c71bb7eec7788c86af30ba4c933d9cc2
parentcd0e80ce902f6e79b31888af4ff4545846ce1c0e (diff)
downloadbusybox-w32-14923db72fe6e97d9c596236841a9eb6338231db.tar.gz
busybox-w32-14923db72fe6e97d9c596236841a9eb6338231db.tar.bz2
busybox-w32-14923db72fe6e97d9c596236841a9eb6338231db.zip
slattach: new applet.
-rw-r--r--include/applets.h1
-rw-r--r--include/usage.h14
-rw-r--r--networking/Config.in6
-rw-r--r--networking/Kbuild1
-rw-r--r--networking/slattach.c240
5 files changed, 262 insertions, 0 deletions
diff --git a/include/applets.h b/include/applets.h
index 0f378bbeb..8a33f5432 100644
--- a/include/applets.h
+++ b/include/applets.h
@@ -296,6 +296,7 @@ USE_FEATURE_SH_IS_HUSH(APPLET_NOUSAGE(sh, hush, _BB_DIR_BIN, _BB_SUID_NEVER))
296USE_FEATURE_SH_IS_LASH(APPLET_NOUSAGE(sh, lash, _BB_DIR_BIN, _BB_SUID_NEVER)) 296USE_FEATURE_SH_IS_LASH(APPLET_NOUSAGE(sh, lash, _BB_DIR_BIN, _BB_SUID_NEVER))
297USE_FEATURE_SH_IS_MSH(APPLET_NOUSAGE(sh, msh, _BB_DIR_BIN, _BB_SUID_NEVER)) 297USE_FEATURE_SH_IS_MSH(APPLET_NOUSAGE(sh, msh, _BB_DIR_BIN, _BB_SUID_NEVER))
298USE_SHA1SUM(APPLET_ODDNAME(sha1sum, md5_sha1_sum, _BB_DIR_USR_BIN, _BB_SUID_NEVER, sha1sum)) 298USE_SHA1SUM(APPLET_ODDNAME(sha1sum, md5_sha1_sum, _BB_DIR_USR_BIN, _BB_SUID_NEVER, sha1sum))
299USE_SLATTACH(APPLET(slattach, _BB_DIR_SBIN, _BB_SUID_NEVER))
299USE_SLEEP(APPLET_NOFORK(sleep, sleep, _BB_DIR_BIN, _BB_SUID_NEVER, sleep)) 300USE_SLEEP(APPLET_NOFORK(sleep, sleep, _BB_DIR_BIN, _BB_SUID_NEVER, sleep))
300USE_SOFTLIMIT(APPLET_ODDNAME(softlimit, chpst, _BB_DIR_USR_BIN, _BB_SUID_NEVER, softlimit)) 301USE_SOFTLIMIT(APPLET_ODDNAME(softlimit, chpst, _BB_DIR_USR_BIN, _BB_SUID_NEVER, softlimit))
301USE_SORT(APPLET_NOEXEC(sort, sort, _BB_DIR_USR_BIN, _BB_SUID_NEVER, sort)) 302USE_SORT(APPLET_NOEXEC(sort, sort, _BB_DIR_USR_BIN, _BB_SUID_NEVER, sort))
diff --git a/include/usage.h b/include/usage.h
index 7d09feb05..2baa495ac 100644
--- a/include/usage.h
+++ b/include/usage.h
@@ -2991,6 +2991,20 @@ USE_FEATURE_RUN_PARTS_FANCY("\n -l Prints names of all matching files even when
2991 " -s Don't output anything, status code shows success\n" \ 2991 " -s Don't output anything, status code shows success\n" \
2992 " -w Warn about improperly formatted SHA1 checksum lines") 2992 " -w Warn about improperly formatted SHA1 checksum lines")
2993 2993
2994#define slattach_trivial_usage \
2995 "[-cehmLF] [-s speed] [-p protocol] DEVICEs"
2996#define slattach_full_usage \
2997 "Attach network interface(s) to serial line(s)\n" \
2998 "\nOptions:" \
2999 "\n -p Set protocol (slip, cslip, slip6, clisp6 or adaptive)" \
3000 "\n -s Set line speed" \
3001 "\n -e Exit after initializing device" \
3002 "\n -h Exit when the carrier is lost" \
3003 "\n -c Execute a command when the line is hung up" \
3004 "\n -m Do NOT initialize the line in raw 8 bits mode" \
3005 "\n -L Enable 3-wire operation" \
3006 "\n -F Disable RTS/CTS flow control" \
3007
2994#define sleep_trivial_usage \ 3008#define sleep_trivial_usage \
2995 USE_FEATURE_FANCY_SLEEP("[") "N" USE_FEATURE_FANCY_SLEEP("]...") 3009 USE_FEATURE_FANCY_SLEEP("[") "N" USE_FEATURE_FANCY_SLEEP("]...")
2996#define sleep_full_usage \ 3010#define sleep_full_usage \
diff --git a/networking/Config.in b/networking/Config.in
index 13ad13f9a..77b5d2558 100644
--- a/networking/Config.in
+++ b/networking/Config.in
@@ -548,6 +548,12 @@ config ROUTE
548 help 548 help
549 Route displays or manipulates the kernel's IP routing tables. 549 Route displays or manipulates the kernel's IP routing tables.
550 550
551config SLATTACH
552 bool "slattach"
553 default n
554 help
555 slattach is a small utility to attach network interfaces to serial lines.
556
551config TELNET 557config TELNET
552 bool "telnet" 558 bool "telnet"
553 default n 559 default n
diff --git a/networking/Kbuild b/networking/Kbuild
index 0f4ab7ba6..23968a833 100644
--- a/networking/Kbuild
+++ b/networking/Kbuild
@@ -27,6 +27,7 @@ lib-$(CONFIG_PING) += ping.o
27lib-$(CONFIG_PING6) += ping.o 27lib-$(CONFIG_PING6) += ping.o
28lib-$(CONFIG_PSCAN) += pscan.o 28lib-$(CONFIG_PSCAN) += pscan.o
29lib-$(CONFIG_ROUTE) += route.o 29lib-$(CONFIG_ROUTE) += route.o
30lib-$(CONFIG_SLATTACH) += slattach.o
30lib-$(CONFIG_TELNET) += telnet.o 31lib-$(CONFIG_TELNET) += telnet.o
31lib-$(CONFIG_TELNETD) += telnetd.o 32lib-$(CONFIG_TELNETD) += telnetd.o
32lib-$(CONFIG_TFTP) += tftp.o 33lib-$(CONFIG_TFTP) += tftp.o
diff --git a/networking/slattach.c b/networking/slattach.c
new file mode 100644
index 000000000..1c00fddb6
--- /dev/null
+++ b/networking/slattach.c
@@ -0,0 +1,240 @@
1/*
2 * Stripped down version of net-tools for busybox.
3 *
4 * Author: Ignacio Garcia Perez (iggarpe at gmail dot com)
5 *
6 * License: GPLv2 or later, see LICENSE file in this tarball.
7 *
8 * There are some differences from the standard net-tools slattach:
9 *
10 * - The -l option is not supported.
11 *
12 * - The -F options allows disabling of RTS/CTS flow control.
13 */
14
15#include "libbb.h"
16
17/* Line discipline code table */
18static const char *const proto_names[] = {
19 "slip", /* 0 */
20 "cslip", /* 1 */
21 "slip6", /* 2 */
22 "cslip6", /* 3 */
23 "adaptive", /* 8 */
24 NULL
25};
26
27struct globals {
28 int handle;
29 int saved_disc;
30 struct termios saved_state;
31};
32#define G (*(struct globals*)&bb_common_bufsiz1)
33#define handle (G.handle )
34#define saved_disc (G.saved_disc )
35#define saved_state (G.saved_state )
36#define INIT_G() do {} while (0)
37
38
39/*
40 * Save tty state and line discipline
41 *
42 * It is fine here to bail out on errors, since we haven modified anything yet
43 */
44static void save_state(void)
45{
46 /* Save line status */
47 if (tcgetattr(handle, &saved_state) < 0)
48 bb_perror_msg_and_die("get state");
49
50 /* Save line discipline */
51 if (ioctl(handle, TIOCGETD, &saved_disc) < 0)
52 bb_perror_msg_and_die("get discipline");
53}
54
55/*
56 * Restore state and line discipline for ALL managed ttys
57 *
58 * Restoring ALL managed ttys is the only way to have a single
59 * hangup delay.
60 *
61 * Go on after errors: we want to restore as many controlled ttys
62 * as possible.
63 */
64static void restore_state_and_exit(int exitcode) ATTRIBUTE_NORETURN;
65static void restore_state_and_exit(int exitcode)
66{
67 struct termios state;
68
69 /* Restore line discipline */
70 if (ioctl(handle, TIOCSETD, &saved_disc) < 0) {
71 bb_perror_msg("set discipline");
72 exitcode = 1;
73 }
74
75 /* Hangup */
76 memcpy(&state, &saved_state, sizeof(state));
77 cfsetispeed(&state, B0);
78 cfsetospeed(&state, B0);
79 if (tcsetattr(handle, TCSANOW, &state) < 0) {
80 bb_perror_msg("set state");
81 exitcode = 1;
82 }
83
84 sleep(1);
85
86 /* Restore line status */
87 if (tcsetattr(handle, TCSANOW, &saved_state) < 0) {
88 bb_perror_msg_and_die("set state");
89 }
90
91 if (ENABLE_FEATURE_CLEAN_UP)
92 close(handle);
93
94 exit(exitcode);
95}
96
97/*
98 * Set tty state, line discipline and encapsulation
99 */
100static void set_state(struct termios *state, int encap)
101{
102 int disc;
103
104 /* Set line status */
105 if (tcsetattr(handle, TCSANOW, state) < 0) {
106 bb_perror_msg("set state");
107 goto bad;
108 }
109
110 /* Set line discliple (N_SLIP always) */
111 disc = N_SLIP;
112 if (ioctl(handle, TIOCSETD, &disc) < 0) {
113 bb_perror_msg("set discipline");
114 goto bad;
115 }
116
117 /* Set encapsulation (SLIP, CSLIP, etc) */
118 if (ioctl(handle, SIOCSIFENCAP, &encap) < 0) {
119 bb_perror_msg("set encapsulation");
120 bad:
121 restore_state_and_exit(1);
122 }
123}
124
125static void sig_handler(int signo)
126{
127 restore_state_and_exit(0);
128}
129
130int slattach_main(int argc, char **argv);
131int slattach_main(int argc, char **argv)
132{
133 int i, encap, opt;
134 struct termios state;
135 const char *proto = "cslip";
136 const char *extcmd; /* Command to execute after hangup */
137 const char *baud_str;
138 int baud_code = -1; /* Line baud rate (system code) */
139
140 enum {
141 OPT_p_proto = 1 << 0,
142 OPT_s_baud = 1 << 1,
143 OPT_c_extcmd = 1 << 2,
144 OPT_e_quit = 1 << 3,
145 OPT_h_watch = 1 << 4,
146 OPT_m_nonraw = 1 << 5,
147 OPT_L_local = 1 << 6,
148 OPT_F_noflow = 1 << 7,
149 };
150
151 INIT_G();
152
153 /* Parse command line options */
154 opt = getopt32(argc, argv, "p:s:c:ehmLF", &proto, &baud_str, &extcmd);
155 /*argc -= optind;*/
156 argv += optind;
157
158 if (!*argv)
159 bb_show_usage();
160
161 encap = index_in_str_array(proto_names, proto);
162
163 if (encap < 0)
164 bb_error_msg_and_die("invalid protocol %s", proto);
165 if (encap > 3)
166 encap = 8;
167
168 /* We want to know if the baud rate is valid before we start touching the ttys */
169 if (opt & OPT_s_baud) {
170 baud_code = tty_value_to_baud(xatoi(baud_str));
171 if (baud_code < 0)
172 bb_error_msg_and_die("invalid baud rate");
173 }
174
175 /* Trap signals in order to restore tty states upon exit */
176 if (!(opt & OPT_e_quit)) {
177 signal(SIGHUP, sig_handler);
178 signal(SIGINT, sig_handler);
179 signal(SIGQUIT, sig_handler);
180 signal(SIGTERM, sig_handler);
181 }
182
183 /* Open tty */
184 handle = open(*argv, O_RDWR | O_NDELAY);
185 if (handle < 0) {
186 char *buf = xasprintf("/dev/%s", *argv);
187 handle = xopen(buf, O_RDWR | O_NDELAY);
188 /* maybe if (ENABLE_FEATURE_CLEAN_UP) ?? */
189 free(buf);
190 }
191
192 /* Save current tty state */
193 save_state();
194
195 /* Confgure tty */
196 memcpy(&state, &saved_state, sizeof(state));
197 if (!(opt & OPT_m_nonraw)) { /* raw not suppressed */
198 memset(&state.c_cc, 0, sizeof(state.c_cc));
199 state.c_cc[VMIN] = 1;
200 state.c_iflag = IGNBRK | IGNPAR;
201 state.c_oflag = 0;
202 state.c_lflag = 0;
203 state.c_cflag = CS8 | HUPCL | CREAD
204 | ((opt & OPT_L_local) ? CLOCAL : 0)
205 | ((opt & OPT_F_noflow) ? 0 : CRTSCTS);
206 }
207
208 if (opt & OPT_s_baud) {
209 cfsetispeed(&state, baud_code);
210 cfsetospeed(&state, baud_code);
211 }
212
213 set_state(&state, encap);
214
215 /* Exit now if option -e was passed */
216 if (opt & OPT_e_quit)
217 return 0;
218
219 /* If we're not requested to watch, just keep descriptor open
220 * till we are killed */
221 if (!(opt & OPT_h_watch))
222 while (1)
223 sleep(24*60*60);
224
225 /* Watch line for hangup */
226 while (1) {
227 if (ioctl(handle, TIOCMGET, &i) < 0 || !(i & TIOCM_CAR))
228 goto no_carrier;
229 sleep(15);
230 }
231
232 no_carrier:
233
234 /* Execute command on hangup */
235 if (opt & OPT_c_extcmd)
236 system(extcmd);
237
238 /* Restore states and exit */
239 restore_state_and_exit(0);
240}