summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2007-06-04 14:50:16 -0400
committerDan McGee <dan@archlinux.org>2007-06-09 13:03:25 -0400
commit35a794c2ed4da7da44d3a04794fc90615e7c52e7 (patch)
tree75fd2667a69867795f6a32cc9bb1dc7d505e2004
parentb6f3fe6957d0206485eac98fb2120578b75d0058 (diff)
downloadpacman-35a794c2ed4da7da44d3a04794fc90615e7c52e7.tar.xz
Allow multiple CacheDirs to be specified
This should hopefully allow multiple cache dirs to be specified in pacman.conf and/or on the command line, and allow pacman to test each one for the package file. The first one found to be writeable is used as the download cache. Signed-off-by: Dan McGee <dan@archlinux.org>
-rw-r--r--lib/libalpm/alpm.h5
-rw-r--r--lib/libalpm/handle.c24
-rw-r--r--lib/libalpm/handle.h2
-rw-r--r--lib/libalpm/package.c27
-rw-r--r--lib/libalpm/sync.c101
-rw-r--r--src/pacman/pacman.c14
-rw-r--r--src/pacman/sync.c4
7 files changed, 126 insertions, 51 deletions
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index 9f029b2e..d4c584f8 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -97,8 +97,9 @@ void alpm_option_set_root(const char *root);
const char *alpm_option_get_dbpath();
void alpm_option_set_dbpath(const char *dbpath);
-const char *alpm_option_get_cachedir();
-void alpm_option_set_cachedir(const char *cachedir);
+alpm_list_t *alpm_option_get_cachedirs();
+void alpm_option_add_cachedir(const char *cachedir);
+void alpm_option_set_cachedirs(alpm_list_t *cachedirs);
const char *alpm_option_get_logfile();
void alpm_option_set_logfile(const char *logfile);
diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c
index ae20ef11..6f9e3330 100644
--- a/lib/libalpm/handle.c
+++ b/lib/libalpm/handle.c
@@ -80,7 +80,7 @@ pmhandle_t *_alpm_handle_new()
#endif
handle->root = NULL;
handle->dbpath = NULL;
- handle->cachedir = NULL;
+ handle->cachedirs = NULL;
handle->lockfile = NULL;
handle->logfile = NULL;
@@ -109,7 +109,7 @@ void _alpm_handle_free(pmhandle_t *handle)
_alpm_trans_free(handle->trans);
FREE(handle->root);
FREE(handle->dbpath);
- FREE(handle->cachedir);
+ FREELIST(handle->cachedirs);
FREE(handle->logfile);
FREE(handle->lockfile);
FREE(handle->xfercommand);
@@ -125,7 +125,7 @@ alpm_cb_log SYMEXPORT alpm_option_get_logcb() { return (handle ? handle->logcb :
alpm_cb_download SYMEXPORT alpm_option_get_dlcb() { return (handle ? handle->dlcb : NULL); }
const char SYMEXPORT *alpm_option_get_root() { return handle->root; }
const char SYMEXPORT *alpm_option_get_dbpath() { return handle->dbpath; }
-const char SYMEXPORT *alpm_option_get_cachedir() { return handle->cachedir; }
+alpm_list_t SYMEXPORT *alpm_option_get_cachedirs() { return handle->cachedirs; }
const char SYMEXPORT *alpm_option_get_logfile() { return handle->logfile; }
const char SYMEXPORT *alpm_option_get_lockfile() { return handle->lockfile; }
unsigned short SYMEXPORT alpm_option_get_usesyslog() { return handle->usesyslog; }
@@ -193,23 +193,31 @@ void SYMEXPORT alpm_option_set_dbpath(const char *dbpath)
}
}
-void SYMEXPORT alpm_option_set_cachedir(const char *cachedir)
+void SYMEXPORT alpm_option_add_cachedir(const char *cachedir)
{
ALPM_LOG_FUNC;
- if(handle->cachedir) FREE(handle->cachedir);
if(cachedir) {
+ char *newcachedir;
/* verify cachedir ends in a '/' */
int cachedirlen = strlen(cachedir);
if(cachedir[cachedirlen-1] != '/') {
cachedirlen += 1;
}
- handle->cachedir = calloc(cachedirlen+1, sizeof(char));
- strncpy(handle->cachedir, cachedir, cachedirlen);
- handle->cachedir[cachedirlen-1] = '/';
+ newcachedir = calloc(cachedirlen + 1, sizeof(char));
+ strncpy(newcachedir, cachedir, cachedirlen);
+ newcachedir[cachedirlen-1] = '/';
+ handle->cachedirs = alpm_list_add(handle->cachedirs, newcachedir);
+ _alpm_log(PM_LOG_DEBUG, _("option 'cachedir' = %s"), newcachedir);
}
}
+void SYMEXPORT alpm_option_set_cachedirs(alpm_list_t *cachedirs)
+{
+ if(handle->cachedirs) FREELIST(handle->cachedirs);
+ if(cachedirs) handle->cachedirs = cachedirs;
+}
+
void SYMEXPORT alpm_option_set_logfile(const char *logfile)
{
ALPM_LOG_FUNC;
diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h
index 8e6003c0..b0e80338 100644
--- a/lib/libalpm/handle.h
+++ b/lib/libalpm/handle.h
@@ -50,7 +50,7 @@ typedef struct _pmhandle_t {
alpm_cb_download dlcb; /* Download callback function */
char *root; /* Root path, default '/' */
char *dbpath; /* Base path to pacman's DBs */
- char *cachedir; /* Base path to pacman's cache */
+ alpm_list_t *cachedirs; /* Paths to pacman cache directories */
char *logfile; /* Name of the file to log to */ /*TODO is this used?*/
char *lockfile; /* Name of the lock file */
unsigned short usesyslog; /* Use syslog instead of logfile? */ /* TODO move to frontend */
diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c
index e25ecbe4..16166691 100644
--- a/lib/libalpm/package.c
+++ b/lib/libalpm/package.c
@@ -103,7 +103,9 @@ int SYMEXPORT alpm_pkg_free(pmpkg_t *pkg)
int alpm_pkg_checksha1sum(pmpkg_t *pkg)
{
char path[PATH_MAX];
+ struct stat buf;
char *sha1sum = NULL;
+ alpm_list_t *i;
int retval = 0;
ALPM_LOG_FUNC;
@@ -113,8 +115,14 @@ int alpm_pkg_checksha1sum(pmpkg_t *pkg)
ASSERT(pkg->origin == PKG_FROM_CACHE, RET_ERR(PM_ERR_PKG_INVALID, -1));
ASSERT(pkg->data != handle->db_local, RET_ERR(PM_ERR_PKG_INVALID, -1));
- snprintf(path, PATH_MAX, "%s/%s-%s" PKGEXT, handle->cachedir,
- alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg));
+ /* Loop through the cache dirs until we find a matching file */
+ for(i = alpm_option_get_cachedirs(); i; i = alpm_list_next(i)) {
+ snprintf(path, PATH_MAX, "%s%s-%s" PKGEXT, (char*)alpm_list_getdata(i),
+ alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg));
+ if(stat(path, &buf) == 0) {
+ break;
+ }
+ }
sha1sum = alpm_get_sha1sum(path);
if(sha1sum == NULL) {
@@ -146,7 +154,9 @@ int alpm_pkg_checksha1sum(pmpkg_t *pkg)
int alpm_pkg_checkmd5sum(pmpkg_t *pkg)
{
char path[PATH_MAX];
+ struct stat buf;
char *md5sum = NULL;
+ alpm_list_t *i;
int retval = 0;
ALPM_LOG_FUNC;
@@ -156,8 +166,14 @@ int alpm_pkg_checkmd5sum(pmpkg_t *pkg)
ASSERT(pkg->origin == PKG_FROM_CACHE, RET_ERR(PM_ERR_PKG_INVALID, -1));
ASSERT(pkg->data != handle->db_local, RET_ERR(PM_ERR_PKG_INVALID, -1));
- snprintf(path, PATH_MAX, "%s/%s-%s" PKGEXT, handle->cachedir,
- alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg));
+ /* Loop through the cache dirs until we find a matching file */
+ for(i = alpm_option_get_cachedirs(); i; i = alpm_list_next(i)) {
+ snprintf(path, PATH_MAX, "%s%s-%s" PKGEXT, (char*)alpm_list_getdata(i),
+ alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg));
+ if(stat(path, &buf) == 0) {
+ break;
+ }
+ }
md5sum = alpm_get_md5sum(path);
if(md5sum == NULL) {
@@ -182,6 +198,9 @@ int alpm_pkg_checkmd5sum(pmpkg_t *pkg)
return(retval);
}
+
+
+
/** Compare versions.
* @param ver1 first version
* @param ver2 secont version
diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c
index 632e510b..5d9e1e6c 100644
--- a/lib/libalpm/sync.c
+++ b/lib/libalpm/sync.c
@@ -766,8 +766,8 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
alpm_list_t *i, *j, *files = NULL;
pmtrans_t *tr = NULL;
int replaces = 0, retval = 0;
- const char *cachedir;
- int varcache = 1;
+ int validcache = 0;
+ const char *maincachedir = NULL;
ALPM_LOG_FUNC;
@@ -776,8 +776,6 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
trans->state = STATE_DOWNLOADING;
/* group sync records by repository and download */
- cachedir = alpm_option_get_cachedir();
-
for(i = handle->dbs_sync; i; i = i->next) {
pmdb_t *current = i->data;
@@ -795,12 +793,20 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
EVENT(trans, PM_TRANS_EVT_PRINTURI, (char *)alpm_db_get_url(current), (char *)fname);
} else {
struct stat buf;
- snprintf(path, PATH_MAX, "%s/%s", cachedir, fname);
- if(stat(path, &buf)) {
+ int found = 0;
+ /* Loop through the cache dirs until we find a matching file */
+ for(i = alpm_option_get_cachedirs(); i; i = alpm_list_next(i)) {
+ snprintf(path, PATH_MAX, "%s%s", (char*)alpm_list_getdata(i),
+ fname);
+ if(stat(path, &buf) == 0) {
+ found = 1;
+ _alpm_log(PM_LOG_DEBUG, _("found cached pkg: %s"), path);
+ break;
+ }
+ }
+ if(!found) {
/* file is not in the cache dir, so add it to the list */
files = alpm_list_add(files, strdup(fname));
- } else {
- _alpm_log(PM_LOG_DEBUG, _("%s is already in the cache\n"), fname);
}
}
}
@@ -808,24 +814,42 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
if(files) {
struct stat buf;
+ char *cachedir;
EVENT(trans, PM_TRANS_EVT_RETRIEVE_START, current->treename, NULL);
- if(stat(cachedir, &buf)) {
- /* no cache directory.... try creating it */
- _alpm_log(PM_LOG_WARNING, _("no %s cache exists, creating...\n"), cachedir);
- alpm_logaction(_("warning: no %s cache exists, creating..."), cachedir);
- if(_alpm_makepath(cachedir)) {
- /* couldn't mkdir the cache directory, so fall back to /tmp and unlink
- * the package afterwards.
- */
- _alpm_log(PM_LOG_WARNING, _("couldn't create package cache, using /tmp instead\n"));
- alpm_logaction(_("warning: couldn't create package cache, using /tmp instead"));
- alpm_option_set_cachedir("/tmp");
- cachedir = alpm_option_get_cachedir();
- varcache = 0;
+ for(i = alpm_option_get_cachedirs(); i; i = alpm_list_next(i)) {
+ cachedir = alpm_list_getdata(i);
+ if(stat(cachedir, &buf) != 0) {
+ /* cache directory does not exist.... try creating it */
+ _alpm_log(PM_LOG_WARNING, _("no %s cache exists, creating...\n"),
+ cachedir);
+ alpm_logaction(_("warning: no %s cache exists, creating..."),
+ cachedir);
+ if(_alpm_makepath(cachedir) == 0) {
+ _alpm_log(PM_LOG_DEBUG, _("setting main cachedir: %s"), cachedir);
+ maincachedir = cachedir;
+ validcache = 1;
+ break;
+ }
+ } else if(S_ISDIR(buf.st_mode) && (buf.st_mode & S_IWUSR)) {
+ _alpm_log(PM_LOG_DEBUG, _("setting main cachedir: %s"), cachedir);
+ maincachedir = cachedir;
+ validcache = 1;
+ break;
}
}
- if(_alpm_downloadfiles(current->servers, alpm_option_get_cachedir(),
- files)) {
+ if(!validcache) {
+ /* we had no valid cache directories, so fall back to /tmp and
+ * unlink the packages afterwards. */
+ alpm_list_t *oldcachedirs = alpm_option_get_cachedirs();
+ alpm_list_t *cachetmp = alpm_list_add(NULL, strdup("/tmp/"));
+ FREELIST(oldcachedirs);
+ alpm_option_set_cachedirs(cachetmp);
+ _alpm_log(PM_LOG_DEBUG, _("setting main cachedir: %s"), "/tmp/");
+ maincachedir = alpm_list_getdata(cachetmp);
+ _alpm_log(PM_LOG_WARNING, _("couldn't create package cache, using /tmp instead"));
+ alpm_logaction(_("warning: couldn't create package cache, using /tmp instead"));
+ }
+ if(_alpm_downloadfiles(current->servers, maincachedir, files)) {
_alpm_log(PM_LOG_WARNING, _("failed to retrieve some files from %s\n"), current->treename);
RET_ERR(PM_ERR_RETRIEVE, -1);
}
@@ -843,6 +867,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
pmsyncpkg_t *sync = i->data;
pmpkg_t *spkg = sync->pkg;
char str[PATH_MAX];
+ struct stat buf;
const char *pkgname;
char *md5sum1, *md5sum2, *sha1sum1, *sha1sum2;
char *ptr=NULL;
@@ -861,9 +886,19 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
retval = 1;
continue;
}
- snprintf(str, PATH_MAX, "%s%s", alpm_option_get_cachedir(), pkgname);
- md5sum2 = _alpm_MDFile(str);
- sha1sum2 = _alpm_SHAFile(str);
+
+ /* Loop through the cache dirs until we find a matching file */
+ for(j = alpm_option_get_cachedirs(); j; j = alpm_list_next(j)) {
+ snprintf(str, PATH_MAX, "%s%s", (char*)alpm_list_getdata(j), pkgname);
+ if(stat(str, &buf) == 0) {
+ _alpm_log(PM_LOG_DEBUG, _("package found for integrity check: %s"),
+ str);
+ break;
+ }
+ }
+
+ md5sum2 = alpm_get_md5sum(str);
+ sha1sum2 = alpm_get_sha1sum(str);
if(md5sum2 == NULL && sha1sum2 == NULL) {
if((ptr = calloc(512, sizeof(char))) == NULL) {
RET_ERR(PM_ERR_MEMORY, -1);
@@ -884,8 +919,6 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
QUESTION(trans, PM_TRANS_CONV_CORRUPTED_PKG, (char *)pkgname, NULL, NULL, &doremove);
}
if(doremove) {
- char str[PATH_MAX];
- snprintf(str, PATH_MAX, "%s%s", alpm_option_get_cachedir(), pkgname);
unlink(str);
snprintf(ptr, 512, _("archive %s was corrupted (bad MD5 or SHA1 checksum)\n"), pkgname);
} else {
@@ -966,12 +999,18 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
for(i = trans->packages; i; i = i->next) {
pmsyncpkg_t *sync = i->data;
pmpkg_t *spkg = sync->pkg;
-
+ struct stat buf;
const char *fname = NULL;
char str[PATH_MAX];
fname = alpm_pkg_get_filename(spkg);
- snprintf(str, PATH_MAX, "%s%s", alpm_option_get_cachedir(), fname);
+ /* Loop through the cache dirs until we find a matching file */
+ for(j = alpm_option_get_cachedirs(); j; j = alpm_list_next(j)) {
+ snprintf(str, PATH_MAX, "%s%s", (char*)alpm_list_getdata(j), fname);
+ if(stat(str, &buf) == 0) {
+ break;
+ }
+ }
if(_alpm_trans_addtarget(tr, str) == -1) {
goto error;
}
@@ -1041,7 +1080,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
}
}
- if(!varcache && !(trans->flags & PM_TRANS_FLAG_DOWNLOADONLY)) {
+ if(!validcache && !(trans->flags & PM_TRANS_FLAG_DOWNLOADONLY)) {
/* delete packages */
for(i = files; i; i = i->next) {
unlink(i->data);
diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
index 2f0ed790..4aaf1422 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -339,12 +339,13 @@ static int parseargs(int argc, char *argv[])
case 1005: config->flags |= PM_TRANS_FLAG_NOSCRIPTLET; break;
case 1006: config->noask = 1; config->ask = atoi(optarg); break;
case 1007:
+ /* TODO redo this logic- check path somewhere else, delete other cachedirs, etc */
if(stat(optarg, &st) == -1 || !S_ISDIR(st.st_mode)) {
fprintf(stderr, _("error: '%s' is not a valid cache directory\n"),
optarg);
return(1);
}
- alpm_option_set_cachedir(optarg);
+ alpm_option_add_cachedir(optarg);
break;
case 1008:
alpm_option_set_lockfile(optarg);
@@ -616,7 +617,7 @@ static int _parseconfig(const char *file, const char *givensection,
alpm_option_set_dbpath(ptr);
pm_printf(PM_LOG_DEBUG, _("config: dbpath: %s\n"), ptr);
} else if(strcmp(key, "CacheDir") == 0 || strcmp(upperkey, "CACHEDIR") == 0) {
- alpm_option_set_cachedir(ptr);
+ alpm_option_add_cachedir(ptr);
pm_printf(PM_LOG_DEBUG, _("config: cachedir: %s\n"), ptr);
} else if(strcmp(key, "RootDir") == 0 || strcmp(upperkey, "ROOTDIR") == 0) {
alpm_option_set_root(ptr);
@@ -762,10 +763,15 @@ if(0) {
#endif
if(config->verbose > 0) {
+ alpm_list_t *i;
printf("Root : %s\n", alpm_option_get_root());
printf("Conf File : %s\n", config->configfile);
- printf("DBPath : %s\n", alpm_option_get_dbpath());
- printf("CacheDir : %s\n", alpm_option_get_cachedir());
+ printf("DB Path : %s\n", alpm_option_get_dbpath());
+ printf("Cache Dirs: ");
+ for(i = alpm_option_get_cachedirs(); i; i = alpm_list_next(i)) {
+ printf("%s ", (char*)alpm_list_getdata(i));
+ }
+ printf("\n");
printf("Lock File : %s\n", alpm_option_get_lockfile());
printf("Log File : %s\n", alpm_option_get_logfile());
list_display("Targets :", pm_targets);
diff --git a/src/pacman/sync.c b/src/pacman/sync.c
index fa99797c..8d810f83 100644
--- a/src/pacman/sync.c
+++ b/src/pacman/sync.c
@@ -89,7 +89,9 @@ static int split_pkgname(char *target, char *name, char *version)
static int sync_cleancache(int level)
{
- const char *cachedir = alpm_option_get_cachedir();
+ /* TODO for now, just mess with the first cache directory */
+ alpm_list_t* cachedirs = alpm_option_get_cachedirs();
+ const char *cachedir = alpm_list_getdata(cachedirs);
if(level == 1) {
/* incomplete cleanup: we keep latest packages and partial downloads */