/*
 * lsattr.c		- List 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	- Display version info only when -V specified (G M Sipe)
 */

#define _LARGEFILE64_SOURCE

#include "config.h"
#include <sys/types.h>
#include <dirent.h>
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include <fcntl.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#else
extern int optind;
extern char *optarg;
#endif
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/stat.h>

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

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

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

static const char * program_name = "lsattr";

static int all;
static int dirs_opt;
static unsigned pf_options;
static int recursive;
static int verbose;
static int generation_opt;
static int project_opt;

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

static void usage(void)
{
	fprintf(stderr, _("Usage: %s [-RVadlpv] [files...]\n"), program_name);
	exit(1);
}

static int list_attributes (const char * name)
{
	unsigned long flags;
	unsigned long generation;
	unsigned long project;

	if (fgetflags (name, &flags) == -1) {
		com_err (program_name, errno, _("While reading flags on %s"),
			 name);
		return -1;
	}
	if (project_opt) {
		if (fgetproject(name, &project) == -1) {
			com_err (program_name, errno,
				 _("While reading project on %s"),
				 name);
			return -1;
		}
		printf ("%5lu ", project);
	}
	if (generation_opt) {
		if (fgetversion (name, &generation) == -1) {
			com_err (program_name, errno,
				 _("While reading version on %s"),
				 name);
			return -1;
		}
		printf ("%-10lu ", generation);
	}
	if (pf_options & PFOPT_LONG) {
		printf("%-28s ", name);
		print_flags(stdout, flags, pf_options);
		fputc('\n', stdout);
	} else {
		print_flags(stdout, flags, pf_options);
		printf(" %s\n", name);
	}
	return 0;
}

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

static int lsattr_args (const char * name)
{
	STRUCT_STAT	st;
	int retval = 0;

	if (LSTAT (name, &st) == -1) {
		com_err (program_name, errno, _("while trying to stat %s"),
			 name);
		retval = -1;
	} else {
		if (S_ISDIR(st.st_mode) && !dirs_opt)
			retval = iterate_on_dir (name, lsattr_dir_proc, NULL);
		else
			retval = list_attributes (name);
	}
	return retval;
}

static int lsattr_dir_proc (const char * dir_name, struct dirent * de,
			    void * private EXT2FS_ATTR((unused)))
{
	STRUCT_STAT	st;
	char *path;
	int dir_len = strlen(dir_name);

	path = malloc(dir_len + strlen (de->d_name) + 2);

	if (dir_len && dir_name[dir_len-1] == '/')
		sprintf (path, "%s%s", dir_name, de->d_name);
	else
		sprintf (path, "%s/%s", dir_name, de->d_name);
	if (LSTAT (path, &st) == -1)
		perror (path);
	else {
		if (de->d_name[0] != '.' || all) {
			list_attributes (path);
			if (S_ISDIR(st.st_mode) && recursive &&
			    strcmp(de->d_name, ".") &&
			    strcmp(de->d_name, "..")) {
				printf ("\n%s:\n", path);
				iterate_on_dir (path, lsattr_dir_proc, NULL);
				printf ("\n");
			}
		}
	}
	free(path);
	return 0;
}

int main (int argc, char ** argv)
{
	int c;
	int i;
	int err, retval = 0;

#ifdef ENABLE_NLS
	setlocale(LC_MESSAGES, "");
	setlocale(LC_CTYPE, "");
	bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
	textdomain(NLS_CAT_NAME);
	set_com_err_gettext(gettext);
#endif
	if (argc && *argv)
		program_name = *argv;
	while ((c = getopt (argc, argv, "RVadlvp")) != EOF)
		switch (c)
		{
			case 'R':
				recursive = 1;
				break;
			case 'V':
				verbose = 1;
				break;
			case 'a':
				all = 1;
				break;
			case 'd':
				dirs_opt = 1;
				break;
			case 'l':
				pf_options = PFOPT_LONG;
				break;
			case 'v':
				generation_opt = 1;
				break;
			case 'p':
				project_opt = 1;
				break;
			default:
				usage();
		}

	if (verbose)
		fprintf (stderr, "lsattr %s (%s)\n",
			 E2FSPROGS_VERSION, E2FSPROGS_DATE);
	if (optind > argc - 1) {
		if (lsattr_args (".") == -1)
			retval = 1;
	} else {
		for (i = optind; i < argc; i++) {
			err = lsattr_args (argv[i]);
			if (err)
				retval = 1;
		}
	}
	exit(retval);
}
