(yp_bind_client_create): Use __libc_clntpudp_bufcreate instead of
[kopensolaris-gnu/glibc.git] / intl / dcigettext.c
1 /* Implementation of the internal dcigettext function.
2    Copyright (C) 1995-2005, 2006, 2007, 2008
3    Free Software Foundation, Inc.
4    This file is part of the GNU C Library.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
20
21 /* Tell glibc's <string.h> to provide a prototype for mempcpy().
22    This must come before <config.h> because <config.h> may include
23    <features.h>, and once <features.h> has been included, it's too late.  */
24 #ifndef _GNU_SOURCE
25 # define _GNU_SOURCE    1
26 #endif
27
28 #ifdef HAVE_CONFIG_H
29 # include <config.h>
30 #endif
31
32 #include <sys/types.h>
33
34 #ifdef __GNUC__
35 # define alloca __builtin_alloca
36 # define HAVE_ALLOCA 1
37 #else
38 # if defined HAVE_ALLOCA_H || defined _LIBC
39 #  include <alloca.h>
40 # else
41 #  ifdef _AIX
42  #pragma alloca
43 #  else
44 #   ifndef alloca
45 char *alloca ();
46 #   endif
47 #  endif
48 # endif
49 #endif
50
51 #include <errno.h>
52 #ifndef errno
53 extern int errno;
54 #endif
55 #ifndef __set_errno
56 # define __set_errno(val) errno = (val)
57 #endif
58
59 #include <stddef.h>
60 #include <stdlib.h>
61 #include <string.h>
62
63 #if defined HAVE_UNISTD_H || defined _LIBC
64 # include <unistd.h>
65 #endif
66
67 #include <locale.h>
68
69 #if defined HAVE_SYS_PARAM_H || defined _LIBC
70 # include <sys/param.h>
71 #endif
72
73 #include "gettextP.h"
74 #include "plural-exp.h"
75 #ifdef _LIBC
76 # include <libintl.h>
77 #else
78 # include "libgnuintl.h"
79 #endif
80 #include "hash-string.h"
81
82 /* Thread safetyness.  */
83 #ifdef _LIBC
84 # include <bits/libc-lock.h>
85 #else
86 /* Provide dummy implementation if this is outside glibc.  */
87 # define __libc_lock_define_initialized(CLASS, NAME)
88 # define __libc_lock_lock(NAME)
89 # define __libc_lock_unlock(NAME)
90 # define __libc_rwlock_define_initialized(CLASS, NAME)
91 # define __libc_rwlock_rdlock(NAME)
92 # define __libc_rwlock_unlock(NAME)
93 #endif
94
95 /* Alignment of types.  */
96 #if defined __GNUC__ && __GNUC__ >= 2
97 # define alignof(TYPE) __alignof__ (TYPE)
98 #else
99 # define alignof(TYPE) \
100     ((int) &((struct { char dummy1; TYPE dummy2; } *) 0)->dummy2)
101 #endif
102
103 /* The internal variables in the standalone libintl.a must have different
104    names than the internal variables in GNU libc, otherwise programs
105    using libintl.a cannot be linked statically.  */
106 #if !defined _LIBC
107 # define _nl_default_default_domain libintl_nl_default_default_domain
108 # define _nl_current_default_domain libintl_nl_current_default_domain
109 # define _nl_default_dirname libintl_nl_default_dirname
110 # define _nl_domain_bindings libintl_nl_domain_bindings
111 #endif
112
113 /* Some compilers, like SunOS4 cc, don't have offsetof in <stddef.h>.  */
114 #ifndef offsetof
115 # define offsetof(type,ident) ((size_t)&(((type*)0)->ident))
116 #endif
117
118 /* @@ end of prolog @@ */
119
120 #ifdef _LIBC
121 /* Rename the non ANSI C functions.  This is required by the standard
122    because some ANSI C functions will require linking with this object
123    file and the name space must not be polluted.  */
124 # define getcwd __getcwd
125 # ifndef stpcpy
126 #  define stpcpy __stpcpy
127 # endif
128 # define tfind __tfind
129 #else
130 # if !defined HAVE_GETCWD
131 char *getwd ();
132 #  define getcwd(buf, max) getwd (buf)
133 # else
134 char *getcwd ();
135 # endif
136 # ifndef HAVE_STPCPY
137 static char *stpcpy PARAMS ((char *dest, const char *src));
138 # endif
139 # ifndef HAVE_MEMPCPY
140 static void *mempcpy PARAMS ((void *dest, const void *src, size_t n));
141 # endif
142 #endif
143
144 /* Amount to increase buffer size by in each try.  */
145 #define PATH_INCR 32
146
147 /* The following is from pathmax.h.  */
148 /* Non-POSIX BSD systems might have gcc's limits.h, which doesn't define
149    PATH_MAX but might cause redefinition warnings when sys/param.h is
150    later included (as on MORE/BSD 4.3).  */
151 #if defined _POSIX_VERSION || (defined HAVE_LIMITS_H && !defined __GNUC__)
152 # include <limits.h>
153 #endif
154
155 #ifndef _POSIX_PATH_MAX
156 # define _POSIX_PATH_MAX 255
157 #endif
158
159 #if !defined PATH_MAX && defined _PC_PATH_MAX
160 # define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 : pathconf ("/", _PC_PATH_MAX))
161 #endif
162
163 /* Don't include sys/param.h if it already has been.  */
164 #if defined HAVE_SYS_PARAM_H && !defined PATH_MAX && !defined MAXPATHLEN
165 # include <sys/param.h>
166 #endif
167
168 #if !defined PATH_MAX && defined MAXPATHLEN
169 # define PATH_MAX MAXPATHLEN
170 #endif
171
172 #ifndef PATH_MAX
173 # define PATH_MAX _POSIX_PATH_MAX
174 #endif
175
176 /* Whether to support different locales in different threads.  */
177 #if defined _LIBC || HAVE_NL_LOCALE_NAME
178 # define HAVE_PER_THREAD_LOCALE
179 #endif
180
181 /* This is the type used for the search tree where known translations
182    are stored.  */
183 struct known_translation_t
184 {
185   /* Domain in which to search.  */
186   const char *domainname;
187
188   /* The category.  */
189   int category;
190
191 #ifdef HAVE_PER_THREAD_LOCALE
192   /* Name of the relevant locale category, or "" for the global locale.  */
193   const char *localename;
194 #endif
195
196   /* State of the catalog counter at the point the string was found.  */
197   int counter;
198
199   /* Catalog where the string was found.  */
200   struct loaded_l10nfile *domain;
201
202   /* And finally the translation.  */
203   const char *translation;
204   size_t translation_length;
205
206   /* Pointer to the string in question.  */
207   union
208     {
209       char appended[ZERO];  /* used if domain != NULL */
210       const char *ptr;      /* used if domain == NULL */
211     }
212   msgid;
213 };
214
215 /* Root of the search tree with known translations.  We can use this
216    only if the system provides the `tsearch' function family.  */
217 #if defined HAVE_TSEARCH || defined _LIBC
218 # include <search.h>
219
220 static void *root;
221
222 # ifdef _LIBC
223 #  define tsearch __tsearch
224 # endif
225
226 /* Function to compare two entries in the table of known translations.  */
227 static int transcmp PARAMS ((const void *p1, const void *p2));
228 static int
229 transcmp (p1, p2)
230      const void *p1;
231      const void *p2;
232 {
233   const struct known_translation_t *s1;
234   const struct known_translation_t *s2;
235   int result;
236
237   s1 = (const struct known_translation_t *) p1;
238   s2 = (const struct known_translation_t *) p2;
239
240   result = strcmp (s1->domain != NULL ? s1->msgid.appended : s1->msgid.ptr,
241                    s2->domain != NULL ? s2->msgid.appended : s2->msgid.ptr);
242   if (result == 0)
243     {
244       result = strcmp (s1->domainname, s2->domainname);
245       if (result == 0)
246         {
247 #ifdef HAVE_PER_THREAD_LOCALE
248           result = strcmp (s1->localename, s2->localename);
249           if (result == 0)
250 #endif
251             /* We compare the category last (though this is the cheapest
252                operation) since it is hopefully always the same (namely
253                LC_MESSAGES).  */
254             result = s1->category - s2->category;
255         }
256     }
257
258   return result;
259 }
260 #endif
261
262 /* Name of the default domain used for gettext(3) prior any call to
263    textdomain(3).  The default value for this is "messages".  */
264 const char _nl_default_default_domain[] attribute_hidden = "messages";
265
266 /* Value used as the default domain for gettext(3).  */
267 const char *_nl_current_default_domain attribute_hidden
268      = _nl_default_default_domain;
269
270 /* Contains the default location of the message catalogs.  */
271
272 #ifdef _LIBC
273 extern const char _nl_default_dirname[];
274 libc_hidden_proto (_nl_default_dirname)
275 #endif
276 const char _nl_default_dirname[] = LOCALEDIR;
277 #ifdef _LIBC
278 libc_hidden_data_def (_nl_default_dirname)
279 #endif
280
281 /* List with bindings of specific domains created by bindtextdomain()
282    calls.  */
283 struct binding *_nl_domain_bindings;
284
285 /* Prototypes for local functions.  */
286 static char *plural_lookup PARAMS ((struct loaded_l10nfile *domain,
287                                     unsigned long int n,
288                                     const char *translation,
289                                     size_t translation_len))
290      internal_function;
291 static const char *guess_category_value PARAMS ((int category,
292                                                  const char *categoryname))
293      internal_function;
294 #ifdef _LIBC
295 # include "../locale/localeinfo.h"
296 # define category_to_name(category) \
297   _nl_category_names.str + _nl_category_name_idxs[category]
298 #else
299 static const char *category_to_name PARAMS ((int category)) internal_function;
300 #endif
301
302
303 /* For those loosing systems which don't have `alloca' we have to add
304    some additional code emulating it.  */
305 #ifdef HAVE_ALLOCA
306 /* Nothing has to be done.  */
307 # define freea(p) /* nothing */
308 # define ADD_BLOCK(list, address) /* nothing */
309 # define FREE_BLOCKS(list) /* nothing */
310 #else
311 struct block_list
312 {
313   void *address;
314   struct block_list *next;
315 };
316 # define ADD_BLOCK(list, addr)                                                \
317   do {                                                                        \
318     struct block_list *newp = (struct block_list *) malloc (sizeof (*newp));  \
319     /* If we cannot get a free block we cannot add the new element to         \
320        the list.  */                                                          \
321     if (newp != NULL) {                                                       \
322       newp->address = (addr);                                                 \
323       newp->next = (list);                                                    \
324       (list) = newp;                                                          \
325     }                                                                         \
326   } while (0)
327 # define FREE_BLOCKS(list)                                                    \
328   do {                                                                        \
329     while (list != NULL) {                                                    \
330       struct block_list *old = list;                                          \
331       list = list->next;                                                      \
332       free (old->address);                                                    \
333       free (old);                                                             \
334     }                                                                         \
335   } while (0)
336 # undef alloca
337 # define alloca(size) (malloc (size))
338 # define freea(p) free (p)
339 #endif  /* have alloca */
340
341
342 #ifdef _LIBC
343 /* List of blocks allocated for translations.  */
344 typedef struct transmem_list
345 {
346   struct transmem_list *next;
347   char data[ZERO];
348 } transmem_block_t;
349 static struct transmem_list *transmem_list;
350 #else
351 typedef unsigned char transmem_block_t;
352 #endif
353 #if defined _LIBC || HAVE_ICONV
354 static const char *get_output_charset PARAMS ((struct binding *domainbinding))
355      internal_function;
356 #endif
357
358
359 /* Names for the libintl functions are a problem.  They must not clash
360    with existing names and they should follow ANSI C.  But this source
361    code is also used in GNU C Library where the names have a __
362    prefix.  So we have to make a difference here.  */
363 #ifdef _LIBC
364 # define DCIGETTEXT __dcigettext
365 #else
366 # define DCIGETTEXT libintl_dcigettext
367 #endif
368
369 /* Lock variable to protect the global data in the gettext implementation.  */
370 #ifdef _LIBC
371 __libc_rwlock_define_initialized (, _nl_state_lock attribute_hidden)
372 #endif
373
374 /* Checking whether the binaries runs SUID must be done and glibc provides
375    easier methods therefore we make a difference here.  */
376 #ifdef _LIBC
377 # define ENABLE_SECURE __libc_enable_secure
378 # define DETERMINE_SECURE
379 #else
380 # ifndef HAVE_GETUID
381 #  define getuid() 0
382 # endif
383 # ifndef HAVE_GETGID
384 #  define getgid() 0
385 # endif
386 # ifndef HAVE_GETEUID
387 #  define geteuid() getuid()
388 # endif
389 # ifndef HAVE_GETEGID
390 #  define getegid() getgid()
391 # endif
392 static int enable_secure;
393 # define ENABLE_SECURE (enable_secure == 1)
394 # define DETERMINE_SECURE \
395   if (enable_secure == 0)                                                     \
396     {                                                                         \
397       if (getuid () != geteuid () || getgid () != getegid ())                 \
398         enable_secure = 1;                                                    \
399       else                                                                    \
400         enable_secure = -1;                                                   \
401     }
402 #endif
403
404 /* Get the function to evaluate the plural expression.  */
405 #include "plural-eval.c"
406
407 /* Look up MSGID in the DOMAINNAME message catalog for the current
408    CATEGORY locale and, if PLURAL is nonzero, search over string
409    depending on the plural form determined by N.  */
410 char *
411 DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
412      const char *domainname;
413      const char *msgid1;
414      const char *msgid2;
415      int plural;
416      unsigned long int n;
417      int category;
418 {
419 #ifndef HAVE_ALLOCA
420   struct block_list *block_list = NULL;
421 #endif
422   struct loaded_l10nfile *domain;
423   struct binding *binding;
424   const char *categoryname;
425   const char *categoryvalue;
426   char *dirname, *xdomainname;
427   char *single_locale;
428   char *retval;
429   size_t retlen;
430   int saved_errno;
431 #if defined HAVE_TSEARCH || defined _LIBC
432   struct known_translation_t search;
433   struct known_translation_t **foundp = NULL;
434 # ifdef HAVE_PER_THREAD_LOCALE
435   const char *localename;
436 # endif
437 #endif
438   size_t domainname_len;
439
440   /* If no real MSGID is given return NULL.  */
441   if (msgid1 == NULL)
442     return NULL;
443
444 #ifdef _LIBC
445   if (category < 0 || category >= __LC_LAST || category == LC_ALL)
446     /* Bogus.  */
447     return (plural == 0
448             ? (char *) msgid1
449             /* Use the Germanic plural rule.  */
450             : n == 1 ? (char *) msgid1 : (char *) msgid2);
451 #endif
452
453 #ifdef _LIBC
454   __libc_rwlock_define (extern, __libc_setlocale_lock attribute_hidden)
455   __libc_rwlock_rdlock (__libc_setlocale_lock);
456 #endif
457
458   __libc_rwlock_rdlock (_nl_state_lock);
459
460   /* If DOMAINNAME is NULL, we are interested in the default domain.  If
461      CATEGORY is not LC_MESSAGES this might not make much sense but the
462      definition left this undefined.  */
463   if (domainname == NULL)
464     domainname = _nl_current_default_domain;
465
466 #if defined HAVE_TSEARCH || defined _LIBC
467   /* Try to find the translation among those which we found at
468      some time.  */
469   search.domain = NULL;
470   search.msgid.ptr = msgid1;
471   search.domainname = domainname;
472   search.category = category;
473 # ifdef HAVE_PER_THREAD_LOCALE
474 #  ifdef _LIBC
475   localename = strdupa (__current_locale_name (category));
476 #  endif
477   search.localename = localename;
478 # endif
479
480   /* Since tfind/tsearch manage a balanced tree, concurrent tfind and
481      tsearch calls can be fatal.  */
482   __libc_rwlock_define_initialized (static, tree_lock);
483   __libc_rwlock_rdlock (tree_lock);
484
485   foundp = (struct known_translation_t **) tfind (&search, &root, transcmp);
486
487   __libc_rwlock_unlock (tree_lock);
488
489   if (foundp != NULL && (*foundp)->counter == _nl_msg_cat_cntr)
490     {
491       /* Now deal with plural.  */
492       if (plural)
493         retval = plural_lookup ((*foundp)->domain, n, (*foundp)->translation,
494                                 (*foundp)->translation_length);
495       else
496         retval = (char *) (*foundp)->translation;
497
498 # ifdef _LIBC
499       __libc_rwlock_unlock (__libc_setlocale_lock);
500 # endif
501       __libc_rwlock_unlock (_nl_state_lock);
502       return retval;
503     }
504 #endif
505
506   /* Preserve the `errno' value.  */
507   saved_errno = errno;
508
509   /* See whether this is a SUID binary or not.  */
510   DETERMINE_SECURE;
511
512   /* First find matching binding.  */
513   for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
514     {
515       int compare = strcmp (domainname, binding->domainname);
516       if (compare == 0)
517         /* We found it!  */
518         break;
519       if (compare < 0)
520         {
521           /* It is not in the list.  */
522           binding = NULL;
523           break;
524         }
525     }
526
527   if (binding == NULL)
528     dirname = (char *) _nl_default_dirname;
529   else if (binding->dirname[0] == '/')
530     dirname = binding->dirname;
531   else
532     {
533       /* We have a relative path.  Make it absolute now.  */
534       size_t dirname_len = strlen (binding->dirname) + 1;
535       size_t path_max;
536       char *ret;
537
538       path_max = (unsigned int) PATH_MAX;
539       path_max += 2;            /* The getcwd docs say to do this.  */
540
541       for (;;)
542         {
543           dirname = (char *) alloca (path_max + dirname_len);
544           ADD_BLOCK (block_list, dirname);
545
546           __set_errno (0);
547           ret = getcwd (dirname, path_max);
548           if (ret != NULL || errno != ERANGE)
549             break;
550
551           path_max += path_max / 2;
552           path_max += PATH_INCR;
553         }
554
555       if (ret == NULL)
556         {
557           /* We cannot get the current working directory.  Don't signal an
558              error but simply return the default string.  */
559           FREE_BLOCKS (block_list);
560           __libc_rwlock_unlock (__libc_setlocale_lock);
561           __libc_rwlock_unlock (_nl_state_lock);
562           __set_errno (saved_errno);
563           return (plural == 0
564                   ? (char *) msgid1
565                   /* Use the Germanic plural rule.  */
566                   : n == 1 ? (char *) msgid1 : (char *) msgid2);
567         }
568
569       stpcpy (stpcpy (strchr (dirname, '\0'), "/"), binding->dirname);
570     }
571
572   /* Now determine the symbolic name of CATEGORY and its value.  */
573   categoryname = category_to_name (category);
574   categoryvalue = guess_category_value (category, categoryname);
575
576   domainname_len = strlen (domainname);
577   xdomainname = (char *) alloca (strlen (categoryname)
578                                  + domainname_len + 5);
579   ADD_BLOCK (block_list, xdomainname);
580
581   stpcpy (mempcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"),
582                   domainname, domainname_len),
583           ".mo");
584
585   /* Creating working area.  */
586   single_locale = (char *) alloca (strlen (categoryvalue) + 1);
587   ADD_BLOCK (block_list, single_locale);
588
589
590   /* Search for the given string.  This is a loop because we perhaps
591      got an ordered list of languages to consider for the translation.  */
592   while (1)
593     {
594       /* Make CATEGORYVALUE point to the next element of the list.  */
595       while (categoryvalue[0] != '\0' && categoryvalue[0] == ':')
596         ++categoryvalue;
597       if (categoryvalue[0] == '\0')
598         {
599           /* The whole contents of CATEGORYVALUE has been searched but
600              no valid entry has been found.  We solve this situation
601              by implicitly appending a "C" entry, i.e. no translation
602              will take place.  */
603           single_locale[0] = 'C';
604           single_locale[1] = '\0';
605         }
606       else
607         {
608           char *cp = single_locale;
609           while (categoryvalue[0] != '\0' && categoryvalue[0] != ':')
610             *cp++ = *categoryvalue++;
611           *cp = '\0';
612
613           /* When this is a SUID binary we must not allow accessing files
614              outside the dedicated directories.  */
615           if (ENABLE_SECURE && strchr (single_locale, '/') != NULL)
616             /* Ingore this entry.  */
617             continue;
618         }
619
620       /* If the current locale value is C (or POSIX) we don't load a
621          domain.  Return the MSGID.  */
622       if (strcmp (single_locale, "C") == 0
623           || strcmp (single_locale, "POSIX") == 0)
624         {
625         no_translation:
626           FREE_BLOCKS (block_list);
627           __libc_rwlock_unlock (__libc_setlocale_lock);
628           __libc_rwlock_unlock (_nl_state_lock);
629           __set_errno (saved_errno);
630           return (plural == 0
631                   ? (char *) msgid1
632                   /* Use the Germanic plural rule.  */
633                   : n == 1 ? (char *) msgid1 : (char *) msgid2);
634         }
635
636
637       /* Find structure describing the message catalog matching the
638          DOMAINNAME and CATEGORY.  */
639       domain = _nl_find_domain (dirname, single_locale, xdomainname, binding);
640
641       if (domain != NULL)
642         {
643           retval = _nl_find_msg (domain, binding, msgid1, 1, &retlen);
644
645           if (retval == NULL)
646             {
647               int cnt;
648
649               for (cnt = 0; domain->successor[cnt] != NULL; ++cnt)
650                 {
651                   retval = _nl_find_msg (domain->successor[cnt], binding,
652                                          msgid1, 1, &retlen);
653
654                   if (retval != NULL)
655                     {
656                       domain = domain->successor[cnt];
657                       break;
658                     }
659                 }
660             }
661
662           /* Returning -1 means that some resource problem exists
663              (likely memory) and that the strings could not be
664              converted.  Return the original strings.  */
665           if (__builtin_expect (retval == (char *) -1, 0))
666             goto no_translation;
667
668           if (retval != NULL)
669             {
670               /* Found the translation of MSGID1 in domain DOMAIN:
671                  starting at RETVAL, RETLEN bytes.  */
672               FREE_BLOCKS (block_list);
673 #if defined HAVE_TSEARCH || defined _LIBC
674               if (foundp == NULL)
675                 {
676                   /* Create a new entry and add it to the search tree.  */
677                   size_t msgid_len;
678                   size_t size;
679                   struct known_translation_t *newp;
680
681                   msgid_len = strlen (msgid1) + 1;
682                   size = offsetof (struct known_translation_t, msgid)
683                          + msgid_len + domainname_len + 1;
684 # ifdef HAVE_PER_THREAD_LOCALE
685                   size += strlen (localename) + 1;
686 # endif
687                   newp = (struct known_translation_t *) malloc (size);
688                   if (newp != NULL)
689                     {
690                       char *new_domainname;
691 # ifdef HAVE_PER_THREAD_LOCALE
692                       char *new_localename;
693 # endif
694
695                       new_domainname =
696                         mempcpy (newp->msgid.appended, msgid1, msgid_len);
697                       memcpy (new_domainname, domainname, domainname_len + 1);
698 # ifdef HAVE_PER_THREAD_LOCALE
699                       new_localename = new_domainname + domainname_len + 1;
700                       strcpy (new_localename, localename);
701 # endif
702                       newp->domainname = new_domainname;
703                       newp->category = category;
704 # ifdef HAVE_PER_THREAD_LOCALE
705                       newp->localename = new_localename;
706 # endif
707                       newp->counter = _nl_msg_cat_cntr;
708                       newp->domain = domain;
709                       newp->translation = retval;
710                       newp->translation_length = retlen;
711
712                       __libc_rwlock_wrlock (tree_lock);
713
714                       /* Insert the entry in the search tree.  */
715                       foundp = (struct known_translation_t **)
716                         tsearch (newp, &root, transcmp);
717
718                       __libc_rwlock_unlock (tree_lock);
719
720                       if (foundp == NULL
721                           || __builtin_expect (*foundp != newp, 0))
722                         /* The insert failed.  */
723                         free (newp);
724                     }
725                 }
726               else
727                 {
728                   /* We can update the existing entry.  */
729                   (*foundp)->counter = _nl_msg_cat_cntr;
730                   (*foundp)->domain = domain;
731                   (*foundp)->translation = retval;
732                   (*foundp)->translation_length = retlen;
733                 }
734 #endif
735               __set_errno (saved_errno);
736
737               /* Now deal with plural.  */
738               if (plural)
739                 retval = plural_lookup (domain, n, retval, retlen);
740
741               __libc_rwlock_unlock (__libc_setlocale_lock);
742               __libc_rwlock_unlock (_nl_state_lock);
743               return retval;
744             }
745         }
746     }
747   /* NOTREACHED */
748 }
749
750
751 char *
752 internal_function
753 _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
754      struct loaded_l10nfile *domain_file;
755      struct binding *domainbinding;
756      const char *msgid;
757      int convert;
758      size_t *lengthp;
759 {
760   struct loaded_domain *domain;
761   nls_uint32 nstrings;
762   size_t act;
763   char *result;
764   size_t resultlen;
765
766   if (domain_file->decided <= 0)
767     _nl_load_domain (domain_file, domainbinding);
768
769   if (domain_file->data == NULL)
770     return NULL;
771
772   domain = (struct loaded_domain *) domain_file->data;
773
774   nstrings = domain->nstrings;
775
776   /* Locate the MSGID and its translation.  */
777   if (domain->hash_tab != NULL)
778     {
779       /* Use the hashing table.  */
780       nls_uint32 len = strlen (msgid);
781       nls_uint32 hash_val = __hash_string (msgid);
782       nls_uint32 idx = hash_val % domain->hash_size;
783       nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2));
784
785       while (1)
786         {
787           nls_uint32 nstr =
788             W (domain->must_swap_hash_tab, domain->hash_tab[idx]);
789
790           if (nstr == 0)
791             /* Hash table entry is empty.  */
792             return NULL;
793
794           nstr--;
795
796           /* Compare msgid with the original string at index nstr.
797              We compare the lengths with >=, not ==, because plural entries
798              are represented by strings with an embedded NUL.  */
799           if (nstr < nstrings
800               ? W (domain->must_swap, domain->orig_tab[nstr].length) >= len
801                 && (strcmp (msgid,
802                             domain->data + W (domain->must_swap,
803                                               domain->orig_tab[nstr].offset))
804                     == 0)
805               : domain->orig_sysdep_tab[nstr - nstrings].length > len
806                 && (strcmp (msgid,
807                             domain->orig_sysdep_tab[nstr - nstrings].pointer)
808                     == 0))
809             {
810               act = nstr;
811               goto found;
812             }
813
814           if (idx >= domain->hash_size - incr)
815             idx -= domain->hash_size - incr;
816           else
817             idx += incr;
818         }
819       /* NOTREACHED */
820     }
821   else
822     {
823       /* Try the default method:  binary search in the sorted array of
824          messages.  */
825       size_t top, bottom;
826
827       bottom = 0;
828       top = nstrings;
829       while (bottom < top)
830         {
831           int cmp_val;
832
833           act = (bottom + top) / 2;
834           cmp_val = strcmp (msgid, (domain->data
835                                     + W (domain->must_swap,
836                                          domain->orig_tab[act].offset)));
837           if (cmp_val < 0)
838             top = act;
839           else if (cmp_val > 0)
840             bottom = act + 1;
841           else
842             goto found;
843         }
844       /* No translation was found.  */
845       return NULL;
846     }
847
848  found:
849   /* The translation was found at index ACT.  If we have to convert the
850      string to use a different character set, this is the time.  */
851   if (act < nstrings)
852     {
853       result = (char *)
854         (domain->data + W (domain->must_swap, domain->trans_tab[act].offset));
855       resultlen = W (domain->must_swap, domain->trans_tab[act].length) + 1;
856     }
857   else
858     {
859       result = (char *) domain->trans_sysdep_tab[act - nstrings].pointer;
860       resultlen = domain->trans_sysdep_tab[act - nstrings].length;
861     }
862
863 #if defined _LIBC || HAVE_ICONV
864   if (convert)
865     {
866       /* We are supposed to do a conversion.  */
867       const char *encoding = get_output_charset (domainbinding);
868
869       /* Protect against reallocation of the table.  */
870       __libc_rwlock_rdlock (domain->conversions_lock);
871
872       /* Search whether a table with converted translations for this
873          encoding has already been allocated.  */
874       size_t nconversions = domain->nconversions;
875       struct converted_domain *convd = NULL;
876       size_t i;
877
878       for (i = nconversions; i > 0; )
879         {
880           i--;
881           if (strcmp (domain->conversions[i].encoding, encoding) == 0)
882             {
883               convd = &domain->conversions[i];
884               break;
885             }
886         }
887
888       __libc_rwlock_unlock (domain->conversions_lock);
889
890       if (convd == NULL)
891         {
892           /* We have to allocate a new conversions table.  */
893           __libc_rwlock_wrlock (domain->conversions_lock);
894           nconversions = domain->nconversions;
895
896           /* Maybe in the meantime somebody added the translation.
897              Recheck.  */
898           for (i = nconversions; i > 0; )
899             {
900               i--;
901               if (strcmp (domain->conversions[i].encoding, encoding) == 0)
902                 {
903                   convd = &domain->conversions[i];
904                   goto found_convd;
905                 }
906             }
907
908           /* Allocate a table for the converted translations for this
909              encoding.  */
910           struct converted_domain *new_conversions =
911             (struct converted_domain *)
912             realloc (domain->conversions,
913                      (nconversions + 1) * sizeof (struct converted_domain));
914
915           if (__builtin_expect (new_conversions == NULL, 0))
916             {
917               /* Nothing we can do, no more memory.  We cannot use the
918                  translation because it might be encoded incorrectly.  */
919             unlock_fail:
920               __libc_rwlock_unlock (domain->conversions_lock);
921               return (char *) -1;
922             }
923
924           domain->conversions = new_conversions;
925
926           /* Copy the 'encoding' string to permanent storage.  */
927           encoding = strdup (encoding);
928           if (__builtin_expect (encoding == NULL, 0))
929             /* Nothing we can do, no more memory.  We cannot use the
930                translation because it might be encoded incorrectly.  */
931             goto unlock_fail;
932
933           convd = &new_conversions[nconversions];
934           convd->encoding = encoding;
935
936           /* Find out about the character set the file is encoded with.
937              This can be found (in textual form) in the entry "".  If this
938              entry does not exist or if this does not contain the 'charset='
939              information, we will assume the charset matches the one the
940              current locale and we don't have to perform any conversion.  */
941 # ifdef _LIBC
942           convd->conv = (__gconv_t) -1;
943 # else
944 #  if HAVE_ICONV
945           convd->conv = (iconv_t) -1;
946 #  endif
947 # endif
948           {
949             char *nullentry;
950             size_t nullentrylen;
951
952             /* Get the header entry.  This is a recursion, but it doesn't
953                reallocate domain->conversions because we pass convert = 0.  */
954             nullentry =
955               _nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen);
956
957             if (nullentry != NULL)
958               {
959                 const char *charsetstr;
960
961                 charsetstr = strstr (nullentry, "charset=");
962                 if (charsetstr != NULL)
963                   {
964                     size_t len;
965                     char *charset;
966                     const char *outcharset;
967
968                     charsetstr += strlen ("charset=");
969                     len = strcspn (charsetstr, " \t\n");
970
971                     charset = (char *) alloca (len + 1);
972 # if defined _LIBC || HAVE_MEMPCPY
973                     *((char *) mempcpy (charset, charsetstr, len)) = '\0';
974 # else
975                     memcpy (charset, charsetstr, len);
976                     charset[len] = '\0';
977 # endif
978
979                     outcharset = encoding;
980
981 # ifdef _LIBC
982                     /* We always want to use transliteration.  */
983                     outcharset = norm_add_slashes (outcharset, "TRANSLIT");
984                     charset = norm_add_slashes (charset, "");
985                     int r = __gconv_open (outcharset, charset, &convd->conv,
986                                           GCONV_AVOID_NOCONV);
987                     if (__builtin_expect (r != __GCONV_OK, 0))
988                       {
989                         /* If the output encoding is the same there is
990                            nothing to do.  Otherwise do not use the
991                            translation at all.  */
992                         if (__builtin_expect (r != __GCONV_NULCONV, 1))
993                           {
994                             __libc_rwlock_unlock (domain->conversions_lock);
995                             free ((char *) encoding);
996                             return NULL;
997                           }
998
999                         convd->conv = (__gconv_t) -1;
1000                       }
1001 # else
1002 #  if HAVE_ICONV
1003                     /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5,
1004                        we want to use transliteration.  */
1005 #   if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2 \
1006        || _LIBICONV_VERSION >= 0x0105
1007                     if (strchr (outcharset, '/') == NULL)
1008                       {
1009                         char *tmp;
1010
1011                         len = strlen (outcharset);
1012                         tmp = (char *) alloca (len + 10 + 1);
1013                         memcpy (tmp, outcharset, len);
1014                         memcpy (tmp + len, "//TRANSLIT", 10 + 1);
1015                         outcharset = tmp;
1016
1017                         convd->conv = iconv_open (outcharset, charset);
1018
1019                         freea (outcharset);
1020                       }
1021                     else
1022 #   endif
1023                       convd->conv = iconv_open (outcharset, charset);
1024 #  endif
1025 # endif
1026
1027                     freea (charset);
1028                   }
1029               }
1030           }
1031           convd->conv_tab = NULL;
1032           /* Here domain->conversions is still == new_conversions.  */
1033           domain->nconversions++;
1034
1035         found_convd:
1036           __libc_rwlock_unlock (domain->conversions_lock);
1037         }
1038
1039       if (
1040 # ifdef _LIBC
1041           convd->conv != (__gconv_t) -1
1042 # else
1043 #  if HAVE_ICONV
1044           convd->conv != (iconv_t) -1
1045 #  endif
1046 # endif
1047           )
1048         {
1049           __libc_lock_define_initialized (static, lock)
1050           /* We are supposed to do a conversion.  First allocate an
1051              appropriate table with the same structure as the table
1052              of translations in the file, where we can put the pointers
1053              to the converted strings in.
1054              There is a slight complication with plural entries.  They
1055              are represented by consecutive NUL terminated strings.  We
1056              handle this case by converting RESULTLEN bytes, including
1057              NULs.  */
1058
1059           if (__builtin_expect (convd->conv_tab == NULL, 0))
1060             {
1061               __libc_lock_lock (lock);
1062               if (convd->conv_tab == NULL)
1063                 {
1064                   convd->conv_tab
1065                     = calloc (nstrings + domain->n_sysdep_strings,
1066                               sizeof (char *));
1067                   if (convd->conv_tab != NULL)
1068                     goto not_translated_yet;
1069                   /* Mark that we didn't succeed allocating a table.  */
1070                   convd->conv_tab = (char **) -1;
1071                 }
1072               __libc_lock_unlock (lock);
1073             }
1074
1075           if (__builtin_expect (convd->conv_tab == (char **) -1, 0))
1076             /* Nothing we can do, no more memory.  We cannot use the
1077                translation because it might be encoded incorrectly.  */
1078             return (char *) -1;
1079
1080           if (convd->conv_tab[act] == NULL)
1081             {
1082               __libc_lock_lock (lock);
1083             not_translated_yet:;
1084
1085               /* We haven't used this string so far, so it is not
1086                  translated yet.  Do this now.  */
1087               /* We use a bit more efficient memory handling.
1088                  We allocate always larger blocks which get used over
1089                  time.  This is faster than many small allocations.   */
1090 # define INITIAL_BLOCK_SIZE     4080
1091               static unsigned char *freemem;
1092               static size_t freemem_size;
1093
1094               const unsigned char *inbuf;
1095               unsigned char *outbuf;
1096               int malloc_count;
1097 # ifndef _LIBC
1098               transmem_block_t *transmem_list = NULL;
1099 # endif
1100
1101               inbuf = (const unsigned char *) result;
1102               outbuf = freemem + sizeof (size_t);
1103
1104               malloc_count = 0;
1105               while (1)
1106                 {
1107                   transmem_block_t *newmem;
1108 # ifdef _LIBC
1109                   size_t non_reversible;
1110                   int res;
1111
1112                   if (freemem_size < sizeof (size_t))
1113                     goto resize_freemem;
1114
1115                   res = __gconv (convd->conv,
1116                                  &inbuf, inbuf + resultlen,
1117                                  &outbuf,
1118                                  outbuf + freemem_size - sizeof (size_t),
1119                                  &non_reversible);
1120
1121                   if (res == __GCONV_OK || res == __GCONV_EMPTY_INPUT)
1122                     break;
1123
1124                   if (res != __GCONV_FULL_OUTPUT)
1125                     {
1126                       /* We should not use the translation at all, it
1127                          is incorrectly encoded.  */
1128                       __libc_lock_unlock (lock);
1129                       return NULL;
1130                     }
1131
1132                   inbuf = (const unsigned char *) result;
1133 # else
1134 #  if HAVE_ICONV
1135                   const char *inptr = (const char *) inbuf;
1136                   size_t inleft = resultlen;
1137                   char *outptr = (char *) outbuf;
1138                   size_t outleft;
1139
1140                   if (freemem_size < sizeof (size_t))
1141                     goto resize_freemem;
1142
1143                   outleft = freemem_size - sizeof (size_t);
1144                   if (iconv (convd->conv,
1145                              (ICONV_CONST char **) &inptr, &inleft,
1146                              &outptr, &outleft)
1147                       != (size_t) (-1))
1148                     {
1149                       outbuf = (unsigned char *) outptr;
1150                       break;
1151                     }
1152                   if (errno != E2BIG)
1153                     {
1154                       __libc_lock_unlock (lock);
1155                       return NULL;
1156                     }
1157 #  endif
1158 # endif
1159
1160                 resize_freemem:
1161                   /* We must allocate a new buffer or resize the old one.  */
1162                   if (malloc_count > 0)
1163                     {
1164                       ++malloc_count;
1165                       freemem_size = malloc_count * INITIAL_BLOCK_SIZE;
1166                       newmem = (transmem_block_t *) realloc (transmem_list,
1167                                                              freemem_size);
1168 # ifdef _LIBC
1169                       if (newmem != NULL)
1170                         transmem_list = transmem_list->next;
1171                       else
1172                         {
1173                           struct transmem_list *old = transmem_list;
1174
1175                           transmem_list = transmem_list->next;
1176                           free (old);
1177                         }
1178 # endif
1179                     }
1180                   else
1181                     {
1182                       malloc_count = 1;
1183                       freemem_size = INITIAL_BLOCK_SIZE;
1184                       newmem = (transmem_block_t *) malloc (freemem_size);
1185                     }
1186                   if (__builtin_expect (newmem == NULL, 0))
1187                     {
1188                       freemem = NULL;
1189                       freemem_size = 0;
1190                       __libc_lock_unlock (lock);
1191                       return (char *) -1;
1192                     }
1193
1194 # ifdef _LIBC
1195                   /* Add the block to the list of blocks we have to free
1196                      at some point.  */
1197                   newmem->next = transmem_list;
1198                   transmem_list = newmem;
1199
1200                   freemem = (unsigned char *) newmem->data;
1201                   freemem_size -= offsetof (struct transmem_list, data);
1202 # else
1203                   transmem_list = newmem;
1204                   freemem = newmem;
1205 # endif
1206
1207                   outbuf = freemem + sizeof (size_t);
1208                 }
1209
1210               /* We have now in our buffer a converted string.  Put this
1211                  into the table of conversions.  */
1212               *(size_t *) freemem = outbuf - freemem - sizeof (size_t);
1213               convd->conv_tab[act] = (char *) freemem;
1214               /* Shrink freemem, but keep it aligned.  */
1215               freemem_size -= outbuf - freemem;
1216               freemem = outbuf;
1217               freemem += freemem_size & (alignof (size_t) - 1);
1218               freemem_size = freemem_size & ~ (alignof (size_t) - 1);
1219
1220               __libc_lock_unlock (lock);
1221             }
1222
1223           /* Now convd->conv_tab[act] contains the translation of all
1224              the plural variants.  */
1225           result = convd->conv_tab[act] + sizeof (size_t);
1226           resultlen = *(size_t *) convd->conv_tab[act];
1227         }
1228     }
1229
1230   /* The result string is converted.  */
1231
1232 #endif /* _LIBC || HAVE_ICONV */
1233
1234   *lengthp = resultlen;
1235   return result;
1236 }
1237
1238
1239 /* Look up a plural variant.  */
1240 static char *
1241 internal_function
1242 plural_lookup (domain, n, translation, translation_len)
1243      struct loaded_l10nfile *domain;
1244      unsigned long int n;
1245      const char *translation;
1246      size_t translation_len;
1247 {
1248   struct loaded_domain *domaindata = (struct loaded_domain *) domain->data;
1249   unsigned long int index;
1250   const char *p;
1251
1252   index = plural_eval (domaindata->plural, n);
1253   if (index >= domaindata->nplurals)
1254     /* This should never happen.  It means the plural expression and the
1255        given maximum value do not match.  */
1256     index = 0;
1257
1258   /* Skip INDEX strings at TRANSLATION.  */
1259   p = translation;
1260   while (index-- > 0)
1261     {
1262 #ifdef _LIBC
1263       p = __rawmemchr (p, '\0');
1264 #else
1265       p = strchr (p, '\0');
1266 #endif
1267       /* And skip over the NUL byte.  */
1268       p++;
1269
1270       if (p >= translation + translation_len)
1271         /* This should never happen.  It means the plural expression
1272            evaluated to a value larger than the number of variants
1273            available for MSGID1.  */
1274         return (char *) translation;
1275     }
1276   return (char *) p;
1277 }
1278
1279 #ifndef _LIBC
1280 /* Return string representation of locale CATEGORY.  */
1281 static const char *
1282 internal_function
1283 category_to_name (category)
1284      int category;
1285 {
1286   const char *retval;
1287
1288   switch (category)
1289   {
1290 #ifdef LC_COLLATE
1291   case LC_COLLATE:
1292     retval = "LC_COLLATE";
1293     break;
1294 #endif
1295 #ifdef LC_CTYPE
1296   case LC_CTYPE:
1297     retval = "LC_CTYPE";
1298     break;
1299 #endif
1300 #ifdef LC_MONETARY
1301   case LC_MONETARY:
1302     retval = "LC_MONETARY";
1303     break;
1304 #endif
1305 #ifdef LC_NUMERIC
1306   case LC_NUMERIC:
1307     retval = "LC_NUMERIC";
1308     break;
1309 #endif
1310 #ifdef LC_TIME
1311   case LC_TIME:
1312     retval = "LC_TIME";
1313     break;
1314 #endif
1315 #ifdef LC_MESSAGES
1316   case LC_MESSAGES:
1317     retval = "LC_MESSAGES";
1318     break;
1319 #endif
1320 #ifdef LC_RESPONSE
1321   case LC_RESPONSE:
1322     retval = "LC_RESPONSE";
1323     break;
1324 #endif
1325 #ifdef LC_ALL
1326   case LC_ALL:
1327     /* This might not make sense but is perhaps better than any other
1328        value.  */
1329     retval = "LC_ALL";
1330     break;
1331 #endif
1332   default:
1333     /* If you have a better idea for a default value let me know.  */
1334     retval = "LC_XXX";
1335   }
1336
1337   return retval;
1338 }
1339 #endif
1340
1341 /* Guess value of current locale from value of the environment variables.  */
1342 static const char *
1343 internal_function
1344 guess_category_value (category, categoryname)
1345      int category;
1346      const char *categoryname;
1347 {
1348   const char *language;
1349   const char *retval;
1350
1351   /* The highest priority value is the `LANGUAGE' environment
1352      variable.  But we don't use the value if the currently selected
1353      locale is the C locale.  This is a GNU extension.  */
1354   language = getenv ("LANGUAGE");
1355   if (language != NULL && language[0] == '\0')
1356     language = NULL;
1357
1358   /* We have to proceed with the POSIX methods of looking to `LC_ALL',
1359      `LC_xxx', and `LANG'.  On some systems this can be done by the
1360      `setlocale' function itself.  */
1361 #ifdef _LIBC
1362   retval = __current_locale_name (category);
1363 #else
1364   retval = _nl_locale_name (category, categoryname);
1365 #endif
1366
1367   return language != NULL && strcmp (retval, "C") != 0 ? language : retval;
1368 }
1369
1370 #if defined _LIBC || HAVE_ICONV
1371 /* Returns the output charset.  */
1372 static const char *
1373 internal_function
1374 get_output_charset (domainbinding)
1375      struct binding *domainbinding;
1376 {
1377   /* The output charset should normally be determined by the locale.  But
1378      sometimes the locale is not used or not correctly set up, so we provide
1379      a possibility for the user to override this: the OUTPUT_CHARSET
1380      environment variable.  Moreover, the value specified through
1381      bind_textdomain_codeset overrides both.  */
1382   if (domainbinding != NULL && domainbinding->codeset != NULL)
1383     return domainbinding->codeset;
1384   else
1385     {
1386       /* For speed reasons, we look at the value of OUTPUT_CHARSET only
1387          once.  This is a user variable that is not supposed to change
1388          during a program run.  */
1389       static char *output_charset_cache;
1390       static int output_charset_cached;
1391
1392       if (!output_charset_cached)
1393         {
1394           const char *value = getenv ("OUTPUT_CHARSET");
1395
1396           if (value != NULL && value[0] != '\0')
1397             {
1398               size_t len = strlen (value) + 1;
1399               char *value_copy = (char *) malloc (len);
1400
1401               if (value_copy != NULL)
1402                 memcpy (value_copy, value, len);
1403               output_charset_cache = value_copy;
1404             }
1405           output_charset_cached = 1;
1406         }
1407
1408       if (output_charset_cache != NULL)
1409         return output_charset_cache;
1410       else
1411         {
1412 # ifdef _LIBC
1413           return _NL_CURRENT (LC_CTYPE, CODESET);
1414 # else
1415 #  if HAVE_ICONV
1416           extern const char *locale_charset PARAMS ((void);
1417           return locale_charset ();
1418 #  endif
1419 # endif
1420         }
1421     }
1422 }
1423 #endif
1424
1425 /* @@ begin of epilog @@ */
1426
1427 /* We don't want libintl.a to depend on any other library.  So we
1428    avoid the non-standard function stpcpy.  In GNU C Library this
1429    function is available, though.  Also allow the symbol HAVE_STPCPY
1430    to be defined.  */
1431 #if !_LIBC && !HAVE_STPCPY
1432 static char *
1433 stpcpy (dest, src)
1434      char *dest;
1435      const char *src;
1436 {
1437   while ((*dest++ = *src++) != '\0')
1438     /* Do nothing. */ ;
1439   return dest - 1;
1440 }
1441 #endif
1442
1443 #if !_LIBC && !HAVE_MEMPCPY
1444 static void *
1445 mempcpy (dest, src, n)
1446      void *dest;
1447      const void *src;
1448      size_t n;
1449 {
1450   return (void *) ((char *) memcpy (dest, src, n) + n);
1451 }
1452 #endif
1453
1454
1455 #ifdef _LIBC
1456 /* If we want to free all resources we have to do some work at
1457    program's end.  */
1458 libc_freeres_fn (free_mem)
1459 {
1460   void *old;
1461
1462   while (_nl_domain_bindings != NULL)
1463     {
1464       struct binding *oldp = _nl_domain_bindings;
1465       _nl_domain_bindings = _nl_domain_bindings->next;
1466       if (oldp->dirname != _nl_default_dirname)
1467         /* Yes, this is a pointer comparison.  */
1468         free (oldp->dirname);
1469       free (oldp->codeset);
1470       free (oldp);
1471     }
1472
1473   if (_nl_current_default_domain != _nl_default_default_domain)
1474     /* Yes, again a pointer comparison.  */
1475     free ((char *) _nl_current_default_domain);
1476
1477   /* Remove the search tree with the known translations.  */
1478   __tdestroy (root, free);
1479   root = NULL;
1480
1481   while (transmem_list != NULL)
1482     {
1483       old = transmem_list;
1484       transmem_list = transmem_list->next;
1485       free (old);
1486     }
1487 }
1488 #endif