/* tar.c - create/extract archives
 *
 * Copyright 2014 Ashwini Kumar <ak.ashwini81@gmail.com>
 *
 * USTAR interchange format is of interest in
 * See http://http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html
 * For writing to external program
 * http://www.gnu.org/software/tar/manual/html_node/Writing-to-an-External-Program.html

USE_TAR(NEWTOY(tar, "&(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)z(gzip)O(to-stdout)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):[!txc]", TOYFLAG_USR|TOYFLAG_BIN))

config TAR
  bool "tar"
  default n
  help
    usage: tar -[cxtzhmvO] [-X FILE] [-T FILE] [-f TARFILE] [-C DIR]

    Create, extract, or list files from a tar file

    Operation:
    c Create
    f Name of TARFILE ('-' for stdin/out)
    h Follow symlinks
    m Don't restore mtime
    t List
    v Verbose
    x Extract
    z (De)compress using gzip
    C Change to DIR before operation
    O Extract to stdout
    exclude=FILE File to exclude
    X File with names to exclude
    T File with names to include
*/
#define FOR_tar
#include "toys.h"

GLOBALS(
  char *fname;
  char *dir;
  struct arg_list *inc_file;
  struct arg_list *exc_file;
  char *tocmd;
  struct arg_list *exc;

  struct arg_list *inc, *pass;
  void *inodes, *handle;
)

struct tar_hdr {
  char name[100], mode[8], uid[8], gid[8],size[12], mtime[12], chksum[8],
       type, link[100], magic[8], uname[32], gname[32], major[8], minor[8],
       prefix[155], padd[12];
};

struct file_header {
  char *name, *link_target, *uname, *gname;
  off_t size;
  uid_t uid;
  gid_t gid;
  mode_t mode;
  time_t mtime;
  dev_t device;
};

struct archive_handler {
  int src_fd;
  struct file_header file_hdr;
  off_t offset;
  void (*extract_handler)(struct archive_handler*);
};

struct inode_list {
  struct inode_list *next;
  char *arg;
  ino_t ino;
  dev_t dev;
};

static void copy_in_out(int src, int dst, off_t size)
{
  int i, rd, rem = size%512, cnt;
  
  cnt = size/512 + (rem?1:0);

  for (i = 0; i < cnt; i++) {
    rd = (i == cnt-1 && rem) ? rem : 512;
    xreadall(src, toybuf, rd);
    writeall(dst, toybuf, rd);
  }
}

//convert to octal
static void itoo(char *str, int len, off_t val)
{
  char *t, tmp[sizeof(off_t)*3+1];
  int cnt  = sprintf(tmp, "%0*llo", len, val);

  t = tmp + cnt - len;
  if (*t == '0') t++;
  memcpy(str, t, len);
}

static struct inode_list *seen_inode(void **list, struct stat *st, char *name)
{
  if (!st) llist_traverse(*list, llist_free_arg);
  else if (!S_ISDIR(st->st_mode) && st->st_nlink > 1) {
    struct inode_list *new;

    for (new = *list; new; new = new->next)
      if(new->ino == st->st_ino && new->dev == st->st_dev)
        return new;

    new = xzalloc(sizeof(*new));
    new->ino = st->st_ino;
    new->dev = st->st_dev;
    new->arg = xstrdup(name);
    new->next = *list;
    *list = new;
  }
  return 0;
}

static void write_longname(struct archive_handler *tar, char *name, char type)
{
  struct tar_hdr tmp;
  unsigned int sum = 0;
  int i, sz = strlen(name) +1;
  char buf[512] = {0,};

  memset(&tmp, 0, sizeof(tmp));
  strcpy(tmp.name, "././@LongLink");
  sprintf(tmp.mode, "%0*d", sizeof(tmp.mode)-1, 0);
  sprintf(tmp.uid, "%0*d", sizeof(tmp.uid)-1, 0);
  sprintf(tmp.gid, "%0*d", sizeof(tmp.gid)-1, 0);
  sprintf(tmp.size, "%0*d", sizeof(tmp.size)-1, 0);
  sprintf(tmp.mtime, "%0*d", sizeof(tmp.mtime)-1, 0);
  itoo(tmp.size, sizeof(tmp.size), sz);
  tmp.type = type;
  memset(tmp.chksum, ' ', 8);
  strcpy(tmp.magic, "ustar  ");
  for (i= 0; i < 512; i++) sum += (unsigned int)((char*)&tmp)[i];
  itoo(tmp.chksum, sizeof(tmp.chksum)-1, sum);

  writeall(tar->src_fd, (void*) &tmp, sizeof(tmp));
  //write name to archive
  writeall(tar->src_fd, name, sz);
  if (sz%512) writeall(tar->src_fd, buf, (512-(sz%512)));
}

