/*
 * 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;
}
