Working as of 12/11

This commit is contained in:
2025-12-11 14:50:41 -05:00
parent e591b71143
commit e79c96a987
29 changed files with 664 additions and 48 deletions

View File

@@ -1,6 +1,6 @@
include config.mk include config.mk
all: prepare log log_test rt make_conf all: prepare log log_test rt istoreutils make_conf
@echo "libglacier-ng has finished building" @echo "libglacier-ng has finished building"
prepare: prepare:
@@ -16,16 +16,29 @@ log:
cp src/log.h build/include/glacier/log.h cp src/log.h build/include/glacier/log.h
log_test: log_test:
$(CC) $(CFLAGS) -shared -fPIC src/log.c -o build/lib/shared/lg_log.so $(CC) $(CFLAGS) -shared -fPIC src/log.c -o build/lib/shared/libglacier_log.so
rt: rt:
$(CC) $(CFLAGS) src/runtime.c -c -o build/lib/tmp/runtime.o $(CC) $(CFLAGS) src/runtime.c -c -o build/lib/tmp/runtime.o
istoreutils:
$(CC) $(CFLAGS) -shared -fPIC src/istoreutils.c \
-Lbuild/lib/shared -lglacier_log \
-Wl,-rpath,'$$ORIGIN' \
-o build/lib/shared/libglacier_istoreutils.so
make_conf: make_conf:
$(CC) $(CFLAGS) src/make_conf.c -c -o build/lib/tmp/make_conf.o $(CC) $(CFLAGS) src/make_conf.c -c -o build/lib/tmp/make_conf.o
install:
mkdir -p $(PREFIX)/lib/glacier/
install build/lib/shared/libglacier_log.so $(PREFIX)/lib/glacier/ -m 755
install build/lib/shared/libglacier_istoreutils.so $(PREFIX)/lib/glacier/ -m 755
install_test_dir: install_test_dir:
install build/lib/shared/lg_log.so $(TEST_DIR) install build/lib/shared/lg_log.so $(TEST_DIR)
install build/lib/shared/
clean: clean:
rm -rf build rm -rf build

51
README Normal file
View File

@@ -0,0 +1,51 @@
+ libglacier-ng
Backend APIs for the Glacier package manager
+ Modularity
Libglacier-ng is, by default, incredibly modular. The default featureset is very
minimal, but modules are available for installtion. These modules allow for features
such as HTML reports, remote package deployment, and more. Keep in mind that the
more features you have installed, the larger the attack surface is. The default
featureset should be sufficient for 99% of users.
+ Installation
Libglacier-ng is provided by default as multiple shared object files (.so).
Static compilation at this time is not possible because glacier-ng, which is primarily
written in Lua, requires shared objects.
Libglacier-ng depends on the following libraries:
~ libconfig
Once these dependencies are installed, clone this repository:
+---------------------------------------------------------------------+
| $ git clone https://git.everestlinux.org/EverestLinux/libglacier-ng |
+---------------------------------------------------------------------+
Enter the directory and make any desired modifications to config.mk:
+----------------------------------------------+
| $ cd libglacier |
| $ EDITOR="/bin/vim" # or your desired editor |
| $ ${EDITOR} config.mk |
+----------------------------------------------+
Build and install the library:
+-----------------+
| $ make $(nproc) |
| # make install |
+-----------------+
+ Documentation
Online documentation can be accessed at https://www.everestlinux.org/docs/libglacier
Offline documentationn can be accessed with the following command:
+--------------------+
| $ man 3 libglacier |
+--------------------+

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
lg_log.so

Binary file not shown.

Binary file not shown.

BIN
build/lib/tmp/istoreutils.o Normal file

Binary file not shown.

BIN
build/lib/tmp/lg_istoreutils.so Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -2,6 +2,8 @@
# config.mk # config.mk
# #
PREFIX ?= /usr
CFLAGS = -std=c11 -pedantic -O2 -flto -Wall -Wextra -Wshadow -Wformat=2 -Wconversion -Wpedantic -Werror CFLAGS = -std=c11 -pedantic -O2 -flto -Wall -Wextra -Wshadow -Wformat=2 -Wconversion -Wpedantic -Werror
TEST_DIR = /home/lw/Projects/glacier-ng/lib TEST_DIR = /home/lw/Projects/glacier-ng/lib

