How does this Binary Search Tree look?
In tree_find and tree_find_min [edit: and even in tree_insert] you're not really gaining anything from using recursion. For example, I think tree_find_min would probably be clearer something like:

tree_position tree_find_min( search_tree tree )
{
   if ( tree == NULL )
      return NULL;
   while (tree-&gt;left != NULL)
       tree = tree-&gt;left;
   return tree;
}


As a side-benefit, this may also be faster with some compilers. In code like:

 HATE_DATA *hatedata;

 /* ... */

 hatedata = (HATE_DATA * ) malloc( sizeof( HATE_DATA ) );


I'd change it to look more like:

 hatedata = malloc(sizeof(*hatedata));


The cast accomplishes nothing useful in C, and can cover up the bug of forgetting to #include &lt;stdlib.h&gt; to get the proper prototype for malloc. Using sizeof(*hatedata) instead of sizeof(HATE_DATA) means that changing the type only requires changing it in one place (where you've defined the variable), instead of everywhere you've done an allocation.