aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2020-06-23 01:16:27 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2020-06-23 01:16:27 -0400
commit9188d893fb00d11a0974582ab1575670777d96cf (patch)
tree665e36e7b31e8fa9c7c74827687fbed83081368a /lib
parentfa17600efcd09bf74954e728047fded3ff0bd0cd (diff)
downloadspmc-9188d893fb00d11a0974582ab1575670777d96cf.tar.gz
Handle unpacking when running as root:
* Check available tar programs and pick one to use
Diffstat (limited to 'lib')
-rw-r--r--lib/archive.c10
-rw-r--r--lib/config_global.c47
2 files changed, 54 insertions, 3 deletions
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);