/*
 * Copyright (c) International Business Machines  Corp., 2001
 *	         written by Wayne Boyer
 * Copyright (c) 2013 Markos Chandras
 * Copyright (c) 2013 Cyril Hrubis <chrubis@suse.cz>
 *
 * This program is free software;  you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "test.h"
#include "safe_macros.h"
#include "getdents.h"

static void cleanup(void);
static void setup(void);

static void reset_flags(void);
static void check_flags(void);
static void set_flag(const char *name);

char *TCID = "getdents01";
int TST_TOTAL = 1;

static int longsyscall;

static option_t options[] = {
		/* -l long option. Tests getdents64 */
		{"l", &longsyscall, NULL},
		{NULL, NULL, NULL}
};

static void help(void)
{
	printf("  -l      Test the getdents64 system call\n");
}

enum entry_type {
	ENTRY_DIR,
	ENTRY_FILE,
	ENTRY_SYMLINK,
};

struct testcase {
	const char *name;
	enum entry_type type;
	int create:1;
	int found:1;
};

struct testcase testcases[] = {
	{.name = ".",       .create = 0, .type = ENTRY_DIR},
	{.name = "..",      .create = 0, .type = ENTRY_DIR},
	{.name = "dir",     .create = 1, .type = ENTRY_DIR},
	{.name = "file",    .create = 1, .type = ENTRY_FILE},
	{.name = "symlink", .create = 1, .type = ENTRY_SYMLINK},
};

/*
 * Big enough for dirp entires + data, the current size returned
 * by kernel is 128 bytes.
 */
#define BUFSIZE 512

int main(int ac, char **av)
{
	int lc;
	const char *msg;
	int rval, fd;
	struct linux_dirent64 *dirp64;
	struct linux_dirent *dirp;
	void *buf;

	/* The buffer is allocated to make sure it's suitably aligned */
	buf = malloc(BUFSIZE);

	if (buf == NULL)
		tst_brkm(TBROK, NULL, "malloc failed");

	dirp64 = buf;
	dirp = buf;

	if ((msg = parse_opts(ac, av, options, &help)) != NULL)
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);

	setup();

	for (lc = 0; TEST_LOOPING(lc); lc++) {
		const char *d_name;

		tst_count = 0;

		if ((fd = open(".", O_RDONLY)) == -1)
			tst_brkm(TBROK, cleanup, "open of directory failed");

		if (longsyscall)
			rval = getdents64(fd, dirp64, BUFSIZE);
		else
			rval = getdents(fd, dirp, BUFSIZE);

		if (rval < 0) {
			if (errno == ENOSYS)
				tst_resm(TCONF, "syscall not implemented");
			else
				tst_resm(TFAIL | TERRNO,
				         "getdents failed unexpectedly");
			continue;
		}

		if (rval == 0) {
			tst_resm(TFAIL,
				 "getdents failed - returned end of directory");
			continue;
		}

		reset_flags();

		do {
			size_t d_reclen;

			if (longsyscall) {
				d_reclen = dirp64->d_reclen;
				d_name = dirp64->d_name;
			} else {
				d_reclen = dirp->d_reclen;
				d_name = dirp->d_name;
			}

			set_flag(d_name);

			tst_resm(TINFO, "Found '%s'", d_name);
			
			rval -= d_reclen;
			
			if (longsyscall)
				dirp64 = (void*)dirp64 + d_reclen;
			else
				dirp = (void*)dirp + d_reclen;

		} while (rval > 0);

		if (close(fd) == -1)
			tst_brkm(TBROK | TERRNO, cleanup, "Directory close failed");
	
		check_flags();
	}

	free(buf);

	cleanup();
	tst_exit();
}

static void reset_flags(void)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(testcases); i++)
		testcases[i].found = 0;
}

static void check_flags(void)
{
	int i, err = 0;

	for (i = 0; i < ARRAY_SIZE(testcases); i++) {
		if (!testcases[i].found) {
			tst_resm(TINFO, "Entry '%s' not found", testcases[i].name);
			err++;
		}
	}

	if (err)
		tst_resm(TFAIL, "Some entires not found");
	else
		tst_resm(TPASS, "All entires found");
}

static void set_flag(const char *name)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(testcases); i++) {
		if (!strcmp(name, testcases[i].name)) {
			testcases[i].found = 1;
			return;
		}
	}

	tst_resm(TFAIL, "Unexpected entry '%s' found", name);
}

static void setup(void)
{
	int i;

	tst_sig(NOFORK, DEF_HANDLER, cleanup);

	tst_tmpdir();

	for (i = 0; i < ARRAY_SIZE(testcases); i++) {
		
		if (!testcases[i].create)
			continue;
	
		switch (testcases[i].type) {
		case ENTRY_DIR:
			SAFE_MKDIR(cleanup, testcases[i].name, 0777);
		break;
		case ENTRY_FILE:
			SAFE_FILE_PRINTF(cleanup, testcases[i].name, " ");
		break;
		case ENTRY_SYMLINK:
			SAFE_SYMLINK(cleanup, "nonexistent", testcases[i].name);
		break;
		}
	}

	TEST_PAUSE;
}

static void cleanup(void)
{
	tst_rmdir();
}
