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 {