+static user_mode_func_t *um_list;
+static void **um_list_extra;
+static unsigned int um_size = 0, um_used = 0;
+
+void
+reg_user_mode_func(user_mode_func_t handler, void *extra)
+{
+ if (um_used == um_size) {
+ if (um_size) {
+ um_size <<= 1;
+ um_list = realloc(um_list, um_size*sizeof(user_mode_func_t));
+ um_list_extra = realloc(um_list_extra, um_size*sizeof(void*));
+ } else {
+ um_size = 8;
+ um_list = malloc(um_size*sizeof(user_mode_func_t));
+ um_list_extra = malloc(um_size*sizeof(void*));
+ }
+ }
+ um_list[um_used] = handler;
+ um_list_extra[um_used++] = extra;
+}
+
+void
+unreg_user_mode_func(user_mode_func_t handler)
+{
+ unsigned int i;
+ for (i=0; i<um_used; i++) {
+ if (um_list[i] == handler) break;
+ }
+ if (i == um_used) return;
+ memmove(um_list+i, um_list+i+1, (um_used-i-1)*sizeof(um_list[0]));
+ um_used--;
+}
+
+static void
+call_user_mode_funcs(struct userNode *user, const char *mode_change)
+{
+ unsigned int n;
+ for (n=0; n<um_used; n++) {
+ um_list[n](user, mode_change, um_list_extra[n]);
+ }
+}
+
+static channel_mode_func_t *cm_list;
+static void **cm_list_extra;
+static unsigned int cm_size = 0, cm_used = 0;
+
+void
+reg_channel_mode_func(channel_mode_func_t handler, void *extra)
+{
+ if (cm_used == cm_size) {
+ if (cm_size) {
+ cm_size <<= 1;
+ cm_list = realloc(cm_list, cm_size*sizeof(channel_mode_func_t));
+ cm_list_extra = realloc(cm_list_extra, cm_size*sizeof(void*));
+ } else {
+ cm_size = 8;
+ cm_list = malloc(cm_size*sizeof(channel_mode_func_t));
+ cm_list_extra = malloc(cm_size*sizeof(void*));
+ }
+ }
+ cm_list[cm_used] = handler;
+ cm_list_extra[cm_used++] = extra;
+}
+
+void
+unreg_channel_mode_func(channel_mode_func_t handler)
+{
+ unsigned int i;
+ for (i=0; i<cm_used; i++) {
+ if(cm_list[i] == handler) break;
+ }
+ if (i == cm_used) return;
+ memmove(cm_list+i, cm_list+i+1, (cm_used-i-1)*sizeof(cm_list[0]));
+ cm_used--;
+}
+
+static void
+call_channel_mode_funcs(struct userNode *who, struct chanNode *channel, char **modes, unsigned int argc)
+{
+ unsigned int n;
+ for (n=0; n<cm_used; n++) {
+ cm_list[n](who, channel, modes, argc, cm_list_extra[n]);
+ }
+}
+