From f3b9d98e5bf248a4f90d378f6b07eb99f46e7321 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Mon, 9 Apr 2018 15:05:08 +0100 Subject: [PATCH] Add support for a PKGIN_DBDIR environment variable This allows users to create their own pkgin database directory, primarily useful for the pkgin test suite. The user will of course still require the appropriate pkg_install permissions for operations which need write access. Some changes are required to work around a regression introduced in have_enough_rights() some years ago, where pkg_dbdir was checked twice instead of checking pkgin_dbdir. The function is renamed to have_privs() and now supports a flag indicating which privileges are required. --- Makefile.in | 6 +++--- actions.c | 23 +++++++++++++--------- autoremove.c | 2 +- fsops.c | 13 ------------- main.c | 6 +++--- messages.h | 2 -- pkgin.h | 16 ++++++++++----- pkgindb.c | 55 ++++++++++++++++++++++++++++++++++++++++++++-------- pkgindb.h | 3 --- summary.c | 2 +- 10 files changed, 80 insertions(+), 48 deletions(-) diff --git a/Makefile.in b/Makefile.in index a50a40f..790d3d6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -63,9 +63,9 @@ CPPFLAGS+= -DPKGIN_VERSION=\"${PKGIN_VERSION}\" .if defined(DEBUG) CPPFLAGS+= -DDEBUG -PKGIN_DB!= pwd +PKGIN_DBDIR!= pwd .else -PKGIN_DB= ${VARBASE}/db/pkgin +PKGIN_DBDIR= ${VARBASE}/db/pkgin .endif .if ${OPSYS} == "NetBSD" @@ -80,7 +80,7 @@ CPPFLAGS+= -DLOCALBASE=\"${LOCALBASE}\" \ -DPKG_SYSCONFDIR=\"${PKG_SYSCONFDIR}\" \ -DPKG_DBDIR="\"${PKG_DBDIR}\"" \ -DDEF_LOG_DIR="\"${PKG_DBDIR}\"" \ - -DPKGIN_DB=\"${PKGIN_DB}\" \ + -DPKGIN_DBDIR=\"${PKGIN_DBDIR}\" \ -DPKGTOOLS=\"${PKGTOOLS}\" CPPFLAGS+= -DHAVE_CONFIG_H diff --git a/actions.c b/actions.c index 37bee4d..e967320 100644 --- a/actions.c +++ b/actions.c @@ -37,7 +37,6 @@ #define LOCALBASE "/usr/pkg" /* see DISCLAIMER below */ #endif -const char *pkgin_cache = PKGIN_CACHE; static int upgrade_type = UPGRADE_NONE, warn_count = 0, err_count = 0; static uint8_t said = 0; FILE *err_fp = NULL; @@ -133,7 +132,7 @@ pkg_download(Plisthead *installhead) } /** - * \brief Analyse PKG_INSTALL_ERR_LOG for warnings + * \brief Analyse pkgin_errlog for warnings */ static void analyse_pkglog(long int filepos) @@ -144,7 +143,7 @@ analyse_pkglog(long int filepos) if (filepos < 0) return; - err_ro = fopen(PKG_INSTALL_ERR_LOG, "r"); + err_ro = fopen(pkgin_errlog, "r"); (void)fseek(err_ro, filepos, SEEK_SET); @@ -167,7 +166,7 @@ analyse_pkglog(long int filepos) } /** - * \brief Tags PKG_INSTALL_ERR_LOG with date + * \brief Tags pkgin_errlog with date */ #define DATELEN 64 @@ -199,9 +198,9 @@ static void open_pi_log(void) { if (!verbosity && !said) { - if ((err_fp = fopen(PKG_INSTALL_ERR_LOG, "a")) == NULL) { + if ((err_fp = fopen(pkgin_errlog, "a")) == NULL) { fprintf(stderr, MSG_CANT_OPEN_WRITE, - PKG_INSTALL_ERR_LOG); + pkgin_errlog); exit(EXIT_FAILURE); } @@ -219,7 +218,7 @@ close_pi_log(void) analyse_pkglog(rm_filepos); printf(MSG_WARNS_ERRS, warn_count, err_count); if (warn_count > 0 || err_count > 0) - printf(MSG_PKG_INSTALL_LOGGING_TO, PKG_INSTALL_ERR_LOG); + printf(MSG_PKG_INSTALL_LOGGING_TO, pkgin_errlog); } } @@ -362,6 +361,7 @@ pkgin_install(char **opkgargs, uint8_t do_inst) { int installnum = 0, upgradenum = 0, removenum = 0; int rc = EXIT_SUCCESS; + int privsreqd = PRIVS_PKGINDB; uint64_t file_size = 0, free_space; int64_t size_pkg = 0; Pkglist *premove, *pinstall; @@ -381,12 +381,17 @@ pkgin_install(char **opkgargs, uint8_t do_inst) return rc; } + if (do_inst) + privsreqd |= PRIVS_PKGDB; + + if (!have_privs(privsreqd)) + errx(EXIT_FAILURE, MSG_DONT_HAVE_RIGHTS); + /* * Perform an explicit summary update to avoid download mismatches * if the repository has been recently updated. */ - if (update_db(REMOTE_SUMMARY, NULL, 0) == EXIT_FAILURE) - errx(EXIT_FAILURE, MSG_DONT_HAVE_RIGHTS); + (void)update_db(REMOTE_SUMMARY, NULL, 0); /* full impact list */ if ((impacthead = pkg_impact(pkgargs, &rc)) == NULL) { diff --git a/autoremove.c b/autoremove.c index 7535be0..401784d 100644 --- a/autoremove.c +++ b/autoremove.c @@ -183,7 +183,7 @@ pkg_keep(int type, char **pkgargs) Pkglist *pkglist = NULL; char **pkeep, *pkgname, query[BUFSIZ]; - if (!have_enough_rights()) + if (!have_privs(PRIVS_PKGDB|PRIVS_PKGINDB)) errx(EXIT_FAILURE, MSG_DONT_HAVE_RIGHTS); if (SLIST_EMPTY(&l_plisthead)) /* no packages recorded */ diff --git a/fsops.c b/fsops.c index 2d985a5..5b3583d 100644 --- a/fsops.c +++ b/fsops.c @@ -98,19 +98,6 @@ clean_cache() closedir(dp); } -void -create_dirs() -{ - /* create database repository */ - if(-1 == mkdir(PKGIN_DB, 0755) && errno != EEXIST) - errx(EXIT_FAILURE, MSG_MKDIR_DB_REPOSITORY_FAILED, - strerror(errno)); - /* create cache repository */ - if(-1 == mkdir(pkgin_cache, 0755) && errno != EEXIST) - errx(EXIT_FAILURE, MSG_MKDIR_CACHE_REPOSITORY_FAILED, - strerror(errno)); -} - char * read_repos() { diff --git a/main.c b/main.c index 260720f..150852b 100644 --- a/main.c +++ b/main.c @@ -146,9 +146,9 @@ main(int argc, char *argv[]) /* for pkg_install */ unsetenv("PKG_PATH"); - /* create base directories */ - if (stat(pkgin_cache, &sb) < 0) - create_dirs(); + + /* Configure pkgin database directory */ + setup_pkgin_dbdir(); pkgindb_init(); diff --git a/messages.h b/messages.h index f7bae97..821b351 100644 --- a/messages.h +++ b/messages.h @@ -166,8 +166,6 @@ please re-run %s with a package name matching one of the following:\n" /* fsops.c */ #define MSG_TRANS_FAILED "Failed to translate %s in repository config file" #define MSG_INVALID_REPOS "Invalid repository: %s" -#define MSG_MKDIR_DB_REPOSITORY_FAILED "Failed to create database repository %s\n" -#define MSG_MKDIR_CACHE_REPOSITORY_FAILED "Failed to create cache repository %s\n" /* selection.c */ #define MSG_EMPTY_IMPORT_LIST "Empty import list." diff --git a/pkgin.h b/pkgin.h index 01d3d5e..0e7ea70 100644 --- a/pkgin.h +++ b/pkgin.h @@ -58,9 +58,6 @@ #define PKG_INFO PKGTOOLS"/pkg_info" #define PKG_SUMMARY "pkg_summary" -#define PKGIN_SQL_LOG PKGIN_DB"/sql.log" -#define PKG_INSTALL_ERR_LOG PKGIN_DB"/pkg_install-err.log" -#define PKGIN_CACHE PKGIN_DB"/cache" #define PKG_EXT ".tgz" #define PKGIN_CONF PKG_SYSCONFDIR"/pkgin" #define REPOS_FILE "repositories.conf" @@ -226,7 +223,6 @@ extern int r_plistcounter; extern int l_plistcounter; extern char *env_repos; extern char **pkg_repos; -extern const char *pkgin_cache; extern char lslimit; extern char pkgtools_flags[]; extern char pkg_dbdir[]; @@ -290,7 +286,6 @@ void pkg_keep(int, char **); int fs_has_room(const char *, int64_t); uint64_t fs_room(const char *); void clean_cache(void); -void create_dirs(void); char *read_repos(void); /* pkg_str.c */ char *unique_pkg(const char *, const char *); @@ -310,8 +305,19 @@ int pkg_has_conflicts(Pkglist *); void show_prov_req(const char *, const char *); /* pkg_infos.c */ void show_pkg_info(char, char *); + /* pkgindb.c */ +#define PRIVS_PKGDB 0x1 +#define PRIVS_PKGINDB 0x2 +extern char *pkgin_dbdir; +extern char *pkgin_sqldb; +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 */ void load_preferred(void); void free_preferred(void); diff --git a/pkgindb.c b/pkgindb.c index b96e9f8..1a7dd34 100644 --- a/pkgindb.c +++ b/pkgindb.c @@ -51,6 +51,38 @@ static const char *pragmaopts[] = { char pkg_dbdir[BUFSIZ]; +char *pkgin_dbdir; +char *pkgin_sqldb; +char *pkgin_cache; +char *pkgin_errlog; +char *pkgin_sqllog; + +void +setup_pkgin_dbdir(void) +{ + char *p; + + if ((p = getenv("PKGIN_DBDIR")) != NULL) + pkgin_dbdir = xasprintf("%s", p); + else + pkgin_dbdir = xasprintf("%s", PKGIN_DBDIR); + + pkgin_sqldb = xasprintf("%s/pkgin.db", pkgin_dbdir); + pkgin_cache = xasprintf("%s/cache", pkgin_dbdir); + pkgin_errlog = xasprintf("%s/pkg_install-err.log", pkgin_dbdir); + pkgin_sqllog = xasprintf("%s/sql.log", pkgin_dbdir); + + if (access(pkgin_dbdir, F_OK) != 0) { + if (mkdir(pkgin_dbdir, 0755) < 0) + err(1, "Failed to create %s", pkgin_dbdir); + } + + if (access(pkgin_cache, F_OK) != 0) { + if (mkdir(pkgin_cache, 0755) < 0) + err(1, "Failed to create %s", pkgin_cache); + } +} + void get_pkg_dbdir(void) { @@ -67,9 +99,16 @@ get_pkg_dbdir(void) } uint8_t -have_enough_rights() +have_privs(int reqd) { - if (access(pkg_dbdir, W_OK) < 0 || access(pkg_dbdir, W_OK) < 0) + if ((reqd & PRIVS_PKGDB) && + (access(pkg_dbdir, F_OK) == 0) && + (access(pkg_dbdir, W_OK) < 0)) + return 0; + + if ((reqd & PRIVS_PKGINDB) && + (access(pkgin_dbdir, F_OK) == 0) && + (access(pkgin_dbdir, W_OK) < 0)) return 0; return 1; @@ -204,13 +243,13 @@ pkgindb_init() char buf[BUFSIZ]; /* - * Do not exit if PKGIN_SQL_LOG is not writable. + * Do not exit if pkgin_sqllog is not writable. * Permit users to do list-operations */ - sql_log_fp = fopen(PKGIN_SQL_LOG, "w"); + sql_log_fp = fopen(pkgin_sqllog, "w"); - if (sqlite3_open(PDB, &pdb) != SQLITE_OK) - pdb_err("Can't open database " PDB); + if (sqlite3_open(pkgin_sqldb, &pdb) != SQLITE_OK) + pdb_err("Can't open database"); /* generic query in order to check tables existence */ if (pkgindb_doquery("select * from sqlite_master;", @@ -234,8 +273,8 @@ pkgindb_reset() { pkgindb_close(); - if (unlink(PDB) < 0) - err(EXIT_FAILURE, MSG_DELETE_DB_FAILED, PDB); + if (unlink(pkgin_sqldb) < 0) + err(EXIT_FAILURE, MSG_DELETE_DB_FAILED, pkgin_sqldb); pkgindb_init(); } diff --git a/pkgindb.h b/pkgindb.h index 8abac5a..2087f99 100644 --- a/pkgindb.h +++ b/pkgindb.h @@ -81,9 +81,6 @@ extern const char SHOW_ALL_CATEGORIES[]; #define LOCAL_PKG "LOCAL_PKG" #define REMOTE_PKG "REMOTE_PKG" -#define PDB PKGIN_DB"/pkgin.db" - -uint8_t have_enough_rights(void); const char *pdb_version(void); uint8_t upgrade_database(void); void pkgindb_init(void); diff --git a/summary.c b/summary.c index d13bd93..81ac513 100644 --- a/summary.c +++ b/summary.c @@ -699,7 +699,7 @@ update_remotedb(int verbose) int update_db(int which, char **pkgkeep, int verbose) { - if (!have_enough_rights()) + if (!have_privs(PRIVS_PKGINDB)) return EXIT_FAILURE; /* always check for LOCAL_SUMMARY updates */