aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2019-12-10 16:08:42 -0500
committerJoseph Hunkeler <jhunkeler@gmail.com>2019-12-10 16:08:42 -0500
commitacbd792900767949c5836e3fc401b134ab93e144 (patch)
tree92445db3b343d1515646f203427b65c2fcaacbb9
parentaaac7bc7fb88bb21ee46e42bc3b664a1163e0e6f (diff)
downloadspmc-acbd792900767949c5836e3fc401b134ab93e144.tar.gz
Fix minor bugs and implement rsync function
-rw-r--r--config.c12
-rw-r--r--spm.c65
-rw-r--r--spm.h3
3 files changed, 78 insertions, 2 deletions
diff --git a/config.c b/config.c
index 6e6ae8a..c35c233 100644
--- a/config.c
+++ b/config.c
@@ -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
diff --git a/spm.c b/spm.c
index c6e09ee..51d7890 100644
--- a/spm.c
+++ b/spm.c
@@ -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
diff --git a/spm.h b/spm.h
index 94b3797..c5b0b58 100644
--- a/spm.h
+++ b/spm.h
@@ -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);