コード例 #1
0
ファイル: gsklog.c プロジェクト: davebenson/gsk
static FILE *
log_file_maybe_open (const char *filename, const char *mode)
{
  FILE *fp;
  if (filename_to_FILE == NULL)
    filename_to_FILE = g_hash_table_new (g_str_hash, g_str_equal);
  if (g_hash_table_lookup_extended (filename_to_FILE, filename, NULL, (gpointer *) &fp))
    return fp;
  fp = fopen (filename, mode);
  if (fp != NULL)
    setlinebuf (fp);
  g_hash_table_insert (filename_to_FILE, g_strdup (filename), fp);
  return fp;
}
コード例 #2
0
static void
add_event (ComponentEventInfo *cei, const GncGUID *entity,
           QofEventId event_mask, gboolean or_in)
{
    GHashTable *hash;

    if (!cei || !cei->entity_events || !entity)
        return;

    hash = cei->entity_events;

    if (event_mask == 0)
    {
        gpointer key;
        gpointer value;

        if (or_in)
            return;

        if (g_hash_table_lookup_extended (hash, entity, &key, &value))
        {
            g_hash_table_remove (hash, entity);
            guid_free (key);
            g_free (value);
        }
    }
    else
    {
        EventInfo *ei;

        ei = g_hash_table_lookup (hash, entity);
        if (ei == NULL)
        {
            GncGUID *key;

            key = guid_malloc ();
            *key = *entity;

            ei = g_new (EventInfo, 1);
            ei->event_mask = 0;

            g_hash_table_insert (hash, key, ei);
        }

        if (or_in)
            ei->event_mask |= event_mask;
        else
            ei->event_mask = event_mask;
    }
}
コード例 #3
0
static void
plugin_if_maintoolbar_goto_frame(gconstpointer user_data)
{
    if ( user_data != NULL )
    {
        GHashTable * dataSet = (GHashTable *) user_data;
        gpointer framenr;
        if ( g_hash_table_lookup_extended(dataSet, "frame_nr", NULL, &framenr ) )
        {
            if ( GPOINTER_TO_UINT(framenr) != 0 )
                cf_goto_frame(&cfile, GPOINTER_TO_UINT(framenr));
        }
    }
}
コード例 #4
0
Value*
ResourceDictionary::Get (const char *key, bool *exists)
{
	Value *v = NULL;
	gpointer orig_key;

	*exists = g_hash_table_lookup_extended (hash, key,
						&orig_key, (gpointer*)&v);

	if (!*exists)
		v = GetFromMergedDictionaries (key, exists);

	return v;
}
コード例 #5
0
ファイル: perwindow.c プロジェクト: Bad-ptr/kbdd
GROUP_TYPE
_kbdd_perwindow_get_prev(WINDOW_TYPE win)
{
    assert( gStorage != NULL );
    dbg("getprev %u", (uint32_t)win);
    GROUP_TYPE group = 0;
    assert(gStorage != NULL);
    gpointer key = NULL;
    gpointer value = NULL;
    gpointer pWindow = GUINT_TO_POINTER(win);
    if ( g_hash_table_lookup_extended(gStorage, pWindow, &key, &value) )
    {
        group = (GROUP_TYPE)((GPOINTER_TO_UINT(value)>>8) & 0xFF );
    }
コード例 #6
0
ファイル: core.c プロジェクト: LoongWin/libvmi
status_t
vmi_init_custom(
    vmi_instance_t *vmi,
    uint32_t flags,
    vmi_config_t config)
{
    status_t ret = VMI_FAILURE;
    uint32_t config_mode = flags & 0xFF000000;

    if (NULL == config) {
        config_mode |= VMI_CONFIG_NONE;
    }

    if (VMI_CONFIG_GLOBAL_FILE_ENTRY == config_mode) {

        ret = vmi_init(vmi, flags, (char *)config);
        goto _done;

    } else if (VMI_CONFIG_GHASHTABLE == config_mode) {

        char *name = NULL;
        uint64_t domid = VMI_INVALID_DOMID;
        GHashTable *configtbl = (GHashTable *)config;
        gpointer idptr = NULL;

        name = (char *)g_hash_table_lookup(configtbl, "name");
        if(g_hash_table_lookup_extended(configtbl, "domid", NULL, &idptr)) {
            domid = *(uint64_t *)idptr;
        }

        if (name != NULL && domid != VMI_INVALID_DOMID) {
            errprint("--specifying both the name and domid is not supported\n");
        } else if (name != NULL) {
            ret = vmi_init_private(vmi, flags, VMI_INVALID_DOMID, name, config);
        } else if (domid != VMI_INVALID_DOMID) {
            ret = vmi_init_private(vmi, flags, domid, NULL, config);
        } else {
            errprint("--you need to specify either the name or the domid\n");
        }

        goto _done;

    } else {
        errprint("Custom configuration input type not defined!\n");
    }

_done:
    return ret;
}
コード例 #7
0
static void fp_calltree_leaves(struct btp_strbuf *buffer, GList *insns,
        uintptr_t begin, uintptr_t end, GHashTable *call_graph, GHashTable *plt)
{
    unsigned iterations_allowed = call_graph_iteration_limit;
    GHashTable *visited = g_hash_table_new_full(g_int64_hash, g_int64_equal, free, NULL);
    GList *queue = g_list_append(NULL, addr_alloc(begin));
    GList *it, *sym = NULL;

    while (queue != NULL && iterations_allowed)
    {
        /* Pop one element */
        it = g_list_first(queue);
        queue = g_list_remove_link(queue, it);
        uintptr_t *key = (uintptr_t*)(it->data);
        /* uintptr_t addr = *key; */
        g_list_free(it);
        iterations_allowed--;

        /* Check if it is not already visited */
        if (g_hash_table_lookup_extended(visited, key, NULL, NULL))
        {
            free(key);
            continue;
        }
        g_hash_table_insert(visited, key, key);

        /* Lookup callees */
        GList *callees = g_hash_table_lookup(call_graph, key);

        /* If callee is PLT, add the corresponding symbols, otherwise
         * extend the worklist */
        for (it = callees; it != NULL; it = g_list_next(it))
        {
            char *s = g_hash_table_lookup(plt, it->data);
            if (s && !g_list_find_custom(sym, s, (GCompareFunc)strcmp))
            {
                sym = g_list_insert_sorted(sym, s, (GCompareFunc)strcmp);
            }
            else if (s == NULL)
            {
                queue = g_list_append(queue, addr_alloc(*(uintptr_t*)(it->data)));
            }
        }
    }
    g_hash_table_destroy(visited);
    list_free_with_free(queue);

    fingerprint_add_list(buffer, "calltree_leaves", sym);
}
static void
add_element_used (InsanityGstPipelineTest * ptest, GstElement * element)
{
  GstElementFactory *factory;
  const char *factory_name;
  char label[32], *element_name;
  GValue string_value = { 0 };
  GstElement *parent;

  /* Only add once */
  element_name = gst_element_get_name (element);
  if (g_hash_table_lookup_extended (ptest->priv->elements_used, element_name,
          NULL, NULL)) {
    g_free (element_name);
    return;
  }
  g_hash_table_insert (ptest->priv->elements_used, g_strdup (element_name),
      NULL);

  ptest->priv->element_count++;
  g_value_init (&string_value, G_TYPE_STRING);

  factory = gst_element_get_factory (element);
  factory_name =
      factory ? gst_element_factory_get_metadata (factory,
      GST_ELEMENT_METADATA_LONGNAME) : "(no factory)";

  g_value_take_string (&string_value, element_name);
  snprintf (label, sizeof (label), "elements-used.%u.name",
      ptest->priv->element_count);
  insanity_test_set_extra_info (INSANITY_TEST (ptest), label, &string_value);
  g_value_reset (&string_value);

  g_value_set_string (&string_value, factory_name);
  snprintf (label, sizeof (label), "elements-used.%u.factory",
      ptest->priv->element_count);
  insanity_test_set_extra_info (INSANITY_TEST (ptest), label, &string_value);
  g_value_reset (&string_value);

  parent = GST_ELEMENT (gst_element_get_parent (element));
  if (parent) {
    g_value_take_string (&string_value, gst_element_get_name (parent));
    snprintf (label, sizeof (label), "elements-used.%u.parent",
        ptest->priv->element_count);
    insanity_test_set_extra_info (INSANITY_TEST (ptest), label, &string_value);
    g_value_reset (&string_value);
    gst_object_unref (parent);
  }
}
コード例 #9
0
ファイル: fragment-util.c プロジェクト: GNOME/gupnp-av
static GList *
get_toplevel_changes (xmlNodePtr current_node,
                      xmlNodePtr new_node)
{
        xmlAttrPtr attribute;
        GHashTable *current_attributes = av_xml_util_get_attributes_map
                                        (current_node);
        GList *changes = NULL;
        const xmlChar *name = new_node->name;

        /* compare attributes */
        for (attribute = new_node->properties;
             attribute != NULL;
             attribute = attribute->next) {
                const xmlChar *value = NULL;
                const xmlChar *key = attribute->name;
                gboolean differs = FALSE;

                if (g_hash_table_lookup_extended (current_attributes,
                                                  key,
                                                  NULL,
                                                  (gpointer *) &value)) {
                        if (xmlStrcmp (value, attribute->children->content))
                                differs = TRUE;
                        g_hash_table_remove (current_attributes, key);
                } else
                        differs = TRUE;
                if (differs)
                        changes = g_list_prepend (changes,
                                                  node_diff_new (name,
                                                                 key));
        }

        if (g_hash_table_size (current_attributes) > 0) {
                GHashTableIter iter;
                xmlChar *key = NULL;

                g_hash_table_iter_init (&iter, current_attributes);
                while (g_hash_table_iter_next (&iter,
                                               (gpointer *) &key,
                                               NULL))
                        changes = g_list_prepend (changes, node_diff_new (name,
                                                                          key));
        }

        g_hash_table_unref (current_attributes);

        return changes;
}
コード例 #10
0
static int
key_binding(PianoKeyboard *pk, const char *key)
{
	gpointer notused, note;
	gboolean found;

	assert(pk->key_bindings != NULL);

	found = g_hash_table_lookup_extended(pk->key_bindings, key, &notused, &note);

	if (!found)
		return -1;

	return (intptr_t)note;
}
コード例 #11
0
ファイル: monodiet.c プロジェクト: ANahr/mono
static void
add_field (MonoClassField *field) {
	MonoClass *k;
	MonoCustomAttrInfo* cattrs;
	gpointer val = NULL, oldkey = NULL;

	if (g_hash_table_lookup_extended (field_table, field, &oldkey, &val))
		return;
	g_hash_table_insert (field_table, field, NULL);
	add_type (field->parent);
	k = mono_class_from_mono_type (field->type);
	add_type (k);
	cattrs = mono_custom_attrs_from_field (field->parent, field);
	handle_cattrs (cattrs);
}
コード例 #12
0
ファイル: metadata.c プロジェクト: BestImageViewer/geeqie
static gboolean metadata_legacy_write(FileData *fd)
{
	gboolean success = FALSE;
	gchar *metadata_pathl;
	gpointer keywords;
	gpointer comment_l;
	gboolean have_keywords;
	gboolean have_comment;
	const gchar *comment;
	GList *orig_keywords = NULL;
	gchar *orig_comment = NULL;

	g_assert(fd->change && fd->change->dest);

	DEBUG_1("Saving comment: %s", fd->change->dest);

	if (!fd->modified_xmp) return TRUE;

	metadata_pathl = path_from_utf8(fd->change->dest);

	have_keywords = g_hash_table_lookup_extended(fd->modified_xmp, KEYWORD_KEY, NULL, &keywords);
	have_comment = g_hash_table_lookup_extended(fd->modified_xmp, COMMENT_KEY, NULL, &comment_l);
	comment = (have_comment && comment_l) ? ((GList *)comment_l)->data : NULL;

	if (!have_keywords || !have_comment) metadata_file_read(metadata_pathl, &orig_keywords, &orig_comment);

	success = metadata_file_write(metadata_pathl,
				      have_keywords ? (GList *)keywords : orig_keywords,
				      have_comment ? comment : orig_comment);

	g_free(metadata_pathl);
	g_free(orig_comment);
	string_list_free(orig_keywords);

	return success;
}
コード例 #13
0
void
_handler_directory_deleted(WildcardSourceDriver *self, const DirectoryMonitorEvent *event)
{
  gchar *key;
  DirectoryMonitor *monitor;
  gboolean found = g_hash_table_lookup_extended(self->directory_monitors, event->full_path,
                                                (gpointer *)&key, (gpointer *)&monitor);
  if (found)
    {
      msg_debug("Monitored directory is deleted", evt_tag_str("dir", event->full_path));
      g_hash_table_steal(self->directory_monitors, event->full_path);
      g_free(key);
      directory_monitor_schedule_destroy(monitor);
    }
}
コード例 #14
0
ファイル: bookmarks.c プロジェクト: ChingezKhan/gthumb
static void
my_remove (GHashTable    *hash_table,
	   gconstpointer  lookup_key)
{
	gpointer orig_key, value;

	if (g_hash_table_lookup_extended (hash_table,
					  lookup_key,
					  &orig_key,
					  &value)) {
		g_hash_table_remove (hash_table, lookup_key);
		g_free (orig_key);
		g_free (value);
	}
}
コード例 #15
0
ファイル: gconfsettingsbackend.c プロジェクト: BARGAN/gconf
static void
gconf_settings_backend_notified (GConfClient          *client,
                                 guint                 cnxn_id,
                                 GConfEntry           *entry,
                                 GConfSettingsBackend *gconf)
{
  if (g_hash_table_lookup_extended (gconf->priv->ignore_notifications, entry->key,
                                    NULL, NULL))
    {
      g_hash_table_remove (gconf->priv->ignore_notifications, entry->key);
      return;
    }

  g_settings_backend_changed (G_SETTINGS_BACKEND (gconf), entry->key, NULL);
}
コード例 #16
0
ファイル: uri_resolver.c プロジェクト: FreeWebOS/libpbnjson
char const *uri_resolver_add_document(UriResolver *u, char const *document)
{
	char const *orig_document = NULL;
	if (g_hash_table_lookup_extended(u->documents, document,
	                                 (gpointer *) &orig_document, NULL))
	{
		return orig_document;
	}

	GHashTable *fragments = g_hash_table_new_full(g_str_hash, g_str_equal,
	                                              g_free, _validator_release);
	char *new_document = g_strdup(document);
	g_hash_table_insert(u->documents, new_document, fragments);
	return new_document;
}
コード例 #17
0
ファイル: themes.c プロジェクト: x3ro/macirssi-irrsi
void theme_unregister_module(const char *module)
{
	gpointer key, value;

	if (default_formats == NULL)
		return; /* already uninitialized */

	if (!g_hash_table_lookup_extended(default_formats, module, &key, &value))
		return;

	g_hash_table_remove(default_formats, key);
	g_free(key);

	themes_remove_module(module);
}
コード例 #18
0
ファイル: themes.c プロジェクト: x3ro/macirssi-irrsi
void theme_set_default_abstract(const char *key, const char *value)
{
	gpointer oldkey, oldvalue;

	if (g_hash_table_lookup_extended(internal_theme->abstracts, key,
					 &oldkey, &oldvalue)) {
		/* new values override old ones */
		g_hash_table_remove(internal_theme->abstracts, oldkey);
		g_free(oldkey);
		g_free(oldvalue);
	}

	g_hash_table_insert(internal_theme->abstracts,
			    g_strdup(key), g_strdup(value));
}
コード例 #19
0
/* Returns FALSE if the component name already exists */
gboolean
jingle_transport_google_set_component_name (
    GabbleJingleTransportGoogle *transport,
    const gchar *name, guint component_id)
{
  GabbleJingleTransportGooglePrivate *priv = transport->priv;

  if (g_hash_table_lookup_extended (priv->component_names, name, NULL, NULL))
      return FALSE;

  g_hash_table_insert (priv->component_names, g_strdup (name),
      GINT_TO_POINTER (component_id));

  return TRUE;
}
コード例 #20
0
ファイル: mail-vfolder.c プロジェクト: jdapena/evolution
static void
store_folder_renamed_cb (CamelStore *store,
                         const gchar *old_name,
                         CamelFolderInfo *info)
{
	EFilterRule *rule;
	gchar *user;

	gpointer key, folder;

	/* This should be more-or-less thread-safe */

	d(printf("Folder renamed to '%s' from '%s'\n", info->full_name, old_name));

	/* Folder is already renamed? */
	G_LOCK (vfolder);
	d(printf("Changing folder name in hash table to '%s'\n", info->full_name));
	if (g_hash_table_lookup_extended (vfolder_hash, old_name, &key, &folder)) {
		const gchar *config_dir;

		g_hash_table_remove (vfolder_hash, key);
		g_free (key);
		g_hash_table_insert (vfolder_hash, g_strdup (info->full_name), folder);

		rule = e_rule_context_find_rule ((ERuleContext *) context, old_name, NULL);
		if (!rule) {
			G_UNLOCK (vfolder);
			g_warning ("Rule shouldn't be NULL\n");
			return;
		}

		g_signal_handlers_disconnect_matched (
			rule, G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
			0, 0, NULL, rule_changed, folder);
		e_filter_rule_set_name (rule, info->full_name);
		g_signal_connect (rule, "changed", G_CALLBACK(rule_changed), folder);

		config_dir = mail_session_get_config_dir ();
		user = g_build_filename (config_dir, "vfolders.xml", NULL);
		e_rule_context_save ((ERuleContext *) context, user);
		g_free (user);

		G_UNLOCK (vfolder);
	} else {
		G_UNLOCK (vfolder);
		g_warning("couldn't find a vfolder rule in our table? %s", info->full_name);
	}
}
コード例 #21
0
ファイル: filter.c プロジェクト: nshi/falcon
gboolean falcon_filter_register(gboolean is_dir, const gchar *pattern,
                                falcon_filter_func func)
{
	GRegex *regex = NULL;
	GRegex *key = NULL;
	GSList *list = NULL;
	falcon_filter_t *value = NULL;

	if (!pattern) {
		g_warning(_("Failed to register filter with no pattern."));
		return FALSE;
	}

	regex = falcon_filter_regex_new(pattern);
	if (!regex)
		return FALSE;

	g_mutex_lock(lock);
	if (!registry) {
		g_critical(_("Filter registry uninitialized."
		             " Failed to register filter with pattern %s"), pattern);
		g_mutex_unlock(lock);
		return FALSE;
	}

	if (!g_hash_table_lookup_extended(registry, regex, (gpointer *)&key,
	                                  (gpointer *)&list)) {
		g_regex_ref(regex);
		key = regex;
	}

	value = g_new0(falcon_filter_t, 1);
	value->is_dir = is_dir;
	value->func = func;

	if (g_slist_find_custom(list, &value, falcon_filter_compare)) {
		g_free(value);
		g_mutex_unlock(lock);
		return FALSE;
	}

	list = g_slist_append(list, value);
	g_hash_table_insert(registry, key, list);

	g_regex_unref(regex);
	g_mutex_unlock(lock);
	return TRUE;
}
コード例 #22
0
ファイル: xml-cache.c プロジェクト: BARGAN/gconf
static void
safe_g_hash_table_insert(GHashTable* ht, gpointer key, gpointer value)
{
  gpointer oldkey = NULL, oldval = NULL;

  if (g_hash_table_lookup_extended(ht, key, &oldkey, &oldval))
    {
      gconf_log(GCL_WARNING, "Hash key `%s' is already in the table!",
                (gchar*)key);
      return;
    }
  else
    {
      g_hash_table_insert(ht, key, value);
    }
}
コード例 #23
0
ファイル: textbuffer-view.c プロジェクト: irssi-import/cuix
/* Set a bookmark in view */
void textbuffer_view_set_bookmark(TEXT_BUFFER_VIEW_REC *view,
				  const char *name, LINE_REC *line)
{
	gpointer key, value;

	g_return_if_fail(view != NULL);
	g_return_if_fail(name != NULL);

	if (g_hash_table_lookup_extended(view->bookmarks, name,
					 &key, &value)) {
		g_hash_table_remove(view->bookmarks, key);
                g_free(key);
	}

	g_hash_table_insert(view->bookmarks, g_strdup(name), line);
}
コード例 #24
0
ファイル: gui-printtext.c プロジェクト: svn2github/irssi
void gui_register_indent_func(const char *name, INDENT_FUNC func)
{
	gpointer key, value;
        GSList *list;

	if (g_hash_table_lookup_extended(indent_functions, name, &key, &value)) {
                list = value;
		g_hash_table_remove(indent_functions, key);
	} else {
		key = g_strdup(name);
                list = NULL;
	}

	list = g_slist_append(list, (void *) func);
	g_hash_table_insert(indent_functions, key, list);
}
コード例 #25
0
ファイル: hive.c プロジェクト: nysan/buildrump.sh
void register_connection(struct bufferevent *bev, int bus_id,
                         uint32_t protocol, uint32_t resource) {
    int32_t result = -1;
    gpointer key = GINT_TO_POINTER(resource),
             value = GINT_TO_POINTER(bus_id);
    if (protocol < 2 &&
            resource > 0 && resource <= UINT16_MAX &&
            !g_hash_table_lookup_extended(
                hive_table[protocol], key, NULL, NULL)) {
        // so there is no entry for that resource, create one
        g_hash_table_insert(hive_table[protocol], key, value);
        result = 0;
    }
    ERR("registered %u/%u for %d\n", protocol, resource, bus_id);
    reply_hive_bind(bev, result);
}
コード例 #26
0
ファイル: hive.c プロジェクト: nysan/buildrump.sh
static int lookup_bus(uint16_t dest_port, bool is_tcp) {
    int pass;
    int i_lookup = dest_port & 0xFFFF;
    uint32_t table_idx = is_tcp ? PROTOCOL_TCP : PROTOCOL_UDP;
    gpointer value = NULL, lookup = GINT_TO_POINTER(i_lookup);
    if (g_hash_table_lookup_extended(
                hive_table[table_idx], lookup, NULL, &value)) {
        pass = GPOINTER_TO_INT(value);
    } else {
        // connection unknown, drop the frame
        pass = DROP_FRAME;
    }

    ERR("%u goes to %d\n", dest_port, pass);
    return pass;
}
コード例 #27
0
gboolean scenemanager_can_draw_label_at(scenemanager_t* pSceneManager, const gchar* pszLabel, GdkPoint* unused_pScreenLocation, gint nFlags)
{
#ifdef ENABLE_NO_DUPLICATE_LABELS
	g_assert(pSceneManager != NULL);
	g_assert(pszLabel != NULL);

	// g_assert(pScreenLocation != NULL);
	// NOTE: ignore pScreenLocation for now
	gpointer pKey, pValue;

	// Can draw if it doesn't exist in table
	return (FALSE == g_hash_table_lookup_extended(pSceneManager->pLabelHash, pszLabel, &pKey, &pValue));
#else
	return TRUE;
#endif
}
コード例 #28
0
ファイル: mdt_residue_bonds.c プロジェクト: salilab/mdt
/* Add the named atom to the list of atoms in this residue */
static void add_residue_atom(struct mdt_residue_bonds *resbond, char *atom)
{
  if (!resbond->atom_names) {
    /* Note: we don't own the atom string pointers (the atom class
       struct does) so don't free them when we're done with the hash. */
    resbond->atom_names = g_hash_table_new(g_str_hash, g_str_equal);
    /* Add backbone N and C atoms at start of table for speed */
    g_hash_table_insert(resbond->atom_names, "N", GINT_TO_POINTER(ATOM_TYPE_N));
    g_hash_table_insert(resbond->atom_names, "C", GINT_TO_POINTER(ATOM_TYPE_C));
  }

  if (!g_hash_table_lookup_extended(resbond->atom_names, atom, NULL, NULL)) {
    int index = g_hash_table_size(resbond->atom_names);
    g_hash_table_insert(resbond->atom_names, atom, GINT_TO_POINTER(index));
  }
}
コード例 #29
0
/**
 * e_xmlhash_remove:
 * @hash: the #EXmlHash to remove an entry from
 * @key: the key of the entry to remove
 *
 * Remove the entry in @hash with key equal to @key, if it exists.
 **/
void
e_xmlhash_remove (EXmlHash *hash,
                  const gchar *key)
{
	gpointer orig_key;
	gpointer orig_value;

	g_return_if_fail (hash != NULL);
	g_return_if_fail (key != NULL);

	if (g_hash_table_lookup_extended (hash->objects, key, &orig_key, &orig_value)) {
		g_hash_table_remove (hash->objects, key);
		g_free (orig_key);
		g_free (orig_value);
	}
}
コード例 #30
0
ファイル: server-redirect.c プロジェクト: svn2github/irssi
void server_redirect_default(SERVER_REC *server, const char *command)
{
	REDIRECT_CMD_REC *cmdrec;
	REDIRECT_REC *rec;
	GSList *events, *list, *grouplist;
	char *event, *origkey;
	int last;

	g_return_if_fail(server != NULL);
	g_return_if_fail(command != NULL);

	if (server->cmdtable == NULL)
		return; /* not connected yet */

	cmdrec = g_hash_table_lookup(server->cmdtable, command);
	if (cmdrec == NULL) return;

	/* add all events used by command to eventtable and eventgrouptable */
	redirect_group++; grouplist = NULL; last = cmdrec->last;
	for (events = cmdrec->events; events != NULL; events = events->next) {
		event = events->data;

		if (g_hash_table_lookup_extended(server->eventtable, event,
						 (gpointer *) &origkey,
						 (gpointer *) &list)) {
			g_hash_table_remove(server->eventtable, origkey);
		} else {
			list = NULL;
			origkey = g_strdup(event);
		}

		rec = g_new0(REDIRECT_REC, 1);
		rec->argpos = -1;
		rec->name = g_strdup(event);
		rec->group = redirect_group;
		rec->last = last > 0;

		grouplist = g_slist_append(grouplist, g_strdup(event));
		list = g_slist_append(list, rec);
		g_hash_table_insert(server->eventtable, origkey, list);

		last--;
	}

	g_hash_table_insert(server->eventgrouptable,
			    GINT_TO_POINTER(redirect_group), grouplist);
}