comparison mcabber/src/commands.c @ 1607:14690e624e9d

Add modules
author Myhailo Danylenko <isbear@ukrpost.net>
date Sun, 11 Oct 2009 16:01:52 +0200
parents 54029aba9452
children 055ea3cdbcd3
comparison
equal deleted inserted replaced
1606:d7f26538c24c 1607:14690e624e9d
91 static void do_say_internal(char *arg, int parse_flags); 91 static void do_say_internal(char *arg, int parse_flags);
92 92
93 // Global variable for the commands list 93 // Global variable for the commands list
94 static GSList *Commands; 94 static GSList *Commands;
95 95
96 #ifdef MODULES_ENABLE
97 #include <gmodule.h>
98
99 static void do_load(char *arg);
100 static void do_unload(char *arg);
101
102 typedef struct {
103 char *name;
104 GModule *module;
105 } loaded_module_t;
106
107 GSList *loaded_modules = NULL;
108
109 static gint cmd_del_comparator (cmd *a, const char *name)
110 {
111 return strcmp(a->name, name);
112 }
113
114 gpointer cmd_del(const char *name)
115 {
116 GSList *command = g_slist_find_custom (Commands, name, (GCompareFunc) cmd_del_comparator);
117 if (command) {
118 cmd *cmnd = command->data;
119 gpointer userdata = cmnd->userdata;
120 Commands = g_slist_delete_link(Commands, command);
121 compl_del_category_word(COMPL_CMD, cmnd->name);
122 g_free(cmnd);
123 return userdata;
124 }
125 return NULL;
126 }
96 127
97 // cmd_add() 128 // cmd_add()
98 // Adds a command to the commands list and to the CMD completion list 129 // Adds a command to the commands list and to the CMD completion list
130 void cmd_add(const char *name, const char *help, guint flags_row1,
131 guint flags_row2, void (*f)(char*), gpointer userdata)
132 #define cmd_add(A, B, C, D, E) cmd_add (A, B, C, D, E, NULL);
133 #else
99 static void cmd_add(const char *name, const char *help, 134 static void cmd_add(const char *name, const char *help,
100 guint flags_row1, guint flags_row2, void (*f)(char*)) 135 guint flags_row1, guint flags_row2, void (*f)(char*))
136 #endif
101 { 137 {
102 cmd *n_cmd = g_new0(cmd, 1); 138 cmd *n_cmd = g_new0(cmd, 1);
103 strncpy(n_cmd->name, name, 32-1); 139 strncpy(n_cmd->name, name, 32-1);
104 n_cmd->help = help; 140 n_cmd->help = help;
105 n_cmd->completion_flags[0] = flags_row1; 141 n_cmd->completion_flags[0] = flags_row1;
106 n_cmd->completion_flags[1] = flags_row2; 142 n_cmd->completion_flags[1] = flags_row2;
107 n_cmd->func = f; 143 n_cmd->func = f;
144 #ifdef MODULES_ENABLE
145 n_cmd->userdata = userdata;
146 #endif
108 Commands = g_slist_append(Commands, n_cmd); 147 Commands = g_slist_append(Commands, n_cmd);
109 // Add to completion CMD category 148 // Add to completion CMD category
110 compl_add_category_word(COMPL_CMD, name); 149 compl_add_category_word(COMPL_CMD, name);
111 } 150 }
112 151
163 cmd_add("source", "Read a configuration file", 0, 0, &do_source); 202 cmd_add("source", "Read a configuration file", 0, 0, &do_source);
164 cmd_add("status", "Show or set your status", COMPL_STATUS, 0, &do_status); 203 cmd_add("status", "Show or set your status", COMPL_STATUS, 0, &do_status);
165 cmd_add("status_to", "Show or set your status for one recipient", 204 cmd_add("status_to", "Show or set your status for one recipient",
166 COMPL_JID, COMPL_STATUS, &do_status_to); 205 COMPL_JID, COMPL_STATUS, &do_status_to);
167 cmd_add("version", "Show mcabber version", 0, 0, &do_version); 206 cmd_add("version", "Show mcabber version", 0, 0, &do_version);
207 #ifdef MODULES_ENABLE
208 cmd_add("load", "Load module", 0, 0, &do_load);
209 cmd_add("unload", "Unload module", 0, 0, &do_unload);
210 #endif
168 211
169 // Status category 212 // Status category
170 compl_add_category_word(COMPL_STATUS, "online"); 213 compl_add_category_word(COMPL_STATUS, "online");
171 compl_add_category_word(COMPL_STATUS, "avail"); 214 compl_add_category_word(COMPL_STATUS, "avail");
172 compl_add_category_word(COMPL_STATUS, "invisible"); 215 compl_add_category_word(COMPL_STATUS, "invisible");
297 compl_add_category_word(COMPL_COLOR, "roster"); 340 compl_add_category_word(COMPL_COLOR, "roster");
298 compl_add_category_word(COMPL_COLOR, "muc"); 341 compl_add_category_word(COMPL_COLOR, "muc");
299 compl_add_category_word(COMPL_COLOR, "mucnick"); 342 compl_add_category_word(COMPL_COLOR, "mucnick");
300 } 343 }
301 344
345 #ifdef MODULES_ENABLE
346 void cmd_deinit ()
347 {
348 GSList *el = loaded_modules;
349 while (el) {
350 loaded_module_t *module = el->data;
351 if (!g_module_close ((GModule *) module->module))
352 scr_LogPrint (LPRINT_LOGNORM, "* Module unloading failed: %s",
353 g_module_error ());
354 g_free (module->name);
355 g_free (module);
356 el = g_slist_next (el);
357 }
358 g_slist_free (loaded_modules);
359 }
360 #endif
361
302 // expandalias(line) 362 // expandalias(line)
303 // If there is one, expand the alias in line and returns a new allocated line 363 // If there is one, expand the alias in line and returns a new allocated line
304 // If no alias is found, returns line 364 // If no alias is found, returns line
305 // Note: if the returned pointer is different from line, the caller should 365 // Note: if the returned pointer is different from line, the caller should
306 // g_free() the pointer after use 366 // g_free() the pointer after use
433 // Skip spaces 493 // Skip spaces
434 while (*p && (*p == ' ')) 494 while (*p && (*p == ' '))
435 p++; 495 p++;
436 // Call command-specific function 496 // Call command-specific function
437 retval_for_cmds = 0; 497 retval_for_cmds = 0;
498 #ifdef MODULES_ENABLE
499 if (curcmd->userdata)
500 (*(void (*)(char *p, gpointer u))curcmd->func)(p, curcmd->userdata);
501 else
502 (*curcmd->func)(p);
503 #else
438 (*curcmd->func)(p); 504 (*curcmd->func)(p);
505 #endif
439 g_free(xpline); 506 g_free(xpline);
440 return retval_for_cmds; 507 return retval_for_cmds;
441 } 508 }
442 509
443 // process_line(line) 510 // process_line(line)
2900 update_roster = TRUE; 2967 update_roster = TRUE;
2901 g_string_free(sbuf, TRUE); 2968 g_string_free(sbuf, TRUE);
2902 g_slist_free(bm); 2969 g_slist_free(bm);
2903 } 2970 }
2904 2971
2972 #ifdef MODULES_ENABLE
2973 static void do_load(char *arg)
2974 {
2975 if (!arg || !*arg) {
2976 scr_LogPrint (LPRINT_LOGNORM, "Missing modulename.");
2977 return;
2978 }
2979 char *mdir = expand_filename (settings_opt_get ("modules_dir"));
2980 char *path = g_module_build_path (mdir, arg);
2981 GModule *mod = g_module_open (path, G_MODULE_BIND_LAZY);
2982 if (!mod)
2983 scr_LogPrint (LPRINT_LOGNORM, "Module %s loading failed: %s",
2984 path, g_module_error ());
2985 else {
2986 loaded_module_t *module = g_new (loaded_module_t, 1);
2987 module->name = g_strdup (arg);
2988 module->module = mod;
2989 loaded_modules = g_slist_prepend (loaded_modules, module);
2990 scr_LogPrint (LPRINT_LOGNORM, "Loaded module %s", arg);
2991 }
2992 g_free (path);
2993 if (mdir)
2994 g_free (mdir);
2995 }
2996
2997 static int module_list_comparator (loaded_module_t *module, const char *name)
2998 {
2999 return g_strcmp0 (module->name, name);
3000 }
3001
3002 static void do_unload(char *arg)
3003 {
3004 if (!arg || !*arg) {
3005 scr_LogPrint (LPRINT_LOGNORM, "Missing modulename.");
3006 return;
3007 }
3008 GSList *module = g_slist_find_custom (loaded_modules, arg, (GCompareFunc) module_list_comparator);
3009 if (module) {
3010 loaded_module_t *mod = module->data;
3011 if (!g_module_close ((GModule *) mod->module))
3012 scr_LogPrint (LPRINT_LOGNORM, "Module unloading failed: %s",
3013 g_module_error ());
3014 else {
3015 g_free (mod->name);
3016 g_free (mod);
3017 loaded_modules = g_slist_delete_link (loaded_modules, module);
3018 }
3019 } else
3020 scr_LogPrint (LPRINT_LOGNORM, "Module %s not loaded.", arg);
3021 }
3022 #endif
2905 3023
2906 static void do_room(char *arg) 3024 static void do_room(char *arg)
2907 { 3025 {
2908 char **paramlst; 3026 char **paramlst;
2909 char *subcmd; 3027 char *subcmd;