/* Copyright (C) 1991-2018 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 <argz.h>
#include <errno.h>
#include <libc-lock.h>
#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "localeinfo.h"

#ifdef NL_CURRENT_INDIRECT

/* For each category declare a special external symbol
   _nl_current_CATEGORY_used with a weak reference.
   This symbol will is defined in lc-CATEGORY.c and will be linked in
   if anything uses _nl_current_CATEGORY (also defined in that module).
   Also use a weak reference for the _nl_current_CATEGORY thread variable.  */

# define DEFINE_CATEGORY(category, category_name, items, a) \
    extern char _nl_current_##category##_used; \
    weak_extern (_nl_current_##category##_used) \
    weak_extern (_nl_current_##category)
# include "categories.def"
# undef	DEFINE_CATEGORY

/* Now define a table of flags based on those special weak symbols' values.
   _nl_current_used[CATEGORY] will be zero if _nl_current_CATEGORY is not
   linked in.  */
static char *const _nl_current_used[] =
  {
# define DEFINE_CATEGORY(category, category_name, items, a) \
    [category] = &_nl_current_##category##_used,
# include "categories.def"
# undef	DEFINE_CATEGORY
  };

# define CATEGORY_USED(category)	(_nl_current_used[category] != 0)

#else

/* The shared library always loads all the categories,
   and the current global settings are kept in _nl_global_locale.  */

# define CATEGORY_USED(category)	(1)

#endif


/* Define an array of category names (also the environment variable names).  */
const union catnamestr_t _nl_category_names attribute_hidden =
  {
    {
#define DEFINE_CATEGORY(category, category_name, items, a) \
      category_name,
#include "categories.def"
#undef DEFINE_CATEGORY
    }
  };

const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden =
  {
#define DEFINE_CATEGORY(category, category_name, items, a) \
    [category] = offsetof (union catnamestr_t, CATNAMEMF (__LINE__)),
#include "categories.def"
#undef DEFINE_CATEGORY
  };

/* An array of their lengths, for convenience.  */
const uint8_t _nl_category_name_sizes[] attribute_hidden =
  {
#define DEFINE_CATEGORY(category, category_name, items, a) \
    [category] = sizeof (category_name) - 1,
#include "categories.def"
#undef	DEFINE_CATEGORY
    [LC_ALL] = sizeof ("LC_ALL") - 1
  };


#ifdef NL_CURRENT_INDIRECT
# define WEAK_POSTLOAD(postload) weak_extern (postload)
#else
# define WEAK_POSTLOAD(postload) /* Need strong refs in static linking.  */
#endif

/* Declare the postload functions used below.  */
#undef	NO_POSTLOAD
#define NO_POSTLOAD _nl_postload_ctype /* Harmless thing known to exist.  */
#define DEFINE_CATEGORY(category, category_name, items, postload) \
extern void postload (void); WEAK_POSTLOAD (postload)
#include "categories.def"
#undef	DEFINE_CATEGORY
#undef	NO_POSTLOAD

/* Define an array indexed by category of postload functions to call after
   loading and installing that category's data.  */
static void (*const _nl_category_postload[]) (void) =
  {
#define DEFINE_CATEGORY(category, category_name, items, postload) \
    [category] = postload,
#include "categories.def"
#undef	DEFINE_CATEGORY
  };


/* Lock for protecting global data.  */
__libc_rwlock_define_initialized (, __libc_setlocale_lock attribute_hidden)

/* Defined in loadmsgcat.c.  */
extern int _nl_msg_cat_cntr;


/* Use this when we come along an error.  */
#define ERROR_RETURN							      \
  do {									      \
    __set_errno (EINVAL);						      \
    return NULL;							      \
  } while (0)


/* Construct a new composite name.  */
static char *
new_composite_name (int category, const char *newnames[__LC_LAST])
{
  size_t last_len = 0;
  size_t cumlen = 0;
  int i;
  char *new, *p;
  int same = 1;

  for (i = 0; i < __LC_LAST; ++i)
    if (i != LC_ALL)
      {
	const char *name = (category == LC_ALL ? newnames[i] :
			    category == i ? newnames[0] :
			    _nl_global_locale.__names[i]);
	last_len = strlen (name);
	cumlen += _nl_category_name_sizes[i] + 1 + last_len + 1;
	if (same && name != newnames[0] && strcmp (name, newnames[0]) != 0)
	  same = 0;
      }

  if (same)
    {
      /* All the categories use the same name.  */
      if (strcmp (newnames[0], _nl_C_name) == 0
	  || strcmp (newnames[0], _nl_POSIX_name) == 0)
	return (char *) _nl_C_name;

      new = malloc (last_len + 1);

      return new == NULL ? NULL : memcpy (new, newnames[0], last_len + 1);
    }

  new = malloc (cumlen);
  if (new == NULL)
    return NULL;
  p = new;
  for (i = 0; i < __LC_LAST; ++i)
    if (i != LC_ALL)
      {
	/* Add "CATEGORY=NAME;" to the string.  */
	const char *name = (category == LC_ALL ? newnames[i] :
			    category == i ? newnames[0] :
			    _nl_global_locale.__names[i]);
	p = __stpcpy (p, _nl_category_names.str + _nl_category_name_idxs[i]);
	*p++ = '=';
	p = __stpcpy (p, name);
	*p++ = ';';
      }
  p[-1] = '\0';		/* Clobber the last ';'.  */
  return new;
}


/* Put NAME in _nl_global_locale.__names.  */
static void
setname (int category, const char *name)
{
  if (_nl_global_locale.__names[category] == name)
    return;

  if (_nl_global_locale.__names[category] != _nl_C_name)
    free ((char *) _nl_global_locale.__names[category]);

  _nl_global_locale.__names[category] = name;
}

/* Put DATA in *_nl_current[CATEGORY].  */
static void
setdata (int category, struct __locale_data *data)
{
  if (CATEGORY_USED (category))
    {
      _nl_global_locale.__locales[category] = data;
      if (_nl_category_postload[category])
	(*_nl_category_postload[category]) ();
    }
}

char *
setlocale (int category, const char *locale)
{
  char *locale_path;
  size_t locale_path_len;
  const char *locpath_var;
  char *composite;

  /* Sanity check for CATEGORY argument.  */
  if (__builtin_expect (category, 0) < 0
      || __builtin_expect (category, 0) >= __LC_LAST)
    ERROR_RETURN;

  /* Does user want name of current locale?  */
  if (locale == NULL)
    return (char *) _nl_global_locale.__names[category];

  /* Protect global data.  */
  __libc_rwlock_wrlock (__libc_setlocale_lock);

  if (strcmp (locale, _nl_global_locale.__names[category]) == 0)
    {
      /* Changing to the same thing.  */
      __libc_rwlock_unlock (__libc_setlocale_lock);

      return (char *) _nl_global_locale.__names[category];
    }

  /* We perhaps really have to load some data.  So we determine the
     path in which to look for the data now.  The environment variable
     `LOCPATH' must only be used when the binary has no SUID or SGID
     bit set.  If using the default path, we tell _nl_find_locale
     by passing null and it can check the canonical locale archive.  */
  locale_path = NULL;
  locale_path_len = 0;

  locpath_var = getenv ("LOCPATH");
  if (locpath_var != NULL && locpath_var[0] != '\0')
    {
      if (__argz_create_sep (locpath_var, ':',
			     &locale_path, &locale_path_len) != 0
	  || __argz_add_sep (&locale_path, &locale_path_len,
			     _nl_default_locale_path, ':') != 0)
	{
	  __libc_rwlock_unlock (__libc_setlocale_lock);
	  return NULL;
	}
    }

  if (category == LC_ALL)
    {
      /* The user wants to set all categories.  The desired locales
	 for the individual categories can be selected by using a
	 composite locale name.  This is a semi-colon separated list
	 of entries of the form `CATEGORY=VALUE'.  */
      const char *newnames[__LC_LAST];
      struct __locale_data *newdata[__LC_LAST];
      /* Copy of the locale argument, for in-place splitting.  */
      char *locale_copy = NULL;

      /* Set all name pointers to the argument name.  */
      for (category = 0; category < __LC_LAST; ++category)
	if (category != LC_ALL)
	  newnames[category] = (char *) locale;

      if (__glibc_unlikely (strchr (locale, ';') != NULL))
	{
	  /* This is a composite name.  Make a copy and split it up.  */
	  locale_copy = __strdup (locale);
	  if (__glibc_unlikely (locale_copy == NULL))
	    {
	      __libc_rwlock_unlock (__libc_setlocale_lock);
	      return NULL;
	    }
	  char *np = locale_copy;
	  char *cp;
	  int cnt;

	  while ((cp = strchr (np, '=')) != NULL)
	    {
	      for (cnt = 0; cnt < __LC_LAST; ++cnt)
		if (cnt != LC_ALL
		    && (size_t) (cp - np) == _nl_category_name_sizes[cnt]
		    && (memcmp (np, (_nl_category_names.str
				     + _nl_category_name_idxs[cnt]), cp - np)
			== 0))
		  break;

	      if (cnt == __LC_LAST)
		{
		error_return:
		  __libc_rwlock_unlock (__libc_setlocale_lock);
		  free (locale_copy);

		  /* Bogus category name.  */
		  ERROR_RETURN;
		}

	      /* Found the category this clause sets.  */
	      newnames[cnt] = ++cp;
	      cp = strchr (cp, ';');
	      if (cp != NULL)
		{
		  /* Examine the next clause.  */
		  *cp = '\0';
		  np = cp + 1;
		}
	      else
		/* This was the last clause.  We are done.  */
		break;
	    }

	  for (cnt = 0; cnt < __LC_LAST; ++cnt)
	    if (cnt != LC_ALL && newnames[cnt] == locale)
	      /* The composite name did not specify all categories.  */
	      goto error_return;
	}

      /* Load the new data for each category.  */
      while (category-- > 0)
	if (category != LC_ALL)
	  {
	    newdata[category] = _nl_find_locale (locale_path, locale_path_len,
						 category,
						 &newnames[category]);

	    if (newdata[category] == NULL)
	      {
#ifdef NL_CURRENT_INDIRECT
		if (newnames[category] == _nl_C_name)
		  /* Null because it's the weak value of _nl_C_LC_FOO.  */
		  continue;
#endif
		break;
	      }

	    /* We must not simply free a global locale since we have
	       no control over the usage.  So we mark it as
	       un-deletable.  And yes, the 'if' is needed, the data
	       might be in read-only memory.  */
	    if (newdata[category]->usage_count != UNDELETABLE)
	      newdata[category]->usage_count = UNDELETABLE;

	    /* Make a copy of locale name.  */
	    if (newnames[category] != _nl_C_name)
	      {
		if (strcmp (newnames[category],
			    _nl_global_locale.__names[category]) == 0)
		  newnames[category] = _nl_global_locale.__names[category];
		else
		  {
		    newnames[category] = __strdup (newnames[category]);
		    if (newnames[category] == NULL)
		      break;
		  }
	      }
	  }

      /* Create new composite name.  */
      composite = (category >= 0
		   ? NULL : new_composite_name (LC_ALL, newnames));
      if (composite != NULL)
	{
	  /* Now we have loaded all the new data.  Put it in place.  */
	  for (category = 0; category < __LC_LAST; ++category)
	    if (category != LC_ALL)
	      {
		setdata (category, newdata[category]);
		setname (category, newnames[category]);
	      }
	  setname (LC_ALL, composite);

	  /* We successfully loaded a new locale.  Let the message catalog
	     functions know about this.  */
	  ++_nl_msg_cat_cntr;
	}
      else
	for (++category; category < __LC_LAST; ++category)
	  if (category != LC_ALL && newnames[category] != _nl_C_name
	      && newnames[category] != _nl_global_locale.__names[category])
	    free ((char *) newnames[category]);

      /* Critical section left.  */
      __libc_rwlock_unlock (__libc_setlocale_lock);

      /* Free the resources.  */
      free (locale_path);
      free (locale_copy);

      return composite;
    }
  else
    {
      struct __locale_data *newdata = NULL;
      const char *newname[1] = { locale };

      if (CATEGORY_USED (category))
	{
	  /* Only actually load the data if anything will use it.  */
	  newdata = _nl_find_locale (locale_path, locale_path_len, category,
				     &newname[0]);
	  if (newdata == NULL)
	    goto abort_single;

	  /* We must not simply free a global locale since we have no
	     control over the usage.  So we mark it as un-deletable.

	     Note: do not remove the `if', it's necessary to cope with
	     the builtin locale data.  */
	  if (newdata->usage_count != UNDELETABLE)
	    newdata->usage_count = UNDELETABLE;
	}

      /* Make a copy of locale name.  */
      if (newname[0] != _nl_C_name)
	{
	  newname[0] = __strdup (newname[0]);
	  if (newname[0] == NULL)
	    goto abort_single;
	}

      /* Create new composite name.  */
      composite = new_composite_name (category, newname);
      if (composite == NULL)
	{
	  if (newname[0] != _nl_C_name)
	    free ((char *) newname[0]);

	  /* Say that we don't have any data loaded.  */
	abort_single:
	  newname[0] = NULL;
	}
      else
	{
	  if (CATEGORY_USED (category))
	    setdata (category, newdata);

	  setname (category, newname[0]);
	  setname (LC_ALL, composite);

	  /* We successfully loaded a new locale.  Let the message catalog
	     functions know about this.  */
	  ++_nl_msg_cat_cntr;
	}

      /* Critical section left.  */
      __libc_rwlock_unlock (__libc_setlocale_lock);

      /* Free the resources (the locale path variable.  */
      free (locale_path);

      return (char *) newname[0];
    }
}
libc_hidden_def (setlocale)

static void __libc_freeres_fn_section
free_category (int category,
	       struct __locale_data *here, struct __locale_data *c_data)
{
  struct loaded_l10nfile *runp = _nl_locale_file_list[category];

  /* If this category is already "C" don't do anything.  */
  if (here != c_data)
    {
      /* We have to be prepared that sometime later we still
	 might need the locale information.  */
      setdata (category, c_data);
      setname (category, _nl_C_name);
    }

  while (runp != NULL)
    {
      struct loaded_l10nfile *curr = runp;
      struct __locale_data *data = (struct __locale_data *) runp->data;

      if (data != NULL && data != c_data)
	_nl_unload_locale (data);
      runp = runp->next;
      free ((char *) curr->filename);
      free (curr);
    }
}

/* This is called from iconv/gconv_db.c's free_mem, as locales must
   be freed before freeing gconv steps arrays.  */
void __libc_freeres_fn_section
_nl_locale_subfreeres (void)
{
#ifdef NL_CURRENT_INDIRECT
  /* We don't use the loop because we want to have individual weak
     symbol references here.  */
# define DEFINE_CATEGORY(category, category_name, items, a)		      \
  if (CATEGORY_USED (category))						      \
    {									      \
      extern struct __locale_data _nl_C_##category;			      \
      weak_extern (_nl_C_##category)					      \
      free_category (category, *_nl_current_##category, &_nl_C_##category);   \
    }
# include "categories.def"
# undef	DEFINE_CATEGORY
#else
  int category;

  for (category = 0; category < __LC_LAST; ++category)
    if (category != LC_ALL)
      free_category (category, _NL_CURRENT_DATA (category),
		     _nl_C_locobj.__locales[category]);
#endif

  setname (LC_ALL, _nl_C_name);

  /* This frees the data structures associated with the locale archive.
     The locales from the archive are not in the file list, so we have
     not called _nl_unload_locale on them above.  */
  _nl_archive_subfreeres ();
}
