/* vi: set sw=4 ts=4: */
/*
 * Stripped down version of net-tools for busybox.
 *
 * Author: Ignacio Garcia Perez (iggarpe at gmail dot com)
 *
 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
 *
 * There are some differences from the standard net-tools slattach:
 *
 * - The -l option is not supported.
 *
 * - The -F options allows disabling of RTS/CTS flow control.
 */
//config:config SLATTACH
//config:	bool "slattach (6.1 kb)"
//config:	default y
//config:	select PLATFORM_LINUX
//config:	help
//config:	slattach configures serial line as SLIP network interface.

//applet:IF_SLATTACH(APPLET(slattach, BB_DIR_SBIN, BB_SUID_DROP))
/* shouldn't be NOEXEC: may sleep indefinitely */

//kbuild:lib-$(CONFIG_SLATTACH) += slattach.o

//usage:#define slattach_trivial_usage
//usage:       "[-ehmLF] [-c SCRIPT] [-s BAUD] [-p PROTOCOL] SERIAL_DEVICE"
//usage:#define slattach_full_usage "\n\n"
//usage:       "Configure serial line as SLIP network interface\n"
//usage:     "\n	-p PROT	Protocol: slip, cslip (default), slip6, clisp6, adaptive"
//usage:     "\n	-s BAUD	Line speed"
//usage:     "\n	-e	Exit after initialization"
//usage:     "\n	-h	Exit if carrier is lost (else never exits)"
//usage:     "\n	-c PROG	Run PROG on carrier loss"
//usage:     "\n	-m	Do NOT set raw 8bit mode"
//usage:     "\n	-L	Enable 3-wire operation"
//usage:     "\n	-F	Disable RTS/CTS flow control"

#include "libbb.h"
#include "common_bufsiz.h"
#include "libiproute/utils.h" /* invarg_1_to_2() */

struct globals {
	int saved_disc;
	struct termios saved_state;
} FIX_ALIASING;
#define G (*(struct globals*)bb_common_bufsiz1)
#define INIT_G() do { setup_common_bufsiz(); } while (0)

#define serial_fd 3

static int tcsetattr_serial_or_warn(struct termios *state)
{
	int ret;

	ret = tcsetattr(serial_fd, TCSANOW, state);
	if (ret != 0) {
		bb_perror_msg("tcsetattr");
		return 1; /* used as exitcode */
	}
	return ret; /* 0 */
}

static void restore_state_and_exit(int exitcode) NORETURN;
static void restore_state_and_exit(int exitcode)
{
	struct termios state;

	/* Restore line discipline */
	if (ioctl_or_warn(serial_fd, TIOCSETD, &G.saved_disc)) {
		exitcode = 1;
	}

	/* Hangup */
	memcpy(&state, &G.saved_state, sizeof(state));
	cfsetispeed(&state, B0);
	cfsetospeed(&state, B0);
	exitcode |= tcsetattr_serial_or_warn(&state);
	sleep(1);

	/* Restore line status */
	if (tcsetattr_serial_or_warn(&G.saved_state))
		exit(EXIT_FAILURE);

	if (ENABLE_FEATURE_CLEAN_UP)
		close(serial_fd);

	exit(exitcode);
}

static void sig_handler(int signo UNUSED_PARAM)
{
	restore_state_and_exit(EXIT_SUCCESS);
}

