/* 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 high)
{
  (*i)++;
  if (!toys.optargs[*i]) error_exit("missing arg");
  return atolx_range(toys.optargs[*i], 0, 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);
}

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

  if (toys.optflags&(FLAG_a|FLAG_g) && *toys.optargs)
    error_exit("no 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);

  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, NR_LDISCS);
      else if (!strcmp(arg, "min")) new.c_cc[VMIN] = get_arg(&i, 255);
      else if (!strcmp(arg, "time")) new.c_cc[VTIME] = get_arg(&i, 255);
      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 (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, 4000000)));
      else if (!strcmp(arg, "ospeed"))
        cfsetospeed(&new, speed(get_arg(&i, 4000000)));
      else if (!strcmp(arg, "rows")) set_size(1, get_arg(&i, USHRT_MAX));
      else if (!strcmp(arg, "cols") || !strcmp(arg, "columns"))
        set_size(0, get_arg(&i, USHRT_MAX));
      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));

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