From c676622869992327b30dde70be353c53bf962761 Mon Sep 17 00:00:00 2001 From: Juan RP Date: Tue, 24 Nov 2009 05:03:26 +0000 Subject: [PATCH] Some changes to know if a file was downloaded successfully or not. Improved xbps-repo sync/add and xbps-fetch to print informative messages when a transfer was not necessary because local/remote size and/or mtime matched. --HG-- extra : convert_revision : xtraeme%40gmail.com-20091124050326-owez7140fdxwepuk --- bin/xbps-bin/install.c | 4 +- bin/xbps-fetch/main.c | 4 +- bin/xbps-repo/main.c | 113 ++++++++++++++++++++++----------------- lib/download.c | 45 ++++++++++------ lib/sync_remote_pkgidx.c | 43 +++++++++------ 5 files changed, 124 insertions(+), 85 deletions(-) diff --git a/bin/xbps-bin/install.c b/bin/xbps-bin/install.c index 90ccdcaf..9956f2bf 100644 --- a/bin/xbps-bin/install.c +++ b/bin/xbps-bin/install.c @@ -177,9 +177,9 @@ download_package_list(prop_object_iterator_t iter) rv = xbps_fetch_file(binfile, savedir, false, NULL); free(savedir); free(binfile); - if (rv != 0) { + if (rv == -1) { printf("Couldn't download %s from %s (%s)\n", - filename, repoloc, strerror(rv)); + filename, repoloc, xbps_fetch_error_string()); free(repoloc_trans); return errno; } diff --git a/bin/xbps-fetch/main.c b/bin/xbps-fetch/main.c index 4885d63a..bed61c54 100644 --- a/bin/xbps-fetch/main.c +++ b/bin/xbps-fetch/main.c @@ -33,9 +33,11 @@ main(int argc, char **argv) usage(); rv = xbps_fetch_file(argv[0], ".", false, flags); - if (rv != 0) { + if (rv == -1) { printf("%s: %s\n", argv[0], xbps_fetch_error_string()); exit(EXIT_FAILURE); + } else if (rv == 0) { + printf("%s: file is identical than remote.\n", argv[0]); } exit(EXIT_SUCCESS); } diff --git a/bin/xbps-repo/main.c b/bin/xbps-repo/main.c index ce333528..413cece4 100644 --- a/bin/xbps-repo/main.c +++ b/bin/xbps-repo/main.c @@ -35,13 +35,8 @@ #include "index.h" #include "util.h" -typedef struct repository_info { - const char *index_version; - uint64_t total_pkgs; -} repo_info_t; - static bool sanitize_localpath(char *, const char *); -static bool pkgindex_getinfo(prop_dictionary_t, repo_info_t *); +static int pkgindex_verify(const char *, const char *, bool); static void usage(void); static void @@ -71,24 +66,54 @@ usage(void) exit(EXIT_FAILURE); } -static bool -pkgindex_getinfo(prop_dictionary_t dict, repo_info_t *ri) +static int +pkgindex_verify(const char *plist, const char *uri, bool only_sync) { - assert(dict != NULL || ri != NULL); + prop_dictionary_t d; + const char *pkgidx_version; + uint64_t total_pkgs; + int rv = 0; - if (!prop_dictionary_get_cstring_nocopy(dict, - "pkgindex-version", &ri->index_version)) - return false; + assert(plist != NULL); - if (!prop_dictionary_get_uint64(dict, "total-pkgs", - &ri->total_pkgs)) - return false; + d = prop_dictionary_internalize_from_file(plist); + if (d == NULL) { + printf("E: repository %s does not contain any " + "xbps pkgindex file.\n", uri); + return errno; + } + + if (!prop_dictionary_get_cstring_nocopy(d, + "pkgindex-version", &pkgidx_version)) { + printf("E: missing 'pkgindex-version' object!\n"); + rv = errno; + goto out; + } + + if (!prop_dictionary_get_uint64(d, "total-pkgs", &total_pkgs)) { + printf("E: missing 'total-pkgs' object!\n"); + rv = errno; + goto out; + } /* Reject empty repositories, how could this happen? :-) */ - if (ri->total_pkgs <= 0) - return false; + if (total_pkgs == 0) { + printf("E: empty package list!\n"); + rv = EINVAL; + goto out; + } - return true; + printf("%s package index at %s (v%s) with %ju packages.\n", + only_sync ? "Updated" : "Added", uri, pkgidx_version, total_pkgs); + +out: + prop_object_release(d); + if (rv != 0) { + printf("W: removing incorrect pkg index file: '%s' ...\n", + plist); + rv = remove(plist); + } + return rv; } static bool @@ -135,8 +160,6 @@ out: static int add_repository(const char *uri) { - prop_dictionary_t dict; - repo_info_t *rinfo; char *plist, idxstr[PATH_MAX]; int rv = 0; @@ -146,10 +169,14 @@ add_repository(const char *uri) printf("Fetching remote package index at %s...\n", uri); rv = xbps_sync_repository_pkg_index(idxstr); - if (rv != 0) { + if (rv == -1) { printf("Error: could not fetch pkg index file: %s.\n", xbps_fetch_error_string()); return rv; + } else if (rv == 0) { + printf("Package index file is already " + "up to date.\n"); + return 0; } plist = xbps_get_pkg_index_plist(idxstr); @@ -163,25 +190,8 @@ add_repository(const char *uri) if (plist == NULL) return errno; - dict = prop_dictionary_internalize_from_file(plist); - if (dict == NULL) { - printf("Repository %s does not contain any " - "xbps pkgindex file.\n", idxstr); - rv = errno; + if ((rv = pkgindex_verify(plist, idxstr, false)) != 0) goto out; - } - - rinfo = malloc(sizeof(*rinfo)); - if (rinfo == NULL) { - rv = errno; - goto out; - } - - if (!pkgindex_getinfo(dict, rinfo)) { - printf("'%s' is incomplete.\n", plist); - rv = EINVAL; - goto out; - } if ((rv = xbps_register_repository(idxstr)) != 0) { printf("ERROR: couldn't register repository (%s)\n", @@ -189,14 +199,7 @@ add_repository(const char *uri) goto out; } - printf("Added repository at %s (%s) with %ju packages.\n", - idxstr, rinfo->index_version, rinfo->total_pkgs); - out: - if (dict != NULL) - prop_object_release(dict); - if (rinfo != NULL) - free(rinfo); if (plist != NULL) free(plist); @@ -206,8 +209,8 @@ out: int main(int argc, char **argv) { - char dpkgidx[PATH_MAX], *root = NULL; struct repository_data *rdata = NULL; + char dpkgidx[PATH_MAX], *plist, *root = NULL; int c, rv = 0; while ((c = getopt(argc, argv, "Vr:")) != -1) { @@ -313,8 +316,22 @@ main(int argc, char **argv) if (xbps_check_is_repo_string_remote(uri)) { printf("Syncing package index from: %s\n", uri); rv = xbps_sync_repository_pkg_index(uri); - if (rv != 0) + if (rv == -1) { + printf("Failed! returned: %s\n", + xbps_fetch_error_string()); break; + } else if (rv == 0) { + printf("Package index file is already " + "up to date.\n"); + continue; + } + plist = xbps_get_pkg_index_plist(uri); + if (plist == NULL) { + rv = EINVAL; + break; + } + (void)pkgindex_verify(plist, uri, true); + free(plist); } } xbps_release_repolist_data(); diff --git a/lib/download.c b/lib/download.c index 31def4e6..88a2e04d 100644 --- a/lib/download.c +++ b/lib/download.c @@ -183,6 +183,10 @@ print_time(time_t *t) } #endif +/* + * Returns -1 on error, 0 if not download (because local/remote + * size and/or mtime match) and 1 if downloaded successfully. + */ int SYMEXPORT xbps_fetch_file(const char *uri, const char *outputdir, bool refetch, const char *flags) @@ -207,15 +211,17 @@ xbps_fetch_file(const char *uri, const char *outputdir, bool refetch, * Get the filename specified in URI argument. */ filename = strrchr(uri, '/'); - if (filename == NULL) - return EINVAL; + if (filename == NULL) { + errno = EINVAL; + return -1; + } filename++; /* * Compute destination file path. */ destfile = xbps_xasprintf("%s/%s", outputdir, filename); if (destfile == NULL) { - rv = errno; + rv = -1; goto out; } /* @@ -227,7 +233,7 @@ xbps_fetch_file(const char *uri, const char *outputdir, bool refetch, restart = true; } else { if (errno != ENOENT) { - rv = errno; + rv = -1; goto out; } } @@ -235,7 +241,7 @@ xbps_fetch_file(const char *uri, const char *outputdir, bool refetch, * Prepare stuff for libfetch. */ if ((url = fetchParseURL(uri)) == NULL) { - rv = fetchLastErrCode; + rv = -1; goto out; } @@ -246,10 +252,9 @@ xbps_fetch_file(const char *uri, const char *outputdir, bool refetch, /* * Issue a HEAD request to know size and mtime. */ - if (fetchStat(url, &url_st, NULL) == -1) { - rv = fetchLastErrCode; + if ((rv = fetchStat(url, &url_st, NULL)) == -1) goto out; - } + /* * If mtime and size match do nothing. */ @@ -268,7 +273,7 @@ xbps_fetch_file(const char *uri, const char *outputdir, bool refetch, * Remove current file (if exists). */ if (restart && remove(destfile) == -1) { - rv = errno; + rv = -1; goto out; } restart = false; @@ -313,22 +318,23 @@ xbps_fetch_file(const char *uri, const char *outputdir, bool refetch, if (url->length == 0) goto out; } - rv = fetchLastErrCode; + rv = -1; goto out; } if (url_st.size == -1) { printf("Remote file size is unknown!\n"); - rv = EINVAL; + errno = EINVAL; + rv = -1; goto out; } else if (st.st_size > url_st.size) { printf("Local file %s is greater than remote file!\n", filename); - rv = EFBIG; + errno = EFBIG; + rv = -1; goto out; } else if (restart && url_st.mtime && url_st.size && url_st.size == st.st_size && url_st.mtime == st.st_mtime) { /* Local and remote size/mtime match, do nothing. */ - rv = 0; goto out; } fprintf(stderr, "Connected to %s.\n", url->host); @@ -342,7 +348,7 @@ xbps_fetch_file(const char *uri, const char *outputdir, bool refetch, fd = open(destfile, O_WRONLY|O_CREAT|O_TRUNC, 0644); if (fd == -1) { - rv = errno; + rv = -1; goto out; } @@ -354,7 +360,7 @@ xbps_fetch_file(const char *uri, const char *outputdir, bool refetch, bytes_written = write(fd, buf, (size_t)bytes_read); if (bytes_written != bytes_read) { fprintf(stderr, "Couldn't write to %s!\n", destfile); - rv = errno; + rv = -1; goto out; } bytes_dld += bytes_read; @@ -363,7 +369,8 @@ xbps_fetch_file(const char *uri, const char *outputdir, bool refetch, if (bytes_read == -1) { fprintf(stderr, "IO error while fetching %s: %s\n", filename, fetchLastErrString); - rv = EINVAL; + errno = EIO; + rv = -1; goto out; } stat_end(&xs); @@ -379,7 +386,11 @@ xbps_fetch_file(const char *uri, const char *outputdir, bool refetch, tv[1].tv_sec = url_st.mtime; tv[0].tv_usec = tv[1].tv_usec = 0; if (utimes(destfile, tv) == -1) - rv = errno; + rv = -1; + else { + /* File downloaded successfully */ + rv = 1; + } out: if (fd != -1) diff --git a/lib/sync_remote_pkgidx.c b/lib/sync_remote_pkgidx.c index e571534e..16bd0367 100644 --- a/lib/sync_remote_pkgidx.c +++ b/lib/sync_remote_pkgidx.c @@ -68,6 +68,10 @@ xbps_get_remote_repo_string(const char *uri) return p; } +/* + * Returns -1 on error, 0 if transfer was not necessary (local/remote + * size and/or mtime match) and 1 if downloaded successfully. + */ int SYMEXPORT xbps_sync_repository_pkg_index(const char *uri) { @@ -84,15 +88,15 @@ xbps_sync_repository_pkg_index(const char *uri) metadir = tmp_metafile = lrepofile = NULL; if (uname(&un) == -1) - return errno; + return -1; if ((url = fetchParseURL(uri)) == NULL) - return errno; + return -1; uri_fixedp = xbps_get_remote_repo_string(uri); if (uri_fixedp == NULL) { fetchFreeURL(url); - return errno; + return -1; } /* @@ -101,17 +105,18 @@ xbps_sync_repository_pkg_index(const char *uri) metadir = xbps_xasprintf("%s/%s", xbps_get_rootdir(), XBPS_META_PATH); if (metadir == NULL) { - rv = errno; + rv = -1; goto out; } rv = stat(metadir, &st); if (rv == -1 && errno == ENOENT) { if (mkpath(metadir, 0755) == -1) { - rv = errno; + rv = -1; goto out; } } else if (rv == 0 && !S_ISDIR(st.st_mode)) { - rv = ENOTDIR; + errno = ENOTDIR; + rv = -1; goto out; } @@ -120,7 +125,7 @@ xbps_sync_repository_pkg_index(const char *uri) */ rpidx = xbps_xasprintf("%s/%s/%s", uri, un.machine, XBPS_PKGINDEX); if (rpidx == NULL) { - rv = errno; + rv = -1; goto out; } /* @@ -129,7 +134,7 @@ xbps_sync_repository_pkg_index(const char *uri) */ tmp_metafile = xbps_xasprintf("%s/%s", metadir, XBPS_PKGINDEX); if (tmp_metafile == NULL) { - rv = errno; + rv = -1; goto out; } /* @@ -138,7 +143,7 @@ xbps_sync_repository_pkg_index(const char *uri) lrepodir = xbps_xasprintf("%s/%s/%s/%s", xbps_get_rootdir(), XBPS_META_PATH, uri_fixedp, un.machine); if (lrepodir == NULL) { - rv = errno; + rv = -1; goto out; } /* @@ -156,7 +161,7 @@ xbps_sync_repository_pkg_index(const char *uri) * Download pkg-index.plist file from repository. */ if ((rv = xbps_fetch_file(rpidx, fetch_outputdir, - true, NULL)) != 0) { + true, NULL)) == -1) { (void)remove(tmp_metafile); goto out; } @@ -171,11 +176,12 @@ xbps_sync_repository_pkg_index(const char *uri) rv = stat(lrepodir, &st); if (rv == -1 && errno == ENOENT) { if (mkpath(lrepodir, 0755) == -1) { - rv = errno; + rv = -1; goto out; } } else if (rv == 0 && !S_ISDIR(st.st_mode)) { - rv = ENOTDIR; + errno = ENOTDIR; + rv = -1; goto out; } /* @@ -186,31 +192,34 @@ xbps_sync_repository_pkg_index(const char *uri) dir = xbps_xasprintf("%s/%s/%s/noarch", xbps_get_rootdir(), XBPS_META_PATH, uri_fixedp); if (dir == NULL) { - rv = errno; + rv = -1; goto out; } rv = stat(dir, &st); if (rv == -1 && errno == ENOENT) { if (mkpath(dir, 0755) == -1) { free(dir); - rv = errno; + rv = -1; goto out; } } else if (rv == 0 && !S_ISDIR(st.st_mode)) { free(dir); - rv = ENOTDIR; + errno = ENOTDIR; + rv = -1; goto out; } free(dir); lrepofile = xbps_xasprintf("%s/%s", lrepodir, XBPS_PKGINDEX); if (lrepofile == NULL) { - rv = errno; + rv = -1; goto out; } /* * Rename to destination file now it has been fetched successfully. */ - rv = rename(tmp_metafile, lrepofile); + if ((rv = rename(tmp_metafile, lrepofile)) == 0) + rv = 1; + out: if (rpidx) free(rpidx);