/[weechat]/weechat/src/plugins/plugins.c
ViewVC logotype

Diff of /weechat/src/plugins/plugins.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.24 by flashcode, Sat Sep 3 12:37:21 2005 UTC revision 1.25 by flashcode, Sat Oct 15 12:34:21 2005 UTC
# Line 17  Line 17 
17   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */   */
19    
20  /* plugins.c: manages WeeChat plugins (Perl and/or Python and/or Ruby) */  /* plugins.c: manages WeeChat plugins (dynamic C libraries) */
21    
22    
23  #ifdef HAVE_CONFIG_H  #ifdef HAVE_CONFIG_H
24  #include "config.h"  #include "config.h"
25  #endif  #endif
26    
27    #include <errno.h>
28  #include <stdlib.h>  #include <stdlib.h>
29  #include <unistd.h>  #include <unistd.h>
30    #include <stdarg.h>
31  #include <string.h>  #include <string.h>
32  #include <sys/types.h>  #include <sys/types.h>
33  #include <sys/stat.h>  #include <sys/stat.h>
34  #include <dirent.h>  #include <dirent.h>
35    #include <dlfcn.h>
36  #include "../common/weechat.h"  #include "../common/weechat.h"
37    #include "weechat-plugin.h"
38  #include "plugins.h"  #include "plugins.h"
39    #include "../common/command.h"
40    #include "../common/weeconfig.h"
41  #include "../irc/irc.h"  #include "../irc/irc.h"
42  #include "../gui/gui.h"  #include "../gui/gui.h"
43    
 #ifdef PLUGIN_PERL  
 #include "perl/wee-perl.h"  
 #endif  
   
 #ifdef PLUGIN_PYTHON  
 #include "python/wee-python.h"  
 #endif  
   
 #ifdef PLUGIN_RUBY  
 #include "ruby/wee-ruby.h"  
 #endif  
44    
45    t_weechat_plugin *weechat_plugins = NULL;
46    t_weechat_plugin *last_weechat_plugin = NULL;
47    
 char *plugin_name[3] = { "Perl", "Python", "Ruby" };  
48    
49  t_plugin_handler *plugin_msg_handlers = NULL;  /*
50  t_plugin_handler *last_plugin_msg_handler = NULL;   * plugin_find_buffer: find a buffer for text display or command execution
51     */
 t_plugin_handler *plugin_cmd_handlers = NULL;  
 t_plugin_handler *last_plugin_cmd_handler = NULL;  