17
src/bar.gpm.cfg Normal file
View File

@@ -0,0 +1,17 @@
#
# bar
#
PKG_NAME = "bar";
PKG_VER = 1.0.0;
PKG_DESC = "example pkg";
PKG_MAINT = "liamwaldron@everestlinux.org";
PKG_COPYRIGHT = "GPL3";
PKG_DEPS = (
{ PKG_NAME = "foo"; PKG_VER = 1.1.1; };
);
PKG_CONFS = (
{};
);

View File

@@ -1,15 +1,21 @@
#ifndef COMMON_H_ #ifndef COMMON_H_
#define COMMON_H_ #define COMMON_H_
#ifndef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200809L #define _POSIX_C_SOURCE 200809L
#endif
#ifndef _DEFAULT_SOURCE
#define _DEFAULT_SOURCE #define _DEFAULT_SOURCE
#endif
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 700 #define _XOPEN_SOURCE 700
#endif
#include <sys/types.h> #include <sys/types.h>
typedef struct typedef struct
{ {
char *path; const char *path;
mode_t mode; mode_t mode;
} }
dir_t; dir_t;

132
src/dag.c Normal file
View File

@@ -0,0 +1,132 @@
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include "graph.h"
graph_t
*graph_create(void)
{
return calloc(1, sizeof(graph_t));
}
void
graph_free(graph_t *g)
{
if (!g) { return; }
for (size_t i = 0; i < g->node_count; i++) {
free(g->nodes[i]->edges);
free(g->nodes[i]);
}
free(g->nodes);
free(g);
}
graph_node_t
*graph_add_node(graph_t *g, void *data)
{
if (!g) { return NULL; }
graph_node_t *n = calloc(1, sizeof(graph_node_t));
if (!n) { return NULL; }
n->data = data;
graph_node_t **tmp = realloc(g->nodes, sizeof(*g->nodes) * (g->node_count + 1));
if (!tmp) {
free(n);
return NULL;
}
g->nodes = tmp;
g->nodes[g->node_count++] = n;
return n;
}
void
graph_add_edge(graph_t *g, graph_node_t *from, graph_node_t *to)
{
if (!g || !from || !to) { return; }
graph_node_t **tmp = realloc(from->edges, sizeof(*from->edges) * (from->edge_count + 1));
if (!tmp) { return; }
from->edges = tmp;
from->edges[from->edge_count++] = to;
}
static book
dfs_cycle(graph_node_t *n)
{
n->visited = true;
n->in_stack = true;
for (size_t i = 0; i < n->edge_count; i++) {
graph_node_t *child = n->edge[i];
if (!child->visited && dfs_cycle(child)) {
return true;
}
else if (child->in_stack) {
return true;
}
}
n->in_stack = false;
return false;
}
bool
graph_has_cycle(graph_t *g)
{
if (!g) { return false; }
for (size_t i = 0; i < g->node_count; i++) {
g->nodes[i]->visited = false;
g->nodes[i]->in_stack = false;
}
for (size_t i = 0; i < g->node_count; i++) {
if (!g->nodes[i]->visited && dfs_cycle(g->nodes[i])) {
return true;
}
return false;
}
}
static void
dfs_toposort(graph_node_t *n, void **result, size_t *index)
{
n->visited = true;
for (size_t i = 0; i < n->edge_count; i++) {
if (!n->edges[i]->visited) {
dfs_toposort(n->edges[i], result, index);
}
}
result[(*index)--] = n->data;
}
void
**graph_toposort(graph_t *g, size_t *out_count)
{
if (!g || !out_count) { return NULL; }
if (graph_has_cycle(g)) {
fprintf(stderr, "Error: dependency cycle detected\n");
return NULL;
}
*out_count = g->node_count;
void **order = calloc(g->node_count, sizeof(void *));
if (!order) { return NULL; }
for (size_t i = 0; i < g->node_count; i++) {
g->nodes[i]->visited = false;
}
ssize_t index = g->node_count - 1;
for (size_t i = 0; i < g->node_count; i++) {
if (!g->nodes[i]->visited) {
dfs_toposort(g->nodes[i], order, (size_t *)&index);
}
}
return order;
}

34
src/dag.h Normal file
View File

@@ -0,0 +1,34 @@
#ifndef DAG_H_
#define DAG_H_
#define _POSIX_C_SOURCE 200809L
#include <stdbool.h>
#include <stddef.h>
typedef struct graph_node graph_node_t;
typedef struct graph graph_t;
struct graph_node {
void *data;
graph_node_t **edges;
size_t edge_count;
bool visited;
bool in_stack;
};
struct graph {
graph_node_t **nodes;
size_t node_count;
};
graph_t *graph_create(void);
void graph_free(graph_t *g);
graph_node_t *graph_add_node(graph_t *g, void *data);
void graph_add_edge(graph_t *g, graph_node_t *from, graph_node_t *to);
bool graph_has_cycle(graph_t *g);
void **graph_toposort(graph_t *g, size_t *out_count);
#endif

8
src/glacier.cfg Normal file
View File

@@ -0,0 +1,8 @@
// If GL_ALLOW_NONFREE is false, software tagged as NONFREE cannot be installed,
// even if NONFREE is listed under GL_ALLOWED_LICENSES.
GL_ALLOW_NONFREE = false;
// GL_ALLOWED_LICENSES allows a user to configure which kinds of software Glacier
// is allowed to install.
GL_ALLOWED_LICENSES = [ "GPL", "GPL2", "GPL3", "BSD", "MIT", "APACHE" ];

View File

@@ -27,3 +27,5 @@
[2025-10-22 15:59:02] [ERR] Failed to install package glibc [2025-10-22 15:59:02] [ERR] Failed to install package glibc
[2025-10-22 15:59:07] [INFO] Glacier started with PID 12345 [2025-10-22 15:59:07] [INFO] Glacier started with PID 12345
[2025-10-22 15:59:07] [ERR] Failed to install package glibc [2025-10-22 15:59:07] [ERR] Failed to install package glibc
[2025-10-29 09:19:46] [INFO] Glacier started with PID 12345
[2025-10-29 09:19:46] [ERR] Failed to install package glibc

View File

