#include "exim.h"
-#ifndef MACRO_PREDEF
/*************************************************
void
tree_add_nonrecipient(uschar *s)
{
-tree_node *node = store_get(sizeof(tree_node) + Ustrlen(s));
+rmark rpoint = store_mark();
+tree_node *node = store_get(sizeof(tree_node) + Ustrlen(s), is_tainted(s));
Ustrcpy(node->name, s);
node->data.ptr = NULL;
-if (!tree_insertnode(&tree_nonrecipients, node)) store_reset(node);
+if (!tree_insertnode(&tree_nonrecipients, node)) store_reset(rpoint);
}
void
tree_add_duplicate(uschar *s, address_item *addr)
{
-tree_node *node = store_get(sizeof(tree_node) + Ustrlen(s));
+rmark rpoint = store_mark();
+tree_node *node = store_get(sizeof(tree_node) + Ustrlen(s), is_tainted(s));
Ustrcpy(node->name, s);
node->data.ptr = addr;
-if (!tree_insertnode(&tree_duplicates, node)) store_reset(node);
+if (!tree_insertnode(&tree_duplicates, node)) store_reset(rpoint);
}
void
tree_add_unusable(host_item *h)
{
+rmark rpoint = store_mark();
tree_node *node;
uschar s[256];
sprintf(CS s, "T:%.200s:%s", h->name, h->address);
-node = store_get(sizeof(tree_node) + Ustrlen(s));
+node = store_get(sizeof(tree_node) + Ustrlen(s),
+ is_tainted(h->name) || is_tainted(h->address));
Ustrcpy(node->name, s);
node->data.val = h->why;
if (h->status == hstatus_unusable_expired) node->data.val += 256;
-if (!tree_insertnode(&tree_unusable, node)) store_reset(node);
+if (!tree_insertnode(&tree_unusable, node)) store_reset(rpoint);
}
static void
write_tree(tree_node *p, FILE *f)
{
-fprintf(f, "%c%c %s\n", p->left ? 'Y':'N', p->right ? 'Y':'N', p->name);
-if (p->left) write_tree(p->left, f);
-if (p->right) write_tree(p->right, f);
+fprintf(f, "%c%c %s\n",
+ (p->left == NULL)? 'N':'Y', (p->right == NULL)? 'N':'Y', p->name);
+if (p->left != NULL) write_tree(p->left, f);
+if (p->right != NULL) write_tree(p->right, f);
}
/* This is the top-level function, with the same arguments. */
void
tree_write(tree_node *p, FILE *f)
{
-if (!p)
+if (p == NULL)
{
fprintf(f, "XX\n");
return;
}
-#endif
/* Deal with an empty tree */
-if (!p)
+if (p == NULL)
{
*treebase = node;
return TRUE;
/* Deal with climbing down the tree, exiting from the loop
when we reach a leaf. */
- q = c > 0 ? &p->right : &p->left;
+ q = (c > 0)? &(p->right) : &(p->left);
p = *q;
- if (!p) break;
+ if (p == NULL) break;
/* Save the address of the pointer to the last node en route
which has a non-zero balance factor. */
next node after it along the route. */
s = *t;
-r = Ustrcmp(node->name, s->name) > 0 ? s->right : s->left;
+r = (Ustrcmp(node->name, s->name) > 0)? s->right : s->left;
/* Adjust balance factors along the route from s to node. */
p = r;
while (p != node)
+ {
if (Ustrcmp(node->name, p->name) < 0)
{
p->balance = tree_lbal;
p->balance = tree_rbal;
p = p->right;
}
+ }
/* Now the World-Famous Balancing Act */
-a = Ustrcmp(node->name, s->name) < 0 ? tree_lbal : tree_rbal;
+a = (Ustrcmp(node->name, s->name) < 0)? tree_lbal : tree_rbal;
-if (s->balance == 0)
- s->balance = (uschar)a; /* The tree has grown higher */
-else if (s->balance != (uschar)a)
- s->balance = 0; /* It's become more balanced */
-else /* It's got out of balance */
+if (s->balance == 0) s->balance = (uschar)a; /* The tree has grown higher */
+ else if (s->balance != (uschar)a) s->balance = 0; /* It's become more balanced */
+else /* It's got out of balance */
{
/* Perform a single rotation */
{
if (a == tree_rbal)
{
- if (!r->left) return TRUE; /* Bail out if tree corrupt */
+ if (r->left == NULL) return TRUE; /* Bail out if tree corrupt */
p = r->left;
r->left = p->right;
p->right = r;
}
else
{
- if (!r->right) return TRUE; /* Bail out if tree corrupt */
+ if (r->right == NULL) return TRUE; /* Bail out if tree corrupt */
p = r->right;
r->right = p->left;
p->left = r;
p->right = s;
}
- s->balance = p->balance == (uschar)a ? (uschar)(a^tree_bmask) : 0;
- r->balance = p->balance == (uschar)(a^tree_bmask) ? (uschar)a : 0;
+ s->balance = (p->balance == (uschar)a)? (uschar)(a^tree_bmask) : 0;
+ r->balance = (p->balance == (uschar)(a^tree_bmask))? (uschar)a : 0;
p->balance = 0;
}
tree_node *
tree_search(tree_node *p, const uschar *name)
{
-int c;
-for ( ; p; p = c < 0 ? p->left : p->right)
- if ((c = Ustrcmp(name, p->name)) == 0)
- return p;
+while (p)
+ {
+ int c = Ustrcmp(name, p->name);
+ if (c == 0) return p;
+ p = c < 0 ? p->left : p->right;
+ }
return NULL;
}
-#ifndef MACRO_PREDEF
/*************************************************
* Walk tree recursively and execute function *
tree_walk(p->right, f, ctx);
}
-#endif
+
+
+/* Add a node to a tree, ignoring possibility of duplicates */
+
+static void
+tree_add_var(uschar * name, uschar * val, void * ctx)
+{
+tree_node ** root = ctx;
+tree_node * node = store_get(sizeof(tree_node) + Ustrlen(name), is_tainted(name));
+Ustrcpy(node->name, name);
+node->data.ptr = val;
+(void) tree_insertnode(root, node);
+}
+
+/* Duplicate a tree */
+
+void
+tree_dup(tree_node ** dstp, tree_node * src)
+{
+tree_walk(src, tree_add_var, dstp);
+}
+
+
/* End of tree.c */