diff -Nru xmail-1.20.vanilla/MainLinux.cpp xmail-1.20.mt/MainLinux.cpp
--- xmail-1.20.vanilla/MainLinux.cpp	2004-05-31 11:47:30.000000000 -0700
+++ xmail-1.20.mt/MainLinux.cpp	2004-05-31 11:52:05.000000000 -0700
@@ -32,6 +32,7 @@
 #include "QueueUtils.h"
 #include "AppDefines.h"
 #include "MailSvr.h"
+#include "memtracer.h"
 
 #define RUNNING_PIDS_DIR            "/var/run"
 #define DEVNULL                     "/dev/null"
@@ -265,8 +266,20 @@
 ///////////////////////////////////////////////////////////////////////////////
 	MnSavePID(pszPidFile);
 
+///////////////////////////////////////////////////////////////////////////////
+//  Trace leaks
+///////////////////////////////////////////////////////////////////////////////
+	memckpoint_t MCI;
+
+	mtr_init();
+	mtr_start(&MCI);
+
+
 	int iServerResult = SvrMain(iArgCount, pszArgs);
 
+
+	mtr_stop(&MCI, "/tmp/XMail.memleaks");
+
 ///////////////////////////////////////////////////////////////////////////////
 //  Remove PID file
 ///////////////////////////////////////////////////////////////////////////////
diff -Nru xmail-1.20.vanilla/Makefile.lnx xmail-1.20.mt/Makefile.lnx
--- xmail-1.20.vanilla/Makefile.lnx	2004-05-31 11:47:30.000000000 -0700
+++ xmail-1.20.mt/Makefile.lnx	2004-05-31 11:53:07.000000000 -0700
@@ -54,18 +54,18 @@
 	AliasDomain.${CPP} POP3GwLink.${CPP} POP3Svr.${CPP} POP3Utils.${CPP} PSYNCSvr.${CPP} ResLocks.${CPP} SList.${CPP} SMAILSvr.${CPP} \
 	TabIndex.${CPP} SMAILUtils.${CPP} SMTPSvr.${CPP} SMTPUtils.${CPP} ShBlocks.${CPP} StrUtils.${CPP} MessQueue.${CPP} \
 	QueueUtils.${CPP} SvrUtils.${CPP} SysDep.${CPP} UsrMailList.${CPP} UsrAuth.${CPP} UsrUtils.${CPP} Main.${CPP} Base64Enc.${CPP} \
-	Filter.${CPP}
+	Filter.${CPP} memtracer.${CPP}
 
 SVROBJS = BuffSock.${O} CTRLSvr.${O} DynDNS.${O} DNS.${O} DNSCache.${O} Errors.${O} ExtAliases.${O} FINGSvr.${O} \
 	MailConfig.${O} MailSvr.${O} Maildir.${O} MailDomains.${O} MD5.${O} MiscUtils.${O} LMAILSvr.${O} \
 	AliasDomain.${O} POP3GwLink.${O} POP3Svr.${O} POP3Utils.${O} PSYNCSvr.${O} ResLocks.${O} SList.${O} SMAILSvr.${O} \
 	TabIndex.${O} SMAILUtils.${O} SMTPSvr.${O} SMTPUtils.${O} ShBlocks.${O} StrUtils.${O} MessQueue.${O} \
 	QueueUtils.${O} SvrUtils.${O} SysDep.${O} UsrMailList.${O} UsrAuth.${O} UsrUtils.${O} Main.${O} Base64Enc.${O} \
-	Filter.${O}
+	Filter.${O} memtracer.${O}
 
-CCLNSRCS = Base64Enc.${CPP} BuffSock.${CPP} SysDep.${CPP} StrUtils.${CPP} MD5.${CPP} MiscUtils.${CPP} CTRLClient.${CPP} Errors.${CPP}
+CCLNSRCS = Base64Enc.${CPP} BuffSock.${CPP} SysDep.${CPP} StrUtils.${CPP} MD5.${CPP} MiscUtils.${CPP} CTRLClient.${CPP} Errors.${CPP} memtracer.${CPP}
 
