44#include "xbps_api_impl.h"
55vpkg_map_add(xbps_dictionary_t d,
const char *pkgname,
const char *vpkgver,
const char *provider)
57 xbps_dictionary_t providers;
60 providers = xbps_dictionary_get(d, pkgname);
62 providers = xbps_dictionary_create();
66 if (!xbps_dictionary_set(d, pkgname, providers)) {
67 xbps_object_release(providers);
73 if (!xbps_dictionary_set_cstring(providers, vpkgver, provider)) {
75 xbps_object_release(providers);
80 xbps_object_release(providers);
86store_virtualpkg(
struct xbps_handle *xhp,
const char *path,
size_t line,
char *val)
88 char namebuf[XBPS_NAME_SIZE];
89 char pkgverbuf[XBPS_NAME_SIZE +
sizeof(
"-99999_1")];
90 const char *vpkgname, *vpkgver, *provider;
100 if (p == NULL || p[1] ==
'\0') {
101 xbps_dbg_printf(
"%s: ignoring invalid "
102 "virtualpkg option at line %zu\n", path, line);
113 snprintf(pkgverbuf,
sizeof(pkgverbuf),
"%s-99999_1", vpkgname);
117 r = vpkg_map_add(xhp->vpkgd, vpkgname, vpkgver, provider);
120 r = vpkg_map_add(xhp->vpkgd_conf, vpkgname, vpkgver, provider);
123 xbps_dbg_printf(
"%s: added virtualpkg %s for %s\n", path, val, p);
128store_preserved_file(
struct xbps_handle *xhp,
const char *file)
131 char *p = NULL, *rfile = NULL;
135 if (xhp->preserved_files == NULL) {
136 xhp->preserved_files = xbps_array_create();
137 assert(xhp->preserved_files);
142 rv = glob(rfile, 0, NULL, &globbuf);
143 if (rv == GLOB_NOMATCH) {
146 xbps_array_add_cstring(xhp->preserved_files, file);
147 xbps_dbg_printf(
"Added preserved file: %s\n", file);
149 }
else if (rv != 0) {
152 for (
size_t i = 0; i < globbuf.gl_pathc; i++) {
156 len = strlen(globbuf.gl_pathv[i]) - strlen(xhp->
rootdir) + 1;
160 xbps_array_add_cstring(xhp->preserved_files, p);
161 xbps_dbg_printf(
"Added preserved file: %s (expanded from %s)\n", p, file);
170store_repo(
struct xbps_handle *xhp,
const char *repo)
172 if (xhp->
flags & XBPS_FLAG_IGNORE_CONF_REPOS)
179store_ignored_pkg(
struct xbps_handle *xhp,
const char *pkgname)
181 if (xhp->ignored_pkgs == NULL) {
182 xhp->ignored_pkgs = xbps_array_create();
183 assert(xhp->ignored_pkgs);
185 xbps_array_add_cstring(xhp->ignored_pkgs, pkgname);
186 xbps_dbg_printf(
"Added ignored package: %s\n", pkgname);
190store_noextract(
struct xbps_handle *xhp,
const char *value)
194 if (xhp->noextract == NULL) {
195 xhp->noextract = xbps_array_create();
196 assert(xhp->noextract);
198 xbps_array_add_cstring(xhp->noextract, value);
199 xbps_dbg_printf(
"Added noextract pattern: %s\n", value);
219static const struct key {
224 {
"architecture", 12, KEY_ARCHITECTURE },
225 {
"bestmatching", 12, KEY_BESTMATCHING },
226 {
"cachedir", 8, KEY_CACHEDIR },
227 {
"ignorepkg", 9, KEY_IGNOREPKG },
228 {
"include", 7, KEY_INCLUDE },
229 {
"keepconf", 8, KEY_KEEPCONF },
230 {
"noextract", 9, KEY_NOEXTRACT },
231 {
"preserve", 8, KEY_PRESERVE },
232 {
"repository", 10, KEY_REPOSITORY },
233 {
"rootdir", 7, KEY_ROOTDIR },
234 {
"staging", 7, KEY_STAGING },
235 {
"syslog", 6, KEY_SYSLOG },
236 {
"virtualpkg", 10, KEY_VIRTUALPKG },
240cmpkey(
const void *a,
const void *b)
242 const struct key *ka = a;
243 const struct key *kb = b;
244 return strncmp(ka->str, kb->str, ka->len);
248parse_option(
char *line,
size_t linelen,
char **valp,
size_t *vallen)
252 struct key needle, *result;
254 p = strpbrk(line,
" \t=");
260 while (*p && isblank((
unsigned char)*p))
265 result = bsearch(&needle, keys, __arraycount(keys),
sizeof(
struct key), cmpkey);
270 while (isblank((
unsigned char)*p))
273 len = linelen-(p-line);
277 while (len > 0 && isblank((
unsigned char)p[len-1]))
287static int parse_file(
struct xbps_handle *,
const char *,
bool);
290parse_files_glob(
struct xbps_handle *xhp, xbps_dictionary_t seen,
291 const char *cwd,
const char *pat,
bool nested)
293 char tmppath[PATH_MAX];
297 rs = snprintf(tmppath, PATH_MAX,
"%s/%s",
298 pat[0] ==
'/' ? xhp->
rootdir : cwd, pat);
299 if (rs < 0 || rs >= PATH_MAX)
302 switch (glob(tmppath, 0, NULL, &globbuf)) {
304 case GLOB_NOSPACE:
return ENOMEM;
305 case GLOB_NOMATCH:
return 0;
308 for (
size_t i = 0; i < globbuf.gl_pathc; i++) {
312 fname = basename(globbuf.gl_pathv[i]);
313 if (xbps_dictionary_get_bool(seen, fname, &mask) && mask)
315 xbps_dictionary_set_bool(seen, fname,
true);
317 if ((rv2 = parse_file(xhp, globbuf.gl_pathv[i], nested)) != 0)
326parse_file(
struct xbps_handle *xhp,
const char *path,
bool nested)
329 size_t len, nlines = 0;
336 if ((fp = fopen(path,
"r")) == NULL) {
338 xbps_error_printf(
"cannot read configuration file %s: %s\n", path, strerror(rv));
342 xbps_dbg_printf(
"Parsing configuration file: %s\n", path);
344 while ((rd = getline(&line, &len, fp)) != -1) {
348 if (line[rd-1] ==
'\n') {
356 while (isblank((
unsigned char)*line))
359 if (line[0] ==
'#' || line[0] ==
'\0')
362 switch (parse_option(line, rd, &val, &vallen)) {
364 xbps_dbg_printf(
"%s: ignoring invalid option at "
365 "line %zu\n", path, nlines);
369 rs = snprintf(xhp->
rootdir, size,
"%s", val);
370 if (rs < 0 || rs >= size) {
374 xbps_dbg_printf(
"%s: rootdir set to %s\n", path, val);
378 rs = snprintf(xhp->
cachedir, size,
"%s", val);
379 if (rs < 0 || rs >= size) {
383 xbps_dbg_printf(
"%s: cachedir set to %s\n", path, val);
385 case KEY_ARCHITECTURE:
388 if (rs < 0 || rs >= size) {
392 xbps_dbg_printf(
"%s: native architecture set to %s\n", path,
396 if (strcasecmp(val,
"true") == 0) {
397 xhp->
flags |= XBPS_FLAG_USE_STAGE;
398 xbps_dbg_printf(
"%s: repository stage enabled\n", path);
400 xhp->
flags &= ~XBPS_FLAG_USE_STAGE;
401 xbps_dbg_printf(
"%s: repository stage disabled\n", path);
405 if (strcasecmp(val,
"true") == 0) {
406 xhp->
flags &= ~XBPS_FLAG_DISABLE_SYSLOG;
407 xbps_dbg_printf(
"%s: syslog enabled\n", path);
409 xhp->
flags |= XBPS_FLAG_DISABLE_SYSLOG;
410 xbps_dbg_printf(
"%s: syslog disabled\n", path);
414 if (store_repo(xhp, val))
415 xbps_dbg_printf(
"%s: added repository %s\n", path, val);
418 rv = store_virtualpkg(xhp, path, nlines, val);
426 store_preserved_file(xhp, val);
429 if (strcasecmp(val,
"true") == 0) {
430 xhp->
flags |= XBPS_FLAG_KEEP_CONFIG;
431 xbps_dbg_printf(
"%s: config preservation enabled\n", path);
433 xhp->
flags &= ~XBPS_FLAG_KEEP_CONFIG;
434 xbps_dbg_printf(
"%s: config preservation disabled\n", path);
437 case KEY_BESTMATCHING:
438 if (strcasecmp(val,
"true") == 0) {
439 xhp->
flags |= XBPS_FLAG_BESTMATCH;
440 xbps_dbg_printf(
"%s: pkg best matching enabled\n", path);
442 xhp->
flags &= ~XBPS_FLAG_BESTMATCH;
443 xbps_dbg_printf(
"%s: pkg best matching disabled\n", path);
447 store_ignored_pkg(xhp, val);
450 store_noextract(xhp, val);
455 xbps_dbg_printf(
"%s: ignoring nested include\n", path);
459 rv = parse_files_glob(xhp, NULL, dirname(dir), val,
true);
473 xbps_dictionary_t seen;
477 seen = xbps_dictionary_create();
481 xbps_dbg_printf(
"Processing configuration directory: %s\n", xhp->
confdir);
482 if ((rv = parse_files_glob(xhp, seen, xhp->
confdir,
"*.conf",
false)))
485 if (*xhp->sysconfdir) {
486 xbps_dbg_printf(
"Processing system configuration directory: %s\n", xhp->sysconfdir);
487 if ((rv = parse_files_glob(xhp, seen, xhp->sysconfdir,
"*.conf",
false)))
492 xbps_object_release(seen);
char confdir[XBPS_MAXPATH]
char rootdir[XBPS_MAXPATH]
char cachedir[XBPS_MAXPATH]
Generic XBPS structure handler for initialization.
bool xbps_match_string_in_array(xbps_array_t array, const char *val)
bool xbps_repo_store(struct xbps_handle *xhp, const char *url)
char * xbps_xasprintf(const char *fmt,...) __attribute__((format(printf
bool xbps_pkg_name(char *dst, size_t len, const char *pkg)
size_t xbps_strlcpy(char *dst, const char *src, size_t dstsize)