/*
 * 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)
 */

#define _LARGEFILE64_SOURCE

#include <sys/types.h>
#include <dirent.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#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

#ifndef S_ISLNK			/* So we can compile even with gcc-warn */
# ifdef __S_IFLNK
#  define S_ISLNK(mode)	 __S_ISTYPE((mode), __S_IFLNK)
# else
#  define S_ISLNK(mode)  0
# endif
#endif

#include "et/com_err.h"
#include "e2p/e2p.h"

#include "../version.h"
#include "nls-enable.h"

static const char * program_name = "chattr";

static int add;
static int rem;
static int set;
static int set_version;

static unsigned long version;

static int recursive;
static int verbose;

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

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

static void fatal_error(const char * fmt_string, int errcode)
{
	fprintf (stderr, fmt_string, program_name);
	exit (errcode);
}

#define usage() fatal_error(_("usage: %s [-RV] [-+=AacDdijsSu] [-v version] files...\n"), \
			     1)

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 != 0; fp++) {
		if (fp->optchar == c)
			return fp->flag;
	}
	return 0;
}


static int decode_arg (int * i, int argc, char ** argv)
{
	char * p;
	char * tmp;
	unsigned long fl;

	switch (argv[*i][0])
	{
	case '-':
		for (p = &argv[*i][1]; *p; p++) {
			if (*p == 'R') {
				recursive = 1;
				continue;
			}
			if (*p == 'V') {
				verbose = 1;
				continue;
			}
			if (*p == 'v') {
				(*i)++;
				if (*i >= argc)
					usage ();
				version = strtol (argv[*i], &tmp, 0);
				if (*tmp) {
					com_err (program_name, 0,
						 _("bad version - %s\n"), 
						 argv[*i]);
					usage ();
				}
				set_version = 1;
				continue;
			}
			if ((fl = get_flag(*p)) == 0)
				usage();
			rf |= fl;
			rem = 1;
		}
		break;
	case '+':
		add = 1;
		for (p = &argv[*i][1]; *p; p++) {
			if ((fl = get_flag(*p)) == 0)
				usage();
			af |= fl;
		}
		break;
	case '=':
		set = 1;
		for (p = &argv[*i][1]; *p; p++) {
			if ((fl = get_flag(*p)) == 0)
				usage();
			sf |= fl;
		}
		break;
	default:
		return EOF;
		break;
	}
	return 1;
}

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

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

	if (LSTAT (name, &st) == -1) {
		com_err (program_name, errno, _("while trying to stat %s"), 
			 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 (set) {
		if (verbose) {
			printf (_("Flags of %s set as "), name);
			print_flags (stdout, sf, 0);
			printf ("\n");
		}
		if (fsetflags (name, sf) == -1)
			perror (name);
	} else {
		if (fgetflags (name, &flags) == -1)
			com_err (program_name, errno,
			         _("while reading flags on %s"), name);
		else {
			if (rem)
				flags &= ~rf;
			if (add)
				flags |= af;
			if (verbose) {
				printf (_("Flags of %s set as "), name);
				print_flags (stdout, flags, 0);
				printf ("\n");
			}
			if (!S_ISDIR(st.st_mode))
				flags &= ~EXT2_DIRSYNC_FL;
			if (fsetflags (name, flags) == -1)
				com_err (program_name, errno,
				         _("while setting flags on %s"), name);
		}
	}
	if (set_version) {
		if (verbose)
			printf (_("Version of %s set as %lu\n"), name, version);
		if (fsetversion (name, version) == -1)
			com_err (program_name, errno,
			         _("while setting version on %s"), name);
	}
	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, "..")) {
	        char *path;

		path = malloc(strlen (dir_name) + 1 + strlen (de->d_name) + 1);
		if (!path)
			fatal_error(_("Couldn't allocate path variable "
				    "in chattr_dir_proc"), 1);
		sprintf (path, "%s/%s", dir_name, de->d_name);
		change_attributes (path);
		free(path);
	}
	return 0;
}

int main (int argc, char ** argv)
{
	int i, j;
	int end_arg = 0;

#ifdef ENABLE_NLS
	setlocale(LC_MESSAGES, "");
	setlocale(LC_CTYPE, "");
	bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
	textdomain(NLS_CAT_NAME);
#endif
	if (argc && *argv)
		program_name = *argv;
	i = 1;
	while (i < argc && !end_arg) {
		/* '--' arg should end option processing */
		if (strcmp(argv[i], "--") == 0) {
			i++;
			end_arg = 1;
		} else if (decode_arg (&i, argc, argv) == EOF)
			end_arg = 1;
		else
			i++;
	}
	if (i >= argc)
		usage ();
	if (set && (add || rem)) {
		fputs(_("= is incompatible with - and +\n"), stderr);
		exit (1);
	}
	if ((rf & af) != 0) {
		fputs("Can't both set and unset same flag.\n", stderr);
		exit (1);
	}
	if (!(add || rem || set || set_version)) {
		fputs(_("Must use '-v', =, - or +\n"), stderr);
		exit (1);
	}
	if (verbose)
		fprintf (stderr, "chattr %s (%s)\n",
			 E2FSPROGS_VERSION, E2FSPROGS_DATE);
	for (j = i; j < argc; j++)
		change_attributes (argv[j]);
	exit(0);
}