@@ -0,0 +1 @@
<svg version="1.1" viewBox="0.0 0.0 649.0 485.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><clipPath id="p.0"><path d="m0 0l649.0 0l0 485.0l-649.0 0l0 -485.0z" clip-rule="nonzero"/></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l649.0 0l0 485.0l-649.0 0z" fill-rule="evenodd"/><path fill="#88c0d0" d="m31.519686 468.3622l194.38202 -378.26773l133.83844 378.26773z" fill-rule="evenodd"/><path stroke="#88c0d0" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m31.519686 468.3622l194.38202 -378.26773l133.83844 378.26773z" fill-rule="evenodd"/><path fill="#5e81ac" d="m412.7575 222.75516l-135.9685 261.5433l-135.9685 -261.5433z" fill-rule="evenodd"/><path stroke="#5e81ac" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m412.7575 222.75516l-135.9685 261.5433l-135.9685 -261.5433z" fill-rule="evenodd"/><path fill="#666666" d="m276.48984 484.30145l135.9685 -261.5433l135.96854 261.5433z" fill-rule="evenodd"/><path stroke="#666666" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m276.48984 484.30145l135.9685 -261.5433l135.96854 261.5433z" fill-rule="evenodd"/><path fill="#5e81ac" d="m0 484.29922l130.77936 -246.89764l98.44899 246.89764z" fill-rule="evenodd"/><path stroke="#5e81ac" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m0 484.29922l130.77936 -246.89764l98.44899 246.89764z" fill-rule="evenodd"/><path fill="#5e81ac" d="m276.4908 484.3176l185.43307 -378.26773l185.43304 378.26773z" fill-rule="evenodd"/><path stroke="#5e81ac" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m276.4908 484.3176l185.43307 -378.26773l185.43304 378.26773z" fill-rule="evenodd"/><path fill="#88c0d0" d="m205.22047 134.99213l71.574814 -134.99213l71.5748 134.99213z" fill-rule="evenodd"/><path stroke="#88c0d0" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m205.22047 134.99213l71.574814 -134.99213l71.5748 134.99213z" fill-rule="evenodd"/><path fill="#5e81ac" d="m140.82677 222.7559l70.13112 -134.99213l131.67477 0l70.131134 134.99213z" fill-rule="evenodd"/><path stroke="#5e81ac" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m140.82677 222.7559l70.13112 -134.99213l131.67477 0l70.131134 134.99213z" fill-rule="evenodd"/><path fill="#5e81ac" d="m205.21523 99.13386l30.761414 -63.27559l112.3882 63.27559z" fill-rule="evenodd"/><path stroke="#5e81ac" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m205.21523 99.13386l30.761414 -63.27559l112.3882 63.27559z" fill-rule="evenodd"/><path fill="#5e81ac" d="m205.22047 199.58267l195.68504 0l0 110.77167l-195.68504 0z" fill-rule="evenodd"/><path stroke="#5e81ac" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m205.22047 199.58267l195.68504 0l0 110.77167l-195.68504 0z" fill-rule="evenodd"/><path fill="#5e81ac" d="m385.25198 283.9475l-106.83533 198.3937l-97.82611 -198.3937z" fill-rule="evenodd"/><path stroke="#5e81ac" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m385.25198 283.9475l-106.83533 198.3937l-97.82611 -198.3937z" fill-rule="evenodd"/></g></svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -0,0 +1 @@
<svg version="1.1" viewBox="0.0 0.0 433.41207349081367 433.5275590551181" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><clipPath id="p.0"><path d="m0 0l433.41208 0l0 433.52756l-433.41208 0l0 -433.52756z" clip-rule="nonzero"/></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l433.41208 0l0 433.52756l-433.41208 0z" fill-rule="evenodd"/><path fill="#88c0d0" d="m0 433.38583l392.89893 -433.38583l40.486908 0l-392.89893 433.38583z" fill-rule="evenodd"/><path fill="#88c0d0" d="m433.38583 433.38583l-392.89893 -433.38583l-40.486904 0l392.89893 433.38583z" fill-rule="evenodd"/><path fill="#5e81ac" d="m199.2126 0l34.960632 0l0 433.38583l-34.960632 0z" fill-rule="evenodd"/><path fill="#5e81ac" d="m433.38583 199.2126l0 34.960632l-433.38583 0l0 -34.960632z" fill-rule="evenodd"/></g></svg>

After

Width:  |  Height:  |  Size: 923 B

View File

