diff options
-rw-r--r-- | src/database.c | 2 | ||||
-rw-r--r-- | src/index.c | 92 |
2 files changed, 70 insertions, 24 deletions
diff --git a/src/database.c b/src/database.c index c80e9a9..80b6fc3 100644 --- a/src/database.c +++ b/src/database.c @@ -991,7 +991,7 @@ static int write_index_entry(apk_hash_item item, void *ctx) struct apk_package *pkg = (struct apk_package *) item; int r; - if (pkg->repos != 0) + if (pkg->filename == NULL) return 0; r = apk_pkg_write_index_entry(pkg, iwctx->os); diff --git a/src/index.c b/src/index.c index b938984..62460f7 100644 --- a/src/index.c +++ b/src/index.c @@ -20,8 +20,8 @@ struct counts { }; struct index_ctx { - const char *index_file; - int delete; + const char *index; + time_t index_mtime; }; static int index_parse(void *ctx, int optch, int optindex, const char *optarg) @@ -29,9 +29,8 @@ static int index_parse(void *ctx, int optch, int optindex, const char *optarg) struct index_ctx *ictx = (struct index_ctx *) ctx; switch (optch) { - case 'd': - ictx->index_file = optarg; - ictx->delete = 1; + case 'x': + ictx->index = optarg; break; default: return -1; @@ -42,13 +41,17 @@ static int index_parse(void *ctx, int optch, int optindex, const char *optarg) static int index_read_file(struct apk_database *db, struct index_ctx *ictx) { struct apk_bstream *bs; + struct apk_file_info fi; int r; - if (ictx->index_file == NULL) + if (ictx->index == NULL) return 0; - bs = apk_bstream_from_istream(apk_bstream_gunzip(apk_bstream_from_url(ictx->index_file), 1)); + if (apk_file_get_info(ictx->index, APK_CHECKSUM_NONE, &fi) < 0) + return -1; + ictx->index_mtime = fi.mtime; + bs = apk_bstream_from_istream(apk_bstream_gunzip(apk_bstream_from_url(ictx->index), 1)); if (bs == NULL) return -1; - r = apk_db_index_read(db, bs, -1); + r = apk_db_index_read(db, bs, 0); bs->close(bs, NULL); return r; } @@ -76,25 +79,67 @@ static int index_main(void *ctx, int argc, char **argv) struct apk_database db; struct counts counts = {0}; struct apk_ostream *os; - int total, i, j; + struct apk_file_info fi; + int total, i, j, found, newpkgs = 0; struct index_ctx *ictx = (struct index_ctx *) ctx; apk_db_open(&db, NULL, APK_OPENF_READ); - index_read_file(&db, ictx); + if (index_read_file(&db, ictx) < 0) { + apk_db_close(&db); + apk_error("The index is corrupt, or of unknown format."); + return -1; + } for (i = 0; i < argc; i++) { - if (ictx->delete) { + if (apk_file_get_info(argv[i], APK_CHECKSUM_NONE, &fi) < 0) { + apk_warning("File '%s' is unaccessible", argv[i]); + continue; + } + + found = FALSE; + do { struct apk_name *name; - name = apk_db_query_name(&db, APK_BLOB_STR(argv[i])); + char *fname, *fend; + apk_blob_t bname, bver; + + /* Check if index is newer than package */ + if (ictx->index == NULL || ictx->index_mtime < fi.mtime) + break; + + /* Check that it looks like a package name */ + fname = strrchr(argv[i], '/'); + if (fname == NULL) + fname = argv[i]; + else + fname++; + fend = strstr(fname, ".apk"); + if (fend == NULL) + break; + if (apk_pkg_parse_name(APK_BLOB_PTR_PTR(fname, fend-1), + &bname, &bver) < 0) + break; + + /* If we have it in the old index already? */ + name = apk_db_query_name(&db, bname); if (name == NULL || name->pkgs == NULL) - continue; - /* apk_db_index_write() will only print the pkgs - where repos == 0. We prevent to write the given - packages by setting repos to non-zero */ - for (j = 0; j < name->pkgs->num; j++) - name->pkgs->item[j]->repos = -1; - } else + break; + + for (j = 0; j < name->pkgs->num; j++) { + struct apk_package *pkg = name->pkgs->item[j]; + if (apk_blob_compare(bver, APK_BLOB_STR(pkg->version)) != 0) + continue; + if (pkg->size != fi.size) + continue; + pkg->filename = strdup(argv[i]); + found = TRUE; + break; + } + } while (0); + + if (!found) { apk_db_pkg_add_file(&db, argv[i]); + newpkgs++; + } } os = apk_ostream_to_fd(STDOUT_FILENO); @@ -108,15 +153,16 @@ static int index_main(void *ctx, int argc, char **argv) apk_warning("Total of %d unsatisfiable package " "names. Your repository maybe broken.", counts.unsatisfied); - apk_message("Index has %d packages", total); + apk_message("Index has %d packages (of which %d are new)", + total, newpkgs); return 0; } static struct apk_option index_options[] = { - { 'd', "delete", - "Read existing INDEXFILE and delete the listed FILEs from it", - required_argument, "INDEXFILE" }, + { 'x', "index", "Read INDEX to speed up new index creation by reusing " + "the information from an old index", + required_argument, "INDEX" }, }; static struct apk_applet apk_index = { |