4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
38 static int validsubpath(const char *subpath)
41 if (subpath[i] == '/')
44 switch(subpath[i++]) {
48 if (subpath[i] == '/') {
52 if (subpath[i++] == '.') {
57 if (subpath[i++] == '/') {
63 while(subpath[i] && subpath[i] != '/')
73 struct wgt *wgt_create()
75 struct wgt *wgt = malloc(sizeof * wgt);
84 void wgt_disconnect(struct wgt *wgt)
92 void wgt_locales_reset(struct wgt *wgt)
96 free(wgt->locales[--wgt->nrlocales]);
99 void wgt_destroy(struct wgt *wgt)
103 wgt_locales_reset(wgt);
109 int wgt_connect(struct wgt *wgt, const char *pathname)
117 rfd = openat(rfd, pathname, O_PATH|O_DIRECTORY);
121 if (wgt->rootfd >= 0)
127 int wgt_is_connected(struct wgt *wgt)
130 return wgt->rootfd != -1;
133 int wgt_has(struct wgt *wgt, const char *filename)
136 assert(wgt_is_connected(wgt));
137 if (!validsubpath(filename)) {
141 return 0 == faccessat(wgt->rootfd, filename, F_OK, 0);
144 int wgt_open_read(struct wgt *wgt, const char *filename)
147 assert(wgt_is_connected(wgt));
148 if (!validsubpath(filename)) {
152 return openat(wgt->rootfd, filename, O_RDONLY);
155 static int locadd(struct wgt *wgt, const char *locstr, int length)
160 item = strndup(locstr, length);
162 for (i = 0 ; item[i] ; i++)
163 item[i] = tolower(item[i]);
164 for (i = 0 ; i < wgt->nrlocales ; i++)
165 if (!strcmp(item, wgt->locales[i])) {
170 ptr = realloc(wgt->locales, (1 + wgt->nrlocales) * sizeof(wgt->locales[0]));
173 wgt->locales[wgt->nrlocales++] = item;
182 int wgt_locales_add(struct wgt *wgt, const char *locstr)
184 const char *stop, *next;
187 stop = strchrnul(locstr, ',');
188 next = stop + !!*stop;
189 while (locstr != stop) {
190 if (locadd(wgt, locstr, stop - locstr))
192 do { stop--; } while(stop > locstr && *stop != '-');
199 int wgt_locales_score(struct wgt *wgt, const char *lang)
205 for (i = 0 ; i < wgt->nrlocales ; i++)
206 if (!strcasecmp(lang, wgt->locales[i]))
212 static const char *localize(struct wgt *wgt, const char *filename, char path[PATH_MAX])
216 if (!validsubpath(filename)) {
220 for (i = 0 ; i < wgt->nrlocales ; i++) {
221 if (snprintf(path, PATH_MAX, "locales/%s/%s", wgt->locales[i], filename) >= PATH_MAX) {
225 if (0 == faccessat(wgt->rootfd, path, F_OK, 0))
228 if (0 == faccessat(wgt->rootfd, filename, F_OK, 0))
234 char *wgt_locales_locate(struct wgt *wgt, const char *filename)
241 assert(wgt_is_connected(wgt));
242 loc = localize(wgt, filename, path);
246 result = strdup(loc);
254 int wgt_locales_open_read(struct wgt *wgt, const char *filename)
260 assert(wgt_is_connected(wgt));
261 loc = localize(wgt, filename, path);
265 return openat(wgt->rootfd, loc, O_RDONLY);