@@ -5,34 +5,48 @@
<link type="text/css" rel="stylesheet" href="nord.css"/> <link type="text/css" rel="stylesheet" href="nord.css"/>
</head> </head>
<body> <body>
<div class="sidenav">
<img src="img/glacier-nord.svg" alt="glacier-logo">
</div>
<div class="main">
<h1>Packaging report: [DATE HERE]</h1> <h1>Packaging report: [DATE HERE]</h1>
<hr></hr> <hr></hr>
<h2>Statistics</h2> <h2>Statistics</h2>
<p>Total transactions: [N_TRANSACTIONS]</p> <p>Total transactions: [N_TRANSACTIONS]</p>
<p>Completed transactions: [N_COMP_TRANSACT]</p> <p>Completed transactions: [N_COMP_TRANSACT]</p>
<p>Failed transactions: [N_FAIL_TRANSACT]</p> <p>Failed transactions: [N_FAIL_TRANSACT]</p>
<p>Writes performed to <code>/glacier/index</code>: [N_IND_WRITES]</p> <bigcodehead><strong>Indices modified</strong></bigcodehead>
<hr></hr> <div class="bigcode">
<p>f localhost:/glacier/usr/index/1000/mmddyyyy@hhmm</p>
<p>f 192.168.30.1:/glacier/usr/index/1000/mmddyyyy@hhmm</p>
<p>f 192.168.30.2:/glacier/usr/index/1000/mmddyyyy@hhmm</p>
</div>
<h2>Systems</h2> <h2>Systems</h2>
<p>Performed these changes on the following systems:</p> <bigcodehead><strong>Systems modified</strong></bigcodehead>
<code> <div class="bigcode">
<p>* localhost</p> <p>* localhost</p>
<p>* 192.168.30.0/24</p> <p>* 192.168.30.0/24</p>
<p>&emsp;&emsp;* 192.168.30.1</p> <p>&emsp;&emsp;&emsp;&emsp;* 192.168.30.1</p>
</code> <p>&emsp;&emsp;&emsp;&emsp;* 192.168.30.2</p>
<hr></hr> </div>
<h2>Insights</h2> <h2>Insights</h2>
<!--PACKAGE INSIGHTS BEGIN HERE--> <!--PACKAGE INSIGHTS BEGIN HERE-->
<p><strong>foo</strong><p> <bigcodehead><strong>world::foo-1.0.1</strong></bigcodehead>
<p>1.0.0 ---&gt; 1.0.1</p> <div class="bigcode">
<p>Files:</p> <p>d localhost:/glacier/usr/store/1000/world::foo-1.0.1</p>
<code> <p>d 192.168.30.1:/glacier/usr/store/1000/world::foo-1.0.1</p>
<p>f&emsp;&emsp;/usr/glacier/index/lw/pkginfo/foo_current/foo.gpm (e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855)<p> <p>d 192.168.30.2:/glacier/usr/store/1000/world::foo-1.0.1</p>
<p>f&emsp;&emsp;usr/glacier/index/lw/pkgdata/foo_current/bin/foo (e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855)<p> </div>
<p>l&emsp;&emsp;/home/lw/.glacier/store/foo -&gt; /usr/glacier/index/lw/pkgdata/foo_current<p> <p></p>
</code> <bigcodehead><strong>world::bar-2.3.5</strong></bigcodehead>
<hr> <div class="bigcode">
<p>d localhost:/glacier/usr/store/1000/world::bar-2.3.5</p>
<p>d 192.168.30.1:/glacier/usr/store/1000/world::bar-2.3.5</p>
<p>d 192.168.30.2:/glacier/usr/store/1000/workd::bar-2.3.5</p>
</div>
<h2>Problems</h2> <h2>Problems</h2>
<p>No problems to report.</p>
</div>
</body> </body>
</html> </html>

184
src/istoreutils.c Normal file
View File

@@ -0,0 +1,184 @@
#include <errno.h>
#include <linux/limits.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <sys/stat.h>
#include "common.h"
#include "log.h"
#include "pkg.h"
typedef enum
{
INDEX,
STORE
}
index_store_t;
static const dir_t usr_index = { "/glacier/usr/index", 0700 };
static const dir_t sys_index = { "/glacier/sys/index", 0700 };
static const dir_t usr_store = { "/glacier/usr/store", 0700 };
static const dir_t sys_store = { "/glacier/sys/store", 0700 };
bool
gl_usr_istore_exists(index_store_t index_or_store, int uid)
{
char path[PATH_MAX];
struct stat st;
switch (index_or_store) {
case INDEX:
snprintf(path, sizeof(path), "%s/%d", usr_index.path, uid);
break;
case STORE:
snprintf(path, sizeof(path), "%s/%d", usr_store.path, uid);
break;
default:
printf("libglacier: argument index_or_store of function gl_usr_istore_exists must be INDEX or STORE\n");
return NULL;
}
if (stat(path, &st) != 0) {
return false;
}
return S_ISDIR(st.st_mode);
}
bool
gl_sys_istore_exists(index_store_t index_or_store)
{
char path[PATH_MAX];
struct stat st;
switch (index_or_store) {
case INDEX:
snprintf(path, sizeof(path), "%s", sys_index.path);
break;
case STORE:
snprintf(path, sizeof(path), "%s", sys_store.path);
break;
default:
printf("libglacier: argument index_or_store of function gl_sys_istore_exists must be INDEX or STORE\n");
return NULL;
}
if (stat(path, &st) != 0) {
return false;
}
return S_ISDIR(st.st_mode);
}
int
gl_init_user(int uid)
{
if (uid < 1000) {
return 2;
}
char ind_path[PATH_MAX];
char sto_path[PATH_MAX];
snprintf(ind_path, sizeof(ind_path), "%s/%d", usr_index.path, uid);
snprintf(sto_path, sizeof(sto_path), "%s/%d", usr_store.path, uid);
if (mkdir(ind_path, 0700) == -1) {
switch (errno) {
case EACCES:
lg_printf(2, "Cannot create index: permission denied");
return 1;
break;
case EEXIST:
lg_printf(2, "Cannot create index: directory already exists");
return 1;
break;
case ENOENT:
/* should never happen, but here for completeness */
lg_printf(2, "Cannot create index: parent directory does not exist");
return 1;
break;
case ENOSPC:
lg_printf(2, "Cannot create index: no space left on device");
return 1;
break;
case EROFS:
lg_printf(2, "Cannot create index: read only filesystem");
return 1;
break;
default:
printf("libglacier: mkdir error in function gl_init_user\n");
return -1;
break;
}
}
if (mkdir(sto_path, 0700) == -1) {
switch (errno) {
case EACCES:
lg_printf(2, "Cannot create store: permission denied");
return 1;
break;
case EEXIST:
lg_printf(2, "Cannot create store: directory already exists");
return 1;
break;
case ENOENT:
/* should never happen, but here for completeness */
lg_printf(2, "Cannot create store: parent directory does not exist");
return 1;
break;
case ENOSPC:
lg_printf(2, "Cannot create store: no space left on device");
return 1;
break;
case EROFS:
lg_printf(2, "Cannot create store: read only filesystem");
return 1;
break;
default:
printf("libglacier: mkdir error in function gl_init_user\n");
return -1;
break;
}
}
return 0;
}
static void
trim(char *s)
{
char *p = s;
while (*p && isspace((unsigned char)*p)) {
p++;
}
if (p != s) {
memmove(s, p, strlen(p) + 1);
}
size_t len = strlen(s);
while (len && isspace((unsigned char)s[len - 1])) {
s[len--] = 0;
}
}
static char
*dupstr(const char *s)
{
size_t n = strlen(s);
char *p = malloc(n + 1);
if (!p) {
return NULL;
}
memcpy(p, s, n + 1);
return p;
}
int
gl_parse_index(struct gindex *idx, FILE *f)
{}