52    
53    t_gui_buffer *
54    plugin_find_buffer (char *server, char *channel)
55    {
56        t_irc_server *ptr_server;
57        t_irc_channel *ptr_channel;
58        t_gui_buffer *ptr_buffer;
59        
60        ptr_server = NULL;
61        ptr_channel = NULL;
62        ptr_buffer = NULL;
63        
64        if (server && server[0])
65        {
66            ptr_server = server_search (server);
67            if (!ptr_server)
68                return NULL;
69        }
70        else
71        {
72            ptr_server = SERVER(gui_current_window->buffer);
73            if (!ptr_server)
74                ptr_server = SERVER(gui_buffers);
75        }
76        
77        if (channel && channel[0])
78        {
79            if (ptr_server)
80            {
81                ptr_channel = channel_search (ptr_server, channel);
82                if (ptr_channel)
83                    ptr_buffer = ptr_channel->buffer;
84            }
85        }
86        else
87        {
88            if (!channel)
89            {
90                ptr_buffer = gui_current_window->buffer;
91                if (ptr_buffer->dcc)
92                    ptr_buffer = gui_buffers;
93            }
94            else
95            {
96                if (ptr_server)
97                    ptr_buffer = ptr_server->buffer;
98            }
99        }
100        
101        if (!ptr_buffer)
102            return NULL;
103        
104        return (ptr_buffer->dcc) ? NULL : ptr_buffer;
105    }
106    
107  /*  /*
108   * plugin_auto_load: auto-load all scripts in a directory   * plugin_exec_on_files: find files in a directory and execute a
109     *                       function on each file
110   */   */
111    
112  void  void
113  plugin_auto_load (int plugin_type, char *directory)  plugin_exec_on_files (t_weechat_plugin *plugin, char *directory,
114                          int (*callback)(t_weechat_plugin *, char *))
115  {  {
116      int dir_length;      char complete_filename[1024];
     char *dir_name, *current_dir;  
117      DIR *dir;      DIR *dir;
118      struct dirent *entry;      struct dirent *entry;
119      struct stat statbuf;      struct stat statbuf;
120            
121      /* build directory, adding WeeChat home */      dir = opendir (directory);
122      dir_length = strlen (weechat_home) + strlen (directory) + 2;      if (dir)
123      dir_name =      {
124          (char *) malloc (dir_length * sizeof (char));          while ((entry = readdir (dir)))
125      snprintf (dir_name, dir_length, "%s%s%s", weechat_home, DIR_SEPARATOR, directory);          {
126                snprintf (complete_filename, sizeof (complete_filename) - 1,
127                          "%s/%s", directory, entry->d_name);
128                lstat (complete_filename, &statbuf);
129                if (!S_ISDIR(statbuf.st_mode))
130                {
131                    (int) (*callback) (plugin, complete_filename);
132                }
133            }
134            closedir (dir);
135        }
136    }
137    
138    /*
139     * plugin_search: search a plugin by name
140     */
141    
142    t_weechat_plugin *
143    plugin_search (char *name)
144    {
145        t_weechat_plugin *ptr_plugin;
146            
147      /* save working directory */      for (ptr_plugin = weechat_plugins; ptr_plugin;
148      current_dir = (char *) malloc (1024 * sizeof (char));           ptr_plugin = ptr_plugin->next_plugin)
     if (!getcwd (current_dir, 1024 - 1))  
149      {      {
150          free (current_dir);          if (ascii_strcasecmp (ptr_plugin->name, name) == 0)
151          current_dir = NULL;              return ptr_plugin;
152      }      }
153            
154      /* browse autoload directory */      /* plugin not found */
155      dir = opendir (dir_name);      return NULL;
156      chdir (dir_name);  }
157      if (dir)  
158    /*
159     * plugin_cmd_handler_search: search a plugin command handler
160     *                            return: pointer to handler, NULL if not found
161     */
162    
163    t_plugin_cmd_handler *
164    plugin_cmd_handler_search (char *command)
165    {
166        t_weechat_plugin *ptr_plugin;
167        t_plugin_cmd_handler *ptr_plugin_cmd_handler;
168        
169        for (ptr_plugin = weechat_plugins; ptr_plugin;
170             ptr_plugin = ptr_plugin->next_plugin)
171      {      {
172          while ((entry = readdir (dir)))          for (ptr_plugin_cmd_handler = ptr_plugin->cmd_handlers;
173                 ptr_plugin_cmd_handler;
174                 ptr_plugin_cmd_handler = ptr_plugin_cmd_handler->next_handler)
175          {          {
176              lstat (entry->d_name, &statbuf);              if (ascii_strcasecmp (ptr_plugin_cmd_handler->command, command) == 0)
177              if (! S_ISDIR(statbuf.st_mode))                  return ptr_plugin_cmd_handler;
178            }
179        }
180        
181        /* command handler not found */
182        return NULL;
183    }
184    
185    /*
186     * plugin_msg_handler_add: add a message handler
187     *                         arguments:
188     *                           1. the plugin pointer
189     *                           2. the IRC command
190     *                           3. the handler function
191     *                           4. handler args: a string given to
192     *                              handler when called (used by scripts)
193     *                           5. handler pointer: a pointer given to
194     *                              handler when called (used by scripts)
195     */
196    
197    t_plugin_msg_handler *
198    plugin_msg_handler_add (t_weechat_plugin *plugin, char *irc_command,
199                            t_plugin_handler_func *handler_func,
200                            char *handler_args, void *handler_pointer)
201    {
202        t_plugin_msg_handler *new_plugin_msg_handler;
203        
204        new_plugin_msg_handler = (t_plugin_msg_handler *)malloc (sizeof (t_plugin_msg_handler));
205        if (new_plugin_msg_handler)
206        {
207            new_plugin_msg_handler->irc_command = strdup (irc_command);
208            new_plugin_msg_handler->msg_handler = handler_func;
209            new_plugin_msg_handler->msg_handler_args = (handler_args) ? strdup (handler_args) : NULL;
210            new_plugin_msg_handler->msg_handler_pointer = handler_pointer;
211            new_plugin_msg_handler->running = 0;
212            
213            /* add new handler to list */
214            new_plugin_msg_handler->prev_handler = plugin->last_msg_handler;
215            new_plugin_msg_handler->next_handler = NULL;
216            if (plugin->msg_handlers)
217                (plugin->last_msg_handler)->next_handler = new_plugin_msg_handler;
218            else
219                plugin->msg_handlers = new_plugin_msg_handler;
220            plugin->last_msg_handler = new_plugin_msg_handler;
221        }
222        else
223        {
224            irc_display_prefix (NULL, PREFIX_ERROR);
225            gui_printf (NULL,
226                        _("%s plugin %s: unable to add handler for IRC command \"%s\" (not enough memory)\n"),
227                        WEECHAT_ERROR, plugin->name, irc_command);
228            return NULL;
229        }
230        return new_plugin_msg_handler;
231    }
232    
233    /*
234     * plugin_cmd_handler_add: add a command handler
235     *                         arguments:
236     *                           1. the plugin pointer
237     *                           2. the WeeChat command
238     *                           3. command description (for /help)
239     *                           4. command arguments (for /help)
240     *                           5. command args description (for /help)
241     *                           6. the handler function
242     *                           7. handler args: a string given to
243     *                              handler when called (used by scripts)
244     *                           8. handler pointer: a pointer given to
245     *                              handler when called (used by scripts)
246     */
247    
248    t_plugin_cmd_handler *
249    plugin_cmd_handler_add (t_weechat_plugin *plugin, char *command,
250                            char *description, char *arguments,
251                            char *arguments_description,
252                            t_plugin_handler_func *handler_func,
253                            char *handler_args, void *handler_pointer)
254    {
255        t_plugin_cmd_handler *new_plugin_cmd_handler;
256        
257        if (plugin_cmd_handler_search (command))
258        {
259            irc_display_prefix (NULL, PREFIX_ERROR);
260            gui_printf (NULL,
261                        _("%s plugin %s: unable to add handler for \"%s\" command "
262                          "(already exists)\n"),
263                        WEECHAT_ERROR, plugin->name, command);
264            return NULL;
265        }
266            
267        new_plugin_cmd_handler = (t_plugin_cmd_handler *)malloc (sizeof (t_plugin_cmd_handler));
268        if (new_plugin_cmd_handler)
269        {
270            new_plugin_cmd_handler->command = strdup (command);
271            new_plugin_cmd_handler->description = (description) ? strdup (description) : NULL;
272            new_plugin_cmd_handler->arguments = (arguments) ? strdup (arguments) : NULL;
273            new_plugin_cmd_handler->arguments_description = (arguments_description) ? strdup (arguments_description) : NULL;
274            new_plugin_cmd_handler->cmd_handler = handler_func;
275            new_plugin_cmd_handler->cmd_handler_args = (handler_args) ? strdup (handler_args) : NULL;
276            new_plugin_cmd_handler->cmd_handler_pointer = handler_pointer;
277            new_plugin_cmd_handler->running = 0;
278            
279            /* add new handler to list */
280            new_plugin_cmd_handler->prev_handler = plugin->last_cmd_handler;
281            new_plugin_cmd_handler->next_handler = NULL;
282            if (plugin->cmd_handlers)
283                (plugin->last_cmd_handler)->next_handler = new_plugin_cmd_handler;
284            else
285                plugin->cmd_handlers = new_plugin_cmd_handler;
286            plugin->last_cmd_handler = new_plugin_cmd_handler;
287            
288            /* add command to WeeChat commands list */
289            if (!weelist_search (index_commands, command))
290                weelist_add (&index_commands, &last_index_command, command);
291        }
292        else
293        {
294            irc_display_prefix (NULL, PREFIX_ERROR);
295            gui_printf (NULL,
296                        _("%s plugin %s: unable to add handler for \"%s\" command (not enough memory)\n"),
297                        WEECHAT_ERROR, plugin->name, command);
298            return NULL;
299        }
300        return new_plugin_cmd_handler;
301    }
302    
303    /*
304     * plugin_msg_handler_exec: execute a message handler
305     *                          return: number of handlers executed (0 means no handler found)
306     */
307    
308    int
309    plugin_msg_handler_exec (char *server, char *irc_command, char *irc_message)
310    {
311        t_weechat_plugin *ptr_plugin;
312        t_plugin_msg_handler *ptr_plugin_msg_handler;
313        int count;
314        
315        count = 0;
316        for (ptr_plugin = weechat_plugins; ptr_plugin;
317             ptr_plugin = ptr_plugin->next_plugin)
318        {
319            for (ptr_plugin_msg_handler = ptr_plugin->msg_handlers;
320                 ptr_plugin_msg_handler;
321                 ptr_plugin_msg_handler = ptr_plugin_msg_handler->next_handler)
322            {
323                if (ascii_strcasecmp (ptr_plugin_msg_handler->irc_command, irc_command) == 0)
324              {              {
325                  wee_log_printf (_("Auto-loading %s script: %s%s%s\n"),                  if (ptr_plugin_msg_handler->running == 0)
326                                  plugin_name[plugin_type],                  {
327                                  dir_name, DIR_SEPARATOR, entry->d_name);                      ptr_plugin_msg_handler->running = 1;
328                  plugin_load (plugin_type, entry->d_name);                      if ((int) (ptr_plugin_msg_handler->msg_handler) (ptr_plugin,
329                                                                         server,
330                                                                         irc_command,
331                                                                         irc_message,
332                                                                         ptr_plugin_msg_handler->msg_handler_args,
333                                                                         ptr_plugin_msg_handler->msg_handler_pointer))
334                            count++;
335                        ptr_plugin_msg_handler->running = 0;
336                    }
337              }              }
338          }          }
         closedir (dir);  
339      }      }
340            
341      /* restore working directory */      return count;
342      if (current_dir)  }
343    
344    /*
345     * plugin_cmd_handler_exec: execute a command handler
346     *                          return: 1 if handler executed, 0 if no handler found
347     */
348    
349    int
350    plugin_cmd_handler_exec (char *server, char *command, char *arguments)
351    {
352        t_weechat_plugin *ptr_plugin;
353        t_plugin_cmd_handler *ptr_plugin_cmd_handler;
354        int return_code;
355        
356        for (ptr_plugin = weechat_plugins; ptr_plugin;
357             ptr_plugin = ptr_plugin->next_plugin)
358      {      {
359          chdir (current_dir);          for (ptr_plugin_cmd_handler = ptr_plugin->cmd_handlers;
360          free (current_dir);               ptr_plugin_cmd_handler;
361                 ptr_plugin_cmd_handler = ptr_plugin_cmd_handler->next_handler)
362            {
363                if (ascii_strcasecmp (ptr_plugin_cmd_handler->command, command) == 0)
364                {
365                    if (ptr_plugin_cmd_handler->running == 0)
366                    {
367                        ptr_plugin_cmd_handler->running = 1;
368                        return_code = (int) (ptr_plugin_cmd_handler->cmd_handler) (ptr_plugin,
369                                                                                   server,
370                                                                                   command,
371                                                                                   arguments,
372                                                                                   ptr_plugin_cmd_handler->cmd_handler_args,
373                                                                                   ptr_plugin_cmd_handler->cmd_handler_pointer);
374                        ptr_plugin_cmd_handler->running = 0;
375                        return (return_code) ? 1 : 0;
376                    }
377                }
378            }
379      }      }
380      free (dir_name);      
381        return 0;
382  }  }
383    
384  /*  /*
385   * plugin_init: initialize all plugins   * plugin_msg_handler_remove: remove a message handler for a plugin
386   */   */
387    
388  void  void
389  plugin_init ()  plugin_msg_handler_remove (t_weechat_plugin *plugin,
390                               t_plugin_msg_handler *plugin_msg_handler)
391  {  {
392  #ifdef PLUGIN_PERL      t_plugin_msg_handler *new_plugin_msg_handlers;
     wee_perl_init();  
     plugin_auto_load (PLUGIN_TYPE_PERL, "perl/autoload");  
 #endif  
393            
394  #ifdef PLUGIN_PYTHON      /* remove handler from list */
395      wee_python_init();      if (plugin->last_msg_handler == plugin_msg_handler)
396      plugin_auto_load (PLUGIN_TYPE_PYTHON, "python/autoload");          plugin->last_msg_handler = plugin_msg_handler->prev_handler;
397  #endif      if (plugin_msg_handler->prev_handler)
398        {
399            (plugin_msg_handler->prev_handler)->next_handler = plugin_msg_handler->next_handler;
400            new_plugin_msg_handlers = plugin->msg_handlers;
401        }
402        else
403            new_plugin_msg_handlers = plugin_msg_handler->next_handler;
404        
405        if (plugin_msg_handler->next_handler)
406            (plugin_msg_handler->next_handler)->prev_handler = plugin_msg_handler->prev_handler;
407    
408  #ifdef PLUGIN_RUBY      /* free data */
409      wee_ruby_init();      if (plugin_msg_handler->irc_command)
410      plugin_auto_load (PLUGIN_TYPE_RUBY, "ruby/autoload");          free (plugin_msg_handler->irc_command);
411  #endif      if (plugin_msg_handler->msg_handler_args)
412            free (plugin_msg_handler->msg_handler_args);
413        plugin->msg_handlers = new_plugin_msg_handlers;
414  }  }
415    
416  /*  /*
417   * plugin_load: load a plugin   * plugin_cmd_handler_remove: remove a command handler for a plugin
418   */   */
419    
420  void  void
421  plugin_load (int plugin_type, char *filename)  plugin_cmd_handler_remove (t_weechat_plugin *plugin,
422                               t_plugin_cmd_handler *plugin_cmd_handler)
423  {  {
424  #ifdef PLUGINS      t_plugin_cmd_handler *new_plugin_cmd_handlers;
425      switch (plugin_type)      
426        /* remove handler from list */
427        if (plugin->last_cmd_handler == plugin_cmd_handler)
428            plugin->last_cmd_handler = plugin_cmd_handler->prev_handler;
429        if (plugin_cmd_handler->prev_handler)
430      {      {
431          case PLUGIN_TYPE_PERL:          (plugin_cmd_handler->prev_handler)->next_handler = plugin_cmd_handler->next_handler;
432  #ifdef PLUGIN_PERL          new_plugin_cmd_handlers = plugin->cmd_handlers;
             wee_perl_load (filename);  
 #endif  
             break;  
         case PLUGIN_TYPE_PYTHON:  
 #ifdef PLUGIN_PYTHON  
             wee_python_load (filename);  
 #endif  
             break;  
         case PLUGIN_TYPE_RUBY:  
 #ifdef PLUGIN_RUBY  
             wee_ruby_load (filename);  
 #endif  
             break;  
433      }      }
434  #else      else
435      /* make gcc happy */          new_plugin_cmd_handlers = plugin_cmd_handler->next_handler;
436      (void) plugin_type;      
437      (void) filename;      if (plugin_cmd_handler->next_handler)
438  #endif /* PLUGINS */          (plugin_cmd_handler->next_handler)->prev_handler = plugin_cmd_handler->prev_handler;
439        
440        /* remove command from WeeChat command list */
441        weelist_remove (&index_commands, &last_index_command,
442                        weelist_search (index_commands, plugin_cmd_handler->command));
443        
444        /* free data */
445        if (plugin_cmd_handler->command)
446            free (plugin_cmd_handler->command);
447        if (plugin_cmd_handler->description)
448            free (plugin_cmd_handler->description);
449        if (plugin_cmd_handler->arguments)
450            free (plugin_cmd_handler->arguments);
451        if (plugin_cmd_handler->arguments_description)
452            free (plugin_cmd_handler->arguments_description);
453        if (plugin_cmd_handler->cmd_handler_args)
454            free (plugin_cmd_handler->cmd_handler_args);
455        plugin->cmd_handlers = new_plugin_cmd_handlers;
456    }
457    
458    /*
459     * plugin_msg_handler_remove_all: remove all message handlers for a plugin
460     */
461    
462    void
463    plugin_msg_handler_remove_all (t_weechat_plugin *plugin)
464    {
465        while (plugin->msg_handlers)
466            plugin_msg_handler_remove (plugin, plugin->msg_handlers);
467  }  }
468    
469  /*  /*
470   * plugin_handler_search: look for message/command handler   * plugin_cmd_handler_remove_all: remove all command handlers for a plugin
471   */   */
472    
473  t_plugin_handler *  void
474  plugin_handler_search (t_plugin_handler *plugin_handlers, char *name)  plugin_cmd_handler_remove_all (t_weechat_plugin *plugin)
475  {  {
476      t_plugin_handler *ptr_plugin_handler;      while (plugin->cmd_handlers)
477            plugin_cmd_handler_remove (plugin, plugin->cmd_handlers);
478    }
479    
480    /*
481     * plugin_search_full_name: search the full name of a file with a part of name
482     *                          and look in WeeChat user's dir, then WeeChat global lib dir
483     */
484    
485    char *
486    plugin_search_full_name (char *filename)
487    {
488        char *name_with_ext, *final_name;
489        int length;
490        struct stat st;
491        
492        /* filename is already a full path */
493        if (strchr (filename, '/') || strchr (filename, '\\'))
494            return strdup (filename);
495        
496        length = strlen (filename) + 16;
497        if (cfg_plugins_extension && cfg_plugins_extension[0])
498            length += strlen (cfg_plugins_extension);
499        name_with_ext = (char *)malloc (length);
500        if (!name_with_ext)
501            return strdup (filename);
502        name_with_ext[0] = '\0';
503        if (ascii_strncasecmp (filename, "lib", 3) != 0)
504            strcat (name_with_ext, "lib");
505        strcat (name_with_ext, filename);
506        if (!strchr (filename, '.')
507            && cfg_plugins_extension && cfg_plugins_extension[0])
508            strcat (name_with_ext, cfg_plugins_extension);
509        
510        /* try WeeChat user's dir */
511        length = strlen (weechat_home) + strlen (name_with_ext) + 16;
512        final_name = (char *)malloc (length);
513        if (!final_name)
514        {
515            free (name_with_ext);
516            return strdup (filename);
517        }
518        snprintf (final_name, length,
519                  "%s/plugins/%s", weechat_home, name_with_ext);
520        if ((stat (final_name, &st) == 0) && (st.st_size > 0))
521        {
522            free (name_with_ext);
523            return final_name;
524        }
525        free (final_name);
526            
527      for (ptr_plugin_handler = plugin_handlers; ptr_plugin_handler;      /* try WeeChat global lib dir */
528           ptr_plugin_handler = ptr_plugin_handler->next_handler)      length = strlen (WEECHAT_LIBDIR) + strlen (name_with_ext) + 16;
529        final_name = (char *)malloc (length);
530        if (!final_name)
531      {      {
532          /* handler found */          free (name_with_ext);
533          if (ascii_strcasecmp (ptr_plugin_handler->name, name) == 0)          return strdup (filename);
             return ptr_plugin_handler;  
534      }      }
535      /* handler not found */      snprintf (final_name, length,
536      return NULL;                "%s/plugins/%s", WEECHAT_LIBDIR, name_with_ext);
537        if ((stat (final_name, &st) == 0) && (st.st_size > 0))
538        {
539            free (name_with_ext);
540            return final_name;
541        }
542        free (final_name);
543    
544        return name_with_ext;
545  }  }
546    
547  /*  /*
548   * plugin_handler_add: add a message/command handler   * plugin_load: load a WeeChat plugin (a dynamic library)
549     *              return: pointer to new WeeChat plugin, NULL if error
550   */   */
551    
552  void  t_weechat_plugin *
553  plugin_handler_add (t_plugin_handler **plugin_handlers,  plugin_load (char *filename)
                     t_plugin_handler **last_plugin_handler,  
                     int plugin_type, char *name, char *function)  
