cfspack: add pattern argument

This commit is contained in:
Virgil Dupras 2019-06-02 16:22:07 -04:00
parent 22e990ed89
commit c317fbdcf9
2 changed files with 21 additions and 6 deletions

View File

@ -1,6 +1,6 @@
# cfspack # cfspack
A tool/library to pack a directory into a CFS blob and unpack a CFS blob into A tool/library to pack files into a CFS blob and unpack a CFS blob into
a directory. a directory.
## Usage ## Usage
@ -12,6 +12,9 @@ To pack a directory into a CFS blob, run:
The blob is spit to stdout. If there are subdirectories, they will be prefixes The blob is spit to stdout. If there are subdirectories, they will be prefixes
to the filenames under it. to the filenames under it.
`cfspack` takes an optional second argument, a "fnmatch" pattern. If specified,
only files patching the pattern will be included.
The program errors out if a file name is too long (> 26 bytes) or too big The program errors out if a file name is too long (> 26 bytes) or too big
(> 0x10000 - 0x20 bytes). (> 0x10000 - 0x20 bytes).

View File

@ -1,6 +1,8 @@
#define _GNU_SOURCE
#include <stdio.h> #include <stdio.h>
#include <dirent.h> #include <dirent.h>
#include <string.h> #include <string.h>
#include <fnmatch.h>
#define BLKSIZE 0x100 #define BLKSIZE 0x100
#define HEADERSIZE 0x20 #define HEADERSIZE 0x20
@ -55,7 +57,7 @@ int spitblock(char *fullpath, char *fn)
return 0; return 0;
} }
int spitdir(char *path, char *prefix) int spitdir(char *path, char *prefix, char *pattern)
{ {
DIR *dp; DIR *dp;
struct dirent *ep; struct dirent *ep;
@ -79,6 +81,12 @@ int spitdir(char *path, char *prefix)
fprintf(stderr, "Filename too long: %s/%s\n", prefix, ep->d_name); fprintf(stderr, "Filename too long: %s/%s\n", prefix, ep->d_name);
return 1; return 1;
} }
if (pattern) {
if (fnmatch(pattern, ep->d_name, FNM_EXTMATCH) != 0) {
continue;
}
}
char fullpath[0x1000]; char fullpath[0x1000];
strcpy(fullpath, path); strcpy(fullpath, path);
strcat(fullpath, "/"); strcat(fullpath, "/");
@ -90,7 +98,7 @@ int spitdir(char *path, char *prefix)
} }
strcat(newprefix, ep->d_name); strcat(newprefix, ep->d_name);
if (ep->d_type == DT_DIR) { if (ep->d_type == DT_DIR) {
int r = spitdir(fullpath, newprefix); int r = spitdir(fullpath, newprefix, pattern);
if (r != 0) { if (r != 0) {
return r; return r;
} }
@ -107,11 +115,15 @@ int spitdir(char *path, char *prefix)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
if (argc != 2) { if ((argc > 3) || (argc < 2)) {
fprintf(stderr, "Usage: cfspack /path/to/dir\n"); fprintf(stderr, "Usage: cfspack /path/to/dir [pattern] \n");
return 1; return 1;
} }
char *srcpath = argv[1]; char *srcpath = argv[1];
return spitdir(srcpath, ""); char *pattern = NULL;
if (argc == 3) {
pattern = argv[2];
}
return spitdir(srcpath, "", pattern);
} }