Working progress as of May 18th
This commit is contained in:
1 parent
6819fe7c69
commit
0d8859b063
15 files changed
+699
-2
No files matched your search
+236
-1
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user