static int filter(struct arg_list *lst, char *name)
{
  struct arg_list *cur;

  for (cur = lst; cur; cur = cur->next)
    if (!fnmatch(cur->arg, name, 1<<3)) return 1;
  return 0;
}

static void add_file(struct archive_handler *tar, char **nam, struct stat *st)
{
  struct tar_hdr hdr;
  struct passwd *pw;
  struct group *gr;
  struct inode_list *node;
  int i, fd =-1;
  char *c, *p, *name = *nam, *lnk, *hname, buf[512] = {0,};
  unsigned int sum = 0;
  static int warn = 1;

  for (p = name; *p; p++)
    if ((p == name || p[-1] == '/') && *p != '/'
        && filter(TT.exc, p)) return;

  if (S_ISDIR(st->st_mode) && name[strlen(name)-1] != '/') {
    lnk = xmprintf("%s/",name);
    free(name);
    *nam = name = lnk;
  }
  hname = name;
  //remove leading '/' or relative path '../' component
  if (*hname == '/') hname++;
  if (!*hname) return;
  while ((c = strstr(hname, "../"))) hname = c + 3;
  if (warn && hname != name) {
    printf("removing leading '%.*s' "
        "from member names\n",hname-name, name);
    warn = 0;
  }

  memset(&hdr, 0, sizeof(hdr));
  strncpy(hdr.name, hname, sizeof(hdr.name));
  itoo(hdr.mode, sizeof(hdr.mode), st->st_mode &07777);
  itoo(hdr.uid, sizeof(hdr.uid), st->st_uid);
  itoo(hdr.gid, sizeof(hdr.gid), st->st_gid);
  itoo(hdr.size, sizeof(hdr.size), 0); //set size later
  itoo(hdr.mtime, sizeof(hdr.mtime), st->st_mtime);
  for (i=0; i<sizeof(hdr.chksum); i++) hdr.chksum[i] = ' ';

  if ((node = seen_inode(&TT.inodes, st, hname))) {
    //this is a hard link
    hdr.type = '1';
    if (strlen(node->arg) > sizeof(hdr.link))
      write_longname(tar, hname, 'K'); //write longname LINK
    strncpy(hdr.link, node->arg, sizeof(hdr.link));
  } else if (S_ISREG(st->st_mode)) {
    hdr.type = '0';
    if (st->st_size <= (off_t)0777777777777LL)
      itoo(hdr.size, sizeof(hdr.size), st->st_size);
    else {
      error_msg("can't store file '%s' of size '%d'\n", hname, st->st_size);
      return;
    }
  } else if (S_ISLNK(st->st_mode)) {
    hdr.type = '2'; //'K' long link
    if (!(lnk = xreadlink(name))) {
      perror_msg("readlink");
      return;
    }
    if (strlen(lnk) > sizeof(hdr.link))
      write_longname(tar, hname, 'K'); //write longname LINK
    strncpy(hdr.link, lnk, sizeof(hdr.link));
    free(lnk);
  }
  else if (S_ISDIR(st->st_mode)) hdr.type = '5';
  else if (S_ISFIFO(st->st_mode)) hdr.type = '6';
  else if (S_ISBLK(st->st_mode) || S_ISCHR(st->st_mode)) {
    hdr.type = (S_ISCHR(st->st_mode))?'3':'4';
    itoo(hdr.major, sizeof(hdr.major), major(st->st_rdev));
    itoo(hdr.minor, sizeof(hdr.minor), minor(st->st_rdev));
  } else {
    error_msg("unknown file type '%s'");
    return;
  }
  if (strlen(hname) > sizeof(hdr.name))
          write_longname(tar, hname, 'L'); //write longname NAME
  strcpy(hdr.magic, "ustar  ");
  if ((pw = getpwuid(st->st_uid)))
    snprintf(hdr.uname, sizeof(hdr.uname), "%s", pw->pw_name);
  else snprintf(hdr.uname, sizeof(hdr.uname), "%d", st->st_uid);

  if ((gr = getgrgid(st->st_gid)))
    snprintf(hdr.gname, sizeof(hdr.gname), "%s", gr->gr_name);
  else snprintf(hdr.gname, sizeof(hdr.gname), "%d", st->st_gid);

  //calculate chksum.
  for (i= 0; i < 512; i++) sum += (unsigned int)((char*)&hdr)[i];
  itoo(hdr.chksum, sizeof(hdr.chksum)-1, sum);
  if (toys.optflags & FLAG_v) printf("%s\n",hname);
  writeall(tar->src_fd, (void*)&hdr, 512);

  //write actual data to archive
  if (hdr.type != '0') return; //nothing to write
  if ((fd = open(name, O_RDONLY)) < 0) {
    perror_msg("can't open '%s'", name);
    return;
  }
  copy_in_out(fd, tar->src_fd, st->st_size);
  if (st->st_size%512) writeall(tar->src_fd, buf, (512-(st->st_size%512)));
  close(fd);
}

