$Id: plugin,v 2.1 2003/02/08 15:26:44 eric Exp $

Plugin usage
------------

since dchub V0.2.4, dchub can use plugin (compiled shared library). A plugin
acts at the same level as PERL and Python scripts. It can send and receive
events directly to dchub. Here is some main rules to respect to have a
working plugin (a sample of plugin is in the plugin directory).

1) plugin start
---------------

The plugin is a shared library (for a C program, it is compiled with -fPIC), it
does not have a main function (like a C program).

When dchub loads the plugin, a function named '_init' (if it exists) is called.
You can use this function to perform tasks you want but you must NOT call any
dchub functions from this function because the dchub internal plugin structure
is not yet fully initialized. The _init function is automatically called by
the system call. Just after (without any other calls occuring between them),
dchub calls a function named 'plugin_beginning' [prototype:
int plugin_beginning(PLUGIN *)]. This function must exists else the plugin is not
loaded. In this function, you can perform all the initializations you want
(allocate memory, register event) and you can call technically any dchub
functions (any C function not declared as static can technically be called). If
plugin_beginning wants to abort the plugin load, it has to return a non-zero
value. A returned value of 0 means plugin_beginning ends successfully and the
plugin is now ready to be used.

2) register/unregister event
----------------------------

dchub provides 2 functions to register and unregister an event:
void register_dchub_plugin_event(PLUGIN *plug, char *evt_name,  PLUGIN_EVENT_FUNCTION fnc);
and
void unregister_dchub_plugin_event(PLUGIN *plug, char *evt_name, PLUGIN_EVENT_FUNCTION fnc);

They take both the same parameters because it is possible to register
an event with more than one function. The parameter 'plug' is the value you
receive as plugin_beginning parameter (you can save it, it won't change
until the end of the plugin).

The list of known events is in Documentation/Script (part III).

The prototype of the function to call is:
void fnc(const GArray *param);

the GArray must not be freed or modified, it is a read only structure. Inside the GArray,
you have N PLUGIN_PARAM entries (at least 3). A PLUGIN_PARAM is a couple (varname,varvalue)
[both are char *, read-only]. The 3 mandatory varnames are: "event" (the name of the event),
"nickname" (the nickname generating the event), "argc" (the number of optional parameters).
If optional parameter exist, they are named "0", "1", "2",... . Optional parameter values
are always strings (char *, read-only). The number and the meaning of parameter is the same
as script one.

NOTE: if you save the value of PLUGIN, you can register/unregister events at any time.

3) plugin stop
--------------

The plugin can be stopped at any time but the only case you will probably
encounter is the end of dchub. Before unloading the plugin, dchub calls a
function named 'plugin_end' [prototype: void plugin_end(PLUGIN *)]. This function
is not mandatory but you should probably have one to free the memory you use
and cleanly leave your plugin. dchub internal plugin structure is still fully
available at this step. If you have registered events, you also may want to
unregister them here (if you don't do this, dchub will unregister them
automatically).

Just after this function, dchub internal plugin structure for your plugin is
deleted and the plugin is unloaded. During the unloading stage, the system
calls a function named _exit (if it exists), you may want to use it to undo what
you have done in the _init function but remember you must NOT call any dchub
functions from this function.

4) plugin pluging plugin
------------------------

Yes, it is technically possible, a plugin can load a plugin (using dchub's
plugin_start function) or any other shared library (using dlopen) but remember
that a loaded library belongs to the process, not to the plugin which had loaded
it. To be more clear, when you leave your plugin, you must unload any plugin
you have loaded else it will keep running.

