diff --git a/lib/libalpm/alpm.c b/lib/libalpm/alpm.c index 2da3432f..55f6ecd1 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 27d04765..62e8702c 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 e94528f9..21b16aa2 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) -{ +static char *canonicalize_path(const char *path) { + char *new_path; + size_t len; + + /* 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 *realroot; - size_t rootlen; + char *real = NULL; + const char *path; - ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); - - 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; } - realroot = calloc(PATH_MAX+1, sizeof(char)); - if(!realpath(root, realroot)) { - FREE(realroot); - pm_errno = PM_ERR_NOT_A_DIR; + if(*storage) { + FREE(*storage); + } + *storage = canonicalize_path(path); + free(real); + 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; } - - /* verify root ends in a '/' */ - rootlen = strlen(realroot); - if(realroot[rootlen-1] != '/') { - rootlen += 1; - } - if(handle->root) { - FREE(handle->root); - } - 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; + + if(_alpm_set_directory_option(dbpath, &(handle->dbpath), 1)) { return -1; } - if(stat(dbpath, &st) == -1 || !S_ISDIR(st.st_mode)) { - pm_errno = PM_ERR_NOT_A_DIR; - 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,16 +392,9 @@ 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; } diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h index 129c8ca4..b72c9b0f 100644 --- a/lib/libalpm/handle.h +++ b/lib/libalpm/handle.h @@ -24,10 +24,7 @@ #include #include "alpm_list.h" -#include "db.h" -#include "log.h" #include "alpm.h" -#include "trans.h" #ifdef HAVE_LIBCURL #include @@ -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 5821bf9f..6f0763d5 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.