diff options
Diffstat (limited to 'locale/programs')
| -rw-r--r-- | locale/programs/ld-address.c | 2 | ||||
| -rw-r--r-- | locale/programs/ld-collate.c | 4 | ||||
| -rw-r--r-- | locale/programs/ld-ctype.c | 3 | ||||
| -rw-r--r-- | locale/programs/ld-identification.c | 3 | ||||
| -rw-r--r-- | locale/programs/ld-measurement.c | 2 | ||||
| -rw-r--r-- | locale/programs/ld-messages.c | 2 | ||||
| -rw-r--r-- | locale/programs/ld-monetary.c | 2 | ||||
| -rw-r--r-- | locale/programs/ld-name.c | 2 | ||||
| -rw-r--r-- | locale/programs/ld-numeric.c | 2 | ||||
| -rw-r--r-- | locale/programs/ld-paper.c | 2 | ||||
| -rw-r--r-- | locale/programs/ld-telephone.c | 2 | ||||
| -rw-r--r-- | locale/programs/ld-time.c | 2 | ||||
| -rw-r--r-- | locale/programs/localedef.c | 95 | ||||
| -rw-r--r-- | locale/programs/localedef.h | 28 | ||||
| -rw-r--r-- | locale/programs/locarchive.c | 931 | ||||
| -rw-r--r-- | locale/programs/locfile.c | 61 | ||||
| -rw-r--r-- | locale/programs/locfile.h | 8 | ||||
| -rw-r--r-- | locale/programs/simple-hash.c | 30 | ||||
| -rw-r--r-- | locale/programs/simple-hash.h | 4 |
19 files changed, 1125 insertions, 60 deletions
diff --git a/locale/programs/ld-address.c b/locale/programs/ld-address.c index 52b91cfc28..5c8efaa282 100644 --- a/locale/programs/ld-address.c +++ b/locale/programs/ld-address.c @@ -422,7 +422,7 @@ address_output (struct localedef_t *locale, const struct charmap_t *charmap, assert (cnt == 3 + _NL_ITEM_INDEX (_NL_NUM_LC_ADDRESS)); - write_locale_data (output_path, "LC_ADDRESS", + write_locale_data (output_path, LC_ADDRESS, "LC_ADDRESS", 3 + _NL_ITEM_INDEX (_NL_NUM_LC_ADDRESS), iov); } diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c index 191194799d..ca58266839 100644 --- a/locale/programs/ld-collate.c +++ b/locale/programs/ld-collate.c @@ -1987,7 +1987,7 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, assert (cnt == _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE)); - write_locale_data (output_path, "LC_COLLATE", 2 + cnt, iov); + write_locale_data (output_path, LC_COLLATE, "LC_COLLATE", 2 + cnt, iov); return; } @@ -2571,7 +2571,7 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, assert (cnt == _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE)); - write_locale_data (output_path, "LC_COLLATE", 2 + cnt, iov); + write_locale_data (output_path, LC_COLLATE, "LC_COLLATE", 2 + cnt, iov); obstack_free (&weightpool, NULL); obstack_free (&extrapool, NULL); diff --git a/locale/programs/ld-ctype.c b/locale/programs/ld-ctype.c index 1026133dc2..eed2e94732 100644 --- a/locale/programs/ld-ctype.c +++ b/locale/programs/ld-ctype.c @@ -1214,7 +1214,8 @@ ctype_output (struct localedef_t *locale, const struct charmap_t *charmap, assert (2 + elem + offset == (nelems + 2 * ctype->nr_charclass + ctype->map_collection_nr + 4 + 2)); - write_locale_data (output_path, "LC_CTYPE", 2 + elem + offset, iov); + write_locale_data (output_path, LC_CTYPE, "LC_CTYPE", 2 + elem + offset, + iov); } diff --git a/locale/programs/ld-identification.c b/locale/programs/ld-identification.c index 481e4e79c4..ae5ea6fb16 100644 --- a/locale/programs/ld-identification.c +++ b/locale/programs/ld-identification.c @@ -291,7 +291,8 @@ identification_output (struct localedef_t *locale, assert (cnt == (2 + _NL_ITEM_INDEX (_NL_NUM_LC_IDENTIFICATION) + (__LC_LAST - 2))); - write_locale_data (output_path, "LC_IDENTIFICATION", cnt, iov); + write_locale_data (output_path, LC_IDENTIFICATION, "LC_IDENTIFICATION", cnt, + iov); } diff --git a/locale/programs/ld-measurement.c b/locale/programs/ld-measurement.c index 75219bdf9f..2aa75b47dc 100644 --- a/locale/programs/ld-measurement.c +++ b/locale/programs/ld-measurement.c @@ -150,7 +150,7 @@ measurement_output (struct localedef_t *locale, assert (cnt == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_MEASUREMENT)); - write_locale_data (output_path, "LC_MEASUREMENT", + write_locale_data (output_path, LC_MEASUREMENT, "LC_MEASUREMENT", 2 + _NL_ITEM_INDEX (_NL_NUM_LC_MEASUREMENT), iov); } diff --git a/locale/programs/ld-messages.c b/locale/programs/ld-messages.c index fadf82757f..d5cc393e4b 100644 --- a/locale/programs/ld-messages.c +++ b/locale/programs/ld-messages.c @@ -226,7 +226,7 @@ messages_output (struct localedef_t *locale, const struct charmap_t *charmap, assert (cnt + 1 == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES)); - write_locale_data (output_path, "LC_MESSAGES", + write_locale_data (output_path, LC_MESSAGES, "LC_MESSAGES", 2 + _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES), iov); } diff --git a/locale/programs/ld-monetary.c b/locale/programs/ld-monetary.c index 4bb7c0bba4..4c36c505ba 100644 --- a/locale/programs/ld-monetary.c +++ b/locale/programs/ld-monetary.c @@ -612,7 +612,7 @@ monetary_output (struct localedef_t *locale, const struct charmap_t *charmap, assert (cnt == 3 + _NL_ITEM_INDEX (_NL_NUM_LC_MONETARY)); - write_locale_data (output_path, "LC_MONETARY", + write_locale_data (output_path, LC_MONETARY, "LC_MONETARY", 3 + _NL_ITEM_INDEX (_NL_NUM_LC_MONETARY), iov); } diff --git a/locale/programs/ld-name.c b/locale/programs/ld-name.c index 11e0ace7d6..80b42f7048 100644 --- a/locale/programs/ld-name.c +++ b/locale/programs/ld-name.c @@ -210,7 +210,7 @@ name_output (struct localedef_t *locale, const struct charmap_t *charmap, assert (cnt == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_NAME)); - write_locale_data (output_path, "LC_NAME", + write_locale_data (output_path, LC_NAME, "LC_NAME", 2 + _NL_ITEM_INDEX (_NL_NUM_LC_NAME), iov); } diff --git a/locale/programs/ld-numeric.c b/locale/programs/ld-numeric.c index 6e385f2be6..594c0c8c1b 100644 --- a/locale/programs/ld-numeric.c +++ b/locale/programs/ld-numeric.c @@ -187,7 +187,7 @@ numeric_output (struct localedef_t *locale, const struct charmap_t *charmap, assert (cnt + 1 == 3 + _NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC)); - write_locale_data (output_path, "LC_NUMERIC", + write_locale_data (output_path, LC_NUMERIC, "LC_NUMERIC", 3 + _NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC), iov); } diff --git a/locale/programs/ld-paper.c b/locale/programs/ld-paper.c index 2dce9ca8da..2910954f04 100644 --- a/locale/programs/ld-paper.c +++ b/locale/programs/ld-paper.c @@ -154,7 +154,7 @@ paper_output (struct localedef_t *locale, const struct charmap_t *charmap, assert (cnt == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_PAPER)); - write_locale_data (output_path, "LC_PAPER", + write_locale_data (output_path, LC_PAPER, "LC_PAPER", 2 + _NL_ITEM_INDEX (_NL_NUM_LC_PAPER), iov); } diff --git a/locale/programs/ld-telephone.c b/locale/programs/ld-telephone.c index 01dcf36008..5a60c016b0 100644 --- a/locale/programs/ld-telephone.c +++ b/locale/programs/ld-telephone.c @@ -218,7 +218,7 @@ telephone_output (struct localedef_t *locale, const struct charmap_t *charmap, assert (cnt == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_TELEPHONE)); - write_locale_data (output_path, "LC_TELEPHONE", + write_locale_data (output_path, LC_TELEPHONE, "LC_TELEPHONE", 2 + _NL_ITEM_INDEX (_NL_NUM_LC_TELEPHONE), iov); } diff --git a/locale/programs/ld-time.c b/locale/programs/ld-time.c index 32d9dad971..2ff56b0034 100644 --- a/locale/programs/ld-time.c +++ b/locale/programs/ld-time.c @@ -906,7 +906,7 @@ time_output (struct localedef_t *locale, const struct charmap_t *charmap, + 2 + time->num_era * 10 - 1)); assert (last_idx == _NL_ITEM_INDEX (_NL_NUM_LC_TIME)); - write_locale_data (output_path, "LC_TIME", 2 + cnt, iov); + write_locale_data (output_path, LC_TIME, "LC_TIME", 2 + cnt, iov); } diff --git a/locale/programs/localedef.c b/locale/programs/localedef.c index 3c159560e9..526f2025e7 100644 --- a/locale/programs/localedef.c +++ b/locale/programs/localedef.c @@ -27,6 +27,7 @@ #include <libintl.h> #include <locale.h> #include <mcheck.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -56,7 +57,8 @@ int verbose; /* If not zero suppress warnings and information messages. */ int be_quiet; -/* If not zero, produce old-style hash table instead of 3-level access tables. */ +/* If not zero, produce old-style hash table instead of 3-level access + tables. */ int oldstyle_tables; /* If not zero force output even if warning were issued. */ @@ -77,15 +79,38 @@ const char *repertoire_global; /* List of all locales. */ static struct localedef_t *locales; +/* If true don't add locale data to archive. */ +bool no_archive; + +/* If true add named locales to archive. */ +static bool add_to_archive; + +/* If true delete named locales from archive. */ +static bool delete_from_archive; + +/* If true replace archive content when adding. */ +static bool replace_archive; + +/* If true list archive content. */ +static bool list_archive; + +/* Maximum number of retries when opening the locale archive. */ +int max_locarchive_open_retry = 10; + /* Name and version of program. */ static void print_version (FILE *stream, struct argp_state *state); void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; -#define OPT_POSIX 1 -#define OPT_QUIET 2 -#define OPT_OLDSTYLE 3 -#define OPT_PREFIX 4 +#define OPT_POSIX 301 +#define OPT_QUIET 302 +#define OPT_OLDSTYLE 303 +#define OPT_PREFIX 304 +#define OPT_NO_ARCHIVE 305 +#define OPT_ADD_TO_ARCHIVE 306 +#define OPT_REPLACE 307 +#define OPT_DELETE_FROM_ARCHIVE 308 +#define OPT_LIST_ARCHIVE 309 /* Definitions of arguments for argp functions. */ static const struct argp_option options[] = @@ -106,6 +131,15 @@ static const struct argp_option options[] = { "quiet", OPT_QUIET, NULL, 0, N_("Suppress warnings and information messages") }, { "verbose", 'v', NULL, 0, N_("Print more messages") }, + { NULL, 0, NULL, 0, N_("Archive control:") }, + { "no-archive", OPT_NO_ARCHIVE, NULL, 0, + N_("Don't add new data to archive") }, + { "add-to-archive", OPT_ADD_TO_ARCHIVE, NULL, 0, + N_("Add locales named by parameters to archive") }, + { "replace", OPT_REPLACE, NULL, 0, N_("Replace existing archive content") }, + { "delete-from-archive", OPT_DELETE_FROM_ARCHIVE, NULL, 0, + N_("Remove locales named by parameters from archive") }, + { "list-archive", OPT_LIST_ARCHIVE, NULL, 0, N_("List content of archive") }, { NULL, 0, NULL, 0, NULL } }; @@ -113,7 +147,10 @@ static const struct argp_option options[] = static const char doc[] = N_("Compile locale specification"); /* Strings for arguments in help texts. */ -static const char args_doc[] = N_("NAME"); +static const char args_doc[] = N_("\ +NAME\n\ +[--add-to-archive|--delete-from-archive] FILE...\n\ +--list-archive [FILE]"); /* Prototype for option handler. */ static error_t parse_opt (int key, char *arg, struct argp_state *state); @@ -163,6 +200,15 @@ main (int argc, char *argv[]) argp_err_exit_status = 4; argp_parse (&argp, argc, argv, 0, &remaining, NULL); + /* Handle a few special cases. */ + if (list_archive) + show_archive_content (); + if (add_to_archive) + return add_locales_to_archive (argc - remaining, &argv[remaining], + replace_archive); + if (delete_from_archive) + return delete_locales_from_archive (argc - remaining, &argv[remaining]); + /* POSIX.2 requires to be verbose about missing characters in the character map. */ verbose |= posix_conformance; @@ -177,10 +223,18 @@ main (int argc, char *argv[]) /* The parameter describes the output path of the constructed files. If the described files cannot be written return a NULL pointer. */ - output_path = construct_output_path (argv[remaining]); - if (output_path == NULL) - error (4, errno, _("cannot create directory for output files")); - cannot_write_why = errno; + if (no_archive) + { + output_path = construct_output_path (argv[remaining]); + if (output_path == NULL) + error (4, errno, _("cannot create directory for output files")); + cannot_write_why = errno; + } + else + { + output_path = NULL; + cannot_write_why = 0; /* Just to shut the compiler up. */ + } /* Now that the parameters are processed we have to reset the local ctype locale. (P1003.2 4.35.5.2) */ @@ -235,7 +289,7 @@ cannot open locale definition file `%s'"), runp->name)); WITH_CUR_LOCALE (error (4, cannot_write_why, _("\ cannot write output files to `%s'"), output_path)); else - write_all_categories (locales, charmap, output_path); + write_all_categories (locales, charmap, argv[remaining], output_path); } else WITH_CUR_LOCALE (error (4, 0, _("\ @@ -264,6 +318,21 @@ parse_opt (int key, char *arg, struct argp_state *state) case OPT_PREFIX: output_prefix = arg; break; + case OPT_NO_ARCHIVE: + no_archive = true; + break; + case OPT_ADD_TO_ARCHIVE: + add_to_archive = true; + break; + case OPT_REPLACE: + replace_archive = true; + break; + case OPT_DELETE_FROM_ARCHIVE: + delete_from_archive = true; + break; + case OPT_LIST_ARCHIVE: + list_archive = true; + break; case 'c': force_output = 1; break; @@ -392,6 +461,10 @@ construct_output_path (char *path) size_t len = strlen (path) + 1; result = xmalloc (len + 1); endp = mempcpy (result, path, len) - 1; + + /* If the user specified an output path we cannot add the output + to the archive. */ + no_archive = true; } errno = 0; diff --git a/locale/programs/localedef.h b/locale/programs/localedef.h index 717962e10b..9567845080 100644 --- a/locale/programs/localedef.h +++ b/locale/programs/localedef.h @@ -1,5 +1,5 @@ /* General definitions for localedef(1). - Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. @@ -22,11 +22,13 @@ #define _LOCALEDEF_H 1 /* Get the basic locale definitions. */ +#include <errno.h> #include <locale.h> +#include <stdbool.h> #include <stddef.h> -#include <errno.h> #include "repertoire.h" +#include "../locarchive.h" /* We need a bitmask for the locales. */ @@ -114,6 +116,8 @@ extern int verbose; extern int be_quiet; extern int oldstyle_tables; extern const char *repertoire_global; +extern int max_locarchive_open_retry; +extern bool no_archive; /* Prototypes for a few program-wide used functions. */ @@ -153,4 +157,24 @@ extern struct localedef_t *load_locale (int locale, const char *name, const struct charmap_t *charmap, struct localedef_t *copy_locale); + +/* Open the locale archive. */ +extern void open_archive (struct locarhandle *ah); + +/* Close the locale archive. */ +extern void close_archive (struct locarhandle *ah); + +/* Add given locale data to the archive. */ +extern int add_locale_to_archive (struct locarhandle *ah, const char *name, + locale_data_t data, bool replace); + +/* Add content of named directories to locale archive. */ +extern int add_locales_to_archive (size_t nlist, char *list[], bool replace); + +/* Removed named locales from archive. */ +extern int delete_locales_from_archive (size_t nlist, char *list[]); + +/* List content of locale archive. */ +extern void show_archive_content (void); + #endif /* localedef.h */ diff --git a/locale/programs/locarchive.c b/locale/programs/locarchive.c new file mode 100644 index 0000000000..861dd5bd68 --- /dev/null +++ b/locale/programs/locarchive.c @@ -0,0 +1,931 @@ +/* Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <dirent.h> +#include <errno.h> +#include <error.h> +#include <fcntl.h> +#include <inttypes.h> +#include <libintl.h> +#include <locale.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/param.h> +#include <sys/stat.h> + +#include "../../crypt/md5.h" +#include "../localeinfo.h" +#include "../locarchive.h" +#include "simple-hash.h" +#include "localedef.h" + + +static const char archivefname[] = LOCALEDIR "/locale-archive"; + +static const char *locnames[] = + { +#define DEFINE_CATEGORY(category, category_name, items, a) \ + [category] = category_name, +#include "categories.def" +#undef DEFINE_CATEGORY + }; + + +/* Size of the initial archive header. */ +#define INITIAL_NUM_NANES 450 +#define INITIAL_SIZE_STRINGS 3500 +#define INITIAL_NUM_LOCREC 350 +#define INITIAL_NUM_SUMS 2000 + + +static void +create_archive (struct locarhandle *ah) +{ + int fd; + char fname[] = LOCALEDIR "/locale-archive.XXXXXX"; + struct locarhead head; + void *p; + size_t total; + + /* Create a temporary file in the correct directory. */ + fd = mkstemp (fname); + if (fd == -1) + error (EXIT_FAILURE, errno, _("cannot create temporary file")); + + /* Create the initial content of the archive. */ + head.magic = AR_MAGIC; + head.namehash_offset = sizeof (struct locarhead); + head.namehash_used = 0; + head.namehash_size = next_prime (INITIAL_NUM_NANES); + + head.string_offset = (head.namehash_offset + + head.namehash_size * sizeof (struct namehashent)); + head.string_used = 0; + head.string_size = INITIAL_SIZE_STRINGS; + + head.locrectab_offset = head.string_offset + head.string_size; + head.locrectab_used = 0; + head.locrectab_size = INITIAL_NUM_LOCREC; + + head.sumhash_offset = (head.locrectab_offset + + head.locrectab_size * sizeof (struct locrecent)); + head.sumhash_used = 0; + head.sumhash_size = next_prime (INITIAL_NUM_SUMS); + + total = head.sumhash_offset + head.sumhash_size * sizeof (struct sumhashent); + + /* Write out the header and create room for the other data structures. */ + if (TEMP_FAILURE_RETRY (write (fd, &head, sizeof (head))) != sizeof (head)) + { + int errval = errno; + unlink (fname); + error (EXIT_FAILURE, errval, _("cannot initialize archive file")); + } + + if (ftruncate64 (fd, total) != 0) + { + int errval = errno; + unlink (fname); + error (EXIT_FAILURE, errval, _("cannot resize archive file")); + } + + /* Map the header and all the administration data structures. */ + p = mmap64 (NULL, total, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (p == MAP_FAILED) + { + int errval = errno; + unlink (fname); + error (EXIT_FAILURE, errval, _("cannot map archive header")); + } + + /* Now try to rename it. We don't use the rename function since + this would overwrite a file which has been created in + parallel. */ + if (link (fname, archivefname) == -1) + { + int errval = errno; + + /* We cannot use the just created file. */ + close (fd); + unlink (fname); |
