/* vi: set sw=4 ts=4:
 *
 * chown.c - Change 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, "<2hPLHRfv", 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.
*/

#include "toys.h"

#define FLAG_v 1
#define FLAG_f 2
#define FLAG_R 4
#define FLAG_H 8
#define FLAG_L 16
#define FLAG_P 32
#define FLAG_h 64

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

#define TT this.chgrp

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->data != -1 && 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("changing owner:group of '%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';
	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;
		}
	} 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(AT_FDCWD, *s,
			toys.optflags&(FLAG_H|FLAG_L));
		if (new) handle_callback(new, do_chgrp);
		else toys.exitval = 1;
	}

	if (CFG_TOYBOX_FREE) free(own);
}
