/* Test program for returning the canonical absolute name of a given file.
   Copyright (C) 1996-2018 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by David Mosberger <davidm@azstarnet.com>.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

/* This file must be run from within a directory called "stdlib".  */

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/stat.h>

/* Prototype for our test function.  */
extern int do_test (int argc, char *argv[]);
#include <test-skeleton.c>

#ifndef PATH_MAX
# define PATH_MAX 4096
#endif
static char	cwd[PATH_MAX];
static size_t	cwd_len;

struct {
  const char *	name;
  const char *	value;
} symlinks[] = {
  {"SYMLINK_LOOP",	"SYMLINK_LOOP"},
  {"SYMLINK_1",		"."},
  {"SYMLINK_2",		"//////./../../etc"},
  {"SYMLINK_3",		"SYMLINK_1"},
  {"SYMLINK_4",		"SYMLINK_2"},
  {"SYMLINK_5",		"doesNotExist"},
};

struct {
  const char * in, * out, * resolved;
  int error;
} tests[] = {
  /*  0 */
  {"/",					"/"},
  {"/////////////////////////////////",	"/"},
  {"/.././.././.././..///",		"/"},
  {"/etc",				"/etc"},
  {"/etc/../etc",			"/etc"},
  /*  5 */
  {"/doesNotExist/../etc",		0, "/doesNotExist", ENOENT},
  {"./././././././././.",		"."},
  {"/etc/.//doesNotExist",		0, "/etc/doesNotExist", ENOENT},
  {"./doesExist",			"./doesExist"},
  {"./doesExist/",			"./doesExist"},
  /* 10 */
  {"./doesExist/../doesExist",		"./doesExist"},
  {"foobar",				0, "./foobar", ENOENT},
  {".",					"."},
  {"./foobar",				0, "./foobar", ENOENT},
  {"SYMLINK_LOOP",			0, "./SYMLINK_LOOP", ELOOP},
  /* 15 */
  {"./SYMLINK_LOOP",			0, "./SYMLINK_LOOP", ELOOP},
  {"SYMLINK_1",				"."},
  {"SYMLINK_1/foobar",			0, "./foobar", ENOENT},
  {"SYMLINK_2",				"/etc"},
  {"SYMLINK_3",				"."},
  /* 20 */
  {"SYMLINK_4",				"/etc"},
  {"../stdlib/SYMLINK_1",		"."},
  {"../stdlib/SYMLINK_2",		"/etc"},
  {"../stdlib/SYMLINK_3",		"."},
  {"../stdlib/SYMLINK_4",		"/etc"},
  /* 25 */
  {"./SYMLINK_5",			0, "./doesNotExist", ENOENT},
  {"SYMLINK_5",				0, "./doesNotExist", ENOENT},
  {"SYMLINK_5/foobar",			0, "./doesNotExist", ENOENT},
  {"doesExist/../../stdlib/doesExist",	"./doesExist"},
  {"doesExist/.././../stdlib/.",	"."},
  /* 30 */
  {"./doesExist/someFile/",		0, "./doesExist/someFile", ENOTDIR},
  {"./doesExist/someFile/..",		0, "./doesExist/someFile", ENOTDIR},
};


static int
check_path (const char * result, const char * expected)
{
  int good;

  if (!result)
    return (expected == NULL);

  if (!expected)
    return 0;

  if (expected[0] == '.' && (expected[1] == '/' || expected[1] == '\0'))
    good = (strncmp (result, cwd, cwd_len) == 0
	    && strcmp (result + cwd_len, expected + 1) == 0);
  else
    good = (strcmp (expected, result) == 0);

  return good;
}


int
do_test (int argc, char ** argv)
{
  char * result;
  int i, errors = 0;
  char buf[PATH_MAX];

  getcwd (cwd, sizeof(buf));
  cwd_len = strlen (cwd);

  errno = 0;
  if (realpath (NULL, buf) != NULL || errno != EINVAL)
    {
      printf ("%s: expected return value NULL and errno set to EINVAL"
	      " for realpath(NULL,...)\n", argv[0]);
      ++errors;
    }

#if 0
  /* This is now allowed.  The test is invalid.  */
  errno = 0;
  if (realpath ("/", NULL) != NULL || errno != EINVAL)
    {
      printf ("%s: expected return value NULL and errno set to EINVAL"
	      " for realpath(...,NULL)\n", argv[0]);
      ++errors;
    }
#endif

  errno = 0;
  if (realpath ("", buf) != NULL || errno != ENOENT)
    {
      printf ("%s: expected return value NULL and set errno to ENOENT"
	      " for realpath(\"\",...)\n", argv[0]);
      ++errors;
    }

  for (i = 0; i < (int) (sizeof (symlinks) / sizeof (symlinks[0])); ++i)
    symlink (symlinks[i].value, symlinks[i].name);

  int has_dir = mkdir ("doesExist", 0777) == 0;

  int fd = has_dir ? creat ("doesExist/someFile", 0777) : -1;

  for (i = 0; i < (int) (sizeof (tests) / sizeof (tests[0])); ++i)
    {
      buf[0] = '\0';
      result = realpath (tests[i].in, buf);

      if (!check_path (result, tests[i].out))
	{
	  printf ("%s: flunked test %d (expected `%s', got `%s')\n",
		  argv[0], i, tests[i].out ? tests[i].out : "NULL",
		  result ? result : "NULL");
	  ++errors;
	  continue;
	}

      if (!check_path (buf, tests[i].out ? tests[i].out : tests[i].resolved))
	{
	  printf ("%s: flunked test %d (expected resolved `%s', got `%s')\n",
		  argv[0], i, tests[i].out ? tests[i].out : tests[i].resolved,
		  buf);
	  ++errors;
	  continue;
	}

      if (!tests[i].out && errno != tests[i].error)
	{
	  printf ("%s: flunked test %d (expected errno %d, got %d)\n",
		  argv[0], i, tests[i].error, errno);
	  ++errors;
	  continue;
	}

      char *result2 = realpath (tests[i].in, NULL);
      if ((result2 == NULL && result != NULL)
	  || (result2 != NULL && strcmp (result, result2) != 0))
	{
	  printf ("\
%s: realpath(..., NULL) produced different result than realpath(..., buf): '%s' vs '%s'\n",
		  argv[0], result2, result);
	  ++errors;
	}
      free (result2);
    }

  getcwd (buf, sizeof(buf));
  if (strcmp (buf, cwd))
    {
      printf ("%s: current working directory changed from %s to %s\n",
	      argv[0], cwd, buf);
      ++errors;
    }

  if (fd >= 0)
    {
      close (fd);
      unlink ("doesExist/someFile");
    }

  if (has_dir)
    rmdir ("doesExist");

  for (i = 0; i < (int) (sizeof (symlinks) / sizeof (symlinks[0])); ++i)
    unlink (symlinks[i].name);

  if (errors != 0)
    {
      printf ("%d errors.\n", errors);
      return EXIT_FAILURE;
    }

  puts ("No errors.");
  return EXIT_SUCCESS;
}
