[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