forked from vieter-v/libvieter
Compare commits
4 Commits
4cacb1534f
...
031e28ed33
Author | SHA1 | Date |
---|---|---|
GreekStapler | 031e28ed33 | |
GreekStapler | 41fabe21a2 | |
GreekStapler | e4d6ffc403 | |
GreekStapler | 307e7ba6e9 |
|
@ -1,21 +1,23 @@
|
|||
#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>
|
||||
|
||||
typedef struct vieter_package vieter_package;
|
||||
|
||||
typedef enum vieter_package_error {
|
||||
vieter_package_ok = 0,
|
||||
vieter_package_unarchive_error = 1,
|
||||
vieter_package_stat_error = 2
|
||||
} vieter_package_error;
|
||||
|
||||
/*
|
||||
* Allocate an empty package
|
||||
*/
|
||||
vieter_package *vieter_package_init();
|
||||
|
||||
/*
|
||||
* Parse package file into something usable by libvieter.
|
||||
* The pointer returned by this function will need to freed at a later point.
|
||||
*/
|
||||
vieter_package *vieter_package_read_archive(const char *pkg_path);
|
||||
vieter_package_error vieter_package_read_archive(vieter_package *pkg, const char *pkg_path);
|
||||
|
||||
/*
|
||||
* Deallocate a package.
|
||||
|
|
|
@ -1,30 +1,29 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <archive.h>
|
||||
#include <archive_entry.h>
|
||||
|
||||
#include "vieter_package_internal.h"
|
||||
#include "sha256.h"
|
||||
|
||||
#define SMALL_BUFF_SIZE 128
|
||||
|
||||
#define ADD_STRING(section, field) if (pkg_info->field != 0) { \
|
||||
snprintf(aux, SMALL_BUFF_SIZE, section, pkg_info->field); \
|
||||
if (buff_size < strlen(description) + SMALL_BUFF_SIZE + 1) { \
|
||||
size_to_be_written = snprintf(aux, small_buff_size, section, pkg_info->field); \
|
||||
if (size_to_be_written > small_buff_size) { \
|
||||
aux = realloc(aux, size_to_be_written + 1); \
|
||||
small_buff_size = size_to_be_written + 1; \
|
||||
snprintf(aux, small_buff_size, section, pkg_info->field); \
|
||||
} \
|
||||
if (buff_size < strlen(description) + small_buff_size + 1) { \
|
||||
description = realloc(description, buff_size * 2); \
|
||||
buff_size *= 2; \
|
||||
} \
|
||||
strcat(description, aux); \
|
||||
}
|
||||
|
||||
#define ADD_ARRAY(section, field) i = 0; if (pkg_info->field != NULL) { \
|
||||
snprintf(aux, SMALL_BUFF_SIZE, section, pkg_info->field->array[i]); i++; \
|
||||
if (buff_size < strlen(description) + SMALL_BUFF_SIZE + 1) { \
|
||||
description = realloc(description, buff_size * 2); \
|
||||
buff_size *= 2; \
|
||||
} \
|
||||
strcat(description, aux); \
|
||||
ADD_STRING(section, field->array[i]); i++; \
|
||||
while (pkg_info->field->array[i] != NULL) { \
|
||||
snprintf(aux, SMALL_BUFF_SIZE, "\n%s", pkg_info->field->array[i]); i++; \
|
||||
if (buff_size < strlen(description) + SMALL_BUFF_SIZE + 1) { \
|
||||
description = realloc(description, buff_size * 2); \
|
||||
buff_size *= 2; \
|
||||
} \
|
||||
strcat(description, aux); \
|
||||
ADD_STRING("\n%s", field->array[i]); i++; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
@ -41,7 +40,7 @@ vieter_package *vieter_package_init() {
|
|||
return calloc(sizeof(vieter_package_info), 1);
|
||||
}
|
||||
|
||||
vieter_package *vieter_package_read_archive(const char *pkg_path) {
|
||||
vieter_package_error vieter_package_read_archive(vieter_package *pkg, const char *pkg_path) {
|
||||
struct archive *a = archive_read_new();
|
||||
struct archive_entry *entry = archive_entry_new();
|
||||
|
||||
|
@ -58,7 +57,7 @@ vieter_package *vieter_package_read_archive(const char *pkg_path) {
|
|||
|
||||
// Exit early if we weren't able to successfully open the archive for reading
|
||||
if (r != ARCHIVE_OK) {
|
||||
return NULL;
|
||||
return vieter_package_unarchive_error;
|
||||
}
|
||||
|
||||
int compression_code = archive_filter_code(a, 0);
|
||||
|
@ -104,7 +103,9 @@ vieter_package *vieter_package_read_archive(const char *pkg_path) {
|
|||
struct stat stats;
|
||||
|
||||
if (stat(pkg_path, &stats) != 0) {
|
||||
return NULL;
|
||||
// errno is set if stat() fails; the calling function should check
|
||||
// the value of errno in case vieter_package_stat_error is returned
|
||||
return vieter_package_stat_error;
|
||||
}
|
||||
|
||||
pkg_info->csize = stats.st_size;
|
||||
|
@ -112,31 +113,31 @@ vieter_package *vieter_package_read_archive(const char *pkg_path) {
|
|||
archive_read_free(a);
|
||||
|
||||
// Create final return value
|
||||
vieter_package *pkg = vieter_package_init();
|
||||
pkg->path = strdup(pkg_path);
|
||||
pkg->info = pkg_info;
|
||||
pkg->files = files;
|
||||
pkg->compression = compression_code;
|
||||
|
||||
return pkg;
|
||||
return vieter_package_ok;
|
||||
}
|
||||
|
||||
void vieter_package_sha256sum(vieter_package *pkg, char *res) {
|
||||
FILE *f = fopen(pkg->path, "r");
|
||||
fseek(f, 0, SEEK_END);
|
||||
size_t size = ftell(f);
|
||||
rewind(f);
|
||||
unsigned char *in = malloc(size);
|
||||
fread(in, 1, size, f);
|
||||
fclose(f);
|
||||
// Try to read 100KiB at a time
|
||||
unsigned char *in = malloc(102400);
|
||||
// Actual number of bytes read
|
||||
size_t read_size;
|
||||
|
||||
unsigned char hash[32];
|
||||
SHA256_CTX *ctx = malloc(sizeof(SHA256_CTX));
|
||||
|
||||
sha256_init(ctx);
|
||||
sha256_update(ctx, in, size);
|
||||
while ((read_size = fread(in, 1, 102400, f)) != 0) {
|
||||
sha256_update(ctx, in, read_size);
|
||||
}
|
||||
unsigned char hash[SHA256_BLOCK_SIZE];
|
||||
|
||||
sha256_final(ctx, hash);
|
||||
|
||||
fclose(f);
|
||||
free(in);
|
||||
free(ctx);
|
||||
|
||||
|
@ -147,8 +148,8 @@ void vieter_package_sha256sum(vieter_package *pkg, char *res) {
|
|||
unsigned int half_byte = 0;
|
||||
int j = 0;
|
||||
|
||||
// We advance in the string 2 bytes for every one byte of the hash
|
||||
for (int i = 0; i < 32; i++) {
|
||||
// We advance 2 bytes in the string for every one byte of the hash
|
||||
for (int i = 0; i < SHA256_BLOCK_SIZE; i++) {
|
||||
// We transform the first half byte into the second character to keep
|
||||
// each byte from becoming reversed in the final string
|
||||
half_byte = hash[i] & 0b1111;
|
||||
|
@ -170,19 +171,32 @@ void vieter_package_sha256sum(vieter_package *pkg, char *res) {
|
|||
res[j] = '\0';
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *vieter_package_to_description(vieter_package *pkg) {
|
||||
vieter_package_info *pkg_info = pkg->info;
|
||||
|
||||
size_t buff_size = 1024;
|
||||
char aux[SMALL_BUFF_SIZE];
|
||||
int small_buff_size = 128;
|
||||
int size_to_be_written;
|
||||
char *aux = malloc(sizeof(char) * small_buff_size);
|
||||
char *description = malloc(sizeof(char) * buff_size);
|
||||
// Helper variable for ADD_ARRAY macro
|
||||
int i;
|
||||
|
||||
// special case for FILENAME
|
||||
// assuming .pkg.tar.zst; other formats are valid, this should account for that
|
||||
snprintf(aux, SMALL_BUFF_SIZE, "%%FILENAME%%\n%s-%s-%s.pkg.tar.zst", pkg_info->name,
|
||||
size_to_be_written = snprintf(aux, small_buff_size, "%%FILENAME%%\n%s-%s-%s.pkg.tar.zst", pkg_info->name,
|
||||
pkg_info->version, pkg_info->arch);
|
||||
|
||||
// We neither want to let an arbritrarily long input to overflow the buffer
|
||||
// nor to truncate perfectly valid inputs
|
||||
if (size_to_be_written > small_buff_size) {
|
||||
aux = realloc(aux, size_to_be_written + 1);
|
||||
small_buff_size = size_to_be_written + 1;
|
||||
snprintf(aux, small_buff_size, "%%FILENAME%%\n%s-%s-%s.pkg.tar.zst", pkg_info->name,
|
||||
pkg_info->version, pkg_info->arch);
|
||||
}
|
||||
strcpy(description, aux);
|
||||
|
||||
ADD_STRING("\n\n%%NAME%%\n%s", name);
|
||||
|
@ -193,11 +207,11 @@ char *vieter_package_to_description(vieter_package *pkg) {
|
|||
ADD_STRING("\n\n%%CSIZE%%\n%ld", csize);
|
||||
ADD_STRING("\n\n%%ISIZE%%\n%ld", size);
|
||||
|
||||
char checksum[65];
|
||||
char checksum[SHA256_BLOCK_SIZE * 2 + 1];
|
||||
vieter_package_sha256sum(pkg, checksum);
|
||||
|
||||
snprintf(aux, SMALL_BUFF_SIZE, "\n\n%%SHA256SUM%%\n%s", checksum);
|
||||
if (buff_size < strlen(description) + SMALL_BUFF_SIZE + 1) {
|
||||
snprintf(aux, small_buff_size, "\n\n%%SHA256SUM%%\n%s", checksum);
|
||||
if (buff_size < strlen(description) + small_buff_size + 1) {
|
||||
description = realloc(description, buff_size * 2);
|
||||
buff_size *= 2;
|
||||
}
|
||||
|
@ -216,8 +230,7 @@ char *vieter_package_to_description(vieter_package *pkg) {
|
|||
ADD_ARRAY("\n\n%%MAKEDEPENDS%%\n%s", makedepends);
|
||||
ADD_ARRAY("\n\n%%CHECKDEPENDS%%\n%s", checkdepends);
|
||||
|
||||
snprintf(aux, SMALL_BUFF_SIZE, "\n\n");
|
||||
strcat(description, aux);
|
||||
strcat(description, "\n\n");
|
||||
|
||||
return description;
|
||||
}
|
||||
|
|
|
@ -12,12 +12,18 @@ void vieter_package_dynarray_add(vieter_package_dynarray *da, const char *s) {
|
|||
// An empty vieter_package_dynarray does not have an allocated internal array yet
|
||||
if (da->size == 0) {
|
||||
da->array = malloc(sizeof(char*) * da->capacity);
|
||||
|
||||
// Initialise all char*'s to 0 so array[i] == NULL can be used to see if field is empty
|
||||
memset(da->array, 0, sizeof(char*) * da->capacity);
|
||||
}
|
||||
// Double array size if it's full
|
||||
else if (da->size == da->capacity) {
|
||||
// if the realloc fails, access to memory in da->array is lost
|
||||
da->array = realloc(da->array, sizeof(char*) * da->capacity * 2);
|
||||
da->capacity *= 2;
|
||||
|
||||
// Same as the previous memset, but only for newly allocated pointers
|
||||
memset(da->array + da->size, 0, sizeof(char*) * da->capacity / 2);
|
||||
}
|
||||
|
||||
da->array[da->size] = strdup(s);
|
||||
|
|
|
@ -39,8 +39,9 @@ void test_info_parse() {
|
|||
}
|
||||
|
||||
void test_pkg_read_archive_files() {
|
||||
vieter_package *pkg = vieter_package_read_archive("./test/package/xcursor-dmz-0.4.5-2-any.pkg.tar.zst");
|
||||
TEST_ASSERT_(pkg != NULL, "failure parsing pkg archive");
|
||||
vieter_package *pkg = vieter_package_init();
|
||||
vieter_package_error e = vieter_package_read_archive(pkg, "./test/package/xcursor-dmz-0.4.5-2-any.pkg.tar.zst");
|
||||
TEST_ASSERT_(e == vieter_package_ok, "failure parsing pkg archive");
|
||||
|
||||
FILE *f = fopen("./test/package/files", "r");
|
||||
TEST_ASSERT_(f != NULL, "could not find test files file in ./test/package");
|
||||
|
@ -58,12 +59,12 @@ void test_pkg_read_archive_files() {
|
|||
TEST_CHECK(pkg->compression = 14);
|
||||
|
||||
vieter_package_free(&pkg);
|
||||
|
||||
}
|
||||
|
||||
void test_pkg_read_archive_desc() {
|
||||
vieter_package *pkg = vieter_package_read_archive("./test/package/xcursor-dmz-0.4.5-2-any.pkg.tar.zst");
|
||||
TEST_ASSERT_(pkg != NULL, "failure parsing pkg archive");
|
||||
vieter_package *pkg = vieter_package_init();
|
||||
vieter_package_error e = vieter_package_read_archive(pkg, "./test/package/xcursor-dmz-0.4.5-2-any.pkg.tar.zst");
|
||||
TEST_ASSERT_(e == vieter_package_ok, "failure parsing pkg archive");
|
||||
|
||||
char *description = vieter_package_to_description(pkg);
|
||||
|
||||
|
|
Loading…
Reference in New Issue