diff options
author | Joseph Hunkeler <jhunkeler@users.noreply.github.com> | 2020-06-23 01:23:16 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-23 01:23:16 -0400 |
commit | 97d4d821894dc58c1419eee998ce5214908af882 (patch) | |
tree | 665e36e7b31e8fa9c7c74827687fbed83081368a | |
parent | fa17600efcd09bf74954e728047fded3ff0bd0cd (diff) | |
parent | 9188d893fb00d11a0974582ab1575670777d96cf (diff) | |
download | spmc-97d4d821894dc58c1419eee998ce5214908af882.tar.gz |
Merge pull request #49 from jhunkeler/tar-some-more
Handle unpacking when running as root:
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | include/conf.h | 2 | ||||
-rw-r--r-- | lib/archive.c | 10 | ||||
-rw-r--r-- | lib/config_global.c | 47 |
4 files changed, 58 insertions, 3 deletions
@@ -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); |