(root)/
glibc-2.38/
catgets/
catgets.c
       1  /* Copyright (C) 1996-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <errno.h>
      19  #include <locale.h>
      20  #include <nl_types.h>
      21  #include <stdlib.h>
      22  #include <string.h>
      23  #include <unistd.h>
      24  #include <sys/mman.h>
      25  
      26  #include "catgetsinfo.h"
      27  
      28  
      29  /* Open the catalog and return a descriptor for the catalog.  */
      30  nl_catd
      31  catopen (const char *cat_name, int flag)
      32  {
      33    __nl_catd result;
      34    const char *env_var = NULL;
      35    const char *nlspath = NULL;
      36    char *tmp = NULL;
      37  
      38    if (strchr (cat_name, '/') == NULL)
      39      {
      40        if (flag == NL_CAT_LOCALE)
      41  	/* Use the current locale setting for LC_MESSAGES.  */
      42  	env_var = setlocale (LC_MESSAGES, NULL);
      43        else
      44  	/* Use the LANG environment variable.  */
      45  	env_var = getenv ("LANG");
      46  
      47        if (env_var == NULL || *env_var == '\0'
      48  	  || (__libc_enable_secure && strchr (env_var, '/') != NULL))
      49  	env_var = "C";
      50  
      51        nlspath = getenv ("NLSPATH");
      52        if (nlspath != NULL && *nlspath != '\0')
      53  	{
      54  	  /* Append the system dependent directory.  */
      55  	  size_t len = strlen (nlspath) + 1 + sizeof NLSPATH;
      56  	  tmp = malloc (len);
      57  
      58  	  if (__glibc_unlikely (tmp == NULL))
      59  	    return (nl_catd) -1;
      60  
      61  	  __stpcpy (__stpcpy (__stpcpy (tmp, nlspath), ":"), NLSPATH);
      62  	  nlspath = tmp;
      63  	}
      64        else
      65  	nlspath = NLSPATH;
      66      }
      67  
      68    result = (__nl_catd) malloc (sizeof (*result));
      69    if (result == NULL)
      70      {
      71        /* We cannot get enough memory.  */
      72        result = (nl_catd) -1;
      73      }
      74    else if (__open_catalog (cat_name, nlspath, env_var, result) != 0)
      75      {
      76        /* Couldn't open the file.  */
      77        free ((void *) result);
      78        result = (nl_catd) -1;
      79      }
      80  
      81    free (tmp);
      82    return (nl_catd) result;
      83  }
      84  
      85  
      86  /* Return message from message catalog.  */
      87  char *
      88  catgets (nl_catd catalog_desc, int set, int message, const char *string)
      89  {
      90    __nl_catd catalog;
      91    size_t idx;
      92    size_t cnt;
      93  
      94    /* Be generous if catalog which failed to be open is used.  */
      95    if (catalog_desc == (nl_catd) -1 || ++set <= 0 || message < 0)
      96      return (char *) string;
      97  
      98    catalog = (__nl_catd) catalog_desc;
      99  
     100    idx = ((set * message) % catalog->plane_size) * 3;
     101    cnt = 0;
     102    do
     103      {
     104        if (catalog->name_ptr[idx + 0] == (uint32_t) set
     105  	  && catalog->name_ptr[idx + 1] == (uint32_t) message)
     106  	return (char *) &catalog->strings[catalog->name_ptr[idx + 2]];
     107  
     108        idx += catalog->plane_size * 3;
     109      }
     110    while (++cnt < catalog->plane_depth);
     111  
     112    __set_errno (ENOMSG);
     113    return (char *) string;
     114  }
     115  
     116  
     117  /* Return resources used for loaded message catalog.  */
     118  int
     119  catclose (nl_catd catalog_desc)
     120  {
     121    __nl_catd catalog;
     122  
     123    /* Be generous if catalog which failed to be open is used.  */
     124    if (catalog_desc == (nl_catd) -1)
     125      {
     126        __set_errno (EBADF);
     127        return -1;
     128      }
     129  
     130    catalog = (__nl_catd) catalog_desc;
     131  
     132  #ifdef _POSIX_MAPPED_FILES
     133    if (catalog->status == mmapped)
     134      __munmap ((void *) catalog->file_ptr, catalog->file_size);
     135    else
     136  #endif	/* _POSIX_MAPPED_FILES */
     137      if (catalog->status == malloced)
     138        free ((void *) catalog->file_ptr);
     139      else
     140        {
     141  	__set_errno (EBADF);
     142  	return -1;
     143        }
     144  
     145    free ((void *) catalog);
     146  
     147    return 0;
     148  }