feat(package): started rewrite in C
parent
9e11237ff9
commit
3e40eeff2d
|
@ -5,6 +5,6 @@ root = true
|
||||||
end_of_line = lf
|
end_of_line = lf
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
|
|
||||||
[*.v]
|
[*.{v,c,h}]
|
||||||
# vfmt wants it :(
|
# vfmt wants it :(
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
*.c
|
vieter.c
|
||||||
/data/
|
/data/
|
||||||
|
|
||||||
# Build artifacts
|
# Build artifacts
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
#include "dynarray.h"
|
||||||
|
|
||||||
|
struct dyn_array {
|
||||||
|
char **array;
|
||||||
|
size_t size;
|
||||||
|
size_t capacity;
|
||||||
|
};
|
||||||
|
|
||||||
|
DynArray *dynarray_init(size_t initial_capacity) {
|
||||||
|
DynArray *da = malloc(sizeof(DynArray));
|
||||||
|
da->size = 0;
|
||||||
|
da->capacity = initial_capacity;
|
||||||
|
|
||||||
|
return da;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dynarray_add(DynArray *da, const char *s) {
|
||||||
|
// An empty dynarray does not have an allocated internal array yet
|
||||||
|
if (da->size == 0) {
|
||||||
|
da->array = malloc(sizeof(char*) * da->capacity);
|
||||||
|
}
|
||||||
|
// Double array size if it's full
|
||||||
|
else if (da->size == da->capacity) {
|
||||||
|
da->array = realloc(da->array, da->capacity * 2);
|
||||||
|
da->capacity *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
da->array[da->size] = strdup(s);
|
||||||
|
da->size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dynarray_free(DynArray **ptp) {
|
||||||
|
DynArray *da = *ptp;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < da->size; i++) {
|
||||||
|
free(da->array[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(da->array);
|
||||||
|
free(da);
|
||||||
|
|
||||||
|
*ptp = NULL;
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef VIETER_DYNARRAY
|
||||||
|
#define VIETER_DYNARRAY
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
typedef struct dyn_array DynArray;
|
||||||
|
|
||||||
|
DynArray *dynarray_init(size_t initial_capacity);
|
||||||
|
void dynarray_add(DynArray *da, const char * s);
|
||||||
|
char ** dynarray_get_array(DynArray *da);
|
||||||
|
void dynarray_free(DynArray **ptp);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,94 @@
|
||||||
|
#include "package.h"
|
||||||
|
|
||||||
|
static char *ignored_names[5] = {
|
||||||
|
".BUILDINFO",
|
||||||
|
".INSTALL",
|
||||||
|
".MTREE",
|
||||||
|
".PKGINFO",
|
||||||
|
".CHANGELOG"
|
||||||
|
};
|
||||||
|
static int ignored_words_len = sizeof(ignored_names) / sizeof(char *);
|
||||||
|
|
||||||
|
inline Pkg *package_init() {
|
||||||
|
return calloc(sizeof(PkgInfo), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Pkg *package_read_archive(const char *pkg_path) {
|
||||||
|
struct archive *a = archive_read_new();
|
||||||
|
struct archive_entry *entry = archive_entry_new();
|
||||||
|
|
||||||
|
// These three are the most commonly used compression methods
|
||||||
|
archive_read_support_filter_zstd(a);
|
||||||
|
archive_read_support_filter_gzip(a);
|
||||||
|
archive_read_support_filter_xz(a);
|
||||||
|
|
||||||
|
// Contents should always be a tarball
|
||||||
|
archive_read_support_format_tar(a);
|
||||||
|
|
||||||
|
// TODO where does this 10240 come from?
|
||||||
|
int r = archive_read_open_filename(a, pkg_path, 10240);
|
||||||
|
|
||||||
|
// Exit early if we weren't able to successfully open the archive for reading
|
||||||
|
if (r != ARCHIVE_OK) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int compression_code = archive_filter_code(a, 0);
|
||||||
|
const char *path_name;
|
||||||
|
|
||||||
|
PkgInfo *pkg_info;
|
||||||
|
DynArray *files = dynarray_init(16);
|
||||||
|
|
||||||
|
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
|
||||||
|
path_name = archive_entry_pathname(entry);
|
||||||
|
|
||||||
|
bool ignore = false;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < ignored_words_len; i++) {
|
||||||
|
if (strcmp(path_name, ignored_names[i]) == 0) {
|
||||||
|
ignore = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ignore) {
|
||||||
|
dynarray_add(files, path_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(path_name, ".PKGINFO") == 0) {
|
||||||
|
// Read data of file into memory buffer
|
||||||
|
int size = archive_entry_size(entry);
|
||||||
|
char *buf = malloc(size);
|
||||||
|
archive_read_data(a, buf, size);
|
||||||
|
|
||||||
|
// Parse package info string into a struct
|
||||||
|
pkg_info = package_info_init();
|
||||||
|
package_info_parse(pkg_info, buf);
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
} else {
|
||||||
|
archive_read_data_skip(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get size of file
|
||||||
|
struct stat stats;
|
||||||
|
|
||||||
|
if (stat(pkg_path, &stats) != 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pkg_info->csize = stats.st_size;
|
||||||
|
|
||||||
|
archive_read_free(a);
|
||||||
|
archive_entry_free(entry);
|
||||||
|
|
||||||
|
// Create final return value
|
||||||
|
Pkg *pkg = package_init();
|
||||||
|
pkg->path = strdup(pkg_path);
|
||||||
|
pkg->info = pkg_info;
|
||||||
|
pkg->files = files;
|
||||||
|
pkg->compression = compression_code;
|
||||||
|
|
||||||
|
return pkg;
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef VIETER_PACKAGE
|
||||||
|
#define VIETER_PACKAGE
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "archive.h"
|
||||||
|
#include "archive_entry.h"
|
||||||
|
|
||||||
|
#include "package_info.h"
|
||||||
|
#include "dynarray.h"
|
||||||
|
|
||||||
|
typedef struct pkg {
|
||||||
|
char *path;
|
||||||
|
PkgInfo *info;
|
||||||
|
DynArray *files;
|
||||||
|
int compression;
|
||||||
|
} Pkg;
|
||||||
|
|
||||||
|
Pkg *package_read_archive(const char *pkg_path);
|
||||||
|
void package_free(Pkg ** ptp);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,46 @@
|
||||||
|
#include "package_info.h"
|
||||||
|
|
||||||
|
PkgInfo *package_info_init() {
|
||||||
|
PkgInfo *pkg_info = calloc(1, sizeof(PkgInfo));
|
||||||
|
|
||||||
|
pkg_info->groups = dynarray_init(4);
|
||||||
|
pkg_info->licenses = dynarray_init(4);
|
||||||
|
pkg_info->replaces = dynarray_init(4);
|
||||||
|
pkg_info->depends = dynarray_init(4);
|
||||||
|
pkg_info->conflicts = dynarray_init(4);
|
||||||
|
pkg_info->provides = dynarray_init(4);
|
||||||
|
pkg_info->optdepends = dynarray_init(4);
|
||||||
|
pkg_info->makedepends = dynarray_init(4);
|
||||||
|
pkg_info->checkdepends = dynarray_init(4);
|
||||||
|
|
||||||
|
return pkg_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
void package_info_free(PkgInfo **ptp) {
|
||||||
|
PkgInfo *pkg_info = *ptp;
|
||||||
|
|
||||||
|
FREE_STRING(pkg_info->name);
|
||||||
|
FREE_STRING(pkg_info->base);
|
||||||
|
FREE_STRING(pkg_info->version);
|
||||||
|
FREE_STRING(pkg_info->description);
|
||||||
|
FREE_STRING(pkg_info->url);
|
||||||
|
FREE_STRING(pkg_info->arch);
|
||||||
|
FREE_STRING(pkg_info->packager);
|
||||||
|
FREE_STRING(pkg_info->pgpsig);
|
||||||
|
|
||||||
|
dynarray_free(&pkg_info->groups);
|
||||||
|
dynarray_free(&pkg_info->licenses);
|
||||||
|
dynarray_free(&pkg_info->replaces);
|
||||||
|
dynarray_free(&pkg_info->depends);
|
||||||
|
dynarray_free(&pkg_info->conflicts);
|
||||||
|
dynarray_free(&pkg_info->provides);
|
||||||
|
dynarray_free(&pkg_info->optdepends);
|
||||||
|
dynarray_free(&pkg_info->makedepends);
|
||||||
|
dynarray_free(&pkg_info->checkdepends);
|
||||||
|
|
||||||
|
*ptp = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void package_info_parse(PkgInfo *pkg_info, const char *pkg_info_str) {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
#ifndef VIETER_PACKAGE_INFO
|
||||||
|
#define VIETER_PACKAGE_INFO
|
||||||
|
|
||||||
|
#define FREE_STRING(sp) if (sp != NULL) free(sp)
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "dynarray.h"
|
||||||
|
|
||||||
|
typedef struct pkg_info {
|
||||||
|
char *name;
|
||||||
|
char *base;
|
||||||
|
char *version;
|
||||||
|
char *description;
|
||||||
|
int64_t size;
|
||||||
|
int64_t csize;
|
||||||
|
char *url;
|
||||||
|
char *arch;
|
||||||
|
int64_t build_date;
|
||||||
|
char *packager;
|
||||||
|
char *pgpsig;
|
||||||
|
int64_t pgpsigsize;
|
||||||
|
|
||||||
|
DynArray *groups;
|
||||||
|
DynArray *licenses;
|
||||||
|
DynArray *replaces;
|
||||||
|
DynArray *depends;
|
||||||
|
DynArray *conflicts;
|
||||||
|
DynArray *provides;
|
||||||
|
DynArray *optdepends;
|
||||||
|
DynArray *makedepends;
|
||||||
|
DynArray *checkdepends;
|
||||||
|
} PkgInfo;
|
||||||
|
|
||||||
|
PkgInfo *package_info_init();
|
||||||
|
void package_info_parse(PkgInfo *pkg_info, const char *pkg_info_str);
|
||||||
|
void package_info_free(PkgInfo **ptp);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue