/* dirtree.c - Functions for dealing with directory trees.
 *
 * Copyright 2007 Rob Landley <rob@landley.net>
 */

#include "toys.h"

static int notdotdot(char *name)
{
  if (name[0]=='.' && (!name[1] || (name[1]=='.' && !name[2]))) return 0;

  return 1;
}

// Default callback, filters out "." and "..".

int dirtree_notdotdot(struct dirtree *catch)
{
  // Should we skip "." and ".."?
  return notdotdot(catch->name) ? DIRTREE_SAVE|DIRTREE_RECURSE : 0;
}

// Create a dirtree node from a path, with stat and symlink info.
// (This doesn't open directory filehandles yet so as not to exhaust the
// filehandle space on large trees, dirtree_handle_callback() does that.)

struct dirtree *dirtree_add_node(struct dirtree *parent, char *name,
  int symfollow)
{
  struct dirtree *dt = NULL;
  struct stat st;
  char buf[4096];
  int len = 0, linklen = 0;

  if (name) {
    // open code this because haven't got node to call dirtree_parentfd() on yet
    int fd = parent ? parent->data : AT_FDCWD;

    if (fstatat(fd, name, &st, symfollow ? 0 : AT_SYMLINK_NOFOLLOW)) goto error;
    if (S_ISLNK(st.st_mode)) {
      if (0>(linklen = readlinkat(fd, name, buf, 4095))) goto error;
      buf[linklen++]=0;
    }
    len = strlen(name);
  }
  dt = xzalloc((len = sizeof(struct dirtree)+len+1)+linklen);
  dt->parent = parent;
  if (name) {
    memcpy(&(dt->st), &st, sizeof(struct stat));
    strcpy(dt->name, name);

    if (linklen) {
      dt->symlink = memcpy(len+(char *)dt, buf, linklen);
      dt->data = --linklen;
    }
  }

  return dt;

error:
  if (notdotdot(name)) {
    char *path = parent ? dirtree_path(parent, 0) : "";
    perror_msg("%s%s%s",path, parent ? "/" : "", name);
  }
  if (parent) parent->symlink = (char *)1;
  free(dt);
  return 0;
}

// Return path to this node, assembled recursively.

char *dirtree_path(struct dirtree *node, int *plen)
{
  char *path;
  int len;

  if (!node || !node->name) {
    path = xmalloc(*plen);
    *plen = 0;
    return path;
  }

  len = (plen ? *plen : 0)+strlen(node->name)+1;
  path = dirtree_path(node->parent, &len);
  if (len && path[len-1] != '/') path[len++]='/';
  len = (stpcpy(path+len, node->name) - path);
  if (plen) *plen = len;

  return path;
}

int dirtree_parentfd(struct dirtree *node)
{
  return node->parent ? node->parent->data : AT_FDCWD;
}

// Handle callback for a node in the tree. Returns saved node(s) or NULL.
//
// By default, allocates a tree of struct dirtree, not following symlinks
// If callback==NULL, or callback always returns 0, allocate tree of struct
// dirtree and return root of tree.  Otherwise call callback(node) on each
// hit, free structures after use, and return NULL.
//

struct dirtree *dirtree_handle_callback(struct dirtree *new,
          int (*callback)(struct dirtree *node))
{
  int flags, dir = S_ISDIR(new->st.st_mode);

  if (!callback) callback = dirtree_notdotdot;

  flags = callback(new);

  if (dir) {
    if (flags & (DIRTREE_RECURSE|DIRTREE_COMEAGAIN)) {
      new->data = openat(dirtree_parentfd(new), new->name, 0);
      dirtree_recurse(new, callback, flags & DIRTREE_SYMFOLLOW);
      if (flags & DIRTREE_COMEAGAIN) flags = callback(new);
    }
  }

  // If this had children, it was callback's job to free them already.
  if (!(flags & DIRTREE_SAVE)) {
    free(new);
    new = NULL;
  }

  return (flags & DIRTREE_ABORT)==DIRTREE_ABORT ? DIRTREE_ABORTVAL : new;
}

// Recursively read/process children of directory node (with dirfd in data),
// filtering through callback().

void dirtree_recurse(struct dirtree *node,
          int (*callback)(struct dirtree *node), int symfollow)
{
  struct dirtree *new, **ddt = &(node->child);
  struct dirent *entry;
  DIR *dir;

  if (!(dir = fdopendir(node->data))) {
    char *path = dirtree_path(node, 0);
    perror_msg("No %s", path);
    free(path);
    close(node->data);

    return;
  }

  // according to the fddir() man page, the filehandle in the DIR * can still
  // be externally used by things that don't lseek() it.

  // The extra parentheses are to shut the stupid compiler up.
  while ((entry = readdir(dir))) {
    if (!(new = dirtree_add_node(node, entry->d_name, symfollow)))
      continue;
    new = dirtree_handle_callback(new, callback);
    if (new == DIRTREE_ABORTVAL) break;
    if (new) {
      *ddt = new;
      ddt = &((*ddt)->next);
    }
  }

  // This closes filehandle as well, so note it
  closedir(dir);
  node->data = -1;
}

// Create dirtree from path, using callback to filter nodes.
// If callback == NULL allocate a tree of struct dirtree nodes and return
// pointer to root node.
// symfollow is just for the top of tree, callback return code controls children

struct dirtree *dirtree_read(char *path, int (*callback)(struct dirtree *node))
{
  struct dirtree *root = dirtree_add_node(0, path, 0);

  return root ? dirtree_handle_callback(root, callback) : DIRTREE_ABORTVAL;
}
