10/29 added basic package processing

This commit is contained in:
lw-everestlinux committed 2025-10-29 09:01:29 -04:00
1 parent 21b3d18b5a
commit e591b71143
12 files changed
+903 -9

No files matched your search

+374
View File
@@ -0,0 +1,374 @@
#define _POSIX_C_SOURCE 200809L
#define _XOPEN_SOURCE 700
#include <errno.h>
#include <libconfig.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include "common.h"
/*
* semver_t
* DESCRIPTION: defines the struct for storing semantic versioning numbers
*/
typedef struct
{
int maj;
int min;
int pat;
char *tag;
}
semver_t;
/*
* dep_t
* DESCRIPTION: defines the struct for storing dependent packages
*/
typedef struct
{
char *dep_name;
semver_t dep_ver;
}
dep_t;
/*
* conf_t
* DESCRIPTION: defines the struct for storing conflicting packages
*/
typedef struct
{
char *conf_name;
semver_t conf_ver;
}
conf_t;
/*
* gl_pkg_t
* DESCRIPTION: defines the struct for storing packages in the gpkg format
*/
typedef struct
{
char *pkg_name;
semver_t pkg_ver;
char *pkg_desc;
char *pkg_maint;
char *pkg_copyright;
dep_t *pkg_dependencies;
conf_t *pkg_conflicts;
}
gl_pkg_t;
/* directory definitions */
static const dir_t gl_root = { "/glacier", 0750 };
static const dir_t gl_usr = { "/glacier/usr", 0700 };
static const dir_t gl_usr_index = { "/glacier/usr/index", 0700 };
static const dir_t gl_usr_store = { "/glacier/usr/store", 0700 };
static const dir_t gl_sys = { "/glacier/sys", 0700 };
static const dir_t gl_sys_index = { "/glacier/sys/index", 0700 };
static const dir_t gl_sys_store = { "/glacier/sys/store", 0700 };
/* null dependencies/conflicts for error throwing */
static dep_t null_dep = { "null", {-1, -1, -1, NULL} };
static conf_t null_conf = { "null", {-1, -1, -1, NULL} };
/*
* gl_pkgver
* DESCRIPTION: takes three integers and formats them as a semver_t struct
* PARAMETERS:
* ~ int major (the MAJOR number)
* ~ int minor (the MINOR number)
* ~ int patch (the PATCH number)
* RETURNS:
* ~ a pointer to a semver_t struct
*/
semver_t
gl_pkgver(int major, int minor, int patch)
{
semver_t pkgver = {major, minor, patch, NULL};
return pkgver;
}
semver_t
gl_parse_semver(const char *str)
{
semver_t v = {0, 0, 0, NULL};
if (!str) { return v; }
char buffer[64];
strncpy(buffer, str, sizeof(buffer) - 1);
buffer[sizeof(buffer) - 1] = '\0';
char *dash = strchr(buffer, '-');
if (dash) {
*dash = '\0';
dash++;
v.tag = strdup(dash);
}
sscanf(buffer, "%d.%d.%d", &v.maj, &v.min, &v.pat);
return v;
}
void
gl_free_semver(semver_T *v)
{
if (v && v->tag) { free (v->tag); };
}
gl_pkg_t empty = {
"null",
{-1, -1, -1, NULL},
"Null package for internal use. Returned upon an error.",
"null@null.null",
"null",
&null_dep,
&null_conf
};
int
gl_mkdir(dir_t *dir)
{
if (mkdir(dir -> path, dir -> mode) == 0) {
return 0;
}
if (errno == EEXIST) { return 0; }
perror("libglacier: mkdir");
return -1;
}
gl_pkg_t
*gl_spawn_pkg(char *name, semver_t *ver, char *desc, char *maint, char *copy, dep_t *dep, conf_t *conf)
{
gl_pkg_t *new_pkg = malloc(sizeof(gl_pkg_t));
if (!new_pkg) { return NULL; }
new_pkg -> pkg_name = name;
new_pkg -> pkg_ver = *ver;
new_pkg -> pkg_desc = desc;
new_pkg -> pkg_maint = maint;
new_pkg -> pkg_copyright = copy;
new_pkg -> pkg_dependencies = dep;
new_pkg -> pkg_conflicts = conf;
return new_pkg;
}
int
gl_gpm2pkg(const char *filename, gl_pkg_t *pkg)
{
config_t cfg;
config_setting_t *deps, *confs;
const char *tmp_str;
config_init(&cfg);
if (!config_read_file(&cfg, filename)) {
return ENOENT;
}
if (config_lookup_string(&cfg, "PKG_NAME", &tmp_str)) { pkg->pkg_name = strdup(tmp_str); }
if (config_lookup_string(&cfg, "PKG_DESC", &tmp_str)) { pkg->pkg_desc = strdup(tmp_str); }
if (config_lookup_string(&cfg, "PKG_MAINT", &tmp_str)) { pkg->pkg_maint = strdup(tmp_str); }
if (config_lookup_string(&cfg, "PKG_COPYRIGHT", &tmp_str)) { pkg->pkg_copyright = strup(tmp_str); }
if (config_lookup_string(&cfg, "PKG_VER", &tmp_str)) { pkg->pkg_ver = gl_parse_semver(tmp_str); }
deps = config_lookup(&cfg, "PKG_DEPS");
if (deps && config_setting_is_list(deps)) {
int count = config_setting_length(deps);
pkg->pkg_dependencies = calloc(count + 1, sizeof(dep_t));
for (int i = 0; i < count; i++) {
config_setting_t *d = config_setting_get_elem(deps, i);
const char *dep_name = NULL;
const char *dep_ver = NULL;
config_setting_lookup_string(d, "PKG_NAME", &dep_name);
config_setting_lookup_string(d, "PKG_VER", &dep_ver);
pkg->pkg_dependencies[i].dep_name = dep_name ? strdup(dep_name) : NULL;
pkg->pkg_dependencies[i].dep_ver = parse_semver(dep_ver);
}
}
confs = config_lookup(&cfg, "PKG_CONFS");
if (confs && config_setting_is_list(confs)) {
int count = config_setting_length(confs);
pkg->pkg_conflicts = calloc(count + 1, sizeof(conf_t));
for (int i = 0; i < count; i++) {
config_setting_t *c = config_setting_get_elem(confs, i);
const char *conf_name = NULL;
const char *conf_ver = NULL;
config_setting_lookup_string(c, "PKG_NAME", &conf_name);
config_setting_lookup_string(c, "PKG_VER", &conf_ver);
pkg->pkg_conflicts[i].conf_name = conf_name ? strdup(conf_name) : NULL;
pkg->pkg_conflicts[i].conf_ver = parse_semver(conf_ver);
}
}
config_destroy(&cfg);
return 0;
}
char
*gl_cat_dir(const dir_t *a, const dir_t *b)
{
size_t length = strlen(a->path) + strlen(b->path) + 2;
char *result = malloc(length);
if (!result) { return NULL; }
snprintf(result, length, "%s/%s", a->path, b-> path);
return result;
}
char
*gl_cat_dir_and_ver(const dir_t *base, const gl_pkg_t *pkg)
{
char version[32];
snprintf(version, sizeof(version), "%d.%d.%d",
pkg->pkg_ver.maj, pkg->pkg_ver.min, pkg->pkg_ver.pat);
size_t length = strlen(base->path) + strlen(pkg->pkg_name) + strlen(version) + 3;
char *result = malloc(length);
if (!result) { return NULL; }
snprintf(result, length, "%s/%s-%s", base->path, pkg->pkg_name, version);
return result;
}
dir_t
gl_return_dir(const dir_t *a, const dir_t *b, mode_t mode)
{
char *path = gl_cat_dir(a, b);
dir_t result = { path, mode };
return result;
}
dir_t
gl_return_dir_and_ver(const dir_t *base, gl_pkg_t *pkg, mode_t mode)
{
char *path = gl_cat_dir_and_ver(base, pkg);
dir_t result = { path, mode };
return result;
}
void
gl_free_path(char *path)
{
free(path);
}
void
gl_free_dir(dir_t *dir)
{
if (dir && dir->path) {
free(dir->path);
dir->path = NULL;
}
}
int
gl_prepare_pkgdir(gl_pkg_t *pkg, bool is_syspkg)
{
dir_t pkg_root = { pkg -> pkg_name, 0750 };
dir_t pkg_store_final;
dir_t pkg_index_final;
if (!is_syspkg) {
dir_t pkg_store_initial = gl_return_dir(&gl_usr_store, &pkg_root, 0750);
pkg_store_final = gl_return_dir_and_ver(&pkg_store_initial, pkg, 0750);
dir_t pkg_index_initial = gl_return_dir(&gl_usr_index, &pkg_root, 0750);
pkg_index_final = gl_return_dir_and_ver(&pkg_index_initial, pkg, 0750);
}
else if (is_syspkg) {
dir_t pkg_store_initial = gl_return_dir(&gl_sys_store, &pkg_root, 0750);
pkg_store_final = gl_return_dir_and_ver(&pkg_store_initial, pkg, 0750);
dir_t pkg_index_initial = gl_return_dir(&gl_sys_index, &pkg_root, 0750);
pkg_index_final = gl_return_dir_and_ver(&pkg_index_initial, pkg, 0750);
}
printf("%s\n%s\n", pkg_index_final.path, pkg_store_final.path);
gl_free_dir(&pkg_index_final);
gl_free_dir(&pkg_store_final);
return 0;
}
void
gl_show_pkg_props(const gl_pkg_t *pkg)
{
if (!pkg) {
printf("(null pkg)\n");
return;
}
printf("Package: %s\n", pkg->pkg_name);
printf("Version: %d.%d.%d\n", pkg->pkg_ver.maj, pkg->pkg_ver.min, pkg->pkg_ver.pat);
printf("Description: %s\n", pkg->pkg_desc);
printf("Maintainer: %s\n", pkg->pkg_maint);
printf("Copyright: %s\n", pkg->pkg_copyright);
if (pkg->pkg_dependencies) {
printf("Dependencies:\n");
dep_t *dep = pkg->pkg_dependencies;
printf("\t~ %s (%d.%d.%d)\n",
dep->dep_name,
dep->dep_ver.maj, dep->dep_ver.min, dep->dep_ver.pat);
}
else {
printf("Dependencies: (none)\n");
}
if (pkg->pkg_conflicts) {
printf("Conflicting packages:\n");
conf_t *conf = pkg->pkg_conflicts;
printf("\t~ %s (%d.%d.%d)\n",
conf->conf_name,
conf->conf_ver.maj, conf->conf_ver.min, conf->conf_ver.pat);
}
else {
printf("Conflicting packages: (none)\n");
}
}
int
main(void)
{
semver_t foo_v = gl_pkgver(1, 1, 1);
dep_t dep_empty = {"empty", foo_v};
conf_t conf_empty = {"empty", foo_v};
gl_pkg_t *foo = gl_spawn_pkg(
"foo",
&foo_v,
"example pkg",
"liamwaldron@everestlinux.org",
"GPL3",
&dep_empty,
&conf_empty
);
gl_show_pkg_props(foo);
gl_show_pkg_props(&empty);
if (gl_prepare_pkgdir(foo, false) == 0) {
printf("Package prepared\n");
return 0;
}
else {
return 1;
}
}