Mercurial > ~mikael > mcabber > hg
comparison mcabber/mcabber/commands.c @ 1735:5093b5ca1572
New modules loading scheme
author | Myhailo Danylenko <isbear@ukrpost.net> |
---|---|
date | Thu, 04 Mar 2010 13:03:20 +0200 |
parents | 4e57d6275a86 |
children | 764ed5c12589 |
comparison
equal
deleted
inserted
replaced
1734:eae4a2637f2c | 1735:5093b5ca1572 |
---|---|
96 | 96 |
97 // Global variable for the commands list | 97 // Global variable for the commands list |
98 static GSList *Commands; | 98 static GSList *Commands; |
99 | 99 |
100 #ifdef MODULES_ENABLE | 100 #ifdef MODULES_ENABLE |
101 #include <gmodule.h> | 101 #include "modules.h" |
102 | 102 |
103 static void do_load(char *arg); | 103 static void do_module(char *arg); |
104 static void do_unload(char *arg); | |
105 | |
106 typedef struct { | |
107 char *name; | |
108 GModule *module; | |
109 } loaded_module_t; | |
110 | |
111 GSList *loaded_modules = NULL; | |
112 | 104 |
113 gpointer cmd_del(const char *name) | 105 gpointer cmd_del(const char *name) |
114 { | 106 { |
115 GSList *sl_cmd; | 107 GSList *sl_cmd; |
116 for (sl_cmd = Commands; sl_cmd; sl_cmd = sl_cmd->next) { | 108 for (sl_cmd = Commands; sl_cmd; sl_cmd = sl_cmd->next) { |
203 cmd_add("status", "Show or set your status", COMPL_STATUS, 0, &do_status); | 195 cmd_add("status", "Show or set your status", COMPL_STATUS, 0, &do_status); |
204 cmd_add("status_to", "Show or set your status for one recipient", | 196 cmd_add("status_to", "Show or set your status for one recipient", |
205 COMPL_JID, COMPL_STATUS, &do_status_to); | 197 COMPL_JID, COMPL_STATUS, &do_status_to); |
206 cmd_add("version", "Show mcabber version", 0, 0, &do_version); | 198 cmd_add("version", "Show mcabber version", 0, 0, &do_version); |
207 #ifdef MODULES_ENABLE | 199 #ifdef MODULES_ENABLE |
208 cmd_add("load", "Load module", 0, 0, &do_load); | 200 cmd_add("module", "Manipulations with modules", 0, 0, &do_module); |
209 cmd_add("unload", "Unload module", 0, 0, &do_unload); | |
210 #endif | 201 #endif |
211 | 202 |
212 // Status category | 203 // Status category |
213 compl_add_category_word(COMPL_STATUS, "online"); | 204 compl_add_category_word(COMPL_STATUS, "online"); |
214 compl_add_category_word(COMPL_STATUS, "avail"); | 205 compl_add_category_word(COMPL_STATUS, "avail"); |
340 // Color category | 331 // Color category |
341 compl_add_category_word(COMPL_COLOR, "roster"); | 332 compl_add_category_word(COMPL_COLOR, "roster"); |
342 compl_add_category_word(COMPL_COLOR, "muc"); | 333 compl_add_category_word(COMPL_COLOR, "muc"); |
343 compl_add_category_word(COMPL_COLOR, "mucnick"); | 334 compl_add_category_word(COMPL_COLOR, "mucnick"); |
344 } | 335 } |
345 | |
346 #ifdef MODULES_ENABLE | |
347 void cmd_deinit () | |
348 { | |
349 GSList *el = loaded_modules; | |
350 while (el) { | |
351 loaded_module_t *module = el->data; | |
352 if (!g_module_close ((GModule *) module->module)) | |
353 scr_LogPrint (LPRINT_LOGNORM, "* Module unloading failed: %s", | |
354 g_module_error ()); | |
355 g_free (module->name); | |
356 g_free (module); | |
357 el = g_slist_next (el); | |
358 } | |
359 g_slist_free (loaded_modules); | |
360 } | |
361 #endif | |
362 | 336 |
363 // expandalias(line) | 337 // expandalias(line) |
364 // If there is one, expand the alias in line and returns a new allocated line | 338 // If there is one, expand the alias in line and returns a new allocated line |
365 // If no alias is found, returns line | 339 // If no alias is found, returns line |
366 // Note: if the returned pointer is different from line, the caller should | 340 // Note: if the returned pointer is different from line, the caller should |
2978 g_string_free(sbuf, TRUE); | 2952 g_string_free(sbuf, TRUE); |
2979 g_slist_free(bm); | 2953 g_slist_free(bm); |
2980 } | 2954 } |
2981 | 2955 |
2982 #ifdef MODULES_ENABLE | 2956 #ifdef MODULES_ENABLE |
2983 static gint module_list_comparator(gconstpointer arg1, gconstpointer arg2) | 2957 static void do_module(char *arg) |
2984 { | 2958 { |
2985 const loaded_module_t *module = arg1; | 2959 gboolean force = FALSE; |
2986 const char *name = arg2; | 2960 char **args; |
2987 return g_strcmp0(module->name, name); | 2961 |
2988 } | 2962 if (arg[0] == '-' && arg[1] == 'f') { |
2989 | 2963 force = TRUE; |
2990 static void do_load(char *arg) | 2964 arg +=2; |
2991 { | 2965 while (*arg && *arg == ' ') |
2992 GModule *mod; | 2966 ++arg; |
2993 GSList *lmod; | 2967 } |
2994 char *mdir, *path; | 2968 |
2995 if (!arg || !*arg) { | 2969 args = split_arg(arg, 2, 0); |
2996 scr_LogPrint(LPRINT_LOGNORM, "Missing modulename."); | 2970 if (!args[0] || !strcmp(args[0], "list")) { |
2997 return; | 2971 module_list_print(); |
2998 } | 2972 } else { |
2999 lmod = g_slist_find_custom(loaded_modules, arg, module_list_comparator); | 2973 const gchar *error; |
3000 if (lmod) { | 2974 if (!strcmp(args[0], "load")) |
3001 scr_LogPrint(LPRINT_LOGNORM, "Module %s is already loaded.", arg); | 2975 error = module_load(args[1], TRUE, force); |
3002 return; | 2976 else if (!strcmp(args[0], "unload")) |
3003 } | 2977 error = module_unload(args[1], TRUE, force); |
3004 mdir = expand_filename(settings_opt_get("modules_dir")); | 2978 else |
3005 path = g_module_build_path(mdir ? mdir : PKGLIB_DIR, arg); | 2979 error = "Unknown subcommand"; |
3006 mod = g_module_open(path, G_MODULE_BIND_LAZY); | 2980 if (error) |
3007 if (!mod) | 2981 scr_LogPrint(LPRINT_LOGNORM, "Error: %s.", error); |
3008 scr_LogPrint(LPRINT_LOGNORM, "Module loading failed: %s", | 2982 } |
3009 g_module_error()); | 2983 free_arg_lst(args); |
3010 else { | |
3011 loaded_module_t *module = g_new(loaded_module_t, 1); | |
3012 module->name = g_strdup(arg); | |
3013 module->module = mod; | |
3014 loaded_modules = g_slist_prepend(loaded_modules, module); | |
3015 scr_LogPrint(LPRINT_LOGNORM, "Loaded module %s.", arg); | |
3016 } | |
3017 g_free(path); | |
3018 g_free(mdir); | |
3019 } | |
3020 | |
3021 static void do_unload(char *arg) | |
3022 { | |
3023 GSList *module; | |
3024 if (!arg || !*arg) { | |
3025 scr_LogPrint(LPRINT_LOGNORM, "Missing modulename."); | |
3026 return; | |
3027 } | |
3028 module = g_slist_find_custom(loaded_modules, arg, module_list_comparator); | |
3029 if (module) { | |
3030 loaded_module_t *mod = module->data; | |
3031 if (!g_module_close(mod->module)) | |
3032 scr_LogPrint(LPRINT_LOGNORM, "Module unloading failed: %s", | |
3033 g_module_error()); | |
3034 else { | |
3035 g_free(mod->name); | |
3036 g_free(mod); | |
3037 loaded_modules = g_slist_delete_link(loaded_modules, module); | |
3038 scr_LogPrint(LPRINT_LOGNORM, "Unloaded module %s.", arg); | |
3039 } | |
3040 } else | |
3041 scr_LogPrint(LPRINT_LOGNORM, "Module %s not loaded.", arg); | |
3042 } | 2984 } |
3043 #endif | 2985 #endif |
3044 | 2986 |
3045 static void do_room(char *arg) | 2987 static void do_room(char *arg) |
3046 { | 2988 { |