"Fossies" - the Fresh Open Source Software Archive

Member "jpilot-2_0_1/plugins.c" (3 Apr 2021, 13382 Bytes) of package /linux/privat/jpilot-2_0_1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "plugins.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.8.2_vs_2_0_1.

    1 /*******************************************************************************
    2  * plugins.c
    3  * A module of J-Pilot http://jpilot.org
    4  *
    5  * Copyright (C) 1999-2014 by Judd Montgomery
    6  *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; version 2 of the License.
   10  *
   11  * This program is distributed in the hope that it will be useful,
   12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14  * GNU General Public License for more details.
   15  *
   16  * You should have received a copy of the GNU General Public License
   17  * along with this program; if not, write to the Free Software
   18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   19  ******************************************************************************/
   20 
   21 /********************************* Includes ***********************************/
   22 #include "config.h"
   23 #ifdef  ENABLE_PLUGINS
   24 #include <dirent.h>
   25 #include <stdio.h>
   26 #include <stdlib.h>
   27 #include <string.h>
   28 #include <ctype.h>
   29 #include "utils.h"
   30 #include "log.h"
   31 #include "plugins.h"
   32 #include <dlfcn.h>
   33 #include "i18n.h"
   34 
   35 /******************************* Global vars **********************************/
   36 static GList *plugins = NULL;
   37 
   38 /****************************** Prototypes ************************************/
   39 static int get_plugin_info(struct plugin_s *p, char *path);
   40 static int get_plugin_sync_bits(void);
   41 static gint plugin_sort(gconstpointer a, gconstpointer b);
   42 
   43 /****************************** Main Code *************************************/
   44 /* Write out the jpilot.plugins file that tells which plugins to sync */
   45 void write_plugin_sync_file(void)
   46 {
   47    FILE *out;
   48    GList *temp_list;
   49    struct plugin_s *Pplugin;
   50 
   51    out=jp_open_home_file(EPN".plugins", "w");
   52    if (!out) {
   53       return;
   54    }
   55    fwrite("Version 1\n", strlen("Version 1\n"), 1, out);
   56    for (temp_list = plugins; temp_list; temp_list = temp_list->next) {
   57       Pplugin = temp_list->data;
   58       if (Pplugin) {
   59          if (Pplugin->sync_on) {
   60             fwrite("Y ", 2, 1, out);
   61          } else {
   62             fwrite("N ", 2, 1, out);
   63          }
   64          fwrite(Pplugin->full_path, strlen(Pplugin->full_path), 1, out);
   65          fwrite("\n", strlen("\n"), 1, out);
   66       }
   67    }
   68    fclose(out);
   69 }
   70 
   71 /* This is just a repeated subroutine to load_plugins not needing
   72  * a name of its own.
   73  * Assumes dir has already been checked */
   74 static int load_plugins_sub1(DIR *dir, char *path, int *number, 
   75                              unsigned char user_only)
   76 {
   77    int i, r;
   78    int count;
   79    struct dirent *dirent;
   80    char full_name[FILENAME_MAX];
   81    struct plugin_s temp_plugin, *new_plugin;
   82    GList *plugin_names = NULL; /* keep a list of plugins found so far */
   83    GList *temp_list = NULL;
   84 
   85    count = 0;
   86    for (i=0; (dirent = readdir(dir)); i++) {
   87       if (i>1000) {
   88          jp_logf(JP_LOG_WARN, "load_plugins_sub1(): %s\n", _("infinite loop"));
   89          return 0;
   90       }
   91       /* If the filename has either of these extensions then plug it in */
   92       if ((strcmp(&(dirent->d_name[strlen(dirent->d_name)-3]), ".so")) &&
   93           (strcmp(&(dirent->d_name[strlen(dirent->d_name)-3]), ".sl")) &&
   94           (strcmp(&(dirent->d_name[strlen(dirent->d_name)-6]), ".dylib"))) {
   95          continue;
   96       } else {
   97          jp_logf(JP_LOG_DEBUG, "found plugin %s\n", dirent->d_name);
   98          /* We know path has a trailing slash after it */
   99          g_snprintf(full_name, sizeof(full_name), "%s%s", path, dirent->d_name);
  100          r = get_plugin_info(&temp_plugin, full_name);
  101          temp_plugin.number = *number;
  102          temp_plugin.user_only = user_only;
  103          if (r==0) {
  104             if (temp_plugin.name) {
  105                jp_logf(JP_LOG_DEBUG, "plugin name is [%s]\n", temp_plugin.name);
  106             }
  107             if (g_list_find_custom(plugin_names, temp_plugin.name, (GCompareFunc)strcmp) == NULL) {
  108                new_plugin = malloc(sizeof(struct plugin_s));
  109                if (!new_plugin) {
  110                   jp_logf(JP_LOG_WARN, "load plugins(): %s\n", _("Out of memory"));
  111                   return count;
  112                }
  113                memcpy(new_plugin, &temp_plugin, sizeof(struct plugin_s));
  114                plugins = g_list_prepend(plugins, new_plugin);
  115                plugin_names = g_list_prepend(plugin_names, g_strdup(temp_plugin.name));
  116                count++;
  117                (*number)++;
  118             }
  119          }
  120       }
  121    }
  122 
  123    plugins = g_list_sort(plugins, plugin_sort);
  124    for (temp_list = plugin_names; temp_list; temp_list = temp_list->next) {
  125       if (temp_list->data) {
  126          g_free(temp_list->data);
  127       }
  128    }
  129    g_list_free(plugin_names);
  130 
  131    return count;
  132 }
  133 
  134 static gint plugin_sort(gconstpointer a, gconstpointer b)
  135 {
  136    const char *ca = ((struct plugin_s *)a)->menu_name;
  137    const char *cb = ((struct plugin_s *)b)->menu_name;
  138 
  139    /* menu_name is NULL for plugin without menu entry */
  140    if (ca == NULL)
  141       ca = ((struct plugin_s *)a)->name;
  142 
  143    if (cb == NULL)
  144       cb = ((struct plugin_s *)b)->name;
  145 
  146    return strcasecmp(ca, cb);
  147 }
  148 
  149 int load_plugins(void)
  150 {
  151    DIR *dir;
  152    char path[FILENAME_MAX];
  153    int count, number;
  154 
  155    count = 0;
  156    number = DATEBOOK + 100; /* I just made up this number */
  157    plugins = NULL;
  158 
  159    /* ABILIB is for Irix, should normally be "lib" */
  160    g_snprintf(path, sizeof(path), "%s/%s/%s/%s/", BASE_DIR, ABILIB, EPN, "plugins");
  161    jp_logf(JP_LOG_DEBUG, "opening dir %s\n", path);
  162    cleanup_path(path);
  163    dir = opendir(path);
  164    if (dir) {
  165       count += load_plugins_sub1(dir, path, &number, 0);
  166       closedir(dir);
  167    }
  168 
  169    get_home_file_name("plugins/", path, sizeof(path));
  170    cleanup_path(path);
  171    jp_logf(JP_LOG_DEBUG, "opening dir %s\n", path);
  172    dir = opendir(path);
  173    if (dir) {
  174       count += load_plugins_sub1(dir, path, &number, 1);
  175       closedir(dir);
  176    }
  177 
  178    get_plugin_sync_bits();
  179 
  180    return count;
  181 }
  182 
  183 /* Now we need to look in the jpilot_plugins file to see which plugins
  184  * are enabled to sync and which are not */
  185 static int get_plugin_sync_bits(void)
  186 {
  187    int i;
  188    GList *temp_list;
  189    struct plugin_s *Pplugin;
  190    char line[1024];
  191    char *Pline;
  192    char *Pc;
  193    FILE *in;
  194 
  195    in=jp_open_home_file(EPN".plugins", "r");
  196    if (!in) {
  197       return EXIT_SUCCESS;
  198    }
  199    for (i=0; (!feof(in)); i++) {
  200       if (i>MAX_NUM_PLUGINS) {
  201          jp_logf(JP_LOG_WARN, "load_plugins(): %s\n", _("infinite loop"));
  202          fclose(in);
  203          return EXIT_FAILURE;
  204       }
  205       line[0]='\0';
  206       Pc = fgets(line, sizeof(line), in);
  207       if (!Pc) {
  208          break;
  209       }
  210       if (line[strlen(line)-1]=='\n') {
  211          line[strlen(line)-1]='\0';
  212       }
  213       if ((!strncmp(line, "Version", 7)) && (strcmp(line, "Version 1"))) {
  214          jp_logf(JP_LOG_WARN, _("While reading %s%s line 1:[%s]\n"), EPN, ".plugins", line);
  215          jp_logf(JP_LOG_WARN, _("Wrong Version\n"));
  216          jp_logf(JP_LOG_WARN, _("Check preferences->conduits\n"));
  217          fclose(in);
  218          return EXIT_FAILURE;
  219       }
  220       if (i>0) {
  221          if (toupper(line[0])=='N') {
  222             Pline = line + 2;
  223             for (temp_list = plugins; temp_list; temp_list = temp_list->next) {
  224                Pplugin = temp_list->data;
  225                if (!strcmp(Pline, Pplugin->full_path)) {
  226                   Pplugin->sync_on=0;
  227                }
  228             }
  229          }
  230       }
  231    }
  232    fclose(in);
  233    return EXIT_SUCCESS;
  234 }
  235 
  236 static int get_plugin_info(struct plugin_s *p, char *path)
  237 {
  238    void *h;
  239    const char *err;
  240    char name[52];
  241    char db_name[52];
  242    int major_version, minor_version;
  243    void (*plugin_versionM)(int *major_version, int *minor_version);
  244 
  245    p->full_path = NULL;
  246    p->handle = NULL;
  247    p->sync_on = 1;
  248    p->name = NULL;
  249    p->db_name = NULL;
  250    p->number = 0;
  251    p->plugin_get_name = NULL;
  252    p->plugin_get_menu_name = NULL;
  253    p->plugin_get_help_name = NULL;
  254    p->plugin_get_db_name = NULL;
  255    p->plugin_startup = NULL;
  256    p->plugin_gui = NULL;
  257    p->plugin_help = NULL;
  258    p->plugin_print = NULL;
  259    p->plugin_import = NULL;
  260    p->plugin_export = NULL;
  261    p->plugin_gui_cleanup = NULL;
  262    p->plugin_pre_sync_pre_connect = NULL;
  263    p->plugin_pre_sync = NULL;
  264    p->plugin_sync = NULL;
  265    p->plugin_post_sync = NULL;
  266    p->plugin_exit_cleanup = NULL;
  267    p->plugin_unpack_cai_from_ai = NULL;
  268    p->plugin_pack_cai_into_ai = NULL;
  269 
  270    h = dlopen(path, RTLD_LAZY);
  271    if (!h) {
  272       jp_logf(JP_LOG_WARN, _("Open failed on plugin [%s]\n error [%s]\n"), path,
  273                   dlerror());
  274       return EXIT_FAILURE;
  275    }
  276    jp_logf(JP_LOG_DEBUG, "opened plugin [%s]\n", path);
  277    p->handle=h;
  278 
  279    p->full_path = strdup(path);
  280 
  281    /* plugin_versionM */
  282 #if defined __OpenBSD__ && !defined __ELF__
  283 #define dlsym(x,y) dlsym(x, "_" y)
  284 #endif
  285    plugin_versionM = dlsym(h, "plugin_version");
  286    if (plugin_versionM==NULL)  {
  287       err = dlerror();
  288       jp_logf(JP_LOG_WARN, "plugin_version: [%s]\n", err);
  289       jp_logf(JP_LOG_WARN, _(" plugin is invalid: [%s]\n"), path);
  290       dlclose(h);
  291       p->handle=NULL;
  292       return EXIT_FAILURE;
  293    }
  294    plugin_versionM(&major_version, &minor_version);
  295    if ((major_version <= 0) && (minor_version < 99)) {
  296       jp_logf(JP_LOG_WARN, _("Plugin:[%s]\n"), path);
  297       jp_logf(JP_LOG_WARN, _("This plugin is version (%d.%d).\n"),
  298                   major_version, minor_version);
  299       jp_logf(JP_LOG_WARN, _("It is too old to work with this version of J-Pilot.\n"));
  300       dlclose(h);
  301       p->handle=NULL;
  302       return EXIT_FAILURE;
  303    }
  304    jp_logf(JP_LOG_DEBUG, "This plugin is version (%d.%d).\n",
  305                major_version, minor_version);
  306 
  307    /* plugin_get_name */
  308    jp_logf(JP_LOG_DEBUG, "getting plugin_get_name\n");
  309    p->plugin_get_name = dlsym(h, "plugin_get_name");
  310    if (p->plugin_get_name==NULL)  {
  311       err = dlerror();
  312       jp_logf(JP_LOG_WARN, "plugin_get_name: [%s]\n", err);
  313       jp_logf(JP_LOG_WARN, _(" plugin is invalid: [%s]\n"), path);
  314       dlclose(h);
  315       p->handle=NULL;
  316       return EXIT_FAILURE;
  317    }
  318 
  319    if (p->plugin_get_name) {
  320       p->plugin_get_name(name, 50);
  321       name[50]='\0';
  322       p->name = strdup(name);
  323    } else {
  324       p->name = NULL;
  325    }
  326 
  327    /* plugin_get_menu_name */
  328    jp_logf(JP_LOG_DEBUG, "getting plugin_get_menu_name\n");
  329    p->plugin_get_menu_name = dlsym(h, "plugin_get_menu_name");
  330    if (p->plugin_get_menu_name) {
  331       p->plugin_get_menu_name(name, 50);
  332       name[50]='\0';
  333       p->menu_name = strdup(name);
  334    } else {
  335       p->menu_name = NULL;
  336    }
  337 
  338    /* plugin_get_help_name */
  339    jp_logf(JP_LOG_DEBUG, "getting plugin_get_help_name\n");
  340    p->plugin_get_help_name = dlsym(h, "plugin_get_help_name");
  341    if (p->plugin_get_help_name) {
  342       p->plugin_get_help_name(name, 50);
  343       name[50]='\0';
  344       p->help_name = strdup(name);
  345    } else {
  346       p->help_name = NULL;
  347    }
  348 
  349    /* plugin_get_db_name */
  350    jp_logf(JP_LOG_DEBUG, "getting plugin_get_db_name\n");
  351    p->plugin_get_db_name = dlsym(h, "plugin_get_db_name");
  352    if (p->plugin_get_db_name) {
  353       p->plugin_get_db_name(db_name, 50);
  354       db_name[50]='\0';
  355    } else {
  356       db_name[0]='\0';
  357    }
  358    p->db_name = strdup(db_name);
  359 
  360    /* plugin_gui */
  361    p->plugin_gui = dlsym(h, "plugin_gui");
  362 
  363    /* plugin_help */
  364    p->plugin_help = dlsym(h, "plugin_help");
  365 
  366    /* plugin_help */
  367    p->plugin_print = dlsym(h, "plugin_print");
  368 
  369    /* plugin_import */
  370    p->plugin_import = dlsym(h, "plugin_import");
  371 
  372    /* plugin_export */
  373    p->plugin_export = dlsym(h, "plugin_export");
  374 
  375    /* plugin_gui_cleanup */
  376    p->plugin_gui_cleanup = dlsym(h, "plugin_gui_cleanup");
  377 
  378    /* plugin_startup */
  379    p->plugin_startup = dlsym(h, "plugin_startup");
  380 
  381    /* plugin_pre_sync */
  382    p->plugin_pre_sync = dlsym(h, "plugin_pre_sync");
  383 
  384    /* plugin_pre_sync_pre_connect */
  385    p->plugin_pre_sync_pre_connect = dlsym(h, "plugin_pre_sync_pre_connect");
  386 
  387    /* plugin_sync */
  388    p->plugin_sync = dlsym(h, "plugin_sync");
  389 
  390    /* plugin_post_sync */
  391    p->plugin_post_sync = dlsym(h, "plugin_post_sync");
  392 
  393    /* plugin_search */
  394    p->plugin_search = dlsym(h, "plugin_search");
  395 
  396    /* plugin_exit_cleanup */
  397    p->plugin_exit_cleanup = dlsym(h, "plugin_exit_cleanup");
  398 
  399    p->plugin_unpack_cai_from_ai = dlsym(h, "plugin_unpack_cai_from_ai");
  400    p->plugin_pack_cai_into_ai = dlsym(h, "plugin_pack_cai_into_ai");
  401 
  402    return EXIT_SUCCESS;
  403 }
  404 
  405 /* This will always return the first plugin list entry */
  406 GList *get_plugin_list(void)
  407 {
  408    return plugins;
  409 }
  410 
  411 void free_plugin_list(GList **plugin_list)
  412 {
  413    GList *temp_list;
  414    struct plugin_s *p;
  415 
  416    for (temp_list = *plugin_list; temp_list; temp_list = temp_list->next) {
  417       if (temp_list->data) {
  418          p=temp_list->data;
  419          if (p->full_path) free(p->full_path);
  420          if (p->name)      free(p->name);
  421          if (p->menu_name) free(p->menu_name);
  422          if (p->help_name) free(p->help_name);
  423          if (p->db_name)   free(p->db_name);
  424 
  425          free(p);
  426       }
  427    }
  428    g_list_free(*plugin_list);
  429    *plugin_list=NULL;
  430 }
  431 
  432 void free_search_result(struct search_result **sr)
  433 {
  434    struct search_result *temp_sr, *temp_sr_next;
  435 
  436    for (temp_sr = *sr; temp_sr; temp_sr=temp_sr_next) {
  437       if (temp_sr->line) {
  438          free(temp_sr->line);
  439       }
  440       temp_sr_next = temp_sr->next;
  441       free(temp_sr);
  442    }
  443    *sr = NULL;
  444 }
  445 #endif  /* ENABLE_PLUGINS */