|
|
bca718 |
The functions in locarchive.c cannot create files in non-default
|
|
|
bca718 |
locations. Rather than enhancing locarchive.c (and risk regressions
|
|
|
bca718 |
in localedef), this patch adapts build-locale-archive to use the
|
|
|
bca718 |
existing output_prefix configuration variable.
|
|
|
bca718 |
|
|
|
bca718 |
Index: glibc-2.17-c758a686/releng/build-locale-archive.c
|
|
|
bca718 |
===================================================================
|
|
|
bca718 |
--- glibc-2.17-c758a686.orig/releng/build-locale-archive.c
|
|
|
bca718 |
+++ glibc-2.17-c758a686/releng/build-locale-archive.c
|
|
|
bca718 |
@@ -92,23 +92,34 @@ xmalloc (size_t size)
|
|
|
bca718 |
return p;
|
|
|
bca718 |
}
|
|
|
bca718 |
|
|
|
bca718 |
+static char *
|
|
|
bca718 |
+xasprintf (const char *format, ...)
|
|
|
bca718 |
+{
|
|
|
bca718 |
+ va_list ap;
|
|
|
bca718 |
+ va_start (ap, format);
|
|
|
bca718 |
+ char *result;
|
|
|
bca718 |
+ if (vasprintf (&result, format, ap) < 0)
|
|
|
bca718 |
+ error (EXIT_FAILURE, errno, "could not format string");
|
|
|
bca718 |
+ va_end (ap);
|
|
|
bca718 |
+ return result;
|
|
|
bca718 |
+}
|
|
|
bca718 |
+
|
|
|
bca718 |
static void
|
|
|
bca718 |
open_tmpl_archive (struct locarhandle *ah)
|
|
|
bca718 |
{
|
|
|
bca718 |
struct stat64 st;
|
|
|
bca718 |
int fd;
|
|
|
bca718 |
struct locarhead head;
|
|
|
bca718 |
- const char *archivefname = ah->fname == NULL ? tmpl_file : ah->fname;
|
|
|
bca718 |
|
|
|
bca718 |
/* Open the archive. We must have exclusive write access. */
|
|
|
bca718 |
- fd = open64 (archivefname, O_RDONLY);
|
|
|
bca718 |
+ fd = open64 (tmpl_file, O_RDONLY);
|
|
|
bca718 |
if (fd == -1)
|
|
|
bca718 |
error (EXIT_FAILURE, errno, "cannot open locale archive template file \"%s\"",
|
|
|
bca718 |
- archivefname);
|
|
|
bca718 |
+ tmpl_file);
|
|
|
bca718 |
|
|
|
bca718 |
if (fstat64 (fd, &st) < 0)
|
|
|
bca718 |
error (EXIT_FAILURE, errno, "cannot stat locale archive template file \"%s\"",
|
|
|
bca718 |
- archivefname);
|
|
|
bca718 |
+ tmpl_file);
|
|
|
bca718 |
|
|
|
bca718 |
/* Read the header. */
|
|
|
bca718 |
if (TEMP_FAILURE_RETRY (read (fd, &head, sizeof (head))) != sizeof (head))
|
|
|
bca718 |
@@ -253,12 +264,11 @@ compute_data (struct locarhandle *ah, st
|
|
|
bca718 |
|
|
|
bca718 |
static int
|
|
|
bca718 |
fill_archive (struct locarhandle *tmpl_ah,
|
|
|
bca718 |
- const char *fname,
|
|
|
bca718 |
size_t install_langs_count, char *install_langs_list[],
|
|
|
bca718 |
size_t nlist, char *list[],
|
|
|
bca718 |
const char *primary)
|
|
|
bca718 |
{
|
|
|
bca718 |
- struct locarhandle ah;
|
|
|
bca718 |
+ struct locarhandle ah = {};
|
|
|
bca718 |
struct locarhead *head;
|
|
|
bca718 |
int result = 0;
|
|
|
bca718 |
struct nameent *names;
|
|
|
bca718 |
@@ -338,9 +348,6 @@ fill_archive (struct locarhandle *tmpl_a
|
|
|
bca718 |
|
|
|
bca718 |
/* Open the archive. This call never returns if we cannot
|
|
|
bca718 |
successfully open the archive. */
|
|
|
bca718 |
- ah.fname = NULL;
|
|
|
bca718 |
- if (fname != NULL)
|
|
|
bca718 |
- ah.fname = fname;
|
|
|
bca718 |
open_archive (&ah, false);
|
|
|
bca718 |
|
|
|
bca718 |
if (primary != NULL)
|
|
|
bca718 |
@@ -619,38 +626,39 @@ Usage: build-locale-archive [OPTION]...
|
|
|
bca718 |
\"de\" but also the aliases \"deutsch\"\n\
|
|
|
bca718 |
and and \"german\" although the latter does not\n\
|
|
|
bca718 |
start with \"de\".\n\
|
|
|
bca718 |
+ --prefix=DIR Operate under the file system root DIR\n\
|
|
|
bca718 |
\n\
|
|
|
bca718 |
- If the arguments TEMPLATE-FILE and ARCHIVE-FILE are not given the locations\n\
|
|
|
bca718 |
- where the glibc used expects these files are used by default.\n\
|
|
|
bca718 |
");
|
|
|
bca718 |
}
|
|
|
bca718 |
|
|
|
bca718 |
int main (int argc, char *argv[])
|
|
|
bca718 |
{
|
|
|
bca718 |
- char path[4096];
|
|
|
bca718 |
DIR *dirp;
|
|
|
bca718 |
struct dirent64 *d;
|
|
|
bca718 |
struct stat64 st;
|
|
|
bca718 |
char *list[16384], *primary;
|
|
|
bca718 |
char *lang;
|
|
|
bca718 |
int install_langs_count = 0;
|
|
|
bca718 |
- int i;
|
|
|
bca718 |
char *install_langs_arg, *ila_start;
|
|
|
bca718 |
char **install_langs_list;
|
|
|
bca718 |
unsigned int cnt = 0;
|
|
|
bca718 |
- struct locarhandle tmpl_ah;
|
|
|
bca718 |
- char *new_locar_fname = NULL;
|
|
|
bca718 |
- size_t loc_path_len = strlen (loc_path);
|
|
|
bca718 |
+ struct locarhandle tmpl_ah = {};
|
|
|
bca718 |
|
|
|
bca718 |
while (1)
|
|
|
bca718 |
{
|
|
|
bca718 |
int c;
|
|
|
bca718 |
|
|
|
bca718 |
+ enum
|
|
|
bca718 |
+ {
|
|
|
bca718 |
+ opt_prefix = 1000,
|
|
|
bca718 |
+ };
|
|
|
bca718 |
+
|
|
|
bca718 |
static struct option long_options[] =
|
|
|
bca718 |
{
|
|
|
bca718 |
{"help", no_argument, 0, 'h'},
|
|
|
bca718 |
{"verbose", no_argument, 0, 'v'},
|
|
|
bca718 |
{"install-langs", required_argument, 0, 'l'},
|
|
|
bca718 |
+ {"prefix", required_argument, 0, opt_prefix},
|
|
|
bca718 |
{0, 0, 0, 0}
|
|
|
bca718 |
};
|
|
|
bca718 |
/* getopt_long stores the option index here. */
|
|
|
bca718 |
@@ -721,6 +729,10 @@ int main (int argc, char *argv[])
|
|
|
bca718 |
}
|
|
|
bca718 |
break;
|
|
|
bca718 |
|
|
|
bca718 |
+ case opt_prefix:
|
|
|
bca718 |
+ output_prefix = optarg;
|
|
|
bca718 |
+ break;
|
|
|
bca718 |
+
|
|
|
bca718 |
case '?':
|
|
|
bca718 |
/* getopt_long already printed an error message. */
|
|
|
bca718 |
usage ();
|
|
|
bca718 |
@@ -730,23 +742,26 @@ int main (int argc, char *argv[])
|
|
|
bca718 |
abort ();
|
|
|
bca718 |
}
|
|
|
bca718 |
}
|
|
|
bca718 |
- tmpl_ah.fname = NULL;
|
|
|
bca718 |
- if (optind < argc)
|
|
|
bca718 |
- tmpl_ah.fname = argv[optind];
|
|
|
bca718 |
- if (optind + 1 < argc)
|
|
|
bca718 |
- new_locar_fname = argv[optind + 1];
|
|
|
bca718 |
+ if (optind != argc)
|
|
|
bca718 |
+ {
|
|
|
bca718 |
+ usage ();
|
|
|
bca718 |
+ exit (1);
|
|
|
bca718 |
+ }
|
|
|
bca718 |
+ if (output_prefix)
|
|
|
bca718 |
+ {
|
|
|
bca718 |
+ tmpl_file = xasprintf ("%s%s", output_prefix, tmpl_file);
|
|
|
bca718 |
+ alias_file = xasprintf ("%s%s", output_prefix, alias_file);
|
|
|
bca718 |
+ locar_file = xasprintf ("%s%s", output_prefix, locar_file);
|
|
|
bca718 |
+ loc_path = xasprintf ("%s%s", output_prefix, loc_path);
|
|
|
bca718 |
+ }
|
|
|
bca718 |
if (verbose)
|
|
|
bca718 |
{
|
|
|
bca718 |
- if (tmpl_ah.fname)
|
|
|
bca718 |
- printf("input archive file specified on command line: %s\n",
|
|
|
bca718 |
- tmpl_ah.fname);
|
|
|
bca718 |
- else
|
|
|
bca718 |
- printf("using default input archive file.\n");
|
|
|
bca718 |
- if (new_locar_fname)
|
|
|
bca718 |
- printf("output archive file specified on command line: %s\n",
|
|
|
bca718 |
- new_locar_fname);
|
|
|
bca718 |
- else
|
|
|
bca718 |
- printf("using default output archive file.\n");
|
|
|
bca718 |
+ if (output_prefix != NULL)
|
|
|
bca718 |
+ printf ("output prefix: %s\n", output_prefix);
|
|
|
bca718 |
+ printf ("input archive file: %s\n", tmpl_file);
|
|
|
bca718 |
+ printf ("input alias file: %s\n", alias_file);
|
|
|
bca718 |
+ printf ("input locale directory prefix: %s\n", loc_path);
|
|
|
bca718 |
+ printf ("output archive file: %s\n", locar_file);
|
|
|
bca718 |
}
|
|
|
bca718 |
|
|
|
bca718 |
dirp = opendir (loc_path);
|
|
|
bca718 |
@@ -754,11 +769,7 @@ int main (int argc, char *argv[])
|
|
|
bca718 |
error (EXIT_FAILURE, errno, "cannot open directory \"%s\"", loc_path);
|
|
|
bca718 |
|
|
|
bca718 |
open_tmpl_archive (&tmpl_ah);
|
|
|
bca718 |
-
|
|
|
bca718 |
- if (new_locar_fname)
|
|
|
bca718 |
- unlink (new_locar_fname);
|
|
|
bca718 |
- else
|
|
|
bca718 |
- unlink (locar_file);
|
|
|
bca718 |
+ unlink (locar_file);
|
|
|
bca718 |
|
|
|
bca718 |
primary = getenv ("LC_ALL");
|
|
|
bca718 |
if (primary == NULL)
|
|
|
bca718 |
@@ -790,8 +801,6 @@ int main (int argc, char *argv[])
|
|
|
bca718 |
}
|
|
|
bca718 |
}
|
|
|
bca718 |
|
|
|
bca718 |
- memcpy (path, loc_path, loc_path_len);
|
|
|
bca718 |
-
|
|
|
bca718 |
while ((d = readdir64 (dirp)) != NULL)
|
|
|
bca718 |
{
|
|
|
bca718 |
if (strcmp (d->d_name, ".") == 0 || strcmp (d->d_name, "..") == 0)
|
|
|
bca718 |
@@ -799,32 +808,25 @@ int main (int argc, char *argv[])
|
|
|
bca718 |
if (strchr (d->d_name, '_') == NULL)
|
|
|
bca718 |
continue;
|
|
|
bca718 |
|
|
|
bca718 |
- size_t d_name_len = strlen (d->d_name);
|
|
|
bca718 |
- if (loc_path_len + d_name_len + 1 > sizeof (path))
|
|
|
bca718 |
- {
|
|
|
bca718 |
- error (0, 0, "too long filename \"%s\"", d->d_name);
|
|
|
bca718 |
- continue;
|
|
|
bca718 |
- }
|
|
|
bca718 |
-
|
|
|
bca718 |
- memcpy (path + loc_path_len, d->d_name, d_name_len + 1);
|
|
|
bca718 |
+ char *path = xasprintf ("%s%s", loc_path, d->d_name);
|
|
|
bca718 |
if (stat64 (path, &st) < 0)
|
|
|
bca718 |
{
|
|
|
bca718 |
error (0, errno, "cannot stat \"%s\"", path);
|
|
|
bca718 |
+ free (path);
|
|
|
bca718 |
continue;
|
|
|
bca718 |
}
|
|
|
bca718 |
if (! S_ISDIR (st.st_mode))
|
|
|
bca718 |
- continue;
|
|
|
bca718 |
+ {
|
|
|
bca718 |
+ free (path);
|
|
|
bca718 |
+ continue;
|
|
|
bca718 |
+ }
|
|
|
bca718 |
if (cnt == 16384)
|
|
|
bca718 |
{
|
|
|
bca718 |
error (0, 0, "too many directories in \"%s\"", loc_path);
|
|
|
bca718 |
+ free (path);
|
|
|
bca718 |
break;
|
|
|
bca718 |
}
|
|
|
bca718 |
- list[cnt] = strdup (path);
|
|
|
bca718 |
- if (list[cnt] == NULL)
|
|
|
bca718 |
- {
|
|
|
bca718 |
- error (0, errno, "cannot add file to list \"%s\"", path);
|
|
|
bca718 |
- continue;
|
|
|
bca718 |
- }
|
|
|
bca718 |
+ list[cnt] = path;
|
|
|
bca718 |
if (primary != NULL && cnt > 0 && strcmp (primary, d->d_name) == 0)
|
|
|
bca718 |
{
|
|
|
bca718 |
char *p = list[0];
|
|
|
bca718 |
@@ -836,7 +838,7 @@ int main (int argc, char *argv[])
|
|
|
bca718 |
closedir (dirp);
|
|
|
bca718 |
/* Store the archive to the file specified as the second argument on the
|
|
|
bca718 |
command line or the default locale archive. */
|
|
|
bca718 |
- fill_archive (&tmpl_ah, new_locar_fname,
|
|
|
bca718 |
+ fill_archive (&tmpl_ah,
|
|
|
bca718 |
install_langs_count, install_langs_list,
|
|
|
bca718 |
cnt, list, primary);
|
|
|
bca718 |
close_archive (&tmpl_ah);
|