db: cache index files, 'update' applet
Cache non-local index files always locally. Introduce 'update' applet to force refresh of cached index files. Fixes #19.cute-signatures
parent
aaa3c227b8
commit
4c2bfd9ded
|
@ -2,8 +2,8 @@ progs-y += apk
|
|||
apk-objs := state.o database.o package.o archive.o \
|
||||
version.o io.o url.o gunzip.o blob.o \
|
||||
hash.o md5.o apk.o \
|
||||
add.o del.o ver.o index.o info.o search.o \
|
||||
fetch.o audit.o
|
||||
add.o del.o update.o info.o search.o \
|
||||
ver.o index.o fetch.o audit.o
|
||||
CFLAGS_apk.o := -DAPK_VERSION=\"$(FULL_VERSION)\"
|
||||
|
||||
progs-$(STATIC) += apk.static
|
||||
|
|
|
@ -67,6 +67,7 @@ struct apk_name {
|
|||
|
||||
struct apk_repository {
|
||||
char *url;
|
||||
char *cache;
|
||||
};
|
||||
|
||||
struct apk_database {
|
||||
|
@ -124,6 +125,8 @@ struct apk_package *apk_db_get_file_owner(struct apk_database *db, apk_blob_t fi
|
|||
int apk_db_index_write(struct apk_database *db, struct apk_ostream *os);
|
||||
|
||||
int apk_db_add_repository(apk_database_t db, apk_blob_t repository);
|
||||
int apk_repository_update(struct apk_database *db, struct apk_repository *repo);
|
||||
|
||||
int apk_db_install_pkg(struct apk_database *db,
|
||||
struct apk_package *oldpkg,
|
||||
struct apk_package *newpkg,
|
||||
|
|
|
@ -69,5 +69,7 @@ apk_blob_t apk_blob_from_istream(struct apk_istream *istream, size_t size);
|
|||
apk_blob_t apk_blob_from_file(const char *file);
|
||||
|
||||
int apk_file_get_info(const char *filename, struct apk_file_info *fi);
|
||||
int apk_url_download(const char *url, const char *file);
|
||||
const char *apk_url_local_file(const char *url);
|
||||
|
||||
#endif
|
||||
|
|
108
src/database.c
108
src/database.c
|
@ -803,8 +803,11 @@ void apk_db_close(struct apk_database *db)
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < db->num_repos; i++)
|
||||
for (i = 0; i < db->num_repos; i++) {
|
||||
free(db->repos[i].url);
|
||||
if (db->repos[i].cache != NULL)
|
||||
free(db->repos[i].cache);
|
||||
}
|
||||
if (db->protected_paths) {
|
||||
for (i = 0; i < db->protected_paths->num; i++)
|
||||
free(db->protected_paths->item[i]);
|
||||
|
@ -896,12 +899,76 @@ int apk_db_index_write(struct apk_database *db, struct apk_ostream *os)
|
|||
return ctx.count;
|
||||
}
|
||||
|
||||
static struct apk_bstream *apk_db_cache_open(struct apk_database *db,
|
||||
const char *file)
|
||||
{
|
||||
char tmp[256];
|
||||
|
||||
if (db->root == NULL)
|
||||
return NULL;
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "%svar/lib/apk/%s", db->root, file);
|
||||
return apk_bstream_from_file(tmp);
|
||||
}
|
||||
|
||||
static int apk_db_cache_has(struct apk_database *db, const char *file)
|
||||
{
|
||||
char tmp[256];
|
||||
struct apk_file_info fi;
|
||||
int r;
|
||||
|
||||
if (db->root == NULL)
|
||||
return FALSE;
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "%svar/lib/apk/%s", db->root, file);
|
||||
r = apk_file_get_info(tmp, &fi);
|
||||
if (r < 0)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static struct apk_bstream *apk_repository_file_open(struct apk_repository *repo,
|
||||
const char *file)
|
||||
{
|
||||
char tmp[256];
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "%s/%s", repo->url, file);
|
||||
|
||||
return apk_bstream_from_url(tmp);
|
||||
}
|
||||
|
||||
int apk_repository_update(struct apk_database *db, struct apk_repository *repo)
|
||||
{
|
||||
char tmp[256], tmp2[256];
|
||||
int r;
|
||||
|
||||
if (repo->cache == NULL)
|
||||
return 0;
|
||||
|
||||
apk_message("fetch index %s", repo->url);
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "%s/APK_INDEX.gz", repo->url);
|
||||
snprintf(tmp2, sizeof(tmp2), "%svar/lib/apk/%s.new",
|
||||
db->root, repo->cache);
|
||||
r = apk_url_download(tmp, tmp2);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
snprintf(tmp2, sizeof(tmp2), "%svar/lib/apk/%s",
|
||||
db->root, repo->cache);
|
||||
if (rename(tmp2, tmp) < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int apk_db_add_repository(apk_database_t _db, apk_blob_t repository)
|
||||
{
|
||||
struct apk_database *db = _db.db;
|
||||
struct apk_istream *is;
|
||||
char tmp[256];
|
||||
int r;
|
||||
struct apk_istream *is = NULL;
|
||||
char buf[2*sizeof(csum_t)+32], *name;
|
||||
int r, n;
|
||||
|
||||
if (repository.ptr == NULL || *repository.ptr == '\0'
|
||||
|| *repository.ptr == '#')
|
||||
|
@ -911,14 +978,37 @@ int apk_db_add_repository(apk_database_t _db, apk_blob_t repository)
|
|||
return -1;
|
||||
|
||||
r = db->num_repos++;
|
||||
db->repos[r] = (struct apk_repository){
|
||||
.url = apk_blob_cstr(repository)
|
||||
db->repos[r] = (struct apk_repository) {
|
||||
.url = apk_blob_cstr(repository),
|
||||
.cache = NULL,
|
||||
};
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "%s/APK_INDEX.gz", db->repos[r].url);
|
||||
is = apk_istream_from_url_gz(tmp);
|
||||
if (apk_url_local_file(db->repos[r].url) == NULL) {
|
||||
csum_ctx_t csum;
|
||||
csum_t res;
|
||||
|
||||
csum_init(&csum);
|
||||
csum_process(&csum, repository.ptr, repository.len);
|
||||
csum_finish(&csum, res);
|
||||
|
||||
n = apk_hexdump_format(sizeof(buf), buf, APK_BLOB_BUF(res)) - 1;
|
||||
snprintf(&buf[n], sizeof(buf) - n, ".index.gz");
|
||||
|
||||
db->repos[r].cache = strdup(buf);
|
||||
|
||||
if (!apk_db_cache_has(db, db->repos[r].cache)) {
|
||||
n = apk_repository_update(db, &db->repos[r]);
|
||||
if (n < 0)
|
||||
return n;
|
||||
}
|
||||
name = db->repos[r].cache;
|
||||
is = apk_bstream_gunzip(apk_db_cache_open(db, db->repos[r].cache), 1);
|
||||
} else {
|
||||
name = "APK_INDEX.gz";
|
||||
is = apk_bstream_gunzip(apk_repository_file_open(&db->repos[r], name), 1);
|
||||
}
|
||||
if (is == NULL) {
|
||||
apk_error("Failed to open index file %s", tmp);
|
||||
apk_error("Failed to open index file %s", name);
|
||||
return -1;
|
||||
}
|
||||
apk_db_index_read(db, is, r);
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/* update.c - Alpine Package Keeper (APK)
|
||||
*
|
||||
* Copyright (C) 2005-2008 Natanael Copa <n@tanael.org>
|
||||
* Copyright (C) 2008 Timo Teräs <timo.teras@iki.fi>
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation. See http://www.gnu.org/ for details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "apk_defines.h"
|
||||
#include "apk_applet.h"
|
||||
#include "apk_database.h"
|
||||
#include "apk_version.h"
|
||||
|
||||
static int update_main(void *ctx, int argc, char **argv)
|
||||
{
|
||||
struct apk_database db;
|
||||
int i;
|
||||
|
||||
if (apk_db_open(&db, apk_root, APK_OPENF_READ) < 0)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < db.num_repos; i++)
|
||||
apk_repository_update(&db, &db.repos[i]);
|
||||
|
||||
apk_db_close(&db);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct apk_applet apk_update = {
|
||||
.name = "update",
|
||||
.usage = "",
|
||||
.main = update_main,
|
||||
};
|
||||
|
||||
APK_DEFINE_APPLET(apk_update);
|
||||
|
34
src/url.c
34
src/url.c
|
@ -13,10 +13,11 @@
|
|||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "apk_io.h"
|
||||
|
||||
static const char *url_is_file(const char *url)
|
||||
const char *apk_url_local_file(const char *url)
|
||||
{
|
||||
if (strncmp(url, "file:", 5) == 0)
|
||||
return &url[5];
|
||||
|
@ -59,8 +60,8 @@ static int fork_wget(const char *url)
|
|||
|
||||
struct apk_istream *apk_istream_from_url(const char *url)
|
||||
{
|
||||
if (url_is_file(url) != NULL)
|
||||
return apk_istream_from_file(url_is_file(url));
|
||||
if (apk_url_local_file(url) != NULL)
|
||||
return apk_istream_from_file(apk_url_local_file(url));
|
||||
|
||||
return apk_istream_from_fd(fork_wget(url));
|
||||
}
|
||||
|
@ -72,9 +73,34 @@ struct apk_istream *apk_istream_from_url_gz(const char *file)
|
|||
|
||||
struct apk_bstream *apk_bstream_from_url(const char *url)
|
||||
{
|
||||
if (url_is_file(url))
|
||||
if (apk_url_local_file(url))
|
||||
return apk_bstream_from_file(url);
|
||||
|
||||
return apk_bstream_from_fd(fork_wget(url));
|
||||
}
|
||||
|
||||
int apk_url_download(const char *url, const char *file)
|
||||
{
|
||||
pid_t pid;
|
||||
int status;
|
||||
|
||||
pid = fork();
|
||||
if (pid == -1)
|
||||
return -1;
|
||||
|
||||
if (pid == 0) {
|
||||
setsid();
|
||||
dup2(open("/dev/null", O_RDONLY), STDIN_FILENO);
|
||||
execlp("wget", "wget", "-q", "-O", file, url, NULL);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
waitpid(pid, &status, 0);
|
||||
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||
unlink(file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue