/* stty.c - Get/set terminal configuration.
 *
 * Copyright 2017 The Android Open Source Project.
 *
 * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/stty.html

USE_STTY(NEWTOY(stty, "?aF:g[!ag]", TOYFLAG_BIN))

config STTY
  bool "stty"
  default n
  help
    usage: stty [-ag] [-F device] SETTING...

    Get/set terminal configuration.

    -F	Open device instead of stdin
    -a	Show all current settings (default differences from "sane")
    -g	Show all current settings usable as input to stty

    Special characters (syntax ^c or undef): intr quit erase kill eof eol eol2
    swtch start stop susp rprnt werase lnext discard

    Control/input/output/local settings as shown by -a, '-' prefix to disable

    Combo settings: cooked/raw, evenp/oddp/parity, nl, ek, sane

    N	set input and output speed (ispeed N or ospeed N for just one)
    cols N	set number of columns
    rows N	set number of rows
    line N	set line discipline
    min N	set minimum chars per read
    time N	set read timeout
    speed	show speed only
    size	show size only
*/

#define FOR_stty
#include "toys.h"

#include <linux/tty.h>

GLOBALS(
  char *device;

  int fd, col;
  unsigned output_cols;
)

static const int bauds[] = {
  0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600,
  19200, 38400, 57600, 115200, 230400, 460800, 500000, 576000, 921600,
  1000000, 1152000, 1500000, 2000000, 2500000, 3000000, 3500000, 4000000
};

static int baud(speed_t speed)
{
  if (speed&CBAUDEX) speed=(speed&~CBAUDEX)+15;
  return bauds[speed];
}

static speed_t speed(int baud)
{
  int i;

  for (i=0;i<ARRAY_LEN(bauds);i++) if (bauds[i] == baud) break;
  if (i == ARRAY_LEN(bauds)) error_exit("unknown speed: %d", baud);
  return i+4081*(i>16);
}

struct flag {
  char *name;
  int value;
  int mask;
};

static const struct flag chars[] = {
  { "intr", VINTR }, { "quit", VQUIT }, { "erase", VERASE }, { "kill", VKILL },
  { "eof", VEOF }, { "eol", VEOL }, { "eol2", VEOL2 }, { "swtch", VSWTC },
  { "start", VSTART }, { "stop", VSTOP }, { "susp", VSUSP },
  { "rprnt", VREPRINT }, { "werase", VWERASE }, { "lnext", VLNEXT },
  { "discard", VDISCARD }, { "min", VMIN }, { "time", VTIME },
};

static const struct flag cflags[] = {
  { "parenb", PARENB }, { "parodd", PARODD }, { "cmspar", CMSPAR },
  { "cs5", CS5, CSIZE }, { "cs6", CS6, CSIZE }, { "cs7", CS7, CSIZE },
  { "cs8", CS8, CSIZE }, { "hupcl", HUPCL }, { "cstopb", CSTOPB },
  { "cread", CREAD }, { "clocal", CLOCAL }, { "crtscts", CRTSCTS },
};

static const struct flag iflags[] = {
  { "ignbrk", IGNBRK }, { "brkint", BRKINT }, { "ignpar", IGNPAR },
  { "parmrk", PARMRK }, { "inpck", INPCK }, { "istrip", ISTRIP },
  { "inlcr", INLCR }, { "igncr", IGNCR }, { "icrnl", ICRNL }, { "ixon", IXON },
  { "ixoff", IXOFF }, { "iuclc", IUCLC }, { "ixany", IXANY },
  { "imaxbel", IMAXBEL }, { "iutf8", IUTF8 },
};

