[Feature][T106]ZXW P56U09 code

Only Configure: Yes
Affected branch: master
Affected module: unknow
Is it affected on both ZXIC and MTK: only ZXIC
Self-test: No
Doc Update: No

Change-Id: I3cbd8b420271eb20c2b40ebe5c78f83059cd42f3
diff --git a/ap/libc/glibc/glibc-2.23/nss/nss_files/files-XXX.c b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-XXX.c
new file mode 100644
index 0000000..3215393
--- /dev/null
+++ b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-XXX.c
@@ -0,0 +1,335 @@
+/* Common code for file-based databases in nss_files module.
+   Copyright (C) 1996-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libc-lock.h>
+#include "nsswitch.h"
+
+#include <kernel-features.h>
+
+/* These symbols are defined by the including source file:
+
+   ENTNAME -- database name of the structure and functions (hostent, pwent).
+   STRUCTURE -- struct name, define only if not ENTNAME (passwd, group).
+   DATABASE -- string of the database file's name ("hosts", "passwd").
+
+   NEED_H_ERRNO - defined iff an arg `int *herrnop' is used.
+
+   Also see files-parse.c.
+*/
+
+#define ENTNAME_r	CONCAT(ENTNAME,_r)
+
+#define DATAFILE	"/etc/" DATABASE
+
+#ifdef NEED_H_ERRNO
+# include <netdb.h>
+# define H_ERRNO_PROTO	, int *herrnop
+# define H_ERRNO_ARG	, herrnop
+# define H_ERRNO_SET(val) (*herrnop = (val))
+#else
+# define H_ERRNO_PROTO
+# define H_ERRNO_ARG
+# define H_ERRNO_SET(val) ((void) 0)
+#endif
+
+#ifndef EXTRA_ARGS
+# define EXTRA_ARGS
+# define EXTRA_ARGS_DECL
+# define EXTRA_ARGS_VALUE
+#endif
+
+/* Locks the static variables in this file.  */
+__libc_lock_define_initialized (static, lock)
+
+/* Maintenance of the stream open on the database file.  For getXXent
+   operations the stream needs to be held open across calls, the other
+   getXXbyYY operations all use their own stream.  */
+
+static FILE *stream;
+
+/* Open database file if not already opened.  */
+static enum nss_status
+internal_setent (FILE **stream)
+{
+  enum nss_status status = NSS_STATUS_SUCCESS;
+
+  if (*stream == NULL)
+    {
+      *stream = fopen (DATAFILE, "rce");
+
+      if (*stream == NULL)
+	status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
+      else
+	{
+#if !defined O_CLOEXEC || !defined __ASSUME_O_CLOEXEC
+# ifdef O_CLOEXEC
+	  if (__have_o_cloexec <= 0)
+# endif
+	    {
+	      /* We have to make sure the file is  `closed on exec'.  */
+	      int result;
+	      int flags;
+
+	      result = flags = fcntl (fileno (*stream), F_GETFD, 0);
+	      if (result >= 0)
+		{
+# ifdef O_CLOEXEC
+		  if (__have_o_cloexec == 0)
+		    __have_o_cloexec = (flags & FD_CLOEXEC) == 0 ? -1 : 1;
+		  if (__have_o_cloexec < 0)
+# endif
+		    {
+		      flags |= FD_CLOEXEC;
+		      result = fcntl (fileno (*stream), F_SETFD, flags);
+		    }
+		}
+	      if (result < 0)
+		{
+		  /* Something went wrong.  Close the stream and return a
+		     failure.  */
+		  fclose (*stream);
+		  *stream = NULL;
+		  status = NSS_STATUS_UNAVAIL;
+		}
+	    }
+#endif
+	}
+    }
+  else
+    rewind (*stream);
+
+  return status;
+}
+
+
+/* Thread-safe, exported version of that.  */
+enum nss_status
+CONCAT(_nss_files_set,ENTNAME) (int stayopen)
+{
+  enum nss_status status;
+
+  __libc_lock_lock (lock);
+
+  status = internal_setent (&stream);
+
+  __libc_lock_unlock (lock);
+
+  return status;
+}
+
+
+/* Close the database file.  */
+static void
+internal_endent (FILE **stream)
+{
+  if (*stream != NULL)
+    {
+      fclose (*stream);
+      *stream = NULL;
+    }
+}
+
+
+/* Thread-safe, exported version of that.  */
+enum nss_status
+CONCAT(_nss_files_end,ENTNAME) (void)
+{
+  __libc_lock_lock (lock);
+
+  internal_endent (&stream);
+
+  __libc_lock_unlock (lock);
+
+  return NSS_STATUS_SUCCESS;
+}
+
+
+typedef enum
+{
+  gcr_ok = 0,
+  gcr_error = -1,
+  gcr_overflow = -2
+} get_contents_ret;
+
+/* Hack around the fact that fgets only accepts int sizes.  */
+static get_contents_ret
+get_contents (char *linebuf, size_t len, FILE *stream)
+{
+  size_t remaining_len = len;
+  char *curbuf = linebuf;
+
+  do
+    {
+      int curlen = ((remaining_len > (size_t) INT_MAX) ? INT_MAX
+		    : remaining_len);
+
+      /* Terminate the line so that we can test for overflow.  */
+      ((unsigned char *) curbuf)[curlen - 1] = 0xff;
+
+      char *p = fgets_unlocked (curbuf, curlen, stream);
+
+      /* EOF or read error.  */
+      if (p == NULL)
+        return gcr_error;
+
+      /* Done reading in the line.  */
+      if (((unsigned char *) curbuf)[curlen - 1] == 0xff)
+        return gcr_ok;
+
+      /* Drop the terminating '\0'.  */
+      remaining_len -= curlen - 1;
+      curbuf += curlen - 1;
+    }
+  /* fgets copies one less than the input length.  Our last iteration is of
+     REMAINING_LEN and once that is done, REMAINING_LEN is decremented by
+     REMAINING_LEN - 1, leaving the result as 1.  */
+  while (remaining_len > 1);
+
+  /* This means that the current buffer was not large enough.  */
+  return gcr_overflow;
+}
+
+/* Parsing the database file into `struct STRUCTURE' data structures.  */
+static enum nss_status
+internal_getent (FILE *stream, struct STRUCTURE *result,
+		 char *buffer, size_t buflen, int *errnop H_ERRNO_PROTO
+		 EXTRA_ARGS_DECL)
+{
+  char *p;
+  struct parser_data *data = (void *) buffer;
+  size_t linebuflen = buffer + buflen - data->linebuffer;
+  int parse_result;
+
+  if (buflen < sizeof *data + 2)
+    {
+      *errnop = ERANGE;
+      H_ERRNO_SET (NETDB_INTERNAL);
+      return NSS_STATUS_TRYAGAIN;
+    }
+
+  do
+    {
+      get_contents_ret r = get_contents (data->linebuffer, linebuflen, stream);
+
+      if (r == gcr_error)
+	{
+	  /* End of file or read error.  */
+	  H_ERRNO_SET (HOST_NOT_FOUND);
+	  return NSS_STATUS_NOTFOUND;
+	}
+
+      if (r == gcr_overflow)
+	{
+	  /* The line is too long.  Give the user the opportunity to
+	     enlarge the buffer.  */
+	  *errnop = ERANGE;
+	  H_ERRNO_SET (NETDB_INTERNAL);
+	  return NSS_STATUS_TRYAGAIN;
+	}
+
+      /* Everything OK.  Now skip leading blanks.  */
+      p = data->linebuffer;
+      while (isspace (*p))
+	++p;
+    }
+  while (*p == '\0' || *p == '#' /* Ignore empty and comment lines.  */
+	 /* Parse the line.  If it is invalid, loop to get the next
+	    line of the file to parse.  */
+	 || ! (parse_result = parse_line (p, result, data, buflen, errnop
+					  EXTRA_ARGS)));
+
+  if (__glibc_unlikely (parse_result == -1))
+    {
+      H_ERRNO_SET (NETDB_INTERNAL);
+      return NSS_STATUS_TRYAGAIN;
+    }
+
+  /* Filled in RESULT with the next entry from the database file.  */
+  return NSS_STATUS_SUCCESS;
+}
+
+
+/* Return the next entry from the database file, doing locking.  */
+enum nss_status
+CONCAT(_nss_files_get,ENTNAME_r) (struct STRUCTURE *result, char *buffer,
+				  size_t buflen, int *errnop H_ERRNO_PROTO)
+{
+  /* Return next entry in host file.  */
+  enum nss_status status = NSS_STATUS_SUCCESS;
+
+  __libc_lock_lock (lock);
+
+  /* Be prepared that the set*ent function was not called before.  */
+  if (stream == NULL)
+    {
+      int save_errno = errno;
+
+      status = internal_setent (&stream);
+
+      __set_errno (save_errno);
+    }
+
+  if (status == NSS_STATUS_SUCCESS)
+    status = internal_getent (stream, result, buffer, buflen, errnop
+			      H_ERRNO_ARG EXTRA_ARGS_VALUE);
+
+  __libc_lock_unlock (lock);
+
+  return status;
+}
+
+/* Macro for defining lookup functions for this file-based database.
+
+   NAME is the name of the lookup; e.g. `hostbyname'.
+
+   DB_CHAR, KEYPATTERN, KEYSIZE are ignored here but used by db-XXX.c
+   e.g. `1 + sizeof (id) * 4'.
+
+   PROTO is the potentially empty list of other parameters.
+
+   BREAK_IF_MATCH is a block of code which compares `struct STRUCTURE *result'
+   to the lookup key arguments and does `break;' if they match.  */
+
+#define DB_LOOKUP(name, db_char, keysize, keypattern, break_if_match, proto...)\
+enum nss_status								      \
+_nss_files_get##name##_r (proto,					      \
+			  struct STRUCTURE *result, char *buffer,	      \
+			  size_t buflen, int *errnop H_ERRNO_PROTO)	      \
+{									      \
+  enum nss_status status;						      \
+  FILE *stream = NULL;							      \
+									      \
+  /* Open file.  */							      \
+  status = internal_setent (&stream);					      \
+									      \
+  if (status == NSS_STATUS_SUCCESS)					      \
+    {									      \
+      while ((status = internal_getent (stream, result, buffer, buflen, errnop \
+					H_ERRNO_ARG EXTRA_ARGS_VALUE))	      \
+	     == NSS_STATUS_SUCCESS)					      \
+	{ break_if_match }						      \
+									      \
+      internal_endent (&stream);					      \
+    }									      \
+									      \
+  return status;							      \
+}
diff --git a/ap/libc/glibc/glibc-2.23/nss/nss_files/files-alias.c b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-alias.c
new file mode 100644
index 0000000..94872b7
--- /dev/null
+++ b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-alias.c
@@ -0,0 +1,439 @@
+/* Mail alias file parser in nss_files module.
+   Copyright (C) 1996-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+   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/>.  */
+
+#include <aliases.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libc-lock.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <kernel-features.h>
+
+#include "nsswitch.h"
+
+/* Locks the static variables in this file.  */
+__libc_lock_define_initialized (static, lock)
+
+/* Maintenance of the stream open on the database file.  For getXXent
+   operations the stream needs to be held open across calls, the other
+   getXXbyYY operations all use their own stream.  */
+
+static FILE *stream;
+
+
+static enum nss_status
+internal_setent (FILE **stream)
+{
+  enum nss_status status = NSS_STATUS_SUCCESS;
+
+  if (*stream == NULL)
+    {
+      *stream = fopen ("/etc/aliases", "rce");
+
+      if (*stream == NULL)
+	status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
+      else
+	{
+#if !defined O_CLOEXEC || !defined __ASSUME_O_CLOEXEC
+# ifdef O_CLOEXEC
+	  if (__have_o_cloexec <= 0)
+# endif
+	    {
+	      /* We have to make sure the file is  `closed on exec'.  */
+	      int result;
+	      int flags;
+
+	      result = flags = fcntl (fileno (*stream), F_GETFD, 0);
+	      if (result >= 0)
+		{
+# ifdef O_CLOEXEC
+		  if (__have_o_cloexec == 0)
+		    __have_o_cloexec = (flags & FD_CLOEXEC) == 0 ? -1 : 1;
+		  if (__have_o_cloexec < 0)
+# endif
+		    {
+		      flags |= FD_CLOEXEC;
+		      result = fcntl (fileno (*stream), F_SETFD, flags);
+		    }
+		}
+	      if (result < 0)
+		{
+		  /* Something went wrong.  Close the stream and return a
+		     failure.  */
+		  fclose (*stream);
+		  stream = NULL;
+		  status = NSS_STATUS_UNAVAIL;
+		}
+	    }
+#endif
+	}
+    }
+  else
+    rewind (*stream);
+
+  return status;
+}
+
+
+/* Thread-safe, exported version of that.  */
+enum nss_status
+_nss_files_setaliasent (void)
+{
+  enum nss_status status;
+
+  __libc_lock_lock (lock);
+
+  status = internal_setent (&stream);
+
+  __libc_lock_unlock (lock);
+
+  return status;
+}
+
+
+/* Close the database file.  */
+static void
+internal_endent (FILE **stream)
+{
+  if (*stream != NULL)
+    {
+      fclose (*stream);
+      *stream = NULL;
+    }
+}
+
+
+/* Thread-safe, exported version of that.  */
+enum nss_status
+_nss_files_endaliasent (void)
+{
+  __libc_lock_lock (lock);
+
+  internal_endent (&stream);
+
+  __libc_lock_unlock (lock);
+
+  return NSS_STATUS_SUCCESS;
+}
+
+/* Parsing the database file into `struct aliasent' data structures.  */
+static enum nss_status
+get_next_alias (FILE *stream, const char *match, struct aliasent *result,
+		char *buffer, size_t buflen, int *errnop)
+{
+  enum nss_status status = NSS_STATUS_NOTFOUND;
+  int ignore = 0;
+
+  result->alias_members_len = 0;
+
+  while (1)
+    {
+      /* Now we are ready to process the input.  We have to read a
+	 line and all its continuations and construct the array of
+	 string pointers.  This pointers and the names itself have to
+	 be placed in BUFFER.  */
+      char *first_unused = buffer;
+      size_t room_left = buflen - (buflen % __alignof__ (char *));
+      char *line;
+
+      /* Check whether the buffer is large enough for even trying to
+	 read something.  */
+      if (room_left < 2)
+	goto no_more_room;
+
+      /* Read the first line.  It must contain the alias name and
+	 possibly some alias names.  */
+      first_unused[room_left - 1] = '\xff';
+      line = fgets_unlocked (first_unused, room_left, stream);
+      if (line == NULL)
+	/* Nothing to read.  */
+	break;
+      else if (first_unused[room_left - 1] != '\xff')
+	{
+	  /* The line is too long for our buffer.  */
+	no_more_room:
+	  *errnop = ERANGE;
+	  status = NSS_STATUS_TRYAGAIN;
+	  break;
+	}
+      else
+	{
+	  char *cp;
+
+	  /* If we are in IGNORE mode and the first character in the
+	     line is a white space we ignore the line and start
+	     reading the next.  */
+	  if (ignore && isspace (*first_unused))
+	    continue;
+
+	  /* Terminate the line for any case.  */
+	  cp = strpbrk (first_unused, "#\n");
+	  if (cp != NULL)
+	    *cp = '\0';
+
+	  /* Skip leading blanks.  */
+	  while (isspace (*line))
+	    ++line;
+
+	  result->alias_name = first_unused;
+	  while (*line != '\0' && *line != ':')
+	    *first_unused++ = *line++;
+	  if (*line == '\0' || result->alias_name == first_unused)
+	    /* No valid name.  Ignore the line.  */
+	    continue;
+
+	  *first_unused++ = '\0';
+	  if (room_left < (size_t) (first_unused - result->alias_name))
+	    goto no_more_room;
+	  room_left -= first_unused - result->alias_name;
+	  ++line;
+
+	  /* When we search for a specific alias we can avoid all the
+	     difficult parts and compare now with the name we are
+	     looking for.  If it does not match we simply ignore all
+	     lines until the next line containing the start of a new
+	     alias is found.  */
+	  ignore = (match != NULL
+		    && __strcasecmp (result->alias_name, match) != 0);
+
+	  while (! ignore)
+	    {
+	      while (isspace (*line))
+		++line;
+
+	      cp = first_unused;
+	      while (*line != '\0' && *line != ',')
+		*first_unused++ = *line++;
+
+	      if (first_unused != cp)
+		{
+		  /* OK, we can have a regular entry or an include
+		     request.  */
+		  if (*line != '\0')
+		    ++line;
+		  *first_unused++ = '\0';
+
+		  if (strncmp (cp, ":include:", 9) != 0)
+		    {
+		      if (room_left < (first_unused - cp) + sizeof (char *))
+			goto no_more_room;
+		      room_left -= (first_unused - cp) + sizeof (char *);
+
+		      ++result->alias_members_len;
+		    }
+		  else
+		    {
+		      /* Oh well, we have to read the addressed file.  */
+		      FILE *listfile;
+		      char *old_line = NULL;
+
+		      first_unused = cp;
+
+		      listfile = fopen (&cp[9], "rce");
+		      /* If the file does not exist we simply ignore
+			 the statement.  */
+		      if (listfile != NULL
+			  && (old_line = strdup (line)) != NULL)
+			{
+			  while (! feof_unlocked (listfile))
+			    {
+			      first_unused[room_left - 1] = '\xff';
+			      line = fgets_unlocked (first_unused, room_left,
+						     listfile);
+			      if (line == NULL)
+				break;
+			      if (first_unused[room_left - 1] != '\xff')
+				{
+				  free (old_line);
+				  goto no_more_room;
+				}
+
+			      /* Parse the line.  */
+			      cp = strpbrk (line, "#\n");
+			      if (cp != NULL)
+				*cp = '\0';
+
+			      do
+				{
+				  while (isspace (*line))
+				    ++line;
+
+				  cp = first_unused;
+				  while (*line != '\0' && *line != ',')
+				    *first_unused++ = *line++;
+
+				  if (*line != '\0')
+				    ++line;
+
+				  if (first_unused != cp)
+				    {
+				      *first_unused++ = '\0';
+				      if (room_left < ((first_unused - cp)
+						       + __alignof__ (char *)))
+					{
+					  free (old_line);
+					  goto no_more_room;
+					}
+				      room_left -= ((first_unused - cp)
+						    + __alignof__ (char *));
+				      ++result->alias_members_len;
+				    }
+				}
+			      while (*line != '\0');
+			    }
+			  fclose (listfile);
+
+			  first_unused[room_left - 1] = '\0';
+			  strncpy (first_unused, old_line, room_left);
+
+			  free (old_line);
+			  line = first_unused;
+
+			  if (first_unused[room_left - 1] != '\0')
+			    goto no_more_room;
+			}
+		    }
+		}
+
+	      if (*line == '\0')
+		{
+		  /* Get the next line.  But we must be careful.  We
+		     must not read the whole line at once since it
+		     might belong to the current alias.  Simply read
+		     the first character.  If it is a white space we
+		     have a continuation line.  Otherwise it is the
+		     beginning of a new alias and we can push back the
+		     just read character.  */
+		  int ch;
+
+		  ch = fgetc_unlocked (stream);
+		  if (ch == EOF || ch == '\n' || !isspace (ch))
+		    {
+		      size_t cnt;
+
+		      /* Now prepare the return.  Provide string
+			 pointers for the currently selected aliases.  */
+		      if (ch != EOF)
+			ungetc (ch, stream);
+
+		      /* Adjust the pointer so it is aligned for
+			 storing pointers.  */
+		      first_unused += __alignof__ (char *) - 1;
+		      first_unused -= ((first_unused - (char *) 0)
+				       % __alignof__ (char *));
+		      result->alias_members = (char **) first_unused;
+
+		      /* Compute addresses of alias entry strings.  */
+		      cp = result->alias_name;
+		      for (cnt = 0; cnt < result->alias_members_len; ++cnt)
+			{
+			  cp = strchr (cp, '\0') + 1;
+			  result->alias_members[cnt] = cp;
+			}
+
+		      status = (result->alias_members_len == 0
+				? NSS_STATUS_RETURN : NSS_STATUS_SUCCESS);
+		      break;
+		    }
+
+		  /* The just read character is a white space and so
+		     can be ignored.  */
+		  first_unused[room_left - 1] = '\xff';
+		  line = fgets_unlocked (first_unused, room_left, stream);
+		  if (first_unused[room_left - 1] != '\xff')
+		    goto no_more_room;
+		  cp = strpbrk (line, "#\n");
+		  if (cp != NULL)
+		    *cp = '\0';
+		}
+	    }
+	}
+
+      if (status != NSS_STATUS_NOTFOUND)
+	/* We read something.  In any case break here.  */
+	break;
+    }
+
+  return status;
+}
+
+
+enum nss_status
+_nss_files_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen,
+			  int *errnop)
+{
+  /* Return next entry in host file.  */
+  enum nss_status status = NSS_STATUS_SUCCESS;
+
+  __libc_lock_lock (lock);
+
+  /* Be prepared that the set*ent function was not called before.  */
+  if (stream == NULL)
+    status = internal_setent (&stream);
+
+  if (status == NSS_STATUS_SUCCESS)
+    {
+      result->alias_local = 1;
+
+      /* Read lines until we get a definite result.  */
+      do
+	status = get_next_alias (stream, NULL, result, buffer, buflen, errnop);
+      while (status == NSS_STATUS_RETURN);
+    }
+
+  __libc_lock_unlock (lock);
+
+  return status;
+}
+
+
+enum nss_status
+_nss_files_getaliasbyname_r (const char *name, struct aliasent *result,
+			     char *buffer, size_t buflen, int *errnop)
+{
+  /* Return next entry in host file.  */
+  enum nss_status status = NSS_STATUS_SUCCESS;
+  FILE *stream = NULL;
+
+  if (name == NULL)
+    {
+      __set_errno (EINVAL);
+      return NSS_STATUS_UNAVAIL;
+    }
+
+  /* Open the stream.  */
+  status = internal_setent (&stream);
+
+  if (status == NSS_STATUS_SUCCESS)
+    {
+      result->alias_local = 1;
+
+      /* Read lines until we get a definite result.  */
+      do
+	status = get_next_alias (stream, name, result, buffer, buflen, errnop);
+      while (status == NSS_STATUS_RETURN);
+    }
+
+  internal_endent (&stream);
+
+  return status;
+}
diff --git a/ap/libc/glibc/glibc-2.23/nss/nss_files/files-ethers.c b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-ethers.c
new file mode 100644
index 0000000..57104f0
--- /dev/null
+++ b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-ethers.c
@@ -0,0 +1,67 @@
+/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#include <string.h>
+#include <netinet/ether.h>
+#include <netinet/if_ether.h>
+
+struct etherent_data {};
+
+#define ENTNAME		etherent
+#define DATABASE	"ethers"
+#include "files-parse.c"
+LINE_PARSER
+("#",
+ /* Read the ethernet address: 6 x 8bit hexadecimal number.  */
+ {
+   size_t cnt;
+
+   for (cnt = 0; cnt < 6; ++cnt)
+     {
+       unsigned int number;
+
+       if (cnt < 5)
+	 INT_FIELD (number, ISCOLON , 0, 16, (unsigned int))
+       else
+	 INT_FIELD (number, isspace, 1, 16, (unsigned int))
+
+       if (number > 0xff)
+	 return 0;
+       result->e_addr.ether_addr_octet[cnt] = number;
+     }
+ };
+ STRING_FIELD (result->e_name, isspace, 1);
+ )
+
+
+#include GENERIC
+
+DB_LOOKUP (hostton, '.', 0, ("%s", name),
+	   {
+	     if (__strcasecmp (result->e_name, name) == 0)
+	       break;
+	   }, const char *name)
+
+DB_LOOKUP (ntohost, '=', 18, ("%x:%x:%x:%x:%x:%x",
+			 addr->ether_addr_octet[0], addr->ether_addr_octet[1],
+			 addr->ether_addr_octet[2], addr->ether_addr_octet[3],
+			 addr->ether_addr_octet[4], addr->ether_addr_octet[5]),
+	   {
+	     if (memcmp (&result->e_addr, addr,
+			 sizeof (struct ether_addr)) == 0)
+	       break;
+	   }, const struct ether_addr *addr)
diff --git a/ap/libc/glibc/glibc-2.23/nss/nss_files/files-grp.c b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-grp.c
new file mode 100644
index 0000000..29d1e5e
--- /dev/null
+++ b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-grp.c
@@ -0,0 +1,44 @@
+/* Group file parser in nss_files module.
+   Copyright (C) 1996-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#include <grp.h>
+
+#define STRUCTURE	group
+#define ENTNAME		grent
+#define DATABASE	"group"
+struct grent_data {};
+
+/* Our parser function is already defined in fgetgrent.c, so use that.
+   to parse lines from the database file.  */
+#define EXTERN_PARSER
+#include "files-parse.c"
+#include GENERIC
+
+DB_LOOKUP (grnam, '.', 0, ("%s", name),
+	   {
+	     if (name[0] != '-' && name[0] != '+'
+		 && ! strcmp (name, result->gr_name))
+	       break;
+	   }, const char *name)
+
+DB_LOOKUP (grgid, '=', 20, ("%lu", (unsigned long int) gid),
+	   {
+	     if (result->gr_gid == gid && result->gr_name[0] != '+'
+		 && result->gr_name[0] != '-')
+	       break;
+	   }, gid_t gid)
diff --git a/ap/libc/glibc/glibc-2.23/nss/nss_files/files-have_o_cloexec.c b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-have_o_cloexec.c
new file mode 100644
index 0000000..30f79ac
--- /dev/null
+++ b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-have_o_cloexec.c
@@ -0,0 +1,23 @@
+/* Copyright (C) 2007-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#include <fcntl.h>
+#include <kernel-features.h>
+
+#if defined O_CLOEXEC && !defined __ASSUME_O_CLOEXEC
+int __have_o_cloexec;
+#endif
diff --git a/ap/libc/glibc/glibc-2.23/nss/nss_files/files-hosts.c b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-hosts.c
new file mode 100644
index 0000000..2a4a665
--- /dev/null
+++ b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-hosts.c
@@ -0,0 +1,482 @@
+/* Hosts file parser in nss_files module.
+   Copyright (C) 1996-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#include <assert.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <resolv.h>
+
+
+/* Get implementation for some internal functions.  */
+#include "../resolv/mapv4v6addr.h"
+#include "../resolv/res_hconf.h"
+
+
+#define ENTNAME		hostent
+#define DATABASE	"hosts"
+#define NEED_H_ERRNO
+
+#define EXTRA_ARGS	 , af, flags
+#define EXTRA_ARGS_DECL	 , int af, int flags
+
+#define ENTDATA hostent_data
+struct hostent_data
+  {
+    unsigned char host_addr[16]; /* IPv4 or IPv6 address.  */
+    char *h_addr_ptrs[2];	/* Points to that and null terminator.  */
+  };
+
+#define TRAILING_LIST_MEMBER		h_aliases
+#define TRAILING_LIST_SEPARATOR_P	isspace
+#include "files-parse.c"
+LINE_PARSER
+("#",
+ {
+   char *addr;
+
+   STRING_FIELD (addr, isspace, 1);
+
+   /* Parse address.  */
+   if (inet_pton (af == AF_UNSPEC ? AF_INET : af, addr, entdata->host_addr)
+       > 0)
+     af = af == AF_UNSPEC ? AF_INET : af;
+   else
+     {
+       if (af == AF_INET6 && (flags & AI_V4MAPPED) != 0
+	   && inet_pton (AF_INET, addr, entdata->host_addr) > 0)
+	 map_v4v6_address ((char *) entdata->host_addr,
+			   (char *) entdata->host_addr);
+       else if (af == AF_INET
+		&& inet_pton (AF_INET6, addr, entdata->host_addr) > 0)
+	 {
+	   if (IN6_IS_ADDR_V4MAPPED (entdata->host_addr))
+	     memcpy (entdata->host_addr, entdata->host_addr + 12, INADDRSZ);
+	   else if (IN6_IS_ADDR_LOOPBACK (entdata->host_addr))
+	     {
+	       in_addr_t localhost = htonl (INADDR_LOOPBACK);
+	       memcpy (entdata->host_addr, &localhost, sizeof (localhost));
+	     }
+	   else
+	     /* Illegal address: ignore line.  */
+	     return 0;
+	 }
+       else if (af == AF_UNSPEC
+		&& inet_pton (AF_INET6, addr, entdata->host_addr) > 0)
+	 af = AF_INET6;
+       else
+	 /* Illegal address: ignore line.  */
+	 return 0;
+     }
+
+   /* We always return entries of the requested form.  */
+   result->h_addrtype = af;
+   result->h_length = af == AF_INET ? INADDRSZ : IN6ADDRSZ;
+
+   /* Store a pointer to the address in the expected form.  */
+   entdata->h_addr_ptrs[0] = (char *) entdata->host_addr;
+   entdata->h_addr_ptrs[1] = NULL;
+   result->h_addr_list = entdata->h_addr_ptrs;
+
+   STRING_FIELD (result->h_name, isspace, 1);
+ })
+
+#define EXTRA_ARGS_VALUE \
+  , ((_res.options & RES_USE_INET6) ? AF_INET6 : AF_INET),		      \
+  ((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0)
+#include "files-XXX.c"
+#undef EXTRA_ARGS_VALUE
+
+/* We only need to consider IPv4 mapped addresses if the input to the
+   gethostbyaddr() function is an IPv6 address.  */
+#define EXTRA_ARGS_VALUE \
+  , af, (len == IN6ADDRSZ ? AI_V4MAPPED : 0)
+DB_LOOKUP (hostbyaddr, ,,,
+	   {
+	     if (result->h_length == (int) len
+		 && ! memcmp (addr, result->h_addr_list[0], len))
+	       break;
+	   }, const void *addr, socklen_t len, int af)
+#undef EXTRA_ARGS_VALUE
+
+enum nss_status
+_nss_files_gethostbyname3_r (const char *name, int af, struct hostent *result,
+			     char *buffer, size_t buflen, int *errnop,
+			     int *herrnop, int32_t *ttlp, char **canonp)
+{
+  FILE *stream = NULL;
+  uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct hostent_data);
+  buffer += pad;
+  buflen = buflen > pad ? buflen - pad : 0;
+
+  /* Open file.  */
+  enum nss_status status = internal_setent (&stream);
+
+  if (status == NSS_STATUS_SUCCESS)
+    {
+      /* XXX Is using _res to determine whether we want to convert IPv4
+         addresses to IPv6 addresses really the right thing to do?  */
+      int flags = ((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0);
+
+      while ((status = internal_getent (stream, result, buffer, buflen, errnop,
+					herrnop, af, flags))
+	     == NSS_STATUS_SUCCESS)
+	{
+	  LOOKUP_NAME_CASE (h_name, h_aliases)
+	}
+
+      if (status == NSS_STATUS_SUCCESS
+	  && _res_hconf.flags & HCONF_FLAG_MULTI)
+	{
+	  /* We have to get all host entries from the file.  */
+	  size_t tmp_buflen = MIN (buflen, 4096);
+	  char tmp_buffer_stack[tmp_buflen]
+	    __attribute__ ((__aligned__ (__alignof__ (struct hostent_data))));
+	  char *tmp_buffer = tmp_buffer_stack;
+	  struct hostent tmp_result_buf;
+	  int naddrs = 1;
+	  int naliases = 0;
+	  char *bufferend;
+	  bool tmp_buffer_malloced = false;
+
+	  while (result->h_aliases[naliases] != NULL)
+	    ++naliases;
+
+	  bufferend = (char *) &result->h_aliases[naliases + 1];
+
+	again:
+	  while ((status = internal_getent (stream, &tmp_result_buf, tmp_buffer,
+					    tmp_buflen, errnop, herrnop, af,
+					    flags))
+		 == NSS_STATUS_SUCCESS)
+	    {
+	      int matches = 1;
+	      struct hostent *old_result = result;
+	      result = &tmp_result_buf;
+	      /* The following piece is a bit clumsy but we want to use the
+		 `LOOKUP_NAME_CASE' value.  The optimizer should do its
+		 job.  */
+	      do
+		{
+		  LOOKUP_NAME_CASE (h_name, h_aliases)
+		  result = old_result;
+		}
+	      while ((matches = 0));
+
+	      if (matches)
+		{
+		  /* We could be very clever and try to recycle a few bytes
+		     in the buffer instead of generating new arrays.  But
+		     we are not doing this here since it's more work than
+		     it's worth.  Simply let the user provide a bit bigger
+		     buffer.  */
+		  char **new_h_addr_list;
+		  char **new_h_aliases;
+		  int newaliases = 0;
+		  size_t newstrlen = 0;
+		  int cnt;
+
+		  /* Count the new aliases and the length of the strings.  */
+		  while (tmp_result_buf.h_aliases[newaliases] != NULL)
+		    {
+		      char *cp = tmp_result_buf.h_aliases[newaliases];
+		      ++newaliases;
+		      newstrlen += strlen (cp) + 1;
+		    }
+		  /* If the real name is different add it also to the
+		     aliases.  This means that there is a duplication
+		     in the alias list but this is really the user's
+		     problem.  */
+		  if (strcmp (old_result->h_name,
+			      tmp_result_buf.h_name) != 0)
+		    {
+		      ++newaliases;
+		      newstrlen += strlen (tmp_result_buf.h_name) + 1;
+		    }
+
+		  /* Make sure bufferend is aligned.  */
+		  assert ((bufferend - (char *) 0) % sizeof (char *) == 0);
+
+		  /* Now we can check whether the buffer is large enough.
+		     16 is the maximal size of the IP address.  */
+		  if (bufferend + 16 + (naddrs + 2) * sizeof (char *)
+		      + roundup (newstrlen, sizeof (char *))
+		      + (naliases + newaliases + 1) * sizeof (char *)
+		      >= buffer + buflen)
+		    {
+		      *errnop = ERANGE;
+		      *herrnop = NETDB_INTERNAL;
+		      status = NSS_STATUS_TRYAGAIN;
+		      goto out;
+		    }
+
+		  new_h_addr_list =
+		    (char **) (bufferend
+			       + roundup (newstrlen, sizeof (char *))
+			       + 16);
+		  new_h_aliases =
+		    (char **) ((char *) new_h_addr_list
+			       + (naddrs + 2) * sizeof (char *));
+
+		  /* Copy the old data in the new arrays.  */
+		  for (cnt = 0; cnt < naddrs; ++cnt)
+		    new_h_addr_list[cnt] = old_result->h_addr_list[cnt];
+
+		  for (cnt = 0; cnt < naliases; ++cnt)
+		    new_h_aliases[cnt] = old_result->h_aliases[cnt];
+
+		  /* Store the new strings.  */
+		  cnt = 0;
+		  while (tmp_result_buf.h_aliases[cnt] != NULL)
+		    {
+		      new_h_aliases[naliases++] = bufferend;
+		      bufferend = (__stpcpy (bufferend,
+					     tmp_result_buf.h_aliases[cnt])
+				   + 1);
+		      ++cnt;
+		    }
+
+		  if (cnt < newaliases)
+		    {
+		      new_h_aliases[naliases++] = bufferend;
+		      bufferend = __stpcpy (bufferend,
+					    tmp_result_buf.h_name) + 1;
+		    }
+
+		  /* Final NULL pointer.  */
+		  new_h_aliases[naliases] = NULL;
+
+		  /* Round up the buffer end address.  */
+		  bufferend += (sizeof (char *)
+				- ((bufferend - (char *) 0)
+				   % sizeof (char *))) % sizeof (char *);
+
+		  /* Now the new address.  */
+		  new_h_addr_list[naddrs++] =
+		    memcpy (bufferend, tmp_result_buf.h_addr,
+			    tmp_result_buf.h_length);
+
+		  /* Also here a final NULL pointer.  */
+		  new_h_addr_list[naddrs] = NULL;
+
+		  /* Store the new array pointers.  */
+		  old_result->h_aliases = new_h_aliases;
+		  old_result->h_addr_list = new_h_addr_list;
+
+		  /* Compute the new buffer end.  */
+		  bufferend = (char *) &new_h_aliases[naliases + 1];
+		  assert (bufferend <= buffer + buflen);
+
+		  result = old_result;
+		}
+	    }
+
+	  if (status == NSS_STATUS_TRYAGAIN)
+	    {
+	      size_t newsize = 2 * tmp_buflen;
+	      if (tmp_buffer_malloced)
+		{
+		  char *newp = realloc (tmp_buffer, newsize);
+		  if (newp != NULL)
+		    {
+		      assert ((((uintptr_t) newp)
+			       & (__alignof__ (struct hostent_data) - 1))
+			      == 0);
+		      tmp_buffer = newp;
+		      tmp_buflen = newsize;
+		      goto again;
+		    }
+		}
+	      else if (!__libc_use_alloca (buflen + newsize))
+		{
+		  tmp_buffer = malloc (newsize);
+		  if (tmp_buffer != NULL)
+		    {
+		      assert ((((uintptr_t) tmp_buffer)
+			       & (__alignof__ (struct hostent_data) - 1))
+			      == 0);
+		      tmp_buffer_malloced = true;
+		      tmp_buflen = newsize;
+		      goto again;
+		    }
+		}
+	      else
+		{
+		  tmp_buffer
+		    = extend_alloca (tmp_buffer, tmp_buflen,
+				     newsize
+				     + __alignof__ (struct hostent_data));
+		  tmp_buffer = (char *) (((uintptr_t) tmp_buffer
+					  + __alignof__ (struct hostent_data)
+					  - 1)
+					 & ~(__alignof__ (struct hostent_data)
+					     - 1));
+		  goto again;
+		}
+	    }
+	  else
+	    status = NSS_STATUS_SUCCESS;
+	out:
+	  if (tmp_buffer_malloced)
+	    free (tmp_buffer);
+	}
+
+      internal_endent (&stream);
+    }
+
+  if (canonp && status == NSS_STATUS_SUCCESS)
+    *canonp = result->h_name;
+
+  return status;
+}
+
+enum nss_status
+_nss_files_gethostbyname_r (const char *name, struct hostent *result,
+			    char *buffer, size_t buflen, int *errnop,
+			    int *herrnop)
+{
+  int af = ((_res.options & RES_USE_INET6) ? AF_INET6 : AF_INET);
+
+  return _nss_files_gethostbyname3_r (name, af, result, buffer, buflen,
+				      errnop, herrnop, NULL, NULL);
+}
+
+enum nss_status
+_nss_files_gethostbyname2_r (const char *name, int af, struct hostent *result,
+			     char *buffer, size_t buflen, int *errnop,
+			     int *herrnop)
+{
+  return _nss_files_gethostbyname3_r (name, af, result, buffer, buflen,
+				      errnop, herrnop, NULL, NULL);
+}
+
+enum nss_status
+_nss_files_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
+			     char *buffer, size_t buflen, int *errnop,
+			     int *herrnop, int32_t *ttlp)
+{
+  FILE *stream = NULL;
+
+  /* Open file.  */
+  enum nss_status status = internal_setent (&stream);
+
+  if (status == NSS_STATUS_SUCCESS)
+    {
+      bool any = false;
+      bool got_canon = false;
+      while (1)
+	{
+	  /* Align the buffer for the next record.  */
+	  uintptr_t pad = (-(uintptr_t) buffer
+			   % __alignof__ (struct hostent_data));
+	  buffer += pad;
+	  buflen = buflen > pad ? buflen - pad : 0;
+
+	  struct hostent result;
+	  status = internal_getent (stream, &result, buffer, buflen, errnop,
+				    herrnop, AF_UNSPEC, 0);
+	  if (status != NSS_STATUS_SUCCESS)
+	    break;
+
+	  int naliases = 0;
+	  if (__strcasecmp (name, result.h_name) != 0)
+	    {
+	      for (; result.h_aliases[naliases] != NULL; ++naliases)
+		if (! __strcasecmp (name, result.h_aliases[naliases]))
+		  break;
+	      if (result.h_aliases[naliases] == NULL)
+		continue;
+
+	      /* We know this alias exist.  Count it.  */
+	      ++naliases;
+	    }
+
+	  /* Determine how much memory has been used so far.  */
+	  // XXX It is not necessary to preserve the aliases array
+	  while (result.h_aliases[naliases] != NULL)
+	    ++naliases;
+	  char *bufferend = (char *) &result.h_aliases[naliases + 1];
+	  assert (buflen >= bufferend - buffer);
+	  buflen -= bufferend - buffer;
+	  buffer = bufferend;
+
+	  /* We found something.  */
+	  any = true;
+
+	  /* Create the record the caller expects.  There is only one
+	     address.  */
+	  assert (result.h_addr_list[1] == NULL);
+	  if (*pat == NULL)
+	    {
+	      uintptr_t pad = (-(uintptr_t) buffer
+			       % __alignof__ (struct gaih_addrtuple));
+	      buffer += pad;
+	      buflen = buflen > pad ? buflen - pad : 0;
+
+	      if (__builtin_expect (buflen < sizeof (struct gaih_addrtuple),
+				    0))
+		{
+		  *errnop = ERANGE;
+		  *herrnop = NETDB_INTERNAL;
+		  status = NSS_STATUS_TRYAGAIN;
+		  break;
+		}
+
+	      *pat = (struct gaih_addrtuple *) buffer;
+	      buffer += sizeof (struct gaih_addrtuple);
+	      buflen -= sizeof (struct gaih_addrtuple);
+	    }
+
+	  (*pat)->next = NULL;
+	  (*pat)->name = got_canon ? NULL : result.h_name;
+	  got_canon = true;
+	  (*pat)->family = result.h_addrtype;
+	  memcpy ((*pat)->addr, result.h_addr_list[0], result.h_length);
+	  (*pat)->scopeid = 0;
+
+	  pat = &((*pat)->next);
+
+	  /* If we only look for the first matching entry we are done.  */
+	  if ((_res_hconf.flags & HCONF_FLAG_MULTI) == 0)
+	    break;
+	}
+
+      /* If we have to look for multiple records and found one, this
+	 is a success.  */
+      if (status == NSS_STATUS_NOTFOUND && any)
+	{
+	  assert ((_res_hconf.flags & HCONF_FLAG_MULTI) != 0);
+	  status = NSS_STATUS_SUCCESS;
+	}
+
+      internal_endent (&stream);
+    }
+  else if (status == NSS_STATUS_TRYAGAIN)
+    {
+      *errnop = errno;
+      *herrnop = TRY_AGAIN;
+    }
+  else
+    {
+      *errnop = errno;
+      *herrnop = NO_DATA;
+    }
+
+  return status;
+}
diff --git a/ap/libc/glibc/glibc-2.23/nss/nss_files/files-init.c b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-init.c
new file mode 100644
index 0000000..9d46529
--- /dev/null
+++ b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-init.c
@@ -0,0 +1,64 @@
+/* Initialization in nss_files module.
+   Copyright (C) 2011-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#ifdef USE_NSCD
+
+#include <string.h>
+#include <nscd/nscd.h>
+
+#define PWD_FILENAME "/etc/passwd"
+define_traced_file (pwd, PWD_FILENAME);
+
+#define GRP_FILENAME "/etc/group"
+define_traced_file (grp, GRP_FILENAME);
+
+#define HST_FILENAME "/etc/hosts"
+define_traced_file (hst, HST_FILENAME);
+
+#define RESOLV_FILENAME "/etc/resolv.conf"
+define_traced_file (resolv, RESOLV_FILENAME);
+
+#define SERV_FILENAME "/etc/services"
+define_traced_file (serv, SERV_FILENAME);
+
+#define NETGR_FILENAME "/etc/netgroup"
+define_traced_file (netgr, NETGR_FILENAME);
+
+void
+_nss_files_init (void (*cb) (size_t, struct traced_file *))
+{
+  init_traced_file (&pwd_traced_file.file, PWD_FILENAME, 0);
+  cb (pwddb, &pwd_traced_file.file);
+
+  init_traced_file (&grp_traced_file.file, GRP_FILENAME, 0);
+  cb (grpdb, &grp_traced_file.file);
+
+  init_traced_file (&hst_traced_file.file, HST_FILENAME, 0);
+  cb (hstdb, &hst_traced_file.file);
+
+  init_traced_file (&resolv_traced_file.file, RESOLV_FILENAME, 1);
+  cb (hstdb, &resolv_traced_file.file);
+
+  init_traced_file (&serv_traced_file.file, SERV_FILENAME, 0);
+  cb (servdb, &serv_traced_file.file);
+
+  init_traced_file (&netgr_traced_file.file, NETGR_FILENAME, 0);
+  cb (netgrdb, &netgr_traced_file.file);
+}
+
+#endif
diff --git a/ap/libc/glibc/glibc-2.23/nss/nss_files/files-initgroups.c b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-initgroups.c
new file mode 100644
index 0000000..6e0d825
--- /dev/null
+++ b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-initgroups.c
@@ -0,0 +1,142 @@
+/* Initgroups handling in nss_files module.
+   Copyright (C) 2011-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#include <alloca.h>
+#include <errno.h>
+#include <grp.h>
+#include <nss.h>
+#include <stdio_ext.h>
+#include <string.h>
+#include <sys/param.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+enum nss_status
+_nss_files_initgroups_dyn (const char *user, gid_t group, long int *start,
+			   long int *size, gid_t **groupsp, long int limit,
+			   int *errnop)
+{
+  FILE *stream = fopen ("/etc/group", "rce");
+  if (stream == NULL)
+    {
+      *errnop = errno;
+      return *errnop == ENOMEM ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
+    }
+
+  /* No other thread using this stream.  */
+  __fsetlocking (stream, FSETLOCKING_BYCALLER);
+
+  char *line = NULL;
+  size_t linelen = 0;
+  enum nss_status status = NSS_STATUS_SUCCESS;
+  bool any = false;
+
+  size_t buflen = 1024;
+  void *buffer = alloca (buflen);
+  bool buffer_use_malloc = false;
+
+  gid_t *groups = *groupsp;
+
+  /* We have to iterate over the entire file.  */
+  while (1)
+    {
+      fpos_t pos;
+      fgetpos (stream, &pos);
+      ssize_t n = getline (&line, &linelen, stream);
+      if (n < 0)
+	{
+	  if (! feof_unlocked (stream))
+	    status = ((*errnop = errno) == ENOMEM
+		      ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL);
+	  break;
+	}
+
+      struct group grp;
+      int res = _nss_files_parse_grent (line, &grp, buffer, buflen, errnop);
+      if (res == -1)
+	{
+	  size_t newbuflen = 2 * buflen;
+	  if (buffer_use_malloc || ! __libc_use_alloca (buflen + newbuflen))
+	    {
+	      void *newbuf = realloc (buffer_use_malloc ? buffer : NULL,
+				      newbuflen);
+	      if (newbuf == NULL)
+		{
+		  *errnop = ENOMEM;
+		  status = NSS_STATUS_TRYAGAIN;
+		  goto out;
+		}
+	      buffer = newbuf;
+	      buflen = newbuflen;
+	      buffer_use_malloc = true;
+	    }
+	  else
+	    buffer = extend_alloca (buffer, buflen, newbuflen);
+	  /* Reread current line, the parser has clobbered it.  */
+	  fsetpos (stream, &pos);
+	  continue;
+	}
+
+      if (res > 0 && grp.gr_gid != group)
+	for (char **m = grp.gr_mem; *m != NULL; ++m)
+	  if (strcmp (*m, user) == 0)
+	    {
+	      /* Matches user.  Insert this group.  */
+	      if (*start == *size)
+		{
+		  /* Need a bigger buffer.  */
+		  if (limit > 0 && *size == limit)
+		    /* We reached the maximum.  */
+		    goto out;
+
+		  long int newsize;
+		  if (limit <= 0)
+		    newsize = 2 * *size;
+		  else
+		    newsize = MIN (limit, 2 * *size);
+
+		  gid_t *newgroups = realloc (groups,
+					      newsize * sizeof (*groups));
+		  if (newgroups == NULL)
+		    {
+		      *errnop = ENOMEM;
+		      status = NSS_STATUS_TRYAGAIN;
+		      goto out;
+		    }
+		  *groupsp = groups = newgroups;
+		  *size = newsize;
+		}
+
+	      groups[*start] = grp.gr_gid;
+	      *start += 1;
+	      any = true;
+
+	      break;
+	    }
+    }
+
+ out:
+  /* Free memory.  */
+  if (buffer_use_malloc)
+    free (buffer);
+  free (line);
+
+  fclose (stream);
+
+  return status == NSS_STATUS_SUCCESS && !any ? NSS_STATUS_NOTFOUND : status;
+}
diff --git a/ap/libc/glibc/glibc-2.23/nss/nss_files/files-key.c b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-key.c
new file mode 100644
index 0000000..5af7ea2
--- /dev/null
+++ b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-key.c
@@ -0,0 +1,111 @@
+/* Public key file parser in nss_files module.
+   Copyright (C) 1996-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <netdb.h>
+#include <rpc/key_prot.h>
+#include <rpc/des_crypt.h>
+#include "nsswitch.h"
+
+#define DATAFILE "/etc/publickey"
+
+
+static enum nss_status
+search (const char *netname, char *result, int *errnop, int secret)
+{
+  FILE *stream = fopen (DATAFILE, "rce");
+  if (stream == NULL)
+    return errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
+
+  for (;;)
+    {
+      char buffer[HEXKEYBYTES * 2 + KEYCHECKSUMSIZE + MAXNETNAMELEN + 17];
+      char *p;
+      char *save_ptr;
+
+      buffer[sizeof (buffer) - 1] = '\xff';
+      p = fgets_unlocked (buffer, sizeof (buffer), stream);
+      if (p == NULL)
+	{
+	  /* End of file or read error.  */
+	  *errnop = errno;
+	  fclose (stream);
+	  return NSS_STATUS_NOTFOUND;
+	}
+      else if (buffer[sizeof (buffer) - 1] != '\xff')
+	{
+	  /* Invalid line in file?  Skip remainder of line.  */
+	  if (buffer[sizeof (buffer) - 2] != '\0')
+	    while (getc_unlocked (stream) != '\n')
+	      continue;
+	  continue;
+	}
+
+      /* Parse line.  */
+      p = __strtok_r (buffer, "# \t:\n", &save_ptr);
+      if (p == NULL) /* Skip empty and comment lines.  */
+	continue;
+      if (strcmp (p, netname) != 0)
+	continue;
+
+      /* A hit!  Find the field we want and return.  */
+      p = __strtok_r (NULL, ":\n", &save_ptr);
+      if (p == NULL)  /* malformed line? */
+	continue;
+      if (secret)
+	p = __strtok_r (NULL, ":\n", &save_ptr);
+      if (p == NULL)  /* malformed line? */
+	continue;
+      fclose (stream);
+      strcpy (result, p);
+      return NSS_STATUS_SUCCESS;
+    }
+}
+
+enum nss_status
+_nss_files_getpublickey (const char *netname, char *pkey, int *errnop)
+{
+  return search (netname, pkey, errnop, 0);
+}
+
+enum nss_status
+_nss_files_getsecretkey (const char *netname, char *skey, char *passwd,
+			 int *errnop)
+{
+  enum nss_status status;
+  char buf[HEXKEYBYTES + KEYCHECKSUMSIZE + 16];
+
+  skey[0] = 0;
+
+  status = search (netname, buf, errnop, 1);
+  if (status != NSS_STATUS_SUCCESS)
+    return status;
+
+  if (!xdecrypt (buf, passwd))
+    return NSS_STATUS_SUCCESS;
+
+  if (memcmp (buf, &(buf[HEXKEYBYTES]), KEYCHECKSUMSIZE) != 0)
+    return NSS_STATUS_SUCCESS;
+
+  buf[HEXKEYBYTES] = 0;
+  strcpy (skey, buf);
+
+  return NSS_STATUS_SUCCESS;
+}
diff --git a/ap/libc/glibc/glibc-2.23/nss/nss_files/files-netgrp.c b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-netgrp.c
new file mode 100644
index 0000000..a1c46b3
--- /dev/null
+++ b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-netgrp.c
@@ -0,0 +1,294 @@
+/* Netgroup file parser in nss_files modules.
+   Copyright (C) 1996-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+   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/>.  */
+
+#include <ctype.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <string.h>
+#include "nsswitch.h"
+#include "netgroup.h"
+
+#define DATAFILE	"/etc/netgroup"
+
+libnss_files_hidden_proto (_nss_files_endnetgrent)
+
+#define EXPAND(needed)							      \
+  do									      \
+    {									      \
+      size_t old_cursor = result->cursor - result->data;		      \
+      void *old_data = result->data;					      \
+									      \
+      result->data_size += 512 > 2 * needed ? 512 : 2 * needed;		      \
+      result->data = realloc (result->data, result->data_size);		      \
+									      \
+      if (result->data == NULL)						      \
+	{								      \
+	  free (old_data);						      \
+	  status = NSS_STATUS_UNAVAIL;					      \
+	  goto the_end;							      \
+	}								      \
+									      \
+      result->cursor = result->data + old_cursor;			      \
+    }									      \
+  while (0)
+
+
+enum nss_status
+_nss_files_setnetgrent (const char *group, struct __netgrent *result)
+{
+  FILE *fp;
+  enum nss_status status;
+
+  if (group[0] == '\0')
+    return NSS_STATUS_UNAVAIL;
+
+  /* Find the netgroups file and open it.  */
+  fp = fopen (DATAFILE, "rce");
+  if (fp == NULL)
+    status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
+  else
+    {
+      /* Read the file line by line and try to find the description
+	 GROUP.  We must take care for long lines.  */
+      char *line = NULL;
+      size_t line_len = 0;
+      const ssize_t group_len = strlen (group);
+
+      status = NSS_STATUS_NOTFOUND;
+      result->cursor = result->data;
+
+      __fsetlocking (fp, FSETLOCKING_BYCALLER);
+
+      while (!feof_unlocked (fp))
+	{
+	  ssize_t curlen = getline (&line, &line_len, fp);
+	  int found;
+
+	  if (curlen < 0)
+	    {
+	      status = NSS_STATUS_NOTFOUND;
+	      break;
+	    }
+
+	  found = (curlen > group_len && strncmp (line, group, group_len) == 0
+		   && isspace (line[group_len]));
+
+	  /* Read the whole line (including continuation) and store it
+	     if FOUND in nonzero.  Otherwise we don't need it.  */
+	  if (found)
+	    {
+	      /* Store the data from the first line.  */
+	      EXPAND (curlen - group_len);
+	      memcpy (result->cursor, &line[group_len + 1],
+		      curlen - group_len);
+	      result->cursor += (curlen - group_len) - 1;
+	    }
+
+	  while (curlen > 1 && line[curlen - 1] == '\n'
+		 && line[curlen - 2] == '\\')
+	    {
+	      /* Yes, we have a continuation line.  */
+	      if (found)
+		/* Remove these characters from the stored line.  */
+		result->cursor -= 2;
+
+	      /* Get next line.  */
+	      curlen = getline (&line, &line_len, fp);
+	      if (curlen <= 0)
+		break;
+
+	      if (found)
+		{
+		  /* Make sure we have enough room.  */
+		  EXPAND (1 + curlen + 1);
+
+		  /* Add separator in case next line starts immediately.  */
+		  *result->cursor++ = ' ';
+
+		  /* Copy new line.  */
+		  memcpy (result->cursor, line, curlen + 1);
+		  result->cursor += curlen;
+		}
+	    }
+
+	  if (found)
+	    {
+	      /* Now we have read the line.  */
+	      status = NSS_STATUS_SUCCESS;
+	      result->cursor = result->data;
+	      result->first = 1;
+	      break;
+	    }
+	}
+
+    the_end:
+      /* We don't need the file and the line buffer anymore.  */
+      free (line);
+      fclose (fp);
+
+      if (status != NSS_STATUS_SUCCESS)
+	_nss_files_endnetgrent (result);
+    }
+
+  return status;
+}
+
+
+enum nss_status
+_nss_files_endnetgrent (struct __netgrent *result)
+{
+  /* Free allocated memory for data if some is present.  */
+  free (result->data);
+  result->data = NULL;
+  result->data_size = 0;
+  result->cursor = NULL;
+  return NSS_STATUS_SUCCESS;
+}
+libnss_files_hidden_def (_nss_files_endnetgrent)
+
+static char *
+strip_whitespace (char *str)
+{
+  char *cp = str;
+
+  /* Skip leading spaces.  */
+  while (isspace (*cp))
+    cp++;
+
+  str = cp;
+  while (*cp != '\0' && ! isspace(*cp))
+    cp++;
+
+  /* Null-terminate, stripping off any trailing spaces.  */
+  *cp = '\0';
+
+  return *str == '\0' ? NULL : str;
+}
+
+enum nss_status
+_nss_netgroup_parseline (char **cursor, struct __netgrent *result,
+			 char *buffer, size_t buflen, int *errnop)
+{
+  enum nss_status status;
+  const char *host, *user, *domain;
+  char *cp = *cursor;
+
+  /* Some sanity checks.  */
+  if (cp == NULL)
+    return NSS_STATUS_NOTFOUND;
+
+  /* First skip leading spaces.  */
+  while (isspace (*cp))
+    ++cp;
+
+  if (*cp != '(')
+    {
+      /* We have a list of other netgroups.  */
+      char *name = cp;
+
+      while (*cp != '\0' && ! isspace (*cp))
+	++cp;
+
+      if (name != cp)
+	{
+	  /* It is another netgroup name.  */
+	  int last = *cp == '\0';
+
+	  result->type = group_val;
+	  result->val.group = name;
+	  *cp = '\0';
+	  if (! last)
+	    ++cp;
+	  *cursor = cp;
+	  result->first = 0;
+
+	  return NSS_STATUS_SUCCESS;
+	}
+
+      return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
+    }
+
+  /* Match host name.  */
+  host = ++cp;
+  while (*cp != ',')
+    if (*cp++ == '\0')
+      return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
+
+  /* Match user name.  */
+  user = ++cp;
+  while (*cp != ',')
+    if (*cp++ == '\0')
+      return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
+
+  /* Match domain name.  */
+  domain = ++cp;
+  while (*cp != ')')
+    if (*cp++ == '\0')
+      return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
+  ++cp;
+
+
+  /* When we got here we have found an entry.  Before we can copy it
+     to the private buffer we have to make sure it is big enough.  */
+  if (cp - host > buflen)
+    {
+      *errnop = ERANGE;
+      status = NSS_STATUS_TRYAGAIN;
+    }
+  else
+    {
+      memcpy (buffer, host, cp - host);
+      result->type = triple_val;
+
+      buffer[(user - host) - 1] = '\0';	/* Replace ',' with '\0'.  */
+      result->val.triple.host = strip_whitespace (buffer);
+
+      buffer[(domain - host) - 1] = '\0'; /* Replace ',' with '\0'.  */
+      result->val.triple.user = strip_whitespace (buffer + (user - host));
+
+      buffer[(cp - host) - 1] = '\0'; /* Replace ')' with '\0'.  */
+      result->val.triple.domain = strip_whitespace (buffer + (domain - host));
+
+      status = NSS_STATUS_SUCCESS;
+
+      /* Remember where we stopped reading.  */
+      *cursor = cp;
+
+      result->first = 0;
+    }
+
+  return status;
+}
+libnss_files_hidden_def (_nss_netgroup_parseline)
+
+
+enum nss_status
+_nss_files_getnetgrent_r (struct __netgrent *result, char *buffer,
+			  size_t buflen, int *errnop)
+{
+  enum nss_status status;
+
+  status = _nss_netgroup_parseline (&result->cursor, result, buffer, buflen,
+				    errnop);
+
+  return status;
+}
diff --git a/ap/libc/glibc/glibc-2.23/nss/nss_files/files-network.c b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-network.c
new file mode 100644
index 0000000..8c95ed5
--- /dev/null
+++ b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-network.c
@@ -0,0 +1,88 @@
+/* Networks file parser in nss_files module.
+   Copyright (C) 1996-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdint.h>
+
+#define ENTNAME		netent
+#define DATABASE	"networks"
+#define NEED_H_ERRNO
+
+struct netent_data {};
+
+#define TRAILING_LIST_MEMBER		n_aliases
+#define TRAILING_LIST_SEPARATOR_P	isspace
+#include "files-parse.c"
+LINE_PARSER
+("#",
+ {
+   char *addr;
+   char *cp;
+   int n = 1;
+
+   STRING_FIELD (result->n_name, isspace, 1);
+
+   STRING_FIELD (addr, isspace, 1);
+   /* 'inet_network' does not add zeroes at the end if the network number
+      does not four byte values.  We add them outselves if necessary.  */
+   cp = strchr (addr, '.');
+   if (cp != NULL)
+     {
+       ++n;
+       cp = strchr (cp + 1, '.');
+       if (cp != NULL)
+	 {
+	   ++n;
+	   cp = strchr (cp + 1, '.');
+	   if (cp != NULL)
+	     ++n;
+	 }
+     }
+   if (n < 4)
+     {
+       char *newp = (char *) alloca (strlen (addr) + (4 - n) * 2 + 1);
+       cp = stpcpy (newp, addr);
+       do
+	 {
+	   *cp++ = '.';
+	   *cp++ = '0';
+	 }
+       while (++n < 4);
+       *cp = '\0';
+       addr = newp;
+     }
+   result->n_net = inet_network (addr);
+   result->n_addrtype = AF_INET;
+
+ })
+
+#include "files-XXX.c"
+
+DB_LOOKUP (netbyname, ,,,
+	   LOOKUP_NAME_CASE (n_name, n_aliases),
+	   const char *name)
+
+DB_LOOKUP (netbyaddr, ,,,
+	   {
+	     if ((type == AF_UNSPEC || result->n_addrtype == type)
+		 && result->n_net == net)
+	       /* Bingo!  */
+	       break;
+	   }, uint32_t net, int type)
diff --git a/ap/libc/glibc/glibc-2.23/nss/nss_files/files-parse.c b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-parse.c
new file mode 100644
index 0000000..3648754
--- /dev/null
+++ b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-parse.c
@@ -0,0 +1,335 @@
+/* Common code for file-based database parsers in nss_files module.
+   Copyright (C) 1996-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+/* These symbols are defined by the including source file:
+
+   ENTNAME -- database name of the structure and functions (hostent, pwent).
+   STRUCTURE -- struct name, define only if not ENTNAME (passwd, group).
+   DATABASE -- string of the database file's name ("hosts", "passwd").
+
+   ENTDATA -- if defined, `struct ENTDATA' is used by the parser to store
+	      things pointed to by the resultant `struct STRUCTURE'.
+
+   NEED_H_ERRNO - defined iff an arg `int *herrnop' is used.
+
+   EXTRA_ARGS -- defined iff extra parameters must be passed to the parser
+   EXTRA_ARGS_DECL -- declaration for these extra parameters
+   EXTRA_ARGS_VALUE -- values to be passed for these parameters
+
+   Also see files-XXX.c.  */
+
+#ifndef EXTRA_ARGS
+# define EXTRA_ARGS
+# define EXTRA_ARGS_DECL
+# define EXTRA_ARGS_VALUE
+#endif
+
+#define CONCAT(a,b) CONCAT1(a,b)
+#define CONCAT1(a,b) a##b
+
+#ifndef STRUCTURE
+# define STRUCTURE ENTNAME
+#endif
+
+
+struct parser_data
+  {
+#ifdef ENTDATA
+    struct ENTDATA entdata;
+# define ENTDATA_DECL(data) struct ENTDATA *const entdata = &data->entdata;
+#else
+# define ENTDATA_DECL(data)
+#endif
+    char linebuffer[0];
+  };
+
+#ifdef ENTDATA
+/* The function can't be exported, because the entdata structure
+   is defined only in files-foo.c.  */
+# define parser_stclass static
+# define nss_files_parse_hidden_def(name)
+#else
+/* Export the line parser function so it can be used in nss_db.  */
+# define parser_stclass /* Global */
+# define parse_line CONCAT(_nss_files_parse_,ENTNAME)
+# if IS_IN (libc)
+/* We are defining one of the functions that actually lives in libc
+   because it is used to implement fget*ent and suchlike.  */
+#  define nss_files_parse_hidden_def(name) libc_hidden_def (name)
+# else
+#  define nss_files_parse_hidden_def(name) libnss_files_hidden_def (name)
+# endif
+#endif
+
+
+#ifdef EXTERN_PARSER
+
+/* The parser is defined in a different module.  */
+extern int parse_line (char *line, struct STRUCTURE *result,
+		       struct parser_data *data, size_t datalen, int *errnop
+		       EXTRA_ARGS_DECL);
+
+# define LINE_PARSER(EOLSET, BODY) /* Do nothing */
+
+#else
+
+/* Define a line parsing function.  */
+
+# define LINE_PARSER(EOLSET, BODY)					      \
+parser_stclass int							      \
+parse_line (char *line, struct STRUCTURE *result,			      \
+	    struct parser_data *data, size_t datalen, int *errnop	      \
+	    EXTRA_ARGS_DECL)						      \
+{									      \
+  ENTDATA_DECL (data)							      \
+  BUFFER_PREPARE							      \
+  char *p = strpbrk (line, EOLSET "\n");				      \
+  if (p != NULL)							      \
+    *p = '\0';								      \
+  BODY;									      \
+  TRAILING_LIST_PARSER;							      \
+  return 1;								      \
+}									      \
+nss_files_parse_hidden_def (parse_line)
+
+
+# define STRING_FIELD(variable, terminator_p, swallow)			      \
+  {									      \
+    variable = line;							      \
+    while (*line != '\0' && !terminator_p (*line))			      \
+      ++line;								      \
+    if (*line != '\0')							      \
+      {									      \
+	*line = '\0';							      \
+	do								      \
+	  ++line;							      \
+	while (swallow && terminator_p (*line));			      \
+      }									      \
+  }
+
+# define STRING_LIST(variable, terminator_c) \
+  {									      \
+    char **list = parse_list (&line, buf_start, buf_end, terminator_c,	      \
+			      errnop);					      \
+    if (list)								      \
+      variable = list;							      \
+    else								      \
+      return -1;		/* -1 indicates we ran out of space.  */      \
+									      \
+    /* Determine the new end of the buffer.  */				      \
+    while (*list != NULL)						      \
+      ++list;								      \
+    buf_start = (char *) (list + 1);					      \
+  }
+
+/* Helper function.  */
+static inline uint32_t
+__attribute__ ((always_inline))
+strtou32 (const char *nptr, char **endptr, int base)
+{
+  unsigned long int val = strtoul (nptr, endptr, base);
+
+  /* Match the 32-bit behavior on 64-bit platforms.  */
+  if (sizeof (long int) > 4 && val > 0xffffffff)
+    val = 0xffffffff;
+
+  return val;
+}
+
+# define INT_FIELD(variable, terminator_p, swallow, base, convert)	      \
+  {									      \
+    char *endp;								      \
+    variable = convert (strtou32 (line, &endp, base));			      \
+    if (endp == line)							      \
+      return 0;								      \
+    else if (terminator_p (*endp))					      \
+      do								      \
+	++endp;								      \
+      while (swallow && terminator_p (*endp));				      \
+    else if (*endp != '\0')						      \
+      return 0;								      \
+    line = endp;							      \
+  }
+
+# define INT_FIELD_MAYBE_NULL(variable, terminator_p, swallow, base, convert, default)	      \
+  {									      \
+    char *endp;								      \
+    if (*line == '\0')							      \
+      /* We expect some more input, so don't allow the string to end here. */ \
+      return 0;								      \
+    variable = convert (strtou32 (line, &endp, base));			      \
+    if (endp == line)							      \
+      variable = default;						      \
+    if (terminator_p (*endp))						      \
+      do								      \
+	++endp;								      \
+      while (swallow && terminator_p (*endp));				      \
+    else if (*endp != '\0')						      \
+      return 0;								      \
+    line = endp;							      \
+  }
+
+# define ISCOLON(c) ((c) == ':')
+
+
+# ifndef TRAILING_LIST_MEMBER
+#  define BUFFER_PREPARE /* Nothing to do.  */
+#  define TRAILING_LIST_PARSER /* Nothing to do.  */
+# else
+
+# define BUFFER_PREPARE \
+  char *buf_start = NULL;						      \
+  char *buf_end = (char *) data + datalen;				      \
+  if (line >= data->linebuffer && line < buf_end)			      \
+    /* Find the end of the line buffer, we will use the space in	      \
+       DATA after it for storing the vector of pointers.  */		      \
+    buf_start = strchr (line, '\0') + 1;				      \
+  else									      \
+    /* LINE does not point within DATA->linebuffer, so that space is	      \
+       not being used for scratch space right now.  We can use all of	      \
+       it for the pointer vector storage.  */				      \
+    buf_start = data->linebuffer;					      \
+
+#  define TRAILING_LIST_PARSER \
+{									      \
+  if (buf_start == NULL)						      \
+    {									      \
+      if (line >= data->linebuffer && line < buf_end)			      \
+	/* Find the end of the line buffer, we will use the space in	      \
+	   DATA after it for storing the vector of pointers.  */	      \
+	buf_start = strchr (line, '\0') + 1;				      \
+      else								      \
+	/* LINE does not point within DATA->linebuffer, so that space is      \
+	   not being used for scratch space right now.  We can use all of     \
+	   it for the pointer vector storage.  */			      \
+	buf_start = data->linebuffer;					      \
+    }									      \
+									      \
+  char **list = parse_list (&line, buf_start, buf_end, '\0', errnop);	      \
+  if (list)								      \
+    result->TRAILING_LIST_MEMBER = list;				      \
+  else									      \
+    return -1;		/* -1 indicates we ran out of space.  */	      \
+}
+
+static inline char **
+__attribute ((always_inline))
+parse_list (char **linep, char *eol, char *buf_end, int terminator_c,
+	    int *errnop)
+{
+  char *line = *linep;
+  char **list, **p;
+
+  /* Adjust the pointer so it is aligned for storing pointers.  */
+  eol += __alignof__ (char *) - 1;
+  eol -= (eol - (char *) 0) % __alignof__ (char *);
+  /* We will start the storage here for the vector of pointers.  */
+  list = (char **) eol;
+
+  p = list;
+  while (1)
+    {
+      if ((char *) (p + 2) > buf_end)
+	{
+	  /* We cannot fit another pointer in the buffer.  */
+	  *errnop = ERANGE;
+	  return NULL;
+	}
+
+      if (*line == '\0')
+	break;
+      if (*line == terminator_c)
+	{
+	  ++line;
+	  break;
+	}
+
+      /* Skip leading white space.  This might not be portable but useful.  */
+      while (isspace (*line))
+	++line;
+
+      char *elt = line;
+      while (1)
+	{
+	  if (*line == '\0' || *line == terminator_c
+	      || TRAILING_LIST_SEPARATOR_P (*line))
+	    {
+	      /* End of the next entry.  */
+	      if (line > elt)
+		/* We really found some data.  */
+		*p++ = elt;
+
+	      /* Terminate string if necessary.  */
+	      if (*line != '\0')
+		{
+		  char endc = *line;
+		  *line++ = '\0';
+		  if (endc == terminator_c)
+		    goto out;
+		}
+	      break;
+	    }
+	  ++line;
+	}
+    }
+ out:
+  *p = NULL;
+  *linep = line;
+
+  return list;
+}
+
+# endif	/* TRAILING_LIST_MEMBER */
+#endif	/* EXTERN_PARSER */
+
+
+#define LOOKUP_NAME(nameelt, aliaselt)					      \
+{									      \
+  char **ap;								      \
+  if (! strcmp (name, result->nameelt))					      \
+    break;								      \
+  for (ap = result->aliaselt; *ap; ++ap)				      \
+    if (! strcmp (name, *ap))						      \
+      break;								      \
+  if (*ap)								      \
+    break;								      \
+}
+
+#define LOOKUP_NAME_CASE(nameelt, aliaselt)				      \
+{									      \
+  char **ap;								      \
+  if (! __strcasecmp (name, result->nameelt))				      \
+    break;								      \
+  for (ap = result->aliaselt; *ap; ++ap)				      \
+    if (! __strcasecmp (name, *ap))					      \
+      break;								      \
+  if (*ap)								      \
+    break;								      \
+}
+
+
+/* This is defined by db-*.c to include "../nss_db/db-XXX.c" instead.  */
+#ifndef GENERIC
+# define GENERIC "files-XXX.c"
+#endif
diff --git a/ap/libc/glibc/glibc-2.23/nss/nss_files/files-proto.c b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-proto.c
new file mode 100644
index 0000000..90a85f0
--- /dev/null
+++ b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-proto.c
@@ -0,0 +1,46 @@
+/* Protocols file parser in nss_files module.
+   Copyright (C) 1996-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#include <netdb.h>
+
+
+#define ENTNAME		protoent
+#define DATABASE	"protocols"
+
+struct protoent_data {};
+
+#define TRAILING_LIST_MEMBER		p_aliases
+#define TRAILING_LIST_SEPARATOR_P	isspace
+#include "files-parse.c"
+LINE_PARSER
+("#",
+ STRING_FIELD (result->p_name, isspace, 1);
+ INT_FIELD (result->p_proto, isspace, 1, 10,);
+ )
+
+#include GENERIC
+
+DB_LOOKUP (protobyname, '.', 0, ("%s", name),
+	   LOOKUP_NAME (p_name, p_aliases),
+	   const char *name)
+
+DB_LOOKUP (protobynumber, '=', 20, ("%zd", (ssize_t) proto),
+	   {
+	     if (result->p_proto == proto)
+	       break;
+	   }, int proto)
diff --git a/ap/libc/glibc/glibc-2.23/nss/nss_files/files-pwd.c b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-pwd.c
new file mode 100644
index 0000000..823e58a
--- /dev/null
+++ b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-pwd.c
@@ -0,0 +1,44 @@
+/* User file parser in nss_files module.
+   Copyright (C) 1996-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#include <pwd.h>
+
+#define STRUCTURE	passwd
+#define ENTNAME		pwent
+#define DATABASE	"passwd"
+struct pwent_data {};
+
+/* Our parser function is already defined in fgetpwent_r.c, so use that
+   to parse lines from the database file.  */
+#define EXTERN_PARSER
+#include "files-parse.c"
+#include GENERIC
+
+DB_LOOKUP (pwnam, '.', 0, ("%s", name),
+	   {
+	     if (name[0] != '+' && name[0] != '-'
+		 && ! strcmp (name, result->pw_name))
+	       break;
+	   }, const char *name)
+
+DB_LOOKUP (pwuid, '=', 20, ("%lu", (unsigned long int) uid),
+	   {
+	     if (result->pw_uid == uid && result->pw_name[0] != '+'
+		 && result->pw_name[0] != '-')
+	       break;
+	   }, uid_t uid)
diff --git a/ap/libc/glibc/glibc-2.23/nss/nss_files/files-rpc.c b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-rpc.c
new file mode 100644
index 0000000..5b9a91f
--- /dev/null
+++ b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-rpc.c
@@ -0,0 +1,46 @@
+/* SunRPC program number file parser in nss_files module.
+   Copyright (C) 1996-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#include <rpc/netdb.h>
+
+
+#define ENTNAME		rpcent
+#define DATABASE	"rpc"
+
+struct rpcent_data {};
+
+#define TRAILING_LIST_MEMBER		r_aliases
+#define TRAILING_LIST_SEPARATOR_P	isspace
+#include "files-parse.c"
+LINE_PARSER
+("#",
+ STRING_FIELD (result->r_name, isspace, 1);
+ INT_FIELD (result->r_number, isspace, 1, 10,);
+ )
+
+#include GENERIC
+
+DB_LOOKUP (rpcbyname, '.', 0, ("%s", name),
+	   LOOKUP_NAME (r_name, r_aliases),
+	   const char *name)
+
+DB_LOOKUP (rpcbynumber, '=', 20, ("%zd", (ssize_t) number),
+	   {
+	     if (result->r_number == number)
+	       break;
+	   }, int number)
diff --git a/ap/libc/glibc/glibc-2.23/nss/nss_files/files-service.c b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-service.c
new file mode 100644
index 0000000..7a6e226
--- /dev/null
+++ b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-service.c
@@ -0,0 +1,63 @@
+/* Services file parser in nss_files module.
+   Copyright (C) 1996-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#include <netinet/in.h>
+#include <netdb.h>
+
+
+#define ENTNAME		servent
+#define DATABASE	"services"
+
+struct servent_data {};
+
+#define TRAILING_LIST_MEMBER		s_aliases
+#define TRAILING_LIST_SEPARATOR_P	isspace
+#include "files-parse.c"
+#define ISSLASH(c) ((c) == '/')
+LINE_PARSER
+("#",
+ STRING_FIELD (result->s_name, isspace, 1);
+ INT_FIELD (result->s_port, ISSLASH, 10, 0, htons);
+ STRING_FIELD (result->s_proto, isspace, 1);
+ )
+
+#include GENERIC
+
+DB_LOOKUP (servbyname, ':',
+	   strlen (name) + 2 + (proto == NULL ? 0 : strlen (proto)),
+	   ("%s/%s", name, proto ?: ""),
+	   {
+	     /* Must match both protocol (if specified) and name.  */
+	     if (proto != NULL && strcmp (result->s_proto, proto))
+	       /* A continue statement here breaks nss_db, because it
+		bypasses advancing to the next db entry, and it
+		doesn't make nss_files any more efficient.  */;
+	     else
+	       LOOKUP_NAME (s_name, s_aliases)
+	   },
+	   const char *name, const char *proto)
+
+DB_LOOKUP (servbyport, '=', 21 + (proto ? strlen (proto) : 0),
+	   ("%zd/%s", (ssize_t) ntohs (port), proto ?: ""),
+	   {
+	     /* Must match both port and protocol.  */
+	     if (result->s_port == port
+		 && (proto == NULL
+		     || strcmp (result->s_proto, proto) == 0))
+	       break;
+	   }, int port, const char *proto)
diff --git a/ap/libc/glibc/glibc-2.23/nss/nss_files/files-sgrp.c b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-sgrp.c
new file mode 100644
index 0000000..15dc659
--- /dev/null
+++ b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-sgrp.c
@@ -0,0 +1,37 @@
+/* User file parser in nss_files module.
+   Copyright (C) 2009-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#include <gshadow.h>
+
+#define STRUCTURE	sgrp
+#define ENTNAME		sgent
+#define DATABASE	"gshadow"
+struct sgent_data {};
+
+/* Our parser function is already defined in sgetspent_r.c, so use that
+   to parse lines from the database file.  */
+#define EXTERN_PARSER
+#include "files-parse.c"
+#include GENERIC
+
+DB_LOOKUP (sgnam, '.', 0, ("%s", name),
+	   {
+	     if (name[0] != '+' && name[0] != '-'
+		 && ! strcmp (name, result->sg_namp))
+	       break;
+	   }, const char *name)
diff --git a/ap/libc/glibc/glibc-2.23/nss/nss_files/files-spwd.c b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-spwd.c
new file mode 100644
index 0000000..652dc13
--- /dev/null
+++ b/ap/libc/glibc/glibc-2.23/nss/nss_files/files-spwd.c
@@ -0,0 +1,37 @@
+/* User file parser in nss_files module.
+   Copyright (C) 1996-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#include <shadow.h>
+
+#define STRUCTURE	spwd
+#define ENTNAME		spent
+#define DATABASE	"shadow"
+struct spent_data {};
+
+/* Our parser function is already defined in sgetspent_r.c, so use that
+   to parse lines from the database file.  */
+#define EXTERN_PARSER
+#include "files-parse.c"
+#include GENERIC
+
+DB_LOOKUP (spnam, '.', 0, ("%s", name),
+	   {
+	     if (name[0] != '+' && name[0] != '-'
+		 && ! strcmp (name, result->sp_namp))
+	       break;
+	   }, const char *name)