Fix for FS 6404 and functionalize some cachedir handling stuff

In order to best resolve bug 6404, move some cachedir handling stuff out of
sync.c and into util.c and create two new functions: filecache_find and
filecache_setup. sync.c was rewritten to use these, and alpm_fetch_pkgurl
now also uses these routines.

Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
Dan McGee 2007-08-20 13:28:51 -04:00
parent 942175feaa
commit 17d9122e01
6 changed files with 137 additions and 143 deletions

View File

@ -101,10 +101,8 @@ int SYMEXPORT alpm_pkg_free(pmpkg_t *pkg)
*/
int SYMEXPORT alpm_pkg_checkmd5sum(pmpkg_t *pkg)
{
char path[PATH_MAX];
struct stat buf;
char *fpath;
char *md5sum = NULL;
alpm_list_t *i;
int retval = 0;
ALPM_LOG_FUNC;
@ -114,16 +112,9 @@ int SYMEXPORT alpm_pkg_checkmd5sum(pmpkg_t *pkg)
ASSERT(pkg->origin == PKG_FROM_CACHE, RET_ERR(PM_ERR_PKG_INVALID, -1));
ASSERT(pkg->origin_data.db != handle->db_local, RET_ERR(PM_ERR_PKG_INVALID, -1));
/* 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;
}
}
fpath = _alpm_filecache_find(alpm_pkg_get_filename(pkg));
md5sum = alpm_get_md5sum(fpath);
md5sum = alpm_get_md5sum(path);
if(md5sum == NULL) {
_alpm_log(PM_LOG_ERROR, _("could not get md5sum for package %s-%s"),
alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg));
@ -141,6 +132,7 @@ int SYMEXPORT alpm_pkg_checkmd5sum(pmpkg_t *pkg)
}
}
FREE(fpath);
FREE(md5sum);
return(retval);

View File

@ -41,20 +41,6 @@
#include "handle.h"
#include "package.h"
/** Fetch a remote pkg.
* @param url
* @return the downloaded filename on success, NULL on error
* @addtogroup alpm_misc
*/
char SYMEXPORT *alpm_fetch_pkgurl(const char *url)
{
ALPM_LOG_FUNC;
ASSERT(strstr(url, "://"), return(NULL));
return(_alpm_fetch_pkgurl(url));
}
pmserver_t *_alpm_server_new(const char *url)
{
struct url *u;
@ -157,9 +143,9 @@ static struct url *url_for_file(pmserver_t *server, const char *filename)
*
* RETURN: 0 for successful download, 1 on error
*/
int _alpm_downloadfiles(alpm_list_t *servers, const char *localpath, alpm_list_t *files)
int _alpm_downloadfiles(alpm_list_t *servers, const char *localpath,
alpm_list_t *files)
{
ALPM_LOG_FUNC;
return(_alpm_downloadfiles_forreal(servers, localpath, files, NULL, NULL));
}
@ -412,15 +398,25 @@ int _alpm_downloadfiles_forreal(alpm_list_t *servers, const char *localpath,
return(done ? 0 : -1);
}
char *_alpm_fetch_pkgurl(const char *target)
/** Fetch a remote pkg.
* @param url URL of the package to download
* @return the downloaded filepath on success, NULL on error
* @addtogroup alpm_misc
*/
char SYMEXPORT *alpm_fetch_pkgurl(const char *url)
{
pmserver_t *server;
char *filename;
struct stat st;
char *filename, *filepath;
const char *cachedir;
ALPM_LOG_FUNC;
server = _alpm_server_new(target);
if(strstr(url, "://") == NULL) {
_alpm_log(PM_LOG_DEBUG, "Invalid URL passed to alpm_fetch_pkgurl");
return(NULL);
}
server = _alpm_server_new(url);
if(!server) {
return(NULL);
}
@ -432,26 +428,26 @@ char *_alpm_fetch_pkgurl(const char *target)
return(NULL);
}
/* do not download the file if it exists in the current dir */
if(stat(filename, &st) == 0) {
_alpm_log(PM_LOG_DEBUG, "%s has already been downloaded", filename);
} else {
alpm_list_t *servers = alpm_list_add(NULL, server);
alpm_list_t *files = alpm_list_add(NULL, filename);
/* find a valid cache dir to download to */
cachedir = _alpm_filecache_setup();
if(_alpm_downloadfiles(servers, "./", files)) {
_alpm_log(PM_LOG_WARNING, _("failed to download %s"), target);
return(NULL);
}
_alpm_log(PM_LOG_DEBUG, "successfully downloaded %s", filename);
alpm_list_free(files);
alpm_list_free(servers);
/* TODO this seems like needless complexity just to download one file */
alpm_list_t *servers = alpm_list_add(NULL, server);
alpm_list_t *files = alpm_list_add(NULL, filename);
/* download the file */
if(_alpm_downloadfiles(servers, cachedir, files)) {
_alpm_log(PM_LOG_WARNING, _("failed to download %s"), url);
return(NULL);
}
_alpm_log(PM_LOG_DEBUG, "successfully downloaded %s", filename);
alpm_list_free(files);
alpm_list_free(servers);
_alpm_server_free(server);
/* return the target with the raw filename, no URL */
return(filename);
/* we should be able to find the file the second time around */
filepath = _alpm_filecache_find(filename);
return(filepath);
}
/* vim: set ts=2 sw=2 noet: */

View File

@ -41,8 +41,6 @@ int _alpm_downloadfiles(alpm_list_t *servers, const char *localpath, alpm_list_t
int _alpm_downloadfiles_forreal(alpm_list_t *servers, const char *localpath,
alpm_list_t *files, const char *mtime1, char *mtime2);
char *_alpm_fetch_pkgurl(const char *target);
#endif /* _ALPM_SERVER_H */
/* vim: set ts=2 sw=2 noet: */

View File

@ -703,14 +703,14 @@ 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;
int validcache = 0;
const char *maincachedir = NULL;
const char *cachedir = NULL;
ALPM_LOG_FUNC;
ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
cachedir = _alpm_filecache_setup();
trans->state = STATE_DOWNLOADING;
/* group sync records by repository and download */
for(i = handle->dbs_sync; i; i = i->next) {
@ -723,71 +723,27 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
if(current == dbs) {
const char *fname = NULL;
char path[PATH_MAX];
fname = alpm_pkg_get_filename(spkg);
if(trans->flags & PM_TRANS_FLAG_PRINTURIS) {
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 {
struct stat 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) {
char *fpath = _alpm_filecache_find(fname);
if(!fpath) {
/* file is not in the cache dir, so add it to the list */
files = alpm_list_add(files, strdup(fname));
}
free(fpath);
}
}
}
if(files) {
struct stat buf;
char *cachedir;
EVENT(trans, PM_TRANS_EVT_RETRIEVE_START, current->treename, NULL);
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(!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);
if(_alpm_downloadfiles(current->servers, cachedir, files)) {
_alpm_log(PM_LOG_WARNING, _("failed to retrieve some files from %s\n"),
current->treename);
RET_ERR(PM_ERR_RETRIEVE, -1);
}
FREELIST(files);
@ -803,13 +759,12 @@ 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;
char str[PATH_MAX];
struct stat buf;
const char *pkgname;
const char *filename;
char *filepath;
char *md5sum1, *md5sum2;
char *ptr=NULL;
pkgname = alpm_pkg_get_filename(spkg);
filename = alpm_pkg_get_filename(spkg);
md5sum1 = spkg->md5sum;
if(md5sum1 == NULL) {
@ -817,28 +772,20 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
if((ptr = calloc(512, sizeof(char))) == NULL) {
RET_ERR(PM_ERR_MEMORY, -1);
}
snprintf(ptr, 512, _("can't get md5 checksum for package %s\n"), pkgname);
snprintf(ptr, 512, _("can't get md5 checksum for package %s\n"), filename);
*data = alpm_list_add(*data, ptr);
retval = 1;
continue;
}
/* 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;
}
}
filepath = _alpm_filecache_find(filename);
md5sum2 = alpm_get_md5sum(str);
md5sum2 = alpm_get_md5sum(filepath);
if(md5sum2 == NULL) {
if((ptr = calloc(512, sizeof(char))) == NULL) {
RET_ERR(PM_ERR_MEMORY, -1);
}
snprintf(ptr, 512, _("can't get md5 checksum for package %s\n"), pkgname);
snprintf(ptr, 512, _("can't get md5 checksum for package %s\n"), filename);
*data = alpm_list_add(*data, ptr);
retval = 1;
continue;
@ -848,16 +795,17 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
if((ptr = calloc(512, sizeof(char))) == NULL) {
RET_ERR(PM_ERR_MEMORY, -1);
}
QUESTION(trans, PM_TRANS_CONV_CORRUPTED_PKG, (char *)pkgname, NULL, NULL, &doremove);
QUESTION(trans, PM_TRANS_CONV_CORRUPTED_PKG, (char *)filename,
NULL, NULL, &doremove);
if(doremove) {
unlink(str);
snprintf(ptr, 512, _("archive %s was corrupted (bad MD5 checksum)\n"), pkgname);
} else {
snprintf(ptr, 512, _("archive %s is corrupted (bad MD5 checksum)\n"), pkgname);
unlink(filepath);
}
snprintf(ptr, 512, _("archive %s was corrupted (bad MD5 checksum)\n"),
filename);
*data = alpm_list_add(*data, ptr);
retval = 1;
}
free(filepath);
FREE(md5sum2);
}
if(retval) {
@ -929,21 +877,19 @@ 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];
const char *fname;
char *fpath;
fname = alpm_pkg_get_filename(spkg);
/* 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) {
fpath = _alpm_filecache_find(fname);
if(_alpm_trans_addtarget(tr, fpath) == -1) {
free(fpath);
goto error;
}
free(fpath);
/* using alpm_list_last() is ok because addtarget() adds the new target at the
* end of the tr->packages list */
spkg = alpm_list_last(tr->packages)->data;
@ -1010,13 +956,6 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
}
}
if(!validcache && !(trans->flags & PM_TRANS_FLAG_DOWNLOADONLY)) {
/* delete packages */
for(i = files; i; i = i->next) {
unlink(i->data);
}
}
return(0);
error:

View File

@ -48,6 +48,7 @@
#include "error.h"
#include "package.h"
#include "alpm.h"
#include "alpm_list.h"
#include "md5.h"
#ifndef HAVE_STRVERSCMP
@ -301,7 +302,7 @@ static void _strnadd(char **str, const char *append, unsigned int count)
if(*str) {
*str = realloc(*str, strlen(*str) + count + 1);
} else {
*str = calloc(sizeof(char), count + 1);
*str = calloc(count + 1, sizeof(char));
}
strncat(*str, append, count);
@ -542,6 +543,72 @@ int _alpm_str_cmp(const void *s1, const void *s2)
return(strcmp(s1, s2));
}
/** Find a package file in an alpm cachedir.
* @param filename name of package file to find
* @return malloced path of file, NULL if not found
*/
char *_alpm_filecache_find(const char* filename)
{
struct stat buf;
char path[PATH_MAX];
char *retpath;
alpm_list_t *i;
/* 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),
filename);
if(stat(path, &buf) == 0) {
/* TODO maybe check to make sure it is readable? */
retpath = strdup(path);
_alpm_log(PM_LOG_DEBUG, "found cached pkg: %s", retpath);
return(retpath);
}
}
/* package wasn't found in any cachedir */
return(NULL);
}
/** Check the alpm cachedirs for existance and find a writable one.
* If no valid cache directory can be found, use /tmp.
* @return pointer to a writable cache directory.
*/
const char *_alpm_filecache_setup(void)
{
struct stat buf;
alpm_list_t *i, *tmp;
char *cachedir;
/* Loop through the cache dirs until we find a writeable dir */
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, "using cachedir: %s", cachedir);
return(cachedir);
}
} else if(S_ISDIR(buf.st_mode) && (buf.st_mode & S_IWUSR)) {
_alpm_log(PM_LOG_DEBUG, "using cachedir: %s", cachedir);
return(cachedir);
}
}
/* we didn't find a valid cache directory. use /tmp. */
i = alpm_option_get_cachedirs();
tmp = alpm_list_add(NULL, strdup("/tmp/"));
FREELIST(i);
alpm_option_set_cachedirs(tmp);
_alpm_log(PM_LOG_DEBUG, "using cachedir: %s", "/tmp/");
_alpm_log(PM_LOG_WARNING, _("couldn't create package cache, using /tmp instead"));
alpm_logaction("warning: couldn't create package cache, using /tmp instead");
return(alpm_list_getdata(tmp));
}
/** Get the md5 sum of file.
* @param filename name of the file
* @return the checksum on success, NULL on error

View File

@ -53,6 +53,8 @@ int _alpm_logaction(unsigned short usesyslog, FILE *f, const char *fmt, va_list
int _alpm_ldconfig(const char *root);
void _alpm_time2string(time_t t, char *buffer);
int _alpm_str_cmp(const void *s1, const void *s2);
char *_alpm_filecache_find(const char *filename);
const char *_alpm_filecache_setup(void);
#ifndef HAVE_STRVERSCMP
static int strverscmp(const char *, const char *);