Working progress as of May 18th

This commit is contained in:
lw-everestlinux committed 2026-05-18 18:43:30 -04:00
1 parent 6819fe7c69
commit 0d8859b063
15 files changed
+699 -2

No files matched your search

+236 -1
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;
}