Working progress as of May 18th
This commit is contained in:
@@ -30,6 +30,7 @@ int supports_utf8(void);
|
|||||||
const char *p2s(int priority);
|
const char *p2s(int priority);
|
||||||
|
|
||||||
void lg_printf(loglevel_t loglevel, const char *fmt, ...);
|
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_syslog(int priority, const char *fmt, ...);
|
||||||
void lg_log(bool use_syslog, FILE *logfile, 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.
Binary file not shown.
@@ -33,3 +33,13 @@
|
|||||||
[2026-02-04 14:49:07] [ERR] Failed to install package glibc
|
[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] [INFO] Glacier started with PID 12345
|
||||||
[2026-03-16 13:29:49] [ERR] Failed to install package glibc
|
[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
347
src/html/k2.css
Normal 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;
|
||||||
|
}
|
||||||
46
src/html/report_example_error.html
Normal file
46
src/html/report_example_error.html
Normal 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>
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Glacier Packaging Report</title>
|
<title>Glacier Packaging Report</title>
|
||||||
<link type="text/css" rel="stylesheet" href="nord.css"/>
|
<link type="text/css" rel="stylesheet" href="k2.css"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="sidenav">
|
<div class="sidenav">
|
||||||
|
|||||||
@@ -401,7 +401,6 @@ gl_rebuild_index(uid_t uid, const char *out_dir)
|
|||||||
|
|
||||||
rewind(out);
|
rewind(out);
|
||||||
fprintf(out, "uid = %d\n", uid);
|
fprintf(out, "uid = %d\n", uid);
|
||||||
fprintf(out, "listed = %zu\n\n", listed);
|
|
||||||
|
|
||||||
closedir(store_dir);
|
closedir(store_dir);
|
||||||
fclose(out);
|
fclose(out);
|
||||||
@@ -696,6 +695,143 @@ gl_mkdirp(const char *path, mode_t mode)
|
|||||||
return 0;
|
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
|
static int
|
||||||
gl_link_pkg(const char *pkg_store_final, uid_t uid)
|
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;
|
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_status_t
|
||||||
gl_install_pkg(const char *gpkg_path, uid_t uid)
|
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 */
|
/* The archive is opened and the manifest is parsed here */
|
||||||
struct archive *a = archive_read_new();
|
struct archive *a = archive_read_new();
|
||||||
archive_read_support_filter_gzip(a);
|
archive_read_support_filter_gzip(a);
|
||||||
@@ -993,6 +1227,7 @@ gl_install_pkg(const char *gpkg_path, uid_t uid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gl_free_pkg(&pkg);
|
gl_free_pkg(&pkg);
|
||||||
|
chdir(original_cwd);
|
||||||
return GL_INSTALL_OK;
|
return GL_INSTALL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,12 @@ typedef enum {
|
|||||||
}
|
}
|
||||||
gl_backup_status_t;
|
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_OK: installation successful
|
||||||
* GL_INSTALL_ERR_OPEN: unable to open .gpkg file
|
* GL_INSTALL_ERR_OPEN: unable to open .gpkg file
|
||||||
@@ -38,9 +44,17 @@ typedef enum {
|
|||||||
GL_INSTALL_ERR_EXTRACT = 3,
|
GL_INSTALL_ERR_EXTRACT = 3,
|
||||||
GL_INSTALL_ERR_INDEX = 4,
|
GL_INSTALL_ERR_INDEX = 4,
|
||||||
GL_INSTALL_ERR_ALREADY_INSTALLED = 5,
|
GL_INSTALL_ERR_ALREADY_INSTALLED = 5,
|
||||||
|
GL_INSTALL_SKIPPED = 6,
|
||||||
}
|
}
|
||||||
gl_install_status_t;
|
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 {
|
struct gpkg_entry {
|
||||||
char *repo;
|
char *repo;
|
||||||
char *pkg;
|
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);
|
bool gl_sys_istore_exists(index_store_t index_or_store);
|
||||||
|
|
||||||
int gl_init_user(uid_t uid, bool isVerbose);
|
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);
|
int gl_parse_index(struct gindex *idx, FILE *f);
|
||||||
void gl_free_index(struct gindex *idx);
|
void gl_free_index(struct gindex *idx);
|
||||||
|
|
||||||
int gl_rebuild_index(uid_t uid, const char *out_dir);
|
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,
|
gl_backup_status_t gl_backup_istore(const char *tar_path, const char *glacier_root,
|
||||||
const char *uid);
|
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_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
|
#endif
|
||||||
|
|||||||
36
src/log.c
36
src/log.c
@@ -92,6 +92,42 @@ lg_printf(loglevel_t loglevel, const char *fmt, ...)
|
|||||||
printf("\n");
|
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
|
void
|
||||||
lg_syslog(int priority, const char *fmt, ...)
|
lg_syslog(int priority, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ int supports_utf8(void);
|
|||||||
const char *p2s(int priority);
|
const char *p2s(int priority);
|
||||||
|
|
||||||
void lg_printf(loglevel_t loglevel, const char *fmt, ...);
|
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_syslog(int priority, const char *fmt, ...);
|
||||||
void lg_log(bool use_syslog, FILE *logfile, int priority, const char *fmt, ...);
|
void lg_log(bool use_syslog, FILE *logfile, int priority, const char *fmt, ...);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user