Annotation of embedaddon/lrzsz/intl/loadmsgcat.c, revision 1.1.1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>