10/29 added basic package processing
This commit is contained in:
1 parent
21b3d18b5a
commit
e591b71143
12 files changed
+903
-9
No files matched your search
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user