static int add_to_tar(struct dirtree *node)
{
  struct stat st;
  char *path;
  struct archive_handler *hdl = (struct archive_handler*)TT.handle;

  if (!fstat(hdl->src_fd, &st) && st.st_dev == node->st.st_dev
      && st.st_ino == node->st.st_ino) {
    error_msg("'%s' file is the archive; not dumped", TT.fname);
    return ((DIRTREE_RECURSE | ((toys.optflags & FLAG_h)?DIRTREE_SYMFOLLOW:0)));
  }

  if (node->parent && !dirtree_notdotdot(node)) return 0;
  path = dirtree_path(node, 0);
  add_file(hdl, &path, &(node->st)); //path may be modified
  free(path);
  if (toys.optflags & FLAG_no_recursion) return 0;
  return ((DIRTREE_RECURSE | ((toys.optflags & FLAG_h)?DIRTREE_SYMFOLLOW:0)));
}

static void compress_stream(struct archive_handler *tar_hdl)
{
  int pipefd[2];
  pid_t cpid;

  if (pipe(pipefd) == -1) error_exit("pipe");

  signal(SIGPIPE, SIG_IGN);
  cpid = fork();
  if (cpid == -1) perror_exit("fork");

  if (!cpid) {    /* Child reads from pipe */
    char *argv[] = {"gzip", "-f", NULL};
    xclose(pipefd[1]); /* Close unused write*/
    dup2(pipefd[0], 0);
    dup2(tar_hdl->src_fd, 1); //write to tar fd
    xexec(argv);
  } else {
    xclose(pipefd[0]);          /* Close unused read end */
    dup2(pipefd[1], tar_hdl->src_fd); //write to pipe
  }
}

static void extract_to_stdout(struct archive_handler *tar)
{
  struct file_header *file_hdr = &tar->file_hdr;

  copy_in_out(tar->src_fd, 0, file_hdr->size);
  tar->offset += file_hdr->size;
}

static void extract_to_command(struct archive_handler *tar)
{
  int pipefd[2], status = 0;
  pid_t cpid;
  struct file_header *file_hdr = &tar->file_hdr;

  if (pipe(pipefd) == -1) error_exit("pipe");
  if (!S_ISREG(file_hdr->mode)) return; //only regular files are supported.

  cpid = fork();
  if (cpid == -1) perror_exit("fork");

  if (!cpid) {    // Child reads from pipe
    char buf[64], *argv[4] = {"sh", "-c", TT.tocmd, NULL};

    setenv("TAR_FILETYPE", "f", 1);
    sprintf(buf, "%0o", file_hdr->mode);
    setenv("TAR_MODE", buf, 1);
    sprintf(buf, "%ld", (long)file_hdr->size);
    setenv("TAR_SIZE", buf, 1);
    setenv("TAR_FILENAME", file_hdr->name, 1);
    setenv("TAR_UNAME", file_hdr->uname, 1);
    setenv("TAR_GNAME", file_hdr->gname, 1);
    sprintf(buf, "%0o", (int)file_hdr->mtime);
    setenv("TAR_MTIME", buf, 1);
    sprintf(buf, "%0o", file_hdr->uid);
    setenv("TAR_UID", buf, 1);
    sprintf(buf, "%0o", file_hdr->gid);
    setenv("TAR_GID", buf, 1);

    xclose(pipefd[1]); // Close unused write
    dup2(pipefd[0], 0);
    signal(SIGPIPE, SIG_DFL);
    xexec(argv);
  } else {
    xclose(pipefd[0]);  // Close unused read end
    copy_in_out(tar->src_fd, pipefd[1], file_hdr->size);
    tar->offset += file_hdr->size;
    xclose(pipefd[1]);
    waitpid(cpid, &status, 0);
    if (WIFSIGNALED(status))
      xprintf("tar : %d: child returned %d\n", cpid, WTERMSIG(status));
  }
}