554  {  {
555      t_plugin_handler *new_plugin_handler;      char *full_name;
556        void *handle;
557        char *name, *description, *version;
558        t_weechat_init_func *init_func;
559        t_weechat_plugin *new_plugin;
560        
561        if (!filename)
562            return NULL;
563        
564        full_name = plugin_search_full_name (filename);
565        
566        if (!full_name)
567            return NULL;
568        
569        handle = dlopen (full_name, RTLD_GLOBAL | RTLD_NOW);
570        if (!handle)
571        {
572            irc_display_prefix (NULL, PREFIX_ERROR);
573            gui_printf (NULL, _("%s unable to load plugin \"%s\": %s\n"),
574                        WEECHAT_ERROR, full_name, dlerror());
575            free (full_name);
576            return NULL;
577        }
578        /* look for plugin name */
579        name = dlsym (handle, "plugin_name");
580        if (!name)
581        {
582            dlclose (handle);
583            irc_display_prefix (NULL, PREFIX_ERROR);
584            gui_printf (NULL, _("%s symbol \"plugin_name\" not found in plugin \"%s\", failed to load\n"),
585                        WEECHAT_ERROR, full_name);
586            free (full_name);
587            return NULL;
588        }
589        /* check for plugin with same name */
590        if (plugin_search (name))
591        {
592            dlclose (handle);
593            irc_display_prefix (NULL, PREFIX_ERROR);
594            gui_printf (NULL,
595                        _("%s unable to load plugin \"%s\": a plugin with "
596                          "same name already exists\n"),
597                        WEECHAT_ERROR, full_name);
598            free (full_name);
599            return NULL;
600        }
601        /* look for plugin description */
602        description = dlsym (handle, "plugin_description");
603        if (!description)
604        {
605            dlclose (handle);
606            irc_display_prefix (NULL, PREFIX_ERROR);
607            gui_printf (NULL, _("%s symbol \"plugin_description\" not found in plugin \"%s\", failed to load\n"),
608                        WEECHAT_ERROR, full_name);
609            free (full_name);
610            return NULL;
611        }
612        /* look for plugin version */
613        version = dlsym (handle, "plugin_version");
614        if (!version)
615        {
616            dlclose (handle);
617            irc_display_prefix (NULL, PREFIX_ERROR);
618            gui_printf (NULL, _("%s symbol \"plugin_version\" not found in plugin \"%s\", failed to load\n"),
619                        WEECHAT_ERROR, full_name);
620            free (full_name);
621            return NULL;
622        }
623        /* look for plugin init function */
624        init_func = dlsym (handle, "weechat_plugin_init");
625        if (!init_func)
626        {
627            dlclose (handle);
628            irc_display_prefix (NULL, PREFIX_ERROR);
629            gui_printf (NULL, _("%s function \"weechat_plugin_init\" not found in plugin \"%s\", failed to load\n"),
630                        WEECHAT_ERROR, full_name);
631            free (full_name);
632            return NULL;
633        }
634            
635      new_plugin_handler = (t_plugin_handler *)malloc (sizeof (t_plugin_handler));      /* create new plugin */
636      if (new_plugin_handler)      new_plugin = (t_weechat_plugin *)malloc (sizeof (t_weechat_plugin));
637        if (new_plugin)
638      {      {
639          new_plugin_handler->plugin_type = plugin_type;          /* variables */
640          new_plugin_handler->name = strdup (name);          new_plugin->filename = strdup (full_name);
641          new_plugin_handler->function_name = strdup (function);          new_plugin->handle = handle;
642          new_plugin_handler->running = 0;          new_plugin->name = strdup (name);
643            new_plugin->description = strdup (description);
644            new_plugin->version = strdup (version);
645                    
646          /* add new handler to list */          /* functions */
647          new_plugin_handler->prev_handler = *last_plugin_handler;          new_plugin->mkdir_home = &weechat_plugin_mkdir_home;
648          new_plugin_handler->next_handler = NULL;          new_plugin->exec_on_files = &weechat_plugin_exec_on_files;
649          if (*plugin_handlers)          new_plugin->msg_handler_add = &weechat_plugin_msg_handler_add;
650              (*last_plugin_handler)->next_handler = new_plugin_handler;          new_plugin->msg_handler_remove = &weechat_plugin_msg_handler_remove;
651            new_plugin->msg_handler_remove_all = &weechat_plugin_msg_handler_remove_all;
652            new_plugin->cmd_handler_add = &weechat_plugin_cmd_handler_add;
653            new_plugin->cmd_handler_remove = &weechat_plugin_cmd_handler_remove;
654            new_plugin->cmd_handler_remove_all = &weechat_plugin_cmd_handler_remove_all;
655            new_plugin->printf = &weechat_plugin_printf;
656            new_plugin->printf_server = &weechat_plugin_printf_server;
657            new_plugin->infobar_printf = &weechat_plugin_infobar_printf;
658            new_plugin->exec_command = &weechat_plugin_exec_command;
659            new_plugin->get_info = &weechat_plugin_get_info;
660            new_plugin->get_dcc_info = &weechat_plugin_get_dcc_info;
661            new_plugin->free_dcc_info = &weechat_plugin_free_dcc_info;
662            new_plugin->explode_string = &weechat_explode_string;
663            new_plugin->free_exploded_string = &weechat_free_exploded_string;
664            new_plugin->ascii_strcasecmp = &weechat_ascii_strcasecmp;
665            
666            /* handlers */
667            new_plugin->msg_handlers = NULL;
668            new_plugin->last_msg_handler = NULL;
669            new_plugin->cmd_handlers = NULL;
670            new_plugin->last_cmd_handler = NULL;
671            
672            /* add new plugin to list */
673            new_plugin->prev_plugin = last_weechat_plugin;
674            new_plugin->next_plugin = NULL;
675            if (weechat_plugins)
676                last_weechat_plugin->next_plugin = new_plugin;
677          else          else
678              *plugin_handlers = new_plugin_handler;              weechat_plugins = new_plugin;
679          *last_plugin_handler = new_plugin_handler;          last_weechat_plugin = new_plugin;
680            
681            irc_display_prefix (NULL, PREFIX_PLUGIN);
682            gui_printf (NULL,
683                        _("Initializing plugin \"%s\" %s\n"),
684                        new_plugin->name, new_plugin->version);
685            
686            /* init plugin */
687            if (!((t_weechat_init_func *)init_func) (new_plugin))
688            {
689                irc_display_prefix (NULL, PREFIX_ERROR);
690                gui_printf (NULL,
691                            _("%s unable to initialize plugin \"%s\"\n"),
692                            WEECHAT_ERROR, full_name);
693                plugin_remove (new_plugin);
694                free (full_name);
695                return NULL;
696            }
697      }      }
698      else      else
699      {      {
700          irc_display_prefix (NULL, PREFIX_ERROR);          irc_display_prefix (NULL, PREFIX_ERROR);
701          gui_printf (NULL,          gui_printf (NULL,
702                      _("%s unable to add handler for \"%s\" message (not enough memory)\n"),                      _("%s unable to load plugin \"%s\" (not enough memory)\n"),
703                      WEECHAT_ERROR, name);                      WEECHAT_ERROR, full_name);
704            free (full_name);
705            return NULL;
706      }      }
707        
708        irc_display_prefix (NULL, PREFIX_PLUGIN);
709        gui_printf (NULL,
710                    _("Plugin \"%s\" (%s) loaded.\n"),
711                    name, full_name);
712        
713        free (full_name);
714        
715        return new_plugin;
716  }  }
717    
718  /*  /*
719   * plugin_handler_free: free message/command handler   * plugin_auto_load_file: load a file found by plugin_aut_load,
720     *                        but only it this is really a dynamic library
721     */
722    
723    int plugin_auto_load_file (t_weechat_plugin *plugin, char *filename)
724    {
725        char *pos;
726        
727        /* make gcc happy */
728        (void) plugin;
729        
730        if (cfg_plugins_extension && cfg_plugins_extension[0])
731        {
732            pos = strstr (filename, cfg_plugins_extension);
733            if (pos)
734            {
735                if (ascii_strcasecmp (pos, cfg_plugins_extension) == 0)
736                    plugin_load (filename);
737            }
738        }
739        else
740            plugin_load (filename);
741        return 1;
742    }
743    
744    /*
745     * plugin_auto_load: auto-load WeeChat plugins
746     */
747    
748    void plugin_auto_load ()
749    {
750        char *dir_name;
751        
752        dir_name = (char *)malloc (strlen (WEECHAT_LIBDIR) + 16);
753        if (dir_name)
754        {
755            snprintf (dir_name, strlen (WEECHAT_LIBDIR) + 16,
756                      "%s/plugins", WEECHAT_LIBDIR);
757            plugin_exec_on_files (NULL, dir_name, &plugin_auto_load_file);
758            free (dir_name);
759        }
760    }
761    
762    /*
763     * plugin_remove: remove a WeeChat plugin
764   */   */
765    
766  void  void
767  plugin_handler_free (t_plugin_handler **plugin_handlers,  plugin_remove (t_weechat_plugin *plugin)
                      t_plugin_handler **last_plugin_handler,  
                      t_plugin_handler *ptr_plugin_handler)  
