Working progress as of May 18th

This commit is contained in:
2026-05-18 18:43:30 -04:00
parent 6819fe7c69
commit 0d8859b063
15 changed files with 699 additions and 2 deletions

View File

@@ -30,6 +30,7 @@ int supports_utf8(void);
const char *p2s(int priority);
void lg_printf(loglevel_t loglevel, const char *fmt, ...);
void lg_printf_no_newline(loglevel_t loglevel, const char *fmt, ...);
void lg_syslog(int priority, const char *fmt, ...);
void lg_log(bool use_syslog, FILE *logfile, int priority, const char *fmt, ...);

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -33,3 +33,13 @@
[2026-02-04 14:49:07] [ERR] Failed to install package glibc
[2026-03-16 13:29:49] [INFO] Glacier started with PID 12345
[2026-03-16 13:29:49] [ERR] Failed to install package glibc
[2026-04-17 14:31:12] [INFO] Glacier started with PID 12345
[2026-04-17 14:31:12] [ERR] Failed to install package glibc
[2026-04-17 14:32:30] [INFO] Glacier started with PID 12345
[2026-04-17 14:32:30] [ERR] Failed to install package glibc
[2026-04-17 14:32:39] [INFO] Glacier started with PID 12345
[2026-04-17 14:32:39] [ERR] Failed to install package glibc
[2026-04-17 14:32:55] [INFO] Glacier started with PID 12345
[2026-04-17 14:32:55] [ERR] Failed to install package glibc
[2026-04-17 14:33:04] [INFO] Glacier started with PID 12345
[2026-04-17 14:33:04] [ERR] Failed to install package glibc

347
src/html/k2.css Normal file
View File

