[PATCH] slattach applet for busybox 1.4.1 (this is the GOOD one)
Ignacio García Pérez
iggarpe at terra.es
Thu Feb 22 11:29:13 UTC 2007
Bernhard Fischer escribió:
Thank you for the corrections. Question is, should I correct the code
and submit a new patch?
I ask because that would be practical if I was to maintain the slattach
applet code, which as far as I know I'm not.
Nacho.
> On Fri, Feb 16, 2007 at 12:21:57PM +0100, Ignacio García Pérez wrote:
>
>> Sorry, attached the wrong patch in previous message. This is the good one.
>>
>> As I already said, would be nice to rewrite the option parsing code to
>> make use of the libbb functions.
>>
>> Regards.
>>
>>
>>
>>
>
>
>> diff -urN busybox-1.4.1/include/applets.h busybox-1.4.1-modified/include/applets.h
>> --- busybox-1.4.1/include/applets.h 2007-01-24 22:34:48.000000000 +0100
>> +++ busybox-1.4.1-modified/include/applets.h 2007-02-16 11:45:33.000000000 +0100
>> @@ -262,6 +262,7 @@
>> USE_FEATURE_SH_IS_LASH(APPLET_NOUSAGE(sh, lash, _BB_DIR_BIN, _BB_SUID_NEVER))
>> USE_FEATURE_SH_IS_MSH(APPLET_NOUSAGE(sh, msh, _BB_DIR_BIN, _BB_SUID_NEVER))
>> USE_SHA1SUM(APPLET_ODDNAME(sha1sum, md5_sha1_sum, _BB_DIR_USR_BIN, _BB_SUID_NEVER, sha1sum))
>> +USE_SLATTACH(APPLET(slattach, _BB_DIR_SBIN, _BB_SUID_NEVER))
>> USE_SLEEP(APPLET(sleep, _BB_DIR_BIN, _BB_SUID_NEVER))
>> USE_SOFTLIMIT(APPLET_ODDNAME(softlimit, chpst, _BB_DIR_USR_BIN, _BB_SUID_NEVER, softlimit))
>> USE_SORT(APPLET(sort, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
>> diff -urN busybox-1.4.1/include/usage.h busybox-1.4.1-modified/include/usage.h
>> --- busybox-1.4.1/include/usage.h 2007-01-24 22:34:48.000000000 +0100
>> +++ busybox-1.4.1-modified/include/usage.h 2007-02-16 11:44:10.000000000 +0100
>> @@ -2788,6 +2788,20 @@
>> " -s Don't output anything, status code shows success\n" \
>> " -w Warn about improperly formatted SHA1 checksum lines")
>>
>> +#define slattach_trivial_usage \
>> + "[-cehmLF] [-s speed] [-p protocol] DEVICEs"
>> +#define slattach_full_usage \
>> + "Attach network interface(s) to serial line(s).\n" \
>> + "Options:\n" \
>> + "\t-p\tset a specific kind of protocol (slip, cslip, slip6, clisp6 or adaptive).\n" \
>> + "\t-s\tset a specific line speed.\n"
>> + "\t-c\texecute a command when the line is hung up\n" \
>> + "\t-e\texit right after initializing device.\n" \
>> + "\t-h\texit when the carrier is lost.\n" \
>> + "\t-m\tdo NOT initialize the line in raw 8 bits mode.\n" \
>> + "\t-L\tenable 3-wire operation.\n" \
>> + "\t-F\tdisable RTS/CTS flow control.\n" \
>> +
>> #define sleep_trivial_usage \
>> USE_FEATURE_FANCY_SLEEP("[") "N" USE_FEATURE_FANCY_SLEEP("]...")
>> #define sleep_full_usage \
>> diff -urN busybox-1.4.1/networking/Config.in busybox-1.4.1-modified/networking/Config.in
>> --- busybox-1.4.1/networking/Config.in 2007-01-24 22:34:34.000000000 +0100
>> +++ busybox-1.4.1-modified/networking/Config.in 2007-02-16 11:47:50.000000000 +0100
>> @@ -523,6 +523,12 @@
>> help
>> Route displays or manipulates the kernel's IP routing tables.
>>
>> +config SLATTACH
>> + bool "slattach"
>> + default n
>> + help
>> + Slattach is a small utility to attach network interfaces to serial lines.
>> +
>> config TELNET
>> bool "telnet"
>> default n
>> diff -urN busybox-1.4.1/networking/Kbuild busybox-1.4.1-modified/networking/Kbuild
>> --- busybox-1.4.1/networking/Kbuild 2007-01-24 22:34:34.000000000 +0100
>> +++ busybox-1.4.1-modified/networking/Kbuild 2007-02-16 11:38:37.000000000 +0100
>> @@ -32,6 +32,7 @@
>> lib-$(CONFIG_PING) += ping.o
>> lib-$(CONFIG_PING6) += ping6.o
>> lib-$(CONFIG_ROUTE) += route.o
>> +lib-$(CONFIG_SLATTACH) += slattach.o
>> lib-$(CONFIG_TELNET) += telnet.o
>> lib-$(CONFIG_TELNETD) += telnetd.o
>> lib-$(CONFIG_TFTP) += tftp.o
>> diff -urN busybox-1.4.1/networking/slattach.c busybox-1.4.1-modified/networking/slattach.c
>> --- busybox-1.4.1/networking/slattach.c 1970-01-01 01:00:00.000000000 +0100
>> +++ busybox-1.4.1-modified/networking/slattach.c 2007-02-16 12:03:18.000000000 +0100
>> @@ -0,0 +1,266 @@
>> +/*
>> + * Stripped down version of net-tools for busybox.
>> + *
>> + * Author: Ignacio Garcia Perez (iggarpe at gmail dot com)
>> + *
>> + * License: GPLv2 or later, see LICENSE file in this tarball.
>> + *
>> + * There are some differences from the standard net-tools slattach:
>> + *
>> + * - The -l option is not supported.
>> + *
>> + * - Several devices can be specified in the command line. This is
>> + * very useful if you are handling many identical serial lines since
>> + * only one process is necessary to configure them all.
>> + *
>> + * - The -F options allows disabling of RTS/CTS flow control.
>> + *
>> + */
>> +
>> +#include <unistd.h>
>> +#include <stdlib.h>
>> +#include <string.h>
>> +#include <stdio.h>
>> +#include <signal.h>
>> +#include <errno.h>
>> +#include <sys/socket.h>
>> +#include <sys/types.h>
>> +#include <sys/stat.h>
>> +#include <fcntl.h>
>> +#include <termios.h>
>> +#include <sys/ioctl.h>
>> +
>> +#include "libbb.h"
>> +
>> +struct tty {
>> + const char * device;
>> + int handle;
>> + int saved_disc;
>> + struct termios saved_state;
>> + struct tty * next;
>> +};
>> +
>> +static struct tty *_tty_head = NULL;
>> +static struct tty *_tty_tail = NULL;
>> +
>> +/* Line discipline code table */
>> +
>> +static struct { const char *name; int code; } _proto [] = {
>> + { "slip", 0 },
>> + { "cslip", 1 },
>> + { "slip6", 2 },
>> + { "cslip6", 3 },
>> + { "adaptive", 8 },
>> + { NULL }
>> +};
>> +
>> +/*
>> + * Save tty state and line discipline
>> + */
>> +
>> +static int _save_state (struct tty *t) {
>> +
>> + if (t->handle < 0) return 0;
>> +
>> + if (tcgetattr(t->handle, &t->saved_state) < 0) /* Save line status */
>> + { bb_perror_msg("get state"); return -1; }
>> +
>> + if (ioctl(t->handle, TIOCGETD, &t->saved_disc) < 0) /* Save line discipline */
>> + { bb_perror_msg("get discipline"); return -1; }
>> +
>> + return 0;
>> +}
>> +
>> +/*
>> + * Set tty state, line discipline and encapsulation
>> + */
>> +
>> +static int _set_state (struct tty *t, struct termios *state, int encap) {
>> +
>> + int disc = N_SLIP;
>> +
>> + if (t->handle < 0) return 0;
>> +
>> + if (tcsetattr(t->handle, TCSANOW, state) < 0) /* Set line status */
>> + { bb_perror_msg("set state"); return -1; }
>> +
>> + if (ioctl(t->handle, TIOCSETD, &disc) < 0) /* Set line discliple (N_SLIP always) */
>> + { bb_perror_msg("set discipline"); return -1; }
>> +
>> + if (ioctl(t->handle, SIOCSIFENCAP, &encap) < 0) /* Set encapsulation (SLIP, CSLIP, etc) */
>> + { bb_perror_msg("set encapsulation"); return -1; }
>> +
>> + return 0;
>> +}
>> +
>> +/*
>> + * Restore state and line discipline for ALL managed ttys
>> + *
>> + * Restoring ALL managed ttys is the only way to have a single
>> + * hangup delay.
>> + *
>> + */
>> +
>> +static int _restore_state_and_close (void) {
>> +
>> + struct tty *t;
>> + struct termios state;
>> +
>> + for (t = _tty_head; t != NULL; t = t->next) if (t->handle >= 0) {
>> +
>> + if (ioctl(t->handle, TIOCSETD, &t->saved_disc) < 0) /* Restore line discipline */
>> + { bb_perror_msg("set discipline"); return -1; }
>> +
>> + memcpy(&state, &t->saved_state, sizeof(state)); /* Hangup */
>> + cfsetispeed(&state, B0);
>> + cfsetospeed(&state, B0);
>> + if (tcsetattr(t->handle, TCSANOW, &state) < 0)
>> + { bb_perror_msg("set state"); return -1; }
>> + }
>> +
>> + sleep(1); /* The sleep time does not depend on the number of managed ttys */
>> +
>> + for (t = _tty_head; t != NULL; t = t->next) if (t->handle >= 0) {
>> +
>> + if (tcsetattr(t->handle, TCSANOW, &t->saved_state) < 0) /* Restore line status */
>> + { perror("set state"); return -1; }
>> +
>> + close(t->handle); t->handle = -1;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static void _sig_handler (int signo) {
>> + if (_restore_state_and_close() < 0) sleep_and_die();
>> + exit(0);
>> +}
>> +
>> +int slattach_main (int argc, char **argv) {
>> +
>> + int i, encap;
>> + struct tty *t;
>> + struct termios state;
>> + char buf [PATH_MAX];
>>
>
> That's a large buffer, imho. xmalloc() or make it
> RESERVE_CONFIG_BUFFER(buf,PATH_MAX)
>
>
>> +
>> + const char *proto = "cslip"; /* Protocol */
>> + const char *extcmd = NULL; /* Command to execute after hangup */
>> +
>> + int baud = -1; /* Line baud rate (value) */
>> + int baud_code = -1; /* Line baud rate (system code) */
>> + int local = 0; /* Local mode (disable carrier watch) */
>> + int quit = 0; /* Initialize and exit */
>> + int watch = 0; /* watch for line hangup */
>> + int raw = 1; /* Initialize line in raw 8 bit mode */
>> + int flow = 1; /* Disable RTS/CTS flow control (not in net-tools slattach !!!) */
>>
>
> most of these should use one variable and mask their bits in.
>
>> +
>> + /* Parse command line options */
>> + /* TODO: use bb lib getopt_whatever? */
>>
>
> getopt32, yes.
>
> The block below is just too bloated.
>
>> +
>> + for (i = 1; i < argc; i++) {
>> +
>> + if (argv[i][0] == '-') switch (argv[i][1]) {
>> + case 'p': proto = argv[++i]; break;
>> + case 's': baud = atoi(argv[++i]); break;
>> + case 'c': extcmd = argv[++i]; break;
>> + case 'e': quit = 1; break;
>> + case 'h': watch = 1; break;
>> + case 'm': raw = 0; break;
>> + case 'L': local = 1; break;
>> + case 'F': flow = 0; break;
>> + default: bb_error_msg_and_die("invalid option %s", argv[i]);
>> + }
>> +
>> + else {
>> + t = (struct tty *)malloc(sizeof(struct tty));
>> + if (t == NULL) bb_error_msg_and_die("not enough memory");
>>
>
> No. xmalloc() instead
>
>
>> +
>> + t->device = argv[i];
>> + t->handle = -1;
>> + t->next = NULL;
>> +
>> + if (_tty_head == NULL) _tty_head = _tty_tail = t;
>> + else { _tty_tail->next = t; _tty_tail = t; }
>> + }
>> + }
>> +
>> + if (_tty_head == NULL) bb_show_usage();
>> +
>> + for (i = 0; _proto[i].name != NULL; i++)
>> + if (!strcmp(_proto[i].name, proto)) break;
>>
>
> index_in_str_array() instead
>
>
>> + if (_proto[i].name == NULL) bb_error_msg_and_die("invalid protocol %s", proto);
>> + encap = _proto[i].code;
>> +
>> + baud_code = tty_value_to_baud(baud);
>> + if (baud_code < 0) bb_error_msg_and_die("invalid baud rate %i", baud);
>> +
>> + /* Trap signals in order to restore tty states upon exit */
>> +
>> + if (!quit) {
>> + signal(SIGHUP, _sig_handler);
>> + signal(SIGINT, _sig_handler);
>> + signal(SIGQUIT, _sig_handler);
>> + signal(SIGTERM, _sig_handler);
>> + }
>> +
>> + /* Configure ttys */
>> +
>> + for (t = _tty_head; t != NULL; t = t->next) {
>> +
>> + t->handle = open(t->device, O_RDWR | O_NDELAY);
>> + if (t->handle < 0) {
>> + snprintf(buf, sizeof(buf), "/dev/%s", t->device);
>>
>
> concat_path_file() instead. Should make that huge buf from above
> superfluous.
>
>
>> + t->handle = open(buf, O_RDWR | O_NDELAY);
>> + if (t->handle < 0) bb_perror_msg_and_die("open %s", t->device);
>> + }
>> +
>> + if (_save_state(t) < 0) sleep_and_die();
>> +
>> + memcpy(&state, &t->saved_state, sizeof(state));
>> +
>> + if (raw) {
>> + memset(&state.c_cc, 0, sizeof(state.c_cc));
>> + state.c_cc[VMIN] = 1;
>> + state.c_iflag = IGNBRK | IGNPAR;
>> + state.c_oflag = 0;
>> + state.c_lflag = 0;
>> + state.c_cflag = CS8 | HUPCL | CREAD
>> + | (local ? CLOCAL : 0) | (flow ? CRTSCTS : 0);
>> + }
>> +
>> + if (baud_code >= 0) {
>>
>
> Didn't we check above that boud_rate not is < 0 above? drop it then.
>
>
>> + cfsetispeed(&state, baud_code);
>> + cfsetospeed(&state, baud_code);
>> + }
>> +
>> + if (_set_state(t, &state, encap) < 0)
>> + { _restore_state_and_close(); sleep_and_die(); }
>> + }
>> +
>> + /* Exit now if option -e was passed */
>> +
>> + if (quit) exit(0);
>> +
>> + /* Watch line for hangup */
>> +
>> + for (;;) {
>> +
>> + if (watch)
>> + for (t = _tty_head; t != NULL; t = t->next)
>> + if (ioctl(t->handle, TIOCMGET, &i) < 0 || !(i & TIOCM_CAR))
>> + quit = 1;
>> +
>> + if (quit) break;
>>
>
> would a while (!option_mask32 & QUIT) be smaller?
>
>
>> + sleep(15);
>> + }
>> +
>> + /* Execute command on hangup */
>> +
>> + if (extcmd != NULL) system(extcmd);
>> +
>> + /* Restore states and exit */
>> +
>> + _restore_state_and_close();
>> + return 0;
>> +}
>> +
>>
>
>
>
More information about the busybox
mailing list