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>
This commit is contained in:
Dan McGee 2007-06-04 14:50:16 -04:00
parent b6f3fe6957
commit 35a794c2ed
7 changed files with 126 additions and 51 deletions

View file

@ -97,8 +97,9 @@ void alpm_option_set_root(const char *root);
const char *alpm_option_get_dbpath(); const char *alpm_option_get_dbpath();
void alpm_option_set_dbpath(const char *dbpath); void alpm_option_set_dbpath(const char *dbpath);
const char *alpm_option_get_cachedir(); alpm_list_t *alpm_option_get_cachedirs();
void alpm_option_set_cachedir(const char *cachedir); void alpm_option_add_cachedir(const char *cachedir);
void alpm_option_set_cachedirs(alpm_list_t *cachedirs);
const char *alpm_option_get_logfile(); const char *alpm_option_get_logfile();
void alpm_option_set_logfile(const char *logfile); void alpm_option_set_logfile(const char *logfile);

View file

@ -80,7 +80,7 @@ pmhandle_t *_alpm_handle_new()
#endif #endif
handle->root = NULL; handle->root = NULL;
handle->dbpath = NULL; handle->dbpath = NULL;
handle->cachedir = NULL; handle->cachedirs = NULL;
handle->lockfile = NULL; handle->lockfile = NULL;
handle->logfile = NULL; handle->logfile = NULL;
@ -109,7 +109,7 @@ void _alpm_handle_free(pmhandle_t *handle)
_alpm_trans_free(handle->trans); _alpm_trans_free(handle->trans);
FREE(handle->root); FREE(handle->root);
FREE(handle->dbpath); FREE(handle->dbpath);
FREE(handle->cachedir); FREELIST(handle->cachedirs);
FREE(handle->logfile); FREE(handle->logfile);
FREE(handle->lockfile); FREE(handle->lockfile);
FREE(handle->xfercommand); 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); } 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_root() { return handle->root; }
const char SYMEXPORT *alpm_option_get_dbpath() { return handle->dbpath; } 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_logfile() { return handle->logfile; }
const char SYMEXPORT *alpm_option_get_lockfile() { return handle->lockfile; } const char SYMEXPORT *alpm_option_get_lockfile() { return handle->lockfile; }
unsigned short SYMEXPORT alpm_option_get_usesyslog() { return handle->usesyslog; } 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; ALPM_LOG_FUNC;
if(handle->cachedir) FREE(handle->cachedir);
if(cachedir) { if(cachedir) {
char *newcachedir;
/* verify cachedir ends in a '/' */ /* verify cachedir ends in a '/' */
int cachedirlen = strlen(cachedir); int cachedirlen = strlen(cachedir);
if(cachedir[cachedirlen-1] != '/') { if(cachedir[cachedirlen-1] != '/') {
cachedirlen += 1; cachedirlen += 1;
} }
handle->cachedir = calloc(cachedirlen+1, sizeof(char)); newcachedir = calloc(cachedirlen + 1, sizeof(char));
strncpy(handle->cachedir, cachedir, cachedirlen); strncpy(newcachedir, cachedir, cachedirlen);
handle->cachedir[cachedirlen-1] = '/'; 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) void SYMEXPORT alpm_option_set_logfile(const char *logfile)
{ {
ALPM_LOG_FUNC; ALPM_LOG_FUNC;

View file

@ -50,7 +50,7 @@ typedef struct _pmhandle_t {
alpm_cb_download dlcb; /* Download callback function */ alpm_cb_download dlcb; /* Download callback function */
char *root; /* Root path, default '/' */ char *root; /* Root path, default '/' */
char *dbpath; /* Base path to pacman's DBs */ 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 *logfile; /* Name of the file to log to */ /*TODO is this used?*/
char *lockfile; /* Name of the lock file */ char *lockfile; /* Name of the lock file */
unsigned short usesyslog; /* Use syslog instead of logfile? */ /* TODO move to frontend */ unsigned short usesyslog; /* Use syslog instead of logfile? */ /* TODO move to frontend */

View file

@ -103,7 +103,9 @@ int SYMEXPORT alpm_pkg_free(pmpkg_t *pkg)
int alpm_pkg_checksha1sum(pmpkg_t *pkg) int alpm_pkg_checksha1sum(pmpkg_t *pkg)
{ {
char path[PATH_MAX]; char path[PATH_MAX];
struct stat buf;
char *sha1sum = NULL; char *sha1sum = NULL;
alpm_list_t *i;
int retval = 0; int retval = 0;
ALPM_LOG_FUNC; 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->origin == PKG_FROM_CACHE, RET_ERR(PM_ERR_PKG_INVALID, -1));
ASSERT(pkg->data != handle->db_local, 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, /* Loop through the cache dirs until we find a matching file */
alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg)); 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); sha1sum = alpm_get_sha1sum(path);
if(sha1sum == NULL) { if(sha1sum == NULL) {
@ -146,7 +154,9 @@ int alpm_pkg_checksha1sum(pmpkg_t *pkg)
int alpm_pkg_checkmd5sum(pmpkg_t *pkg) int alpm_pkg_checkmd5sum(pmpkg_t *pkg)
{ {
char path[PATH_MAX]; char path[PATH_MAX];
struct stat buf;
char *md5sum = NULL; char *md5sum = NULL;
alpm_list_t *i;
int retval = 0; int retval = 0;
ALPM_LOG_FUNC; 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->origin == PKG_FROM_CACHE, RET_ERR(PM_ERR_PKG_INVALID, -1));
ASSERT(pkg->data != handle->db_local, 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, /* Loop through the cache dirs until we find a matching file */
alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg)); 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); md5sum = alpm_get_md5sum(path);
if(md5sum == NULL) { if(md5sum == NULL) {
@ -182,6 +198,9 @@ int alpm_pkg_checkmd5sum(pmpkg_t *pkg)
return(retval); return(retval);
} }
/** Compare versions. /** Compare versions.
* @param ver1 first version * @param ver1 first version
* @param ver2 secont version * @param ver2 secont version

View file

@ -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; alpm_list_t *i, *j, *files = NULL;
pmtrans_t *tr = NULL; pmtrans_t *tr = NULL;
int replaces = 0, retval = 0; int replaces = 0, retval = 0;
const char *cachedir; int validcache = 0;
int varcache = 1; const char *maincachedir = NULL;
ALPM_LOG_FUNC; 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; trans->state = STATE_DOWNLOADING;
/* group sync records by repository and download */ /* group sync records by repository and download */
cachedir = alpm_option_get_cachedir();
for(i = handle->dbs_sync; i; i = i->next) { for(i = handle->dbs_sync; i; i = i->next) {
pmdb_t *current = i->data; 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); EVENT(trans, PM_TRANS_EVT_PRINTURI, (char *)alpm_db_get_url(current), (char *)fname);
} else { } else {
struct stat buf; struct stat buf;
snprintf(path, PATH_MAX, "%s/%s", cachedir, fname); int found = 0;
if(stat(path, &buf)) { /* 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 */ /* file is not in the cache dir, so add it to the list */
files = alpm_list_add(files, strdup(fname)); 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) { if(files) {
struct stat buf; struct stat buf;
char *cachedir;
EVENT(trans, PM_TRANS_EVT_RETRIEVE_START, current->treename, NULL); EVENT(trans, PM_TRANS_EVT_RETRIEVE_START, current->treename, NULL);
if(stat(cachedir, &buf)) { for(i = alpm_option_get_cachedirs(); i; i = alpm_list_next(i)) {
/* no cache directory.... try creating it */ cachedir = alpm_list_getdata(i);
_alpm_log(PM_LOG_WARNING, _("no %s cache exists, creating...\n"), cachedir); if(stat(cachedir, &buf) != 0) {
alpm_logaction(_("warning: no %s cache exists, creating..."), cachedir); /* cache directory does not exist.... try creating it */
if(_alpm_makepath(cachedir)) { _alpm_log(PM_LOG_WARNING, _("no %s cache exists, creating...\n"),
/* couldn't mkdir the cache directory, so fall back to /tmp and unlink cachedir);
* the package afterwards. alpm_logaction(_("warning: no %s cache exists, creating..."),
*/ cachedir);
_alpm_log(PM_LOG_WARNING, _("couldn't create package cache, using /tmp instead\n")); if(_alpm_makepath(cachedir) == 0) {
alpm_logaction(_("warning: couldn't create package cache, using /tmp instead")); _alpm_log(PM_LOG_DEBUG, _("setting main cachedir: %s"), cachedir);
alpm_option_set_cachedir("/tmp"); maincachedir = cachedir;
cachedir = alpm_option_get_cachedir(); validcache = 1;
varcache = 0; 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(), if(!validcache) {
files)) { /* 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); _alpm_log(PM_LOG_WARNING, _("failed to retrieve some files from %s\n"), current->treename);
RET_ERR(PM_ERR_RETRIEVE, -1); 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; pmsyncpkg_t *sync = i->data;
pmpkg_t *spkg = sync->pkg; pmpkg_t *spkg = sync->pkg;
char str[PATH_MAX]; char str[PATH_MAX];
struct stat buf;
const char *pkgname; const char *pkgname;
char *md5sum1, *md5sum2, *sha1sum1, *sha1sum2; char *md5sum1, *md5sum2, *sha1sum1, *sha1sum2;
char *ptr=NULL; char *ptr=NULL;
@ -861,9 +886,19 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
retval = 1; retval = 1;
continue; continue;
} }
snprintf(str, PATH_MAX, "%s%s", alpm_option_get_cachedir(), pkgname);
md5sum2 = _alpm_MDFile(str); /* Loop through the cache dirs until we find a matching file */
sha1sum2 = _alpm_SHAFile(str); 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(md5sum2 == NULL && sha1sum2 == NULL) {
if((ptr = calloc(512, sizeof(char))) == NULL) { if((ptr = calloc(512, sizeof(char))) == NULL) {
RET_ERR(PM_ERR_MEMORY, -1); 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); QUESTION(trans, PM_TRANS_CONV_CORRUPTED_PKG, (char *)pkgname, NULL, NULL, &doremove);
} }
if(doremove) { if(doremove) {
char str[PATH_MAX];
snprintf(str, PATH_MAX, "%s%s", alpm_option_get_cachedir(), pkgname);
unlink(str); unlink(str);
snprintf(ptr, 512, _("archive %s was corrupted (bad MD5 or SHA1 checksum)\n"), pkgname); snprintf(ptr, 512, _("archive %s was corrupted (bad MD5 or SHA1 checksum)\n"), pkgname);
} else { } 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) { for(i = trans->packages; i; i = i->next) {
pmsyncpkg_t *sync = i->data; pmsyncpkg_t *sync = i->data;
pmpkg_t *spkg = sync->pkg; pmpkg_t *spkg = sync->pkg;
struct stat buf;
const char *fname = NULL; const char *fname = NULL;
char str[PATH_MAX]; char str[PATH_MAX];
fname = alpm_pkg_get_filename(spkg); 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) { if(_alpm_trans_addtarget(tr, str) == -1) {
goto error; 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 */ /* delete packages */
for(i = files; i; i = i->next) { for(i = files; i; i = i->next) {
unlink(i->data); unlink(i->data);

View file

@ -339,12 +339,13 @@ static int parseargs(int argc, char *argv[])
case 1005: config->flags |= PM_TRANS_FLAG_NOSCRIPTLET; break; case 1005: config->flags |= PM_TRANS_FLAG_NOSCRIPTLET; break;
case 1006: config->noask = 1; config->ask = atoi(optarg); break; case 1006: config->noask = 1; config->ask = atoi(optarg); break;
case 1007: case 1007:
/* TODO redo this logic- check path somewhere else, delete other cachedirs, etc */
if(stat(optarg, &st) == -1 || !S_ISDIR(st.st_mode)) { if(stat(optarg, &st) == -1 || !S_ISDIR(st.st_mode)) {
fprintf(stderr, _("error: '%s' is not a valid cache directory\n"), fprintf(stderr, _("error: '%s' is not a valid cache directory\n"),
optarg); optarg);
return(1); return(1);
} }
alpm_option_set_cachedir(optarg); alpm_option_add_cachedir(optarg);
break; break;
case 1008: case 1008:
alpm_option_set_lockfile(optarg); alpm_option_set_lockfile(optarg);
@ -616,7 +617,7 @@ static int _parseconfig(const char *file, const char *givensection,
alpm_option_set_dbpath(ptr); alpm_option_set_dbpath(ptr);
pm_printf(PM_LOG_DEBUG, _("config: dbpath: %s\n"), ptr); pm_printf(PM_LOG_DEBUG, _("config: dbpath: %s\n"), ptr);
} else if(strcmp(key, "CacheDir") == 0 || strcmp(upperkey, "CACHEDIR") == 0) { } 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); pm_printf(PM_LOG_DEBUG, _("config: cachedir: %s\n"), ptr);
} else if(strcmp(key, "RootDir") == 0 || strcmp(upperkey, "ROOTDIR") == 0) { } else if(strcmp(key, "RootDir") == 0 || strcmp(upperkey, "ROOTDIR") == 0) {
alpm_option_set_root(ptr); alpm_option_set_root(ptr);
@ -762,10 +763,15 @@ if(0) {
#endif #endif
if(config->verbose > 0) { if(config->verbose > 0) {
alpm_list_t *i;
printf("Root : %s\n", alpm_option_get_root()); printf("Root : %s\n", alpm_option_get_root());
printf("Conf File : %s\n", config->configfile); printf("Conf File : %s\n", config->configfile);
printf("DBPath : %s\n", alpm_option_get_dbpath()); printf("DB Path : %s\n", alpm_option_get_dbpath());
printf("CacheDir : %s\n", alpm_option_get_cachedir()); 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("Lock File : %s\n", alpm_option_get_lockfile());
printf("Log File : %s\n", alpm_option_get_logfile()); printf("Log File : %s\n", alpm_option_get_logfile());
list_display("Targets :", pm_targets); list_display("Targets :", pm_targets);

View file

@ -89,7 +89,9 @@ static int split_pkgname(char *target, char *name, char *version)
static int sync_cleancache(int level) 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) { if(level == 1) {
/* incomplete cleanup: we keep latest packages and partial downloads */ /* incomplete cleanup: we keep latest packages and partial downloads */