/*
 * chattr.c		- Change file attributes on an ext2 file system
 *
 * Copyright (C) 1993, 1994  Remy Card <card@masi.ibp.fr>
 *                           Laboratoire MASI, Institut Blaise Pascal
 *                           Universite Pierre et Marie Curie (Paris VI)
 *
 * This file can be redistributed under the terms of the GNU General
 * Public License
 */

/*
 * History:
 * 93/10/30	- Creation
 * 93/11/13	- Replace stat() calls by lstat() to avoid loops
 * 94/02/27	- Integrated in Ted's distribution
 * 98/12/29	- Ignore symlinks when working recursively (G M Sipe)
 * 98/12/29	- Display version info only when -V specified (G M Sipe)
 */

#include <sys/types.h>
#include <dirent.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/param.h>
#include <sys/stat.h>
#include "ext2fs/ext2_fs.h"

#ifdef __GNUC__
# define EXT2FS_ATTR(x) __attribute__(x)
#else
# define EXT2FS_ATTR(x)
#endif

#include "e2fsbb.h"
#include "e2p/e2p.h"

#define OPT_ADD 1
#define OPT_REM 2
#define OPT_SET 4
#define OPT_SET_VER 8
static int flags;
static int recursive;

static unsigned long version;

static unsigned long af;
static unsigned long rf;
static unsigned long sf;

#ifdef CONFIG_LFS
# define LSTAT lstat64
# define STRUCT_STAT struct stat64
#else
# define LSTAT lstat
# define STRUCT_STAT struct stat
#endif

struct flags_char {
	unsigned long flag;
	char optchar;
};

static const struct flags_char flags_array[] = {
	{ EXT2_NOATIME_FL,      'A' },
	{ EXT2_SYNC_FL,         'S' },
	{ EXT2_DIRSYNC_FL,      'D' },
	{ EXT2_APPEND_FL,       'a' },
	{ EXT2_COMPR_FL,        'c' },
	{ EXT2_NODUMP_FL,       'd' },
	{ EXT2_IMMUTABLE_FL,    'i' },
	{ EXT3_JOURNAL_DATA_FL, 'j' },
	{ EXT2_SECRM_FL,        's' },
	{ EXT2_UNRM_FL,         'u' },
	{ EXT2_NOTAIL_FL,       't' },
	{ EXT2_TOPDIR_FL,       'T' },
	{ 0, 0 }
};

static unsigned long get_flag(char c)
{
	const struct flags_char *fp;
	for (fp = flags_array; fp->flag; fp++)
		if (fp->optchar == c)
			return fp->flag;
	bb_show_usage();
	return 0;
}

static int decode_arg(char *arg)
{
	unsigned long *fl;
	char opt = *arg++;

	if (opt == '-') {
		flags |= OPT_REM;
		fl = &rf;
	} else if (opt == '+') {
		flags |= OPT_ADD;
		fl = &af;
	} else if (opt == '=') {
		flags |= OPT_SET;
		fl = &sf;
	} else
		return EOF;

	for (; *arg ; ++arg)
		(*fl) |= get_flag(*arg);

	return 1;
}

static int chattr_dir_proc(const char *, struct dirent *, void *);

static void change_attributes(const char * name)
{
	unsigned long fsflags;
	STRUCT_STAT	st;

	if (LSTAT(name, &st) == -1) {
		bb_error_msg("stat %s failed", name);
		return;
	}
	if (S_ISLNK(st.st_mode) && recursive)
		return;

	/* Don't try to open device files, fifos etc.  We probably
	 * ought to display an error if the file was explicitly given
	 * on the command line (whether or not recursive was
	 * requested).  */
	if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode) && !S_ISDIR(st.st_mode))
		return;

	if (flags & OPT_SET_VER)
		if (fsetversion(name, version) == -1)
			bb_error_msg("setting version on %s", name);

	if (flags & OPT_SET) {
		fsflags = sf;
	} else {
		if (fgetflags(name, &fsflags) == -1) {
			bb_error_msg("reading flags on %s", name);
			goto skip_setflags;
		}
		if (flags & OPT_REM)
			fsflags &= ~rf;
		if (flags & OPT_ADD)
			fsflags |= af;
		if (!S_ISDIR(st.st_mode))
			fsflags &= ~EXT2_DIRSYNC_FL;
	}
	if (fsetflags(name, fsflags) == -1)
		bb_error_msg("setting flags on %s", name);

skip_setflags:
	if (S_ISDIR(st.st_mode) && recursive)
		iterate_on_dir(name, chattr_dir_proc, NULL);
}

static int chattr_dir_proc(const char *dir_name, struct dirent *de,
			   void *private EXT2FS_ATTR((unused)))
{
	/*if (strcmp(de->d_name, ".") && strcmp(de->d_name, "..")) {*/
	if (de->d_name[0] == '.' && (de->d_name[1] == '\0' || \
	   (de->d_name[1] == '.' && de->d_name[2] == '\0'))) {
		char *path = concat_subpath_file(dir_name, de->d_name);
		if (path) {
			change_attributes(path);
			free(path);
		}
	}
	return 0;
}

int chattr_main(int argc, char **argv)
{
	int i;
	char *arg;

	/* parse the args */
	for (i = 1; i < argc; ++i) {
		arg = argv[i];

		/* take care of -R and -v <version> */
		if (arg[0] == '-') {
			if (arg[1] == 'R' && arg[2] == '\0') {
				recursive = 1;
				continue;
			} else if (arg[1] == 'v' && arg[2] == '\0') {
				char *tmp;
				++i;
				if (i >= argc)
					bb_show_usage();
				version = strtol(argv[i], &tmp, 0);
				if (*tmp)
					bb_error_msg_and_die("bad version '%s'", arg);
				flags |= OPT_SET_VER;
				continue;
			}
		}

		if (decode_arg(arg) == EOF)
			break;
	}

	/* run sanity checks on all the arguments given us */
	if (i >= argc)
		bb_show_usage();
	if ((flags & OPT_SET) && ((flags & OPT_ADD) || (flags & OPT_REM)))
		bb_error_msg_and_die("= is incompatible with - and +");
	if ((rf & af) != 0)
		bb_error_msg_and_die("Can't set and unset a flag");
	if (!flags)
		bb_error_msg_and_die("Must use '-v', =, - or +");

	/* now run chattr on all the files passed to us */
	while (i < argc)
		change_attributes(argv[i++]);

	return EXIT_SUCCESS;
}