static void extract_to_disk(struct archive_handler *tar)
{
  int flags, dst_fd = -1;
  char *s;
  struct stat ex;
  struct file_header *file_hdr = &tar->file_hdr;

  if (file_hdr->name[strlen(file_hdr->name)-1] == '/')
    file_hdr->name[strlen(file_hdr->name)-1] = 0;
  //Regular file with preceding path
  if ((s = strrchr(file_hdr->name, '/'))) {
    if (mkpathat(AT_FDCWD, file_hdr->name, 00, 2) && errno !=EEXIST) {
      error_msg(":%s: not created", file_hdr->name);
      return;
    }
  }

  //remove old file, if exists
  if (!(toys.optflags & FLAG_k) && !S_ISDIR(file_hdr->mode)
      && !lstat( file_hdr->name, &ex)) {
    if (unlink(file_hdr->name)) {
      perror_msg("can't remove: %s",file_hdr->name);
    }
  }

  //hard link
  if (S_ISREG(file_hdr->mode) && file_hdr->link_target) {
    if (link(file_hdr->link_target, file_hdr->name))
      perror_msg("can't link '%s' -> '%s'",file_hdr->name, file_hdr->link_target);
    goto COPY;
  }

  switch (file_hdr->mode & S_IFMT) {
    case S_IFREG:
      flags = O_WRONLY|O_CREAT|O_EXCL;
      if (toys.optflags & FLAG_overwrite) flags = O_WRONLY|O_CREAT|O_TRUNC;
      dst_fd = open(file_hdr->name, flags, file_hdr->mode & 07777);
      if (dst_fd == -1) perror_msg("%s: can't open", file_hdr->name);
      break;
    case S_IFDIR:
      if ((mkdir(file_hdr->name, file_hdr->mode) == -1) && errno != EEXIST)
        perror_msg("%s: can't create", file_hdr->name);
      break;
    case S_IFLNK:
      if (symlink(file_hdr->link_target, file_hdr->name))
        perror_msg("can't link '%s' -> '%s'",file_hdr->name, file_hdr->link_target);
      break;
    case S_IFBLK:
    case S_IFCHR:
    case S_IFIFO:
      if (mknod(file_hdr->name, file_hdr->mode, file_hdr->device))
        perror_msg("can't create '%s'", file_hdr->name);
      break;
    default:
      printf("type not yet supported\n");
      break;
  }

  //copy file....
COPY:
  copy_in_out(tar->src_fd, dst_fd, file_hdr->size);
  tar->offset += file_hdr->size;
  close(dst_fd);

  if (S_ISLNK(file_hdr->mode)) return;
  if (!(toys.optflags & FLAG_o)) {
    //set ownership..., --no-same-owner, --numeric-owner
    uid_t u = file_hdr->uid;
    gid_t g = file_hdr->gid;

    if (!(toys.optflags & FLAG_numeric_owner)) {
      struct group *gr = getgrnam(file_hdr->gname);
      struct passwd *pw = getpwnam(file_hdr->uname);
      if (pw) u = pw->pw_uid;
      if (gr) g = gr->gr_gid;
    }
    chown(file_hdr->name, u, g);
  }

  if (toys.optflags & FLAG_p) // || !(toys.optflags & FLAG_no_same_permissions))
    chmod(file_hdr->name, file_hdr->mode);

  //apply mtime
  if (!(toys.optflags & FLAG_m)) {
    struct timeval times[2] = {{file_hdr->mtime, 0},{file_hdr->mtime, 0}};
    utimes(file_hdr->name, times);
  }
}