768  {  {
769      t_plugin_handler *new_plugin_handlers;      t_weechat_plugin *new_weechat_plugins;
770            
771      /* remove handler from list */      /* remove handler from list */
772      if (*last_plugin_handler == ptr_plugin_handler)      if (last_weechat_plugin == plugin)
773          *last_plugin_handler = ptr_plugin_handler->prev_handler;          last_weechat_plugin = plugin->prev_plugin;
774      if (ptr_plugin_handler->prev_handler)      if (plugin->prev_plugin)
775      {      {
776          (ptr_plugin_handler->prev_handler)->next_handler = ptr_plugin_handler->next_handler;          (plugin->prev_plugin)->next_plugin = plugin->next_plugin;
777          new_plugin_handlers = *plugin_handlers;          new_weechat_plugins = weechat_plugins;
778      }      }
779      else      else
780          new_plugin_handlers = ptr_plugin_handler->next_handler;          new_weechat_plugins = plugin->next_plugin;
781        
782        if (plugin->next_plugin)
783            (plugin->next_plugin)->prev_plugin = plugin->prev_plugin;
784            
     if (ptr_plugin_handler->next_handler)  
         (ptr_plugin_handler->next_handler)->prev_handler = ptr_plugin_handler->prev_handler;  
   
785      /* free data */      /* free data */
786      free (ptr_plugin_handler->name);      plugin_msg_handler_remove_all (plugin);
787      free (ptr_plugin_handler->function_name);      plugin_cmd_handler_remove_all (plugin);
788      free (ptr_plugin_handler);      if (plugin->filename)
789      *plugin_handlers = new_plugin_handlers;          free (plugin->filename);
790        dlclose (plugin->handle);
791        if (plugin->name)
792            free (plugin->name);
793        if (plugin->description)
794            free (plugin->description);
795        if (plugin->version)
796            free (plugin->version);
797        free (plugin);
798        
799        weechat_plugins = new_weechat_plugins;
800  }  }
801    
802  /*  /*
803   * plugin_handler_free_all: remove all message/command handlers   * plugin_unload: unload a WeeChat plugin
804   */   */
805    
806  void  void
807  plugin_handler_free_all (t_plugin_handler **plugin_handlers,  plugin_unload (t_weechat_plugin *plugin)
                          t_plugin_handler **last_plugin_handler)  