View File

@@ -144,18 +144,18 @@ lg_gpkg_help(int argc, char *argv[])
{ {
(void)argc; (void)argc;
printf("%s: Manage the user package index\n", argv[0]); printf("%s: Install, update, and remove packages\n", argv[0]);
printf("usage: %s [-hv] [-fux PKG]\n", argv[0]); printf("usage: %s [-hv] [-fux PKG] [-V]\n", argv[0]);
printf("\n"); printf("\n");
printf("{-h}\tShow this message\n" printf("%-25s %s\n", "{-h --help}", "Show this message");
"{-v}\tShow the current version\n" printf("%-25s %s\n", "{-v --version}", "Show the current version");
"{-f} PKG...\tMerge a package into the user index\n" printf("%-25s %s\n", "{-f --merge} PKG...", "Merge a package into the index and store");
"{-u} PKG...\tUpgrade a merged package\n" printf("%-25s %s\n", "{-u --update} PKG...", "Upgrade a merged package");
"{-x} PKG...\tRemove a merged package\n" printf("%-25s %s\n", "{-x --remove} PKG...", "Remove a package from the index and store");
"\n" printf("%-25s %s\n", "{-V --verbose}", "Log events more verbosely");
"This program is free software.\n" printf("\n");
"See the GNU GPL version 3 for details.\n" printf("This program is free software.\n");
); printf("See the GNU GPL version 3 for details.\n");
} }
void void
@@ -177,18 +177,21 @@ lg_syspkg_help(int argc, char *argv[])
); );
} }
int void
main(int argc, char *argv[]) lg_gstore_help(int argc, char *argv[])
{ {
lg_gpkg_help(argc, argv); (void)argc;
lg_syspkg_help(argc, argv);
lg_printf(LG_INFO, "info");
lg_printf(LG_WARN, "warning");
lg_printf(LG_ERR, "error");
lg_printf(LG_SUCCESS, "success");
lg_log(true, "./glacier.log", LOG_INFO, "Glacier started with PID %d", 12345); printf("%s: Manage Glacier packages indexes/stores\n", argv[0]);
lg_log(true, "./glacier.log", LOG_ERR, "Failed to install package %s", "glibc"); printf("usage: %s [-hv] [-snx UID] [-V]\n", argv[0]);
printf("\n");
return 0; printf("%-25s %s\n", "{-h --help}", "Show this message");
printf("%-25s %s\n", "{-v --version}", "Show the current version");
printf("%-25s %s\n", "{-s --sync} UID", "Sync UID's store with their index");
printf("%-25s %s\n", "{-n --new} UID", "Create new store and index for UID");
printf("%-25s %s\n", "{-x --delete} UID", "Delete UID's store and index");
printf("%-25s %s\n", "{-V --verbose}", "Log events more verbosely");
printf("\n");
printf("This program is free software.\n");
printf("See the GNU GPL version 3 for details.\n");
} }