static void add_to_list(struct arg_list **llist, char *name)
{
  struct arg_list **list = llist;

  while (*list) list=&((*list)->next);
  *list = xzalloc(sizeof(struct arg_list));
  (*list)->arg = name;
  if ((name[strlen(name)-1] == '/') && strlen(name) != 1)
    name[strlen(name)-1] = '\0';
}

static void add_from_file(struct arg_list **llist, struct arg_list *flist)
{
  char *line = NULL;

  while (flist) {
    int fd = 0;

    if (strcmp((char *)flist->arg, "-"))
      fd = xopen((char *)flist->arg, O_RDONLY);

    while ((line = get_line(fd))) {
      add_to_list(llist, line);
    }
    if (fd) close(fd);
    flist = flist->next;
  }
}

static struct archive_handler *init_handler()
{
  struct archive_handler *tar_hdl = xzalloc(sizeof(struct archive_handler));
  tar_hdl->extract_handler = extract_to_disk;
  return tar_hdl;
}

//convert octal to int
static int otoi(char *str, int len)
{
  long val;
  char *endp, inp[len+1]; //1 for NUL termination

  memcpy(inp, str, len);
  inp[len] = '\0'; //nul-termination made sure
  val = strtol(inp, &endp, 8);
  if (*endp && *endp != ' ') error_exit("invalid param");
  return (int)val;
}

static void extract_stream(struct archive_handler *tar_hdl)
{
  int pipefd[2];              
  pid_t cpid;                 

  if (pipe(pipefd) == -1) error_exit("pipe");

  cpid = fork();
  if (cpid == -1) perror_exit("fork");

  if (!cpid) {    /* Child reads from pipe */
    char *argv[] = {"gunzip", "-cf", "-", NULL};
    xclose(pipefd[0]); /* Close unused read*/
    dup2(tar_hdl->src_fd, 0);
    dup2(pipefd[1], 1); //write to pipe
    xexec(argv);
  } else {
    xclose(pipefd[1]);          /* Close unused read end */
    dup2(pipefd[0], tar_hdl->src_fd); //read from pipe
  }
}

static char *process_extended_hdr(struct archive_handler *tar, int size)
{
  char *value = NULL, *p, *buf = xzalloc(size+1);

  if (readall(tar->src_fd, buf, size) != size) error_exit("short read");
  buf[size] = 0;
  tar->offset += size;
  p = buf;

  while (size) {
    char *key;
    int len, n;

    // extended records are of the format: "LEN NAME=VALUE\n"
    sscanf(p, "%d %n", &len, &n);
    key = p + n;
    p += len;
    size -= len;
    p[-1] = 0;
    if (size < 0) {
      error_msg("corrupted extended header");
      break;
    }

    len = strlen("path=");
    if (!strncmp(key, "path=", len)) {
      value = key + strlen("path=");
      break;
    }
  }
  if (value) value = xstrdup(value);
  free(buf);
  return value;
}

static void tar_skip(struct archive_handler *tar, int sz)
{
  int x;

  while ((x = lskip(tar->src_fd, sz))) {
    tar->offset += sz - x;
    sz = x;
  }
  tar->offset += sz;
}

