diff -urNab dbmail-2.0cvs031804.acsi/dbmailtypes.h dbmail-2.0cvs031804/dbmailtypes.h
--- dbmail-2.0cvs031804.acsi/dbmailtypes.h	2004-03-01 05:48:06.000000000 -0500
+++ dbmail-2.0cvs031804/dbmailtypes.h	2004-03-23 16:33:56.000000000 -0500
@@ -139,7 +139,6 @@
 /* max length of number/dots part specifier */
 #define IMAP_MAX_PARTSPEC_LEN 100
 
-
 /* 
  * (imap) mailbox data type
  */
@@ -157,7 +156,7 @@
  * search data types
  */
 
-enum IMAP_SEARCH_TYPES { IST_SET, IST_SET_UID, IST_FLAG, IST_HDR, 
+enum IMAP_SEARCH_TYPES { IST_SET, IST_SET_UID, IST_FLAG, IST_SORT, IST_SORTHDR, IST_HDR, 
 			 IST_HDRDATE_BEFORE, IST_HDRDATE_ON, IST_HDRDATE_SINCE,
 			 IST_IDATE, IST_DATA_BODY, IST_DATA_TEXT, 
 			 IST_SIZE_LARGER, IST_SIZE_SMALLER, IST_SUBSEARCH_AND,
diff -urNab dbmail-2.0cvs031804.acsi/dbsearch.c dbmail-2.0cvs031804/dbsearch.c
--- dbmail-2.0cvs031804.acsi/dbsearch.c	2004-03-01 05:48:06.000000000 -0500
+++ dbmail-2.0cvs031804/dbsearch.c	2004-03-23 18:00:35.000000000 -0500
@@ -117,6 +117,14 @@
 		"AND msg.status < 2 "
 		"AND msg.unique_id <> '' "
 		"AND pms.%s", mb->uid, key);
+  } else if ( type == IST_SORT) {
+       snprintf(query, DEF_QUERYSIZE,
+                "SELECT msg.message_idnr FROM messages msg, physmessage pms "
+                "WHERE msg.mailbox_idnr = '%llu' "
+                "AND msg.physmessage_id = pms.id "
+                "AND msg.status < 2 "
+                "AND msg.unique_id <> '' "
+                "%s", mb->uid, key);
   } else {
        snprintf(query, DEF_QUERYSIZE, 
 		"SELECT message_idnr FROM messages "
@@ -131,6 +139,7 @@
 
   for (i = 0; i < db_num_rows(); i++) {
 	  uid = db_get_result_u64(i, 0);
+      if(type != IST_SORT) {
       msn = db_binary_search(mb->seq_list, mb->exists, uid);
 
       if (msn == -1 || msn >= setlen) {
@@ -139,12 +148,73 @@
 	  }
 
 	  rset[msn] = 1;
+      }else{
+	rset[i] = (i+1);
+      }
   }
 	  
   db_free_result();
   return 0;
 }
 
+void addto_btree_curr(sortitems_t ** root, char *str, int mid)
+{
+   sortitems_t *curr = (sortitems_t *)my_malloc(sizeof(sortitems_t));
+   curr->left = curr->right = NULL;
+   curr->mid = mid;
+   curr->ustr = (char *)my_malloc(sizeof(char)*(strlen(str)+8)); 
+   memset(curr->ustr, '\0', sizeof(char)*(strlen(str)+8));
+   sprintf(curr->ustr, "%s%06d", str,mid);
+   list_btree_insert(root, curr);
+}
+
+int db_sort_parsed(int *rset, unsigned int setlen,
+                     search_key_t *sk, mailbox_t *mb)
+{
+
+     unsigned int i;
+     int result, idx = 0;
+     mime_message_t msg;
+     struct mime_record *mr;
+     sortitems_t *root = NULL;
+
+     if (!sk->search)
+          return 0;
+
+     if (mb->exists != setlen)
+          return 1;
+
+     memset(rset, 0, sizeof(int)*setlen);
+     /*create a btree for all messages hdrfld */
+     for (i=0; i<setlen; i++)
+     {
+          memset(&msg, 0, sizeof(msg));
+
+          result = db_fetch_headers(mb->seq_list[i], &msg);
+          if (result != 0)
+               continue; /* ignore parse errors */
+
+          if (list_getstart(&msg.mimeheader))
+          {
+             mime_findfield(sk->hdrfld, &msg.mimeheader, &mr);
+             if (mr)
+              addto_btree_curr(&root, (char *)mr->value,(i+1));
+          }
+          if (list_getstart(&msg.rfcheader))
+          {
+             mime_findfield(sk->hdrfld, &msg.rfcheader, &mr);
+             if (mr)
+              addto_btree_curr(&root, (char *)mr->value,(i+1));
+          }
+          db_free_msg(&msg);
+    }
+
+    list_btree_traverse(root, &idx, rset); /* fill in the rset array with mid's */
+    list_btree_free(root); 
+
+    return 0;
+}
+
 int db_search_parsed(int *rset, unsigned int setlen, 
 		     search_key_t *sk, mailbox_t *mb)
 {
diff -urNab dbmail-2.0cvs031804.acsi/dbsearch.h dbmail-2.0cvs031804/dbsearch.h
--- dbmail-2.0cvs031804.acsi/dbsearch.h	2004-01-07 10:00:16.000000000 -0500
+++ dbmail-2.0cvs031804/dbsearch.h	2004-03-18 23:35:35.000000000 -0500
@@ -69,5 +69,7 @@
  */
 int db_search_parsed(int *rset, unsigned setlen, 
 		     search_key_t *sk, mailbox_t *mb);
+int db_sort_parsed(int *rset, unsigned setlen, 
+		     search_key_t *sk, mailbox_t *mb);
 
 #endif
diff -urNab dbmail-2.0cvs031804.acsi/imap4.c dbmail-2.0cvs031804/imap4.c
--- dbmail-2.0cvs031804.acsi/imap4.c	2004-03-18 16:09:57.000000000 -0500
+++ dbmail-2.0cvs031804/imap4.c	2004-03-18 17:03:39.000000000 -0500
@@ -69,7 +69,7 @@
   "select", "examine", "create", "delete", "rename", "subscribe", "unsubscribe", 
   "list", "lsub", "status", "append", 
   "check", "close", "expunge", "search", "fetch", "store", "copy", "uid",
-  "getquotaroot", "getquota", 
+  "sort", "getquotaroot", "getquota", 
   "setacl", "deleteacl", "getacl", "listrights", "myrights",
   "namespace",
   "***NOMORE***"
@@ -85,7 +85,7 @@
 			  IMAP_COMM_STATUS, IMAP_COMM_APPEND,
 			  IMAP_COMM_CHECK, IMAP_COMM_CLOSE, IMAP_COMM_EXPUNGE,
 			  IMAP_COMM_SEARCH, IMAP_COMM_FETCH, IMAP_COMM_STORE,
-			  IMAP_COMM_COPY, IMAP_COMM_UID,
+			  IMAP_COMM_COPY, IMAP_COMM_UID, IMAP_COMM_SORT,
 			  IMAP_COMM_GETQUOTAROOT, IMAP_COMM_GETQUOTA,
 			  IMAP_COMM_SETACL, IMAP_COMM_DELETEACL, IMAP_COMM_GETACL,
 			  IMAP_COMM_LISTRIGHTS, IMAP_COMM_MYRIGHTS,
@@ -100,7 +100,7 @@
   _ic_authenticate, _ic_login, 
   _ic_select, _ic_examine, _ic_create, _ic_delete, _ic_rename, 
   _ic_subscribe, _ic_unsubscribe, _ic_list, _ic_lsub, _ic_status, _ic_append, 
-  _ic_check, _ic_close, _ic_expunge, _ic_search, _ic_fetch, _ic_store, _ic_copy, _ic_uid,
+  _ic_check, _ic_close, _ic_expunge, _ic_search, _ic_fetch, _ic_store, _ic_copy, _ic_uid,_ic_sort,
   _ic_getquotaroot, _ic_getquota,
   _ic_setacl, _ic_deleteacl, _ic_getacl, _ic_listrights, _ic_myrights,
   _ic_namespace,
diff -urNab dbmail-2.0cvs031804.acsi/imap4.h dbmail-2.0cvs031804/imap4.h
--- dbmail-2.0cvs031804.acsi/imap4.h	2004-01-27 10:53:34.000000000 -0500
+++ dbmail-2.0cvs031804/imap4.h	2004-03-18 16:54:39.000000000 -0500
@@ -35,7 +35,7 @@
 
 #define IMAP_SERVER_VERSION VERSION
 //#define IMAP_CAPABILITY_STRING "IMAP4 IMAP4rev1 AUTH=LOGIN QUOTA"
-#define IMAP_CAPABILITY_STRING "IMAP4 IMAP4rev1 AUTH=LOGIN ACL NAMESPACE"
+#define IMAP_CAPABILITY_STRING "IMAP4 IMAP4rev1 AUTH=LOGIN ACL NAMESPACE SORT"
 #define IMAP_TIMEOUT_MSG "* BYE dbmail IMAP4 server signing off due to timeout\r\n"
 
 /* max number of BAD/NO responses */
diff -urNab dbmail-2.0cvs031804.acsi/imapcommands.c dbmail-2.0cvs031804/imapcommands.c
--- dbmail-2.0cvs031804.acsi/imapcommands.c	2004-03-18 16:09:57.000000000 -0500
+++ dbmail-2.0cvs031804/imapcommands.c	2004-03-20 12:24:26.000000000 -0500
@@ -1686,9 +1686,143 @@
 
 /* 
  * SELECTED-STATE COMMANDS 
- * check, close, expunge, search, fetch, store, copy, uid
+ * sort, check, close, expunge, search, fetch, store, copy, uid
  */
 
+
+/*
+ * _ic_sort()
+ * 
+ * sort and return sorted IDS for the selected mailbox
+ */
+int _ic_sort(char *tag, char **args, ClientInfo *ci)
+{
+  imap_userdata_t *ud = (imap_userdata_t*)ci->userData;
+  unsigned *result_set;
+  unsigned i;
+  int result=0,only_ascii=0,idx=0;
+  search_key_t sk;
+
+  if (ud->state != IMAPCS_SELECTED)
+    {
+      fprintf(ci->tx,"%s BAD SORT command received in invalid state\r\n", tag);
+      return 1;
+    }
+  
+  memset(&sk, 0, sizeof(sk));
+  list_init(&sk.sub_search);
+
+  if (!args[0])
+    {
+      fprintf(ci->tx,"%s BAD invalid arguments to SORT\r\n",tag);
+      return 1;
+    }
+
+  if (strcasecmp(args[0], "charset") == 0)
+    {
+      /* charset specified */
+      if (!args[1])
+	{
+	  fprintf(ci->tx,"%s BAD invalid argument list\r\n",tag);
+	  return 1;
+	}
+
+      if (strcasecmp(args[1], "us-ascii") != 0)
+	{
+	  fprintf(ci->tx,"%s NO specified charset is not supported\r\n",tag);
+	  return 0;
+	}
+
+      only_ascii = 1;
+      idx = 2;
+    }
+
+  /* parse the search keys */
+  while ( args[idx] && (result = build_imap_search(args, &sk.sub_search, &idx,1)) >= 0);
+
+  if (result == -2)
+    {
+      free_searchlist(&sk.sub_search);
+      fprintf(ci->tx, "* BYE server ran out of memory\r\n");
+      return -1;
+    }
+
+  if (result == -1)
+    {
+      free_searchlist(&sk.sub_search);
+      fprintf(ci->tx, "%s BAD syntax error in sort keys\r\n",tag);
+      return 1;
+    }
+
+  /* check if user has the right to search in this mailbox */
+  result = acl_has_right(ud->userid, ud->mailbox.uid, ACL_RIGHT_READ);
+  if (result < 0) {
+	  fprintf(ci->tx,"* BYE internal database error\r\n");
+	  free_searchlist(&sk.sub_search);
+	  return -1;
+  }
+  if (result == 0) {
+	  fprintf(ci->tx,"%s NO no permission to sort mailbox\r\n", tag);
+	  free_searchlist(&sk.sub_search);
+	  return 1;
+  }
+  
+  /* make it a top-level search key */
+  sk.type = IST_SUBSEARCH_AND;
+
+  /* allocate memory for result set */
+  result_set = (unsigned*)my_malloc(sizeof(unsigned) * ud->mailbox.exists);
+  if (!result_set)
+  {
+    free_searchlist(&sk.sub_search);
+    fprintf(ci->tx,"* NO server ran out of memory\r\n");
+    return -1;
+  }
+   
+  /* do i need this? */ 
+  for (i=0; i<ud->mailbox.exists; i++)
+	result_set[i] = (i+1);
+
+  /* now perform the search operations */
+  result = perform_imap_search(result_set, ud->mailbox.exists, &sk, &ud->mailbox,1);
+    
+  if (result < 0)
+  {
+    free_searchlist(&sk.sub_search);
+    my_free(result_set);
+    fprintf(ci->tx,"%s", (result == -1) ? 
+		  "* NO internal dbase error\r\n" :
+		  "* NO server ran out of memory\r\n");
+
+	  trace(TRACE_ERROR, "ic_sort(): fatal error [%d] from perform_imap_search()\n",result);
+	  return -1;
+	}
+
+  free_searchlist(&sk.sub_search);
+
+  if (result == 1)
+    {
+      fprintf(ci->tx,"* NO error synchronizing dbase\r\n");
+      return -1;
+    }
+      
+  /* ok, display results */
+  fprintf(ci->tx, "* SORT");
+
+  for (i=0; i<ud->mailbox.exists; i++)
+    {
+       /*trace(TRACE_INFO, "ic_sort(): i: %d, rs[i]: %d, mbuid[i]: %llu ", i, result_set[i], ud->mailbox.seq_list[i]); */
+       if (result_set[i])
+        fprintf(ci->tx, " %llu", imapcommands_use_uid ? ud->mailbox.seq_list[i] : (u64_t)result_set[i]);
+    }
+
+  fprintf(ci->tx,"\r\n");
+  my_free(result_set);
+      
+  fprintf(ci->tx,"%s OK SORT completed\r\n",tag);
+  return 0;
+}
+
 /*
  * _ic_check()
  * 
@@ -1890,7 +2024,7 @@
     }
 
   /* parse the search keys */
-  while ( args[idx] && (result = build_imap_search(args, &sk.sub_search, &idx)) >= 0);
+  while ( args[idx] && (result = build_imap_search(args, &sk.sub_search, &idx,0)) >= 0);
 
   if (result == -2)
     {
@@ -1955,7 +2089,7 @@
 	result_set[i] = 1;
 
       /* now perform the search operations */
-      result = perform_imap_search(result_set, ud->mailbox.exists, &sk, &ud->mailbox);
+      result = perform_imap_search(result_set, ud->mailbox.exists, &sk, &ud->mailbox,0);
     
       if (result < 0)
 	{
@@ -3681,6 +3815,8 @@
     result = _ic_store(tag, &args[1], ci);
   else if (strcasecmp(args[0], "search") == 0)
     result = _ic_search(tag, &args[1], ci);
+  else if (strcasecmp(args[0], "sort") == 0)
+    result = _ic_sort(tag, &args[1], ci);
   else
     {
       fprintf(ci->tx,"%s BAD invalid UID command\r\n",tag);
diff -urNab dbmail-2.0cvs031804.acsi/imapcommands.h dbmail-2.0cvs031804/imapcommands.h
--- dbmail-2.0cvs031804.acsi/imapcommands.h	2004-01-27 10:53:34.000000000 -0500
+++ dbmail-2.0cvs031804/imapcommands.h	2004-03-18 16:39:11.000000000 -0500
@@ -57,6 +57,7 @@
 int _ic_append(char *tag, char **args, ClientInfo *ci);
 
 /* selected-state commands */
+int _ic_sort(char *tag, char **args, ClientInfo *ci);
 int _ic_check(char *tag, char **args, ClientInfo *ci);
 int _ic_close(char *tag, char **args, ClientInfo *ci);
 int _ic_expunge(char *tag, char **args, ClientInfo *ci);
diff -urNab dbmail-2.0cvs031804.acsi/imaputil.c dbmail-2.0cvs031804/imaputil.c
--- dbmail-2.0cvs031804.acsi/imaputil.c	2004-01-27 10:53:34.000000000 -0500
+++ dbmail-2.0cvs031804/imaputil.c	2004-03-20 12:19:38.000000000 -0500
@@ -2326,7 +2326,7 @@
  *
  * returns -1 on syntax error, -2 on memory error; 0 on success, 1 if ')' has been encountered
  */
-int build_imap_search(char **search_keys, struct list *sl, int *idx)
+int build_imap_search(char **search_keys, struct list *sl, int *idx, int sorted)
 {
   search_key_t key;
   int result;
@@ -2336,7 +2336,63 @@
 
   memset(&key, 0, sizeof(key));
 
-  if (strcasecmp(search_keys[*idx], "all") == 0)
+  /* coming from _ic_sort */
+  if(sorted && (strcasecmp(search_keys[*idx], "arrival") == 0))
+    {
+      key.type = IST_SORT;
+      strncpy(key.search, "order by pms.internal_date", MAX_SEARCH_LEN);
+      (*idx)++;
+    }
+  else if(sorted && (strcasecmp(search_keys[*idx], "from") == 0))
+    {
+      key.type = IST_SORTHDR;
+      strncpy(key.hdrfld, "from", MIME_FIELD_MAX);
+      (*idx)++;
+    }
+  else if(sorted && (strcasecmp(search_keys[*idx], "subject") == 0))
+    {
+      key.type = IST_SORTHDR;
+      strncpy(key.hdrfld, "subject", MIME_FIELD_MAX);
+      (*idx)++;
+    }
+  else if(sorted && (strcasecmp(search_keys[*idx], "cc") == 0))
+    {
+      key.type = IST_SORTHDR;
+      strncpy(key.hdrfld, "cc", MIME_FIELD_MAX);
+      (*idx)++;
+    }
+  else if(sorted && (strcasecmp(search_keys[*idx], "to") == 0))
+    {
+      key.type = IST_SORTHDR;
+      strncpy(key.hdrfld, "to", MIME_FIELD_MAX);
+      (*idx)++;
+    }
+  else if(sorted && (strcasecmp(search_keys[*idx], "reverse") == 0))
+    {
+      /* TODO */ 
+      (*idx)++;
+    }
+  else if(sorted && (strcasecmp(search_keys[*idx], "size") == 0))
+    {
+      /* TODO */ 
+      (*idx)++;
+    }
+  else if(sorted && (strcasecmp(search_keys[*idx], "iso-8859-1") == 0))
+    {
+      /* TODO */ 
+      (*idx)++;
+    }
+  else if(sorted && (strcasecmp(search_keys[*idx], "date") == 0))
+    {
+      /* TODO */ 
+      (*idx)++;
+    }
+  else if(sorted && (strcasecmp(search_keys[*idx], "all") == 0))
+    {
+      /* TODO */ 
+      (*idx)++;
+    }
+  else if (strcasecmp(search_keys[*idx], "all") == 0)
     {
       key.type = IST_SET;
       strcpy(key.search, "1:*");
@@ -2682,7 +2738,7 @@
       key.type = IST_SUBSEARCH_NOT;
 
       (*idx)++;
-      if ((result = build_imap_search(search_keys, &key.sub_search, idx)) < 0)
+      if ((result = build_imap_search(search_keys, &key.sub_search, idx,sorted)) < 0)
 	{
 	  list_freelist(&key.sub_search.start);
 	  return result;
@@ -2700,13 +2756,13 @@
       key.type = IST_SUBSEARCH_OR;
 
       (*idx)++;
-      if ((result = build_imap_search(search_keys, &key.sub_search, idx)) < 0)
+      if ((result = build_imap_search(search_keys, &key.sub_search, idx,sorted)) < 0)
 	{
 	  list_freelist(&key.sub_search.start);
 	  return result;
 	}
 
-      if ((result = build_imap_search(search_keys, &key.sub_search, idx)) < 0)
+      if ((result = build_imap_search(search_keys, &key.sub_search, idx,sorted)) < 0)
 	{
 	  list_freelist(&key.sub_search.start);
 	  return result;
@@ -2725,7 +2781,7 @@
       key.type = IST_SUBSEARCH_AND;
 
       (*idx)++;
-      while ((result = build_imap_search(search_keys, &key.sub_search, idx)) == 0 
+      while ((result = build_imap_search(search_keys, &key.sub_search, idx,sorted)) == 0 
 	     && search_keys[*idx]) ;
 
       if (result < 0)
@@ -2772,7 +2828,7 @@
  * returns 0 on succes, -1 on dbase error, -2 on memory error, 1 if result set is too small
  * (new mail has been added to mailbox while searching, mailbox data out of sync)
  */
-int perform_imap_search(int *rset, int setlen, search_key_t *sk, mailbox_t *mb)
+int perform_imap_search(int *rset, int setlen, search_key_t *sk, mailbox_t *mb, int sorted)
 {
   search_key_t *subsk;
   struct element *el;
@@ -2799,6 +2855,18 @@
       build_uid_set(rset, setlen, sk->search, mb);
       break;
 
+    case IST_SORT:
+      result = db_search(rset, setlen, sk->search, mb, sk->type);
+      my_free(newset);
+      return 0;
+      break;
+
+    case IST_SORTHDR:
+      result = db_sort_parsed(rset, setlen, sk, mb);
+      my_free(newset);
+      return 0;
+      break;
+
     case IST_FLAG:
 	 result = db_search(rset, setlen, sk->search, mb, sk->type);
       if (result != 0)
@@ -2847,14 +2915,19 @@
 	    for (i=0; i<setlen; i++)
 	      newset[i] = 1;
 	      
-	  result = perform_imap_search(newset, setlen, subsk, mb);
+	  result = perform_imap_search(newset, setlen, subsk, mb, sorted);
 	  if (result < 0 || result == 1)
 	    {
 	      my_free(newset);
 	      return result;
 	    }
 
+	  if(!sorted)
 	  combine_sets(rset, newset, setlen, subtype);
+          else {
+	    for (i=0; i<setlen; i++)
+	      rset[i] = newset[i];
+          }
 
 	  el = el->nextnode;
 	}
diff -urNab dbmail-2.0cvs031804.acsi/imaputil.h dbmail-2.0cvs031804/imaputil.h
--- dbmail-2.0cvs031804.acsi/imaputil.h	2004-01-07 10:00:16.000000000 -0500
+++ dbmail-2.0cvs031804/imaputil.h	2004-03-18 16:43:18.000000000 -0500
@@ -82,8 +82,8 @@
 int quoted_string_out(FILE *outstream, const char *s);
 void send_data(FILE *to, MEM *from, int cnt);
 
-int build_imap_search(char **search_keys, struct list *sl, int *idx);
-int perform_imap_search(int *rset, int setlen, search_key_t *sk, mailbox_t *mb);
+int build_imap_search(char **search_keys, struct list *sl, int *idx, int sorted);
+int perform_imap_search(int *rset, int setlen, search_key_t *sk, mailbox_t *mb, int sorted);
 void free_searchlist(struct list *sl);
 
 void invert_set(int *set, int setlen);
diff -urNab dbmail-2.0cvs031804.acsi/list.c dbmail-2.0cvs031804/list.c
--- dbmail-2.0cvs031804.acsi/list.c	2004-03-09 04:47:09.000000000 -0500
+++ dbmail-2.0cvs031804/list.c	2004-03-23 17:58:49.000000000 -0500
@@ -234,3 +234,39 @@
       temp=temp->nextnode;
     }
 } 
+
+/* basic binary tree */
+void list_btree_insert(sortitems_t ** tree, sortitems_t * item) {
+   int val;
+   if(!(*tree)) {
+      *tree = item;
+      return;
+   }
+   val = strcmp(item->ustr,(*tree)->ustr);
+   if(val < 0)
+      list_btree_insert(&(*tree)->left, item);
+   else if(val > 0)
+      list_btree_insert(&(*tree)->right, item);
+}
+
+void list_btree_printout(sortitems_t * tree, int * i) {
+   if(tree->left) list_btree_printout(tree->left, i);
+   trace(TRACE_INFO, "list_btree_printout: i '%d' '%d', '%s'\n", *i, tree->mid, tree->ustr); (*i)++;
+   if(tree->right) list_btree_printout(tree->right, i);
+}
+
+void list_btree_traverse(sortitems_t * tree, int * i, int *rset) {
+   if(tree->left) list_btree_traverse(tree->left, i, rset);
+   trace(TRACE_DEBUG, "list_btree_traverse: i '%d' '%d', '%s'\n", *i, tree->mid, tree->ustr); 
+   rset[*i] = tree->mid;
+   (*i)++;
+   if(tree->right) list_btree_traverse(tree->right, i, rset);
+}
+
+void list_btree_free(sortitems_t * tree) {
+   if(tree->left) list_btree_free(tree->left);
+   my_free(tree->ustr);
+   if(tree->right) list_btree_free(tree->right);
+   else my_free(tree);
+}
+
diff -urNab dbmail-2.0cvs031804.acsi/list.h dbmail-2.0cvs031804/list.h
--- dbmail-2.0cvs031804.acsi/list.h	2004-03-09 04:47:09.000000000 -0500
+++ dbmail-2.0cvs031804/list.h	2004-03-23 17:59:19.000000000 -0500
@@ -66,4 +66,18 @@
  */
 struct element* dbmail_list_reverse(struct element *start);
 
+/* sort stuff */
+
+typedef struct _sortitems
+{
+  char *ustr;
+  unsigned int mid;
+  struct _sortitems * right, * left;
+} sortitems_t;
+
+void list_btree_insert(sortitems_t ** tree, sortitems_t * item);
+void list_btree_printout(sortitems_t * tree, int *i);
+void list_btree_traverse(sortitems_t * tree, int * i, int *rset);
+void list_btree_free(sortitems_t * tree);
+
 #endif 