@@ -0,0 +1,347 @@
/* css/k2.css - stylesheet for everest-web */
/* Sidebar menu */
.sidenav {
height: 100%;
width: 200px;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: #1a2030;
overflow-x: hidden;
padding-top: 20px;
}
/* Menu links */
.sidenav a {
padding: 6px 8px 6px 16px;
text-decoration: none;
font-size: 20px;
color: #a0b4cc;
display: block;
}
.sidenav a:hover {
color: #4a86e8;
}
html {
background-color: #1e2535;
color: #a0b4cc;
}
.main {
margin-left: 200px;
padding: 0px 10px;
background-color: #1e2535;
}
.file {
font-family: monospace;
background-color: #141820;
border-left: 4px solid #3a9e78;
border-radius: 2px;
padding: 4px;
/*width: 50%;*/
color: #a0b4cc;
}
.kernel {
font-family: monospace;
background-color: #141820;
border-left: 4px solid #7a6eda;
border-radius: 2px;
padding: 4px;
/*width: 50%;*/
color: #a0b4cc;
}
.note {
background-color: #141c2e;
border-left: 4px solid #4a86e8;
border-radius: 2px;
padding: 4px;
/*width: 50%;*/
color: #a0b4cc;
}
.caution {
background-color: #2a1e00;
border-left: 4px solid #e8a83a;
border-radius: 2px;
padding: 4px;
/*width: 50%;*/
color: #e8a83a;
}
.warning {
background-color: #2a0e08;
border-left: 4px solid #e85a4a;
border-radius: 2px;
padding: 4px;
/*width: 50%;*/
color: #e85a4a;
}
.news {
background-color: #1a2030;
border-left: 4px solid #4a86e8;
border-radius: 2px;
padding: 4px;
/*width: 50%;*/
color: #a0b4cc;
}
table, td {
border: 2px solid #a0b4cc;
border-collapse: collapse;
padding: 4px;
background-color: #141820;
color: #a0b4cc;
}
th {
border: 2px solid #a0b4cc;
background-color: #252d3d;
color: #e8eef8;
}
notehead {
background-color: #141c2e;
border-left: 4px solid #4a86e8;
border-radius: 2px;
padding: 6px;
width: 50%;
color: #4a86e8;
}
fhead {
background-color: #141820;
border-left: 4px solid #3a9e78;
border-radius: 2px;
padding: 6px;
width: 50%;
color: #3a9e78;
}
khead {
background-color: #141820;
border-left: 4px solid #7a6eda;
border-radius: 2px;
padding: 6px;
width: 50%;
color: #7a6eda;
}
cautionhead {
background-color: #2a1e00;
border-left: 4px solid #e8a83a;
border-radius: 2px;
padding: 6px;
width: 50%;
color: #e8a83a;
}
warnhead {
background-color: #2a0e08;
border-left: 4px solid #e85a4a;
border-radius: 2px;
padding: 6px;
width: 50%;
color: #e85a4a;
}
newshead {
background-color: #1a2030;
border-left: 4px solid #4a86e8;
border-radius: 2px;
padding: 4px;
width: 50%;
color: #4a86e8;
}
wikihead {
border-left: 4px solid #e86a9e;
border-radius: 2px;
padding: 6px;
color: #e86a9e;
}
bigcodehead {
background-color: #141820;
border-left: 4px solid #a0b4cc;
border-radius: 2px;
padding: 4px;
width: 50%;
color: #a0b4cc;
}
body {
font-family: sans-serif;
background-color: #1e2535;
color: #a0b4cc;
}
code {
font-family: monospace;
background-color: #141820;
border-left: 4px solid #4a86e8;
border-radius: 2px;
padding: 2px;
color: #a0b4cc;
}
.bigcode {
font-family: monospace;
background-color: #141820;
border-left: 4px solid #a0b4cc;
border-radius: 2px;
padding: 6px;
width: 50%;
}
cil {
font-family: monospace;
background-color: #141820;
padding: 2px;
}
cil-inv {
font-family: monospace;
background-color: #141820;
color: #a0b4cc;
padding: 2px;
}
wiki {
border-left: 4px solid #e86a9e;
border-radius: 2px;
padding: 6px;
}
h2 {
border-left: 6px solid #4a86e8;
padding-left: 4px;
border-radius: 5px;
color: #e8eef8;
}
button {
font-size: 24px;
border: none;
border-left: 8px solid #4a86e8;
padding: 12px 28px;
border-radius: 5px;
background-color: #252d3d;
color: #e8eef8;
}
button:hover {
background-color: #2e3850;
}
hr.dotted {
border-top: 3px dotted #607080;
}
hr {
color: #4a86e8;
width: 50%;
border-width: 4px;
border-radius: 5px;
margin-left: 0;
}
footer {
text-align: center;
font-size: 10px;
padding: 20px;
}
#myInput {
width: 378px;
font-size: 16px;
padding: 10px;
border: 2px solid #4a86e8;
border-radius: 2px;
margin-bottom: 12px;
background-color: #252d3d;
color: #e8eef8;
}
#myUL {
width: 400px;
list-style-type: none;
padding: 0;
margin: 0;
}
#myUL li a {
border-left: 2px solid #4a86e8;
margin-top: -1px;
background-color: #252d3d;
padding: 12px;
text-decoration: none;
font-size: 18px;
color: #e8eef8;
display: block;
}
#myUL li a:hover:not(.header) {
background-color: #1e2535;
}
img {
padding: 8px;
}
body, html {
height: 100%;
}
.hero-image {
background-image: linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.5)), url("../img/banner.jpg");
height: 55%;
background-position: 50% 30%;
background-repeat: no-repeat;
background-size: cover;
position: relative;
padding-top: 0px;
padding-right: 0px;
margin-right: -8px;
margin-top: -8px;
}
.hero-text {
text-align: center;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
}
.tab {
display: inline-block;
margin-left: 80px;
}
pre.bigcode {
margin-top: 0;
margin-bottom; 0;
}
.top-banner {
background-color: #4c566a;
color: #eceff4;
text-align: center;
padding: 11px 16px;
font-size: 0.9rem;
width: 100%;
box-sizing: border-box;
position: sticky;
top: 0;
z-index: 1000;
border-bottom: 2px solid #88c0d0;
}

View File