static void unpack_tar(struct archive_handler *tar_hdl)
{
  struct tar_hdr tar;
  struct file_header *file_hdr;
  int i, j, maj, min, sz, e = 0;
  unsigned int cksum;
  unsigned char *gzMagic;
  char *longname = NULL, *longlink = NULL;

  while (1) {
    cksum = 0;
    if (tar_hdl->offset % 512) {
      sz = 512 - tar_hdl->offset % 512;
      tar_skip(tar_hdl, sz);
    }
    i = readall(tar_hdl->src_fd, &tar, 512);
    tar_hdl->offset += i;
    if (i != 512) {
      if (i >= 2) goto CHECK_MAGIC; //may be a small (<512 byte)zipped file
      error_exit("read error");
    }

    if (!tar.name[0]) {
      if (e) return; //end of tar 2 empty blocks
      e = 1;//empty jump to next block
      continue;
    }
    if (strncmp(tar.magic, "ustar", 5)) {
      //try detecting by reading magic
CHECK_MAGIC:
      gzMagic = (unsigned char*)&tar;
      if ((gzMagic[0] == 0x1f) && (gzMagic[1] == 0x8b) 
          && !lseek(tar_hdl->src_fd, -i, SEEK_CUR)) {
        tar_hdl->offset -= i;
        extract_stream(tar_hdl);
        continue;
      }
      error_exit("invalid tar format");
    }

    for (j = 0; j<148; j++) cksum += (unsigned int)((char*)&tar)[j];
    for (j = 156; j<500; j++) cksum += (unsigned int)((char*)&tar)[j];
    //cksum field itself treated as ' '
    for ( j= 0; j<8; j++) cksum += (unsigned int)' ';

    if (cksum != otoi(tar.chksum, sizeof(tar.chksum))) error_exit("wrong cksum");

    file_hdr = &tar_hdl->file_hdr;
    memset(file_hdr, 0, sizeof(struct file_header));
    file_hdr->mode = otoi(tar.mode, sizeof(tar.mode));
    file_hdr->uid = otoi(tar.uid, sizeof(tar.uid));
    file_hdr->gid = otoi(tar.gid, sizeof(tar.gid));
    file_hdr->size = otoi(tar.size, sizeof(tar.size));
    file_hdr->mtime = otoi(tar.mtime, sizeof(tar.mtime));
    file_hdr->uname = xstrdup(tar.uname);
    file_hdr->gname = xstrdup(tar.gname);
    maj = otoi(tar.major, sizeof(tar.major));
    min = otoi(tar.minor, sizeof(tar.minor));
    file_hdr->device = makedev(maj, min);

    if (tar.type <= '7') {
      if (tar.link[0]) {
        sz = sizeof(tar.link);
        file_hdr->link_target = xmalloc(sz + 1);
        memcpy(file_hdr->link_target, tar.link, sz);
        file_hdr->link_target[sz] = '\0';
      }

      file_hdr->name = xzalloc(256);// pathname supported size
      if (tar.prefix[0]) {
        memcpy(file_hdr->name, tar.prefix, sizeof(tar.prefix));
        sz = strlen(file_hdr->name);
        if (file_hdr->name[sz-1] != '/') file_hdr->name[sz] = '/';
      }
      sz = strlen(file_hdr->name);
      memcpy(file_hdr->name + sz, tar.name, sizeof(tar.name));
      if (file_hdr->name[255]) error_exit("filename too long");
    }

    switch (tar.type) {
      //    case '\0':
      case '0':
      case '7':
      case '1': //Hard Link
        file_hdr->mode |= S_IFREG;
        break;
      case '2':
        file_hdr->mode |= S_IFLNK;
        break;
      case '3':
        file_hdr->mode |= S_IFCHR;
        break;
      case '4':
        file_hdr->mode |= S_IFBLK;
        break;
      case '5':
        file_hdr->mode |= S_IFDIR;
        break;
      case '6':
        file_hdr->mode |= S_IFIFO;
        break;
      case 'K':
        longlink = xzalloc(file_hdr->size +1);
        xread(tar_hdl->src_fd, longlink, file_hdr->size);
        tar_hdl->offset += file_hdr->size;
        continue;
      case 'L':
        free(longname);
        longname = xzalloc(file_hdr->size +1);           
        xread(tar_hdl->src_fd, longname, file_hdr->size);
        tar_hdl->offset += file_hdr->size;
        continue;
      case 'D':
      case 'M':
      case 'N':
      case 'S':
      case 'V':
      case 'g':  // pax global header
        tar_skip(tar_hdl, file_hdr->size);
        continue;
      case 'x':  // pax extended header
        free(longname);
        longname = process_extended_hdr(tar_hdl, file_hdr->size);
        continue;
      default: break;
    }

    if (longname) {
      free(file_hdr->name);
      file_hdr->name = longname;
      longname = NULL;
    }
    if (longlink) {
      free(file_hdr->link_target);
      file_hdr->link_target = longlink;
      longlink = NULL;
    }

    if ((file_hdr->mode & S_IFREG) && 
        file_hdr->name[strlen(file_hdr->name)-1] == '/') {
      file_hdr->name[strlen(file_hdr->name)-1] = '\0';
      file_hdr->mode &= ~S_IFREG;
      file_hdr->mode |= S_IFDIR;
    }

    if ((file_hdr->link_target && *(file_hdr->link_target)) 
        || S_ISLNK(file_hdr->mode) || S_ISDIR(file_hdr->mode))
      file_hdr->size = 0;

    if (filter(TT.exc, file_hdr->name) ||
        (TT.inc && !filter(TT.inc, file_hdr->name))) goto SKIP;
    add_to_list(&TT.pass, xstrdup(file_hdr->name));

    if (toys.optflags & FLAG_t) {
      if (toys.optflags & FLAG_v) {
        char perm[11];
        struct tm *lc = localtime((const time_t*)&(file_hdr->mtime));

        mode_to_string(file_hdr->mode, perm);
        printf("%s %s/%s %9ld %d-%02d-%02d %02d:%02d:%02d ",perm,file_hdr->uname,
            file_hdr->gname, (long)file_hdr->size, 1900+lc->tm_year,
            1+lc->tm_mon, lc->tm_mday, lc->tm_hour, lc->tm_min, lc->tm_sec);
      }
      printf("%s",file_hdr->name);
      if (file_hdr->link_target) printf(" -> %s",file_hdr->link_target);
      xputc('\n');
SKIP:
      tar_skip(tar_hdl, file_hdr->size);
    } else {
      if (toys.optflags & FLAG_v) printf("%s\n",file_hdr->name);
      tar_hdl->extract_handler(tar_hdl);
    }
    free(file_hdr->name);
    free(file_hdr->link_target);
    free(file_hdr->uname);
    free(file_hdr->gname);
  }
}