static const struct flag oflags[] = {
  { "opost", OPOST }, { "olcuc", OLCUC }, { "ocrnl", OCRNL },
  { "onlcr", ONLCR }, { "onocr", ONOCR }, { "onlret", ONLRET },
  { "ofill", OFILL }, { "ofdel", OFDEL }, { "nl0", NL0, NLDLY },
  { "nl1", NL1, NLDLY }, { "cr0", CR0, CRDLY }, { "cr1", CR1, CRDLY },
  { "cr2", CR2, CRDLY }, { "cr3", CR3, CRDLY }, { "tab0", TAB0, TABDLY },
  { "tab1", TAB1, TABDLY }, { "tab2", TAB2, TABDLY }, { "tab3", TAB3, TABDLY },
  { "bs0", BS0, BSDLY }, { "bs1", BS1, BSDLY }, { "vt0", VT0, VTDLY },
  { "vt1", VT1, VTDLY }, { "ff0", FF0, FFDLY }, { "ff1", FF1, FFDLY },
};

static const struct flag lflags[] = {
  { "isig", ISIG }, { "icanon", ICANON }, { "iexten", IEXTEN },
  { "echo", ECHO }, { "echoe", ECHOE }, { "echok", ECHOK },
  { "echonl", ECHONL }, { "noflsh", NOFLSH }, { "xcase", XCASE },
  { "tostop", TOSTOP }, { "echoprt", ECHOPRT }, { "echoctl", ECHOCTL },
  { "echoke", ECHOKE }, { "flusho", FLUSHO }, { "extproc", EXTPROC },
};

static const struct synonym {
  char *from;
  char *to;
} synonyms[] = {
  { "cbreak", "-icanon" }, { "-cbreak", "icanon" }, { "-cooked", "raw" },
  { "crterase", "echoe" }, { "-crterase", "-echoe" }, { "crtkill", "echoke" },
  { "-crtkill", "-echoke" }, { "ctlecho", "echoctl" }, { "-tandem", "-ixoff" },
  { "-ctlecho", "-echoctl" }, { "hup", "hupcl" }, { "-hup", "-hupcl" },
  { "prterase", "echoprt" }, { "-prterase", "-echoprt" }, { "-raw", "cooked" },
  { "tabs", "tab0" }, { "-tabs", "tab3" }, { "tandem", "ixoff" },
};

static void out(const char *fmt, ...)
{
  va_list va;
  int len;
  char *prefix = " ";

  va_start(va, fmt);
  len = vsnprintf(toybuf, sizeof(toybuf), fmt, va);
  va_end(va);

  if (TT.output_cols == 0) {
    TT.output_cols = 80;
    terminal_size(&TT.output_cols, NULL);
  }

  if (TT.col == 0 || *fmt == '\n') prefix = "";
  else if (TT.col + 1 + len >= TT.output_cols) {
    prefix = "\n";
    TT.col = 0;
  }
  xprintf("%s%s", prefix, toybuf);

  if (toybuf[len-1] == '\n') TT.col = 0;
  else TT.col += strlen(prefix) + len;
}

static void show_flags(tcflag_t actual, tcflag_t sane,
                       const struct flag *flags, int len)
{
  int i, j, value, mask;

  // Implement -a by ensuring that sane != actual so we'll show everything.
  if (toys.optflags&FLAG_a) sane = ~actual;

  for (i=j=0;i<len;i++) {
    value = flags[i].value;
    if ((mask = flags[i].mask)) {
      if ((actual&mask)==value && (sane&mask)!=value) {
        out("%s", flags[i].name);
        j++;
      }
    } else {
      if ((actual&value) != (sane&value)) {
        out("%s%s", actual&value?"":"-", flags[i].name);
        j++;
      }
    }
  }
  if (j) out("\n");
}

static void show_size(int verbose)
{
  struct winsize ws;

  if (ioctl(TT.fd, TIOCGWINSZ, &ws)) perror_exit("TIOCGWINSZ %s", TT.device);
  out(verbose ? "rows %d; columns %d;" : "%d %d\n", ws.ws_row, ws.ws_col);
}

