diff --git a/NEWS b/NEWS index 10978c32..36a7fcab 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,20 @@ xbps-0.38 (???): + * Implemented support to preserve existent on-disk files, by always ignoring + the pkg content if the file has been matched. Details here: + https://github.com/voidlinux/xbps/issues/51 + + The new "preserve" keyword can be used in the xbps configuration file, as well + as for the system and configuration directories: + + - /usr/share/xbps/preserve.d + - /etc/xbps/preserve.d + + Full path to a file or globbing can be used: + + - preserve=/usr/bin/blah + - preserve=/etc/blah/*.conf + * Always preserve files that exist on disk, but are managed by a package. When such condition ocurrs install the pkg configuration file as `file.new-`. This fixes GH issue #50 https://github.com/voidlinux/xbps/issues/50. diff --git a/bin/xbps-checkvers/main.c b/bin/xbps-checkvers/main.c index 711378c4..cd99e0a5 100644 --- a/bin/xbps-checkvers/main.c +++ b/bin/xbps-checkvers/main.c @@ -208,7 +208,7 @@ rcv_init(rcv_t *rcv, const char *prog) rcv->have_vars = 0; rcv->ptr = rcv->input = NULL; if (rcv->xbps_conf != NULL) - rcv->xhp.conffile = rcv->xbps_conf; + strncpy(rcv->xhp.conffile, rcv->xbps_conf, sizeof(rcv->xhp.conffile)); if (rcv->rootdir != NULL) strncpy(rcv->xhp.rootdir, rcv->rootdir, sizeof(rcv->xhp.rootdir)); xbps_init(&rcv->xhp); diff --git a/bin/xbps-install/main.c b/bin/xbps-install/main.c index 463ca9df..b11fa272 100644 --- a/bin/xbps-install/main.c +++ b/bin/xbps-install/main.c @@ -190,7 +190,8 @@ main(int argc, char **argv) strncpy(xh.rootdir, rootdir, sizeof(xh.rootdir)); if (cachedir) strncpy(xh.cachedir, cachedir, sizeof(xh.cachedir)); - xh.conffile = conffile; + if (conffile) + strncpy(xh.conffile, conffile, sizeof(xh.conffile)); xh.flags = flags; if (flags & XBPS_FLAG_VERBOSE) xh.unpack_cb = unpack_progress_cb; diff --git a/bin/xbps-install/state_cb.c b/bin/xbps-install/state_cb.c index 78984938..5e63e766 100644 --- a/bin/xbps-install/state_cb.c +++ b/bin/xbps-install/state_cb.c @@ -136,6 +136,9 @@ state_cb(struct xbps_state_cb_data *xscd, void *cbdata _unused) case XBPS_STATE_SHOW_INSTALL_MSG: printf("%s: post-install message:\n%s", xscd->arg, xscd->desc); break; + case XBPS_STATE_UNPACK_FILE_PRESERVED: + printf("%s\n", xscd->desc); + break; /* errors */ case XBPS_STATE_UNPACK_FAIL: case XBPS_STATE_UPDATE_FAIL: diff --git a/bin/xbps-pkgdb/main.c b/bin/xbps-pkgdb/main.c index 0d72f8c9..e42232fa 100644 --- a/bin/xbps-pkgdb/main.c +++ b/bin/xbps-pkgdb/main.c @@ -137,7 +137,8 @@ main(int argc, char **argv) memset(&xh, 0, sizeof(xh)); if (rootdir) strncpy(xh.rootdir, rootdir, sizeof(xh.rootdir)); - xh.conffile = conffile; + if (conffile) + strncpy(xh.conffile, conffile, sizeof(xh.conffile)); xh.flags = flags; if ((rv = xbps_init(&xh)) != 0) { diff --git a/bin/xbps-query/main.c b/bin/xbps-query/main.c index 3d0c16a5..77c6e4e2 100644 --- a/bin/xbps-query/main.c +++ b/bin/xbps-query/main.c @@ -213,7 +213,9 @@ main(int argc, char **argv) strncpy(xh.rootdir, rootdir, sizeof(xh.rootdir)); if (cachedir) strncpy(xh.cachedir, cachedir, sizeof(xh.cachedir)); - xh.conffile = conffile; + if (conffile) + strncpy(xh.conffile, conffile, sizeof(xh.conffile)); + xh.flags = flags; if ((rv = xbps_init(&xh)) != 0) { diff --git a/bin/xbps-reconfigure/main.c b/bin/xbps-reconfigure/main.c index 300e7dbb..dcc944b7 100644 --- a/bin/xbps-reconfigure/main.c +++ b/bin/xbps-reconfigure/main.c @@ -147,7 +147,9 @@ main(int argc, char **argv) xh.state_cb = state_cb; if (rootdir) strncpy(xh.rootdir, rootdir, sizeof(xh.rootdir)); - xh.conffile = conffile; + if (conffile) + strncpy(xh.conffile, conffile, sizeof(xh.conffile)); + xh.flags = flags; if ((rv = xbps_init(&xh)) != 0) { diff --git a/bin/xbps-remove/main.c b/bin/xbps-remove/main.c index 918055fb..d5808f2d 100644 --- a/bin/xbps-remove/main.c +++ b/bin/xbps-remove/main.c @@ -251,7 +251,9 @@ main(int argc, char **argv) strncpy(xh.rootdir, rootdir, sizeof(xh.rootdir)); if (cachedir) strncpy(xh.cachedir, cachedir, sizeof(xh.cachedir)); - xh.conffile = conffile; + if (conffile) + strncpy(xh.conffile, conffile, sizeof(xh.conffile)); + xh.flags = flags; if ((rv = xbps_init(&xh)) != 0) { diff --git a/bin/xbps-uhelper/main.c b/bin/xbps-uhelper/main.c index bb13c6f7..2a32a8d5 100644 --- a/bin/xbps-uhelper/main.c +++ b/bin/xbps-uhelper/main.c @@ -87,14 +87,14 @@ main(int argc, char **argv) xbps_dictionary_t dict; struct xbps_handle xh; struct xferstat xfer; - const char *version, *rootdir = NULL, *confdir = NULL; + const char *version, *rootdir = NULL, *conffile = NULL; char *pkgname, *hash, *sep; int flags = 0, c, rv = 0; while ((c = getopt(argc, argv, "C:dr:V")) != -1) { switch (c) { case 'C': - confdir = optarg; + conffile = optarg; break; case 'r': /* To specify the root directory */ @@ -131,7 +131,8 @@ main(int argc, char **argv) xh.fetch_cb_data = &xfer; if (rootdir) strncpy(xh.rootdir, rootdir, sizeof(xh.rootdir)); - xh.conffile = confdir; + if (conffile) + strncpy(xh.conffile, conffile, sizeof(xh.conffile)); if ((rv = xbps_init(&xh)) != 0) { xbps_error_printf("xbps-uhelper: failed to " "initialize libxbps: %s.\n", strerror(rv)); diff --git a/include/xbps.h.in b/include/xbps.h.in index 07d36730..21912c88 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 "20140727" +#define XBPS_API_VERSION "20140801" #ifndef XBPS_VERSION #define XBPS_VERSION "UNSET" @@ -112,6 +112,18 @@ */ #define XBPS_SYS_REPOD_PATH XBPS_SYSDEFCONF_PATH "/repo.d" +/** + * @def XBPS_PRESERVED_PATH + * Configuration directory to store preserve configuration files. + */ +#define XBPS_PRESERVED_PATH XBPS_SYSCONF_PATH "/preserve.d" + +/** + * @def XBPS_SYS_PRESERVED_PATH + * System directory to store preserve configuration files. + */ +#define XBPS_SYS_PRESERVED_PATH XBPS_SYSDEFCONF_PATH "/preserve.d" + /** * @def XBPS_PKGDB * Filename for the package database. @@ -278,6 +290,7 @@ extern "C" { * - XBPS_STATE_INVALID_DEP: package has an invalid dependency. * - XBPS_STATE_SHOW_INSTALL_MSG: package must show a post-install message. * - XBPS_STATE_SHOW_REMOVE_MSG: package must show a pre-remove message. + * - XBPS_STATE_UNPACK_FILE_PRESERVED: package unpack preserved a file. */ typedef enum xbps_state { XBPS_STATE_UNKNOWN = 0, @@ -319,7 +332,8 @@ typedef enum xbps_state { XBPS_STATE_REPO_KEY_IMPORT, XBPS_STATE_INVALID_DEP, XBPS_STATE_SHOW_INSTALL_MSG, - XBPS_STATE_SHOW_REMOVE_MSG + XBPS_STATE_SHOW_REMOVE_MSG, + XBPS_STATE_UNPACK_FILE_PRESERVED } xbps_state_t; /** @@ -492,6 +506,7 @@ struct xbps_handle { /** * @private */ + xbps_array_t preserved_files; xbps_dictionary_t pkg_metad; xbps_dictionary_t pkgdb_revdeps; xbps_dictionary_t vpkgd; @@ -558,18 +573,18 @@ struct xbps_handle { * the \a xbps_fetch_cb function callback. */ void *fetch_cb_data; - /** - * @var conffile - * - * Full path to the xbps configuration file. - */ - const char *conffile; /** * @var target_arch * * Target architecture, as set by XBPS_TARGET_ARCH from environment. */ const char *target_arch; + /** + * @var conffile + * + * Full path to the xbps configuration file. + */ + char conffile[XBPS_MAXPATH-1]; /** * @var rootdir * diff --git a/lib/initend.c b/lib/initend.c index 19ffbbb7..ab97d9af 100644 --- a/lib/initend.c +++ b/lib/initend.c @@ -45,7 +45,7 @@ #pragma clang diagnostic ignored "-Wformat-nonliteral" #endif -static int parse_file(struct xbps_handle *, const char *, bool, bool); +static int parse_file(struct xbps_handle *, const char *, const char *, bool, bool); /** * @file lib/initend.c @@ -89,25 +89,58 @@ store_vpkg(struct xbps_handle *xhp, const char *path, size_t line, char *vpkg_s) xbps_dbg_printf(xhp, "%s: added vpkg %s for %s\n", path, vpkg, rpkg); } +static void +store_preserved_file(struct xbps_handle *xhp, const char *file) +{ + glob_t globbuf; + char *p = NULL, *rfile = NULL; + size_t len; + int rv = 0; + + if (xhp->preserved_files == NULL) { + xhp->preserved_files = xbps_array_create(); + assert(xhp->preserved_files); + } + + rfile = xbps_xasprintf("%s%s", xhp->rootdir, file); + + rv = glob(rfile, 0, NULL, &globbuf); + if (rv == GLOB_NOMATCH) { + if (xbps_match_string_in_array(xhp->preserved_files, file)) + goto out; + xbps_array_add_cstring(xhp->preserved_files, file); + xbps_dbg_printf(xhp, "Added preserved file: %s\n", file); + goto out; + } else if (rv != 0) { + goto out; + } + for (size_t i = 0; i < globbuf.gl_pathc; i++) { + if (xbps_match_string_in_array(xhp->preserved_files, globbuf.gl_pathv[i])) + continue; + + len = strlen(globbuf.gl_pathv[i]) - strlen(xhp->rootdir) + 1; + p = malloc(len); + assert(len); + strlcpy(p, globbuf.gl_pathv[i] + strlen(xhp->rootdir), len); + xbps_array_add_cstring(xhp->preserved_files, p); + xbps_dbg_printf(xhp, "Added preserved file: %s (expanded from %s)\n", p, file); + free(p); + } +out: + globfree(&globbuf); + if (rfile) + free(rfile); +} + static bool store_repo(struct xbps_handle *xhp, const char *repo) { - /* - * Append repositories to our proplib array. - */ if (xhp->repositories == NULL) xhp->repositories = xbps_array_create(); - /* - * Do not add duplicates. - */ - for (unsigned int i = 0; i < xbps_array_count(xhp->repositories); i++) { - const char *srepo; + if (xbps_match_string_in_array(xhp->repositories, repo)) + return false; - xbps_array_get_cstring_nocopy(xhp->repositories, i, &srepo); - if (strcmp(repo, srepo) == 0) - return false; - } xbps_array_add_cstring(xhp->repositories, repo); return true; } @@ -123,7 +156,8 @@ parse_option(char *buf, char **k, char **v) "syslog", "repository", "virtualpkg", - "include" + "include", + "preserve" }; bool found = false; @@ -158,14 +192,14 @@ parse_option(char *buf, char **k, char **v) } static int -parse_files_glob(struct xbps_handle *xhp, const char *path, bool nested, bool vpkgconf) +parse_files_glob(struct xbps_handle *xhp, const char *cwd, const char *path, bool nested, bool vpkgconf) { glob_t globbuf; - int i, rv = 0; + int rv = 0; glob(path, 0, NULL, &globbuf); - for (i = 0; globbuf.gl_pathv; i++) { - if ((rv = parse_file(xhp, globbuf.gl_pathv[i], nested, vpkgconf)) != 0) + for (size_t i = 0; i < globbuf.gl_pathc; i++) { + if ((rv = parse_file(xhp, cwd, globbuf.gl_pathv[i], nested, vpkgconf)) != 0) break; } globfree(&globbuf); @@ -174,14 +208,13 @@ parse_files_glob(struct xbps_handle *xhp, const char *path, bool nested, bool vp } static int -parse_file(struct xbps_handle *xhp, const char *path, bool nested, bool vpkgconf) +parse_file(struct xbps_handle *xhp, const char *cwd, const char *path, bool nested, bool vpkgconf) { FILE *fp; + char tmppath[XBPS_MAXPATH] = {0}; size_t len, nlines = 0; ssize_t read; - char *line = NULL; - char ocwd[XBPS_MAXPATH] = { 0 }, tmppath[XBPS_MAXPATH] = { 0 }; - char *cwd; + char *cfcwd, *line = NULL; int rv = 0; if ((fp = fopen(path, "r")) == NULL) { @@ -196,15 +229,10 @@ parse_file(struct xbps_handle *xhp, const char *path, bool nested, bool vpkgconf /* cwd to the dir containing the config file */ strlcpy(tmppath, path, sizeof(tmppath)); - cwd = dirname(tmppath); - if (getcwd(ocwd, sizeof(ocwd)) == NULL) { + cfcwd = dirname(tmppath); + if (chdir(cfcwd) == -1) { rv = errno; - xbps_dbg_printf(xhp, "cannot get cwd: %s\n", strerror(rv)); - return rv; - } - if (chdir(cwd)) { - rv = errno; - xbps_dbg_printf(xhp, "cannot chdir to %s: %s\n", cwd, strerror(rv)); + xbps_dbg_printf(xhp, "cannot chdir to %s: %s\n", cfcwd, strerror(rv)); return rv; } @@ -245,6 +273,8 @@ parse_file(struct xbps_handle *xhp, const char *path, bool nested, bool vpkgconf xbps_dbg_printf(xhp, "%s: added repository %s\n", path, v); } else if (strcmp(k, "virtualpkg") == 0) { store_vpkg(xhp, path, nlines, v); + } else if (strcmp(k, "preserve") == 0) { + store_preserved_file(xhp, v); } /* Avoid double-nested parsing, only allow it once */ if (nested) @@ -253,25 +283,18 @@ parse_file(struct xbps_handle *xhp, const char *path, bool nested, bool vpkgconf if (strcmp(k, "include")) continue; - if ((rv = parse_files_glob(xhp, v, true, false)) != 0) + if ((rv = parse_files_glob(xhp, cwd, v, true, false)) != 0) break; } free(line); fclose(fp); - /* Going back to old working directory */ - if (chdir(ocwd)) { - rv = errno; - xbps_dbg_printf(xhp, "cannot chdir to %s: %s\n", ocwd, strerror(rv)); - return rv; - } - return rv; } static int -parse_dir(struct xbps_handle *xhp, const char *dir, const char *confdir, bool vpkg) +parse_dir(struct xbps_handle *xhp, const char *cwd, const char *dir, const char *confdir, bool vpkg) { struct dirent **namelist; char *ext, ldir[PATH_MAX], conf[PATH_MAX]; @@ -313,7 +336,7 @@ parse_dir(struct xbps_handle *xhp, const char *dir, const char *confdir, bool vp } /* parse conf file */ snprintf(conf, sizeof(conf), "%s/%s", ldir, namelist[i]->d_name); - if ((rv = parse_file(xhp, conf, false, vpkg)) != 0) { + if ((rv = parse_file(xhp, cwd, conf, false, vpkg)) != 0) { free(namelist[i]); break; } @@ -351,7 +374,7 @@ stage2: } /* parse conf file */ snprintf(conf, sizeof(conf), "%s/%s", ldir, namelist[i]->d_name); - if ((rv = parse_file(xhp, conf, false, vpkg)) != 0) { + if ((rv = parse_file(xhp, cwd, conf, false, vpkg)) != 0) { free(namelist[i]); break; } @@ -365,37 +388,38 @@ int xbps_init(struct xbps_handle *xhp) { struct utsname un; - char *buf; + char cwd[PATH_MAX-1], *buf; const char *repodir, *native_arch; int rv; assert(xhp != NULL); - xbps_dbg_printf(xhp, "%s\n", XBPS_RELVER); + /* get cwd */ + if (getcwd(cwd, sizeof(cwd)) == NULL) + return ENOTSUP; - if (xhp->conffile == NULL) - xhp->conffile = XBPS_CONF_DEF; - - /* parse configuration file */ - if ((rv = parse_file(xhp, xhp->conffile, false, false)) != 0) { - xbps_dbg_printf(xhp, "Using built-in defaults\n"); + /* set conffile */ + if (xhp->conffile[0] == '\0') { + snprintf(xhp->conffile, sizeof(xhp->conffile), XBPS_CONF_DEF); + } else { + buf = strdup(xhp->conffile); + snprintf(xhp->conffile, sizeof(xhp->conffile), "%s/%s", cwd, buf); + free(buf); } /* Set rootdir */ if (xhp->rootdir[0] == '\0') { xhp->rootdir[0] = '/'; xhp->rootdir[1] = '\0'; } else if (xhp->rootdir[0] != '/') { - /* relative path */ - char path[PATH_MAX-1]; - - if (getcwd(path, sizeof(path)) == NULL) - return ENOTSUP; - buf = strdup(xhp->rootdir); - snprintf(xhp->rootdir, sizeof(xhp->rootdir), - "%s/%s", path, buf); + snprintf(xhp->rootdir, sizeof(xhp->rootdir), "%s/%s", cwd, buf); free(buf); } + /* parse configuration file */ + xbps_dbg_printf(xhp, "%s\n", XBPS_RELVER); + if ((rv = parse_file(xhp, cwd, xhp->conffile, false, false)) != 0) { + xbps_dbg_printf(xhp, "Using built-in defaults\n"); + } /* Set cachedir */ if (xhp->cachedir[0] == '\0') { snprintf(xhp->cachedir, sizeof(xhp->cachedir), @@ -421,11 +445,15 @@ xbps_init(struct xbps_handle *xhp) free(buf); } /* process virtualpkg.d dirs */ - if ((rv = parse_dir(xhp, XBPS_SYS_VPKG_PATH, XBPS_VPKG_PATH, true)) != 0) + if ((rv = parse_dir(xhp, cwd, XBPS_SYS_VPKG_PATH, XBPS_VPKG_PATH, true)) != 0) return rv; /* process repo.d dirs */ - if ((rv = parse_dir(xhp, XBPS_SYS_REPOD_PATH, XBPS_REPOD_PATH, false)) != 0) + if ((rv = parse_dir(xhp, cwd, XBPS_SYS_REPOD_PATH, XBPS_REPOD_PATH, false)) != 0) + return rv; + + /* process preserve.d dirs */ + if ((rv = parse_dir(xhp, cwd, XBPS_SYS_PRESERVED_PATH, XBPS_PRESERVED_PATH, false)) != 0) return rv; xhp->target_arch = getenv("XBPS_TARGET_ARCH"); @@ -452,6 +480,10 @@ xbps_init(struct xbps_handle *xhp) xbps_dbg_printf(xhp, "Repository[%u]=%s\n", i, repodir); } } + /* Going back to old working directory */ + if (chdir(cwd) == -1) + xbps_dbg_printf(xhp, "%s: cannot chdir to %s: %s\n", __func__, cwd, strerror(errno)); + return 0; } diff --git a/lib/package_unpack.c b/lib/package_unpack.c index 865adc61..d62250d1 100644 --- a/lib/package_unpack.c +++ b/lib/package_unpack.c @@ -151,6 +151,24 @@ create_pkg_metaplist(struct xbps_handle *xhp, const char *pkgname, const char *p return rv; } +static bool +match_preserved_file(struct xbps_handle *xhp, const char *entry) +{ + char *file; + + if (xhp->preserved_files == NULL) + return false; + + if (entry[0] == '.' && entry[1] != '\0') { + file = strchr(entry, '.') + 1; + assert(file); + } else { + file = __UNCONST(entry); + } + + return xbps_match_string_in_array(xhp->preserved_files, file); +} + static int unpack_archive(struct xbps_handle *xhp, xbps_dictionary_t pkg_repod, @@ -353,6 +371,17 @@ unpack_archive(struct xbps_handle *xhp, conf_file = skip_extract = file_exists = false; if (lstat(entry_pname, &st) == 0) file_exists = true; + /* + * Check if the file to be extracted must be preserved, if true, + * pass to the next file. + */ + if (file_exists && match_preserved_file(xhp, entry_pname)) { + archive_read_data_skip(ar); + xbps_dbg_printf(xhp, "[unpack] `%s' exists on disk and must be preserved, skipping.\n", xhp, entry_pname); + xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FILE_PRESERVED, 0, pkgver, + pkgver, "%s: file `%s' won't be extracted, it's preserved.\n", pkgver, entry_pname); + continue; + } /* * If file to be extracted does not match the file type of * file currently stored on disk, remove file on disk. diff --git a/tests/xbps/libxbps/common/Kyuafile b/tests/xbps/libxbps/common/Kyuafile index fdafd7c6..0729f169 100644 --- a/tests/xbps/libxbps/common/Kyuafile +++ b/tests/xbps/libxbps/common/Kyuafile @@ -21,6 +21,7 @@ atf_test_program{name="scripts_test"} atf_test_program{name="incorrect_deps_test"} atf_test_program{name="vpkg_test"} atf_test_program{name="install_test"} +atf_test_program{name="preserve_files_test"} include('config/Kyuafile') include('find_pkg_orphans/Kyuafile') diff --git a/tests/xbps/libxbps/config/main.c b/tests/xbps/libxbps/config/main.c index 57e52026..5112ad7b 100644 --- a/tests/xbps/libxbps/config/main.c +++ b/tests/xbps/libxbps/config/main.c @@ -36,7 +36,6 @@ ATF_TC_BODY(config_include_test, tc) { struct xbps_handle xh; const char *tcsdir; - char conffile[XBPS_MAXPATH-1]; /* get test source dir */ tcsdir = atf_tc_get_config_var(tc, "srcdir"); @@ -46,9 +45,7 @@ ATF_TC_BODY(config_include_test, tc) memset(&xh, 0, sizeof(xh)); strncpy(xh.rootdir, tcsdir, sizeof(xh.rootdir)); strncpy(xh.metadir, tcsdir, sizeof(xh.metadir)); - strncpy(conffile, tcsdir, sizeof(conffile)); - strncat(conffile, "/xbps.conf", sizeof(conffile)-1); - xh.conffile = conffile; + snprintf(xh.conffile, sizeof(xh.conffile), "%s/xbps.conf", tcsdir); xh.flags = XBPS_FLAG_DEBUG; ATF_REQUIRE_EQ(xbps_init(&xh), 0); @@ -67,7 +64,6 @@ ATF_TC_BODY(config_include_nomatch_test, tc) { struct xbps_handle xh; const char *tcsdir; - char conffile[XBPS_MAXPATH-1]; /* get test source dir */ tcsdir = atf_tc_get_config_var(tc, "srcdir"); @@ -77,9 +73,7 @@ ATF_TC_BODY(config_include_nomatch_test, tc) memset(&xh, 0, sizeof(xh)); strncpy(xh.rootdir, tcsdir, sizeof(xh.rootdir)); strncpy(xh.metadir, tcsdir, sizeof(xh.metadir)); - strncpy(conffile, tcsdir, sizeof(conffile)); - strncat(conffile, "/xbps_nomatch.conf", sizeof(conffile)-1); - xh.conffile = conffile; + strncpy(xh.conffile, "/xbps_nomatch.conf", sizeof(xh.conffile)); xh.flags = XBPS_FLAG_DEBUG; ATF_REQUIRE_EQ(xbps_init(&xh), 0); diff --git a/tests/xbps/libxbps/find_pkg_obsoletes/main.c b/tests/xbps/libxbps/find_pkg_obsoletes/main.c index f3d656ac..be15dc23 100644 --- a/tests/xbps/libxbps/find_pkg_obsoletes/main.c +++ b/tests/xbps/libxbps/find_pkg_obsoletes/main.c @@ -79,7 +79,7 @@ ATF_TC_BODY(find_pkg_obsoletes_test, tc) memset(&xh, 0, sizeof(xh)); strncpy(xh.rootdir, tcsdir, sizeof(xh.rootdir)); - xh.conffile = "/tmp/unexistent.conf"; + strncpy(xh.conffile, "/tmp/unexistent.conf", sizeof(xh.conffile)); ATF_REQUIRE_EQ(xbps_init(&xh), 0); d1 = create_dict("files", "/etc/foo.conf"); diff --git a/tests/xbps/libxbps/shell/Makefile b/tests/xbps/libxbps/shell/Makefile index a05cb08d..488a18d8 100644 --- a/tests/xbps/libxbps/shell/Makefile +++ b/tests/xbps/libxbps/shell/Makefile @@ -4,7 +4,7 @@ TOPDIR = ../../../.. TESTSHELL = conf_files_test issue6_test issue18_test issue20_test remove_test TESTSHELL+= replace_test installmode_test obsoletefiles_test TESTSHELL+= issue31_test scripts_test incorrect_deps_test -TESTSHELL+= vpkg_test install_test +TESTSHELL+= vpkg_test install_test preserve_files_test include ../Makefile.inc include $(TOPDIR)/mk/test.mk diff --git a/tests/xbps/libxbps/shell/preserve_files_test.sh b/tests/xbps/libxbps/shell/preserve_files_test.sh new file mode 100644 index 00000000..d2769258 --- /dev/null +++ b/tests/xbps/libxbps/shell/preserve_files_test.sh @@ -0,0 +1,83 @@ +#!/usr/bin/env atf-sh + +atf_test_case tc1 + +tc1_head() { + atf_set "descr" "Tests for pkg install/upgrade with preserved files: preserve on-disk files with globs" +} + +tc1_body() { + mkdir some_repo + mkdir -p pkg_A/usr/bin + echo "blahblah" > pkg_A/usr/bin/blah + echo "foofoo" > pkg_A/usr/bin/foo + cd some_repo + xbps-create -A noarch -n A-1.0_1 -s "A pkg" ../pkg_A + atf_check_equal $? 0 + xbps-rindex -a *.xbps + atf_check_equal $? 0 + cd .. + + mkdir -p root/usr/bin + echo "modified blahblah" > root/usr/bin/blah + echo "modified foofoo" > root/usr/bin/foo + + echo "preserve=/usr/bin/*" > foo.conf + + xbps-install -C foo.conf -r root --repository=$PWD/some_repo -yd A + atf_check_equal $? 0 + + rv=1 + if [ "$(cat root/usr/bin/blah)" = "modified blahblah" -a "$(cat root/usr/bin/foo)" = "modified foofoo" ]; then + rv=0 + fi + atf_check_equal $rv 0 +} + +atf_test_case tc2 + +tc2_head() { + atf_set "descr" "Tests for pkg install/upgrade with preserved files: preserve on-disk files without globs" +} + +tc2_body() { + mkdir some_repo + mkdir -p pkg_A/usr/bin + echo "blahblah" > pkg_A/usr/bin/blah + echo "foofoo" > pkg_A/usr/bin/foo + cd some_repo + xbps-create -A noarch -n A-1.0_1 -s "A pkg" ../pkg_A + atf_check_equal $? 0 + xbps-rindex -a *.xbps + atf_check_equal $? 0 + cd .. + + mkdir -p root/usr/bin + echo "modified blahblah" > root/usr/bin/blah + echo "modified foofoo" > root/usr/bin/foo + + printf "preserve=/usr/bin/blah\npreserve=/usr/bin/foo\n" > foo.conf + + echo "foo.conf" >&2 + cat foo.conf >&2 + + xbps-install -C foo.conf -r root --repository=$PWD/some_repo -yd A + atf_check_equal $? 0 + + rv=1 + if [ "$(cat root/usr/bin/blah)" = "modified blahblah" -a "$(cat root/usr/bin/foo)" = "modified foofoo" ]; then + rv=0 + fi + + echo "root/usr/bin/blah" >&2 + cat root/usr/bin/blah >&2 + echo "root/usr/bin/foo" >&2 + cat root/usr/bin/foo >&2 + + atf_check_equal $rv 0 +} + +atf_init_test_cases() { + atf_add_test_case tc1 + atf_add_test_case tc2 +} diff --git a/tests/xbps/libxbps/shell/scripts_test.sh b/tests/xbps/libxbps/shell/scripts_test.sh index f6c9d53f..41a86cdf 100644 --- a/tests/xbps/libxbps/shell/scripts_test.sh +++ b/tests/xbps/libxbps/shell/scripts_test.sh @@ -41,7 +41,7 @@ script_nargs_body() { rval=0 xbps-reconfigure -C empty.conf -r root -f A 2>out out="$(cat out)" - expected="post A 1.0_1 no empty.conf $(uname -m)" + expected="post A 1.0_1 no $(pwd)/empty.conf $(uname -m)" if [ "$out" != "$expected" ]; then echo "out: '$out'" echo "expected: '$expected'" @@ -75,7 +75,7 @@ script_arch_body() { rval=0 XBPS_ARCH=foo xbps-reconfigure -C empty.conf -r root -f A 2>out out="$(cat out)" - expected="post A 1.0_1 no empty.conf foo" + expected="post A 1.0_1 no $(pwd)/empty.conf foo" if [ "$out" != "$expected" ]; then echo "out: '$out'" echo "expected: '$expected'"