Try to automatically locate plugins, show loaded plugins on web interface
This commit is contained in:
parent
c37e33f5c1
commit
a4dea03121
|
@ -35,6 +35,17 @@
|
|||
</tbody>
|
||||
</table>
|
||||
<br />
|
||||
<table id="plugin" cellspacing="0">
|
||||
<col style="width: 20ex;" />
|
||||
<col />
|
||||
<thead>
|
||||
<tr><th>Plugin</th><th>Version</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td></td><td></tr></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br />
|
||||
<table id="stat" cellspacing="0">
|
||||
<col style="width: 20ex;" />
|
||||
<col />
|
||||
|
|
|
@ -51,6 +51,19 @@ var Updater = {
|
|||
row.push(Element.textContent(element.childNodes[2]));
|
||||
threadTable.addTbodyRow(row);
|
||||
});
|
||||
|
||||
// Monkey see, monkey do
|
||||
var plugin = $A(request.responseXML.getElementsByTagName('plugin'));
|
||||
var pluginTable = new Table('plugin');
|
||||
pluginTable.removeTBodyRows();
|
||||
plugin.each(function(element) {
|
||||
row = [];
|
||||
info = Element.textContent(element.childNodes[0]).split('/',2);
|
||||
row.push(info[0]);
|
||||
row.push(info[1]);
|
||||
pluginTable.addTbodyRow(row);
|
||||
});
|
||||
|
||||
// $('session_count').replaceChild(document.createTextNode(users + ' Connected Users'),$('session_count').firstChild);
|
||||
if (!Updater.stop) {
|
||||
Updater.wait();
|
||||
|
|
|
@ -96,7 +96,7 @@ typedef struct tag_mp3file {
|
|||
uint32_t play_count;
|
||||
uint32_t rating;
|
||||
uint32_t db_timestamp;
|
||||
|
||||
|
||||
uint32_t disabled;
|
||||
uint32_t bpm; /* TBPM */
|
||||
|
||||
|
@ -187,6 +187,7 @@ typedef struct tag_packed_mp3file {
|
|||
char *has_video;
|
||||
char *contentrating;
|
||||
char *bits_per_sample;
|
||||
char *album_artist;
|
||||
} PACKED_MP3FILE;
|
||||
|
||||
#define PL_STATICWEB 0
|
||||
|
|
93
src/main.c
93
src/main.c
|
@ -197,6 +197,50 @@ void usage(char *program) {
|
|||
printf("\n\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* process a directory for plugins
|
||||
*
|
||||
* @returns TRUE if at least one plugin loaded successfully
|
||||
*/
|
||||
int load_plugin_dir(char *plugindir) {
|
||||
DIR *d_plugin;
|
||||
char de[sizeof(struct dirent) + MAXNAMLEN + 1]; /* ?? solaris */
|
||||
struct dirent *pde;
|
||||
char *pext;
|
||||
char *perr=NULL;
|
||||
int loaded=FALSE;
|
||||
char plugin[PATH_MAX];
|
||||
|
||||
if((d_plugin=opendir(plugindir)) == NULL) {
|
||||
DPRINTF(E_LOG,L_MAIN,"Error opening plugin dir %s. Ignoring\n",
|
||||
plugindir);
|
||||
return FALSE;
|
||||
|
||||
} else {
|
||||
while((readdir_r(d_plugin,(struct dirent *)de,&pde) != 1) && pde) {
|
||||
pext = strrchr(pde->d_name,'.');
|
||||
if((strcasecmp(pext,".so") == 0) ||
|
||||
(strcasecmp(pext,".dylib") == 0) ||
|
||||
(strcasecmp(pext,".dll") == 0)) {
|
||||
/* must be a plugin */
|
||||
snprintf(plugin,PATH_MAX,"%s%c%s",plugindir,
|
||||
PATHSEP,pde->d_name);
|
||||
if(plugin_load(&perr,plugin) != PLUGIN_E_SUCCESS) {
|
||||
DPRINTF(E_LOG,L_MAIN,"Error loading plugin %s: %s\n",
|
||||
plugin,perr);
|
||||
free(perr);
|
||||
perr = NULL;
|
||||
} else {
|
||||
loaded = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(d_plugin);
|
||||
}
|
||||
|
||||
return loaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Kick off the daap server and wait for events.
|
||||
*
|
||||
|
@ -233,18 +277,12 @@ int main(int argc, char *argv[]) {
|
|||
char *servername, *iface;
|
||||
char *ffid = NULL;
|
||||
int appdir = 0;
|
||||
|
||||
char *perr=NULL;
|
||||
char txtrecord[255];
|
||||
|
||||
void *phandle;
|
||||
char *plugindir;
|
||||
char plugin[PATH_MAX];
|
||||
DIR *d_plugin;
|
||||
char de[sizeof(struct dirent) + MAXNAMLEN + 1]; /* ?? solaris */
|
||||
struct dirent *pde;
|
||||
char *pext;
|
||||
|
||||
int err;
|
||||
char *perr=NULL;
|
||||
char *apppath;
|
||||
|
||||
int debuglevel=0;
|
||||
|
@ -390,28 +428,27 @@ int main(int argc, char *argv[]) {
|
|||
if((plugindir=conf_alloc_string("plugins","plugin_dir",NULL)) != NULL) {
|
||||
/* instead of specifying plugins, let's walk through the directory
|
||||
* and load each of them */
|
||||
if((d_plugin=opendir(plugindir)) == NULL) {
|
||||
DPRINTF(E_LOG,L_MAIN,"Error opening plugin dir. Ignoring\n");
|
||||
} else {
|
||||
while((readdir_r(d_plugin,(struct dirent *)de,&pde) != 1) && pde) {
|
||||
pext = strrchr(pde->d_name,'.');
|
||||
if((strcasecmp(pext,".so") == 0) ||
|
||||
(strcasecmp(pext,".dylib") == 0) ||
|
||||
(strcasecmp(pext,".dll") == 0)) {
|
||||
/* must be a plugin */
|
||||
snprintf(plugin,PATH_MAX,"%s%c%s",plugindir,
|
||||
PATHSEP,pde->d_name);
|
||||
if(plugin_load(&perr,plugin) != PLUGIN_E_SUCCESS) {
|
||||
DPRINTF(E_LOG,L_MAIN,"Error loading plugin %s: %s\n",
|
||||
plugin,perr);
|
||||
free(perr);
|
||||
perr = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(d_plugin);
|
||||
if(!load_plugin_dir(plugindir)) {
|
||||
DPRINTF(E_LOG,L_MAIN,"Warning: Could not load plugins\n");
|
||||
}
|
||||
free(plugindir);
|
||||
} else {
|
||||
if((!load_plugin_dir("/usr/lib/firefly")) &&
|
||||
(!load_plugin_dir("/usr/lib/mt-daapd")) &&
|
||||
(!load_plugin_dir("/usr/share/firefly/plugins")) &&
|
||||
(!load_plugin_dir("/usr/share/mt-daapd/plugins")) &&
|
||||
(!load_plugin_dir("/usr/local/share/firefly/plugins")) &&
|
||||
(!load_plugin_dir("/usr/local/share/mt-daapd/plugins")) &&
|
||||
(!load_plugin_dir("/opt/share/firefly/plugins")) &&
|
||||
(!load_plugin_dir("/opt/share/mt-daapd/plugins")) &&
|
||||
(!load_plugin_dir("plugins/.libs"))) {
|
||||
DPRINTF(E_FATAL,L_MAIN,"plugins/plugin_dir not specified\n");
|
||||
}
|
||||
}
|
||||
|
||||
phandle=NULL;
|
||||
while((phandle=plugin_enum(phandle))) {
|
||||
DPRINTF(E_LOG,L_MAIN,"Plugin loaded: %s\n",plugin_get_description(phandle));
|
||||
}
|
||||
|
||||
runas = conf_alloc_string("general","runas","nobody");
|
||||
|
|
29
src/plugin.c
29
src/plugin.c
|
@ -247,6 +247,35 @@ void _plugin_recalc_codecs(void) {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* plugin_get_description
|
||||
*/
|
||||
char *plugin_get_description(void *which) {
|
||||
PLUGIN_ENTRY *ppi = (PLUGIN_ENTRY *)which;
|
||||
|
||||
return ppi->pinfo->server;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* walk through the loaded plugin list
|
||||
*/
|
||||
void *plugin_enum(void *where) {
|
||||
PLUGIN_ENTRY *ppi = (PLUGIN_ENTRY *)where;
|
||||
|
||||
if(!ppi) {
|
||||
// _plugin_readlock();
|
||||
return (void*) _plugin_list.next;
|
||||
}
|
||||
|
||||
if(!ppi->next) {
|
||||
// _plugin_unlock();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (void*) ppi->next;
|
||||
}
|
||||
|
||||
/**
|
||||
* load a specified plugin.
|
||||
*
|
||||
|
|
|
@ -37,6 +37,9 @@ extern int plugin_auth_handle(WS_CONNINFO *pwsc, char *username, char *pw);
|
|||
extern int plugin_rend_register(char *name, int port, char *iface, char *txt);
|
||||
extern void plugin_event_dispatch(int event_id, int intval, void *vp, int len);
|
||||
|
||||
extern void *plugin_enum(void *);
|
||||
extern char *plugin_get_description(void *);
|
||||
|
||||
/* these should really get rows */
|
||||
|
||||
#define PLUGIN_E_SUCCESS 0
|
||||
|
|
|
@ -508,6 +508,7 @@ void xml_get_stats(WS_CONNINFO *pwsc) {
|
|||
WSTHREADENUM wste;
|
||||
int count;
|
||||
XMLSTRUCT *pxml;
|
||||
void *phandle;
|
||||
|
||||
pxml=xml_init(pwsc,1);
|
||||
xml_push(pxml,"status");
|
||||
|
@ -525,7 +526,6 @@ void xml_get_stats(WS_CONNINFO *pwsc) {
|
|||
xml_output(pxml,"status","Disabled");
|
||||
}
|
||||
#else
|
||||
|
||||
ws_writefd(pwsc,"<td>No Support</td><td> </td></tr>\n");
|
||||
#endif
|
||||
xml_pop(pxml); /* service */
|
||||
|
@ -542,6 +542,16 @@ void xml_get_stats(WS_CONNINFO *pwsc) {
|
|||
|
||||
xml_pop(pxml); /* service_status */
|
||||
|
||||
xml_push(pxml,"plugins");
|
||||
phandle = NULL;
|
||||
while((phandle = plugin_enum(phandle))) {
|
||||
xml_push(pxml,"plugin");
|
||||
xml_output(pxml,"name",plugin_get_description(phandle));
|
||||
xml_pop(pxml); /* plugin */
|
||||
}
|
||||
|
||||
xml_pop(pxml); /* plugins */
|
||||
|
||||
xml_push(pxml,"thread_status");
|
||||
|
||||
pci = ws_thread_enum_first(config.server,&wste);
|
||||
|
|
Loading…
Reference in New Issue