Example #1
0
static DirectNode *
tree_node_insert (DirectTree *tree,
                  DirectNode *node,
                  void       *key,
                  void       *value,
                  int        *inserted)
{
     int cmp;
     int old_balance;

     if (!node) {
          *inserted = 1;
          return tree_node_new (tree, key, value);
     }

     cmp = key - node->key;
     if (cmp == 0) {
          node->value = value;
          return node;
     }

     if (cmp < 0) {
          if (node->left) {
               old_balance = node->left->balance;
           node->left = tree_node_insert (tree, node->left,
                                              key, value, inserted);

               if ((old_balance != node->left->balance) && node->left->balance)
                   node->balance -= 1;
          }
          else {
               *inserted = 1;
               node->left = tree_node_new (tree, key, value);
               node->balance -= 1;
          }
     }
     else if (cmp > 0) {
          if (node->right) {
               old_balance = node->right->balance;
               node->right = tree_node_insert (tree, node->right,
                                               key, value, inserted);

               if ((old_balance != node->right->balance) && node->right->balance)
                    node->balance += 1;
          }
          else {
               *inserted = 1;
               node->right = tree_node_new (tree, key, value);
               node->balance += 1;
          }
     }

     if (*inserted && (node->balance < -1 || node->balance > 1))
          node = tree_node_balance (node);

     return node;
}
Example #2
0
static TreeNode *
create_node_for_file (FMTreeModelRoot *root, NemoFile *file)
{
	TreeNode *node;

	g_assert (get_node_from_file (root, file) == NULL);
	node = tree_node_new (file, root);
	g_hash_table_insert (root->file_to_node_map, node->file, node);
	return node;
}
Example #3
0
static void add_reg_key(struct regedit *regedit, struct tree_node *node,
			bool subkey)
{
	char *name;
	const char *msg;

	if (!subkey && !node->parent) {
		return;
	}

	msg = "Enter name of new key";
	if (subkey) {
		msg = "Enter name of new subkey";
	}
	dialog_input(regedit, &name, "New Key", msg);
	if (name) {
		WERROR rv;
		struct registry_key *new_key;
		struct tree_node *new_node;
		struct tree_node *list;
		struct tree_node *parent;

		if (subkey) {
			parent = node;
			list = node->child_head;
		} else {
			parent = node->parent;
			list = tree_node_first(node);
			SMB_ASSERT(list != NULL);
		}
		rv = reg_key_add_name(regedit, parent->key, name,
				      NULL, NULL, &new_key);
		if (W_ERROR_IS_OK(rv)) {
			/* The list of subkeys may not be present in
			   cache yet, so if not, don't bother allocating
			   a new node for the key. */
			if (list) {
				new_node = tree_node_new(parent, parent,
							 name, new_key);
				SMB_ASSERT(new_node);
				tree_node_append_last(list, new_node);
			}

			list = tree_node_first(node);
			tree_view_clear(regedit->keys);
			tree_view_update(regedit->keys, list);
		} else {
			dialog_notice(regedit, DIA_ALERT, "New Key",
				      "Failed to create key.");
		}
		talloc_free(name);
	}
}
/**
 * Create a new tree.
 *
 * @param peer A short peer id of the root of the tree.
 *
 * @return A newly allocated and initialized tunnel tree.
 */
struct MeshTunnelTree *
tree_new (GNUNET_PEER_Id peer)
{
  struct MeshTunnelTree *tree;

  tree = GNUNET_malloc (sizeof (struct MeshTunnelTree));
  tree->first_hops = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
  tree->root = tree_node_new (NULL, peer);
  tree->root->status = MESH_PEER_ROOT;

  if (1 == peer)
  {
    tree->me = tree->root;
  }

  return tree;
}
Example #5
0
/* load all available hives */
static struct tree_node *load_hives(TALLOC_CTX *mem_ctx,
				    struct registry_context *ctx)
{
	const char *hives[] = {
		"HKEY_CLASSES_ROOT",
		"HKEY_CURRENT_USER",
		"HKEY_LOCAL_MACHINE",
		"HKEY_PERFORMANCE_DATA",
		"HKEY_USERS",
		"HKEY_CURRENT_CONFIG",
		"HKEY_DYN_DATA",
		"HKEY_PERFORMANCE_TEXT",
		"HKEY_PERFORMANCE_NLSTEXT",
		NULL
	};
	struct tree_node *root, *prev, *node;
	struct registry_key *key;
	WERROR rv;
	size_t i;