static void show_speed(struct termios *t, int verbose)
{
  int ispeed = baud(cfgetispeed(t)), ospeed = baud(cfgetospeed(t));
  char *fmt = verbose ? "ispeed %d baud; ospeed %d baud;" : "%d %d\n";

  if (ispeed == ospeed) fmt += (verbose ? 17 : 3);
  out(fmt, ispeed, ospeed);
}

static int get_arg(int *i, long long low, long long high)
{
  (*i)++;
  if (!toys.optargs[*i]) error_exit("missing arg");
  return atolx_range(toys.optargs[*i], low, high);
}

static int set_flag(tcflag_t *f, const struct flag *flags, int len,
                    char *name, int on)
{
  int i;

  for (i=0;i<len;i++) {
    if (!strcmp(flags[i].name, name)) {
      if (on) {
        *f &= ~flags[i].mask;
        *f |= flags[i].value;
      } else {
        if (flags[i].mask) error_exit("%s isn't a boolean", name);
        *f &= ~flags[i].value;
      }
      return 1;
    }
  }
  return 0;
}

static void set_option(struct termios *new, char *option)
{
  int on = (*option != '-');

  if (!on) option++;
  if (!set_flag(&new->c_cflag, cflags, ARRAY_LEN(cflags), option, on) &&
      !set_flag(&new->c_iflag, iflags, ARRAY_LEN(iflags), option, on) &&
      !set_flag(&new->c_oflag, oflags, ARRAY_LEN(oflags), option, on) &&
      !set_flag(&new->c_lflag, lflags, ARRAY_LEN(lflags), option, on))
    error_exit("unknown option: %s", option);
}

static void set_options(struct termios* new, ...)
{
  va_list va;
  char *option;

  va_start(va, new);
  while ((option = va_arg(va, char *))) set_option(new, option);
  va_end(va);
}

static void set_size(int is_rows, unsigned short value)
{
  struct winsize ws;

  if (ioctl(TT.fd, TIOCGWINSZ, &ws)) perror_exit("TIOCGWINSZ %s", TT.device);
  if (is_rows) ws.ws_row = value;
  else ws.ws_col = value;
  if (ioctl(TT.fd, TIOCSWINSZ, &ws)) perror_exit("TIOCSWINSZ %s", TT.device);
}

static int set_special_character(struct termios *new, int *i, char *char_name)
{
  int j;

  // The -2 is to ignore VMIN and VTIME, which are just unsigned integers.
  for (j=0;j<ARRAY_LEN(chars)-2;j++) {
    if (!strcmp(chars[j].name, char_name)) {
      char *arg = toys.optargs[++(*i)];
      cc_t ch;

      if (!arg) error_exit("missing arg");
      if (!strcmp(arg, "^-") || !strcmp(arg, "undef")) ch = _POSIX_VDISABLE;
      else if (!strcmp(arg, "^?")) ch = 0x7f;
      else if (arg[0] == '^' && arg[2] == 0) ch = (toupper(arg[1])-'@');
      else if (!arg[1]) ch = arg[0];
      else error_exit("invalid arg: %s", arg);
      xprintf("setting %s to %s (%02x)\n", char_name, arg, ch);
      new->c_cc[chars[j].value] = ch;
      return 1;
    }
  }
  return 0;
}

