aboutsummaryrefslogtreecommitdiff
path: root/locale/programs
diff options
context:
space:
mode:
Diffstat (limited to 'locale/programs')
-rw-r--r--locale/programs/ld-address.c2
-rw-r--r--locale/programs/ld-collate.c4
-rw-r--r--locale/programs/ld-ctype.c3
-rw-r--r--locale/programs/ld-identification.c3
-rw-r--r--locale/programs/ld-measurement.c2
-rw-r--r--locale/programs/ld-messages.c2
-rw-r--r--locale/programs/ld-monetary.c2
-rw-r--r--locale/programs/ld-name.c2
-rw-r--r--locale/programs/ld-numeric.c2
-rw-r--r--locale/programs/ld-paper.c2
-rw-r--r--locale/programs/ld-telephone.c2
-rw-r--r--locale/programs/ld-time.c2
-rw-r--r--locale/programs/localedef.c95
-rw-r--r--locale/programs/localedef.h28
-rw-r--r--locale/programs/locarchive.c931
-rw-r--r--locale/programs/locfile.c61
-rw-r--r--locale/programs/locfile.h8
-rw-r--r--locale/programs/simple-hash.c30
-rw-r--r--locale/programs/simple-hash.h4
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);