17#define PCRE2_CODE_UNIT_WIDTH 8
24#include "physfs_archiver_blacklist.h"
48 if ( PHYSFS_mount( filename, NULL, 0 ) == 0 ) {
49 WARN( _(
"Failed to mount plugin '%s': %s" ), filename,
50 _( PHYSFS_getErrorByCode( PHYSFS_getLastErrorCode() ) ) );
55 PHYSFS_stat(
"plugin.xml", &stat );
56 realdir = PHYSFS_getRealDir(
"plugin.xml" );
57 if ( ( stat.filetype != PHYSFS_FILETYPE_REGULAR ) || ( realdir == NULL ) ||
58 strcmp( realdir, filename ) != 0 )
67 plg->
author = strdup( _(
"Unknown" ) );
69 plg->
version = strdup( _(
"Unknown" ) );
74 PHYSFS_unmount( filename );
87 xmlNodePtr node, parent;
92 parent = doc->xmlChildrenNode;
93 if ( parent == NULL ) {
95 nfile_concatPaths( buf,
sizeof( buf ), plg->
mountpoint, file );
96 WARN( _(
"Malformed '%s' file: does not contain elements" ), buf );
100 xmlr_attr_strd( parent,
"name", plg->
name );
101 if ( plg->
name == NULL )
102 WARN( _(
"Plugin '%s' has no name!" ), path );
104 node = parent->xmlChildrenNode;
106 xml_onlyNodes( node );
108 xmlr_strd( node,
"author", plg->
author );
109 xmlr_strd( node,
"version", plg->
version );
110 xmlr_strd( node,
"description", plg->
description );
112 xmlr_int( node,
"priority", plg->
priority );
113 xmlr_strd( node,
"source", plg->
source );
114 if ( xml_isNode( node,
"blacklist" ) ) {
119 if ( xml_isNode( node,
"whitelist" ) ) {
124 if ( xml_isNode( node,
"total_conversion" ) ) {
126 const char *blk[] = {
129 "^spob_virtual/.*\\.xml",
130 "^factions/.*\\.xml",
131 "^commodities/.*\\.xml",
134 "^missions/.*\\.lua",
137 "^asteroids/.*\\.xml",
139 "^map_decorator/.*\\.xml",
140 "^naevpedia/.*\\.xml",
144 const char *wht[] = {
145 "^events/settings.lua",
148 for (
int i = 0; blk[i] != NULL; i++ )
150 for (
int i = 0; wht[i] != NULL; i++ )
157 WARN( _(
"Plugin '%s' has unknown metadata node '%s'!" ),
159 }
while ( xml_nextNode( node ) );
163#define MELEMENT( o, s ) \
165 WARN( _( "Plugin '%s' missing/invalid '%s' element" ), plg->name, \
167 MELEMENT( plg->
author == NULL,
"author" );
168 MELEMENT( plg->
version == NULL,
"version" );
169 MELEMENT( plg->
description == NULL,
"description" );
171 MELEMENT( plg->
source == NULL,
"source" );
199 nfile_concatPaths( dir,
sizeof( dir ), PHYSFS_getWriteDir(),
"plugins" );
215 PHYSFS_stat(
"plugins", &stat );
216 if ( stat.filetype == PHYSFS_FILETYPE_DIRECTORY ) {
218 char **files = PHYSFS_enumerateFiles(
"plugins" );
219 for (
char **f = files; *f != NULL; f++ ) {
222 nfile_concatPaths( buf,
PATH_MAX, PHYSFS_getWriteDir(),
"plugins",
227 if ( PHYSFS_mount( buf, NULL, 0 ) == 0 ) {
228 WARN( _(
"Failed to mount plugin '%s': %s" ), buf,
229 _( PHYSFS_getErrorByCode( PHYSFS_getLastErrorCode() ) ) );
235 memset( plg, 0,
sizeof(
plugin_t ) );
239 PHYSFS_stat(
"plugin.xml", &stat );
240 realdir = PHYSFS_getRealDir(
"plugin.xml" );
241 if ( ( stat.filetype == PHYSFS_FILETYPE_REGULAR ) && realdir &&
242 strcmp( realdir, buf ) == 0 )
245 WARN( _(
"Plugin '%s' does not have a valid '%s'!" ), buf,
249 if ( plg->
author == NULL )
250 plg->
author = strdup( _(
"Unknown" ) );
252 plg->
version = strdup( _(
"Unknown" ) );
256 PHYSFS_freeList( files );
260 for (
int i = 0; i < n; i++ )
261 PHYSFS_unmount(
plugins[i].mountpoint );
270 for (
int i = n - 1; i >= 0; i-- )
271 PHYSFS_mount(
plugins[i].mountpoint, NULL, 0 );
274 DEBUG(
"Loaded plugins:" );
275 for (
int i = 0; i < n; i++ ) {
280 nfile_concatPaths( buf,
PATH_MAX, PHYSFS_getWriteDir(),
"plugins" );
317 if ( plg->
name != NULL )
347 PCRE2_SIZE erroroffset;
349 pcre2_match_data *match_data;
351 if (
plugins[i].compatibility == NULL )
354 re = pcre2_compile( (PCRE2_SPTR)
plugins[i].compatibility,
355 PCRE2_ZERO_TERMINATED, 0, &errornumber, &erroroffset,
358 PCRE2_UCHAR buffer[256];
359 pcre2_get_error_message( errornumber, buffer,
sizeof( buffer ) );
360 WARN( _(
"Plugin '%s' PCRE2 compilation failed at offset %d: %s" ),
366 match_data = pcre2_match_data_create_from_pattern( re, NULL );
367 int rc = pcre2_match( re, (PCRE2_SPTR)version, strlen( version ), 0, 0,
369 pcre2_match_data_free( match_data );
372 case PCRE2_ERROR_NOMATCH:
373 WARN(
"Plugin '%s' does not support Naev version '%s'.",
378 WARN( _(
"Matching error %d" ), rc );
385 pcre2_code_free( re );
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_grow(ptr_array)
Increases the number of elements by one and returns the last element.
#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.
const char * naev_version(int long_version)
Returns the version in a human readable string.
int nfile_dirMakeExist(const char *path)
Creates a directory if it doesn't exist.
int nfile_fileExists(const char *path)
Checks to see if a file exists.
int nfile_dirExists(const char *path)
Checks to see if a directory exists.
xmlDocPtr xml_parsePhysFS(const char *filename)
Analogous to xmlParseMemory/xmlParseFile.
int blacklist_init(void)
Initializes the blacklist system if necessary. If no plugin is blacklisting, it will not do anything.
int blacklist_append(const char *path)
Appends a regex string to be blacklisted.
int whitelist_append(const char *path)
Appends a regex string to be whitelisted.
void blacklist_exit(void)
Exits the blacklist system and cleans up as necessary.
plugin_t * plugin_test(const char *filename)
Tests to see if a file is a plugin and loads information.
void plugin_insert(plugin_t *plg)
Inserts a plugin to the list, but does not properly enable it (requires restart).
int plugin_init(void)
Initialize and loads all the available plugins.
int plugin_check(void)
Checks to see if the plugins are self-declared compatible with Naev.
const char * plugin_name(const plugin_t *plg)
Tries to tget the name of a plugin.
static plugin_t * plugins
void plugin_exit(void)
Exits the plugin stuff.
static int plugin_parse(plugin_t *plg, const char *file, const char *path, int apply)
Parses a plugin description file.
static int plugin_cmp(const void *a, const void *b)
For qsort on plugins.
const char * plugin_dir(void)
Gets the plugin directory.
void plugin_free(plugin_t *plg)
Frees a previously allocated plugin.
const plugin_t * plugin_list(void)
Returns the list of all the plugins.