static void make_sane(struct termios *t)
{
  // POSIX has no opinion about what "sane" means. From "man stty".
  // "cs8" is missing from the man page, but needed to get identical results.
  set_options(t, "cread", "-ignbrk", "brkint", "-inlcr", "-igncr", "icrnl",
    "icanon", "iexten", "echo", "echoe", "echok", "-echonl", "-noflsh",
    "-ixoff", "-iutf8", "-iuclc", "-ixany", "imaxbel", "-xcase", "-olcuc",
    "-ocrnl", "opost", "-ofill", "onlcr", "-onocr", "-onlret", "nl0", "cr0",
    "tab0", "bs0", "vt0", "ff0", "isig", "-tostop", "-ofdel", "-echoprt",
    "echoctl", "echoke", "-extproc", "-flusho", "cs8", NULL);
  memset(t->c_cc, 0, NCCS);
  t->c_cc[VINTR] = 0x3;
  t->c_cc[VQUIT] = 0x1c;
  t->c_cc[VERASE] = 0x7f;
  t->c_cc[VKILL] = 0x15;
  t->c_cc[VEOF] = 0x4;
  t->c_cc[VTIME] = 0;
  t->c_cc[VMIN] = 1;
  t->c_cc[VSWTC] = 0;
  t->c_cc[VSTART] = 0x11;
  t->c_cc[VSTOP] = 0x13;
  t->c_cc[VSUSP] = 0x1a;
  t->c_cc[VEOL] = 0;
  t->c_cc[VREPRINT] = 0x12;
  t->c_cc[VDISCARD] = 0xf;
  t->c_cc[VWERASE] = 0x17;
  t->c_cc[VLNEXT] = 0x16;
  t->c_cc[VEOL2] = 0;
}

static void xtcgetattr(struct termios *t)
{
  if (tcgetattr(TT.fd, t)) perror_exit("tcgetattr %s", TT.device);
}

