diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2020-01-23 01:38:41 -0500 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2020-01-23 01:38:41 -0500 |
commit | bb13dd28686146c07ca9054a95ae19d09b320c8d (patch) | |
tree | c9f84ba3ad709e5757574498579290887a2cc640 | |
parent | 74ddda664b9d7e843da3ec8254716c11016007e5 (diff) | |
download | spmc-bb13dd28686146c07ca9054a95ae19d09b320c8d.tar.gz |
fstree() now accepts filter modes SPM_FSTREE_FLT_{NONE,CONTAINS,ENDSWITH,STARTSWITH}
-rw-r--r-- | include/spm.h | 8 | ||||
-rw-r--r-- | src/fs.c | 80 | ||||
-rw-r--r-- | src/manifest.c | 7 | ||||
-rw-r--r-- | src/relocation.c | 2 |
4 files changed, 61 insertions, 36 deletions
diff --git a/include/spm.h b/include/spm.h index c011e34..f40ea10 100644 --- a/include/spm.h +++ b/include/spm.h @@ -66,13 +66,17 @@ #define SPM_META_PREFIX_TEXT ".SPM_PREFIX_TEXT" #define SPM_META_MANIFEST ".SPM_MANIFEST" // TODO: Implement - #define SPM_MANIFEST_SEPARATOR '|' #define SPM_MANIFEST_SEPARATOR_MAX 7 #define SPM_MANIFEST_NODATA "*" #define SPM_MANIFEST_HEADER "# SPM PACKAGE MANIFEST" #define SPM_MANIFEST_FILENAME "manifest.dat" +#define SPM_FSTREE_FLT_NONE 1 << 0 +#define SPM_FSTREE_FLT_CONTAINS 1 << 1 +#define SPM_FSTREE_FLT_ENDSWITH 1 << 2 +#define SPM_FSTREE_FLT_STARTSWITH 1 << 3 + #define PREFIX_WRITE_BIN 0 #define PREFIX_WRITE_TEXT 1 @@ -239,7 +243,7 @@ int rpath_set(const char *filename, const char *rpath); // fs.c int _fstree_compare(const FTSENT **a, const FTSENT **b); void fstree_free(FSTree *fsdata); -FSTree *fstree(const char *_path, char **filter_by); +FSTree *fstree(const char *_path, char **filter_by, unsigned int filter_mode); int rmdirs(const char *_path); long int get_file_size(const char *filename); int mkdirs(const char *_path, mode_t mode); @@ -8,11 +8,11 @@ * @param _path * @return */ -FSTree *fstree(const char *_path, char **filter_by) { - // TODO: Implement filter_by +FSTree *fstree(const char *_path, char **filter_by, unsigned int filter_mode) { FTS *parent = NULL; FTSENT *node = NULL; FSTree *fsdata = NULL; + int no_filter = 0; char *path = realpath(_path, NULL); if (path == NULL) { perror(_path); @@ -21,44 +21,64 @@ FSTree *fstree(const char *_path, char **filter_by) { } char *root[2] = { path, NULL }; + if (filter_by == NULL) { + // Create an array with an empty string. This signifies we want don't want to filter any paths. + no_filter = 1; + filter_by = calloc(2, sizeof(char *)); + filter_by[0] = calloc(2, sizeof(char)); + strcpy(filter_by[0], ""); + } + 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->root = (char *)calloc(strlen(path) + 1, sizeof(char)); fsdata->dirs = (char **)calloc(dirs_size, sizeof(char *)); - fsdata->files= (char **)calloc(files_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; + for (size_t i = 0; filter_by[i] != NULL; i++) { + // Drop paths containing filter string(s) according to the requested mode + if (filter_mode & SPM_FSTREE_FLT_CONTAINS && strstr(node->fts_path, filter_by[i]) == NULL) { + continue; + } + else if (filter_mode & SPM_FSTREE_FLT_ENDSWITH && endswith(node->fts_path, filter_by[i]) != 0) { + continue; + } + else if (filter_mode & SPM_FSTREE_FLT_STARTSWITH && startswith(node->fts_path, filter_by[i]) != 0) { + continue; + } + 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); @@ -66,6 +86,10 @@ FSTree *fstree(const char *_path, char **filter_by) { fsdata->dirs_length = dirs_records; fsdata->files_length = files_records; free(path); + if (no_filter) { + free(filter_by[0]); + free(filter_by); + } return fsdata; } @@ -89,7 +113,7 @@ int rmdirs(const char *_path) { return -1; } - FSTree *data = fstree(_path, NULL); + FSTree *data = fstree(_path, NULL, SPM_FSTREE_FLT_NONE); if (data->files) { for (size_t i = 0; data->files[i] != NULL; i++) { remove(data->files[i]); diff --git a/src/manifest.c b/src/manifest.c index df8d056..3aa054e 100644 --- a/src/manifest.c +++ b/src/manifest.c @@ -12,12 +12,9 @@ * @return `Manifest` */ Manifest *manifest_from(const char *package_dir) { + char *package_filter[] = {SPM_PACKAGE_EXTENSION, NULL}; // We only want packages FSTree *fsdata = NULL; - char *filter[] = { - SPM_PACKAGE_EXTENSION, - NULL, - }; - fsdata = fstree(package_dir, filter); + fsdata = fstree(package_dir, package_filter, SPM_FSTREE_FLT_ENDSWITH); Manifest *info = (Manifest *)calloc(1, sizeof(Manifest)); info->records = fsdata->files_length; diff --git a/src/relocation.c b/src/relocation.c index 9407036..4dc784f 100644 --- a/src/relocation.c +++ b/src/relocation.c @@ -253,7 +253,7 @@ int prefixes_write(const char *output_file, int mode, char **prefix, const char return -1; } - FSTree *fsdata = fstree(tree, NULL); + FSTree *fsdata = fstree(tree, NULL, SPM_FSTREE_FLT_NONE); if (!fsdata) { fclose(fp); fprintf(SYSERROR); |