/* 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.2 kb)"
//config:	default y
//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_simple_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);
	sleep1();

	/* 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 = getopt32(argv, "^" "p:s:c:ehmLF" "\0" "=1",
				&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_simple_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);
}
