/*
 * ls.c - list files and directories
 *
 * Copyright (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <common.h>
#include <command.h>
#include <fs.h>
#include <linux/stat.h>
#include <errno.h>
#include <malloc.h>
#include <getopt.h>
#include <stringlist.h>

static void ls_one(const char *path, struct stat *s)
{
	char modestr[11];
	unsigned int namelen = strlen(path);

	mkmodestr(s->st_mode, modestr);
	printf("%s %10lu %*.*s\n", modestr, s->st_size, namelen, namelen, path);
}

int ls(const char *path, ulong flags)
{
	DIR *dir;
	struct dirent *d;
	char tmp[PATH_MAX];
	struct stat s;
	struct string_list sl;

	string_list_init(&sl);

	if (stat(path, &s))
		return errno;

	if (flags & LS_SHOWARG && s.st_mode & S_IFDIR)
		printf("%s:\n", path);

	if (!(s.st_mode & S_IFDIR)) {
		ls_one(path, &s);
		return 0;
	}

	dir = opendir(path);
	if (!dir)
		return errno;

	while ((d = readdir(dir))) {
		sprintf(tmp, "%s/%s", path, d->d_name);
		if (stat(tmp, &s))
			goto out;
		if (flags & LS_COLUMN)
			string_list_add(&sl, d->d_name);
		else
			ls_one(d->d_name, &s);
	}

	closedir(dir);

	if (flags & LS_COLUMN) {
		string_list_print_by_column(&sl);
		string_list_free(&sl);
	}

	if (!(flags & LS_RECURSIVE))
		return 0;

	dir = opendir(path);
	if (!dir) {
		errno = -ENOENT;
		return -ENOENT;
	}

	while ((d = readdir(dir))) {

		if (!strcmp(d->d_name, "."))
			continue;
		if (!strcmp(d->d_name, ".."))
			continue;
		sprintf(tmp, "%s/%s", path, d->d_name);

		if (stat(tmp, &s))
			goto out;
		if (s.st_mode & S_IFDIR) {
			char *norm = normalise_path(tmp);
			ls(norm, flags);
			free(norm);
		}
	}
out:
	closedir(dir);

	return 0;
}

static int do_ls(struct command *cmdtp, int argc, char *argv[])
{
	int ret, opt, o;
	struct stat s;
	ulong flags = LS_COLUMN;
	struct string_list sl;

	while((opt = getopt(argc, argv, "RCl")) > 0) {
		switch(opt) {
		case 'R':
			flags |= LS_RECURSIVE | LS_SHOWARG;
			break;
		case 'C':
			flags |= LS_COLUMN;
			break;
		case 'l':
			flags &= ~LS_COLUMN;
			break;
		}
	}

	if (argc - optind > 1)
		flags |= LS_SHOWARG;

	if (optind == argc) {
		ret = ls(getcwd(), flags);
		return ret ? 1 : 0;
	}

	string_list_init(&sl);

	o = optind;

	/* first pass: all files */
	while (o < argc) {
		ret = stat(argv[o], &s);
		if (ret) {
			printf("%s: %s: %s\n", argv[0],
					argv[o], errno_str());
			o++;
			continue;
		}

		if (!(s.st_mode & S_IFDIR)) {
			if (flags & LS_COLUMN)
				string_list_add(&sl, argv[o]);
			else
				ls_one(argv[o], &s);
		}

		o++;
	}

	if (flags & LS_COLUMN)
		string_list_print_by_column(&sl);

	string_list_free(&sl);

	o = optind;

	/* second pass: directories */
	while (o < argc) {
		ret = stat(argv[o], &s);
		if (ret) {
			o++;
			continue;
		}

		if (s.st_mode & S_IFDIR) {
			ret = ls(argv[o], flags);
			if (ret) {
				perror("ls");
				o++;
				continue;
			}
		}

		o++;
	}

	return 0;
}

BAREBOX_CMD_HELP_START(ls)
BAREBOX_CMD_HELP_USAGE("ls [OPTIONS] [FILES]\n")
BAREBOX_CMD_HELP_SHORT("List information about the FILEs (the current directory by default).\n")
BAREBOX_CMD_HELP_OPT  ("-R",  "list subdirectories recursively\n")
BAREBOX_CMD_HELP_END

BAREBOX_CMD_START(ls)
	.cmd		= do_ls,
	.usage		= "list a file or directory",
	BAREBOX_CMD_HELP(cmd_ls_help)
BAREBOX_CMD_END
