[pacman-dev] [PATCH 1/6] Use standard errno codes in return from _alpm_archive_fgets
This allows us to not require the context (e.g. handle) when calling this function. Also beef up the checks in the two callers of this function to bail if the last return code is not ARCHIVE_EOF, which is the expected value. This requires a change to one of the pactest return codes and the overall result of the test, but results in a much safer operating condition whereby invalid database entries will stop the operation. Signed-off-by: Dan McGee <dan@archlinux.org> --- lib/libalpm/be_package.c | 10 +++++++--- lib/libalpm/be_sync.c | 22 ++++++++++++++++++---- lib/libalpm/util.c | 7 +++---- test/pacman/pactest.py | 1 + test/pacman/tests/smoke002.py | 12 +++++------- 5 files changed, 34 insertions(+), 18 deletions(-) diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c index c70d1e9..c89365a 100644 --- a/lib/libalpm/be_package.c +++ b/lib/libalpm/be_package.c @@ -137,13 +137,13 @@ static struct pkg_operations *get_file_pkg_ops(void) * @param archive the archive to read from, pointed at the .PKGINFO entry * @param newpkg an empty pmpkg_t struct to fill with package info * - * @return 0 on success, 1 on error + * @return 0 on success, -1 on error */ static int parse_descfile(struct archive *a, pmpkg_t *newpkg) { char *ptr = NULL; char *key = NULL; - int linenum = 0; + int ret, linenum = 0; struct archive_read_buffer buf; memset(&buf, 0, sizeof(buf)); @@ -151,7 +151,7 @@ static int parse_descfile(struct archive *a, pmpkg_t *newpkg) buf.max_line_size = 512 * 1024; /* loop until we reach EOF or other error */ - while(_alpm_archive_fgets(a, &buf) == ARCHIVE_OK) { + while((ret = _alpm_archive_fgets(a, &buf)) == ARCHIVE_OK) { char *line = _alpm_strtrim(buf.line); linenum++; @@ -215,6 +215,10 @@ static int parse_descfile(struct archive *a, pmpkg_t *newpkg) } line[0] = '\0'; } + if(ret != ARCHIVE_EOF) { + _alpm_log(PM_LOG_DEBUG, "error parsing package descfile\n"); + return -1; + } return 0; } diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c index 953e4dc..aeba86f 100644 --- a/lib/libalpm/be_sync.c +++ b/lib/libalpm/be_sync.c @@ -294,6 +294,7 @@ static int sync_db_populate(pmdb_t *db) _alpm_log(PM_LOG_ERROR, _("invalid name for database entry '%s'\n"), name); _alpm_pkg_free(pkg); + pkg = NULL; continue; } @@ -301,6 +302,7 @@ static int sync_db_populate(pmdb_t *db) if(_alpm_pkghash_find(db->pkgcache, pkg->name)) { _alpm_log(PM_LOG_ERROR, _("duplicated database entry '%s'\n"), pkg->name); _alpm_pkg_free(pkg); + pkg = NULL; continue; } @@ -316,7 +318,14 @@ static int sync_db_populate(pmdb_t *db) count++; } else { /* we have desc, depends or deltas - parse it */ - sync_db_read(db, archive, entry, pkg); + if(sync_db_read(db, archive, entry, pkg) != 0) { + _alpm_log(PM_LOG_ERROR, + _("could not parse package '%s' description file from db '%s'\n"), + pkg->name, db->treename); + _alpm_pkg_free(pkg); + pkg = NULL; + continue; + } } } @@ -401,7 +410,8 @@ static int sync_db_read(pmdb_t *db, struct archive *archive, if(strcmp(filename, "desc") == 0 || strcmp(filename, "depends") == 0 || strcmp(filename, "deltas") == 0) { - while(_alpm_archive_fgets(archive, &buf) == ARCHIVE_OK) { + int ret; + while((ret = _alpm_archive_fgets(archive, &buf)) == ARCHIVE_OK) { char *line = _alpm_strtrim(buf.line); if(strcmp(line, "%NAME%") == 0) { @@ -478,6 +488,9 @@ static int sync_db_read(pmdb_t *db, struct archive *archive, } } } + if(ret != ARCHIVE_EOF) { + goto error; + } } else if(strcmp(filename, "files") == 0) { /* currently do nothing with this file */ } else { @@ -485,10 +498,11 @@ static int sync_db_read(pmdb_t *db, struct archive *archive, _alpm_log(PM_LOG_DEBUG, "unknown database file: %s\n", filename); } + return 0; + error: FREE(pkgname); - /* TODO: return 0 always? */ - return 0; + return -1; } static int sync_db_version(pmdb_t UNUSED *db) diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index e25e19d..5821bf9 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -771,20 +771,19 @@ int _alpm_archive_fgets(struct archive *a, struct archive_read_buffer *b) /* allocate our buffer, or ensure our existing one is big enough */ if(!b->line) { /* set the initial buffer to the read block_size */ - CALLOC(b->line, b->block_size + 1, sizeof(char), - RET_ERR(PM_ERR_MEMORY, -1)); + CALLOC(b->line, b->block_size + 1, sizeof(char), return ENOMEM); b->line_size = b->block_size + 1; b->line_offset = b->line; } else { size_t needed = (size_t)((b->line_offset - b->line) + (i - b->block_offset) + 1); if(needed > b->max_line_size) { - RET_ERR(PM_ERR_MEMORY, -1); + return ERANGE; } if(needed > b->line_size) { /* need to realloc + copy data to fit total length */ char *new; - CALLOC(new, needed, sizeof(char), RET_ERR(PM_ERR_MEMORY, -1)); + CALLOC(new, needed, sizeof(char), return ENOMEM); memcpy(new, b->line, b->line_size); b->line_size = needed; b->line_offset = new + (b->line_offset - b->line); diff --git a/test/pacman/pactest.py b/test/pacman/pactest.py index 64d5651..77f87da 100755 --- a/test/pacman/pactest.py +++ b/test/pacman/pactest.py @@ -114,6 +114,7 @@ def createOptParser(): env.results() if env.failed > 0: + print "pacman testing root saved: %s" % root_path sys.exit(1) if not opts.keeproot: diff --git a/test/pacman/tests/smoke002.py b/test/pacman/tests/smoke002.py index 44f2d0e..8ff5cab 100644 --- a/test/pacman/tests/smoke002.py +++ b/test/pacman/tests/smoke002.py @@ -10,10 +10,8 @@ self.args = "-U %s %s" % (p1.filename(), p2.filename()) -# Note that the current cutoff on line length is 512K, so the first package -# will succeed while the second one will fail to record the description. -self.addrule("PACMAN_RETCODE=0") -self.addrule("PKG_EXIST=pkg1") -self.addrule("PKG_DESC=pkg1|%s" % p1.desc) -self.addrule("PKG_EXIST=pkg1") -self.addrule("!PKG_DESC=pkg1|%s" % p2.desc) +# We error out when fed a package with an invalid description; the second one +# fits the bill in this case as the desc is > 512K +self.addrule("PACMAN_RETCODE=1") +self.addrule("!PKG_EXIST=pkg1") +self.addrule("!PKG_EXIST=pkg1") -- 1.7.5.2
This keeps duplicate code to a minimum and also addresses the issue where calling set_cachedirs() didn't canonicalize the passed-in paths. This will come in more handy as we refactor some of these option setters away. Signed-off-by: Dan McGee <dan@archlinux.org> --- lib/libalpm/alpm.c | 1 + lib/libalpm/deps.c | 1 + lib/libalpm/handle.c | 120 ++++++++++++++++++++++++++------------------------ lib/libalpm/handle.h | 5 +- lib/libalpm/util.c | 10 +++- 5 files changed, 73 insertions(+), 64 deletions(-) diff --git a/lib/libalpm/alpm.c b/lib/libalpm/alpm.c index 2da3432..55f6ecd 100644 --- a/lib/libalpm/alpm.c +++ b/lib/libalpm/alpm.c @@ -31,6 +31,7 @@ #include "alpm.h" #include "alpm_list.h" #include "handle.h" +#include "log.h" #include "util.h" /* Globals */ diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c index 27d0476..62e8702 100644 --- a/lib/libalpm/deps.c +++ b/lib/libalpm/deps.c @@ -35,6 +35,7 @@ #include "package.h" #include "db.h" #include "handle.h" +#include "trans.h" /* global handle variable */ extern pmhandle_t *handle; diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c index e94528f..0b0db2f 100644 --- a/lib/libalpm/handle.c +++ b/lib/libalpm/handle.c @@ -298,72 +298,76 @@ int SYMEXPORT alpm_option_set_totaldlcb(alpm_cb_totaldl cb) return 0; } -int SYMEXPORT alpm_option_set_root(const char *root) -{ - struct stat st; - char *realroot; - size_t rootlen; +static char *canonicalize_path(const char *path) { + char *new_path; + size_t len; - ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); + /* verify path ends in a '/' */ + len = strlen(path); + if(path[len - 1] != '/') { + len += 1; + } + new_path = calloc(len + 1, sizeof(char)); + strncpy(new_path, path, len); + new_path[len - 1] = '/'; + return new_path; +} + +int _alpm_set_directory_option(const char *value, + char **storage, int must_exist) + { + struct stat st; + char *real = NULL; + const char *path; - if(!root) { + path = value; + if(!path) { pm_errno = PM_ERR_WRONG_ARGS; return -1; } - if(stat(root, &st) == -1 || !S_ISDIR(st.st_mode)) { - pm_errno = PM_ERR_NOT_A_DIR; - return -1; - } + if(must_exist) { + if(stat(path, &st) == -1 || !S_ISDIR(st.st_mode)) { + pm_errno = PM_ERR_NOT_A_DIR; + return -1; + } + real = calloc(PATH_MAX + 1, sizeof(char)); + if(!realpath(path, real)) { + free(real); + pm_errno = PM_ERR_NOT_A_DIR; + return -1; + } + path = real; + } + + if(*storage) { + FREE(*storage); + } + *storage = canonicalize_path(path); + free(real); + return 0; +} - realroot = calloc(PATH_MAX+1, sizeof(char)); - if(!realpath(root, realroot)) { - FREE(realroot); - pm_errno = PM_ERR_NOT_A_DIR; - return -1; - } +int SYMEXPORT alpm_option_set_root(const char *root) +{ + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); - /* verify root ends in a '/' */ - rootlen = strlen(realroot); - if(realroot[rootlen-1] != '/') { - rootlen += 1; - } - if(handle->root) { - FREE(handle->root); + if(_alpm_set_directory_option(root, &(handle->root), 1)) { + return -1; } - handle->root = calloc(rootlen + 1, sizeof(char)); - strncpy(handle->root, realroot, rootlen); - handle->root[rootlen-1] = '/'; - FREE(realroot); _alpm_log(PM_LOG_DEBUG, "option 'root' = %s\n", handle->root); return 0; } int SYMEXPORT alpm_option_set_dbpath(const char *dbpath) { - struct stat st; - size_t dbpathlen, lockfilelen; const char *lf = "db.lck"; + size_t lockfilelen; ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); - if(!dbpath) { - pm_errno = PM_ERR_WRONG_ARGS; - return -1; - } - if(stat(dbpath, &st) == -1 || !S_ISDIR(st.st_mode)) { - pm_errno = PM_ERR_NOT_A_DIR; + + if(_alpm_set_directory_option(dbpath, &(handle->dbpath), 1)) { return -1; } - /* verify dbpath ends in a '/' */ - dbpathlen = strlen(dbpath); - if(dbpath[dbpathlen-1] != '/') { - dbpathlen += 1; - } - if(handle->dbpath) { - FREE(handle->dbpath); - } - handle->dbpath = calloc(dbpathlen+1, sizeof(char)); - strncpy(handle->dbpath, dbpath, dbpathlen); - handle->dbpath[dbpathlen-1] = '/'; _alpm_log(PM_LOG_DEBUG, "option 'dbpath' = %s\n", handle->dbpath); if(handle->lockfile) { @@ -379,7 +383,6 @@ int SYMEXPORT alpm_option_set_dbpath(const char *dbpath) int SYMEXPORT alpm_option_add_cachedir(const char *cachedir) { char *newcachedir; - size_t cachedirlen; ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); if(!cachedir) { @@ -389,24 +392,25 @@ int SYMEXPORT alpm_option_add_cachedir(const char *cachedir) /* don't stat the cachedir yet, as it may not even be needed. we can * fail later if it is needed and the path is invalid. */ - /* verify cachedir ends in a '/' */ - cachedirlen = strlen(cachedir); - if(cachedir[cachedirlen-1] != '/') { - cachedirlen += 1; - } - newcachedir = calloc(cachedirlen + 1, sizeof(char)); - strncpy(newcachedir, cachedir, cachedirlen); - newcachedir[cachedirlen-1] = '/'; + newcachedir = canonicalize_path(cachedir); handle->cachedirs = alpm_list_add(handle->cachedirs, newcachedir); - _alpm_log(PM_LOG_DEBUG, "option 'cachedir' = %s\n", newcachedir); + _alpm_log(PM_LOG_DEBUG, "backend option 'cachedir' = %s\n", newcachedir); return 0; } int SYMEXPORT alpm_option_set_cachedirs(alpm_list_t *cachedirs) { + alpm_list_t *i, *new_cachedirs = NULL; ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); + for(i = cachedirs; i; i = i->next) { + int ret = alpm_option_add_cachedir(i->data); + if(ret) { + return ret; + } + } if(handle->cachedirs) FREELIST(handle->cachedirs); - handle->cachedirs = cachedirs; + handle->cachedirs = new_cachedirs; + FREELIST(cachedirs); return 0; } diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h index 129c8ca..b72c9b0 100644 --- a/lib/libalpm/handle.h +++ b/lib/libalpm/handle.h @@ -24,10 +24,7 @@ #include <sys/types.h> #include "alpm_list.h" -#include "db.h" -#include "log.h" #include "alpm.h" -#include "trans.h" #ifdef HAVE_LIBCURL #include <curl/curl.h> @@ -78,6 +75,8 @@ struct __pmhandle_t { pmhandle_t *_alpm_handle_new(void); void _alpm_handle_free(pmhandle_t *handle); +int _alpm_set_directory_option(const char *value, char **storage, int must_exist); + #endif /* _ALPM_HANDLE_H */ /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index 5821bf9..6f0763d 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -56,6 +56,7 @@ #include "alpm.h" #include "alpm_list.h" #include "handle.h" +#include "trans.h" #ifndef HAVE_STRSEP /* This is a replacement for strsep which is not portable (missing on Solaris). @@ -606,15 +607,18 @@ const char *_alpm_filecache_setup(void) } else if(S_ISDIR(buf.st_mode) && (buf.st_mode & S_IWUSR)) { _alpm_log(PM_LOG_DEBUG, "using cachedir: %s\n", cachedir); return cachedir; + } else { + _alpm_log(PM_LOG_DEBUG, "skipping cachedir: %s\n", cachedir); } } /* we didn't find a valid cache directory. use /tmp. */ - tmp = alpm_list_add(NULL, strdup("/tmp/")); + tmp = alpm_list_add(NULL, "/tmp/"); alpm_option_set_cachedirs(tmp); - _alpm_log(PM_LOG_DEBUG, "using cachedir: %s", "/tmp/\n"); + alpm_list_free(tmp); + _alpm_log(PM_LOG_DEBUG, "using cachedir: %s\n", "/tmp/"); _alpm_log(PM_LOG_WARNING, _("couldn't create package cache, using /tmp instead\n")); - return alpm_list_getdata(tmp); + return "/tmp/"; } /** lstat wrapper that treats /path/dirsymlink/ the same as /path/dirsymlink. -- 1.7.5.2
On 04/06/11 08:40, Dan McGee wrote:
This keeps duplicate code to a minimum and also addresses the issue where calling set_cachedirs() didn't canonicalize the passed-in paths. This will come in more handy as we refactor some of these option setters away.
Signed-off-by: Dan McGee<dan@archlinux.org> --- <snip>
int SYMEXPORT alpm_option_set_cachedirs(alpm_list_t *cachedirs) { + alpm_list_t *i, *new_cachedirs = NULL; ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); + for(i = cachedirs; i; i = i->next) { + int ret = alpm_option_add_cachedir(i->data); + if(ret) { + return ret; + } + } if(handle->cachedirs) FREELIST(handle->cachedirs); - handle->cachedirs = cachedirs; + handle->cachedirs = new_cachedirs; + FREELIST(cachedirs); return 0; }
Should the clean-up done to this function in PATCH 3/6 be in here instead? This confused the hell out of me until I saw the next patch and I'm not sure how the clean-up fits into the next patch. Allan
On Fri, Jun 3, 2011 at 6:49 PM, Allan McRae <allan@archlinux.org> wrote:
On 04/06/11 08:40, Dan McGee wrote:
This keeps duplicate code to a minimum and also addresses the issue where calling set_cachedirs() didn't canonicalize the passed-in paths. This will come in more handy as we refactor some of these option setters away.
Signed-off-by: Dan McGee<dan@archlinux.org> ---
<snip>
int SYMEXPORT alpm_option_set_cachedirs(alpm_list_t *cachedirs) { + alpm_list_t *i, *new_cachedirs = NULL; ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); + for(i = cachedirs; i; i = i->next) { + int ret = alpm_option_add_cachedir(i->data); + if(ret) { + return ret; + } + } if(handle->cachedirs) FREELIST(handle->cachedirs); - handle->cachedirs = cachedirs; + handle->cachedirs = new_cachedirs; + FREELIST(cachedirs); return 0; }
Should the clean-up done to this function in PATCH 3/6 be in here instead? This confused the hell out of me until I saw the next patch and I'm not sure how the clean-up fits into the next patch.
This was a tough one to split, so I think it would be a tad confusing either way. It might make more sense to have this bit above be a patch all on its own; I can attempt to do that. -Dan
In all cases we should duplicate the passed-in list so the caller is free to do with it as it pleases. Signed-off-by: Dan McGee <dan@archlinux.org> --- lib/libalpm/handle.c | 16 ++++++++-------- 1 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c index 0b0db2f..d794992 100644 --- a/lib/libalpm/handle.c +++ b/lib/libalpm/handle.c @@ -400,17 +400,17 @@ int SYMEXPORT alpm_option_add_cachedir(const char *cachedir) int SYMEXPORT alpm_option_set_cachedirs(alpm_list_t *cachedirs) { - alpm_list_t *i, *new_cachedirs = NULL; + alpm_list_t *i; ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); + if(handle->cachedirs){ + FREELIST(handle->cachedirs); + } for(i = cachedirs; i; i = i->next) { int ret = alpm_option_add_cachedir(i->data); if(ret) { return ret; } } - if(handle->cachedirs) FREELIST(handle->cachedirs); - handle->cachedirs = new_cachedirs; - FREELIST(cachedirs); return 0; } @@ -496,7 +496,7 @@ int SYMEXPORT alpm_option_set_noupgrades(alpm_list_t *noupgrade) { ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); if(handle->noupgrade) FREELIST(handle->noupgrade); - handle->noupgrade = noupgrade; + handle->noupgrade = alpm_list_strdup(noupgrade); return 0; } @@ -523,7 +523,7 @@ int SYMEXPORT alpm_option_set_noextracts(alpm_list_t *noextract) { ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); if(handle->noextract) FREELIST(handle->noextract); - handle->noextract = noextract; + handle->noextract = alpm_list_strdup(noextract); return 0; } @@ -550,7 +550,7 @@ int SYMEXPORT alpm_option_set_ignorepkgs(alpm_list_t *ignorepkgs) { ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); if(handle->ignorepkg) FREELIST(handle->ignorepkg); - handle->ignorepkg = ignorepkgs; + handle->ignorepkg = alpm_list_strdup(ignorepkgs); return 0; } @@ -577,7 +577,7 @@ int SYMEXPORT alpm_option_set_ignoregrps(alpm_list_t *ignoregrps) { ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); if(handle->ignoregrp) FREELIST(handle->ignoregrp); - handle->ignoregrp = ignoregrps; + handle->ignoregrp = alpm_list_strdup(ignoregrps); return 0; } -- 1.7.5.2
These new method signatures return and take handle objects to operate on so we can move away from the idea of one global handle in the API. There is also another important change and that deals with the setting of root and dbpaths. These are now done at initialization time instead of using setter methods. This allows the library to operate more safely knowing that paths won't change underneath it. Signed-off-by: Dan McGee <dan@archlinux.org> --- lib/libalpm/alpm.c | 72 ++++++++++++++++++++++++++++++++++-------------- lib/libalpm/alpm.h | 36 ++++++++---------------- lib/libalpm/be_local.c | 2 +- lib/libalpm/db.c | 2 +- lib/libalpm/db.h | 4 +-- lib/libalpm/handle.c | 44 ++-------------------------- lib/libalpm/handle.h | 3 +- 7 files changed, 72 insertions(+), 91 deletions(-) diff --git a/lib/libalpm/alpm.c b/lib/libalpm/alpm.c index 55f6ecd..d516870 100644 --- a/lib/libalpm/alpm.c +++ b/lib/libalpm/alpm.c @@ -45,21 +45,37 @@ extern pmhandle_t *handle; /** Initializes the library. This must be called before any other * functions are called. - * @return 0 on success, -1 on error (pm_errno is set accordingly) + * @param root the root path for all filesystem operations + * @param dbpath the absolute path to the libalpm database + * @param err an optional variable to hold any error return codes + * @return a context handle on success, NULL on error, err will be set if provided */ -int SYMEXPORT alpm_initialize(void) +pmhandle_t SYMEXPORT *alpm_initialize(const char *root, const char *dbpath, + enum _pmerrno_t *err) { - ASSERT(handle == NULL, RET_ERR(PM_ERR_HANDLE_NOT_NULL, -1)); - - handle = _alpm_handle_new(); - if(handle == NULL) { - RET_ERR(PM_ERR_MEMORY, -1); + enum _pmerrno_t myerr; + const char *lf = "db.lck"; + size_t lockfilelen; + pmhandle_t *myhandle = _alpm_handle_new(); + + if(myhandle == NULL) { + myerr = PM_ERR_MEMORY; + goto cleanup; } - if(_alpm_db_register_local(handle) == NULL) { - /* error code should be set */ - _alpm_handle_free(handle); - handle = NULL; - return -1; + if((myerr = _alpm_set_directory_option(root, &(myhandle->root), 1))) { + goto cleanup; + } + if((myerr = _alpm_set_directory_option(dbpath, &(myhandle->dbpath), 1))) { + goto cleanup; + } + + lockfilelen = strlen(myhandle->dbpath) + strlen(lf) + 1; + myhandle->lockfile = calloc(lockfilelen, sizeof(char)); + snprintf(myhandle->lockfile, lockfilelen, "%s%s", myhandle->dbpath, lf); + + if(_alpm_db_register_local(myhandle) == NULL) { + myerr = PM_ERR_DB_CREATE; + goto cleanup; } #ifdef ENABLE_NLS @@ -68,33 +84,47 @@ int SYMEXPORT alpm_initialize(void) #ifdef HAVE_LIBCURL curl_global_init(CURL_GLOBAL_SSL); - handle->curl = curl_easy_init(); + myhandle->curl = curl_easy_init(); #endif - return 0; + /* TODO temporary until global var removed */ + handle = myhandle; + return myhandle; + +cleanup: + _alpm_handle_free(myhandle); + if(err && myerr) { + *err = myerr; + } + return NULL; } /** Release the library. This should be the last alpm call you make. - * @return 0 on success, -1 on error (pm_errno is set accordingly) + * After this returns, handle should be considered invalid and cannot be reused + * in any way. + * @param handle the context handle + * @return 0 on success, -1 on error */ -int SYMEXPORT alpm_release(void) +int SYMEXPORT alpm_release(pmhandle_t *myhandle) { pmdb_t *db; - ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); + ASSERT(myhandle != NULL, return -1); /* close local database */ - db = handle->db_local; + db = myhandle->db_local; if(db) { db->ops->unregister(db); - handle->db_local = NULL; + myhandle->db_local = NULL; } - if(alpm_db_unregister_all() == -1) { + if(alpm_db_unregister_all(myhandle) == -1) { return -1; } - _alpm_handle_free(handle); + _alpm_handle_free(myhandle); + myhandle = NULL; + /* TODO temporary until global var removed */ handle = NULL; #ifdef HAVE_LIBCURL diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index bc06cc0..ee55d0b 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -86,14 +86,6 @@ typedef struct __pmconflict_t pmconflict_t; typedef struct __pmfileconflict_t pmfileconflict_t; /* - * Library - */ - -int alpm_initialize(void); -int alpm_release(void); -const char *alpm_version(void); - -/* * Logging facilities */ @@ -165,15 +157,14 @@ alpm_cb_totaldl alpm_option_get_totaldlcb(void); /** Sets the callback used to report total download size. */ int alpm_option_set_totaldlcb(alpm_cb_totaldl cb); -/** Returns the root of the destination filesystem. */ +/** Returns the root of the destination filesystem. Read-only. */ const char *alpm_option_get_root(void); -/** Sets the root of the destination filesystem. */ -int alpm_option_set_root(const char *root); -/** Returns the path to the database directory. */ +/** Returns the path to the database directory. Read-only. */ const char *alpm_option_get_dbpath(void); -/** Sets the path to the database directory. */ -int alpm_option_set_dbpath(const char *dbpath); + +/** Get the name of the database lock file. Read-only. */ +const char *alpm_option_get_lockfile(void); /** @name Accessors to the list of package cache directories. * @{ @@ -189,15 +180,6 @@ const char *alpm_option_get_logfile(void); /** Sets the logfile name. */ int alpm_option_set_logfile(const char *logfile); -/** Get the name of the database lock file. - * - * This properly is read-only, and determined from - * the database path. - * - * @sa alpm_option_set_dbpath(const char*) - */ -const char *alpm_option_get_lockfile(void); - /** Returns the signature directory path. */ const char *alpm_option_get_signaturedir(void); /** Sets the signature directory path. */ @@ -302,9 +284,10 @@ pmdb_t *alpm_db_register_sync(const char *treename); int alpm_db_unregister(pmdb_t *db); /** Unregister all package databases. + * @param handle the context handle * @return 0 on success, -1 on error (pm_errno is set accordingly) */ -int alpm_db_unregister_all(void); +int alpm_db_unregister_all(pmhandle_t *handle); /** Get the name of a package database. * @param db pointer to the package database @@ -1054,6 +1037,11 @@ const char *alpm_strerrorlast(void); /* End of alpm_api_errors */ /** @} */ +pmhandle_t *alpm_initialize(const char *root, const char *dbpath, + enum _pmerrno_t *err); +int alpm_release(pmhandle_t *handle); +const char *alpm_version(void); + /* End of alpm_api */ /** @} */ diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c index 64af4b9..3a0887d 100644 --- a/lib/libalpm/be_local.c +++ b/lib/libalpm/be_local.c @@ -936,7 +936,7 @@ pmdb_t *_alpm_db_register_local(pmhandle_t *handle) db = _alpm_db_new("local", 1); if(db == NULL) { - RET_ERR(PM_ERR_DB_CREATE, NULL); + return NULL; } db->ops = &local_db_ops; db->handle = handle; diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c index 9b1f4fb..fda8428 100644 --- a/lib/libalpm/db.c +++ b/lib/libalpm/db.c @@ -71,7 +71,7 @@ void _alpm_db_unregister(pmdb_t *db) } /** Unregister all package databases. */ -int SYMEXPORT alpm_db_unregister_all(void) +int SYMEXPORT alpm_db_unregister_all(pmhandle_t *handle) { alpm_list_t *i; pmdb_t *db; diff --git a/lib/libalpm/db.h b/lib/libalpm/db.h index 3a7ab72..9ecf31f 100644 --- a/lib/libalpm/db.h +++ b/lib/libalpm/db.h @@ -22,9 +22,6 @@ #ifndef _ALPM_DB_H #define _ALPM_DB_H -#include "alpm.h" -#include "pkghash.h" - #include <time.h> /* libarchive */ @@ -32,6 +29,7 @@ #include <archive_entry.h> #include "alpm.h" +#include "pkghash.h" #include "signing.h" /* Database entries */ diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c index d794992..48ab3a3 100644 --- a/lib/libalpm/handle.c +++ b/lib/libalpm/handle.c @@ -313,7 +313,7 @@ static char *canonicalize_path(const char *path) { return new_path; } -int _alpm_set_directory_option(const char *value, +enum _pmerrno_t _alpm_set_directory_option(const char *value, char **storage, int must_exist) { struct stat st; @@ -322,19 +322,16 @@ int _alpm_set_directory_option(const char *value, path = value; if(!path) { - pm_errno = PM_ERR_WRONG_ARGS; - return -1; + return PM_ERR_WRONG_ARGS; } if(must_exist) { if(stat(path, &st) == -1 || !S_ISDIR(st.st_mode)) { - pm_errno = PM_ERR_NOT_A_DIR; - return -1; + return PM_ERR_NOT_A_DIR; } real = calloc(PATH_MAX + 1, sizeof(char)); if(!realpath(path, real)) { free(real); - pm_errno = PM_ERR_NOT_A_DIR; - return -1; + return PM_ERR_NOT_A_DIR; } path = real; } @@ -347,39 +344,6 @@ int _alpm_set_directory_option(const char *value, return 0; } -int SYMEXPORT alpm_option_set_root(const char *root) -{ - ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); - - if(_alpm_set_directory_option(root, &(handle->root), 1)) { - return -1; - } - _alpm_log(PM_LOG_DEBUG, "option 'root' = %s\n", handle->root); - return 0; -} - -int SYMEXPORT alpm_option_set_dbpath(const char *dbpath) -{ - const char *lf = "db.lck"; - size_t lockfilelen; - - ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); - - if(_alpm_set_directory_option(dbpath, &(handle->dbpath), 1)) { - return -1; - } - _alpm_log(PM_LOG_DEBUG, "option 'dbpath' = %s\n", handle->dbpath); - - if(handle->lockfile) { - FREE(handle->lockfile); - } - lockfilelen = strlen(handle->dbpath) + strlen(lf) + 1; - handle->lockfile = calloc(lockfilelen, sizeof(char)); - snprintf(handle->lockfile, lockfilelen, "%s%s", handle->dbpath, lf); - _alpm_log(PM_LOG_DEBUG, "option 'lockfile' = %s\n", handle->lockfile); - return 0; -} - int SYMEXPORT alpm_option_add_cachedir(const char *cachedir) { char *newcachedir; diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h index b72c9b0..ecfefcc 100644 --- a/lib/libalpm/handle.h +++ b/lib/libalpm/handle.h @@ -75,7 +75,8 @@ struct __pmhandle_t { pmhandle_t *_alpm_handle_new(void); void _alpm_handle_free(pmhandle_t *handle); -int _alpm_set_directory_option(const char *value, char **storage, int must_exist); +enum _pmerrno_t _alpm_set_directory_option(const char *value, + char **storage, int must_exist); #endif /* _ALPM_HANDLE_H */ -- 1.7.5.2
Signed-off-by: Dan McGee <dan@archlinux.org> --- src/util/cleanupdelta.c | 14 ++++++++------ src/util/pactree.c | 23 +++++++---------------- src/util/testdb.c | 17 ++++++++--------- src/util/testpkg.c | 11 +++++++---- 4 files changed, 30 insertions(+), 35 deletions(-) diff --git a/src/util/cleanupdelta.c b/src/util/cleanupdelta.c index ae36d2a..9247c2c 100644 --- a/src/util/cleanupdelta.c +++ b/src/util/cleanupdelta.c @@ -29,9 +29,11 @@ #define BASENAME "cleanupdelta" +pmhandle_t *handle = NULL; + static void cleanup(int signum) { - if(alpm_release() == -1) { - fprintf(stderr, "error releasing alpm: %s\n", alpm_strerrorlast()); + if(handle && alpm_release(handle) == -1) { + fprintf(stderr, "error releasing alpm\n"); } exit(signum); @@ -94,6 +96,7 @@ static void usage(void) { int main(int argc, char *argv[]) { const char *dbpath = DBPATH; + enum _pmerrno_t err; int a = 1; alpm_list_t *dbnames = NULL; @@ -117,16 +120,15 @@ int main(int argc, char *argv[]) usage(); } - if(alpm_initialize() == -1) { - fprintf(stderr, "cannot initialize alpm: %s\n", alpm_strerrorlast()); + handle = alpm_initialize(ROOTDIR, dbpath, &err); + if(!handle) { + fprintf(stderr, "cannot initialize alpm: %s\n", alpm_strerror(err)); return 1; } /* let us get log messages from libalpm */ alpm_option_set_logcb(output_cb); - alpm_option_set_dbpath(dbpath); - checkdbs(dbpath,dbnames); alpm_list_free(dbnames); diff --git a/src/util/pactree.c b/src/util/pactree.c index e9a2816..23e0562 100644 --- a/src/util/pactree.c +++ b/src/util/pactree.c @@ -74,6 +74,7 @@ static struct color_choices no_color = { }; /* globals */ +pmhandle_t *handle = NULL; pmdb_t *db_local; alpm_list_t *walked = NULL; alpm_list_t *provisions = NULL; @@ -87,23 +88,13 @@ int reverse = 0; int unique = 0; const char *dbpath = DBPATH; -static int alpm_local_init(void) +static int alpm_local_init() { - int ret; - - ret = alpm_initialize(); - if(ret != 0) { - return ret; - } + enum _pmerrno_t err; - ret = alpm_option_set_root(ROOTDIR); - if(ret != 0) { - return ret; - } - - ret = alpm_option_set_dbpath(dbpath); - if(ret != 0) { - return ret; + handle = alpm_initialize(ROOTDIR, dbpath, &err); + if(!handle) { + return -1; } db_local = alpm_option_get_localdb(); @@ -196,7 +187,7 @@ static void cleanup(void) { alpm_list_free(walked); alpm_list_free(provisions); - alpm_release(); + alpm_release(handle); } /* pkg provides provision */ diff --git a/src/util/testdb.c b/src/util/testdb.c index d8a2fb4..06c01f8 100644 --- a/src/util/testdb.c +++ b/src/util/testdb.c @@ -31,9 +31,11 @@ #define BASENAME "testdb" +pmhandle_t *handle = NULL; + static void cleanup(int signum) { - if(alpm_release() == -1) { - fprintf(stderr, "error releasing alpm: %s\n", alpm_strerrorlast()); + if(handle && alpm_release(handle) == -1) { + fprintf(stderr, "error releasing alpm\n"); } exit(signum); @@ -184,6 +186,7 @@ static void usage(void) { int main(int argc, char *argv[]) { int ret = 0; + enum _pmerrno_t err; const char *dbpath = DBPATH; int a = 1; alpm_list_t *dbnames = NULL; @@ -204,19 +207,15 @@ int main(int argc, char *argv[]) a++; } - if(alpm_initialize() == -1) { - fprintf(stderr, "cannot initialize alpm: %s\n", alpm_strerrorlast()); + handle = alpm_initialize(ROOTDIR, dbpath, &err); + if(!handle) { + fprintf(stderr, "cannot initialize alpm: %s\n", alpm_strerror(err)); return EXIT_FAILURE; } /* let us get log messages from libalpm */ alpm_option_set_logcb(output_cb); - if(alpm_option_set_dbpath(dbpath) != 0) { - fprintf(stderr, "cannot set dbpath: %s\n", alpm_strerrorlast()); - return EXIT_FAILURE; - } - if(!dbnames) { ret = check_localdb(); } else { diff --git a/src/util/testpkg.c b/src/util/testpkg.c index ad6ec30..20920ff 100644 --- a/src/util/testpkg.c +++ b/src/util/testpkg.c @@ -40,6 +40,8 @@ static void output_cb(pmloglevel_t level, const char *fmt, va_list args) int main(int argc, char *argv[]) { int retval = 1; /* default = false */ + pmhandle_t *handle; + enum _pmerrno_t err; pmpkg_t *pkg = NULL; if(argc != 2) { @@ -47,8 +49,9 @@ int main(int argc, char *argv[]) return 1; } - if(alpm_initialize() == -1) { - fprintf(stderr, "cannot initialize alpm: %s\n", alpm_strerrorlast()); + handle = alpm_initialize(ROOTDIR, DBPATH, &err); + if(!handle) { + fprintf(stderr, "cannot initialize alpm: %s\n", alpm_strerror(err)); return 1; } @@ -76,8 +79,8 @@ int main(int argc, char *argv[]) retval = 0; } - if(alpm_release() == -1) { - fprintf(stderr, "error releasing alpm: %s\n", alpm_strerrorlast()); + if(alpm_release(handle) == -1) { + fprintf(stderr, "error releasing alpm\n"); } return retval; -- 1.7.5.2
On 04/06/11 08:41, Dan McGee wrote:
Signed-off-by: Dan McGee<dan@archlinux.org> --- src/util/cleanupdelta.c | 14 ++++++++------ src/util/pactree.c | 23 +++++++---------------- src/util/testdb.c | 17 ++++++++--------- src/util/testpkg.c | 11 +++++++---- 4 files changed, 30 insertions(+), 35 deletions(-)
<snip>
diff --git a/src/util/pactree.c b/src/util/pactree.c index e9a2816..23e0562 100644 --- a/src/util/pactree.c +++ b/src/util/pactree.c @@ -74,6 +74,7 @@ static struct color_choices no_color = { };
/* globals */ +pmhandle_t *handle = NULL; pmdb_t *db_local; alpm_list_t *walked = NULL; alpm_list_t *provisions = NULL; @@ -87,23 +88,13 @@ int reverse = 0; int unique = 0; const char *dbpath = DBPATH;
-static int alpm_local_init(void) +static int alpm_local_init()
pactree.c:91:12: error: function declaration isn’t a prototype [-Werror=strict-prototypes]
On Fri, Jun 3, 2011 at 6:05 PM, Allan McRae <allan@archlinux.org> wrote:
On 04/06/11 08:41, Dan McGee wrote:
Signed-off-by: Dan McGee<dan@archlinux.org> --- src/util/cleanupdelta.c | 14 ++++++++------ src/util/pactree.c | 23 +++++++---------------- src/util/testdb.c | 17 ++++++++--------- src/util/testpkg.c | 11 +++++++---- 4 files changed, 30 insertions(+), 35 deletions(-)
<snip>
diff --git a/src/util/pactree.c b/src/util/pactree.c index e9a2816..23e0562 100644 --- a/src/util/pactree.c +++ b/src/util/pactree.c @@ -74,6 +74,7 @@ static struct color_choices no_color = { };
/* globals */ +pmhandle_t *handle = NULL; pmdb_t *db_local; alpm_list_t *walked = NULL; alpm_list_t *provisions = NULL; @@ -87,23 +88,13 @@ int reverse = 0; int unique = 0; const char *dbpath = DBPATH;
-static int alpm_local_init(void) +static int alpm_local_init()
pactree.c:91:12: error: function declaration isn’t a prototype [-Werror=strict-prototypes]
Fail on my part after some numerous refactoring passes, whoops. I'll fix this up, thanks for noticing! -Dan
Signed-off-by: Dan McGee <dan@archlinux.org> --- src/pacman/conf.c | 205 ++++++++++++++++++++++++++++----------------------- src/pacman/conf.h | 16 ++++- src/pacman/pacman.c | 52 +++---------- 3 files changed, 140 insertions(+), 133 deletions(-) diff --git a/src/pacman/conf.c b/src/pacman/conf.c index 370ec51..b16be04 100644 --- a/src/pacman/conf.c +++ b/src/pacman/conf.c @@ -34,6 +34,7 @@ #include "conf.h" #include "util.h" #include "pacman.h" +#include "callback.h" /* global config variable */ config_t *config = NULL; @@ -50,8 +51,8 @@ config_t *config_new(void) /* defaults which may get overridden later */ newconfig->op = PM_OP_MAIN; newconfig->logmask = PM_LOG_ERROR | PM_LOG_WARNING; - /* CONFFILE is defined at compile-time */ newconfig->configfile = strdup(CONFFILE); + newconfig->sigverify = PM_PGP_VERIFY_UNKNOWN; return newconfig; } @@ -64,12 +65,19 @@ int config_free(config_t *oldconfig) FREELIST(oldconfig->holdpkg); FREELIST(oldconfig->syncfirst); + FREELIST(oldconfig->ignorepkg); + FREELIST(oldconfig->ignoregrp); + FREELIST(oldconfig->noupgrade); + FREELIST(oldconfig->noextract); free(oldconfig->configfile); free(oldconfig->rootdir); free(oldconfig->dbpath); free(oldconfig->logfile); + free(oldconfig->gpgdir); + FREELIST(oldconfig->cachedirs); free(oldconfig->xfercommand); free(oldconfig->print_format); + free(oldconfig->arch); free(oldconfig); oldconfig = NULL; @@ -206,12 +214,12 @@ int config_set_arch(const char *arch) if(strcmp(arch, "auto") == 0) { struct utsname un; uname(&un); - pm_printf(PM_LOG_DEBUG, "config: Architecture: %s\n", un.machine); - return alpm_option_set_arch(un.machine); + config->arch = strdup(un.machine); } else { - pm_printf(PM_LOG_DEBUG, "config: Architecture: %s\n", arch); - return alpm_option_set_arch(arch); + config->arch = strdup(arch); } + pm_printf(PM_LOG_DEBUG, "config: arch: %s\n", config->arch); + return 0; } static pgp_verify_t option_verifysig(const char *value) @@ -230,27 +238,19 @@ static pgp_verify_t option_verifysig(const char *value) return level; } -/* helper for being used with setrepeatingoption */ -static int option_add_holdpkg(const char *name) { - config->holdpkg = alpm_list_add(config->holdpkg, strdup(name)); - return 0; -} - -/* helper for being used with setrepeatingoption */ -static int option_add_syncfirst(const char *name) { - config->syncfirst = alpm_list_add(config->syncfirst, strdup(name)); - return 0; -} - -/* helper for being used with setrepeatingoption */ -static int option_add_cleanmethod(const char *value) { - if(strcmp(value, "KeepInstalled") == 0) { - config->cleanmethod |= PM_CLEAN_KEEPINST; - } else if(strcmp(value, "KeepCurrent") == 0) { - config->cleanmethod |= PM_CLEAN_KEEPCUR; - } else { - pm_printf(PM_LOG_ERROR, _("invalid value for 'CleanMethod' : '%s'\n"), - value); +static int process_cleanmethods(alpm_list_t *values) { + alpm_list_t *i; + for(i = values; i; i = alpm_list_next(i)) { + const char *value = i->data; + if(strcmp(value, "KeepInstalled") == 0) { + config->cleanmethod |= PM_CLEAN_KEEPINST; + } else if(strcmp(value, "KeepCurrent") == 0) { + config->cleanmethod |= PM_CLEAN_KEEPCUR; + } else { + pm_printf(PM_LOG_ERROR, _("invalid value for 'CleanMethod' : '%s'\n"), + value); + return 1; + } } return 0; } @@ -260,21 +260,21 @@ static int option_add_cleanmethod(const char *value) { * the exact same thing and duplicated code. * @param ptr a pointer to the start of the multiple options * @param option the string (friendly) name of the option, used for messages - * @param optionfunc a function pointer to an alpm_option_add_* function + * @param list the list to add the option to */ static void setrepeatingoption(char *ptr, const char *option, - int (*optionfunc)(const char *)) + alpm_list_t **list) { char *q; while((q = strchr(ptr, ' '))) { *q = '\0'; - (*optionfunc)(ptr); + *list = alpm_list_add(*list, strdup(ptr)); pm_printf(PM_LOG_DEBUG, "config: %s: %s\n", option, ptr); ptr = q; ptr++; } - (*optionfunc)(ptr); + *list = alpm_list_add(*list, strdup(ptr)); pm_printf(PM_LOG_DEBUG, "config: %s: %s\n", option, ptr); } @@ -284,7 +284,7 @@ static int _parse_options(const char *key, char *value, if(value == NULL) { /* options without settings */ if(strcmp(key, "UseSyslog") == 0) { - alpm_option_set_usesyslog(1); + config->usesyslog = 1; pm_printf(PM_LOG_DEBUG, "config: usesyslog\n"); } else if(strcmp(key, "ILoveCandy") == 0) { config->chomp = 1; @@ -293,13 +293,13 @@ static int _parse_options(const char *key, char *value, config->verbosepkglists = 1; pm_printf(PM_LOG_DEBUG, "config: verbosepkglists\n"); } else if(strcmp(key, "UseDelta") == 0) { - alpm_option_set_usedelta(1); + config->usedelta = 1; pm_printf(PM_LOG_DEBUG, "config: usedelta\n"); } else if(strcmp(key, "TotalDownload") == 0) { config->totaldownload = 1; pm_printf(PM_LOG_DEBUG, "config: totaldownload\n"); } else if(strcmp(key, "CheckSpace") == 0) { - alpm_option_set_checkspace(1); + config->checkspace = 1; } else { pm_printf(PM_LOG_WARNING, _("config file %s, line %d: directive '%s' in section '%s' not recognized.\n"), @@ -308,19 +308,21 @@ static int _parse_options(const char *key, char *value, } else { /* options with settings */ if(strcmp(key, "NoUpgrade") == 0) { - setrepeatingoption(value, "NoUpgrade", alpm_option_add_noupgrade); + setrepeatingoption(value, "NoUpgrade", &(config->noupgrade)); } else if(strcmp(key, "NoExtract") == 0) { - setrepeatingoption(value, "NoExtract", alpm_option_add_noextract); + setrepeatingoption(value, "NoExtract", &(config->noextract)); } else if(strcmp(key, "IgnorePkg") == 0) { - setrepeatingoption(value, "IgnorePkg", alpm_option_add_ignorepkg); + setrepeatingoption(value, "IgnorePkg", &(config->ignorepkg)); } else if(strcmp(key, "IgnoreGroup") == 0) { - setrepeatingoption(value, "IgnoreGroup", alpm_option_add_ignoregrp); + setrepeatingoption(value, "IgnoreGroup", &(config->ignoregrp)); } else if(strcmp(key, "HoldPkg") == 0) { - setrepeatingoption(value, "HoldPkg", option_add_holdpkg); + setrepeatingoption(value, "HoldPkg", &(config->holdpkg)); } else if(strcmp(key, "SyncFirst") == 0) { - setrepeatingoption(value, "SyncFirst", option_add_syncfirst); + setrepeatingoption(value, "SyncFirst", &(config->syncfirst)); + } else if(strcmp(key, "CacheDir") == 0) { + setrepeatingoption(value, "CacheDir", &(config->cachedirs)); } else if(strcmp(key, "Architecture") == 0) { - if(!alpm_option_get_arch()) { + if(!config->arch) { config_set_arch(value); } } else if(strcmp(key, "DBPath") == 0) { @@ -329,13 +331,6 @@ static int _parse_options(const char *key, char *value, config->dbpath = strdup(value); pm_printf(PM_LOG_DEBUG, "config: dbpath: %s\n", value); } - } else if(strcmp(key, "CacheDir") == 0) { - if(alpm_option_add_cachedir(value) != 0) { - pm_printf(PM_LOG_ERROR, _("problem adding cachedir '%s' (%s)\n"), - value, alpm_strerrorlast()); - return 1; - } - pm_printf(PM_LOG_DEBUG, "config: cachedir: %s\n", value); } else if(strcmp(key, "RootDir") == 0) { /* don't overwrite a path specified on the command line */ if(!config->rootdir) { @@ -354,14 +349,19 @@ static int _parse_options(const char *key, char *value, } } else if(strcmp(key, "XferCommand") == 0) { config->xfercommand = strdup(value); - alpm_option_set_fetchcb(download_with_xfercommand); pm_printf(PM_LOG_DEBUG, "config: xfercommand: %s\n", value); } else if(strcmp(key, "CleanMethod") == 0) { - setrepeatingoption(value, "CleanMethod", option_add_cleanmethod); + alpm_list_t *methods = NULL; + setrepeatingoption(value, "CleanMethod", &methods); + if(process_cleanmethods(methods)) { + FREELIST(methods); + return 1; + } + FREELIST(methods); } else if(strcmp(key, "VerifySig") == 0) { pgp_verify_t level = option_verifysig(value); if(level != PM_PGP_VERIFY_UNKNOWN) { - alpm_option_set_default_sigverify(level); + config->sigverify = level; } else { pm_printf(PM_LOG_ERROR, _("config file %s, line %d: directive '%s' has invalid value '%s'\n"), @@ -384,7 +384,7 @@ static int _add_mirror(pmdb_t *db, char *value) /* let's attempt a replacement for the current repo */ char *temp = strreplace(value, "$repo", dbname); /* let's attempt a replacement for the arch */ - const char *arch = alpm_option_get_arch(); + const char *arch = config->arch; char *server; if(arch) { server = strreplace(temp, "$arch", arch); @@ -411,73 +411,97 @@ static int _add_mirror(pmdb_t *db, char *value) return 0; } -/** Sets all libalpm required paths in one go. Called after the command line +/** Sets up libalpm global stuff in one go. Called after the command line * and inital config file parsing. Once this is complete, we can see if any * paths were defined. If a rootdir was defined and nothing else, we want all * of our paths to live under the rootdir that was specified. Safe to call * multiple times (will only do anything the first time). */ -static int setlibpaths(void) +static int setup_libalpm(void) { int ret = 0; + enum _pmerrno_t err; + + pm_printf(PM_LOG_DEBUG, "setup_libalpm called\n"); - pm_printf(PM_LOG_DEBUG, "setlibpaths() called\n"); /* Configure root path first. If it is set and dbpath/logfile were not * set, then set those as well to reside under the root. */ if(config->rootdir) { char path[PATH_MAX]; - ret = alpm_option_set_root(config->rootdir); - if(ret != 0) { - pm_printf(PM_LOG_ERROR, _("problem setting rootdir '%s' (%s)\n"), - config->rootdir, alpm_strerrorlast()); - return ret; - } if(!config->dbpath) { - /* omit leading slash from our static DBPATH, root handles it */ - snprintf(path, PATH_MAX, "%s%s", alpm_option_get_root(), DBPATH + 1); + snprintf(path, PATH_MAX, "%s/%s", config->rootdir, DBPATH + 1); config->dbpath = strdup(path); } if(!config->logfile) { - /* omit leading slash from our static LOGFILE path, root handles it */ - snprintf(path, PATH_MAX, "%s%s", alpm_option_get_root(), LOGFILE + 1); + snprintf(path, PATH_MAX, "%s/%s", config->rootdir, LOGFILE + 1); config->logfile = strdup(path); } - } - /* Set other paths if they were configured. Note that unless rootdir - * was left undefined, these two paths (dbpath and logfile) will have - * been set locally above, so the if cases below will now trigger. */ - if(config->dbpath) { - ret = alpm_option_set_dbpath(config->dbpath); - if(ret != 0) { - pm_printf(PM_LOG_ERROR, _("problem setting dbpath '%s' (%s)\n"), - config->dbpath, alpm_strerrorlast()); - return ret; + } else { + config->rootdir = strdup(ROOTDIR); + if(!config->dbpath) { + config->dbpath = strdup(DBPATH); } } - if(config->logfile) { - ret = alpm_option_set_logfile(config->logfile); - if(ret != 0) { - pm_printf(PM_LOG_ERROR, _("problem setting logfile '%s' (%s)\n"), - config->logfile, alpm_strerrorlast()); - return ret; - } + + /* initialize library */ + config->handle = alpm_initialize(config->rootdir, config->dbpath, &err); + if(!config->handle) { + pm_printf(PM_LOG_ERROR, _("failed to initialize alpm library (%s)\n"), + alpm_strerror(err)); + return -1; + } + + alpm_option_set_logcb(cb_log); + alpm_option_set_dlcb(cb_dl_progress); + + config->logfile = config->logfile ? config->logfile : strdup(LOGFILE); + ret = alpm_option_set_logfile(config->logfile); + if(ret != 0) { + pm_printf(PM_LOG_ERROR, _("problem setting logfile '%s' (%s)\n"), + config->logfile, alpm_strerrorlast()); + return ret; } /* Set GnuPG's home directory. This is not relative to rootdir, even if * rootdir is defined. Reasoning: gpgdir contains configuration data. */ - if(config->gpgdir) { - ret = alpm_option_set_signaturedir(config->gpgdir); - if(ret != 0) { - pm_printf(PM_LOG_ERROR, _("problem setting gpgdir '%s' (%s)\n"), - config->gpgdir, alpm_strerrorlast()); - return ret; - } + config->gpgdir = config->gpgdir ? config->gpgdir : strdup(GPGDIR); + ret = alpm_option_set_signaturedir(config->gpgdir); + if(ret != 0) { + pm_printf(PM_LOG_ERROR, _("problem setting gpgdir '%s' (%s)\n"), + config->gpgdir, alpm_strerrorlast()); + return ret; } /* add a default cachedir if one wasn't specified */ - if(alpm_option_get_cachedirs() == NULL) { + if(config->cachedirs == NULL) { alpm_option_add_cachedir(CACHEDIR); + } else { + alpm_option_set_cachedirs(config->cachedirs); + } + + if(config->sigverify != PM_PGP_VERIFY_UNKNOWN) { + alpm_option_set_default_sigverify(config->sigverify); + } + + if(config->xfercommand) { + alpm_option_set_fetchcb(download_with_xfercommand); } + + if(config->totaldownload) { + alpm_option_set_totaldlcb(cb_dl_total); + } + + alpm_option_set_arch(config->arch); + alpm_option_set_checkspace(config->checkspace); + alpm_option_set_usesyslog(config->usesyslog); + alpm_option_set_usedelta(config->usedelta); + alpm_option_set_default_sigverify(config->sigverify); + + alpm_option_set_ignorepkgs(config->ignorepkg); + alpm_option_set_ignoregrps(config->ignoregrp); + alpm_option_set_noupgrades(config->noupgrade); + alpm_option_set_noextracts(config->noextract); + return 0; } @@ -682,8 +706,7 @@ int parseconfig(const char *file) return ret; } free(section); - /* call setlibpaths here to ensure we have called it at least once */ - if((ret = setlibpaths())) { + if((ret = setup_libalpm())) { return ret; } /* second pass, repo section parsing */ diff --git a/src/pacman/conf.h b/src/pacman/conf.h index 76c76cf..4c44bfd 100644 --- a/src/pacman/conf.h +++ b/src/pacman/conf.h @@ -32,6 +32,10 @@ typedef struct __config_t { unsigned short noprogressbar; unsigned short logmask; unsigned short print; + unsigned short checkspace; + unsigned short usesyslog; + unsigned short usedelta; + char *arch; char *print_format; /* unfortunately, we have to keep track of paths both here and in the library * because they can come from both the command line or config file, and we @@ -41,7 +45,7 @@ typedef struct __config_t { char *dbpath; char *logfile; char *gpgdir; - /* TODO how to handle cachedirs? */ + alpm_list_t *cachedirs; unsigned short op_q_isfile; unsigned short op_q_info; @@ -64,9 +68,10 @@ typedef struct __config_t { unsigned short op_s_upgrade; unsigned short group; - pmtransflag_t flags; unsigned short noask; unsigned int ask; + pmtransflag_t flags; + pgp_verify_t sigverify; /* conf file options */ /* I Love Candy! */ @@ -80,7 +85,14 @@ typedef struct __config_t { unsigned short cleanmethod; alpm_list_t *holdpkg; alpm_list_t *syncfirst; + alpm_list_t *ignorepkg; + alpm_list_t *ignoregrp; + alpm_list_t *noupgrade; + alpm_list_t *noextract; char *xfercommand; + + /* our connection to libalpm */ + pmhandle_t *handle; } config_t; /* Operations */ diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index 8458c97..4b54eb3 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -50,7 +50,6 @@ /* pacman */ #include "pacman.h" #include "util.h" -#include "callback.h" #include "conf.h" /* list of targets specified on command line */ @@ -264,8 +263,8 @@ static void setuseragent(void) */ static void cleanup(int ret) { /* free alpm library resources */ - if(alpm_release() == -1) { - pm_printf(PM_LOG_ERROR, "%s\n", alpm_strerrorlast()); + if(alpm_release(config->handle) == -1) { + pm_printf(PM_LOG_ERROR, "error releasing alpm library\n"); } /* free memory */ @@ -322,18 +321,16 @@ static void handler(int signum) #define check_optarg() if(!optarg) { return 1; } -typedef int (*fn_add) (const char *s); - -static int parsearg_util_addlist(fn_add fn) +static int parsearg_util_addlist(alpm_list_t **list) { - alpm_list_t *list = NULL, *item = NULL; /* lists for splitting strings */ + alpm_list_t *split, *item; check_optarg(); - list = strsplit(optarg, ','); - for(item = list; item; item = alpm_list_next(item)) { - fn((char *)alpm_list_getdata(item)); + split = strsplit(optarg, ','); + for(item = split; item; item = alpm_list_next(item)) { + *list = alpm_list_add(*list, item->data); } - FREELIST(list); + alpm_list_free(split); return 0; } @@ -385,7 +382,7 @@ static int parsearg_global(int opt) switch(opt) { case OP_ARCH: check_optarg(); - config_set_arch(optarg); + config_set_arch(strdup(optarg)); break; case OP_ASK: check_optarg(); @@ -394,11 +391,7 @@ static int parsearg_global(int opt) break; case OP_CACHEDIR: check_optarg(); - if(alpm_option_add_cachedir(optarg) != 0) { - pm_printf(PM_LOG_ERROR, _("problem adding cachedir '%s' (%s)\n"), - optarg, alpm_strerrorlast()); - return 1; - } + config->cachedirs = alpm_list_add(config->cachedirs, strdup(optarg)); break; case OP_CONFIG: check_optarg(); @@ -535,10 +528,10 @@ static int parsearg_upgrade(int opt) case OP_ASDEPS: config->flags |= PM_TRANS_FLAG_ALLDEPS; break; case OP_ASEXPLICIT: config->flags |= PM_TRANS_FLAG_ALLEXPLICIT; break; case OP_IGNORE: - parsearg_util_addlist(alpm_option_add_ignorepkg); + parsearg_util_addlist(&(config->ignorepkg)); break; case OP_IGNOREGROUP: - parsearg_util_addlist(alpm_option_add_ignoregrp); + parsearg_util_addlist(&(config->ignoregrp)); break; default: return 1; } @@ -800,22 +793,6 @@ int main(int argc, char *argv[]) config->noprogressbar = 1; } - /* initialize library */ - if(alpm_initialize() == -1) { - pm_printf(PM_LOG_ERROR, _("failed to initialize alpm library (%s)\n"), - alpm_strerrorlast()); - cleanup(EXIT_FAILURE); - } - - /* Setup logging as soon as possible, to print out maximum debugging info */ - alpm_option_set_logcb(cb_log); - alpm_option_set_dlcb(cb_dl_progress); - /* define paths to reasonable defaults */ - alpm_option_set_root(ROOTDIR); - alpm_option_set_dbpath(DBPATH); - alpm_option_set_signaturedir(GPGDIR); - alpm_option_set_logfile(LOGFILE); - /* Priority of options: * 1. command line * 2. config file @@ -874,11 +851,6 @@ int main(int argc, char *argv[]) cleanup(ret); } - /* set TotalDownload callback if option enabled */ - if(config->totaldownload) { - alpm_option_set_totaldlcb(cb_dl_total); - } - /* noask is meant to be non-interactive */ if(config->noask) { config->noconfirm = 1; -- 1.7.5.2
participants (3)
-
Allan McRae
-
Dan McGee
-
Dan McGee