/* chgrp.c - Change user and group ownership
 *
 * Copyright 2012 Georgi Chorbadzhiyski <georgi@unixsol.org>
 *
 * See http://opengroup.org/onlinepubs/9699919799/utilities/chown.html
 * See http://opengroup.org/onlinepubs/9699919799/utilities/chgrp.html
 *
 * TODO: group only one of [HLP]

USE_CHGRP(NEWTOY(chgrp, "<2hPLHRfv", TOYFLAG_BIN))
USE_CHGRP(OLDTOY(chown, chgrp, OPTSTR_chgrp, TOYFLAG_BIN))

config CHGRP
  bool "chgrp/chown"
  default y
  help
    usage: chown [-RHLP] [-fvh] [owner][:group] file...
    usage: chgrp [-RHLP] [-fvh] group file...

    Change ownership of one or more files.

    -f	suppress most error messages.
    -h	change symlinks instead of what they point to
    -R	recurse into subdirectories (implies -h).
    -H	with -R change target of symlink, follow command line symlinks
    -L	with -R change target of symlink, follow all symlinks
    -P	with -R change symlink, do not follow symlinks (default)
    -v	verbose output.
*/

#define FOR_chgrp
#include "toys.h"

GLOBALS(
  uid_t owner;
  gid_t group;
  char *owner_name, *group_name;
  int symfollow;
)

static int do_chgrp(struct dirtree *node)
{
  int fd, ret, flags = toys.optflags;

  // Depth first search
  if (!dirtree_notdotdot(node)) return 0;
  if ((flags & FLAG_R) && !node->again && S_ISDIR(node->st.st_mode))
    return DIRTREE_COMEAGAIN|((flags&FLAG_L) ? DIRTREE_SYMFOLLOW : 0);

  fd = dirtree_parentfd(node);
  ret = fchownat(fd, node->name, TT.owner, TT.group,
    (flags&(FLAG_L|FLAG_H)) || !(flags&(FLAG_h|FLAG_R))
      ? 0 : AT_SYMLINK_NOFOLLOW);

  if (ret || (flags & FLAG_v)) {
    char *path = dirtree_path(node, 0);
    if (flags & FLAG_v)
      xprintf("%s %s%s%s %s\n", toys.which->name,
        TT.owner_name ? TT.owner_name : "",
        toys.which->name[2]=='o' && TT.group_name ? ":" : "",
        TT.group_name ? TT.group_name : "", path);
    if (ret == -1 && !(toys.optflags & FLAG_f))
      perror_msg("'%s' to '%s:%s'", path, TT.owner_name, TT.group_name);
    free(path);
  }
  toys.exitval |= ret;

  return 0;
}

void chgrp_main(void)
{
  int ischown = toys.which->name[2] == 'o', hl = toys.optflags&(FLAG_H|FLAG_L);
  char **s, *own;

  // Distinguish chown from chgrp
  if (ischown) {
    char *grp;
    struct passwd *p;

    own = xstrdup(*toys.optargs);
    if ((grp = strchr(own, ':')) || (grp = strchr(own, '.'))) {
      *(grp++) = 0;
      TT.group_name = grp;
    }
    if (*own) {
      TT.owner_name = own;
      p = getpwnam(own);
      // TODO: trailing garbage?
      if (!p && isdigit(*own)) p=getpwuid(atoi(own));
      if (!p) error_exit("no user '%s'", own);
      TT.owner = p->pw_uid;
      if (CFG_TOYBOX_FREE) free(own);
    }
  } else TT.group_name = *toys.optargs;

  if (TT.group_name) {
    struct group *g;
    g = getgrnam(TT.group_name);
    if (!g) g=getgrgid(atoi(TT.group_name));
    if (!g) error_exit("no group '%s'", TT.group_name);
    TT.group = g->gr_gid;
  }

  for (s=toys.optargs+1; *s; s++) {
    struct dirtree *new = dirtree_add_node(0, *s, hl);
    if (new) dirtree_handle_callback(new, do_chgrp);
    else toys.exitval = 1;
  }
}
