From b6e9fa5b02cd5d24b952c933dde3874cf1d0e5d3 Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Thu, 20 Jan 2022 17:11:03 +0100 Subject: [PATCH] First working version of creating archive --- src/archive.v | 15 +++++++++++++++ src/repo.v | 52 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/src/archive.v b/src/archive.v index ee72e3a..7ded6a1 100644 --- a/src/archive.v +++ b/src/archive.v @@ -51,6 +51,15 @@ fn C.archive_write_open_filename(&C.archive, &char) // Write an entry to the archive file fn C.archive_write_header(&C.archive, &C.archive_entry) +// Write the data in the buffer to the archive +fn C.archive_write_data(&C.archive, voidptr, int) + +// Close an archive for writing +fn C.archive_write_close(&C.archive) + +// Free the write archive +fn C.archive_write_free(&C.archive) + #include "archive_entry.h" struct C.archive_entry {} @@ -79,6 +88,12 @@ fn C.archive_entry_set_filetype(&C.archive_entry, u32) // Sets the file permissions for an entry fn C.archive_entry_set_perm(&C.archive_entry, int) +// Clears out an entry struct +fn C.archive_entry_clear(&C.archive_entry) + +// Copy over a stat struct to the archive entry +fn C.archive_entry_copy_stat(&C.archive_entry, &C.stat) + #include // Compare two C strings; 0 means they're equal diff --git a/src/repo.v b/src/repo.v index 389ebce..ff84909 100644 --- a/src/repo.v +++ b/src/repo.v @@ -59,7 +59,7 @@ pub fn (r &Repo) add_from_path(pkg_path string) ?bool { } } - return true + return added } // add adds a given Pkg to the repository @@ -83,7 +83,8 @@ fn (r &Repo) add(pkg &package.Pkg) ?bool { return error('Failed to write files file.') } - // TODO generate database archive + + r.sync() ? return true } @@ -92,3 +93,50 @@ fn (r &Repo) add(pkg &package.Pkg) ?bool { fn (r &Repo) pkg_path(pkg &package.Pkg) string { return os.join_path(r.repo_dir, '$pkg.info.name-$pkg.info.version') } + +// Re-generate the repo archive files +fn (r &Repo) sync() ? { + a := C.archive_write_new() + entry := C.archive_entry_new() + st := C.stat{} + buf := [8192]byte{} + + // This makes the archive a gzip-compressed tarball + C.archive_write_add_filter_gzip(a) + C.archive_write_set_format_pax_restricted(a) + + repo_path := os.join_path_single(r.repo_dir, 'repo.db') + + C.archive_write_open_filename(a, &char(repo_path.str)) + + // Iterate over each directory + for d in os.ls(r.repo_dir) ?.filter(os.is_dir(os.join_path_single(r.repo_dir, it))) { + inner_path := os.join_path_single(d, 'desc') + actual_path := os.join_path_single(r.repo_dir, inner_path) + + unsafe { + C.stat(&char(actual_path.str), &st) + } + + C.archive_entry_set_pathname(entry, &char(inner_path.str)) + // C.archive_entry_copy_stat(entry, &st) + C.archive_entry_set_size(entry, st.st_size) + C.archive_entry_set_filetype(entry, C.AE_IFREG) + C.archive_entry_set_perm(entry, 0o644) + C.archive_write_header(a, entry) + + fd := C.open(&char(actual_path.str), C.O_RDONLY) + mut len := C.read(fd, &buf, sizeof(buf)) + + for len > 0 { + C.archive_write_data(a, &buf, len) + len = C.read(fd, &buf, sizeof(buf)) + } + C.close(fd) + + C.archive_entry_clear(entry) + } + + C.archive_write_close(a) + C.archive_write_free(a) +}