static void do_stty()
{
  struct termios old, sane;
  int i, j, n;

  xtcgetattr(&old);

  if (*toys.optargs) {
    struct termios new = old;

    for (i=0; toys.optargs[i]; i++) {
      char *arg = toys.optargs[i];

      if (!strcmp(arg, "size")) show_size(0);
      else if (!strcmp(arg, "speed")) show_speed(&old, 0);
      else if (!strcmp(arg, "line")) new.c_line = get_arg(&i, N_TTY, NR_LDISCS);
      else if (!strcmp(arg, "min")) new.c_cc[VMIN] = get_arg(&i, 0, 255);
      else if (!strcmp(arg, "time")) new.c_cc[VTIME] = get_arg(&i, 0, 255);
      else if (atoi(arg) > 0) {
        int new_speed = speed(atolx_range(arg, 0, 4000000));

        cfsetispeed(&new, new_speed);
        cfsetospeed(&new, new_speed);
      } else if (!strcmp(arg, "ispeed"))
        cfsetispeed(&new, speed(get_arg(&i, 0, 4000000)));
      else if (!strcmp(arg, "ospeed"))
        cfsetospeed(&new, speed(get_arg(&i, 0, 4000000)));
      else if (!strcmp(arg, "rows")) set_size(1, get_arg(&i, 0, USHRT_MAX));
      else if (!strcmp(arg, "cols") || !strcmp(arg, "columns"))
        set_size(0, get_arg(&i, 0, USHRT_MAX));
      else if (sscanf(arg, "%x:%x:%x:%x:%n", &new.c_iflag, &new.c_oflag,
                        &new.c_cflag, &new.c_lflag, &n) == 4)
      {
        int value;

        arg += n;
        for (j=0;j<NCCS;j++) {
          if (sscanf(arg, "%x%n", &value, &n) != 1) error_exit("bad -g string");
          new.c_cc[j] = value;
          arg += n+1;
        }
      } else if (set_special_character(&new, &i, arg));
        // Already done as a side effect.
      else if (!strcmp(arg, "cooked"))
        set_options(&new, "brkint", "ignpar", "istrip", "icrnl", "ixon",
          "opost", "isig", "icanon", NULL);
      else if (!strcmp(arg, "evenp") || !strcmp(arg, "parity"))
        set_options(&new, "parenb", "cs7", "-parodd", NULL);
      else if (!strcmp(arg, "oddp"))
        set_options(&new, "parenb", "cs7", "parodd", NULL);
      else if (!strcmp(arg, "-parity") || !strcmp(arg, "-evenp") ||
                 !strcmp(arg, "-oddp")) {
        set_options(&new, "-parenb", "cs8", NULL);
      } else if (!strcmp(arg, "raw")) {
        // POSIX and "man stty" differ wildly. This is "man stty".
        set_options(&new, "-ignbrk", "-brkint", "-ignpar", "-parmrk", "-inpck",
          "-istrip", "-inlcr", "-igncr", "-icrnl", "-ixon", "-ixoff", "-iuclc",
          "-ixany", "-imaxbel", "-opost", "-isig", "-icanon", "-xcase", NULL);
        new.c_cc[VMIN] = 1;
        new.c_cc[VTIME] = 0;
      } else if (!strcmp(arg, "nl"))
        set_options(&new, "-icrnl", "-ocrnl", NULL);
      else if (!strcmp(arg, "-nl"))
        set_options(&new, "icrnl", "ocrnl", "-inlcr", "-igncr", NULL);
      else if (!strcmp(arg, "ek")) {
        new.c_cc[VERASE] = 0x7f;
        new.c_cc[VKILL] = 0x15;
      } else if (!strcmp(arg, "sane")) make_sane(&new);
      else {
        // Translate historical cruft into canonical forms.
        for (j=0;j<ARRAY_LEN(synonyms);j++) {
          if (!strcmp(synonyms[j].from, arg)) {
            arg = synonyms[j].to;
            break;
          }
        }
        set_option(&new, arg);
      }
    }
    tcsetattr(TT.fd, TCSAFLUSH, &new);
    xtcgetattr(&old);
    if (memcmp(&old, &new, sizeof(old)))
      error_exit("unable to perform all requested operations on %s", TT.device);

    return;
  }

  if (toys.optflags&FLAG_g) {
    xprintf("%x:%x:%x:%x:", old.c_iflag, old.c_oflag, old.c_cflag, old.c_lflag);
    for (i=0;i<NCCS;i++) xprintf("%x%c", old.c_cc[i], i==NCCS-1?'\n':':');
    return;
  }

  // Without arguments, "stty" only shows the speed, the line discipline,
  // special characters and any flags that differ from the "sane" settings.
  make_sane(&sane);
  show_speed(&old, 1);
  if (toys.optflags&FLAG_a) show_size(1);
  out("line = %d;\n", old.c_line);

  for (i=j=0;i<ARRAY_LEN(chars);i++) {
    char vis[16] = {};
    cc_t ch = old.c_cc[chars[i].value];

    if (ch == sane.c_cc[chars[i].value] && (toys.optflags&FLAG_a)==0)
      continue;

    if (chars[i].value == VMIN || chars[i].value == VTIME) {
      snprintf(vis, sizeof(vis), "%u", ch);
    } else if (ch == _POSIX_VDISABLE) {
      strcat(vis, "<undef>");
    } else {
      if (ch > 0x7f) {
        strcat(vis, "M-");
        ch -= 128;
      }
      if (ch < ' ') sprintf(vis+strlen(vis), "^%c", (ch+'@'));
      else if (ch == 0x7f) strcat(vis, "^?");
      else sprintf(vis+strlen(vis), "%c", ch);
    }
    out("%s = %s;", chars[i].name, vis);
    j++;
  }
  if (j) out("\n");

  show_flags(old.c_cflag, sane.c_cflag, cflags, ARRAY_LEN(cflags));
  show_flags(old.c_iflag, sane.c_iflag, iflags, ARRAY_LEN(iflags));
  show_flags(old.c_oflag, sane.c_oflag, oflags, ARRAY_LEN(oflags));
  show_flags(old.c_lflag, sane.c_lflag, lflags, ARRAY_LEN(lflags));
}

void stty_main(void)
{
  if (toys.optflags&(FLAG_a|FLAG_g) && *toys.optargs)
    error_exit("can't make settings with -a/-g");

  if (!TT.device) TT.device = "standard input";
  else TT.fd=xopen(TT.device, (O_RDWR*!!*toys.optargs)|O_NOCTTY|O_NONBLOCK);

  do_stty();

  if (CFG_TOYBOX_FREE && TT.device) close(TT.fd);
}
