(glibc.spec): Drop Makefile dep.
[glibc.git] / fedora / build-locale-archive.c
blobbc89863c144b51bb29e754171e536c4c9749b82f
1 #define _GNU_SOURCE
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <dirent.h>
5 #include <errno.h>
6 #include <string.h>
7 #include <stdbool.h>
8 #include <sys/stat.h>
9 #include <stdio.h>
10 #include <stdarg.h>
11 #include "../locale/hashval.h"
13 const char *alias_file = DATADIR "/locale/locale.alias";
14 const char *locar_file = PREFIX "/lib/locale/locale-archive";
15 const char *loc_path = PREFIX "/lib/locale/";
16 int be_quiet = 1;
17 int verbose = 0;
18 int max_locarchive_open_retry = 10;
19 const char *output_prefix;
21 static int
22 is_prime (unsigned long candidate)
24 /* No even number and none less than 10 will be passed here. */
25 unsigned long int divn = 3;
26 unsigned long int sq = divn * divn;
28 while (sq < candidate && candidate % divn != 0)
30 ++divn;
31 sq += 4 * divn;
32 ++divn;
35 return candidate % divn != 0;
38 unsigned long
39 next_prime (unsigned long seed)
41 /* Make it definitely odd. */
42 seed |= 1;
44 while (!is_prime (seed))
45 seed += 2;
47 return seed;
50 /* xmalloc is only used by show_archive_content. */
51 void *
52 xmalloc (size_t size)
54 exit (255);
57 void
58 error (int status, int errnum, const char *message, ...)
60 va_list args;
62 va_start (args, message);
63 fflush (stdout);
64 fprintf (stderr, "%s: ", program_invocation_name);
65 vfprintf (stderr, message, args);
66 va_end (args);
67 if (errnum)
68 fprintf (stderr, ": %s", strerror (errnum));
69 putc ('\n', stderr);
70 fflush (stderr);
71 if (status)
72 exit (errnum == EROFS ? 0 : status);
75 extern int add_locales_to_archive (size_t nlist, char *list[], bool replace);
77 int main ()
79 char path[4096];
80 DIR *dirp;
81 struct dirent64 *d;
82 struct stat64 st;
83 char *list[16384], *primary;
84 unsigned int cnt = 0;
86 unlink (locar_file);
87 dirp = opendir (loc_path);
88 if (dirp == NULL)
89 error (EXIT_FAILURE, errno, "cannot open directory \"%s\"", loc_path);
91 primary = getenv ("LC_ALL");
92 if (primary == NULL)
93 primary = getenv ("LANG");
94 if (primary != NULL)
96 if (strncmp (primary, "ja", 2) != 0
97 && strncmp (primary, "ko", 2) != 0
98 && strncmp (primary, "zh", 2) != 0)
100 char *ptr = malloc (strlen (primary) + strlen (".utf8") + 1), *p, *q;
102 if (ptr)
104 p = ptr;
105 q = primary;
106 while (*q && *q != '.' && *q != '@')
107 *p++ = *q++;
108 if (*q == '.')
109 while (*q && *q != '@')
110 q++;
111 p = stpcpy (p, ".utf8");
112 strcpy (p, q);
113 primary = ptr;
115 else
116 primary = ".....";
118 strcpy (stpcpy (path, loc_path), primary);
119 if (stat64 (path, &st) >= 0 && S_ISDIR (st.st_mode))
121 list[cnt] = strdup (path);
122 if (list[cnt] == NULL)
123 error (0, errno, "cannot add file to list \"%s\"", path);
124 else
125 cnt++;
127 if (cnt == 0)
128 primary = NULL;
131 while ((d = readdir64 (dirp)) != NULL)
133 if (strcmp (d->d_name, ".") == 0 || strcmp (d->d_name, "..") == 0)
134 continue;
136 if (primary && strcmp (d->d_name, primary) == 0)
137 continue;
139 strcpy (stpcpy (path, loc_path), d->d_name);
140 if (stat64 (path, &st) < 0)
142 error (0, errno, "cannot stat \"%s\"", path);
143 continue;
145 if (! S_ISDIR (st.st_mode))
146 continue;
147 if (cnt == 16384)
148 error (EXIT_FAILURE, 0, "too many directories in \"%s\"", loc_path);
149 list[cnt] = strdup (path);
150 if (list[cnt] == NULL)
152 error (0, errno, "cannot add file to list \"%s\"", path);
153 continue;
155 cnt++;
157 closedir (dirp);
158 add_locales_to_archive (cnt, list, 0);
159 exit (0);