From 17d9122e01f5a675f4c7882e68ceae65aae7b5aa Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Mon, 20 Aug 2007 13:28:51 -0400 Subject: 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 --- lib/libalpm/package.c | 16 ++----- lib/libalpm/server.c | 68 +++++++++++++--------------- lib/libalpm/server.h | 2 - lib/libalpm/sync.c | 123 +++++++++++++------------------------------------- lib/libalpm/util.c | 69 +++++++++++++++++++++++++++- lib/libalpm/util.h | 2 + 6 files changed, 137 insertions(+), 143 deletions(-) (limited to 'lib/libalpm') diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c index cb56bccf..e11d7476 100644 --- a/lib/libalpm/package.c +++ b/lib/libalpm/package.c @@ -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); diff --git a/lib/libalpm/server.c b/lib/libalpm/server.c index ddc6674a..1ab89843 100644 --- a/lib/libalpm/server.c +++ b/lib/libalpm/server.c @@ -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: */ diff --git a/lib/libalpm/server.h b/lib/libalpm/server.h index 76758d21..462d9b24 100644 --- a/lib/libalpm/server.h +++ b/lib/libalpm/server.h @@ -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: */ diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index 4b4df1fe..336e3ff9 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -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: diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index 64371348..72bc9673 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -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 diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h index 8d84d87f..0dab0639 100644 --- a/lib/libalpm/util.h +++ b/lib/libalpm/util.h @@ -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 *); -- cgit v1.2.3-70-g09d2