vieter/src/archive/archive.v

54 lines
1.3 KiB
V

module archive
import os
// Returns the .PKGINFO file's contents & the list of files.
pub fn pkg_info(pkg_path string) ?(string, []string) {
if !os.is_file(pkg_path) {
return error("'$pkg_path' doesn't exist or isn't a file.")
}
a := C.archive_read_new()
entry := C.archive_entry_new()
mut r := 0
C.archive_read_support_filter_all(a)
C.archive_read_support_format_all(a)
// TODO find out where does this 10240 come from
r = C.archive_read_open_filename(a, &char(pkg_path.str), 10240)
defer {
C.archive_read_free(a)
}
if r != C.ARCHIVE_OK {
return error('Failed to open package.')
}
// We iterate over every header in search of the .PKGINFO one
mut buf := voidptr(0)
mut files := []string{}
for C.archive_read_next_header(a, &entry) == C.ARCHIVE_OK {
pathname := C.archive_entry_pathname(entry)
ignored_names := [c'.BUILDINFO', c'.INSTALL', c'.MTREE', c'.PKGINFO', c'.CHANGELOG']
if ignored_names.all(C.strcmp(it, pathname) != 0) {
unsafe {
files << cstring_to_vstring(pathname)
}
}
if C.strcmp(pathname, c'.PKGINFO') == 0 {
size := C.archive_entry_size(entry)
// TODO can this unsafe block be avoided?
buf = unsafe { malloc(size) }
C.archive_read_data(a, voidptr(buf), size)
} else {
C.archive_read_data_skip(a)
}
}
return unsafe { cstring_to_vstring(&char(buf)) }, files
}