diff -uN popa3d-0.5.9/Makefile popa3d-0.5.9-maildir/Makefile
--- popa3d-0.5.9/Makefile	Sun Nov 10 07:02:31 2002
+++ popa3d-0.5.9-maildir/Makefile	Sun Nov 10 07:03:17 2002
@@ -35,7 +35,7 @@
 	virtual.o \
 	auth_passwd.o auth_shadow.o auth_pam.o \
 	pop_root.o pop_auth.o pop_trans.o \
-	protocol.o database.o mailbox.o \
+	protocol.o database.o mailbox.o maildir.o \
 	misc.o \
 	md5/md5.o
 
diff -uN popa3d-0.5.9/database.h popa3d-0.5.9-maildir/database.h
--- popa3d-0.5.9/database.h	Sun Nov 10 07:02:31 2002
+++ popa3d-0.5.9-maildir/database.h	Sun Nov 10 06:50:15 2002
@@ -7,6 +7,8 @@
 
 #include "params.h"
 
+#include <sys/time.h>
+
 /*
  * Message flags.
  */
@@ -30,6 +32,10 @@
 	unsigned long data_offset;	/* Just the message itself */
 	unsigned long data_size;
 	unsigned char hash[16];		/* MD5 hash, to be used for UIDL */
+#if POP_MAILDIR
+	time_t mtime;
+	char *filename;
+#endif
 };
 
 struct db_main {
diff -uN popa3d-0.5.9/maildir.c popa3d-0.5.9-maildir/maildir.c
--- popa3d-0.5.9/maildir.c	Thu Jan  1 00:00:00 1970
+++ popa3d-0.5.9-maildir/maildir.c	Sun Nov 10 17:54:49 2002
@@ -0,0 +1,177 @@
+/*
+ * Maildir access
+ */
+
+#include "params.h"
+
+#if POP_MAILDIR
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <syslog.h>
+#include <errno.h>
+
+#include "md5/md5.h"
+
+#include "misc.h"
+#include "protocol.h"
+#include "database.h"
+
+static int msgcmp(const void *p1, const void *p2)
+{
+        struct db_message *m1, *m2;
+
+        m1 = *(struct db_message **) p1;
+        m2 = *(struct db_message **) p2;
+
+        if (m1->mtime < m2->mtime)
+                return -1;
+        else if (m1->mtime == m2->mtime)
+                return 0;
+        else
+                return 1;
+}
+
+static int maildir_changed(void)
+{
+	struct stat stat;
+	unsigned int i;
+	struct db_message *msg;
+
+	for (i = 0; i < db.total_count; i++) {
+		msg = db.array[i];
+
+		if (lstat(msg->filename, &stat) ||
+		    stat.st_mtime != msg->mtime) {
+			db.flags |= DB_STALE;
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+int maildir_get(struct db_message *msg, int lines)
+{
+	int fd;
+
+	if (maildir_changed()) return POP_CRASH_SERVER;
+
+	if ((fd = open(msg->filename, O_RDONLY)) < 0)
+		return POP_CRASH_SERVER;
+
+	if (pop_reply_multiline(fd, msg->size, lines)) {
+		close(fd);
+		return POP_CRASH_NETFAIL;
+	}
+
+	close(fd);
+
+	if (maildir_changed()) return POP_CRASH_SERVER;
+
+	if (pop_reply_terminate()) return POP_CRASH_NETFAIL;
+
+	return POP_OK;
+}
+
+int maildir_update(void)
+{
+	unsigned int i;
+	struct db_message *msg;
+
+	for (i = 0; i < db.total_count; i++) {
+		msg = db.array[i];
+
+		if (msg->flags & MSG_DELETED)
+		{
+			if (unlink(msg->filename) < 0) {
+				if (errno == ENOENT)
+					continue;
+
+				return 1;
+			}
+		}
+	}
+
+	return 0;
+}
+
+int maildir_open(char *spool, char *mailbox)
+{
+	char *pathname;
+	DIR *dirp;
+	struct dirent *de;
+	struct db_message msg;
+	MD5_CTX hash;
+	struct stat stat;
+
+	pathname = malloc(strlen(spool) + strlen(mailbox) + 3);
+	if (!pathname) return 1;
+	sprintf(pathname, "%s/%s/", spool, mailbox);
+
+	if (lstat(pathname, &stat)) {
+		free(pathname);
+		return errno != ENOENT;
+	}
+
+	if (!S_ISDIR(stat.st_mode)) {
+		free(pathname);
+		return 1;
+	}
+
+	dirp = opendir(pathname);
+
+	if (!dirp) return 1;
+
+	while ((de = readdir(dirp))) {
+		if (de->d_name[0] == '.') continue;
+
+		pathname = malloc(strlen(spool) + strlen(mailbox) + strlen(de->d_name) + 3);
+		if (!pathname) return 1;
+
+		sprintf(pathname, "%s/%s/%s", spool, mailbox, de->d_name);
+
+		if (lstat(pathname, &stat)) {
+			free(pathname);
+			continue;
+		}
+
+		if (!S_ISREG(stat.st_mode)) {
+			free(pathname);
+			continue;
+		}
+
+		if (!stat.st_size) {
+			free(pathname);
+			continue;
+		}
+
+		memset(&msg, 0, sizeof(msg));
+
+		msg.size = stat.st_size;
+		msg.mtime = stat.st_mtime;
+		msg.filename = pathname;
+/*
+ * According to RFC1939 the message uidl can be from 1 to 70 characters
+ * in the range 0x21 to 0x7E. If your MTA generates valid unique filenames
+ * you could just as well use the filename instead of a md5 hash.
+ */
+		MD5_Init(&hash);
+		MD5_Update(&hash, pathname, strlen(pathname));
+		MD5_Final(msg.hash, &hash);
+
+		if (db_add(&msg)) return 1;
+	}
+
+	qsort(&db.array, db.total_count, sizeof(db.array[0]), msgcmp);
+
+	return 0;
+}
+
+#endif
diff -uN popa3d-0.5.9/maildir.h popa3d-0.5.9-maildir/maildir.h
--- popa3d-0.5.9/maildir.h	Thu Jan  1 00:00:00 1970
+++ popa3d-0.5.9-maildir/maildir.h	Sun Nov 10 06:50:15 2002
@@ -0,0 +1,25 @@
+/*
+ * Maildir access.
+ */
+
+#ifndef _POP_MAILDIR_H
+#define _POP_MAILDIR_H
+
+/*
+ * Opens the maildir, filling in the maildir database. Returns a non-zero
+ * value on error.
+ */
+extern int maildir_open(char *spool, char *maildir);
+
+/*
+ * Sends (first lines of) a message to the POP client. Returns one of the
+ * POP_* event codes.
+ */
+extern int maildir_get(struct db_message *msg, int lines);
+
+/*
+ * Updates the maildir according to flags in the database.
+ */
+extern int maildir_update(void);
+
+#endif
Common subdirectories: popa3d-0.5.9/md5 and popa3d-0.5.9-maildir/md5
diff -uN popa3d-0.5.9/params.h popa3d-0.5.9-maildir/params.h
--- popa3d-0.5.9/params.h	Sun Nov 10 07:02:32 2002
+++ popa3d-0.5.9-maildir/params.h	Sun Nov 10 07:03:28 2002
@@ -58,6 +58,11 @@
 
 #endif
 
+ /*
+ * Maildir support by Hallgrimur H. Gunnarsson <hhg@data.is>
+ */
+#define POP_MAILDIR			0
+
 /*
  * Do we want to support virtual domains?
  */
diff -uN popa3d-0.5.9/pop_trans.c popa3d-0.5.9-maildir/pop_trans.c
--- popa3d-0.5.9/pop_trans.c	Sun Nov 10 07:02:32 2002
+++ popa3d-0.5.9-maildir/pop_trans.c	Sun Nov 10 06:50:16 2002
@@ -9,6 +9,7 @@
 #include "protocol.h"
 #include "database.h"
 #include "mailbox.h"
+#include "maildir.h"
 
 static int pop_trans_quit(char *params)
 {
@@ -104,7 +105,11 @@
 	if (number < 1 || number > db.total_count || params) return POP_ERROR;
 	msg = db.array[number - 1];
 	if (msg->flags & MSG_DELETED) return POP_ERROR;
+#if POP_MAILDIR
+	if ((event = maildir_get(msg, -1)) != POP_OK) return event;
+#else
 	if ((event = mailbox_get(msg, -1)) != POP_OK) return event;
+#endif
 #if POP_SUPPORT_LAST
 	if (number > db.last) db.last = number;
 #endif
@@ -123,7 +128,11 @@
 	if (lines < 0 || params) return POP_ERROR;
 	msg = db.array[number - 1];
 	if (msg->flags & MSG_DELETED) return POP_ERROR;
+#if POP_MAILDIR
+	if ((event = maildir_get(msg, lines)) != POP_OK) return event;
+#else
 	if ((event = mailbox_get(msg, lines)) != POP_OK) return event;
+#endif
 	return POP_QUIET;
 }
 
@@ -192,10 +201,16 @@
 {
 	db_init();
 
+#if POP_MAILDIR
+	if (maildir_open(spool, mailbox)) return 1;
+#else
 	if (mailbox_open(spool, mailbox)) return 1;
+#endif
 
 	if (db_fix()) {
+#if !POP_MAILDIR
 		mailbox_close();
+#endif
 		return 1;
 	}
 
@@ -225,7 +240,11 @@
 	else
 	switch ((result = pop_handle_state(pop_trans_commands))) {
 	case POP_STATE:
+#if POP_MAILDIR
+		if (maildir_update()) {
+#else
 		if (mailbox_update()) {
+#endif
 			if (db.flags & DB_STALE) break;
 			syslog(SYSLOG_PRI_ERROR,
 				"Failed to update %s/%s",
@@ -258,7 +277,9 @@
 			"Server failure accessing %s/%s",
 			spool, mailbox);
 
+#if !POP_MAILDIR
 	mailbox_close();
+#endif
 
 	return 0;
 }
