aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2020-01-23 01:38:41 -0500
committerJoseph Hunkeler <jhunkeler@gmail.com>2020-01-23 01:38:41 -0500
commitbb13dd28686146c07ca9054a95ae19d09b320c8d (patch)
treec9f84ba3ad709e5757574498579290887a2cc640
parent74ddda664b9d7e843da3ec8254716c11016007e5 (diff)
downloadspmc-bb13dd28686146c07ca9054a95ae19d09b320c8d.tar.gz
fstree() now accepts filter modes SPM_FSTREE_FLT_{NONE,CONTAINS,ENDSWITH,STARTSWITH}
-rw-r--r--include/spm.h8
-rw-r--r--src/fs.c80
-rw-r--r--src/manifest.c7
-rw-r--r--src/relocation.c2
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);
diff --git a/src/fs.c b/src/fs.c
index f729c2a..baf5d7a 100644
--- a/src/fs.c
+++ b/src/fs.c
@@ -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);