	root = NULL;
	prev = NULL;

	for (i = 0; hives[i] != NULL; ++i) {
		rv = reg_get_predefined_key_by_name(ctx, hives[i], &key);
		if (!W_ERROR_IS_OK(rv)) {
			continue;
		}

		node = tree_node_new(mem_ctx, NULL, hives[i], key);
		if (node == NULL) {
			return NULL;
		}

		if (root == NULL) {
			root = node;
		}
		if (prev) {
			tree_node_append(prev, node);
		}
		prev = node;
	}

	return root;
}
Example #6
0
static WatchTree *
tree_node_get_child (WatchTree       *node,
                     const StringRef *ref,
                     gboolean         create)
{
  WatchTree *child;

  if (!node->children)
    node->children = g_hash_table_new_full (string_ref_hash, string_ref_equal, NULL, tree_node_free);

  child = g_hash_table_lookup (node->children, ref);

  if (!child && create)
    {
      child = tree_node_new (node->full_path, ref);

      g_hash_table_add (node->children, child);
    }

  return child;
}
/**
 * Integrate a stand alone path into the tunnel tree.
 * If the peer toward which the new path is already in the tree, the peer
 * and its children will be maked as disconnected and the callback
 * will be called on each one of them. They will be maked as online only after
 * receiving a PATH ACK for the new path for each one of them, so the caller
 * should take care of sending a new CREATE PATH message for each disconnected
 * peer.
 *
 * @param t Tunnel where to add the new path.
 * @param p Path to be integrated.
 * @param cb Callback to use to notify about peers temporarily disconnecting.
 * @param cbcls Closure for cb.
 *
 * @return GNUNET_OK in case of success.
 *         GNUNET_SYSERR in case of error.
 *
 * TODO: optimize
 * - go backwards on path looking for each peer in the present tree
 * - do not disconnect peers until new path is created & connected
 */
int
tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p,
               MeshTreeCallback cb, void *cbcls)
{
  struct MeshTunnelTreeNode *parent;
  struct MeshTunnelTreeNode *oldnode;
  struct MeshTunnelTreeNode *n;
  struct MeshTunnelTreeNode *c;
  struct GNUNET_PeerIdentity id;
  int me;
  unsigned int i;

#if MESH_TREE_DEBUG
  GNUNET_PEER_resolve (p->peers[p->length - 1], &id);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "tree:   Adding path [%u] towards peer %s.\n", p->length,
              GNUNET_i2s (&id));
#endif

  GNUNET_assert (0 != p->length);
  parent = n = t->root;
  if (n->peer != p->peers[0])
  {
    GNUNET_break (0);
    return GNUNET_SYSERR;
  }
  if (1 == p->length)
    return GNUNET_OK;
  oldnode = tree_del_path (t, p->peers[p->length - 1], cb, cbcls);
  /* Look for the first node that is not already present in the tree
   *
   * Assuming that the tree is somewhat balanced, O(log n * log N).
   * - Length of the path is expected to be log N (size of whole network).
   * - Each level of the tree is expected to have log n children (size of tree).
   */
  me = t->root->peer == 1 ? 0 : -1;
  for (i = 1; i < p->length; i++)
  {
#if MESH_TREE_DEBUG
    GNUNET_PEER_resolve (p->peers[i], &id);
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree:   Looking for peer %s.\n",
                GNUNET_i2s (&id));
#endif
    parent = n;
    if (p->peers[i] == 1)
      me = i;
    for (c = n->children_head; NULL != c; c = c->next)
    {
      if (c->peer == p->peers[i])
      {
#if MESH_TREE_DEBUG
        GNUNET_PEER_resolve (parent->peer, &id);
        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                    "tree:   Found in children of %s.\n", GNUNET_i2s (&id));
#endif
        n = c;
        break;
      }
    }
    /*  If we couldn't find a child equal to path[i], we have reached the end
     * of the common path. */
    if (parent == n)
      break;
  }
