diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2019-12-17 09:41:52 -0500 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2019-12-17 09:41:52 -0500 |
commit | fa992c8655f2fe27a97fe0e6768800a356de3744 (patch) | |
tree | 7fc38d4bd3ff47abe6b76ded773450b9b65d11b8 | |
parent | fcf0e9159b76be699bc8560f853ece8bb2c7ff2e (diff) | |
download | spmc-fa992c8655f2fe27a97fe0e6768800a356de3744.tar.gz |
Dependencies are finally installable
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | config.c | 32 | ||||
-rw-r--r-- | deps.c | 115 | ||||
-rw-r--r-- | fstree.c | 101 | ||||
-rw-r--r-- | spm.c | 369 | ||||
-rw-r--r-- | spm.h | 34 |
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) @@ -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; } @@ -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); + } +} @@ -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; } @@ -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 |