/* dd.c - program to convert and copy a file.
 *
 * Copyright 2013 Ashwini Kumar <ak.ashwini@gmail.com>
 * Copyright 2013 Kyungwan Han <asura321@gmail.com>
 *
 * See  http://opengroup.org/onlinepubs/9699919799/utilities/dd.html
USE_DD(NEWTOY(dd, NULL, TOYFLAG_USR|TOYFLAG_BIN))

config DD
  bool "dd"
  default n
    help
    usage: dd [if=FILE] [of=FILE] [ibs=N] [obs=N] [bs=N] [count=N] [skip=N]
            [seek=N] [conv=notrunc|noerror|sync|fsync]

    Options:
    if=FILE   Read from FILE instead of stdin
    of=FILE   Write to FILE instead of stdout
    bs=N      Read and write N bytes at a time
    ibs=N     Read N bytes at a time
    obs=N     Write N bytes at a time
    count=N   Copy only N input blocks
    skip=N    Skip N input blocks
    seek=N    Skip N output blocks
    conv=notrunc  Don't truncate output file
    conv=noerror  Continue after read errors
    conv=sync     Pad blocks with zeros
    conv=fsync    Physically write data out before finishing

    Numbers may be suffixed by c (x1), w (x2), b (x512), kD (x1000), k (x1024),
    MD (x1000000), M (x1048576), GD (x1000000000) or G (x1073741824)
    Copy a file, converting and formatting according to the operands.
*/
#define FOR_dd
#include "toys.h"

GLOBALS(
  int sig;
)
#define C_CONV    0x0000
#define C_BS      0x0001
#define C_COUNT   0x0002
#define C_IBS     0x0004
#define C_OBS     0x0008
#define C_IF      0x0010
#define C_OF      0x0020
#define C_SEEK    0x0040
#define C_SKIP    0x0080
#define C_SYNC    0x0100
#define C_FSYNC   0x0200
#define C_NOERROR 0x0400
#define C_NOTRUNC 0x0800

struct io {
  char *name;
  int fd;
  unsigned char *buff, *bp;
  long sz, count;
  unsigned long long offset;
};

struct iostat {
  unsigned long long in_full, in_part, out_full, out_part, bytes;
  struct timeval start;
};

struct pair {
  char *name;
  unsigned val;
};

static struct pair suffixes[] = {
  { "c", 1 }, { "w", 2 }, { "b", 512 },
  { "kD", 1000 }, { "k", 1024 }, { "K", 1024 },
  { "MD", 1000000 }, { "M", 1048576 },
  { "GD", 1000000000 }, { "G", 1073741824 }
};

static struct pair clist[] = {
  { "fsync",    C_FSYNC },
  { "noerror",  C_NOERROR },
  { "notrunc",  C_NOTRUNC },
  { "sync",     C_SYNC },
};

static struct pair operands[] = {
  // keep the array sorted by name, bsearch() can be used.
  { "bs",    C_BS   },
  { "conv",  C_CONV },
  { "count", C_COUNT},
  { "ibs",   C_IBS  },
  { "if",    C_IF   },
  { "obs",   C_OBS  },
  { "of",    C_OF   },
  { "seek",  C_SEEK },
  { "skip",  C_SKIP },
};

static struct io in, out;
static struct iostat st;
static unsigned long long c_count;

static unsigned long long strsuftoll(char* arg, int def, unsigned long long max)
{
  unsigned long long result;
  char *endp, *ch = arg;
  int i, idx = -1;
  errno = 0;

  while (isspace(*ch)) ch++;
  if (*ch == '-') error_exit("invalid number '%s'",arg);
  result = strtoull(arg, &endp, 10);
  if (errno == ERANGE || result > max || result < def)
    perror_exit("invalid number '%s'",arg);
  if (*endp != '\0') {
    for (i = 0; i < ARRAY_LEN(suffixes); i++)
      if (!strcmp(endp, suffixes[i].name)) idx = i;
    if (idx == -1 || (max/suffixes[idx].val < result)) 
      error_exit("invalid number '%s'",arg);
    result = result* suffixes[idx].val;
  }
  return result;
}

static void summary()
{
  double seconds = 5.0;
  struct timeval now;

  gettimeofday(&now, NULL);
  seconds = ((now.tv_sec * 1000000 + now.tv_usec) - (st.start.tv_sec * 1000000
        + st.start.tv_usec))/1000000.0;
  //out to STDERR
  fprintf(stderr,"%llu+%llu records in\n%llu+%llu records out\n", st.in_full, st.in_part,
      st.out_full, st.out_part);
  human_readable(toybuf, st.bytes, HR_SPACE|HR_B);
  fprintf(stderr, "%llu bytes (%s) copied, ",st.bytes, toybuf);
  human_readable(toybuf, st.bytes/seconds, HR_SPACE|HR_B);
  fprintf(stderr, "%f s, %s/s\n", seconds, toybuf);
}

static void sig_handler(int sig)
{
  TT.sig = sig;
}

static int xmove_fd(int fd)
{
  int newfd;

  if (fd > STDERR_FILENO) return fd;
  if ((newfd = fcntl(fd, F_DUPFD, 3) < 0)) perror_exit("dupfd IO");
  close(fd);
  return newfd;
}