-CCLNOBJS = Base64Enc.${O} BuffSock.${O} SysDep.${O} StrUtils.${O} MD5.${O} MiscUtils.${O} CTRLClient.${O} Errors.${O}
+CCLNOBJS = Base64Enc.${O} BuffSock.${O} SysDep.${O} StrUtils.${O} MD5.${O} MiscUtils.${O} CTRLClient.${O} Errors.${O} memtracer.${O}
 
 XMCSRCS = XMCrypt.${CPP}
 
diff -Nru xmail-1.20.vanilla/memtracer.cpp xmail-1.20.mt/memtracer.cpp
--- xmail-1.20.vanilla/memtracer.cpp	1969-12-31 16:00:00.000000000 -0800
+++ xmail-1.20.mt/memtracer.cpp	2004-05-31 11:54:32.000000000 -0700
@@ -0,0 +1,274 @@
+/*
+ *  MemTracer by Davide Libenzi ( Memory Tracer )
+ *  Copyright (C) 2004  Davide Libenzi
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#define LIB_MEMTRACER
+#include "memtracer.h"
+
+
+
+#if !defined(MTR_CORE_MALLOC)
+#define MTR_CORE_MALLOC malloc
+#endif /* #if !defined(MTR_CORE_MALLOC) */
+
+#if !defined(MTR_CORE_FREE)
+#define MTR_CORE_FREE free
+#endif /* #if !defined(MTR_CORE_FREE) */
+
+#if !defined(MTR_CORE_REALLOC)
+#define MTR_CORE_REALLOC realloc
+#endif /* #if !defined(MTR_CORE_REALLOC) */
+
+
+#define MTR_MAXTRACE 8
+#define MTR_DUMPFILE "MTR_DUMPFILE"
+
+#define OFFSET_PTR(p, n) ((char *) (p) + (n))
+#define OFFSET_OF(t, f) ((int) &(((t *) 0)->f))
+
+#define LLIST_INIT(p) (p)->prev = (p)->next = (p)
+#define LLIST_ADD(i, p, n) do { \
+	llist_t *__p = (p), *__n = (n); \
+	(i)->prev = (__p), (i)->next = (__n); \
+	(__p)->next = (i), (__n)->prev = (i); \
+} while (0)
+#define LLIST_ADDH(i, h) LLIST_ADD(i, h, (h)->next)
+#define LLIST_ADDT(i, h) LLIST_ADD(i, (h)->prev, h)
+#define LLIST_DEL(i) do { \
+	llist_t *__p = (i)->prev, *__n = (i)->next; \
+	__p->next = __n, __n->prev = __p; \
+} while (0)
+#define LLIST_DEL_INIT(i) do { \
+	llist_t *__p = (i)->prev, *__n = (i)->next; \
+	__p->next = __n, __n->prev = __p; \
+	LLIST_INIT(i); \
+} while (0)
+#define LLIST_EMPTY(h) ((h)->next == (h))
+#define LLIST_FIRST(h) ((h)->next != (h) ? (h)->next: NULL)
+#define LLIST_LAST(h) ((h)->prev != (h) ? (h)->prev: NULL)
+#define LLIST_NEXT(i, h) ((i)->next != (h) ? (i)->next: NULL)
+#define LLIST_PREV(i, h) ((i)->prev != (h) ? (i)->prev: NULL)
+#define LLIST_ITEM(p, t, f) ((t *) OFFSET_PTR(p, -OFFSET_OF(t, f)))
+
+
+typedef struct s_llist {
+	struct s_llist *prev, *next;
+} llist_t;
+
+typedef struct s_memhdr {
+	llist_t lnk;
+	unsigned int size;
+	unsigned long long aid;
+	void *strace[MTR_MAXTRACE];
+} memhdr_t;
+
+typedef unsigned long long idalloc_t;
+typedef struct s_pipesem {
+	int fds[2];
+} pipesem_t;
+
+
+
+static pipesem_t sem;
+static llist_t alist;
+static unsigned long blks, asize;
+static idalloc_t aid;
+
+
+
+
+static int psem_init(pipesem_t *ps, int icnt) {
+
+	if (pipe(ps->fds) < 0)
+		return -1;
+	for (; icnt > 0; icnt--)
+		write(ps->fds[1], "w", 1);
+	return 0;
+}
+
+static void psem_cleanup(pipesem_t *ps) {
+
+	close(ps->fds[0]);
+	close(ps->fds[1]);
+}
+
+static int psem_down(pipesem_t *ps) {
+	int rb;
+	unsigned char b;
+
+	while ((rb = read(ps->fds[0], &b, 1)) != 1 && errno == EINTR);
+	return rb == 1 ? 0: -1;
+}
+
+static int psem_up(pipesem_t *ps) {
+	int wb;
+
+	while ((wb = write(ps->fds[1], "w", 1)) != 1 && errno == EINTR);
+	return wb == 1 ? 0: -1;
+}
+
+int mtr_init(void) {
+
+	LLIST_INIT(&alist);
+	blks = asize = 0;
+	aid = 0;
+	psem_init(&sem, 1);
+	return 0;
+}
+
+static int mtr_filltrace(memhdr_t *mh) {
+	int td = 0;
+
+	memset(mh->strace, 0, sizeof(mh->strace));
+	if (!__builtin_frame_address(0))
+		return td;
+	mh->strace[td++] = __builtin_return_address(0);
+	if (!__builtin_frame_address(1))
+		return td;
+	mh->strace[td++] = __builtin_return_address(1);
+	if (!__builtin_frame_address(2))
+		return td;
+	mh->strace[td++] = __builtin_return_address(2);
+	if (!__builtin_frame_address(3))
+		return td;
+	mh->strace[td++] = __builtin_return_address(3);
+	if (!__builtin_frame_address(4))
+		return td;
+	mh->strace[td++] = __builtin_return_address(4);
+	if (!__builtin_frame_address(5))
+		return td;
+	mh->strace[td++] = __builtin_return_address(5);
+	if (!__builtin_frame_address(6))
+		return td;
+	mh->strace[td++] = __builtin_return_address(6);
+	if (!__builtin_frame_address(7))
+		return td;
+	mh->strace[td++] = __builtin_return_address(7);
+	return td;
+}
+
+void *mtr_malloc(unsigned int size) {
+	void *ptr;
+	memhdr_t *mh;
+
+	if ((ptr = MTR_CORE_MALLOC(size + sizeof(memhdr_t))) != NULL) {
+		mh = (memhdr_t *) ptr;
+		mh->size = size;
+		mtr_filltrace(mh);
+		psem_down(&sem);
+		LLIST_ADDT(&mh->lnk, &alist);
+		blks++;
+		asize += mh->size;
+		mh->aid = ++aid;
+		psem_up(&sem);
+		ptr = (char *) ptr + sizeof(memhdr_t);
+	}
+	return ptr;
+}
+
+void mtr_free(void *ptr) {
+	memhdr_t *mh;
+
+	if (ptr) {
+		mh = ((memhdr_t *) ptr) - 1;
+		psem_down(&sem);
+		LLIST_DEL(&mh->lnk);
+		blks--;
+		asize -= mh->size;
+		psem_up(&sem);
+		MTR_CORE_FREE(mh);
+	}
+}
+
+void *mtr_realloc(void *ptr, unsigned int size) {
+	memhdr_t *mh;
+
+	if (ptr) {
+		mh = ((memhdr_t *) ptr) - 1;
+		psem_down(&sem);
+		LLIST_DEL(&mh->lnk);
+		blks--;
+		asize -= mh->size;
+		psem_up(&sem);
+	} else
+		mh = NULL;
+	if ((ptr = MTR_CORE_REALLOC(mh, size + sizeof(memhdr_t))) != NULL) {
+		mh = (memhdr_t *) ptr;
+		mh->size = size;
+		mh->aid = ++aid;
+		mtr_filltrace(mh);
+		ptr = (char *) ptr + sizeof(memhdr_t);
+	}
+	if (mh) {
+		psem_down(&sem);
+		LLIST_ADDT(&mh->lnk, &alist);
+		blks++;
+		asize += mh->size;
+		psem_up(&sem);
+	}
+	return ptr;
+}
+
+int mtr_start(memckpoint_t *mci) {
+
+	psem_down(&sem);
+	*((idalloc_t *) mci->id) = aid;
+	psem_up(&sem);
+	return 0;
+}
+
+int mtr_stop(memckpoint_t *mci, char const *mdmpf) {
+	int i;
+	idalloc_t said;
+	FILE *fdump;
+	llist_t *pos;
+	memhdr_t *mh;
+	char dftmp[256];
+
+	if (!mdmpf && !(mdmpf = getenv(MTR_DUMPFILE))) {
+		sprintf(dftmp, "/tmp/mtr-dump-%u.txt", getpid());
+		mdmpf = dftmp;
+	}
+	if (!(fdump = fopen(mdmpf, "w"))) {
+		perror(mdmpf);
+		return -1;
+	}
+	said = *((idalloc_t *) mci->id);
+	psem_down(&sem);
+	for (pos = LLIST_FIRST(&alist); pos; pos = LLIST_NEXT(pos, &alist)) {
+		mh = LLIST_ITEM(pos, memhdr_t, lnk);
+		if (mh->aid <= said)
+			continue;
+		fprintf(fdump, "* addr=0x%08x\tsize=%u\n", mh, mh->size);
+		for (i = 0; i < MTR_MAXTRACE && mh->strace[i]; i++)
+			fprintf(fdump, "\tfrom=0x%08x\n", mh->strace[i]);
+	}
+	psem_up(&sem);
+	fclose(fdump);
+	return 0;
+}
+
diff -Nru xmail-1.20.vanilla/memtracer.h xmail-1.20.mt/memtracer.h
--- xmail-1.20.vanilla/memtracer.h	1969-12-31 16:00:00.000000000 -0800
+++ xmail-1.20.mt/memtracer.h	2004-05-31 11:50:25.000000000 -0700
@@ -0,0 +1,48 @@
+/*
+ *  MemTracer by Davide Libenzi ( Memory Tracer )
+ *  Copyright (C) 2004  Davide Libenzi
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+
+#if !defined(_MEMTRACER_H)
+#define _MEMTRACER_H
+
+
+#if !defined(LIB_MEMTRACER)
+#define malloc mtr_malloc
+#define free mtr_free
+#define realloc mtr_realloc
+#endif
+
+
+typedef struct s_memckpoint {
+	char id[8];
+} memckpoint_t;
+
+
+int mtr_init(void);
+void *mtr_malloc(unsigned int size);
+void mtr_free(void *ptr);
+void *mtr_realloc(void *ptr, unsigned int size);
+int mtr_start(memckpoint_t *mci);
+int mtr_stop(memckpoint_t *mci, char const *mdmpf);
+
+
+#endif /* #if !defined(_MEMTRACER_H) */
+
diff -Nru xmail-1.20.vanilla/SysDepLinux.cpp xmail-1.20.mt/SysDepLinux.cpp
--- xmail-1.20.vanilla/SysDepLinux.cpp	2004-05-31 11:47:30.000000000 -0700
+++ xmail-1.20.mt/SysDepLinux.cpp	2004-05-31 11:49:01.000000000 -0700
@@ -23,6 +23,7 @@
 #include "SysInclude.h"
 #include "SysDep.h"
 #include "AppDefines.h"
+#include "memtracer.h"
 
 #define SYS_INT_CALL()              (!iShutDown && (errno == EINTR))
 
