[pacman-dev] [PATCH 2/6] Add helper methods for setting directory options

Dan McGee dan at archlinux.org
Fri Jun 3 18:40:58 EDT 2011


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 at 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



More information about the pacman-dev mailing list