diff --git a/Makefile.in b/Makefile.in index 790d3d6..f72c50e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -6,7 +6,7 @@ VERSION= @PACKAGE_VERSION@ SRCS= main.c summary.c tools.c pkgindb.c depends.c actions.c \ pkglist.c download.c order.c impact.c autoremove.c fsops.c \ pkgindb_queries.c pkg_str.c sqlite_callbacks.c selection.c \ - pkg_check.c pkg_infos.c preferred.c + pkg_check.c pkg_infos.c pkg_install.c preferred.c # included from libinstall SRCS+= automatic.c dewey.c fexec.c global.c opattern.c pkgdb.c var.c SRCS+= xwrapper.c @@ -36,7 +36,6 @@ LOCALBASE?= @prefix@ BINDIR?= ${LOCALBASE}/bin PKG_SYSCONFDIR?= ${LOCALBASE}/etc VARBASE?= /var -PKG_DBDIR?= ${VARBASE}/db/pkg .if !defined(PKGMANDIR) MANDIR= ${LOCALBASE}/share/man .endif @@ -78,8 +77,6 @@ CPPFLAGS+= -g CPPFLAGS+= -DLOCALBASE=\"${LOCALBASE}\" \ -DPKG_SYSCONFDIR=\"${PKG_SYSCONFDIR}\" \ - -DPKG_DBDIR="\"${PKG_DBDIR}\"" \ - -DDEF_LOG_DIR="\"${PKG_DBDIR}\"" \ -DPKGIN_DBDIR=\"${PKGIN_DBDIR}\" \ -DPKGTOOLS=\"${PKGTOOLS}\" diff --git a/actions.c b/actions.c index e967320..71446c9 100644 --- a/actions.c +++ b/actions.c @@ -250,7 +250,7 @@ do_pkg_remove(Plisthead *removehead) #ifndef DEBUG if (!verbosity) log_tag(MSG_REMOVING, premove->depend); - if (fexec(PKG_DELETE, verb_flag("-f"), premove->depend, NULL) + if (fexec(pkg_delete, verb_flag("-f"), premove->depend, NULL) != EXIT_SUCCESS) err_count++; #endif @@ -299,7 +299,7 @@ do_pkg_install(Plisthead *installhead) /* there was a previous version, record +PRESERVE path */ if (pinstall->old != NULL) snprintf(preserve, BUFSIZ, "%s/%s/%s", - PKG_DBDIR, pinstall->old, PRESERVE_FNAME); + pkgdb_get_dir(), pinstall->old, PRESERVE_FNAME); /* are we upgrading pkg_install ? */ if (pi_upgrade) { /* set in order.c */ @@ -320,7 +320,7 @@ do_pkg_install(Plisthead *installhead) /* every other package */ pflags = verb_flag("-D"); - if (fexec(PKG_ADD, pflags, pkgpath, NULL) == EXIT_FAILURE) + if (fexec(pkg_add, pflags, pkgpath, NULL) == EXIT_FAILURE) rc = EXIT_FAILURE; #endif } /* installation loop */ diff --git a/autoremove.c b/autoremove.c index 401784d..aa04d56 100644 --- a/autoremove.c +++ b/autoremove.c @@ -84,7 +84,7 @@ pkgin_autoremove() } } snprintf(preserve, BUFSIZ, "%s/%s/%s", - PKG_DBDIR, pkglist->full, PRESERVE_FNAME); + pkgdb_get_dir(), pkglist->full, PRESERVE_FNAME); /* is or a dependency or a preserved package */ if (is_keep_dep || access(preserve, F_OK) != -1) continue; diff --git a/external/lib.h b/external/lib.h index c6d3889..009e3e2 100644 --- a/external/lib.h +++ b/external/lib.h @@ -422,18 +422,8 @@ void append_plist(package_t *, FILE *); int delete_package(Boolean, Boolean, package_t *, Boolean); /* Package Database */ -int pkgdb_open(int); -void pkgdb_close(void); -int pkgdb_store(const char *, const char *); -char *pkgdb_retrieve(const char *); -int pkgdb_dump(void); -int pkgdb_remove(const char *); -int pkgdb_remove_pkg(const char *); -char *pkgdb_refcount_dir(void); -char *_pkgdb_getPKGDB_FILE(char *, unsigned); -const char *_pkgdb_getPKGDB_DIR(void); -void _pkgdb_setPKGDB_DIR(const char *); - +const char *pkgdb_get_dir(void); +void pkgdb_set_dir(const char *, int); char *pkgdb_pkg_file(const char *, const char *); /* List of packages functions */ diff --git a/external/pkgdb.c b/external/pkgdb.c index a687555..8a5a671 100644 --- a/external/pkgdb.c +++ b/external/pkgdb.c @@ -1,20 +1,7 @@ -/* $NetBSD: pkgdb.c,v 1.1.1.1 2008/09/30 19:00:27 joerg Exp $ */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif -#if HAVE_NBCOMPAT_H -#include -#endif -#if HAVE_SYS_CDEFS_H -#include -#endif -#ifndef lint -__RCSID("$NetBSD: pkgdb.c,v 1.1.1.1 2008/09/30 19:00:27 joerg Exp $"); -#endif +/* NetBSD: pkgdb.c,v 1.39 2010/04/20 21:22:38 joerg Exp */ /*- - * Copyright (c) 1999-2008 The NetBSD Foundation, Inc. + * Copyright (c) 1999-2010 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -42,313 +29,39 @@ __RCSID("$NetBSD: pkgdb.c,v 1.1.1.1 2008/09/30 19:00:27 joerg Exp $"); * POSSIBILITY OF SUCH DAMAGE. */ -#if HAVE_DB_185_H -#include -#elif HAVE_DB1_DB_H -#include -#elif HAVE_DB_H -#include -#endif -#if HAVE_ERR_H -#include -#endif -#if HAVE_ERRNO_H -#include -#endif -#if HAVE_FCNTL_H -#include -#endif -#if HAVE_STDARG_H -#include -#endif -#if HAVE_STDIO_H -#include -#endif -#if HAVE_STRING_H -#include -#endif -#if defined(HAVE_DBOPEN) || (defined(HAVE___DB185_OPEN) && defined(HAVE_DB_185_H)) -#define HAVE_DBLIB 1 -#else -#define HAVE_DBLIB 0 -#endif - -#include "lib.h" - -#define PKGDB_FILE "pkgdb.byfile.db" /* indexed by filename */ - /* - * Where we put logging information by default if PKG_DBDIR is unset. + * This is a much simplified version of pkgdb.c that provides what is required + * by the other files we have pulled from pkg_install. It is also modified to + * set pkgdb_dir explicitly to what we have parsed from pkg_admin(1). */ -#ifndef DEF_LOG_DIR -#define DEF_LOG_DIR "/var/db/pkg" -#endif -/* just in case we change the environment variable name */ -#if 0 /* defined by upstream Makefile */ -#define PKG_DBDIR "PKG_DBDIR" -#endif +#include "lib.h" -#if HAVE_DBLIB -static DB *pkgdbp; -#endif static char *pkgdb_dir = NULL; -static char pkgdb_cache[MaxPathSize]; +static int pkgdb_dir_prio = 0; -#if HAVE_DBLIB -/* - * Open the pkg-database - * Return value: - * 1: everything ok - * 0: error - */ -int -pkgdb_open(int mode) +const char * +pkgdb_get_dir(void) { - BTREEINFO info; - char cachename[MaxPathSize]; - - /* try our btree format first */ - info.flags = 0; - info.cachesize = 2*1024*1024; - info.maxkeypage = 0; - info.minkeypage = 0; - info.psize = 4096; - info.compare = NULL; - info.prefix = NULL; - info.lorder = 0; - pkgdbp = (DB *) dbopen(_pkgdb_getPKGDB_FILE(cachename, sizeof(cachename)), - (mode == ReadOnly) ? O_RDONLY : O_RDWR | O_CREAT, - 0644, DB_BTREE, (void *) &info); - return (pkgdbp != NULL); + return pkgdb_dir; } -/* - * Close the pkg database - */ void -pkgdb_close(void) -{ - if (pkgdbp != NULL) { - (void) (*pkgdbp->close) (pkgdbp); - pkgdbp = NULL; - } -} - -/* - * Store value "val" with key "key" in database - * Return value is as from ypdb_store: - * 0: ok - * 1: key already present - * -1: some other error, see errno - */ -int -pkgdb_store(const char *key, const char *val) -{ - DBT keyd, vald; - - if (pkgdbp == NULL) - return -1; - - keyd.data = (void *) key; - keyd.size = strlen(key) + 1; - vald.data = (void *) val; - vald.size = strlen(val) + 1; - - if (keyd.size > MaxPathSize || vald.size > MaxPathSize) - return -1; - - return (*pkgdbp->put) (pkgdbp, &keyd, &vald, R_NOOVERWRITE); -} - -/* - * Recall value for given key - * Return value: - * NULL if some error occurred or value for key not found (check errno!) - * String for "value" else - */ -char * -pkgdb_retrieve(const char *key) -{ - DBT keyd, vald; - int status; - - if (pkgdbp == NULL) - return NULL; - - keyd.data = (void *) key; - keyd.size = strlen(key) + 1; - errno = 0; /* to be sure it's 0 if the key doesn't match anything */ - - vald.data = (void *)NULL; - vald.size = 0; - status = (*pkgdbp->get) (pkgdbp, &keyd, &vald, 0); - if (status) { - vald.data = NULL; - vald.size = 0; - } - - return vald.data; -} - -/* dump contents of the database to stdout */ -int -pkgdb_dump(void) -{ - DBT key; - DBT val; - int type; - - if (pkgdb_open(ReadOnly)) { - for (type = R_FIRST ; (*pkgdbp->seq)(pkgdbp, &key, &val, type) == 0 ; type = R_NEXT) { - printf("file: %.*s pkg: %.*s\n", - (int) key.size, (char *) key.data, - (int) val.size, (char *) val.data); - } - pkgdb_close(); - return 0; - } else - return -1; -} - -/* - * Remove data set from pkgdb - * Return value as ypdb_delete: - * 0: everything ok - * 1: key not present - * -1: some error occurred (see errno) - */ -int -pkgdb_remove(const char *key) +pkgdb_set_dir(const char *dir, int prio) { - DBT keyd; + if (prio < pkgdb_dir_prio) + return; - if (pkgdbp == NULL) - return -1; + pkgdb_dir_prio = prio; - keyd.data = (char *) key; - keyd.size = strlen(key) + 1; - if (keyd.size > MaxPathSize) - return -1; + if (dir == pkgdb_dir) + return; - return (*pkgdbp->del) (pkgdbp, &keyd, 0); -} - -/* - * Remove any entry from the cache which has a data field of `pkg'. - * Return value: - * 1: everything ok - * 0: error - */ -int -pkgdb_remove_pkg(const char *pkg) -{ - DBT data; - DBT key; - int type; - int ret; - int cc; - char cachename[MaxPathSize]; - - if (pkgdbp == NULL) { - return 0; - } - (void) _pkgdb_getPKGDB_FILE(cachename, sizeof(cachename)); - cc = strlen(pkg); - for (ret = 1, type = R_FIRST; (*pkgdbp->seq)(pkgdbp, &key, &data, type) == 0 ; type = R_NEXT) { - if ((cc + 1) == data.size && strncmp(data.data, pkg, cc) == 0) { - if (Verbose) { - printf("Removing file `%s' from %s\n", (char *)key.data, cachename); - } - switch ((*pkgdbp->del)(pkgdbp, &key, 0)) { - case -1: - warn("Error removing `%s' from %s", (char *)key.data, cachename); - ret = 0; - break; - case 1: - warn("Key `%s' not present in %s", (char *)key.data, cachename); - ret = 0; - break; - - } - } - } - return ret; -} - -#else /* !HAVE_DBLIB */ - -int pkgdb_open(int mode) { return 1; } -void pkgdb_close(void) {} -int pkgdb_store(const char *key, const char *val) { return 0; } -char *pkgdb_retrieve(const char *key) { return NULL; } -int pkgdb_dump(void) { return 0; } -int pkgdb_remove(const char *key) { return 0; } -int pkgdb_remove_pkg(const char *pkg) { return 1; } - -#endif /* HAVE_DBLIB */ - -/* - * Return the location of the package reference counts database directory. - */ -char * -pkgdb_refcount_dir(void) -{ - static char buf[MaxPathSize]; - char *tmp; - - if ((tmp = getenv(PKG_REFCOUNT_DBDIR_VNAME))) - strlcpy(buf, tmp, sizeof(buf)); - else - snprintf(buf, sizeof(buf), "%s.refcount", _pkgdb_getPKGDB_DIR()); - return buf; -} - -/* - * Return name of cache file in the buffer that was passed. - */ -char * -_pkgdb_getPKGDB_FILE(char *buf, unsigned size) -{ - (void) snprintf(buf, size, "%s/%s", _pkgdb_getPKGDB_DIR(), PKGDB_FILE); - return buf; -} - -/* - * Return directory where pkgdb is stored - */ -const char * -_pkgdb_getPKGDB_DIR(void) -{ - char *tmp; - - if (pkgdb_dir == NULL) { - if ((tmp = getenv(PKG_DBDIR))) - _pkgdb_setPKGDB_DIR(tmp); - else - _pkgdb_setPKGDB_DIR(DEF_LOG_DIR); - } - - return pkgdb_dir; -} - -/* - * Set the first place we look for where pkgdb is stored. - */ -void -_pkgdb_setPKGDB_DIR(const char *dir) -{ - (void) snprintf(pkgdb_cache, sizeof(pkgdb_cache), "%s", dir); - pkgdb_dir = pkgdb_cache; + pkgdb_dir = xstrdup(dir); } char * pkgdb_pkg_file(const char *pkg, const char *file) { - char *buf; - - if (asprintf(&buf, "%s/%s/%s", _pkgdb_getPKGDB_DIR(), pkg, file) == -1) - err(EXIT_FAILURE, "asprintf failed"); - - return buf; + return xasprintf("%s/%s/%s", pkgdb_get_dir(), pkg, file); } diff --git a/main.c b/main.c index 150852b..66f55db 100644 --- a/main.c +++ b/main.c @@ -50,7 +50,6 @@ main(int argc, char *argv[]) uint8_t need_upgrade, need_refresh; uint8_t do_inst = DO_INST; /* by default, do install packages */ int ch, i, rc = EXIT_SUCCESS; - struct stat sb; const char *chrootpath = NULL; setprogname(argv[0]); @@ -137,15 +136,8 @@ main(int argc, char *argv[]) errx(-1, MSG_CHDIR_FAILED); } - /* check for pkg_install */ - if (stat(PKG_ADD, &sb) < 0) - errx(EXIT_FAILURE, MSG_PKG_INSTALL_NOT_PRESENT); - - /* retrieve PKG_DBDIR from pkg_admin(1) */ - get_pkg_dbdir(); - - /* for pkg_install */ - unsetenv("PKG_PATH"); + /* Configure pkg_install */ + setup_pkg_install(); /* Configure pkgin database directory */ setup_pkgin_dbdir(); diff --git a/pkg_infos.c b/pkg_infos.c index 5b5005c..846ef30 100644 --- a/pkg_infos.c +++ b/pkg_infos.c @@ -43,8 +43,8 @@ show_pkg_info(char flag, char *pkgname) /* loop through PKG_REPOS */ for (prepos = pkg_repos; *prepos != NULL; prepos++) { - snprintf(cmd, BUFSIZ, - PKG_INFO" -%c %s/%s%s", flag, *prepos, fullpkgname, PKG_EXT); + snprintf(cmd, BUFSIZ, "%s -%c %s/%s%s", + pkg_info, flag, *prepos, fullpkgname, PKG_EXT); if ((out_cmd = exec_list(cmd, NULL)) == NULL) continue; diff --git a/pkg_install.c b/pkg_install.c new file mode 100644 index 0000000..b949c67 --- /dev/null +++ b/pkg_install.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2018 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Routines for configuring and using pkg_install utilities. + */ + +#include "pkgin.h" + +char *pkg_install_dir; +char *pkg_add; +char *pkg_admin; +char *pkg_delete; +char *pkg_info; + +/* + * Configure the location to pkg_install used in this instance, either via the + * PKG_INSTALL_DIR environment variable or the default compiled-in location. + */ +void +setup_pkg_install() +{ + FILE *fp; + char *line, *p; + size_t len; + ssize_t llen; + + if ((p = getenv("PKG_INSTALL_DIR")) != NULL) + pkg_install_dir = xstrdup(p); + else + pkg_install_dir = xstrdup(PKGTOOLS); + + pkg_add = xasprintf("%s/pkg_add", pkg_install_dir); + pkg_admin = xasprintf("%s/pkg_admin", pkg_install_dir); + pkg_info = xasprintf("%s/pkg_info", pkg_install_dir); + pkg_delete = xasprintf("%s/pkg_delete", pkg_install_dir); + + /* Sanity check */ + if (access(pkg_admin, X_OK) != 0) + err(EXIT_FAILURE, "Cannot execute %s", pkg_admin); + + /* Ensure pkg_install only looks at our specified paths */ + unsetenv("PKG_PATH"); + + /* Get PKG_DBDIR from pkg_admin */ + p = xasprintf("%s config-var PKG_DBDIR", pkg_admin); + + if ((fp = popen(p, "r")) == NULL) + err(EXIT_FAILURE, "Cannot execute '%s'", p); + + line = NULL; len = 0; + while ((llen = getline(&line, &len, fp)) > 0) { + if (line[llen - 1] == '\n') + line[llen - 1] = '\0'; + pkgdb_set_dir(line, 1); + } + pclose(fp); + + free(line); + free(p); + + if (pkgdb_get_dir() == NULL) + errx(EXIT_FAILURE, "Could not determine PKG_DBDIR"); +} diff --git a/pkgin.h b/pkgin.h index 0e7ea70..27bd38f 100644 --- a/pkgin.h +++ b/pkgin.h @@ -50,13 +50,6 @@ #include "lib.h" #include "dewey.h" -#ifndef PKGTOOLS -#define PKGTOOLS "/usr/sbin" -#endif -#define PKG_DELETE PKGTOOLS"/pkg_delete" -#define PKG_ADD PKGTOOLS"/pkg_add" -#define PKG_INFO PKGTOOLS"/pkg_info" - #define PKG_SUMMARY "pkg_summary" #define PKG_EXT ".tgz" #define PKGIN_CONF PKG_SYSCONFDIR"/pkgin" @@ -224,8 +217,6 @@ extern int l_plistcounter; extern char *env_repos; extern char **pkg_repos; extern char lslimit; -extern char pkgtools_flags[]; -extern char pkg_dbdir[]; extern Plisthead r_plisthead; extern Plisthead l_plisthead; extern FILE *tracefp; @@ -306,6 +297,14 @@ void show_prov_req(const char *, const char *); /* pkg_infos.c */ void show_pkg_info(char, char *); +/* pkg_install.c */ +extern char *pkg_install_dir; +extern char *pkg_add; +extern char *pkg_admin; +extern char *pkg_delete; +extern char *pkg_info; +void setup_pkg_install(void); + /* pkgindb.c */ #define PRIVS_PKGDB 0x1 #define PRIVS_PKGINDB 0x2 @@ -315,7 +314,6 @@ extern char *pkgin_cache; extern char *pkgin_errlog; extern char *pkgin_sqllog; void setup_pkgin_dbdir(void); -void get_pkg_dbdir(void); uint8_t have_privs(int); /* preferred.c */ diff --git a/pkgindb.c b/pkgindb.c index 1a7dd34..bbfb645 100644 --- a/pkgindb.c +++ b/pkgindb.c @@ -49,8 +49,6 @@ static const char *pragmaopts[] = { NULL }; -char pkg_dbdir[BUFSIZ]; - char *pkgin_dbdir; char *pkgin_sqldb; char *pkgin_cache; @@ -83,27 +81,12 @@ setup_pkgin_dbdir(void) } } -void -get_pkg_dbdir(void) -{ - char **exec_cmd; - - if ((exec_cmd = - exec_list(PKGTOOLS"/pkg_admin config-var PKG_DBDIR", NULL)) - == NULL) - strcpy(pkg_dbdir, PKG_DBDIR); - else { - XSTRCPY(pkg_dbdir, exec_cmd[0]); - free_list(exec_cmd); - } -} - uint8_t have_privs(int reqd) { if ((reqd & PRIVS_PKGDB) && - (access(pkg_dbdir, F_OK) == 0) && - (access(pkg_dbdir, W_OK) < 0)) + (access(pkgdb_get_dir(), F_OK) == 0) && + (access(pkgdb_get_dir(), W_OK) < 0)) return 0; if ((reqd & PRIVS_PKGINDB) && @@ -282,14 +265,13 @@ pkgindb_reset() int pkg_db_mtime() { - uint8_t pkgdb_present = 1; struct stat st; time_t db_mtime = 0; char str_mtime[20], buf[BUFSIZ]; /* no pkgdb file */ - if (stat(pkg_dbdir, &st) < 0) - pkgdb_present = 0; + if (stat(pkgdb_get_dir(), &st) < 0) + return 0; str_mtime[0] = '\0'; @@ -300,7 +282,7 @@ pkg_db_mtime() db_mtime = (time_t)strtol(str_mtime, (char **)NULL, 10); /* mtime is up to date */ - if (!pkgdb_present || db_mtime == st.st_mtime) + if (db_mtime == st.st_mtime) return 0; snprintf(buf, BUFSIZ, UPDATE_PKGDB_MTIME, (long long)st.st_mtime); diff --git a/summary.c b/summary.c index 81ac513..5bf9af8 100644 --- a/summary.c +++ b/summary.c @@ -558,12 +558,9 @@ update_localdb(char **pkgkeep) Pkglist *pkglist; /* has the pkgdb (pkgsrc) changed ? if not, continue */ - if (!pkg_db_mtime() || !pkgdb_open(ReadWrite)) + if (!pkg_db_mtime()) return; - /* just checking */ - pkgdb_close(); - /* record the keep list */ keeplisthead = rec_pkglist(KEEP_LOCAL_PKGS); /* delete local pkg table (faster than updating) */