Working as of 12/11
This commit is contained in:
17
Makefile
17
Makefile
@@ -1,6 +1,6 @@
|
||||
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"
|
||||
|
||||
prepare:
|
||||
@@ -16,16 +16,29 @@ log:
|
||||
cp src/log.h build/include/glacier/log.h
|
||||
|
||||
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:
|
||||
$(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:
|
||||
$(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 build/lib/shared/lg_log.so $(TEST_DIR)
|
||||
install build/lib/shared/
|
||||
|
||||
clean:
|
||||
rm -rf build
|
||||
|
||||
51
README
Normal file
51
README
Normal 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 |
|
||||
+--------------------+
|
||||
BIN
build/lib/shared/lg_istoreutils.so
Executable file
BIN
build/lib/shared/lg_istoreutils.so
Executable file
Binary file not shown.
Binary file not shown.
1
build/lib/shared/libgl_log.so
Symbolic link
1
build/lib/shared/libgl_log.so
Symbolic link
@@ -0,0 +1 @@
|
||||
lg_log.so
|
||||
BIN
build/lib/shared/libglacier_istoreutils.so
Executable file
BIN
build/lib/shared/libglacier_istoreutils.so
Executable file
Binary file not shown.
BIN
build/lib/shared/libglacier_log.so
Executable file
BIN
build/lib/shared/libglacier_log.so
Executable file
Binary file not shown.
BIN
build/lib/tmp/istoreutils.o
Normal file
BIN
build/lib/tmp/istoreutils.o
Normal file
Binary file not shown.
BIN
build/lib/tmp/lg_istoreutils.so
Executable file
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.
@@ -2,6 +2,8 @@
|
||||
# config.mk
|
||||
#
|
||||
|
||||
PREFIX ?= /usr
|
||||
|
||||
CFLAGS = -std=c11 -pedantic -O2 -flto -Wall -Wextra -Wshadow -Wformat=2 -Wconversion -Wpedantic -Werror
|
||||
|
||||
TEST_DIR = /home/lw/Projects/glacier-ng/lib
|
||||
|
||||
17
src/bar.gpm.cfg
Normal file
17
src/bar.gpm.cfg
Normal 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 = (
|
||||
{};
|
||||
);
|
||||
@@ -1,15 +1,21 @@
|
||||
#ifndef COMMON_H_
|
||||
#define COMMON_H_
|
||||
|
||||
#ifndef _POSIX_C_SOURCE
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#endif
|
||||
#ifndef _DEFAULT_SOURCE
|
||||
#define _DEFAULT_SOURCE
|
||||
#endif
|
||||
#ifndef _XOPEN_SOURCE
|
||||
#define _XOPEN_SOURCE 700
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *path;
|
||||
const char *path;
|
||||
mode_t mode;
|
||||
}
|
||||
dir_t;
|
||||
|
||||
132
src/dag.c
Normal file
132
src/dag.c
Normal 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
34
src/dag.h
Normal 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
8
src/glacier.cfg
Normal 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" ];
|
||||
@@ -27,3 +27,5 @@
|
||||
[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] [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
|
||||
|
||||
1
src/html/img/everest-nord.svg
Normal file
1
src/html/img/everest-nord.svg
Normal 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 |
1
src/html/img/glacier-nord.svg
Normal file
1
src/html/img/glacier-nord.svg
Normal 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 |
@@ -5,34 +5,48 @@
|
||||
<link type="text/css" rel="stylesheet" href="nord.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div class="sidenav">
|
||||
<img src="img/glacier-nord.svg" alt="glacier-logo">
|
||||
</div>
|
||||
<div class="main">
|
||||
<h1>Packaging report: [DATE HERE]</h1>
|
||||
<hr></hr>
|
||||
<h2>Statistics</h2>
|
||||
<p>Total transactions: [N_TRANSACTIONS]</p>
|
||||
<p>Completed transactions: [N_COMP_TRANSACT]</p>
|
||||
<p>Failed transactions: [N_FAIL_TRANSACT]</p>
|
||||
<p>Writes performed to <code>/glacier/index</code>: [N_IND_WRITES]</p>
|
||||
<hr></hr>
|
||||
<bigcodehead><strong>Indices modified</strong></bigcodehead>
|
||||
<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>
|
||||
<p>Performed these changes on the following systems:</p>
|
||||
<code>
|
||||
<bigcodehead><strong>Systems modified</strong></bigcodehead>
|
||||
<div class="bigcode">
|
||||
<p>* localhost</p>
|
||||
<p>* 192.168.30.0/24</p>
|
||||
<p>  * 192.168.30.1</p>
|
||||
</code>
|
||||
<hr></hr>
|
||||
<p>    * 192.168.30.1</p>
|
||||
<p>    * 192.168.30.2</p>
|
||||
</div>
|
||||
<h2>Insights</h2>
|
||||
<!--PACKAGE INSIGHTS BEGIN HERE-->
|
||||
<p><strong>foo</strong><p>
|
||||
<p>1.0.0 ---> 1.0.1</p>
|
||||
<p>Files:</p>
|
||||
<code>
|
||||
<p>f  /usr/glacier/index/lw/pkginfo/foo_current/foo.gpm (e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855)<p>
|
||||
<p>f  usr/glacier/index/lw/pkgdata/foo_current/bin/foo (e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855)<p>
|
||||
<p>l  /home/lw/.glacier/store/foo -> /usr/glacier/index/lw/pkgdata/foo_current<p>
|
||||
</code>
|
||||
<hr>
|
||||
<bigcodehead><strong>world::foo-1.0.1</strong></bigcodehead>
|
||||
<div class="bigcode">
|
||||
<p>d localhost:/glacier/usr/store/1000/world::foo-1.0.1</p>
|
||||
<p>d 192.168.30.1:/glacier/usr/store/1000/world::foo-1.0.1</p>
|
||||
<p>d 192.168.30.2:/glacier/usr/store/1000/world::foo-1.0.1</p>
|
||||
</div>
|
||||
<p></p>
|
||||
<bigcodehead><strong>world::bar-2.3.5</strong></bigcodehead>
|
||||
<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>
|
||||
<p>No problems to report.</p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
184
src/istoreutils.c
Normal file
184
src/istoreutils.c
Normal 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)
|
||||
{}
|
||||
49
src/log.c
49
src/log.c
@@ -144,18 +144,18 @@ lg_gpkg_help(int argc, char *argv[])
|
||||
{
|
||||
(void)argc;
|
||||
|
||||
printf("%s: Manage the user package index\n", argv[0]);
|
||||
printf("usage: %s [-hv] [-fux PKG]\n", argv[0]);
|
||||
printf("%s: Install, update, and remove packages\n", argv[0]);
|
||||
printf("usage: %s [-hv] [-fux PKG] [-V]\n", argv[0]);
|
||||
printf("\n");
|
||||
printf("{-h}\tShow this message\n"
|
||||
"{-v}\tShow the current version\n"
|
||||
"{-f} PKG...\tMerge a package into the user index\n"
|
||||
"{-u} PKG...\tUpgrade a merged package\n"
|
||||
"{-x} PKG...\tRemove a merged package\n"
|
||||
"\n"
|
||||
"This program is free software.\n"
|
||||
"See the GNU GPL version 3 for details.\n"
|
||||
);
|
||||
printf("%-25s %s\n", "{-h --help}", "Show this message");
|
||||
printf("%-25s %s\n", "{-v --version}", "Show the current version");
|
||||
printf("%-25s %s\n", "{-f --merge} PKG...", "Merge a package into the index and store");
|
||||
printf("%-25s %s\n", "{-u --update} PKG...", "Upgrade a merged package");
|
||||
printf("%-25s %s\n", "{-x --remove} PKG...", "Remove a package from the index and store");
|
||||
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");
|
||||
}
|
||||
|
||||
void
|
||||
@@ -177,18 +177,21 @@ lg_syspkg_help(int argc, char *argv[])
|
||||
);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
void
|
||||
lg_gstore_help(int argc, char *argv[])
|
||||
{
|
||||
lg_gpkg_help(argc, argv);
|
||||
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");
|
||||
(void)argc;
|
||||
|
||||
lg_log(true, "./glacier.log", LOG_INFO, "Glacier started with PID %d", 12345);
|
||||
lg_log(true, "./glacier.log", LOG_ERR, "Failed to install package %s", "glibc");
|
||||
|
||||
return 0;
|
||||
printf("%s: Manage Glacier packages indexes/stores\n", argv[0]);
|
||||
printf("usage: %s [-hv] [-snx UID] [-V]\n", argv[0]);
|
||||
printf("\n");
|
||||
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");
|
||||
}
|
||||
|
||||
72
src/pkg.c
72
src/pkg.c
@@ -3,12 +3,14 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <libconfig.h>
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.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 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
|
||||
* DESCRIPTION: takes three integers and formats them as a semver_t struct
|
||||
@@ -119,7 +139,7 @@ gl_parse_semver(const char *str)
|
||||
}
|
||||
|
||||
void
|
||||
gl_free_semver(semver_T *v)
|
||||
gl_free_semver(semver_t *v)
|
||||
{
|
||||
if (v && v->tag) { free (v->tag); };
|
||||
}
|
||||
@@ -164,7 +184,7 @@ gl_pkg_t
|
||||
}
|
||||
|
||||
int
|
||||
gl_gpm2pkg(const char *filename, gl_pkg_t *pkg)
|
||||
gl_gpm2gpkg(const char *filename, gl_pkg_t *pkg)
|
||||
{
|
||||
config_t cfg;
|
||||
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_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_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); }
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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
|
||||
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(&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) {
|
||||
printf("Package prepared\n");
|
||||
return 0;
|
||||
@@ -371,4 +430,7 @@ main(void)
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
|
||||
gl_free_pkg(foo);
|
||||
gl_free_pkg(&bar);
|
||||
}
|
||||
|
||||
84
src/pkg.h
Normal file
84
src/pkg.h
Normal 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
|
||||
@@ -1 +0,0 @@
|
||||
#ifndef
|
||||
2
src/test_deps.c
Normal file
2
src/test_deps.c
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "dag.h"
|
||||
#include
|
||||
Reference in New Issue
Block a user