/ story-4-Plugins.org
story-4-Plugins.org
  1  #+TITLE: Story 4 - Plugins
  2  #+OPTIONS: author:nil date:nil
  3  
  4  Plugins are a collection of code that plugs into the Le'Sec Core library to
  5  perform certain types of functions.  Plugins may be built into the
  6  application that uses the Le'Sec Core library, any other library the
  7  application is linked with, or as a shared object that's loaded
  8  dynamically.
  9  
 10  * Start and stop functions
 11  
 12  By definition, a Le'Sec plugin is nothing more than a start and a stop
 13  function, both taking the exact same argument.
 14  
 15  #+BEGIN_SRC C
 16    LE_STATUS start(LSC_plugin_t *plugin);
 17    LE_STATUS stop(LSC_plugin_t *plugin);
 18  #+END_SRC
 19  
 20  The ~start()~ and ~stop()~ names are only figurative, they could be named
 21  anything anyone wishes.
 22  
 23  ~plugin~ is explained further down.
 24  
 25  For convenience, the function signature types ~LSC_plugin_start_fn~ and
 26  ~LSC_plugin_stop_fn~ should be defined.
 27  
 28  * Plugin invocation and revocation
 29  
 30  Applications will need to get a plugin started (invocation) and stopped
 31  (revocation), for which there should be simple API.
 32  
 33  #+BEGIN_SRC C
 34    LE_STATUS LSC_invoke_plugin(LSC_plugin_start_fn *start, LSC_plugin_t **plugin,
 35                                LSC_env_t *env);
 36    LE_STATUS LSC_revoke_plugin(LSC_plugin_stop_fn *stop, LSC_plugin_t *plugin);
 37  #+END_SRC
 38  
 39  ~LSC_invoke_plugin()~ will create and populate an ~LSC_plugin_t~, pass that to
 40  the ~start()~ function, as well as assign it to ~*plugin~.  The application
 41  must pass that same value to ~LSC_revoke_plugin()~ when done with that
 42  plugin.
 43  
 44  ~LSC_revoke_plugin()~ will pass ~plugin~ to the ~stop()~ function, and then
 45  destroy it.
 46  
 47  * ~LSC_plugin_t~ and manipulating it
 48  
 49  ~LSC_plugin_t~ is most of all a handle type, but it also contains data that's
 50  of interest for the plugin itself, as it will want to:
 51  
 52  1. Have some private data held for its life time.
 53  2. Have acccess to the parent (application) environment it was called
 54     within.
 55  
 56  #+BEGIN_SRC C
 57     LE_STATUS LSC_set_plugin_data(LSC_plugin_t *plugin, void *data);
 58     LE_STATUS LSC_get_plugin_data(LSC_plugin_t *plugin, void **data);
 59     LE_STATUS LSC_get_plugin_parent_environment(LSC_plugin_t *plugin,
 60                                                 LSC_env_t **parent_env);
 61  #+END_SRC
 62  
 63  * Conventions
 64  
 65  An application is free to specify a plugin start and stop function in
 66  whatever manner it wishes.  Le'Sec core offers no enforcement with regards
 67  to names, or how the application gets access to those functions.
 68  
 69  For dynamically loadable plugins, some conventions are still suitable allow
 70  consistency.
 71  
 72  ** Dynamically loadable plugin start and stop function names
 73  
 74  #+BEGIN_SRC C
 75    LSC_EXPORT LE_STATUS LSC_plugin_start(LSC_env_t *env)
 76    {
 77      /* Do stuff */
 78    }
 79  
 80    LSC_EXPORT LE_STATUS LSC_plugin_stop(LSC_env_t *env)
 81    {
 82      /* Do stuff */
 83    }
 84  #+END_SRC
 85  
 86  For convenience, =<lscore/plugin.h>= should declare the functions
 87  ~LSC_plugin_start()~ and ~LSC_plugin_stop()~.
 88  
 89  ** Standard location for plugins
 90  
 91  For convenience, =<lscore/plugin.h>= should define a macro with the standard
 92  location for Le'Sec plugins.
 93  
 94  #+BEGIN_SRC C
 95    #define LSC_PLUGIN_DIR        "/usr/share/LeSec/plugins"
 96  #+END_SRC
 97  
 98  * Examples
 99  
100  ** A dynamically loadable plugin
101  
102  In a dynamically loadable plugin, the source for the start and stop
103  functions would typically look like this: 
104  
105  #+BEGIN_SRC C
106    #include <lscore/plugin.h>
107  
108    LE_STATUS LSC_plugin_start(LSC_env_t *env)
109    {
110      /* Do stuff */
111    }
112  
113    LE_STATUS LSC_plugin_stop(LSC_env_t *env)
114    {
115      /* Do stuff */
116    }
117  #+END_SRC
118  
119  ** An application loading a plugin
120  
121  #+BEGIN_SRC C
122    #include <inttypes.h>
123    #include <dlfcn.h>
124    #include <lscore/plugin.h>
125  
126    #define _(x) #x
127    int main(int argc, const char *argv[])
128    {
129      const char *plugin_name = LSC_PLUGIN_DIR "/foo.so";
130      void *plugin;
131      LSC_plugin_start_fn *start;
132      LSC_plugin_stop_fn *stop;
133      LSC_env_t *env;
134      LSC_plugin_t *plugin;
135      LE_STATUS sts;
136  
137      if ((plugin = dlopen(plugin_name, RTLD_NOW)) != NULL
138          && (start = dlsym(plugin, _(LSC_plugin_start))) != NULL
139          && (stop = dlsym(plugin, _(LSC_plugin_stop))) != NULL
140          && LE_status_is_OK(sts = LSC_new_environment(&env))) {
141        if (!LE_status_is_OK(sts = LE_invoke_plugin(start, &plugin, env)))
142          fprintf(stderr, "Couldn't start %s: %" PRIu32 "\n",
143                  plugin_name, sts);
144        if (!LE_status_is_OK(sts = LSC_revoke_plugin(stop, plugin)))
145          fprintf(stderr, "Couldn't stop %s: %" PRIu32 "\n",
146                  plugin_name, sts);
147      }
148    }
149  #+END_SRC