aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@users.noreply.github.com>2020-06-23 01:23:16 -0400
committerGitHub <noreply@github.com>2020-06-23 01:23:16 -0400
commit97d4d821894dc58c1419eee998ce5214908af882 (patch)
tree665e36e7b31e8fa9c7c74827687fbed83081368a
parentfa17600efcd09bf74954e728047fded3ff0bd0cd (diff)
parent9188d893fb00d11a0974582ab1575670777d96cf (diff)
downloadspmc-97d4d821894dc58c1419eee998ce5214908af882.tar.gz
Merge pull request #49 from jhunkeler/tar-some-more
Handle unpacking when running as root:
-rw-r--r--README.md2
-rw-r--r--include/conf.h2
-rw-r--r--lib/archive.c10
-rw-r--r--lib/config_global.c47
4 files changed, 58 insertions, 3 deletions
diff --git a/README.md b/README.md
index 6025d93..fb681c3 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,7 @@ A basic userland package management system with a few humble goals:
- make (https://www.gnu.org/software/make)
- openssl (https://www.openssl.org)
- bsdtar (https://www.libarchive.org)
+ - OR gnutar (https://www.gnu.org/software/tar)
- which (https://carlowood.github.io/which)
## Runtime Requirements
@@ -27,6 +28,7 @@ A basic userland package management system with a few humble goals:
- reloc (https://github.com/jhunkeler/reloc)
- rsync (https://rsync.samba.org)
- bsdtar (https://www.libarchive.org)
+ - OR gnutar (https://www.gnu.org/software/tar)
- which (https://carlowood.github.io/which)
## Installation
diff --git a/include/conf.h b/include/conf.h
index 7952eed..0d16f08 100644
--- a/include/conf.h
+++ b/include/conf.h
@@ -39,8 +39,10 @@ typedef struct {
char *repo_target;
char *user_config_basedir;
char *user_config_file;
+ char *tar_program;
int verbose;
int prompt_user;
+ int privileged;
ConfigItem **config;
struct utsname sysinfo;
SPM_Hierarchy fs;
diff --git a/lib/archive.c b/lib/archive.c
index 6452647..33c1dcd 100644
--- a/lib/archive.c
+++ b/lib/archive.c
@@ -35,7 +35,7 @@ int tar_extract_file(const char *_archive, const char* _filename, const char *_d
strchrdel(destination, SHELL_INVALID);
strchrdel(filename, SHELL_INVALID);
- sprintf(cmd, "bsdtar -x -f \"%s\" -C \"%s\" \"%s\" 2>&1", archive, destination, filename);
+ sprintf(cmd, "%s -x -f \"%s\" -C \"%s\" \"%s\" 2>&1", SPM_GLOBAL.tar_program, archive, destination, filename);
if (exists(archive) != 0) {
fprintf(stderr, "unable to find archive: %s\n", archive);
fprintf(SYSERROR);
@@ -92,7 +92,13 @@ int tar_extract_archive(const char *_archive, const char *_destination) {
// sanitize destination
strchrdel(destination, SHELL_INVALID);
- sprintf(cmd, "bsdtar -x -f %s -C %s 2>&1", archive, destination);
+ sprintf(cmd, "%s -x -f %s -C %s ", SPM_GLOBAL.tar_program, archive, destination);
+ if (SPM_GLOBAL.privileged) {
+ // Extract the package as if we were a regular user instead of root.
+ strcat(cmd, "--no-same-owner --no-same-permissions ");
+ }
+ strcat(cmd, "2>&1");
+
shell(&proc, SHELL_OUTPUT, cmd);
if (!proc) {
fprintf(SYSERROR);
diff --git a/lib/config_global.c b/lib/config_global.c
index 0d244fc..5f7e99d 100644
--- a/lib/config_global.c
+++ b/lib/config_global.c
@@ -6,6 +6,40 @@
// GLOBAL
spm_vars SPM_GLOBAL;
+/**
+ * Is the user executing this program the system administrator?
+ * @return 0=no, 1=yes
+ */
+static int is_root() {
+#if !OS_WINDOWS
+ uid_t euid;
+ euid = geteuid();
+ if (euid == 0) {
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+/**
+ * Return path to the system's tar program
+ * @return
+ */
+static char *find_tar_program() {
+ const char *programs[] = {
+ "bsdtar",
+ "tar",
+ };
+ char *program;
+
+ for (size_t i = 0; i < (sizeof(programs) / sizeof(char *)); i++) {
+ if ((program = find_executable(programs[i])) != NULL) {
+ return program;
+ }
+ program = NULL;
+ }
+ return program;
+}
/**
* Get path to user's local configuration directory
@@ -138,7 +172,6 @@ void check_runtime_environment(void) {
#endif
"objdump",
"rsync",
- "bsdtar",
"bash",
"reloc",
NULL,
@@ -157,6 +190,12 @@ void check_runtime_environment(void) {
}
free(result);
}
+
+ if (SPM_GLOBAL.tar_program == NULL) {
+ fprintf(stderr, "A supported tar program could not be found.\nPlease install bsdtar or gnutar.");
+ bad_rt = 1;
+ }
+
if (bad_rt) {
exit(1);
}
@@ -219,6 +258,8 @@ void init_config_global(void) {
SPM_GLOBAL.repo_target = NULL;
SPM_GLOBAL.mirror_list = NULL;
SPM_GLOBAL.prompt_user = 1;
+ SPM_GLOBAL.privileged = is_root();
+ SPM_GLOBAL.tar_program = find_tar_program();
if (uname(&SPM_GLOBAL.sysinfo) != 0) {
fprintf(SYSERROR);
@@ -352,6 +393,9 @@ void free_global_config(void) {
if (SPM_GLOBAL.mirror_list) {
mirror_list_free(SPM_GLOBAL.mirror_list);
}
+ if (SPM_GLOBAL.tar_program) {
+ free(SPM_GLOBAL.tar_program);
+ }
free(SPM_GLOBAL.fs.bindir);
free(SPM_GLOBAL.fs.includedir);
@@ -378,6 +422,7 @@ void show_global_config(void) {
printf("# -> %s: %s\n", SPM_GLOBAL.config[i]->key, SPM_GLOBAL.config[i]->value);
}
}
+ printf("# system target: %s\n", SPM_GLOBAL.repo_target);
printf("# package storage: %s\n", SPM_GLOBAL.package_dir);
printf("# temp storage: %s\n", SPM_GLOBAL.tmp_dir);
printf("# package manifest: %s\n", SPM_GLOBAL.package_manifest);