diff --git a/src/apk_blob.h b/src/apk_blob.h index a91f6b5..5f30fd6 100644 --- a/src/apk_blob.h +++ b/src/apk_blob.h @@ -20,6 +20,8 @@ struct apk_blob { }; typedef struct apk_blob apk_blob_t; +#define APK_BLOB_IS_NULL(blob) (blob.ptr == NULL) + #define APK_BLOB_NULL ((apk_blob_t){0, NULL}) #define APK_BLOB_STR(str) ((apk_blob_t){strlen(str), (str)}) #define APK_BLOB_BUF(buf) ((apk_blob_t){sizeof(buf), (char *)(buf)}) diff --git a/src/apk_io.h b/src/apk_io.h index 0eadec0..f0b06e1 100644 --- a/src/apk_io.h +++ b/src/apk_io.h @@ -47,5 +47,6 @@ struct apk_bstream *apk_bstream_from_istream(struct apk_istream *istream); struct apk_bstream *apk_bstream_from_fd(int fd); apk_blob_t apk_blob_from_istream(struct apk_istream *istream, size_t size); +apk_blob_t apk_blob_from_file(const char *file); #endif diff --git a/src/database.c b/src/database.c index 4ed3ece..2376249 100644 --- a/src/database.c +++ b/src/database.c @@ -244,7 +244,7 @@ static struct apk_db_file *apk_db_file_get(struct apk_database *db, return file; } -static int apk_db_read_fdb(struct apk_database *db, int fd) +static int apk_db_read_fdb(struct apk_database *db, struct apk_istream *is) { struct apk_package *pkg = NULL; struct apk_db_dir *dir = NULL; @@ -260,7 +260,7 @@ static int apk_db_read_fdb(struct apk_database *db, int fd) r = APK_BLOB_PTR_LEN(buf, 0); while (1) { - n = read(fd, &r.ptr[r.len], sizeof(buf) - r.len); + n = is->read(is, &r.ptr[r.len], sizeof(buf) - r.len); if (n <= 0) break; r.len += n; @@ -450,9 +450,7 @@ int apk_db_create(const char *root) static int apk_db_read_state(struct apk_database *db) { struct apk_istream *is; - struct stat st; - char *buf; - int fd; + apk_blob_t blob; if (db->root == NULL) return 0; @@ -467,23 +465,18 @@ static int apk_db_read_state(struct apk_database *db) */ fchdir(db->root_fd); - fd = open("var/lib/apk/world", O_RDONLY); - if (fd < 0) { + blob = apk_blob_from_file("var/lib/apk/world"); + if (APK_BLOB_IS_NULL(blob)) { apk_error("Please run 'apk create' to initialize root"); return -1; } + apk_deps_parse(db, &db->world, blob); + free(blob.ptr); - fstat(fd, &st); - buf = malloc(st.st_size); - read(fd, buf, st.st_size); - apk_deps_parse(db, &db->world, - APK_BLOB_PTR_LEN(buf, st.st_size)); - close(fd); - - fd = open("var/lib/apk/files", O_RDONLY); - if (fd >= 0) { - apk_db_read_fdb(db, fd); - close(fd); + is = apk_istream_from_file("var/lib/apk/files"); + if (is != NULL) { + apk_db_read_fdb(db, is); + is->close(is); } is = apk_istream_from_file("var/lib/apk/scripts"); diff --git a/src/io.c b/src/io.c index 2bb8afc..84b556b 100644 --- a/src/io.c +++ b/src/io.c @@ -305,6 +305,35 @@ apk_blob_t apk_blob_from_istream(struct apk_istream *is, size_t size) return APK_BLOB_PTR_LEN(ptr, rsize); } +apk_blob_t apk_blob_from_file(const char *file) +{ + int fd; + struct stat st; + char *buf; + + fd = open(file, O_RDONLY); + if (fd < 0) + return APK_BLOB_NULL; + + if (fstat(fd, &st) < 0) + goto err_fd; + + buf = malloc(st.st_size); + if (buf == NULL) + goto err_fd; + + if (read(fd, buf, st.st_size) != st.st_size) + goto err_read; + + close(fd); + return APK_BLOB_PTR_LEN(buf, st.st_size); +err_read: + free(buf); +err_fd: + close(fd); + return APK_BLOB_NULL; +} + int apk_file_get_info(const char *filename, struct apk_file_info *fi) { struct stat st;