808  {  {
809      while (*plugin_handlers)      t_weechat_end_func *end_func;
810          plugin_handler_free (plugin_handlers, last_plugin_handler,      
811                               *plugin_handlers);      end_func = dlsym (plugin->handle, "weechat_plugin_end");
812        if (end_func)
813            (void) (end_func) (plugin);
814        plugin_remove (plugin);
815  }  }
816    
817  /*  /*
818   * plugin_handler_free_all_type: remove all message/command handlers for one type   * plugin_unload_name: unload a WeeChat plugin by name
819   */   */
820    
821  void  void
822  plugin_handler_free_all_type (t_plugin_handler **plugin_handlers,  plugin_unload_name (char *name)
                               t_plugin_handler **last_plugin_handler,  
                               int plugin_type)  
823  {  {
824      t_plugin_handler *ptr_plugin_handler, *new_plugin_handler;      t_weechat_plugin *ptr_plugin;
825            
826      ptr_plugin_handler = *plugin_handlers;      ptr_plugin = plugin_search (name);
827      while (ptr_plugin_handler)      if (ptr_plugin)
828      {      {
829          if (ptr_plugin_handler->plugin_type == plugin_type)          plugin_unload (ptr_plugin);
830          {          irc_display_prefix (NULL, PREFIX_PLUGIN);
831              new_plugin_handler = ptr_plugin_handler->next_handler;          gui_printf (NULL, _("Plugin \"%s\" unloaded.\n"), name);
832              plugin_handler_free (plugin_handlers, last_plugin_handler,      }
833                                   ptr_plugin_handler);      else
834              ptr_plugin_handler = new_plugin_handler;      {
835          }          irc_display_prefix (NULL, PREFIX_ERROR);
836          else          gui_printf (NULL,
837              ptr_plugin_handler = ptr_plugin_handler->next_handler;                      _("%s plugin \"%s\" not found\n"),
838                        WEECHAT_ERROR, name);
839      }      }
840  }  }
841    
842  /*  /*
843   * plugin_event_msg: IRC message received => call all handlers for this message   * plugin_unload_all: unload all WeeChat plugins
844   */   */
845    
846  void  void
847  plugin_event_msg (char *irc_command, char *server, char *arguments)  plugin_unload_all ()
848  {  {
849  #ifdef PLUGINS      while (weechat_plugins)
850      t_plugin_handler *ptr_plugin_handler;          plugin_unload (weechat_plugins);
851    }
852    
853    /*
854     * plugin_init: init plugin support
855     */
856    
857    void
858    plugin_init ()
859    {
860        char *list_plugins, *pos, *pos2;
861            
862      for (ptr_plugin_handler = plugin_msg_handlers; ptr_plugin_handler;      if (cfg_plugins_autoload && cfg_plugins_autoload[0])
          ptr_plugin_handler = ptr_plugin_handler->next_handler)  
863      {      {
864          if (ascii_strcasecmp (ptr_plugin_handler->name, irc_command) == 0)          if (ascii_strcasecmp (cfg_plugins_autoload, "*") == 0)
865                plugin_auto_load ();
866            else
867          {          {
868  #ifdef PLUGIN_PERL              list_plugins = strdup (cfg_plugins_autoload);
869              if (ptr_plugin_handler->plugin_type == PLUGIN_TYPE_PERL)              if (list_plugins)
870              {              {
871                  if (ptr_plugin_handler->running == 0)                  pos = list_plugins;
872                    while (pos && pos[0])
873                  {                  {
874                      ptr_plugin_handler->running = 1;                      pos2 = strchr (pos, ',');
875                      wee_perl_exec (ptr_plugin_handler->function_name, server, arguments);                      if (pos2)
876                      ptr_plugin_handler->running = 0;                          pos2[0] = '\0';
877                        plugin_load (pos);
878                        if (pos2)
879                            pos = pos2 + 1;
880                        else
881                            pos = NULL;
882                  }                  }
883                    free (list_plugins);
884              }              }
 #endif  
 #ifdef PLUGIN_PYTHON  
             if (ptr_plugin_handler->plugin_type == PLUGIN_TYPE_PYTHON)  
             {  
                 if (ptr_plugin_handler->running == 0)  
                 {  
                     ptr_plugin_handler->running = 1;  
                     wee_python_exec (ptr_plugin_handler->function_name, server, arguments);  
                     ptr_plugin_handler->running = 0;  
                 }  
             }  
 #endif  
 #ifdef PLUGIN_RUBY  
             if (ptr_plugin_handler->plugin_type == PLUGIN_TYPE_RUBY)  
             {  
                 if (ptr_plugin_handler->running == 0)  
                 {  
                     ptr_plugin_handler->running = 1;  
                     wee_ruby_exec (ptr_plugin_handler->function_name, server, arguments);  
                     ptr_plugin_handler->running = 0;  
                 }  
             }  
 #endif  
885          }          }
886      }      }
 #else  
     /* make gcc happy */  
     (void) irc_command;  
     (void) arguments;  
     (void) server;  
 #endif /* PLUGINS */  
887  }  }
888    
889  /*  /*
890   * plugin_exec_command: execute a command handler   * plugin_end: end plugin support
891     */
892    
893    void
894    plugin_end ()
895    {
896        plugin_unload_all ();
897    }
898    
899    /*************************** Public plugin interface **************************/
900    
901    /*
902     * weechat_plugin_mkdir_home: create a directory for script in WeeChat home
903   */   */
904    
905  int  int
906  plugin_exec_command (char *user_command, char *server, char *arguments)  weechat_plugin_mkdir_home (t_weechat_plugin *plugin, char *path)
907  {  {
908  #ifdef PLUGINS      char *dir_name;
909      t_plugin_handler *ptr_plugin_handler;      int dir_length;
910        
911        /* make gcc happy */
912        (void) plugin;
913        
914        if (!path)
915            return 0;
916            
917      for (ptr_plugin_handler = plugin_cmd_handlers; ptr_plugin_handler;      /* build directory, adding WeeChat home */
918           ptr_plugin_handler = ptr_plugin_handler->next_handler)      dir_length = strlen (weechat_home) + strlen (path) + 2;
919        dir_name =
920            (char *) malloc (dir_length * sizeof (char));
921        if (!dir_name)
922            return 0;
923        
924        snprintf (dir_name, dir_length, "%s/%s", weechat_home, path);
925        
926        if (mkdir (dir_name, 0755) < 0)
927      {      {
928          if (ascii_strcasecmp (ptr_plugin_handler->name, user_command) == 0)          if (errno != EEXIST)
929          {          {
930  #ifdef PLUGIN_PERL              free (dir_name);
931              if (ptr_plugin_handler->plugin_type == PLUGIN_TYPE_PERL)              return 0;
             {  
                 if (ptr_plugin_handler->running == 0)  
                 {  
                     ptr_plugin_handler->running = 1;  
                     wee_perl_exec (ptr_plugin_handler->function_name, server, arguments);  
                     ptr_plugin_handler->running = 0;  
                 }  
             }  
 #endif  
 #ifdef PLUGIN_PYTHON  
             if (ptr_plugin_handler->plugin_type == PLUGIN_TYPE_PYTHON)  
             {  
                 if (ptr_plugin_handler->running == 0)  
                 {  
                     ptr_plugin_handler->running = 1;  
                     wee_python_exec (ptr_plugin_handler->function_name, server, arguments);  
                     ptr_plugin_handler->running = 0;  
                 }  
             }  
 #endif  
 #ifdef PLUGIN_RUBY  
             if (ptr_plugin_handler->plugin_type == PLUGIN_TYPE_RUBY)  
             {  
                 if (ptr_plugin_handler->running == 0)  
                 {  
                     ptr_plugin_handler->running = 1;  
                     wee_ruby_exec (ptr_plugin_handler->function_name, server, arguments);  
                     ptr_plugin_handler->running = 0;  
                 }  
             }  
 #endif  
               
             /* command executed */  
             return 1;  
932          }          }
933      }      }
 #else  
     /* make gcc happy */  
     (void) user_command;  
     (void) arguments;  
     (void) server;  
 #endif /* PLUGINS */  
934            
935      /* no command executed */      free (dir_name);
936      return 0;      return 1;
937  }  }
938    
939  /*  /*
940   * plugin_find_buffer: find a buffer for text display or command execution   * weechat_plugin_exec_on_files: find files in a directory and execute a
941     *                               function on each file
942   */   */
943    
944  t_gui_buffer *  void
945  plugin_find_buffer (char *server, char *channel)  weechat_plugin_exec_on_files (t_weechat_plugin *plugin, char *directory,
946                                  int (*callback)(t_weechat_plugin *, char *))
947    {
948        if (directory && callback)
949            plugin_exec_on_files (plugin, directory, callback);
950    }
951    
952    /*
953     * weechat_plugin_msg_handler_add: add a message handler
954     */
955    
956    t_plugin_msg_handler *
957    weechat_plugin_msg_handler_add (t_weechat_plugin *plugin, char *message,
958                                    t_plugin_handler_func *handler_func,
959                                    char *handler_args, void *handler_pointer)
960    {
961        if (plugin && message && handler_func)
962            return plugin_msg_handler_add (plugin, message, handler_func,
963                                           handler_args, handler_pointer);
964        
965        return NULL;
966    }
967    
968    /*
969     * weechat_plugin_msg_handler_remove: remove a WeeChat message handler
970     */
971    
972    void
973    weechat_plugin_msg_handler_remove (t_weechat_plugin *plugin,
974                                       t_plugin_msg_handler *msg_handler)
975    {
976        if (plugin && msg_handler)
977            plugin_msg_handler_remove (plugin, msg_handler);
978    }
979    
980    /*
981     * weechat_plugin_msg_handler_remove_all: remove all WeeChat message handlers
982     */
983    
984    void
985    weechat_plugin_msg_handler_remove_all (t_weechat_plugin *plugin)
986    {
987        if (plugin)
988            plugin_msg_handler_remove_all (plugin);
989    }
990    
991    /*
992     * weechat_plugin_cmd_handler_add: add a command handler
993     */
994    
995    t_plugin_cmd_handler *
996    weechat_plugin_cmd_handler_add (t_weechat_plugin *plugin, char *command,
997                                    char *description, char *arguments,
998                                    char *arguments_description,
999                                    t_plugin_handler_func *handler_func,
1000                                    char *handler_args, void *handler_pointer)
1001    {
1002        if (plugin && command && handler_func)
1003            return plugin_cmd_handler_add (plugin, command, description, arguments,
1004                                           arguments_description,
1005                                           handler_func,
1006                                           handler_args, handler_pointer);
1007        
1008        return NULL;
1009    }
1010    
1011    /*
1012     * weechat_cmd_plugin_handler_remove: remove a WeeChat command handler
1013     */
1014    
1015    void
1016    weechat_plugin_cmd_handler_remove (t_weechat_plugin *plugin,
1017                                       t_plugin_cmd_handler *cmd_handler)
1018    {
1019        if (plugin && cmd_handler)
1020            plugin_cmd_handler_remove (plugin, cmd_handler);
1021    }
1022    
1023    /*
1024     * weechat_plugin_cmd_handler_remove_all: remove all WeeChat command handlers
1025     */
1026    
1027    void
1028    weechat_plugin_cmd_handler_remove_all (t_weechat_plugin *plugin)
1029    {
1030        if (plugin)
1031            plugin_cmd_handler_remove_all (plugin);
1032    }
1033    
1034    /*
1035     * weechat_plugin_printf: print a message on a server or channel buffer
1036     */
1037    
1038    void
1039    weechat_plugin_printf (t_weechat_plugin *plugin,
1040                           char *server, char *channel, char *message, ...)
1041  {  {
     t_irc_server *ptr_server;  
     t_irc_channel *ptr_channel;  
1042      t_gui_buffer *ptr_buffer;      t_gui_buffer *ptr_buffer;
1043        va_list argptr;
1044        static char buf[8192];
1045            
1046      ptr_server = NULL;      if (!plugin || !message)
1047      ptr_channel = NULL;          return;
     ptr_buffer = NULL;  
1048            
1049      if (server && server[0])      ptr_buffer = plugin_find_buffer (server, channel);
1050        va_start (argptr, message);
1051        vsnprintf (buf, sizeof (buf) - 1, message, argptr);
1052        va_end (argptr);
1053        irc_display_prefix (ptr_buffer, PREFIX_PLUGIN);
1054        gui_printf (ptr_buffer, "%s\n", buf);
1055    }
1056    
1057    /*
1058     * weechat_plugin_printf_server: print a message on server buffer
1059     */
1060    
1061    void
1062    weechat_plugin_printf_server (t_weechat_plugin *plugin, char *message, ...)
1063    {
1064        va_list argptr;
1065        static char buf[8192];
1066        
1067        if (!plugin || !message)
1068            return;
1069        
1070        va_start (argptr, message);
1071        vsnprintf (buf, sizeof (buf) - 1, message, argptr);
1072        va_end (argptr);
1073        irc_display_prefix (NULL, PREFIX_PLUGIN);
1074        gui_printf (NULL, "%s\n", buf);
1075    }
1076    
1077    /*
1078     * weechat_plugin_infobar_printf: print a message in infobar
1079     */
1080    
1081    void
1082    weechat_plugin_infobar_printf (t_weechat_plugin *plugin, int time_displayed, char *message, ...)
1083    {
1084        va_list argptr;
1085        static char buf[1024];
1086        
1087        if (!plugin || (time_displayed < 0) || !message)
1088            return;
1089        
1090        va_start (argptr, message);
1091        vsnprintf (buf, sizeof (buf) - 1, message, argptr);
1092        va_end (argptr);
1093        gui_infobar_printf (time_displayed, COLOR_WIN_INFOBAR, buf);
1094    }
1095    
1096    /*
1097     * weechat_plugin_exec_command: execute a command (simulate user entry)
1098     */
1099    
1100    void
1101    weechat_plugin_exec_command (t_weechat_plugin *plugin,
1102                                 char *server, char *channel, char *command)
1103    {
1104        t_gui_buffer *ptr_buffer;
1105        
1106        if (!plugin || !command)
1107            return;
1108        
1109        ptr_buffer = plugin_find_buffer (server, channel);
1110        if (ptr_buffer)
1111            user_command (SERVER(ptr_buffer), ptr_buffer, command);
1112    }
1113    
1114    /*
1115     * weechat_plugin_get_info: get info about WeeChat
1116     *                          WARNING: caller should free string returned
1117     *                          by this function after use
1118     */
1119    
1120    char *
1121    weechat_plugin_get_info (t_weechat_plugin *plugin, char *info, char *server, char *channel)
1122    {
1123        t_gui_buffer *ptr_buffer;
1124        
1125        if (!plugin || !info)
1126            return NULL;
1127        
1128        ptr_buffer = plugin_find_buffer (server, channel);
1129        if (!ptr_buffer)
1130            return NULL;
1131        
1132        if (ascii_strcasecmp (info, "version") == 0)
1133      {      {
1134          ptr_server = server_search (server);          return strdup (PACKAGE_STRING);
         if (!ptr_server)  
             return NULL;  
1135      }      }
1136      else      else if (ascii_strcasecmp (info, "nick") == 0)
1137      {      {
1138          ptr_server = SERVER(gui_current_window->buffer);          if (SERVER(ptr_buffer) && (SERVER(ptr_buffer)->is_connected)
1139          if (!ptr_server)              && (SERVER(ptr_buffer)->nick))
1140              ptr_server = SERVER(gui_buffers);              return strdup (SERVER(ptr_buffer)->nick);
1141      }      }
1142            else if (ascii_strcasecmp (info, "channel") == 0)
     if (channel && channel[0])  
1143      {      {
1144          if (ptr_server)          if (BUFFER_IS_CHANNEL(ptr_buffer))
1145          {              return strdup (CHANNEL(gui_current_window->buffer)->name);
             ptr_channel = channel_search (ptr_server, channel);  
             if (ptr_channel)  
                 ptr_buffer = ptr_channel->buffer;  
         }  
1146      }      }
1147      else      else if (ascii_strcasecmp (info, "server") == 0)
1148      {      {
1149          if (!channel)          if (SERVER(ptr_buffer) && (SERVER(ptr_buffer)->is_connected)
1150                && (SERVER(ptr_buffer)->name))
1151                return strdup (SERVER(ptr_buffer)->name);
1152        }
1153        else if (ascii_strcasecmp (info, "away") == 0)
1154        {
1155            if (SERVER(ptr_buffer) && (SERVER(ptr_buffer)->is_connected))
1156          {          {
1157              ptr_buffer = gui_current_window->buffer;              if (SERVER(ptr_buffer)->is_away)
1158              if (ptr_buffer->dcc)                  return strdup ("1");
1159                  ptr_buffer = gui_buffers;              else
1160          }                  return strdup ("0");
         else  
         {  
             if (ptr_server)  
                 ptr_buffer = ptr_server->buffer;  
1161          }          }
1162      }      }
1163        else if (ascii_strcasecmp (info, "weechat_dir") == 0)
1164        {
1165            return strdup (weechat_home);
1166        }
1167        else if (ascii_strcasecmp (info, "weechat_libdir") == 0)
1168        {
1169            return strdup (WEECHAT_LIBDIR);
1170        }
1171        else if (ascii_strcasecmp (info, "weechat_sharedir") == 0)
1172        {
1173            return strdup (WEECHAT_SHAREDIR);
1174        }
1175            
1176      if (!ptr_buffer)      /* info not found */
1177        return NULL;
1178    }
1179    
1180    /*
1181     * weechat_plugin_get_dcc_info: get list of DCC files/chats info
1182     */
1183    
1184    t_plugin_dcc_info *
1185    weechat_plugin_get_dcc_info (t_weechat_plugin *plugin)
1186    {
1187        t_plugin_dcc_info *dcc_info, *last_dcc_info, *new_dcc_info;
1188        t_irc_dcc *ptr_dcc;
1189        
1190        if (!plugin)
1191          return NULL;          return NULL;
1192            
1193      return (ptr_buffer->dcc) ? NULL : ptr_buffer;      if (dcc_list)
1194        {
1195            dcc_info = NULL;
1196            last_dcc_info = NULL;
1197            for (ptr_dcc = dcc_list; ptr_dcc; ptr_dcc = ptr_dcc->next_dcc)
1198            {
1199                new_dcc_info = (t_plugin_dcc_info *)malloc (sizeof (t_plugin_dcc_info));
1200                if (new_dcc_info)
1201                {
1202                    new_dcc_info->server = (ptr_dcc->server) ? strdup (ptr_dcc->server->name) : strdup ("");
1203                    new_dcc_info->channel = (ptr_dcc->channel) ? strdup (ptr_dcc->channel->name) : strdup ("");
1204                    new_dcc_info->type = ptr_dcc->type;
1205                    new_dcc_info->status = ptr_dcc->status;
1206                    new_dcc_info->start_time = ptr_dcc->start_time;
1207                    new_dcc_info->start_transfer = ptr_dcc->start_transfer;
1208                    new_dcc_info->addr = ptr_dcc->addr;
1209                    new_dcc_info->port = ptr_dcc->port;
1210                    new_dcc_info->nick = (ptr_dcc->nick) ? strdup (ptr_dcc->nick) : strdup ("");
1211                    new_dcc_info->filename = (ptr_dcc->filename) ? strdup (ptr_dcc->filename) : strdup ("");
1212                    new_dcc_info->local_filename = (ptr_dcc->local_filename) ? strdup (ptr_dcc->local_filename) : strdup ("");
1213                    new_dcc_info->filename_suffix = ptr_dcc->filename_suffix;
1214                    new_dcc_info->size = ptr_dcc->size;
1215                    new_dcc_info->pos = ptr_dcc->pos;
1216                    new_dcc_info->start_resume = ptr_dcc->start_resume;
1217                    new_dcc_info->bytes_per_sec = ptr_dcc->bytes_per_sec;
1218                    
1219                    new_dcc_info->prev_dcc = last_dcc_info;
1220                    new_dcc_info->next_dcc = NULL;
1221                    if (!dcc_info)
1222                    {
1223                        dcc_info = new_dcc_info;
1224                        last_dcc_info = new_dcc_info;
1225                    }
1226                    else
1227                        last_dcc_info->next_dcc = new_dcc_info;
1228                }
1229            }
1230            
1231            return dcc_info;
1232        }
1233        
1234        return NULL;
1235  }  }
1236    
1237  /*  /*
1238   * plugin_unload: unload all scripts for a plugin type   * weechat_plugin_free_dcc_info: free dcc info struct list
1239   */   */
1240    
1241  void  void
1242  plugin_unload (int plugin_type, char *scriptname)  weechat_plugin_free_dcc_info (t_weechat_plugin *plugin, t_plugin_dcc_info *dcc_info)
1243  {  {
1244      /* make gcc happy */      t_plugin_dcc_info *new_dcc_info;
1245      (void) scriptname;      
1246        if (!plugin || !dcc_info)
1247            return;
1248            
1249  #ifdef PLUGINS      while (dcc_info)
     switch (plugin_type)  
1250      {      {
1251          case PLUGIN_TYPE_PERL:          if (dcc_info->server)
1252  #ifdef PLUGIN_PERL              free (dcc_info->server);
1253              /* unload one Perl script is not allowed */          if (dcc_info->channel)
1254              wee_perl_end ();              free (dcc_info->channel);
1255              wee_perl_init ();          if (dcc_info->nick)
1256  #endif              free (dcc_info->nick);
1257              break;          if (dcc_info->filename)
1258          case PLUGIN_TYPE_PYTHON:              free (dcc_info->filename);
1259  #ifdef PLUGIN_PYTHON          if (dcc_info->local_filename)
1260              wee_python_end ();              free (dcc_info->local_filename);
1261              wee_python_init ();          new_dcc_info = dcc_info->next_dcc;
1262  #endif          free (dcc_info);
1263              break;          dcc_info = new_dcc_info;
         case PLUGIN_TYPE_RUBY:  
 #ifdef PLUGIN_RUBY  
             wee_ruby_end ();  
             wee_ruby_init ();  
 #endif  
             break;  
1264      }      }
1265  #else  }
1266    
1267    /*
1268     * weechat_explode_string: explode a string
1269     */
1270    
1271    char **
1272    weechat_explode_string (t_weechat_plugin *plugin, char *string,
1273                            char *separators, int num_items_max,
1274                            int *num_items)
1275    {
1276      /* make gcc happy */      /* make gcc happy */
1277      (void) plugin_type;      (void) plugin;
1278  #endif /* PLUGINS */      
1279        if (!plugin || !string || !separators || !num_items)
1280            return NULL;
1281        
1282        return explode_string (string, separators, num_items_max, num_items);
1283  }  }
1284    
1285  /*  /*
1286   * plugin_end: shutdown plugin interface   * weechat_free_exploded_string: free exploded string
1287   */   */
1288    
1289  void  void
1290  plugin_end ()  weechat_free_exploded_string (t_weechat_plugin *plugin, char **exploded_string)
1291  {  {
1292      plugin_handler_free_all (&plugin_msg_handlers, &last_plugin_msg_handler);      /* make gcc happy */
1293      plugin_handler_free_all (&plugin_cmd_handlers, &last_plugin_cmd_handler);      (void) plugin;
       
 #ifdef PLUGIN_PERL  
     wee_perl_end();  
 #endif  
1294            
1295  #ifdef PLUGIN_PYTHON      free_exploded_string (exploded_string);
1296      wee_python_end();  }
 #endif  
1297    
1298  #ifdef PLUGIN_RUBY  /*
1299      wee_ruby_end();   * weechat_ascii_strcasecmp: locale and case independent string comparison
1300  #endif   */
1301    
1302    int
1303    weechat_ascii_strcasecmp (t_weechat_plugin *plugin,
1304                              char *string1, char *string2)
1305    {
1306        /* make gcc happy */
1307        (void) plugin;
1308        
1309        return ascii_strcasecmp (string1, string2);
1310  }  }

Legend:
Removed from v.1.24  
changed lines
  Added in v.1.25

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26