static void setup_inout()
{
  ssize_t n;

  /* for C_BS, in/out is done as it is. so only in.sz is enough.
   * With Single buffer there will be overflow in a read following partial read
   */
  in.buff = out.buff = xmalloc(in.sz + ((toys.optflags & C_BS)? 0: out.sz));
  in.bp = out.bp = in.buff;
  atexit(summary);
  //setup input
  if (!in.name) {
    in.name = "stdin";
    in.fd = STDIN_FILENO;
  } else {
    in.fd = xopen(in.name, O_RDONLY);
    in.fd = xmove_fd(in.fd);
  }
  //setup outout
  if (!out.name) {
    out.name = "stdout";
    out.fd = STDOUT_FILENO;
  } else {
    out.fd = xcreate(out.name, O_WRONLY | O_CREAT, 0666);
    out.fd = xmove_fd(out.fd);
  }

  if (in.offset) {
    if (lseek(in.fd, (off_t)(in.offset * in.sz), SEEK_CUR) < 0) {
      while (in.offset--) {
        if ((n = read(in.fd, in.bp, in.sz)) < 0) {
          if (toys.optflags & C_NOERROR) { //warn message and summary
            error_msg("%s: read error", in.name);
            summary();
          } else perror_exit("%s: read error", in.name);
        } else if (!n) {
          xprintf("%s: Can't skip\n", in.name);
          exit(0);
        }
      }
    }
  }

  if (out.offset) xlseek(out.fd, (off_t)(out.offset * out.sz), SEEK_CUR);
}

static void write_out(int all)
{
  ssize_t nw;
  out.bp = out.buff;
  while (out.count) {
    nw = writeall(out.fd, out.bp, ((all)? out.count : out.sz));
    all = 0; //further writes will be on obs
    if (nw <= 0) perror_exit("%s: write error",out.name);
    if (nw == out.sz) st.out_full++;
    else st.out_part++;
    out.count -= nw;
    out.bp += nw;
    st.bytes += nw;
    if (out.count < out.sz) break;
  }
  if (out.count) memmove(out.buff, out.bp, out.count); //move remainder to front
}

static void do_dd(void)
{
  ssize_t n;
  struct sigaction sa;

  memset(&sa, 0, sizeof(sa));
  sa.sa_handler = sig_handler;
  sigaction(SIGINT, &sa, NULL);
  sigaction(SIGUSR1, &sa, NULL);
  setup_inout();
  gettimeofday(&st.start, NULL);

  if (toys.optflags & (C_OF | C_SEEK) && !(toys.optflags & C_NOTRUNC))
    ftruncate(out.fd, (off_t)out.offset * out.sz);

  while (!(toys.optflags & C_COUNT) || (st.in_full + st.in_part) < c_count) {
    if (TT.sig == SIGUSR1) {
      summary();
      TT.sig = 0;
    } else if (TT.sig == SIGINT) exit(TT.sig | 128);
    in.bp = in.buff + in.count;
    if (toys.optflags & C_SYNC) memset(in.bp, 0, in.sz);
    if (!(n = read(in.fd, in.bp, in.sz))) break;
    if (n < 0) { 
      if (errno == EINTR) continue;
      //read error case.
      perror_msg("%s: read error", in.name);
      if (!(toys.optflags & C_NOERROR)) exit(1);
      summary();
      xlseek(in.fd, in.sz, SEEK_CUR);
      if (!(toys.optflags & C_SYNC)) continue;
      // if SYNC, then treat as full block of nuls
      n = in.sz;
    }
    if (n == in.sz) {
      st.in_full++;
      in.count += n;
    } else {
      st.in_part++;
      if (toys.optflags & C_SYNC) in.count += in.sz;
      else in.count += n;
    }

    out.count = in.count;
    if (toys.optflags & C_BS) {
      write_out(1);
      in.count = 0;
      continue;
    }

    if (in.count >= out.sz) {
      write_out(0);
      in.count = out.count;
    }
  }
  if (out.count) write_out(1); //write any remaining input blocks
  if (toys.optflags & C_FSYNC && fsync(out.fd) < 0) 
    perror_exit("%s: fsync fail", out.name);

  close(in.fd);
  close(out.fd);
  if (in.buff) free(in.buff);
}

static int comp(const void *a, const void *b) //const to shut compiler up
{
  return strcmp(((struct pair*)a)->name, ((struct pair*)b)->name);
}

void dd_main()
{
  struct pair *res, key;
  char *arg;
  long sz;

  in.sz = out.sz = 512; //default io block size
  while (*toys.optargs) {
    if (!(arg = strchr(*toys.optargs, '='))) error_exit("unknown arg %s", *toys.optargs);
    *arg++ = '\0';
    if (!*arg) help_exit(0);
    key.name = *toys.optargs;
    if (!(res = bsearch(&key, operands, ARRAY_LEN(operands), sizeof(struct pair),
            comp))) error_exit("unknown arg %s", key.name);

    toys.optflags |= res->val;
    switch(res->val) {
      case C_BS:
        in.sz = out.sz = strsuftoll(arg, 1, LONG_MAX);
        break;
      case C_IBS:
        sz = strsuftoll(arg, 1, LONG_MAX);
        if (!(toys.optflags & C_BS)) in.sz = sz;
        break;
      case C_OBS:
        sz = strsuftoll(arg, 1, LONG_MAX);
        if (!(toys.optflags & C_BS)) out.sz = sz;
        break;
      case C_COUNT:
        c_count = strsuftoll(arg, 0, ULLONG_MAX);
        break;
      case C_IF:
        in.name = arg;
        break;
      case C_OF:
        out.name = arg;
        break;
      case C_SEEK:
        out.offset = strsuftoll(arg, 0, ULLONG_MAX);
        break;
      case C_SKIP:
        in.offset = strsuftoll(arg, 0, ULLONG_MAX);
        break;
      case C_CONV:
        while (arg) {
          key.name = strsep(&arg, ",");
          if (!(res = bsearch(&key, clist, ARRAY_LEN(clist), 
                  sizeof(struct pair), comp)))
            error_exit("unknown conversion %s", key.name);

          toys.optflags |= res->val;
        }            
        break;
    }
    toys.optargs++;
  }

  do_dd();
}