View File

@@ -3,12 +3,14 @@
#include <errno.h> #include <errno.h>
#include <libconfig.h> #include <libconfig.h>
#include <limits.h>
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h>
#include "common.h" #include "common.h"
@@ -80,6 +82,24 @@ static const dir_t gl_sys_store = { "/glacier/sys/store", 0700 };
static dep_t null_dep = { "null", {-1, -1, -1, NULL} }; static dep_t null_dep = { "null", {-1, -1, -1, NULL} };
static conf_t null_conf = { "null", {-1, -1, -1, NULL} }; static conf_t null_conf = { "null", {-1, -1, -1, NULL} };
static char
*join_with_cwd(const char *path)
{
char cwd[PATH_MAX];
if (!getcwd(cwd, sizeof(cwd))) {
perror("getcwd");
return NULL;
}
size_t length = strlen(cwd + strlen(path) + 2);
char *result = malloc(length);
if (!result) { return NULL; }
snprintf(result, length, "%s/%s", cwd, path);
return result;
}
/* /*
* gl_pkgver * gl_pkgver
* DESCRIPTION: takes three integers and formats them as a semver_t struct * DESCRIPTION: takes three integers and formats them as a semver_t struct
@@ -119,7 +139,7 @@ gl_parse_semver(const char *str)
} }
void void
gl_free_semver(semver_T *v) gl_free_semver(semver_t *v)
{ {
if (v && v->tag) { free (v->tag); }; if (v && v->tag) { free (v->tag); };
} }
@@ -164,7 +184,7 @@ gl_pkg_t
} }
int int
gl_gpm2pkg(const char *filename, gl_pkg_t *pkg) gl_gpm2gpkg(const char *filename, gl_pkg_t *pkg)
{ {
config_t cfg; config_t cfg;
config_setting_t *deps, *confs; config_setting_t *deps, *confs;
@@ -179,7 +199,7 @@ gl_gpm2pkg(const char *filename, gl_pkg_t *pkg)
if (config_lookup_string(&cfg, "PKG_NAME", &tmp_str)) { pkg->pkg_name = strdup(tmp_str); } 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_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_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_COPYRIGHT", &tmp_str)) { pkg->pkg_copyright = strdup(tmp_str); }
if (config_lookup_string(&cfg, "PKG_VER", &tmp_str)) { pkg->pkg_ver = gl_parse_semver(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"); deps = config_lookup(&cfg, "PKG_DEPS");
@@ -196,7 +216,7 @@ gl_gpm2pkg(const char *filename, gl_pkg_t *pkg)
config_setting_lookup_string(d, "PKG_VER", &dep_ver); 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_name = dep_name ? strdup(dep_name) : NULL;
pkg->pkg_dependencies[i].dep_ver = parse_semver(dep_ver); pkg->pkg_dependencies[i].dep_ver = gl_parse_semver(dep_ver);
} }
} }
@@ -214,7 +234,7 @@ gl_gpm2pkg(const char *filename, gl_pkg_t *pkg)
config_setting_lookup_string(c, "PKG_VER", &conf_ver); 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_name = conf_name ? strdup(conf_name) : NULL;
pkg->pkg_conflicts[i].conf_ver = parse_semver(conf_ver); pkg->pkg_conflicts[i].conf_ver = gl_parse_semver(conf_ver);
} }
} }
@@ -280,6 +300,35 @@ gl_free_dir(dir_t *dir)
} }
} }
void
gl_free_pkg(gl_pkg_t *pkg)
{
if (!pkg) return;
free(pkg->pkg_name);
free(pkg->pkg_desc);
free(pkg->pkg_maint);
free(pkg->pkg_copyright);
gl_free_semver(&pkg->pkg_ver);
if (pkg->pkg_dependencies) {
for (dep_t *d = pkg->pkg_dependencies; d->dep_name; d++) {
free(d->dep_name);
gl_free_semver(&d->dep_ver);
}
free(pkg->pkg_dependencies);
}
if (pkg->pkg_conflicts) {
for (conf_t *c = pkg->pkg_conflicts; c->conf_name; c++) {
free(c->conf_name);
gl_free_semver(&c->conf_ver);
}
free(pkg->pkg_conflicts);
}
}
int int
gl_prepare_pkgdir(gl_pkg_t *pkg, bool is_syspkg) gl_prepare_pkgdir(gl_pkg_t *pkg, bool is_syspkg)
{ {
@@ -364,6 +413,16 @@ main(void)
gl_show_pkg_props(foo); gl_show_pkg_props(foo);
gl_show_pkg_props(&empty); gl_show_pkg_props(&empty);
gl_pkg_t bar = {0};
char *bar_path = join_with_cwd("bar.gpm.cfg");
if (!bar_path) { return 1; }
if (gl_gpm2gpkg(bar_path, &bar) == 0) { gl_show_pkg_props(&bar); }
else { return 99; }
free(bar_path);
if (gl_prepare_pkgdir(foo, false) == 0) { if (gl_prepare_pkgdir(foo, false) == 0) {
printf("Package prepared\n"); printf("Package prepared\n");
return 0; return 0;
@@ -371,4 +430,7 @@ main(void)
else { else {
return 1; return 1;
} }
gl_free_pkg(foo);
gl_free_pkg(&bar);
} }

84
src/pkg.h Normal file
View File

@@ -0,0 +1,84 @@
#ifndef PKG_H_
#define PKG_H_
#define _POSIX_C_SOURCE 200809L
#define _XOPEN_SOURCE 700
#include <libconfig.h>
#include <stdbool.h>
#include <stddef.h>
#include <sys/stat.h>
#include "common.h"
typedef struct {
int maj;
int min;
int pat;
char *tag;
}
semver_t;
typedef struct {
char *dep_name;
semver_t dep_ver;
}
dep_t;
typedef struct {
char *conf_name;
semver_t conf_ver;
}
conf_t;
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;
extern const dir_t gl_root;
extern const dir_t gl_usr;
extern const dir_t gl_usr_index;
extern const dir_t gl_usr_store;
extern const dir_t gl_sys;
extern const dir_t gl_sys_index;
extern const dir_t gl_sys_store;
extern dep_t null_dep;
extern conf_t null_conf;
extern gl_pkg_t empty;
semver_t gl_pkgver(int major, int minor, int patch);
semver_t gl_parse_semver(const char *str);
void gl_free_semver(semver_t *v);
gl_pkg_t *gl_spawn_pkg(
char *name, semver_t *ver, char *desc,
char *maint, char *copy, dep_t *dep,
conf_t conf
);
void gl_show_pkg_props(const gl_pkg_t *pkg);
void gl_free_pkg(gl_pkg_t *pkg);
int gl_mkdir(dir_t *dir);
char *gl_cat_dir(const dir_t *a, const dir_t *b);
char *gl_cat_dir_and_ver(const dir_t *base, const gl_pkg_t *pkg);
dir_t gl_return_dir(const dir_t *a, const dir_t *b, mode_t mode);
dir_t gl_return_dir_and_ver(const dir_t *base, gl_pkg_t *pkg, mode_t mode);
void gl_free_path(char *path);
void gl_free_dir(dir_t *dir);
int gl_gpm2gpkg(const char *filename, gl_pkg_t pkg);
int gl_prepare_pkgdir(gl_pkg_t *pkg, bool is_syspkg);
char *join_with_cwd(const char *path);
#endif

View File

@@ -1 +0,0 @@
#ifndef

2
src/test_deps.c Normal file
View File

@@ -0,0 +1,2 @@
#include "dag.h"
#include

BIN
src/x_pkg

Binary file not shown.