Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/nogaim.c

    r977a9d5 rff468a7  
    4040
    4141#ifdef WITH_PLUGINS
     42GList *plugins = NULL;
     43
     44static gint pluginscmp(gconstpointer a, gconstpointer b, gpointer data)
     45{
     46        const struct plugin_info *ia = a;
     47        const struct plugin_info *ib = b;
     48
     49        return g_strcasecmp(ia->name, ib->name);
     50}
     51
    4252gboolean load_plugin(char *path)
    4353{
     54        GList *l;
     55        struct plugin_info *i;
     56        struct plugin_info *info;
     57        struct plugin_info * (*info_function) (void) = NULL;
    4458        void (*init_function) (void);
    4559
    4660        GModule *mod = g_module_open(path, G_MODULE_BIND_LAZY);
     61        gboolean loaded = FALSE;
    4762
    4863        if (!mod) {
    49                 log_message(LOGLVL_ERROR, "Can't find `%s', not loading (%s)\n", path, g_module_error());
     64                log_message(LOGLVL_ERROR, "Error loading plugin `%s': %s\n", path, g_module_error());
    5065                return FALSE;
     66        }
     67
     68        if (g_module_symbol(mod, "init_plugin_info", (gpointer *) &info_function)) {
     69                info = info_function();
     70
     71                if (info->abiver != BITLBEE_ABI_VERSION_CODE) {
     72                        log_message(LOGLVL_ERROR,
     73                                    "`%s' uses ABI %u but %u is required\n",
     74                                    path, info->abiver,
     75                                    BITLBEE_ABI_VERSION_CODE);
     76                        g_module_close(mod);
     77                        return FALSE;
     78                }
     79
     80                if (!info->name || !info->version) {
     81                        log_message(LOGLVL_ERROR,
     82                                    "Name or version missing from the "
     83                                    "plugin info in `%s'\n", path);
     84                        g_module_close(mod);
     85                        return FALSE;
     86                }
     87
     88                for (l = plugins; l; l = l->next) {
     89                        i = l->data;
     90
     91                        if (g_strcasecmp(i->name, info->name) == 0) {
     92                                loaded = TRUE;
     93                                break;
     94                        }
     95                }
     96
     97                if (loaded) {
     98                        log_message(LOGLVL_WARNING,
     99                                    "%s plugin already loaded\n",
     100                                    info->name);
     101                        g_module_close(mod);
     102                        return FALSE;
     103                }
     104        } else {
     105                log_message(LOGLVL_WARNING, "Can't find function `init_plugin_info' in `%s'\n", path);
    51106        }
    52107
    53108        if (!g_module_symbol(mod, "init_plugin", (gpointer *) &init_function)) {
    54109                log_message(LOGLVL_WARNING, "Can't find function `init_plugin' in `%s'\n", path);
     110                g_module_close(mod);
    55111                return FALSE;
    56112        }
    57113
     114        if (info_function) {
     115                plugins = g_list_insert_sorted_with_data(plugins, info,
     116                                                         pluginscmp, NULL);
     117        }
     118
    58119        init_function();
    59 
    60120        return TRUE;
    61121}
     
    73133
    74134                while ((entry = g_dir_read_name(dir))) {
     135                        if (!g_str_has_suffix(entry, "." G_MODULE_SUFFIX)) {
     136                                continue;
     137                        }
     138
    75139                        path = g_build_filename(global.conf->plugindir, entry, NULL);
    76140                        if (!path) {
     
    86150                g_dir_close(dir);
    87151        }
     152}
     153
     154GList *get_plugins()
     155{
     156        return plugins;
    88157}
    89158#endif
     
    163232        load_plugins();
    164233#endif
     234}
     235
     236GList *get_protocols()
     237{
     238        return protocols;
     239}
     240
     241GList *get_protocols_disabled()
     242{
     243        return disabled_protocols;
    165244}
    166245
     
    479558}
    480559
    481 /* Mainly meant for ICQ (and now also for Jabber conferences) to allow IM
    482    modules to suggest a nickname for a handle. */
    483 void imcb_buddy_nick_hint(struct im_connection *ic, const char *handle, const char *nick)
     560/* Implements either imcb_buddy_nick_hint() or imcb_buddy_nick_change() depending on the value of 'change' */
     561static void buddy_nick_hint_or_change(struct im_connection *ic, const char *handle, const char *nick, gboolean change)
    484562{
    485563        bee_t *bee = ic->bee;
     
    493571        bu->nick = g_strdup(nick);
    494572
    495         if (bee->ui->user_nick_hint) {
     573        if (change && bee->ui->user_nick_change) {
     574                bee->ui->user_nick_change(bee, bu, nick);
     575        } else if (!change && bee->ui->user_nick_hint) {
    496576                bee->ui->user_nick_hint(bee, bu, nick);
    497577        }
    498578}
    499579
     580/* Soft variant, for newly created users. Does nothing if it's already online */
     581void imcb_buddy_nick_hint(struct im_connection *ic, const char *handle, const char *nick)
     582{
     583        buddy_nick_hint_or_change(ic, handle, nick, FALSE);
     584}
     585
     586/* Hard variant, always changes the nick */
     587void imcb_buddy_nick_change(struct im_connection *ic, const char *handle, const char *nick)
     588{
     589        buddy_nick_hint_or_change(ic, handle, nick, TRUE);
     590}
    500591
    501592struct imcb_ask_cb_data {
     
    621712        if (away && *away) {
    622713                GList *m = ic->acc->prpl->away_states(ic);
     714                if (m == NULL) {
     715                        return 0;
     716                }
    623717                msg = ic->acc->flags & ACC_FLAG_AWAY_MESSAGE ? away : NULL;
    624718                away = imc_away_state_find(m, away, &msg) ? :
Note: See TracChangeset for help on using the changeset viewer.