Working progress as of May 18th
This commit is contained in:
@@ -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.
Binary file not shown.
@@ -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
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>
|
||||
<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">
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
36
src/log.c
36
src/log.c
@@ -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, ...)
|
||||
{
|
||||
|
||||
@@ -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, ...);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user