/* 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);
  fprintf(stderr, "%llu bytes (%sB) copied,",st.bytes, human_readable(st.bytes));
  fprintf(stderr, "%f seconds, %sB/s\n", seconds, human_readable(st.bytes/seconds));
}

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) {
      toys.exithelp = 1;
      error_exit("");
    }
    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();
}
