summaryrefslogtreecommitdiff
path: root/src/index.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/index.c')
-rw-r--r--src/index.c92
1 files changed, 69 insertions, 23 deletions
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 = {