@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html>
<head>
<title>Glacier Packaging Report</title>
<link type="text/css" rel="stylesheet" href="k2.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: 2</p>
<p>Completed transactions: 0</p>
<p>Failed transactions: 2</p>
<bigcodehead><strong>Indices modified</strong></bigcodehead>
<div class="bigcode">
<p>f localhost:/glacier/usr/index/1000/index-03_24_2026@15:11</p>
</div>
<h2>Systems</h2>
<bigcodehead><strong>Systems modified</strong></bigcodehead>
<div class="bigcode">
<p>* localhost</p>
</div>
<h2>Insights</h2>
<!--PACKAGE INSIGHTS BEGIN HERE-->
<bigcodehead><strong>base::glibc-2.43.0</strong></bigcodehead>
<div class="bigcode">
<p>d localhost:/glacier/usr/store/1000/base/glibc-2.43.0</p>
</div>
<p></p>
<bigcodehead><strong>base::vim-9.2.0</strong></bigcodehead>
<div class="bigcode">
<p>d localhost:/glacier/usr/store/1000/base/vim-9.2.0</p>
</div>
<h2>Problems</h2>
<div class="warning">
<p>[x] ACTUAL signature for base::glibc-2.43.0 differs from EXPECTED</p>
<p>[x] ACTUAL signature for base::vim-9.2.0 differs from EXPECTED</p>
<p>[x] One or more packages did not pass integrity checks!</p></div>
</div>
</body>
</html>

View File

@@ -2,7 +2,7 @@
<html>
<head>
<title>Glacier Packaging Report</title>
<link type="text/css" rel="stylesheet" href="nord.css"/>
<link type="text/css" rel="stylesheet" href="k2.css"/>
</head>
<body>
<div class="sidenav">

View File

