/*
 * Copyright (c) 2003-2013
 * Distributed Systems Software.  All rights reserved.
 * See the file LICENSE for redistribution information.
 */

/*
 * Program for testing the fts() library function
 * It does a recursive directory listing of the given directory
 * (default is ".") and prints each filename, its nesting level, and its type.
 * The -1 flag prevents descending into subdirectories.
 *
 * Usage:
 * ftstest [-1] [directory]
 */

#ifndef lint
static const char copyright[] =
"Copyright (c) 2003-2013\n\
Distributed Systems Software.  All rights reserved.";
static const char revid[] =
  "$Id: ftstest.c 2669 2013-10-22 17:03:44Z brachman $";
#endif

#include "dacs_config.h"

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

#ifdef ENABLE_FTS
#include "dacs_fts.h"
#else
#include <fts.h>
#endif

static int onelevel = 0;

int
main(int argc, char **argv)
{
  int i, n;
  char **hier;
  FTS *ftsp;
  FTSENT *f;

  if (argc > 1 && strcmp(argv[1], "-1") == 0) {
	onelevel = 1;
	argc--;
	argv++;
  }

  if (argc == 1) {
	hier = (char **) malloc(sizeof(char *) * 2);
	hier[0] = ".";
	hier[1] = NULL;
  }
  else {
	hier = (char **) malloc(sizeof(char *) * argc);
	for (i = 1; i < argc; i++)
	  hier[i - 1] = argv[i];
	hier[i - 1] = NULL;
  }

  ftsp = fts_open(hier, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, NULL);
  if (ftsp == NULL) {
	perror("fts_open");
	exit(1);
  }

  n = 0;
  while ((f = fts_read(ftsp)) != NULL) {
	n++;
	printf("%s: ", f->fts_path);

	printf("L%d ", f->fts_level);

	if (f->fts_info == FTS_D)
	  printf("FTS_D");
	else if (f->fts_info == FTS_DC)
	  printf("FTS_DC");
	else if (f->fts_info == FTS_DEFAULT)
	  printf("FTS_DEFAULT");
	else if (f->fts_info == FTS_DNR)
	  printf("FTS_DNR (%s)", strerror(f->fts_errno));
	else if (f->fts_info == FTS_DOT)
	  printf("FTS_DOT");
	else if (f->fts_info == FTS_DP)
	  printf("FTS_DP");
	else if (f->fts_info == FTS_F)
	  printf("FTS_F");
	else if (f->fts_info == FTS_NS)
	  printf("FTS_NS (%s)", strerror(f->fts_errno));
	else if (f->fts_info == FTS_NSOK)
	  printf("FTS_NSOK");
	else if (f->fts_info == FTS_SL)
	  printf("FTS_SL");
	else if (f->fts_info == FTS_SLNONE)
	  printf("FTS_SLNONE");
	else if (f->fts_info == FTS_ERR)
	  printf("FTS_ERR (%s)", strerror(f->fts_errno));
	else
	  printf("FTS_???");

	if (f->fts_info == FTS_NS || f->fts_info == FTS_NSOK)
	  printf(" (nostat)");
	else
	  printf(" (%lu bytes)", (unsigned long) f->fts_statp->st_size);

	printf("\n");

	if (onelevel && f->fts_level > 0
		&& (f->fts_info == FTS_D || f->fts_info == FTS_DP)) {
	  if (fts_set(ftsp, f, FTS_SKIP) == -1) {
		perror("fts_set");
		exit(1);
	  }
	}
  }

  if (errno != 0) {
	perror("fts_read");
	exit(1);
  }

  fts_close(ftsp);
  exit(0);
}
