diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2019-12-10 16:08:42 -0500 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2019-12-10 16:08:42 -0500 |
commit | acbd792900767949c5836e3fc401b134ab93e144 (patch) | |
tree | 92445db3b343d1515646f203427b65c2fcaacbb9 | |
parent | aaac7bc7fb88bb21ee46e42bc3b664a1163e0e6f (diff) | |
download | spmc-acbd792900767949c5836e3fc401b134ab93e144.tar.gz |
Fix minor bugs and implement rsync function
-rw-r--r-- | config.c | 12 | ||||
-rw-r--r-- | spm.c | 65 | ||||
-rw-r--r-- | spm.h | 3 |
3 files changed, 78 insertions, 2 deletions
@@ -91,7 +91,9 @@ ConfigItem **config_read(const char *filename) { continue; } - // Calculate key and value lengths dynamically + // These values are approximations. The real length(s) are recorded using strlen below. + // At most we'll lose a few heap bytes to whitespace, but it's better than allocating PATH_MAX or BUFSIZ + // for a measly ten byte string. size_t key_length = strcspn(lptr, &sep); size_t value_length = strlen(sep_pos); @@ -104,6 +106,10 @@ ConfigItem **config_read(const char *filename) { char *key = config[record]->key; char *value = config[record]->value; + // Copy the array pointers (used to populate config->key/value_length + char *key_orig = key; + char *value_orig = value; + // Populate the key and remove any trailing space while (lptr != sep_pos) { *key++ = *lptr++; @@ -134,6 +140,10 @@ ConfigItem **config_read(const char *filename) { *value++ = *lptr++; } + // Populate length data + config[record]->key_length = strlen(key_orig); + config[record]->value_length = strlen(value_orig); + // increment record count record++; // Expand config by another record @@ -1001,12 +1001,13 @@ void check_runtime_environment(void) { "rsync", "tar", "bash", + "reloc", NULL, }; for (int i = 0; required[i] != NULL; i++) { char *result = find_executable(required[i]); if (!result) { - fprintf(stderr, "Required program '%s' is not installed or on your PATH\n", required[i]); + fprintf(stderr, "Required program '%s' is not installed\n", required[i]); bad_rt = 1; } free(result); @@ -1203,11 +1204,20 @@ int install(const char *destroot, const char *_package) { } } + char source[PATH_MAX]; char template[PATH_MAX]; char suffix[PATH_MAX] = "spm_destroot_XXXXXX"; sprintf(template, "%s%c%s", TMP_DIR, DIRSEP, suffix); + char *tmpdir = mkdtemp(template); tar_extract_archive(package, tmpdir); + // do things + + sprintf(source, "%s%c", tmpdir, DIRSEP); + char *wtf = source; + if (rsync(NULL, source, destroot) != 0) { + exit(1); + } rmdirs(tmpdir); free(package); } @@ -1299,6 +1309,59 @@ void show_global_config(void) { printf("\n"); } +/** + * Basic rsync wrapper for copying files + * @param _args arguments to pass to rsync (set to `NULL` for default options) + * @param _source source file or directory + * @param _destination destination file or directory + * @return success=0, failure=-1 + */ +int rsync(const char *_args, const char *_source, const char *_destination) { + int returncode; + Process *proc = NULL; + char *args = NULL; + if (_args) { + args = strdup(_args); + } + char *source = strdup(_source); + char *destination = strdup(_destination); + char cmd[PATH_MAX]; + char args_combined[PATH_MAX]; + + memset(cmd, '\0', sizeof(cmd)); + memset(args_combined, '\0', sizeof(args_combined)); + strcpy(args_combined, "--archive --hard-links "); + if (args) { + strcat(args_combined, _args); + } + + sprintf(cmd, "rsync %s \"%s\" \"%s\"", args_combined, source, destination); + // sanitize command + strchrdel(cmd, "&;|"); + shell(&proc, SHELL_OUTPUT, cmd); + if (!proc) { + if (args) { + free(args); + } + free(source); + free(destination); + return -1; + } + + returncode = proc->returncode; + if (returncode != 0 && proc->output) { + fprintf(stderr, proc->output); + } + shell_free(proc); + + if (args) { + free(args); + } + free(source); + free(destination); + return returncode; +} + int main(int argc, char *argv[]) { // not much to see here yet // at the moment this will all be random tests, for better or worse @@ -42,6 +42,8 @@ typedef struct { char *key; char *value; + size_t key_length; + size_t value_length; } ConfigItem; typedef struct { @@ -70,6 +72,7 @@ void shell(Process **proc_info, u_int64_t option, const char *fmt, ...); void shell_free(Process *proc_info); int tar_extract_archive(const char *_archive, const char *_destination); int tar_extract_file(const char *archive, const char* filename, const char *destination); +int rsync(const char *_args, const char *_source, const char *_destination); int errglob(const char *epath, int eerrno); int num_chars(const char *sptr, int ch); |