@@ -401,7 +401,6 @@ gl_rebuild_index(uid_t uid, const char *out_dir)
rewind(out);
fprintf(out, "uid = %d\n", uid);
fprintf(out, "listed = %zu\n\n", listed);
closedir(store_dir);
fclose(out);
@@ -696,6 +695,143 @@ gl_mkdirp(const char *path, mode_t mode)
return 0;
}
int
gl_rmdir_recursive(const char *path)
{
DIR *dir = opendir(path);
if (!dir) { return -1; }
struct dirent *ent;
while ((ent = readdir(dir))) {
if (ent->d_name[0] == '.') { continue; }
char full[PATH_MAX];
snprintf(full, sizeof(full), "%s/%s", path, ent->d_name);
struct stat st;
if (lstat(full, &st) != 0) { continue; }
if (S_ISDIR(st.st_mode)) {
gl_rmdir_recursive(full);
}
else {
unlink(full);
}
}
closedir(dir);
return rmdir(path);
}
static int
gl_unlink_pkg(const char *pkg_store_final, uid_t uid)
{
char links_base[PATH_MAX];
snprintf(links_base, sizeof(links_base), "%s/%d", usr_links.path, uid);
size_t strip_len = strlen(pkg_store_final);
char *stack[4096];
int top = 0;
stack[top++] = strdup(pkg_store_final);
while (top > 0) {
char * current = stack[--top];
DIR *dir = opendir(current);
if (!dir) {
free(current);
continue;
}
struct dirent *ent;
while ((ent = readdir(dir))) {
if (ent->d_name[0] == '.') { continue; }
char full_path[PATH_MAX];
snprintf(full_path, sizeof(full_path), "%s/%s",
current, ent->d_name);
struct stat st;
if (lstat(full_path, &st) != 0) { continue; }
const char *rel = full_path + strip_len;
if (rel[0] == '/') { rel++; }
if (strncmp(rel, "usr/", 4) == 0) { rel += 4; }
char link_path[PATH_MAX];
snprintf(link_path, sizeof(link_path), "%s/%s",
links_base, rel);
if (S_ISDIR(st.st_mode)) {
if (top < 4096) {
stack[top++] = strdup(full_path);
}
}
else if (S_ISREG(st.st_mode)) {
unlink(link_path);
}
}
closedir(dir);
free(current);
}
return 0;
}
gl_remove_status_t
gl_remove_pkg(const char *pkg_name, const char *pkg_repo, uid_t uid)
{
/* find the package base directory in the store */
char pkg_store_base[PATH_MAX];
snprintf(pkg_store_base, sizeof(pkg_store_base),
"%s/%d/%s/%s", usr_store.path, uid, pkg_repo, pkg_name);
struct stat st;
if (stat(pkg_store_base, &st) != 0 || !S_ISDIR(st.st_mode)) {
return GL_REMOVE_ERR_NOT_FOUND;
}
/* find the versioned subdirectory */
DIR *dir = opendir(pkg_store_base);
if (!dir) { return GL_REMOVE_ERR_NOT_FOUND; }
char pkg_store_final[PATH_MAX] = {0};
struct dirent *ent;
while ((ent = readdir(dir))) {
if (ent->d_name[0] == '.') { continue; }
snprintf(pkg_store_final, sizeof(pkg_store_final),
"%s/%s", pkg_store_base, ent->d_name);
break;
}
closedir(dir);
if (pkg_store_final[0] == '\0') {
return GL_REMOVE_ERR_NOT_FOUND;
}
/* remove symlinks from links tree */
if (gl_unlink_pkg(pkg_store_final, uid) != 0) {
return GL_REMOVE_ERR_UNLINK;
}
/* remove package from store */
if (gl_rmdir_recursive(pkg_store_base) != 0) {
return GL_REMOVE_ERR_UNLINK;
}
/* rebuild index */
char index_dir[PATH_MAX];
snprintf(index_dir, sizeof(index_dir), "%s/%d", usr_index.path, uid);
if (gl_rebuild_index(uid, index_dir) != 0) {
return GL_REMOVE_ERR_INDEX;
}
return GL_REMOVE_OK;
}
static int
gl_link_pkg(const char *pkg_store_final, uid_t uid)
{
@@ -781,9 +917,107 @@ gl_link_pkg(const char *pkg_store_final, uid_t uid)
return 0;
}
int
gl_delete_user(uid_t uid, bool isVerbose)
{
char ind_path[PATH_MAX];
char sto_path[PATH_MAX];
char lnk_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);
snprintf(lnk_path, sizeof(lnk_path), "%s/%d", usr_links.path, uid);
if (isVerbose) { lg_printf(0, "Removing Glacier directories for UID %d...", uid); }
if (gl_rmdir_recursive(ind_path) != 0) {
lg_printf(2, "Failed to remove index for UID %d", uid);
return 1;
}
if (gl_rmdir_recursive(sto_path) != 0) {
lg_printf(2, "Failed to remove store for UID %d", uid);
return 1;
}
if (gl_rmdir_recursive(lnk_path) != 0) {
lg_printf(2, "Failed to remove links for UID %d", uid);
return 1;
}
lg_printf(3, "Successfully removed Glacier directories for UID %d.", uid);
return 0;
}
gl_restore_status_t
gl_restore_istore(const char *tar_path, const char *glacier_root, const char *uid)
{
struct archive *a = archive_read_new();
archive_read_support_filter_gzip(a);
archive_read_support_format_tar(a);
if (archive_read_open_filename(a, tar_path, 10240) != ARCHIVE_OK) {
archive_read_free(a);
return GL_RESTORE_ERR_OPEN;
}
struct archive_entry *entry;
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
const char *rel = archive_entry_pathname(entry);
char dest[PATH_MAX];
snprintf(dest, sizeof(dest), "%s/%s/%s",
glacier_root, uid, rel);
archive_entry_set_pathname(entry, dest);
if (archive_entry_filetype(entry) == AE_IFDIR) {
gl_mkdirp(dest, archive_entry_perm(entry));
archive_read_data_skip(a);
continue;
}
/* create parent dirs */
char parent[PATH_MAX];
strncpy(parent, dest, sizeof(parent));
char *slash = strrchr(parent, '/');
if (slash) {
*slash = '\0';
gl_mkdirp(parent, 0700);
}
int fd = open(dest, O_WRONLY | O_CREAT | O_TRUNC,
archive_entry_perm(entry));
if (fd < 0) {
archive_read_free(a);
return GL_RESTORE_ERR_EXTRACT;
}
char buf[8192];
ssize_t n;
while ((n = archive_read_data(a, buf, sizeof(buf))) > 0) {
ssize_t written = write(fd, buf, (size_t)n);
if (written < 0 || written != n) {
close(fd);
archive_read_free(a);
return GL_RESTORE_ERR_EXTRACT;
}
}
close(fd);
}
archive_read_free(a);
return GL_RESTORE_OK;
}
gl_install_status_t
gl_install_pkg(const char *gpkg_path, uid_t uid)
{
char original_cwd[PATH_MAX];
if (getcwd(original_cwd, sizeof(original_cwd)) == NULL) {
return GL_INSTALL_ERR_OPEN;
}
/* The archive is opened and the manifest is parsed here */
struct archive *a = archive_read_new();
archive_read_support_filter_gzip(a);
@@ -993,6 +1227,7 @@ gl_install_pkg(const char *gpkg_path, uid_t uid)
}
gl_free_pkg(&pkg);
chdir(original_cwd);
return GL_INSTALL_OK;
}

