loadmsgcat.c
上传用户:xxcykj
上传日期:2007-01-04
资源大小:727k
文件大小:6k
源码类别:

Email客户端

开发平台:

Unix_Linux

  1. /* Load needed message catalogs.
  2.    Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
  3.    This program is free software; you can redistribute it and/or modify
  4.    it under the terms of the GNU General Public License as published by
  5.    the Free Software Foundation; either version 2, or (at your option)
  6.    any later version.
  7.    This program is distributed in the hope that it will be useful,
  8.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.    GNU General Public License for more details.
  11.    You should have received a copy of the GNU General Public License
  12.    along with this program; if not, write to the Free Software Foundation,
  13.    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
  14. #ifdef HAVE_CONFIG_H
  15. # include <config.h>
  16. #endif
  17. #include <fcntl.h>
  18. #include <sys/types.h>
  19. #include <sys/stat.h>
  20. #if defined STDC_HEADERS || defined _LIBC
  21. # include <stdlib.h>
  22. #endif
  23. #if defined HAVE_UNISTD_H || defined _LIBC
  24. # include <unistd.h>
  25. #endif
  26. #if (defined HAVE_MMAP && defined HAVE_MUNMAP) || defined _LIBC
  27. # include <sys/mman.h>
  28. #endif
  29. #include "gettext.h"
  30. #include "gettextP.h"
  31. /* @@ end of prolog @@ */
  32. #ifdef _LIBC
  33. /* Rename the non ISO C functions.  This is required by the standard
  34.    because some ISO C functions will require linking with this object
  35.    file and the name space must not be polluted.  */
  36. # define open   __open
  37. # define close  __close
  38. # define read   __read
  39. # define mmap   __mmap
  40. # define munmap __munmap
  41. #endif
  42. /* We need a sign, whether a new catalog was loaded, which can be associated
  43.    with all translations.  This is important if the translations are
  44.    cached by one of GCC's features.  */
  45. int _nl_msg_cat_cntr = 0;
  46. /* Load the message catalogs specified by FILENAME.  If it is no valid
  47.    message catalog do nothing.  */
  48. void
  49. internal_function
  50. _nl_load_domain (domain_file)
  51.      struct loaded_l10nfile *domain_file;
  52. {
  53.   int fd;
  54.   size_t size;
  55.   struct stat st;
  56.   struct mo_file_header *data = (struct mo_file_header *) -1;
  57. #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) 
  58.     || defined _LIBC
  59.   int use_mmap = 0;
  60. #endif
  61.   struct loaded_domain *domain;
  62.   domain_file->decided = 1;
  63.   domain_file->data = NULL;
  64.   /* If the record does not represent a valid locale the FILENAME
  65.      might be NULL.  This can happen when according to the given
  66.      specification the locale file name is different for XPG and CEN
  67.      syntax.  */
  68.   if (domain_file->filename == NULL)
  69.     return;
  70.   /* Try to open the addressed file.  */
  71.   fd = open (domain_file->filename, O_RDONLY);
  72.   if (fd == -1)
  73.     return;
  74.   /* We must know about the size of the file.  */
  75.   if (fstat (fd, &st) != 0
  76.       || (size = (size_t) st.st_size) != st.st_size
  77.       || size < sizeof (struct mo_file_header))
  78.     {
  79.       /* Something went wrong.  */
  80.       close (fd);
  81.       return;
  82.     }
  83. #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) 
  84.     || defined _LIBC
  85.   /* Now we are ready to load the file.  If mmap() is available we try
  86.      this first.  If not available or it failed we try to load it.  */
  87.   data = (struct mo_file_header *) mmap (NULL, size, PROT_READ,
  88.  MAP_PRIVATE, fd, 0);
  89.   if (data != (struct mo_file_header *) -1)
  90.     {
  91.       /* mmap() call was successful.  */
  92.       close (fd);
  93.       use_mmap = 1;
  94.     }
  95. #endif
  96.   /* If the data is not yet available (i.e. mmap'ed) we try to load
  97.      it manually.  */
  98.   if (data == (struct mo_file_header *) -1)
  99.     {
  100.       size_t to_read;
  101.       char *read_ptr;
  102.       data = (struct mo_file_header *) malloc (size);
  103.       if (data == NULL)
  104. return;
  105.       to_read = size;
  106.       read_ptr = (char *) data;
  107.       do
  108. {
  109.   long int nb = (long int) read (fd, read_ptr, to_read);
  110.   if (nb == -1)
  111.     {
  112.       close (fd);
  113.       return;
  114.     }
  115.   read_ptr += nb;
  116.   to_read -= nb;
  117. }
  118.       while (to_read > 0);
  119.       close (fd);
  120.     }
  121.   /* Using the magic number we can test whether it really is a message
  122.      catalog file.  */
  123.   if (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED)
  124.     {
  125.       /* The magic number is wrong: not a message catalog file.  */
  126. #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) 
  127.     || defined _LIBC
  128.       if (use_mmap)
  129. munmap ((caddr_t) data, size);
  130.       else
  131. #endif
  132. free (data);
  133.       return;
  134.     }
  135.   domain_file->data
  136.     = (struct loaded_domain *) malloc (sizeof (struct loaded_domain));
  137.   if (domain_file->data == NULL)
  138.     return;
  139.   domain = (struct loaded_domain *) domain_file->data;
  140.   domain->data = (char *) data;
  141. #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) 
  142.     || defined _LIBC
  143.   domain->use_mmap = use_mmap;
  144. #endif
  145.   domain->mmap_size = size;
  146.   domain->must_swap = data->magic != _MAGIC;
  147.   /* Fill in the information about the available tables.  */
  148.   switch (W (domain->must_swap, data->revision))
  149.     {
  150.     case 0:
  151.       domain->nstrings = W (domain->must_swap, data->nstrings);
  152.       domain->orig_tab = (struct string_desc *)
  153. ((char *) data + W (domain->must_swap, data->orig_tab_offset));
  154.       domain->trans_tab = (struct string_desc *)
  155. ((char *) data + W (domain->must_swap, data->trans_tab_offset));
  156.       domain->hash_size = W (domain->must_swap, data->hash_tab_size);
  157.       domain->hash_tab = (nls_uint32 *)
  158. ((char *) data + W (domain->must_swap, data->hash_tab_offset));
  159.       break;
  160.     default:
  161.       /* This is an illegal revision.  */
  162. #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) 
  163.     || defined _LIBC
  164.       if (use_mmap)
  165. munmap ((caddr_t) data, size);
  166.       else
  167. #endif
  168. free (data);
  169.       free (domain);
  170.       domain_file->data = NULL;
  171.       return;
  172.     }
  173.   /* Show that one domain is changed.  This might make some cached
  174.      translations invalid.  */
  175.   ++_nl_msg_cat_cntr;
  176. }
  177. #ifdef _LIBC
  178. void
  179. internal_function
  180. _nl_unload_domain (domain)
  181.      struct loaded_domain *domain;
  182. {
  183.   if (domain->use_mmap)
  184.     munmap ((caddr_t) domain->data, domain->mmap_size);
  185.   else
  186.     free ((void *) domain->data);
  187.   free (domain);
  188. }
  189. #endif