diff --git a/src/os-win32.c b/src/os-win32.c index 61c20327..a1a95843 100644 --- a/src/os-win32.c +++ b/src/os-win32.c @@ -16,6 +16,7 @@ #include "win32.h" #include "err.h" #include "os-win32.h" +#include "plugin.h" #include "w32-eventlog.h" #include "w32-service.h" @@ -127,6 +128,7 @@ int os_closesyslog(void) { * @return TRUE on success, FALSE otherwise */ int os_syslog(int level, char *msg) { + plugin_event_dispatch(PLUGIN_EVENT_LOG, level, msg, (int)strlen(msg)+1); return elog_message(level, msg); } diff --git a/src/plugin.c b/src/plugin.c index 8a9abaa4..38667fbb 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -49,7 +49,8 @@ typedef struct tag_pluginentry { int type; char *versionstring; regex_t regex; - void *functions; + PLUGIN_OUTPUT_FN *output_fns; + PLUGIN_EVENT_FN *event_fns; PLUGIN_REND_INFO *rend_info; struct tag_pluginentry *next; } PLUGIN_ENTRY; @@ -233,13 +234,14 @@ int plugin_load(char **pe, char *path) { ppi->type = pinfo->type; ppi->versionstring = pinfo->server; - if(ppi->type == PLUGIN_OUTPUT) { + if(ppi->type & PLUGIN_OUTPUT) { /* build the regex */ if(regcomp(&ppi->regex,pinfo->url,REG_EXTENDED | REG_NOSUB)) { DPRINTF(E_LOG,L_PLUG,"Bad regex in %s: %s\n",path,pinfo->url); } } - ppi->functions = pinfo->handler_functions; + ppi->output_fns = pinfo->output_fns; + ppi->event_fns = pinfo->event_fns; ppi->rend_info = pinfo->rend_info; DPRINTF(E_INF,L_PLUG,"Loaded plugin %s (%s)\n",path,ppi->versionstring); @@ -271,7 +273,7 @@ int plugin_url_candispatch(WS_CONNINFO *pwsc) { _plugin_readlock(); ppi = _plugin_list.next; while(ppi) { - if(ppi->type == PLUGIN_OUTPUT) { + if(ppi->type & PLUGIN_OUTPUT) { if(!regexec(&ppi->regex,pwsc->uri,0,NULL,0)) { /* we have a winner */ _plugin_unlock(); @@ -298,14 +300,14 @@ void plugin_url_handle(WS_CONNINFO *pwsc) { _plugin_readlock(); ppi = _plugin_list.next; while(ppi) { - if(ppi->type == PLUGIN_OUTPUT) { + if(ppi->type & PLUGIN_OUTPUT) { if(!regexec(&ppi->regex,pwsc->uri,0,NULL,0)) { /* we have a winner */ DPRINTF(E_DBG,L_PLUG,"Dispatching %s to %s\n", pwsc->uri, ppi->versionstring); /* so functions must be a tag_plugin_output_fn */ - disp_fn=(((PLUGIN_OUTPUT_FN*)ppi->functions)->handler); + disp_fn=(ppi->output_fns)->handler; disp_fn(pwsc); _plugin_unlock(); return; @@ -382,14 +384,14 @@ int plugin_auth_handle(WS_CONNINFO *pwsc, char *username, char *pw) { _plugin_readlock(); ppi = _plugin_list.next; while(ppi) { - if(ppi->type == PLUGIN_OUTPUT) { + if(ppi->type & PLUGIN_OUTPUT) { if(!regexec(&ppi->regex,pwsc->uri,0,NULL,0)) { /* we have a winner */ DPRINTF(E_DBG,L_PLUG,"Dispatching %s to %s\n", pwsc->uri, ppi->versionstring); /* so functions must be a tag_plugin_output_fn */ - auth_fn=(((PLUGIN_OUTPUT_FN*)ppi->functions)->auth); + auth_fn=(ppi->output_fns)->auth; if(auth_fn) { result=auth_fn(pwsc,username,pw); _plugin_unlock(); @@ -409,6 +411,30 @@ int plugin_auth_handle(WS_CONNINFO *pwsc, char *username, char *pw) { return FALSE; } +/** + * send an event to a plugin... this can be a connection, disconnection, etc. + */ +void plugin_event_dispatch(int event_id, int intval, void *vp, int len) { + PLUGIN_ENTRY *ppi; + + _plugin_readlock(); + ppi = _plugin_list.next; + while(ppi) { + if(ppi->type & PLUGIN_EVENT) { + DPRINTF(E_DBG,L_PLUG,"Dispatching event %d to %s\n", + event_id,ppi->versionstring); + + if((ppi->event_fns) && (ppi->event_fns->handler)) { + ppi->event_fns->handler(event_id, intval, vp, len); + } + } + ppi=ppi->next; + } + _plugin_unlock(); +} + + + /* plugin wrappers for utility functions & stuff * diff --git a/src/plugin.h b/src/plugin.h index 9f77af2d..f277b3de 100644 --- a/src/plugin.h +++ b/src/plugin.h @@ -24,6 +24,7 @@ #include "webserver.h" #include "xml-rpc.h" +#include "db-generic.h" extern int plugin_init(void); extern int plugin_load(char **pe, char *path); @@ -34,18 +35,29 @@ extern int plugin_url_candispatch(WS_CONNINFO *pwsc); extern void plugin_url_handle(WS_CONNINFO *pwsc); extern int plugin_auth_handle(WS_CONNINFO *pwsc, char *username, char *pw); extern int plugin_rend_register(char *name, int port, char *iface); +extern void plugin_event_dispatch(int event_id, int intval, void *vp, int len); + #define PLUGIN_E_SUCCESS 0 #define PLUGIN_E_NOLOAD 1 #define PLUGIN_E_BADFUNCS 2 -#define PLUGIN_OUTPUT 0 -#define PLUGIN_SCANNER 1 -#define PLUGIN_DATABASE 2 -#define PLUGIN_OTHER 3 +#define PLUGIN_OUTPUT 1 +#define PLUGIN_SCANNER 2 +#define PLUGIN_DATABASE 4 +#define PLUGIN_EVENT 8 -#define PLUGIN_VERSION 1 +#define PLUGIN_EVENT_LOG 0 +#define PLUGIN_EVENT_FULLSCAN_START 1 +#define PLUGIN_EVENT_FULLSCAN_END 2 +#define PLUGIN_EVENT_STARTING 3 +#define PLUGIN_EVENT_SHUTDOWN 4 +#define PLUGIN_EVENT_STARTSTREAM 5 +#define PLUGIN_EVENT_ABORTSTREAM 6 +#define PLUGIN_EVENT_ENDSTREAM 7 + +#define PLUGIN_VERSION 1 typedef struct tag_plugin_output_fn { @@ -53,6 +65,10 @@ typedef struct tag_plugin_output_fn { int(*auth)(WS_CONNINFO *pwsc, char *username, char *pw); } PLUGIN_OUTPUT_FN; +typedef struct tag_plugin_event_fn { + void(*handler)(int event_id, int intval, void *vp, int len); +} PLUGIN_EVENT_FN; + /* version 1 plugin info */ typedef struct tag_plugin_rend_info { char *type; @@ -64,7 +80,8 @@ typedef struct tag_plugin_info { int type; char *server; char *url; /* for output plugins */ - void *handler_functions; + PLUGIN_OUTPUT_FN *output_fns; + PLUGIN_EVENT_FN *event_fns; void *pi; /* exported functions */ PLUGIN_REND_INFO *rend_info; } PLUGIN_INFO; diff --git a/src/plugins/mtd-plugins.h b/src/plugins/mtd-plugins.h index e74c569a..bc352e3e 100644 --- a/src/plugins/mtd-plugins.h +++ b/src/plugins/mtd-plugins.h @@ -5,13 +5,21 @@ #ifndef _MTD_PLUGINS_H_ #define _MTD_PLUGINS_H_ -#define PLUGIN_OUTPUT 0 -#define PLUGIN_SCANNER 1 -#define PLUGIN_DATABASE 2 -#define PLUGIN_OTHER 3 +#define PLUGIN_OUTPUT 1 +#define PLUGIN_SCANNER 2 +#define PLUGIN_DATABASE 4 +#define PLUGIN_EVENT 8 #define PLUGIN_VERSION 1 +#define PLUGIN_EVENT_LOG 0 +#define PLUGIN_EVENT_FULLSCAN_START 1 +#define PLUGIN_EVENT_FULLSCAN_END 2 +#define PLUGIN_EVENT_STARTING 3 +#define PLUGIN_EVENT_SHUTDOWN 4 +#define PLUGIN_EVENT_STARTSTREAM 5 +#define PLUGIN_EVENT_ABORTSTREAM 6 +#define PLUGIN_EVENT_ENDSTREAM 7 typedef void* PARSETREE; @@ -23,6 +31,10 @@ typedef struct tag_plugin_output_fn { int(*auth)(WS_CONNINFO *pwsc, char *username, char *pw); } PLUGIN_OUTPUT_FN; +typedef struct tag_plugin_event_fn { + void(*handler)(int event_id, int intval, void *vp, int len); +} PLUGIN_EVENT_FN; + typedef struct tag_plugin_rend_info { char *type; char *txt; @@ -33,8 +45,9 @@ typedef struct tag_plugin_info { int type; char *server; char *url; /* regex of namespace to handle if OUTPUT type */ - void *handler_functions; - void *fn; /* input functions*/ + PLUGIN_OUTPUT_FN *output_fns; + PLUGIN_EVENT_FN *event_fns; + void *pi; /* exported functions */ PLUGIN_REND_INFO *rend_info; } PLUGIN_INFO; diff --git a/src/plugins/rsp.h b/src/plugins/rsp.h index 4d8975e2..4f244533 100644 --- a/src/plugins/rsp.h +++ b/src/plugins/rsp.h @@ -8,7 +8,7 @@ #define RSP_VERSION "1.0" extern PLUGIN_INFO _pi; -#define infn ((PLUGIN_INPUT_FN *)(_pi.fn)) +#define infn ((PLUGIN_INPUT_FN *)(_pi.pi)) #ifndef TRUE # define TRUE 1 diff --git a/src/plugins/w32-event.c b/src/plugins/w32-event.c new file mode 100644 index 00000000..436572a5 --- /dev/null +++ b/src/plugins/w32-event.c @@ -0,0 +1,65 @@ +/* + * $Id: $ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "compat.h" +#include "mtd-plugins.h" + +/* Forwards */ +PLUGIN_INFO *plugin_info(void); +void plugin_handler(int, int, void *, int); + +#define PIPE_BUFFER_SIZE 4096 + +/* Globals */ +PLUGIN_EVENT_FN _pefn = { plugin_handler }; + +PLUGIN_INFO _pi = { + PLUGIN_VERSION, + PLUGIN_EVENT, + "w32-event/1.0", + NULL, + NULL, + &_pefn, + NULL, + NULL +}; + +typedef struct tag_plugin_msg { + int size; + int event_id; + int intval; + char vp[1]; +} PLUGIN_MSG; + +#define infn ((PLUGIN_INPUT_FN *)(_pi.pi)) + +PLUGIN_INFO *plugin_info(void) { + return &_pi; +} + +void plugin_handler(int event_id, int intval, void *vp, int len) { + int total_len = 3 * sizeof(int) + len + 1; + PLUGIN_MSG *pmsg; + + pmsg = (PLUGIN_MSG*)malloc(total_len); + if(!pmsg) { + infn->log(E_LOG,"Malloc error in w32-event.c/plugin_handler\n"); + return; + } + + memset(pmsg,0,total_len); + pmsg->size = total_len; + pmsg->event_id = event_id; + pmsg->intval = intval; + memcpy(&pmsg->vp,vp,len); + + CallNamedPipe("\\\\.\\pipe\\firefly",NULL,0,pmsg,total_len,NULL,NMPWAIT_NOWAIT); + + free(pmsg); + return; +} diff --git a/win32/mt-daapd.sln b/win32/mt-daapd.sln index 68b97335..654e7cd3 100644 --- a/win32/mt-daapd.sln +++ b/win32/mt-daapd.sln @@ -11,6 +11,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FireflyConfig", "FireflyCon ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "w32-event", "w32-event.vcproj", "{E60F90F1-A1E5-49D8-A565-B990CA4BA860}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug @@ -29,6 +33,10 @@ Global {842826B0-521A-4296-B2B4-5746BF1C91C2}.Debug.Build.0 = Debug|.NET {842826B0-521A-4296-B2B4-5746BF1C91C2}.Release.ActiveCfg = Release|.NET {842826B0-521A-4296-B2B4-5746BF1C91C2}.Release.Build.0 = Release|.NET + {E60F90F1-A1E5-49D8-A565-B990CA4BA860}.Debug.ActiveCfg = Debug|Win32 + {E60F90F1-A1E5-49D8-A565-B990CA4BA860}.Debug.Build.0 = Debug|Win32 + {E60F90F1-A1E5-49D8-A565-B990CA4BA860}.Release.ActiveCfg = Release|Win32 + {E60F90F1-A1E5-49D8-A565-B990CA4BA860}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection diff --git a/win32/w32-event.def b/win32/w32-event.def new file mode 100644 index 00000000..b604ead9 --- /dev/null +++ b/win32/w32-event.def @@ -0,0 +1,4 @@ +LIBRARY w32-event +EXPORTS + plugin_info + diff --git a/win32/w32-event.vcproj b/win32/w32-event.vcproj new file mode 100644 index 00000000..ccc25eee --- /dev/null +++ b/win32/w32-event.vcproj @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +