diff --git a/NEWS b/NEWS index 3c44e369..5b09654f 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,12 @@ xbps-0.37 (???): + * Added support for system and configuration repository directories, as + explained in GH #39 (https://github.com/voidlinux/xbps/issues/39). + + The system repository directory set to /share/xbps/repo.d contains + system repository configuration files (.conf) that can be overrided by the admin + in /xbps/repo.d bearing the same file name. + * xbps-create(8): new option `-t, --tags` to specify a list of tags (categories) the package should be part of. This is just for metadata purposes and querying packages by tags in the future. diff --git a/include/Makefile b/include/Makefile index 4b953bc5..99adb27b 100644 --- a/include/Makefile +++ b/include/Makefile @@ -4,7 +4,7 @@ INCS = xbps.h .PHONY: all all: - sed -e "s|@@VERSION@@|${VERSION}|g" ${INCS}.in > ${INCS} + sed -e "s|@@VERSION@@|${VERSION}|g;s|@@PREFIX@@|${PREFIX}|g" ${INCS}.in > ${INCS} .PHONY: install install: diff --git a/include/xbps.h.in b/include/xbps.h.in index 7a85e041..f4bd8aec 100644 --- a/include/xbps.h.in +++ b/include/xbps.h.in @@ -48,7 +48,7 @@ * * This header documents the full API for the XBPS Library. */ -#define XBPS_API_VERSION "20140420" +#define XBPS_API_VERSION "20140530" #ifndef XBPS_VERSION #define XBPS_VERSION "UNSET" @@ -70,7 +70,10 @@ */ #define XBPS_SYSDIR "/xbps" #ifndef XBPS_SYSCONF_PATH -#define XBPS_SYSCONF_PATH "/etc" XBPS_SYSDIR +# define XBPS_SYSCONF_PATH "/etc" XBPS_SYSDIR +#endif +#ifndef XBPS_SYSDEFCONF_PATH +# define XBPS_SYSDEFCONF_PATH "@@PREFIX@@/share" XBPS_SYSDIR #endif /** @@ -91,6 +94,18 @@ */ #define XBPS_VPKG_PATH XBPS_SYSCONF_PATH "/virtualpkg.d" +/** + * @def XBPS_REPOD_PATH + * Configuration directory to store repository configuration files. + */ +#define XBPS_REPOD_PATH XBPS_SYSCONF_PATH "/repo.d" + +/** + * @def XBPS_SYS_REPOD_PATH + * System directory to store repository configuration files. + */ +#define XBPS_SYS_REPOD_PATH XBPS_SYSDEFCONF_PATH "/repo.d" + /** * @def XBPS_PKGDB * Filename for the package database. diff --git a/lib/initend.c b/lib/initend.c index 283f01d9..72ca539e 100644 --- a/lib/initend.c +++ b/lib/initend.c @@ -283,7 +283,7 @@ parse_vpkgdir(struct xbps_handle *xhp) if ((dirp = opendir(xhp->virtualpkgdir)) == NULL) return 0; - xbps_dbg_printf(xhp, "Parsing virtualpkg directory: %s\n", xhp->virtualpkgdir); + xbps_dbg_printf(xhp, "Processing virtualpkg directory: %s\n", xhp->virtualpkgdir); while ((dp = readdir(dirp)) != NULL) { if ((strcmp(dp->d_name, "..") == 0) || @@ -307,6 +307,83 @@ parse_vpkgdir(struct xbps_handle *xhp) return rv; } +static int +parse_repodir(struct xbps_handle *xhp) +{ + DIR *dirp; + struct dirent *dp; + char *ext, conf[PATH_MAX]; + int rv = 0; + + /* + * Read all repository configuration files stored in the system + * repo.d directory. + */ + if ((dirp = opendir(XBPS_SYS_REPOD_PATH)) == NULL) + return 0; + + xbps_dbg_printf(xhp, "Processing system repo.d directory: %s\n", XBPS_SYS_REPOD_PATH); + + while ((dp = readdir(dirp)) != NULL) { + if ((strcmp(dp->d_name, "..") == 0) || + (strcmp(dp->d_name, ".") == 0)) + continue; + + /* only process .conf files, ignore something else */ + if ((ext = strrchr(dp->d_name, '.')) == NULL) + continue; + if (strcmp(ext, ".conf")) { + xbps_dbg_printf(xhp, "%s: ignoring %s\n", XBPS_SYS_REPOD_PATH, dp->d_name); + continue; + } + /* if the same file exists in configuration directory, ignore it */ + snprintf(conf, sizeof(conf), "%s/%s", XBPS_REPOD_PATH, dp->d_name); + if (access(conf, R_OK) == 0) { + xbps_dbg_printf(xhp, "%s: ignoring %s (exists in confdir)\n", XBPS_SYS_REPOD_PATH, dp->d_name); + continue; + } + /* parse repo conf file */ + snprintf(conf, sizeof(conf), "%s/%s", XBPS_SYS_REPOD_PATH, dp->d_name); + if ((rv = parse_file(xhp, conf, false, false)) != 0) { + break; + } + } + closedir(dirp); + if (rv != 0) + return rv; + + /* + * Read all repository configuration files stored in the configuration + * repo.d directory. + */ + if ((dirp = opendir(XBPS_REPOD_PATH)) == NULL) + return 0; + + xbps_dbg_printf(xhp, "Processing configuration repo.d directory: %s\n", XBPS_REPOD_PATH); + + while ((dp = readdir(dirp)) != NULL) { + if ((strcmp(dp->d_name, "..") == 0) || + (strcmp(dp->d_name, ".") == 0)) + continue; + + /* only process .conf files, ignore something else */ + if ((ext = strrchr(dp->d_name, '.')) == NULL) + continue; + if (strcmp(ext, ".conf")) { + xbps_dbg_printf(xhp, "%s: ignoring %s\n", XBPS_REPOD_PATH, dp->d_name); + continue; + } + /* parse repo conf file */ + snprintf(conf, sizeof(conf), "%s/%s", XBPS_REPOD_PATH, dp->d_name); + if ((rv = parse_file(xhp, conf, false, false)) != 0) { + break; + } + } + closedir(dirp); + + return rv; +} + int xbps_init(struct xbps_handle *xhp) { @@ -320,6 +397,10 @@ xbps_init(struct xbps_handle *xhp) if (xhp->conffile == NULL) xhp->conffile = XBPS_CONF_DEF; + /* parse repository configuration files */ + if ((rv = parse_repodir(xhp)) != 0) { + xbps_dbg_printf(xhp, "failed to parse repo.d files: %s\n", strerror(rv)); + } /* parse configuration file */ if ((rv = parse_file(xhp, xhp->conffile, false, false)) != 0) { xbps_dbg_printf(xhp, "failed to read configuration file %s: %s\n",