View File

@@ -22,6 +22,12 @@ typedef enum {
}
gl_backup_status_t;
typedef enum {
GL_RESTORE_OK = 0,
GL_RESTORE_ERR_OPEN = 1,
GL_RESTORE_ERR_EXTRACT = 2
} gl_restore_status_t;
/*
* GL_INSTALL_OK: installation successful
* GL_INSTALL_ERR_OPEN: unable to open .gpkg file
@@ -38,9 +44,17 @@ typedef enum {
GL_INSTALL_ERR_EXTRACT = 3,
GL_INSTALL_ERR_INDEX = 4,
GL_INSTALL_ERR_ALREADY_INSTALLED = 5,
GL_INSTALL_SKIPPED = 6,
}
gl_install_status_t;
typedef enum {
GL_REMOVE_OK = 0,
GL_REMOVE_ERR_NOT_FOUND = 1,
GL_REMOVE_ERR_UNLINK = 2,
GL_REMOVE_ERR_INDEX = 3,
} gl_remove_status_t;
struct gpkg_entry {
char *repo;
char *pkg;
@@ -57,15 +71,22 @@ bool gl_usr_istore_exists(index_store_t index_or_store, int uid);
bool gl_sys_istore_exists(index_store_t index_or_store);
int gl_init_user(uid_t uid, bool isVerbose);
int gl_delete_user(uid_t uid, bool isVerbose);
int gl_parse_index(struct gindex *idx, FILE *f);
void gl_free_index(struct gindex *idx);
int gl_rebuild_index(uid_t uid, const char *out_dir);
char *gl_find_pkg_repo(const char *pkg_name, uid_t uid);
gl_backup_status_t gl_backup_istore(const char *tar_path, const char *glacier_root,
const char *uid);
gl_restore_status_t gl_restore_istore(const char *tar_path, const char *glacier_root, const char *uid);
gl_install_status_t gl_install_pkg(const char *gpkg_path, uid_t uid);
gl_remove_status_t gl_remove_pkg(const char *pkg_name, const char *pkg_repo, uid_t uid);
#endif

View File

@@ -92,6 +92,42 @@ lg_printf(loglevel_t loglevel, const char *fmt, ...)
printf("\n");
}
void
lg_printf_no_newline(loglevel_t loglevel, const char *fmt, ...)
{
const char *prefix;
int utf8_ok = supports_utf8();
switch (loglevel) {
case LG_INFO:
prefix = COL_BLUE "[i]" COL_RESET " ";
break;
case LG_WARN:
prefix = COL_YELLOW "[!]" COL_RESET " ";
break;
case LG_ERR:
prefix = COL_RED "[x]" COL_RESET " ";
break;
case LG_SUCCESS:
if (utf8_ok) {
prefix = COL_GREEN "[" "\xE2\x9C\x93" "]" COL_RESET " ";
} else {
prefix = COL_GREEN "[*]" COL_RESET " ";
}
break;
default:
prefix = "[?] ";
}
fputs(prefix, stdout);
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
}
void
lg_syslog(int priority, const char *fmt, ...)
{

View File

@@ -30,6 +30,7 @@ int supports_utf8(void);
const char *p2s(int priority);
void lg_printf(loglevel_t loglevel, const char *fmt, ...);
void lg_printf_no_newline(loglevel_t loglevel, const char *fmt, ...);
void lg_syslog(int priority, const char *fmt, ...);
void lg_log(bool use_syslog, FILE *logfile, int priority, const char *fmt, ...);