int slattach_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int slattach_main(int argc UNUSED_PARAM, char **argv)
{
	/* Line discipline code table */
	static const char proto_names[] ALIGN1 =
		"slip\0"        /* 0 */
		"cslip\0"       /* 1 */
		"slip6\0"       /* 2 */
		"cslip6\0"      /* 3 */
		"adaptive\0"    /* 8 */
		;
	static const int int_N_SLIP = N_SLIP;

	int encap, opt, fd;
	struct termios state;
	const char *proto = "cslip";
	const char *extcmd;   /* Command to execute after hangup */
	const char *baud_str;
	int baud_code = baud_code; /* for compiler */

	enum {
		OPT_p_proto  = 1 << 0,
		OPT_s_baud   = 1 << 1,
		OPT_c_extcmd = 1 << 2,
		OPT_e_quit   = 1 << 3,
		OPT_h_watch  = 1 << 4,
		OPT_m_nonraw = 1 << 5,
		OPT_L_local  = 1 << 6,
		OPT_F_noflow = 1 << 7
	};

	INIT_G();

	/* Parse command line options */
	opt_complementary = "=1";
	opt = getopt32(argv, "p:s:c:ehmLF", &proto, &baud_str, &extcmd);
	/*argc -= optind;*/
	argv += optind;

	encap = index_in_strings(proto_names, proto);
	if (encap < 0)
		invarg_1_to_2(proto, "protocol");
	if (encap > 3)
		encap = 8;

	/* We want to know if the baud rate is valid before we start touching the ttys */
	if (opt & OPT_s_baud) {
		baud_code = tty_value_to_baud(xatoi(baud_str));
		if (baud_code < 0)
			invarg_1_to_2(baud_str, "baud rate");
	}

	/* Open tty */
	fd = open(*argv, O_RDWR | O_NDELAY);
	if (fd < 0) {
		char *buf = concat_path_file("/dev", *argv);
		fd = xopen(buf, O_RDWR | O_NDELAY);
		/* maybe if (ENABLE_FEATURE_CLEAN_UP) ?? */
		free(buf);
	}
	xmove_fd(fd, serial_fd);

	/* Save current tty state */
	if (tcgetattr(serial_fd, &G.saved_state) != 0)
		bb_perror_msg_and_die("tcgetattr");
	/* Save line discipline */
	xioctl(serial_fd, TIOCGETD, &G.saved_disc);

	/* Trap signals in order to restore tty states upon exit */
	if (!(opt & OPT_e_quit)) {
		bb_signals(0
			+ (1 << SIGHUP)
			+ (1 << SIGINT)
			+ (1 << SIGQUIT)
			+ (1 << SIGTERM)
			, sig_handler);
	}

	/* Configure tty */
	memcpy(&state, &G.saved_state, sizeof(state));
	if (!(opt & OPT_m_nonraw)) { /* raw not suppressed */
		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
		              | ((opt & OPT_L_local) ? CLOCAL : 0)
		              | ((opt & OPT_F_noflow) ? 0 : CRTSCTS);
		cfsetispeed(&state, cfgetispeed(&G.saved_state));
		cfsetospeed(&state, cfgetospeed(&G.saved_state));
	}
	if (opt & OPT_s_baud) {
		cfsetispeed(&state, baud_code);
		cfsetospeed(&state, baud_code);
	}
	/* Set line status */
	if (tcsetattr_serial_or_warn(&state))
		goto bad;
	/* Set line disclipline (N_SLIP always) */
	if (ioctl_or_warn(serial_fd, TIOCSETD, (void*)&int_N_SLIP))
		goto bad;
	/* Set encapsulation (SLIP, CSLIP, etc) */
	if (ioctl_or_warn(serial_fd, SIOCSIFENCAP, &encap))
		goto bad;

	/* Exit now if option -e was passed */
	if (opt & OPT_e_quit)
		return EXIT_SUCCESS;

	/* If we're not requested to watch, just keep descriptor open
	 * until we are killed */
	if (!(opt & OPT_h_watch))
		while (1)
			sleep(24*60*60);

	/* Watch line for hangup */
	while (1) {
		int modem_stat;
		if (ioctl(serial_fd, TIOCMGET, &modem_stat))
			break;
		if (!(modem_stat & TIOCM_CAR))
			break;
		sleep(15);
	}

	/* Execute command on hangup */
	if (opt & OPT_c_extcmd)
		system(extcmd);

	/* Restore states and exit */
	restore_state_and_exit(EXIT_SUCCESS);
 bad:
	restore_state_and_exit(EXIT_FAILURE);
}
