12#define PCRE2_CODE_UNIT_WIDTH 8
19#define BLACKLIST_FILENAME "naev.BLACKLIST"
24typedef struct BlkFile_ {
39static PHYSFS_Io *blk_unsupportedIO(
void *opaque,
const char *filename );
40static int blk_unsupported(
void *opaque,
const char *name );
41static void *blk_openArchive( PHYSFS_Io *io,
const char *name,
int forWrite,
int *claimed );
42static PHYSFS_EnumerateCallbackResult blk_enumerate(
void *opaque,
const char *dirname, PHYSFS_EnumerateCallback cb,
const char *origdir,
void *callbackdata );
43static PHYSFS_Io *blk_openRead(
void *opaque,
const char *fnm);
44static int blk_stat(
void *opaque,
const char *fn, PHYSFS_Stat *stat );
45static void blk_closeArchive(
void *opaque );
53 .extension =
"BLACKLIST",
54 .description =
"Naev blacklist archiver.",
55 .author =
"Naev DevTeam",
56 .url =
"https://naev.org",
57 .supportsSymlinks = 0,
59 .openArchive = blk_openArchive,
60 .enumerate = blk_enumerate,
61 .openRead = blk_openRead,
62 .openWrite = blk_unsupportedIO,
63 .openAppend = blk_unsupportedIO,
64 .remove = blk_unsupported,
65 .mkdir = blk_unsupported,
67 .closeArchive = blk_closeArchive,
70static PHYSFS_sint64 blk_read(
struct PHYSFS_Io *io,
void *buf, PHYSFS_uint64 len );
71static PHYSFS_sint64 blk_write(
struct PHYSFS_Io *io,
const void *buffer, PHYSFS_uint64 len );
72static int blk_seek(
struct PHYSFS_Io *io, PHYSFS_uint64 offset );
73static PHYSFS_sint64 blk_tell(
struct PHYSFS_Io *io );
74static PHYSFS_sint64 blk_length(
struct PHYSFS_Io *io );
75static struct PHYSFS_Io *blk_duplicate(
struct PHYSFS_Io *io );
76static int blk_flush(
struct PHYSFS_Io *io );
77static void blk_destroy(
struct PHYSFS_Io *io );
90 .duplicate = blk_duplicate,
92 .destroy = blk_destroy,
103 .filetype = PHYSFS_FILETYPE_REGULAR,
115 .filetype = PHYSFS_FILETYPE_DIRECTORY,
129 dir_len = strlen( origdir );
130 fmt = ((dir_len && origdir[dir_len-1]==
'/') || dir_len==0) ?
"%s%s" :
"%s/%s";
131 SDL_asprintf( &path, fmt, origdir, fname );
132 if (!PHYSFS_stat( path, &stat )) {
133 PHYSFS_ErrorCode err = PHYSFS_getLastErrorCode();
134 if (err!=PHYSFS_ERR_BAD_FILENAME)
135 WARN( _(
"PhysicsFS: Cannot stat %s: %s"), path,
136 _(PHYSFS_getErrorByCode( err ) ) );
139 else if (stat.filetype == PHYSFS_FILETYPE_REGULAR) {
141 int rc = pcre2_match(
blk_re, (PCRE2_SPTR)path, strlen(path), 0, 0,
blk_match, NULL );
144 case PCRE2_ERROR_NOMATCH:
148 WARN(_(
"Matching error %d"), rc );
159 .filename= strdup(fname),
160 .dirname = strdup(origdir),
178 else if (stat.filetype == PHYSFS_FILETYPE_DIRECTORY ) {
183 .filename = strdup(fname),
184 .dirname = strdup(origdir),
193 return PHYSFS_ENUM_OK;
205 PCRE2_SIZE erroroffset;
217 blk_re = pcre2_compile( (PCRE2_SPTR)buf, PCRE2_ZERO_TERMINATED, 0, &errornumber, &erroroffset, NULL );
219 PCRE2_UCHAR buffer[256];
220 pcre2_get_error_message( errornumber, buffer,
sizeof(buffer) );
221 WARN(_(
"Blacklist PCRE2 compilation failed at offset %d: %s"), (
int)erroroffset, buffer );
237 pcre2_code_free(
blk_re );
246 int ret = PHYSFS_mountMemory( &
blk_archiver, 0, NULL, BLACKLIST_FILENAME, NULL, 0 );
248 WARN( _(
"PhysicsFS: %s"), _(PHYSFS_getErrorByCode( PHYSFS_getLastErrorCode() ) ) );
278 free(
blk_fs[i].filename );
279 free(
blk_fs[i].dirname );
300 const char *str = bsearch( &filename, lst,
array_size(lst),
sizeof(
const char*),
strsort );
304static PHYSFS_Io *blk_unsupportedIO(
void *opaque,
const char *filename )
311static int blk_unsupported(
void *opaque,
const char *filename )
318static void *blk_openArchive( PHYSFS_Io *io,
const char *name,
int forWrite,
int *claimed )
322 if (strcmp(name,BLACKLIST_FILENAME)==0) {
329static PHYSFS_EnumerateCallbackResult blk_enumerate(
void *opaque,
const char *dirname, PHYSFS_EnumerateCallback cb,
const char *origdir,
void *callbackdata )
333 PHYSFS_EnumerateCallbackResult retval = PHYSFS_ENUM_OK;
336 if (strcmp(
blk_fs[i].dirname, origdir )!=0)
339 retval = cb( callbackdata, origdir,
blk_fs[i].filename );
340 if (retval == PHYSFS_ENUM_ERROR)
341 PHYSFS_setErrorCode(PHYSFS_ERR_APP_CALLBACK);
342 if (retval != PHYSFS_ENUM_OK)
349static PHYSFS_Io *blk_openRead(
void *opaque,
const char *fnm )
353 PHYSFS_Io *io = malloc(
sizeof(PHYSFS_Io) );
360static int blk_stat(
void *opaque,
const char *fn, PHYSFS_Stat *stat )
374static void blk_closeArchive(
void *opaque )
379static PHYSFS_sint64 blk_read(
struct PHYSFS_Io *io,
void *buf, PHYSFS_uint64 len )
387static PHYSFS_sint64 blk_write(
struct PHYSFS_Io *io,
const void *buffer, PHYSFS_uint64 len )
395static int blk_seek(
struct PHYSFS_Io *io, PHYSFS_uint64 offset )
402static PHYSFS_sint64 blk_tell(
struct PHYSFS_Io *io )
408static PHYSFS_sint64 blk_length(
struct PHYSFS_Io *io )
414static struct PHYSFS_Io *blk_duplicate(
struct PHYSFS_Io *io )
419static int blk_flush(
struct PHYSFS_Io *io )
425static void blk_destroy(
struct PHYSFS_Io *io )
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
#define array_push_back(ptr_array, element)
Adds a new element at the end of the array.
#define array_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
Header file with generic functions and naev-specifics.
int strsort(const void *p1, const void *p2)
Sort function for sorting strings with qsort().
int scnprintf(char *text, size_t maxlen, const char *fmt,...)
Like snprintf(), but returns the number of characters ACTUALLY "printed" into the buffer....
static pcre2_code * blk_re
int blacklist_init(void)
Initializes the blacklist system if necessary. If no plugin is blacklisting, it will not do anything.
static const PHYSFS_Stat blk_emptystat
Stat for an empty regular file.
static int blk_matches(char **lst, const char *filename)
Tries to match a string in an array of strings that are sorted.
int blacklist_append(const char *path)
Appends a regex string to be blacklisted.
static char ** blk_dirnames
static const PHYSFS_Stat blk_emptystatdir
Stat for a fake directory.
static char ** blk_blacklists
static char ** blk_blacklists_re
static const PHYSFS_Io blk_emptyio
Mimicks an empty file.
void blacklist_exit(void)
Exits the blacklist system and cleans up as necessary.
static pcre2_match_data * blk_match
static const PHYSFS_Archiver blk_archiver
The archiver for blacklists.
static int blk_enumerateCallback(void *data, const char *origdir, const char *fname)
Used to build the blacklist and pseudo filesystem when iterating over real files.
Represents a file in a directory. Used to enumerate files.