void tar_main(void)
{
  struct archive_handler *tar_hdl;
  int fd = 0, flags = O_RDONLY;
  struct arg_list *tmp;
  char **args = toys.optargs;

  if (!toys.argv[1]) {
    toys.exithelp++;
    error_exit(NULL);
  }

  if (!geteuid()) toys.optflags |= FLAG_p;

  for (tmp = TT.exc; tmp; tmp = tmp->next)
    tmp->arg = xstrdup(tmp->arg); //freeing at the end fails otherwise

  while(*args) add_to_list(&TT.inc, xstrdup(*args++));
  if (toys.optflags & FLAG_X) add_from_file(&TT.exc, TT.exc_file);
  if (toys.optflags & FLAG_T) add_from_file(&TT.inc, TT.inc_file);

  if (toys.optflags & FLAG_c) {
    if (!TT.inc) error_exit("empty archive");
    fd = 1, flags = O_WRONLY|O_CREAT|O_TRUNC;
  }
  if ((toys.optflags & FLAG_f) && strcmp(TT.fname, "-")) 
    fd = xcreate(TT.fname, flags, 0666);
  if (toys.optflags & FLAG_C) xchdir(TT.dir);

  tar_hdl = init_handler();
  tar_hdl->src_fd = fd;

  if (toys.optflags & FLAG_x || toys.optflags & FLAG_t) {
    if (toys.optflags & FLAG_O) tar_hdl->extract_handler = extract_to_stdout;
    if (toys.optflags & FLAG_to_command) {
      signal(SIGPIPE, SIG_IGN); //will be using pipe between child & parent
      tar_hdl->extract_handler = extract_to_command;
    }
    if (toys.optflags & FLAG_z) extract_stream(tar_hdl);
    unpack_tar(tar_hdl);
    for (tmp = TT.inc; tmp; tmp = tmp->next)
      if (!filter(TT.exc, tmp->arg) && !filter(TT.pass, tmp->arg))
        error_msg("'%s' not in archive", tmp->arg);
  } else if (toys.optflags & FLAG_c) {
    //create the tar here.
    if (toys.optflags & FLAG_z) compress_stream(tar_hdl);
    for (tmp = TT.inc; tmp; tmp = tmp->next) {
      TT.handle = tar_hdl;
      //recurse thru dir and add files to archive
      struct dirtree *root = dirtree_add_node(0,tmp->arg,toys.optflags & FLAG_h);

      if (root) dirtree_handle_callback(root, add_to_tar);
    }
    memset(toybuf, 0, 1024);
    writeall(tar_hdl->src_fd, toybuf, 1024);
    seen_inode(&TT.inodes, 0, 0);
  }

  if (CFG_TOYBOX_FREE) {
    close(tar_hdl->src_fd);
    free(tar_hdl);
    llist_traverse(TT.exc, llist_free_arg);
    llist_traverse(TT.inc, llist_free_arg);
    llist_traverse(TT.pass, llist_free_arg);
  }
}
