summaryrefslogtreecommitdiffstats
path: root/src/io.c
diff options
context:
space:
mode:
authorTimo Teras <timo.teras@iki.fi>2009-06-28 20:36:16 +0300
committerTimo Teras <timo.teras@iki.fi>2009-06-29 09:29:57 +0300
commit233918e518f72e469ba39206abf70250bd6fc54a (patch)
tree426a311a98ffa3c4bc592287730b3a55e58a9197 /src/io.c
parentfac4cdb3fad6037e0841724a50d5364d16603f07 (diff)
downloadapk-tools-233918e518f72e469ba39206abf70250bd6fc54a.tar.bz2
apk-tools-233918e518f72e469ba39206abf70250bd6fc54a.tar.xz
db: cache packages (ref #49)
If /etc/apk/cache is a symlink to directory, a copy of all installed packages is stored there, and the index of remote repositories will be there instead of /var/lib/apk. This enables to reconstruct running system during boot. Left as todo: remove cached copy when the package is removed, and additional apk applet to download missing packages to cache and/or remove extra items.
Diffstat (limited to 'src/io.c')
-rw-r--r--src/io.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/src/io.c b/src/io.c
index defbe46..22a69e5 100644
--- a/src/io.c
+++ b/src/io.c
@@ -319,6 +319,64 @@ struct apk_bstream *apk_bstream_from_file(const char *file)
return apk_bstream_from_fd(fd);
}
+
+struct apk_tee_bstream {
+ struct apk_bstream bs;
+ struct apk_bstream *inner_bs;
+ int fd;
+ size_t size;
+};
+
+static size_t tee_read(void *stream, void **ptr)
+{
+ struct apk_tee_bstream *tbs =
+ container_of(stream, struct apk_tee_bstream, bs);
+ size_t size;
+
+ size = tbs->inner_bs->read(tbs->inner_bs, ptr);
+ if (size >= 0)
+ tbs->size += write(tbs->fd, *ptr, size);
+
+ return size;
+}
+
+static void tee_close(void *stream, csum_t csum, size_t *size)
+{
+ struct apk_tee_bstream *tbs =
+ container_of(stream, struct apk_tee_bstream, bs);
+
+ tbs->inner_bs->close(tbs->inner_bs, csum, NULL);
+ if (size != NULL)
+ *size = tbs->size;
+ close(tbs->fd);
+ free(tbs);
+}
+
+struct apk_bstream *apk_bstream_tee(struct apk_bstream *from, const char *to)
+{
+ struct apk_tee_bstream *tbs;
+ int fd;
+
+ fd = creat(to, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ if (fd < 0)
+ return NULL;
+
+ tbs = malloc(sizeof(struct apk_tee_bstream));
+ if (tbs == NULL) {
+ close(fd);
+ return NULL;
+ }
+
+ tbs->bs = (struct apk_bstream) {
+ .read = tee_read,
+ .close = tee_close,
+ };
+ tbs->inner_bs = from;
+ tbs->fd = fd;
+
+ return &tbs->bs;
+}
+
apk_blob_t apk_blob_from_istream(struct apk_istream *is, size_t size)
{
void *ptr;