/*
 * ls.c --- list directories
 *
 * Copyright (C) 1997 Theodore Ts'o.  This file may be redistributed
 * under the terms of the GNU Public License.
 */

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

#include "debugfs.h"

/*
 * list directory
 */

#define LONG_OPT	0x0001
#define PARSE_OPT	0x0002
#define RAW_OPT		0x0004
#define ENCRYPT_OPT	0x8000

struct list_dir_struct {
	FILE	*f;
	int	col;
	int	options;
	int	state;
};

static const char *monstr[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
				"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};

static int print_filename(FILE *f, struct ext2_dir_entry *dirent, int options)
{
	unsigned char	ch;
	const char *cp = dirent->name;
	int len = ext2fs_dirent_name_len(dirent);
	int retlen = 0;

	if ((options & ENCRYPT_OPT) && !(options & RAW_OPT)) {
		if (f)
			return fprintf(f, "<encrypted (%d)>", len);
		else {
			char tmp[1];
			return snprintf(tmp, sizeof(tmp),
					"<encrypted (%d)>", len);
		}
	}
	while (len--) {
		ch = *cp++;
		if (ch > 128) {
			if (f)
				fputs("M-", f);
			ch -= 128;
			retlen += 2;
		}
		if ((ch < 32) || (ch == 0x7f)) {
			if (f)
				fputc('^', f);
			ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
			retlen++;
		}
		if (f)
			fputc(ch, f);
		retlen++;
	}
	return retlen;
}

static int list_dir_proc(ext2_ino_t dir EXT2FS_ATTR((unused)),
			 int	entry,
			 struct ext2_dir_entry *dirent,
			 int	offset EXT2FS_ATTR((unused)),
			 int	blocksize EXT2FS_ATTR((unused)),
			 char	*buf EXT2FS_ATTR((unused)),
			 void	*private)
{
	struct ext2_inode	inode;
	ext2_ino_t		ino;
	struct tm		*tm_p;
	time_t			modtime;
	char			tmp[EXT2_NAME_LEN + 16];
	char			datestr[80];
	char			lbr, rbr;
	int			thislen;
	int			options;
	struct list_dir_struct *ls = (struct list_dir_struct *) private;
	struct ext2_dir_entry_tail *t = (struct ext2_dir_entry_tail *) dirent;

	thislen = ext2fs_dirent_name_len(dirent);
	ino = dirent->inode;
	options = ls->options;
	if (ls->state < 2) {
		ls->state++;
		options |= RAW_OPT;
	}

	if (entry == DIRENT_DELETED_FILE) {
		lbr = '<';
		rbr = '>';
		ino = 0;
	} else {
		lbr = rbr = ' ';
	}
	if (options & PARSE_OPT) {
		if (ino) {
			if (debugfs_read_inode(ino, &inode, "ls"))
				return 0;
		} else
			memset(&inode, 0, sizeof(struct ext2_inode));
		fprintf(ls->f,"/%u/%06o/%d/%d/%*s/", ino, inode.i_mode,
			inode.i_uid, inode.i_gid, thislen, dirent->name);
		if (LINUX_S_ISDIR(inode.i_mode))
			fprintf(ls->f, "/");
		else
			fprintf(ls->f, "%lld/", EXT2_I_SIZE(&inode));
		fprintf(ls->f, "\n");
	} else if (options & LONG_OPT) {
		if (ino) {
			if (debugfs_read_inode(ino, &inode, "ls"))
				return 0;
			modtime = inode.i_mtime;
			tm_p = localtime(&modtime);
			sprintf(datestr, "%2d-%s-%4d %02d:%02d",
				tm_p->tm_mday, monstr[tm_p->tm_mon],
				1900 + tm_p->tm_year, tm_p->tm_hour,
				tm_p->tm_min);
		} else {
			strcpy(datestr, "                 ");
			memset(&inode, 0, sizeof(struct ext2_inode));
		}
		fprintf(ls->f, "%c%6u%c %6o ", lbr, ino, rbr, inode.i_mode);
		if (entry == DIRENT_CHECKSUM) {
			fprintf(ls->f, "(dirblock checksum: 0x%08x)\n",
				t->det_checksum);
			return 0;
		}
		fprintf(ls->f, "(%d)  %5d  %5d   ",
			ext2fs_dirent_file_type(dirent),
			inode_uid(inode), inode_gid(inode));
		if (LINUX_S_ISDIR(inode.i_mode))
			fprintf(ls->f, "%5d", inode.i_size);
		else
			fprintf(ls->f, "%5llu", EXT2_I_SIZE(&inode));
		fputs(datestr, ls->f);
		fputc(' ', ls->f);
		print_filename(ls->f, dirent, options);
		fputc('\n', ls->f);
	} else {
		if (entry == DIRENT_CHECKSUM) {
			sprintf(tmp, "%c%u%c (dirblock checksum: 0x%08x)   ",
				lbr, dirent->inode, rbr, t->det_checksum);
			thislen = strlen(tmp);
			if (ls->col + thislen > 80) {
				fputc('\n', ls->f);
				ls->col = 0;
			}
			fprintf(ls->f, "%s", tmp);
			ls->col += thislen;
			return 0;
		}
		sprintf(tmp, "%c%u%c (%d) ", lbr, dirent->inode, rbr,
			dirent->rec_len);
		thislen = strlen(tmp) + 3;
		thislen += print_filename(NULL, dirent, options);

		if (ls->col + thislen > 80) {
			fputc('\n', ls->f);
			ls->col = 0;
		}
		fprintf(ls->f, "%s", tmp);
		print_filename(ls->f, dirent, options);
		fputs("   ", ls->f);
		ls->col += thislen;
	}
	return 0;
}

void do_list_dir(int argc, char *argv[])
{
	struct ext2_inode inode;
	ext2_ino_t	ino;
	int		retval;
	int		c;
	int		flags = DIRENT_FLAG_INCLUDE_EMPTY;
	struct list_dir_struct ls;

	ls.options = 0;
	ls.state = 0;
	if (check_fs_open(argv[0]))
		return;

	reset_getopt();
	while ((c = getopt (argc, argv, "cdlpr")) != EOF) {
		switch (c) {
		case 'c':
			flags |= DIRENT_FLAG_INCLUDE_CSUM;
			break;
		case 'l':
			ls.options |= LONG_OPT;
			break;
		case 'd':
			flags |= DIRENT_FLAG_INCLUDE_REMOVED;
			break;
		case 'p':
			ls.options |= PARSE_OPT;
			break;
		case 'r':
			ls.options |= RAW_OPT;
			break;
		default:
			goto print_usage;
		}
	}

	if (argc > optind+1) {
	print_usage:
		com_err(0, 0, "Usage: ls [-l] [-d] [-p] file");
		return;
	}

	if (argc == optind)
		ino = cwd;
	else
		ino = string_to_inode(argv[optind]);
	if (!ino)
		return;

	ls.f = open_pager();
	ls.col = 0;

	if (debugfs_read_inode(ino, &inode, argv[0]))
		return;

	if (inode.i_flags & EXT4_ENCRYPT_FL)
		ls.options |= ENCRYPT_OPT;

	retval = ext2fs_dir_iterate2(current_fs, ino, flags,
				    0, list_dir_proc, &ls);
	fprintf(ls.f, "\n");
	close_pager(ls.f);
	if (retval)
		com_err(argv[1], retval, 0);

	return;
}