#if MESH_TREE_DEBUG
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree:   All childen visited.\n");
#endif
  /* Add the rest of the path as a branch from parent. */
  while (i < p->length)
  {
#if MESH_TREE_DEBUG
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree:   Adding peer %u to %u.\n",
                p->peers[i], parent->peer);
    GNUNET_PEER_resolve (p->peers[i], &id);
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree:   Adding peer %s.\n",
                GNUNET_i2s (&id));
    GNUNET_PEER_resolve (parent->peer, &id);
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree:            to %s.\n",
                GNUNET_i2s (&id));
#endif

    if (i == p->length - 1 && NULL != oldnode)
    {
#if MESH_TREE_DEBUG
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                  "tree:   Putting old node into place.\n");
#endif
      oldnode->parent = parent;
      GNUNET_CONTAINER_DLL_insert (parent->children_head, parent->children_tail,
                                   oldnode);
      tree_node_update_first_hops (t, oldnode, NULL);
      n = oldnode;
    }
    else
    {
#if MESH_TREE_DEBUG
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree:   Creating new node.\n");
#endif
      n = tree_node_new (parent, p->peers[i]);
      n->status = MESH_PEER_RELAY;
    }
    if (n->peer == 1)
    {
      t->me = n;
      me = i;
    }
    i++;
    parent = n;
  }
  n->status = MESH_PEER_SEARCHING;

  GNUNET_break (-1 != me);

  /* Add info about first hop into hashmap. */
  if (-1 != me && me < p->length - 1)
  {
#if MESH_TREE_DEBUG
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "MESH:   finding first hop (own pos %d/%u)\n", me,
                p->length - 1);
#endif
    GNUNET_PEER_resolve (p->peers[me + 1], &id);
    tree_update_first_hops (t, p->peers[me + 1], &id);
  }
#if MESH_TREE_DEBUG
  else
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "MESH:   was last in path, not updating first hops (%d/%u)\n",
                me, p->length - 1);
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree:   New node added.\n");
#endif
  if (NULL == t->me)
    t->me = tree_find_peer (t, 1);
  return GNUNET_OK;
}
static void add_reg_key(struct regedit *regedit, struct tree_node *node,
			bool subkey)
{
	const char *name;
	const char *msg;

	if (!subkey && tree_node_is_top_level(node)) {
		return;
	}

	msg = "Enter name of new key";
	if (subkey) {
		msg = "Enter name of new subkey";
	}
	dialog_input(regedit, &name, "New Key", msg);
	if (name) {
		WERROR rv;
		struct registry_key *new_key;
		struct tree_node *new_node;
		struct tree_node *list;
		struct tree_node *parent;

		if (subkey) {
			parent = node;
			list = node->child_head;
		} else {
			parent = node->parent;
			list = tree_node_first(node);
			SMB_ASSERT(list != NULL);
		}
		rv = reg_key_add_name(regedit, parent->key, name,
				      NULL, NULL, &new_key);
		if (W_ERROR_IS_OK(rv)) {
			/* The list of subkeys may not be present in
			   cache yet, so if not, don't bother allocating
			   a new node for the key. */
			if (list) {
				new_node = tree_node_new(parent, parent,
							 name, new_key);
				SMB_ASSERT(new_node);
				tree_node_insert_sorted(list, new_node);
			} else {
				/* Reopen the parent key to make sure the
				   new subkey will be noticed. */
				tree_node_reopen_key(regedit->registry_context,
						     parent);
			}

			list = tree_node_first(node);
			tree_view_clear(regedit->keys);
			tree_view_update(regedit->keys, list);
			if (!subkey) {
				node = new_node;
			}
			tree_view_set_current_node(regedit->keys, node);
			load_values(regedit);
		} else {
			msg = get_friendly_werror_msg(rv);
			dialog_notice(regedit, DIA_ALERT, "New Key",
				      "Failed to create key: %s", msg);
		}
		talloc_free(discard_const(name));
	}
}