aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2019-12-17 09:41:52 -0500
committerJoseph Hunkeler <jhunkeler@gmail.com>2019-12-17 09:41:52 -0500
commitfa992c8655f2fe27a97fe0e6768800a356de3744 (patch)
tree7fc38d4bd3ff47abe6b76ded773450b9b65d11b8
parentfcf0e9159b76be699bc8560f853ece8bb2c7ff2e (diff)
downloadspmc-fa992c8655f2fe27a97fe0e6768800a356de3744.tar.gz
Dependencies are finally installable
-rw-r--r--CMakeLists.txt2
-rw-r--r--config.c32
-rw-r--r--deps.c115
-rw-r--r--fstree.c101
-rw-r--r--spm.c369
-rw-r--r--spm.h34
6 files changed, 429 insertions, 224 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a130cda..f492572 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,5 +7,5 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})
check_symbol_exists(strsep string.h HAVE_STRSEP)
configure_file(config.h.in config.h)
-add_executable(spm spm.c config.c spm.h config.h.in compat.c)
+add_executable(spm spm.c config.c spm.h config.h.in compat.c deps.c fstree.c)
target_link_libraries(spm rt)
diff --git a/config.c b/config.c
index c35c233..0295be8 100644
--- a/config.c
+++ b/config.c
@@ -7,8 +7,15 @@
/// \param sptr pointer to string
/// \return pointer to first non-whitespace character in string
char *lstrip(char *sptr) {
- while (isblank(*sptr)) {
- sptr++;
+ char *tmp = sptr;
+ size_t bytes = 0;
+ while (isblank(*tmp)) {
+ bytes++;
+ tmp++;
+ }
+ if (tmp != sptr) {
+ memmove(sptr, sptr + bytes, strlen(sptr) - bytes);
+ memset((sptr + strlen(sptr)) - bytes, '\0', bytes);
}
return sptr;
}
@@ -17,11 +24,10 @@ char *lstrip(char *sptr) {
/// \param sptr pointer to string
/// \return truncated string
char *strip(char *sptr) {
- char *tmp = sptr + strlen(sptr) - 1;
- while (isblank(*tmp) || *tmp == '\n') {
- *tmp = '\0';
- tmp--;
+ if (!strlen(sptr)) {
+ return sptr;
}
+ strchrdel(sptr, " \r\n");
return sptr;
}
@@ -57,7 +63,7 @@ int isquoted(char *sptr) {
ConfigItem **config_read(const char *filename) {
const char sep = '=';
- char line[CONFIG_BUFFER_SIZE];
+ char *line = (char *)calloc(CONFIG_BUFFER_SIZE, sizeof(char));
FILE *fp = fopen(filename, "r");
if (!fp) {
// errno will be set, so die, and let the caller handle it
@@ -67,14 +73,14 @@ ConfigItem **config_read(const char *filename) {
ConfigItem **config = (ConfigItem **) calloc(record_initial, sizeof(ConfigItem *));
int record = 0;
-
- while (fgets(line, sizeof(line), fp) != NULL) {
+ while (fgets(line, CONFIG_BUFFER_SIZE, fp) != NULL) {
char *lptr = line;
- // Remove leading space and newlines
- lptr = lstrip(lptr);
// Remove trailing space and newlines
lptr = strip(lptr);
+ // Remove leading space and newlines
+ lptr = lstrip(lptr);
+
// Skip empty lines
if (isempty(lptr)) {
continue;
@@ -144,11 +150,15 @@ ConfigItem **config_read(const char *filename) {
config[record]->key_length = strlen(key_orig);
config[record]->value_length = strlen(value_orig);
+ // Destroy contents of line buffer
+ memset(line, '\0', CONFIG_BUFFER_SIZE);
+
// increment record count
record++;
// Expand config by another record
config = (ConfigItem **)reallocarray(config, record + record_initial + 1, sizeof(ConfigItem *));
}
+ free(line);
return config;
}
diff --git a/deps.c b/deps.c
new file mode 100644
index 0000000..7eb587f
--- /dev/null
+++ b/deps.c
@@ -0,0 +1,115 @@
+//
+// Created by jhunk on 12/16/19.
+//
+#include "spm.h"
+
+int exists(const char *filename) {
+ return access(filename, F_OK);
+}
+
+int dep_seen(Dependencies **deps, const char *name) {
+ if (!deps) {
+ return -1;
+ }
+ for (int i = 0; i != (*deps)->records; i++) {
+ if (strstr((*deps)->list[i], name) != NULL) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int dep_init(Dependencies **deps) {
+ (*deps) = (Dependencies *)calloc(1, sizeof(Dependencies));
+ (*deps)->__size = 2;
+ (*deps)->records = 0;
+ (*deps)->list = (char **)calloc((*deps)->__size, sizeof(char *));
+ if (!(*deps)->list) {
+ return -1;
+ }
+ return 0;
+}
+
+void dep_free(Dependencies **deps) {
+ if ((*deps) != NULL) {
+ return;
+ }
+ for (int i = 0; i < (*deps)->__size; i++) {
+ if ((*deps)->list[i] != NULL) {
+ free((*deps)->list[i]);
+ }
+ }
+ free((*deps));
+}
+
+int dep_append(Dependencies **deps, char *name) {
+ if (!(*deps)) {
+ return -1;
+ }
+ (*deps)->__size++;
+ (*deps)->list = (char **)realloc((*deps)->list, sizeof(char *) * (*deps)->__size);
+ if (!(*deps)->list) {
+ return -1;
+ }
+ (*deps)->list[(*deps)->records] = (char *)calloc(strlen(name) + 1, sizeof(char));
+ if (!(*deps)->list[(*deps)->records]) {
+ return -1;
+ }
+ strcpy((*deps)->list[(*deps)->records], name);//, strlen(name));
+ (*deps)->records++;
+ return 0;
+}
+
+int dep_solve(Dependencies **deps, const char *filename) {
+ if (!(*deps)) {
+ return -1;
+ }
+ if (exists(filename) != 0) {
+ return -1;
+ }
+ FILE *fp = fopen(filename, "r");
+ if (!fp) {
+ perror(filename);
+ return -1;
+ }
+
+ char data[BUFSIZ];
+ memset(data, '\0', sizeof(data));
+
+ char *line = data;
+ int line_count = 0;
+ while (fgets(line, BUFSIZ, fp) != NULL) {
+ size_t line_length = strlen(line);
+ if (line_length > 1 && strstr(line, "\r\n")) {
+ line[line_length - 2] = '\0';
+ }
+ if (line_length > 1 && line[line_length - 1] == '\n') {
+ line[line_length - 1] = '\0';
+ }
+ if (strcmp(line, "") == 0) {
+ continue;
+ }
+ line_count++;
+ if (dep_seen(deps, line) > 0) {
+ // Already seen this dependency. Skip it.
+ continue;
+ }
+ else {
+ // Have not seen this dependency before
+ if (dep_append(deps, line) == 0) {
+ dep_solve(deps, line);
+ }
+ }
+ }
+ fclose(fp);
+ return line_count;
+}
+
+void dep_show(Dependencies **deps) {
+ if ((*deps) == NULL) {
+ return;
+ }
+ for (int i = 0; i < (*deps)->records; i++) {
+ printf("%d: %s\n", i, (*deps)->list[i]);
+ }
+}
diff --git a/fstree.c b/fstree.c
new file mode 100644
index 0000000..0f5e95a
--- /dev/null
+++ b/fstree.c
@@ -0,0 +1,101 @@
+#include "spm.h"
+
+FSTree *fstree(const char *_path) {
+ FTS *parent = NULL;
+ FTSENT *node = NULL;
+ FSTree *fsdata = NULL;
+ char *path = realpath(_path, NULL);
+ char *root[2] = { path, NULL };
+
+ size_t dirs_size = 2;
+ size_t dirs_records = 0;
+ size_t files_size = 2;
+ size_t files_records = 0;
+
+ fsdata = (FSTree *)calloc(1, sizeof(FSTree));
+ fsdata->root= (char *)calloc(strlen(path) + 1, sizeof(char));
+ fsdata->dirs = (char **)calloc(dirs_size, sizeof(char *));
+ fsdata->files= (char **)calloc(files_size, sizeof(char *));
+
+ strncpy(fsdata->root, path, strlen(path));
+ parent = fts_open(root, FTS_PHYSICAL | FTS_NOCHDIR, &_fstree_compare);
+
+ if (parent != NULL) {
+ while ((node = fts_read(parent)) != NULL) {
+ switch (node->fts_info) {
+ case FTS_D:
+ if (strcmp(node->fts_path, "..") == 0 || strcmp(node->fts_path, ".") == 0) {
+ continue;
+ }
+ fsdata->dirs = (char **)realloc(fsdata->dirs, sizeof(char*) * dirs_size);
+ fsdata->dirs[dirs_size - 1] = NULL;
+ fsdata->dirs[dirs_records] = (char *)calloc(strlen(node->fts_path) + 1, sizeof(char));
+ strncpy(fsdata->dirs[dirs_records], node->fts_path, strlen(node->fts_path));
+ dirs_size++;
+ dirs_records++;
+ break;
+ case FTS_F:
+ case FTS_SL:
+ fsdata->files = (char **)realloc(fsdata->files, sizeof(char*) * files_size);
+ fsdata->files[files_size - 1] = NULL;
+ fsdata->files[files_records] = (char *)calloc(strlen(node->fts_path) + 1, sizeof(char));
+ strncpy(fsdata->files[files_records], node->fts_path, strlen(node->fts_path));
+ files_size++;
+ files_records++;
+ break;
+ default:
+ break;
+ }
+ }
+ fts_close(parent);
+ }
+ fsdata->dirs_length = dirs_records;
+ fsdata->files_length = files_records;
+ free(path);
+ return fsdata;
+}
+
+int _fstree_compare(const FTSENT **one, const FTSENT **two) {
+ return (strcmp((*one)->fts_name, (*two)->fts_name));
+}
+
+int rmdirs(const char *_path) {
+ if (access(_path, F_OK) != 0) {
+ return -1;
+ }
+
+ FSTree *data = fstree(_path);
+ if (data->files) {
+ for (int i = 0; data->files[i] != NULL; i++) {
+ remove(data->files[i]);
+ }
+ }
+ if (data->dirs) {
+ for (int i = data->dirs_length - 1; i != 0; i--) {
+ remove(data->dirs[i]);
+ }
+ }
+ remove(data->root);
+
+ fstree_free(data);
+ return 0;
+}
+
+void fstree_free(FSTree *fsdata) {
+ if (fsdata != NULL) {
+ if (fsdata->root != NULL) {
+ free(fsdata->root);
+ }
+ if (fsdata->files != NULL) {
+ for (int i = 0; fsdata->files[i] != NULL; i++) {
+ free(fsdata->files[i]);
+ }
+ }
+ if (fsdata->dirs != NULL) {
+ for (int i = 0; fsdata->dirs[i] != NULL; i++) {
+ free(fsdata->dirs[i]);
+ }
+ }
+ free(fsdata);
+ }
+}
diff --git a/spm.c b/spm.c
index 96640fd..f1d38ac 100644
--- a/spm.c
+++ b/spm.c
@@ -28,19 +28,19 @@ char *get_user_conf_dir(void) {
char *get_user_config_file(void) {
const char *filename = "spm.conf";
char template[PATH_MAX];
- char *ucb = get_user_conf_dir();
- if (!ucb) {
+ char *ucd = get_user_conf_dir();
+ if (!ucd) {
return NULL;
}
// Initialize temporary path
template[0] = '\0';
- sprintf(template, "%s%c%s", ucb, DIRSEP, filename);
+ sprintf(template, "%s%c%s", ucd, DIRSEP, filename);
if (access(template, F_OK) != 0) {
// No configuration exists, so fail
return NULL;
}
-
+ free(ucd);
// Allocate and return path to configuration file
return strdup(template);
}
@@ -199,7 +199,7 @@ int tar_extract_file(const char *archive, const char* filename, const char *dest
int status;
char cmd[PATH_MAX];
- sprintf(cmd, "tar xf %s %s -C %s 2>&1", archive, filename, destination);
+ sprintf(cmd, "tar xf %s -C %s %s 2>&1", archive, destination, filename);
shell(&proc, SHELL_OUTPUT, cmd);
if (!proc) {
fprintf(SYSERROR);
@@ -237,12 +237,15 @@ int tar_extract_archive(const char *_archive, const char *_destination) {
shell(&proc, SHELL_OUTPUT, cmd);
if (!proc) {
fprintf(SYSERROR);
+ free(archive);
+ free(destination);
return -1;
}
status = proc->returncode;
shell_free(proc);
-
+ free(archive);
+ free(destination);
return status;
}
@@ -750,16 +753,27 @@ void walkdir(char *dirpath, Dirwalk **result, unsigned int dirs) {
return;
}
+ struct dirent *entry;
+ int record_count = 0;
+
+ while ((entry = readdir(dp)) != NULL) {
+ if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) {
+ continue;
+ }
+ record_count++;
+ }
+ rewinddir(dp);
+
if (!locked) {
(*result) = (Dirwalk *)reallocarray((*result),1, sizeof(Dirwalk));
- (*result)->paths = (char **)calloc(initial_records, sizeof(char *));
+ (*result)->paths = (char **)calloc(record_count, sizeof(char *));
i = 0;
locked++;
}
- struct dirent *entry;
+ //(*result)->paths = (char **) reallocarray((*result)->paths, record_count, sizeof(char *));
while ((entry = readdir(dp)) != NULL) {
- (*result)->paths = (char **) reallocarray((*result)->paths, (initial_records + i), sizeof(char *));
+ printf("i=%d, dname=%s\n", i, entry->d_name);
char *name = entry->d_name;
char path[PATH_MAX];
@@ -774,7 +788,7 @@ void walkdir(char *dirpath, Dirwalk **result, unsigned int dirs) {
if (entry->d_type == DT_DIR) {
if (dirs) {
strncpy((*result)->paths[i], path, (size_t) path_size);
- i++;
+ //i++;
}
dirpath[dirpath_size] = DIRSEP;
strcpy(dirpath + dirpath_size + 1, name);
@@ -783,8 +797,8 @@ void walkdir(char *dirpath, Dirwalk **result, unsigned int dirs) {
}
else {
strncpy((*result)->paths[i], path, (size_t) path_size);
- i++;
}
+ i++;
}
(*result)->count = i;
(*result)->paths[i] = NULL;
@@ -794,40 +808,6 @@ void walkdir(char *dirpath, Dirwalk **result, unsigned int dirs) {
}
}
-/**
- * Generate a listing of all files under `path`
- * @param path
- * @return success=array of paths, failure=NULL
- */
-char **fstree(const char *path, unsigned int get_dir_flag) {
- Dirwalk *dlist = NULL;
- char wpath[PATH_MAX];
- strcpy(wpath, path);
-
- if (access(wpath, F_OK) != 0) {
- return NULL;
- }
-
- walkdir(wpath, &dlist, get_dir_flag);
- char **result = (char **)calloc((size_t) (dlist->count + 1), sizeof(char *));
- if (!result) {
- return NULL;
- }
- for (int i = 0; dlist->paths[i] != NULL; i++) {
- result[i] = (char *)calloc(strlen(dlist->paths[i]) + 1, sizeof(char));
- if (!result[i]) {
- return NULL;
- }
- memcpy(result[i], dlist->paths[i], strlen(dlist->paths[i]));
- free(dlist->paths[i]);
- }
- strsort(result);
-
- free(dlist->paths);
- free(dlist);
- return result;
-}
-
/*
* Helper function for `strsort`
*/
@@ -1052,9 +1032,8 @@ char *dirname(const char *_path) {
* @param _path
* @return success=file name, failure=NULL
*/
-char *basename(const char *_path) {
+char *basename(char *path) {
char *result = NULL;
- char *path = strdup(_path);
char *last = strrchr(path, DIRSEP);
if (!last) {
return NULL;
@@ -1064,7 +1043,6 @@ char *basename(const char *_path) {
if ((last + 1) != NULL) {
result = last + 1;
}
- free(path);
return result;
}
@@ -1160,40 +1138,6 @@ Process *patchelf(const char *_filename, const char *_args) {
return proc_info;
}
-
-int rmdirs(const char *_path) {
- char *path = strdup(_path);
- if (!path) {
- return -1;
- }
- if (access(path, F_OK) != 0) {
- fprintf(SYSERROR);
- free(path);
- return -1;
- }
-
- char **files = fstree(path, 1);
- if (!files) {
- free(path);
- return -1;
- }
-
- while (access(path, F_OK) == 0) {
- for (int i = 0; files[i] != NULL; i++) {
- remove(files[i]);
- }
- remove(path);
- }
-
- for (int i = 0; files[i] != NULL; i++) {
- free(files[i]);
- }
-
- free(files);
- free(path);
- return 0;
-}
-
/**
* Replace all occurrences of `_oldstr` in `_oldbuf` with `_newstr`
* @param _oldbuf
@@ -1203,6 +1147,7 @@ int rmdirs(const char *_path) {
*/
char *replace_text(char *_oldbuf, const char *_oldstr, const char *_newstr) {
int occurrences = 0;
+ int i = 0;
size_t _oldstr_len = strlen(_oldstr);
size_t _newstr_len = strlen(_newstr);
size_t _oldbuf_len = strlen(_oldbuf);
@@ -1213,18 +1158,22 @@ char *replace_text(char *_oldbuf, const char *_oldstr, const char *_newstr) {
if (strstr(tmp, _oldstr) == tmp) {
occurrences++;
// Move pointer past last occurrence
- tmp += _oldstr_len - 1;
+ i++;
+ tmp += _oldstr_len;
+ continue;
}
+ i++;
tmp++;
}
- int i = 0;
- char *result = (char *)calloc(1, ((occurrences * _newstr_len) + _oldbuf_len) + 1);
+ char *result = (char *)calloc(((i + (occurrences * _newstr_len)) + 1), sizeof(char));
if (!result) {
+ fprintf(SYSERROR);
return NULL;
}
// Continuously scan until _oldstr has been completely removed
+ i = 0;
while (strstr(_oldbuf, _oldstr) != NULL) {
// Search for _oldstr in _oldbuf
if (strstr(_oldbuf, _oldstr) == _oldbuf) {
@@ -1237,7 +1186,6 @@ char *replace_text(char *_oldbuf, const char *_oldstr, const char *_newstr) {
// Write non-matches to result buffer
result[i++] = *_oldbuf++;
}
-
}
return result;
@@ -1256,6 +1204,7 @@ int file_replace_text(const char *filename, const char *oldstr, const char *news
char *data_orig = (char *)calloc(file_size + 1, sizeof(char));
FILE *fp = fopen(filename, "r+");
if (!fp) {
+ fprintf(SYSERROR);
free(data_orig);
return -1;
}
@@ -1264,6 +1213,7 @@ int file_replace_text(const char *filename, const char *oldstr, const char *news
fread(data_orig, file_size, sizeof(char), fp);
if ((err = ferror(fp)) < 0) {
free(data_orig);
+ fclose(fp);
return err;
}
// Jump back to the beginning of the file
@@ -1271,6 +1221,12 @@ int file_replace_text(const char *filename, const char *oldstr, const char *news
// Create a new buffer
char *data_new = replace_text(data_orig, oldstr, newstr);
+ if (!data_new) {
+ fprintf(SYSERROR);
+ free(data_orig);
+ fclose(fp);
+ return -1;
+ }
// Update expected file size
file_size = strlen(data_new);
// Write back changes
@@ -1278,6 +1234,7 @@ int file_replace_text(const char *filename, const char *oldstr, const char *news
if ((err = ferror(fp)) < 0) {
free(data_orig);
free(data_new);
+ fclose(fp);
return err;
}
@@ -1299,7 +1256,7 @@ int strstr_array(char **arr, const char *str) {
}
for (int i = 0; arr[i] != NULL; i++) {
- if (strstr(arr[i], str) == arr[i]) {
+ if (strstr(arr[i], str) != NULL) {
return 0;
}
}
@@ -1350,41 +1307,29 @@ char **strdeldup(char **arr) {
return result;
}
-char **depends_read(const char *filename) {
- int records = 0;
- char line[BUFSIZ];
- memset(line, '\0', BUFSIZ);
- FILE *fp = fopen(filename, "r");
- if (!fp) {
- fprintf(SYSERROR);
- return NULL;
- }
+void depends_all(Dependencies **deps, const char *_package) {
+ static int next = 0;
+ char *package = find_package(_package);
+ char depfile[PATH_MAX];
+ char template[PATH_MAX];
+ char suffix[PATH_MAX] = "spm_depends_all_XXXXXX";
+ sprintf(template, "%s%c%s", TMP_DIR, DIRSEP, suffix);
- while (fgets(line, BUFSIZ, fp) != NULL) {
- if (strstr(line, "\n") != NULL || strstr(line, "\r\n") != NULL) {
- records++;
+ // Create a new temporary directory and extract the requested package into it
+ char *tmpdir = mkdtemp(template);
+ tar_extract_file(package, ".SPM_DEPENDS", tmpdir);
+ sprintf(depfile, "%s%c%s", tmpdir, DIRSEP, ".SPM_DEPENDS");
+
+ int resolved = dep_solve(deps, depfile);
+ for (int i = next; i < resolved; i++) {
+ next++;
+ if (dep_seen(deps, (*deps)->list[i])) {
+ depends_all(deps, (*deps)->list[i]);
}
}
- rewind(fp);
- int i = 0;
- char **result = (char **)calloc(records + 1, sizeof(char *));
- char *wtf = line;
- while (fgets(line, BUFSIZ, fp) != NULL) {
- if (isempty(line) || startswith(line, "#") == 0) {
- continue;
- }
- if (endswith(line, "\n") == 0) {
- memset(&line[strlen(line) - 1], '\0', 1);
- }
- else if (endswith(line, "\r\n") == 0) {
- memset(&line[strlen(line) - 2], '\0', 2);
- }
- result[i] = find_package(line);
- i++;
- }
- fclose(fp);
- return result;
+ unlink(depfile);
+ unlink(tmpdir);
}
int install(const char *destroot, const char *_package) {
@@ -1413,44 +1358,28 @@ int install(const char *destroot, const char *_package) {
getcwd(cwd, sizeof(cwd));
+ RelocationEntry **b_record = NULL;
+ RelocationEntry **t_record = NULL;
chdir(tmpdir);
{
// Rewrite binary prefixes
RelocationEntry **b_record = prefixes_read(".SPM_PREFIX_BIN");
- if (!b_record) {
- fprintf(SYSERROR);
- exit(1);
- }
-
- for (int i = 0; b_record[i] != NULL; i++) {
- relocate(b_record[i]->path, b_record[i]->prefix, destroot);
+ if (b_record) {
+ for (int i = 0; b_record[i] != NULL; i++) {
+ relocate(b_record[i]->path, b_record[i]->prefix, destroot);
+ }
}
- prefixes_free(b_record);
// Rewrite text prefixes
RelocationEntry **t_record = prefixes_read(".SPM_PREFIX_TEXT");
- if (!t_record) {
- fprintf(SYSERROR);
- exit(1);
+ if (t_record) {
+ for (int i = 0; t_record[i] != NULL; i++) {
+ file_replace_text(t_record[i]->path, t_record[i]->prefix, destroot);
+ }
}
- for (int i = 0; t_record[i] != NULL; i++) {
- file_replace_text(t_record[i]->path, t_record[i]->prefix, destroot);
- }
+ prefixes_free(b_record);
prefixes_free(t_record);
-
- char **deptmp = depends_read(".SPM_DEPENDS");
- char **depends = strdeldup(deptmp);
- for (int i = 0; deptmp[i]; i++) {
- free(deptmp[i]);
- }
- free(deptmp);
-
- for (int i = 0; depends[i] != NULL; i++) {
- install(destroot, basename(depends[i]));
- free(depends[i]);
- }
- free(depends);
}
chdir(cwd);
@@ -1460,13 +1389,13 @@ int install(const char *destroot, const char *_package) {
if (rsync(NULL, source, destroot) != 0) {
exit(1);
}
- //rmdirs(tmpdir);
+ rmdirs(tmpdir);
free(package);
}
/**
- * Free memory allocated by `read_prefixes` function
+ * Free memory allocated by `prefixes_read` function
* @param entry array of RelocationEntry
*/
void prefixes_free(RelocationEntry **entry) {
@@ -1474,7 +1403,9 @@ void prefixes_free(RelocationEntry **entry) {
return;
}
for (int i = 0; entry[i] != NULL; i++) {
- free(entry[i]);
+ if (entry[i]->prefix) free(entry[i]->prefix);
+ if (entry[i]->path) free(entry[i]->path);
+ if (entry[i]) free(entry[i]);
}
free(entry);
}
@@ -1496,56 +1427,96 @@ void prefixes_free(RelocationEntry **entry) {
* @return success=array of RelocationEntry, failure=NULL
*/
RelocationEntry **prefixes_read(const char *filename) {
- const int initial_records = 2;
size_t i = 0;
+ int record_count = 0;
+ int parity = 0;
FILE *fp = fopen(filename, "r");
if (!fp) {
fprintf(SYSERROR);
return NULL;
}
- char prefix[BUFSIZ];
- char path[BUFSIZ];
RelocationEntry **entry = NULL;
+ char line[BUFSIZ];
+ memset(line, '\0', BUFSIZ);
+
+ while (fgets(line, BUFSIZ, fp) != NULL) {
+ if (isempty(line)) {
+ continue;
+ }
+ record_count++;
+ }
+ rewind(fp);
// Initialize the relocation entry array
- entry = (RelocationEntry **)calloc(initial_records, sizeof(RelocationEntry *));
- if (!entry) {
+ if (record_count == 0) {
return NULL;
}
- // Read two lines at a time from the prefix file
- while (fgets(prefix, BUFSIZ, fp) != NULL && fgets(path, BUFSIZ, fp) != NULL) {
- // Allocate a relocation record
- entry[i] = (RelocationEntry *)calloc(1, sizeof(RelocationEntry));
+ parity = record_count % 2;
+ if (parity != 0) {
+ fprintf(stderr, "%s: records are not divisible by 2 (got: %d %% 2 = %d)\n", filename, record_count, parity);
+ return NULL;
+ }
+ record_count /= 2;
+
+ entry = (RelocationEntry **)calloc(record_count + 1, sizeof(RelocationEntry *));
+ if (!entry) {
+ return NULL;
+ }
+ for (int i = 0; i < record_count; i++) {
+ entry[i] = (RelocationEntry *) calloc(1, sizeof(RelocationEntry));
if (!entry[i]) {
- prefixes_free(entry);
- fclose(fp);
return NULL;
}
+ }
- // Populate prefix data (a prefix starts with a #)
- entry[i]->prefix = (char *)calloc(strlen(prefix) + 1, sizeof(char));
- if (!entry[i]->prefix) {
- prefixes_free(entry);
- fclose(fp);
- return NULL;
+ int do_prefix = 0;
+ int do_path = 0;
+ while (fgets(line, BUFSIZ, fp) != NULL) {
+ char *wtf = line;
+ if (isempty(line)) {
+ continue;
+ }
+ if (startswith(line, "#") == 0) {
+ do_prefix = 1;
+ }
+ else {
+ do_path = 1;
}
- strncpy(entry[i]->prefix, prefix, strlen(prefix));
- // Remove prefix delimiter and whitespace
- strchrdel(entry[i]->prefix, "#");
- entry[i]->prefix = strip(entry[i]->prefix);
-
- // Populate path data
- entry[i]->path = (char *)calloc(strlen(path) + 1, sizeof(char));
- if (!entry[i]->path) {
- prefixes_free(entry);
+
+ // Allocate a relocation record
+ if (!entry[i]) {
fclose(fp);
return NULL;
}
- strncpy(entry[i]->path, path, strlen(path));
- entry[i]->path = strip(entry[i]->path);
- entry = (RelocationEntry **) reallocarray(entry, initial_records + i, sizeof(RelocationEntry *));
+
+ if (do_prefix) {
+ // Populate prefix data (a prefix starts with a #)
+ entry[i]->prefix = (char *) calloc(strlen(line) + 1, sizeof(char));
+ if (!entry[i]->prefix) {
+ fclose(fp);
+ return NULL;
+ }
+ strncpy(entry[i]->prefix, line, strlen(line));
+ // Remove prefix delimiter and whitespace
+ strchrdel(entry[i]->prefix, "#");
+ entry[i]->prefix = strip(entry[i]->prefix);
+ do_prefix = 0;
+ continue;
+ }
+
+ else if (do_path) {
+ // Populate path data
+ entry[i]->path = (char *) calloc(strlen(line) + 1, sizeof(char));
+ if (!entry[i]->path) {
+ fclose(fp);
+ return NULL;
+ }
+ strncpy(entry[i]->path, line, strlen(line));
+ entry[i]->path = strip(entry[i]->path);
+ do_path = 0;
+ }
i++;
}
fclose(fp);
@@ -1557,6 +1528,7 @@ void init_config_global(void) {
SPM_GLOBAL.user_config_file = NULL;
SPM_GLOBAL.package_dir = NULL;
SPM_GLOBAL.tmp_dir = NULL;
+ SPM_GLOBAL.config = NULL;
if (uname(&SPM_GLOBAL.sysinfo) != 0) {
fprintf(SYSERROR);
@@ -1738,41 +1710,20 @@ int main(int argc, char *argv[]) {
// Ensure external programs are available for use.
check_runtime_environment();
- printf("find_package test:\n");
- const char *pkg_name = "python";
- char *package = NULL;
- package = find_package(pkg_name);
-
- if (package != NULL) {
- printf("Package found: %s\n", package);
- free(package);
- } else {
- fprintf(stderr, "Package does not exist: %s\n", pkg_name);
- }
-
- /*
- char *test_path = realpath("root/lib/python3.7/lib-dynload/_multiprocessing.cpython-37m-x86_64-linux-gnu.so", NULL);
- if (!test_path) {
- fprintf(stderr, "Unable to get absolute path for %s\n", test_path);
- exit(1);
- }
- char *rpath = gen_rpath(test_path);
-
- if (!rpath) {
- fprintf(stderr, "Unable to generate RPATH for %s\n", test_path);
- free(test_path);
- exit(1);
- }
+ // Install a package to test things out
+ const char *root = "/tmp/root";
+ const char *package = "python-pip";
+ Dependencies *deps;
+ dep_init(&deps);
+ depends_all(&deps, package);
+ dep_show(&deps);
- printf("Setting RPATH: %s\n", test_path);
- if (set_rpath(test_path, rpath) != 0) {
- fprintf(stderr, "RPATH assignment failed\n");
+ for (int i = 0; i < deps->records; i++) {
+ install(root, deps->list[i]);
}
- */
+ install(root, package);
- install("/tmp/root", "python");
- //free(test_path);
- //free(rpath);
+ dep_free(&deps);
free_global_config();
return 0;
}
diff --git a/spm.h b/spm.h
index d78fb63..f8eab43 100644
--- a/spm.h
+++ b/spm.h
@@ -4,6 +4,7 @@
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
+#include <fts.h>
#include <glob.h>
#include <stdio.h>
#include <stdlib.h>
@@ -40,6 +41,20 @@
#define SHELL_BENCHMARK 1 << 2
typedef struct {
+ char *root;
+ char **dirs;
+ size_t dirs_length;
+ char **files;
+ size_t files_length;
+} FSTree;
+
+typedef struct {
+ size_t __size; // Count of allocated records
+ size_t records; // Count of usable records
+ char **list; // Array of dependencies
+} Dependencies;
+
+typedef struct {
char *key;
char *value;
size_t key_length;
@@ -111,12 +126,10 @@ char *gen_rpath(const char *_filename);
int set_rpath(const char *filename, char *_rpath);
void walkdir(char *dirpath, Dirwalk **result, unsigned int dirs);
-char **fstree(const char *path, unsigned int get_dir_flag);
long int get_file_size(const char *filename);
int mkdirs(const char *_path, mode_t mode);
-int rmdirs(const char *_path);
char *dirname(const char *_path);
-char *basename(const char *_path);
+char *basename(char *path);
char *get_user_conf_dir(void);
char *get_user_config_file(void);
@@ -142,4 +155,19 @@ ConfigItem *config_get(ConfigItem **item, const char *key);
void config_free(ConfigItem **item);
void config_test(void);
+// deps.c
+int exists(const char *filename);
+int dep_seen(Dependencies **deps, const char *name);
+int dep_init(Dependencies **deps);
+void dep_free(Dependencies **deps);
+int dep_append(Dependencies **deps, char *name);
+int dep_solve(Dependencies **deps, const char *filename);
+void dep_show(Dependencies **deps);
+
+// fstree.c
+int _fstree_compare(const FTSENT **a, const FTSENT **b);
+void fstree_free(FSTree *fsdata);
+FSTree *fstree(const char *_path);
+int rmdirs(const char *_path);
+
#endif //SPM_SPM_H