some cleanups and fixes for Cyrus IMAPd....

Greg A. Woods woods-cyrus at weird.com
Mon Jul 14 17:09:27 EDT 2008


Here's a whack of cleanups and fixes for Cyrus IMAPd.  Many I would
consider absolutely critical while some are simply helpful and others
are just to shut up the compiler.  I may have posted this before, but
here it is again, updated to match the head of the CVS trunk today.

A note about the "const" related fixes:  There are two simple rules in C
about type qualifiers like 'const':

	1. if you qualify storage as 'const' then you _MUST_ copy it to
           unqualified storage before you can change it.

	2. casts _CANNOT_ be used to blindly remove type qualifiers.

There's still lots of really poor code in here, with many, sometimes
invalid, assumptions about buffer length, etc.  Some of this stuff is
just ugly and a major maintenance headache, but not immediately
dangerous, but there may be current dangers lurking too.  I don't have
time or funding to go through it all carefully enough.

There's also a whole whack of stuff that'll break on any platform where
time_t is widened beyond the size of a long (and yes, that's already in
the works on several platforms!).

I also provide a commented out version of a simpler auto-create hack
than the one from email.uoa.gr, as well as a sample config file with
some useful settings.

(oh, and the sievetest manual page provided here is still just a
template, as a reminder for someone to help finish it off)

-- 
						Greg A. Woods
						Planix, Inc.

<woods at planix.com>     +1 416 489-5852 x122     http://www.planix.com/

cvs diff: Diffing .
Index: .cvsignore
===================================================================
RCS file: /cvs/src/cyrus/.cvsignore,v
retrieving revision 1.2
diff -u -r1.2 .cvsignore
--- .cvsignore	4 Oct 2002 14:09:26 -0000	1.2
+++ .cvsignore	14 Jul 2008 20:44:35 -0000
@@ -1,9 +1,10 @@
-autom4te*.cache
 Makefile
 aclocal.m4
+autom4te*.cache
 config.cache
 config.h
 config.h.in
 config.log
 config.status
 configure
+configure.lineno
Index: contrib/unix2cyrus.sh
===================================================================
RCS file: contrib/unix2cyrus.sh
diff -N contrib/unix2cyrus.sh
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ contrib/unix2cyrus.sh	14 Jul 2008 20:44:35 -0000
@@ -0,0 +1,52 @@
+#! /bin/sh
+#
+#	unix2cyrus.sh - feed unix mailboxes to cyrus
+#
+# Here's a VERY simple little script to pipe individual messages from
+# a unix mailbox format spool file into "deliver" so as to move that
+# user's current incoming mail into their new Cyrus IMAPd "INBOX".
+#
+# WARNING: This script assumes the return-path header will be just one line.
+#
+# Usage:  unix2cyrus /var/mail/USER
+
+awk -v user=$(basename $1) '
+	BEGIN {
+		FS = " ";
+		pipe_cmd = "";
+		deliver_cmd = "@PREFIX@" "/cyrus/bin/deliver -q ";
+		last_line = "";
+		ret_path = "";
+		in_header = 1;
+		header[0] = "";
+		hc = 1;
+	}
+	$1 == "From" && last_line == "" {
+		close(pipe_cmd);
+		hc = 1;
+		in_header = 1;
+		ret_path = "root at localhost";
+		next;
+	}
+	in_header && $0 != "" {
+		if ($1 ~ /[Rr][Ee][Tt][Uu][Rr][Nn]-[Pp][Aa][Tt][Hh]:/) {
+			ret_path = $2;
+			gsub(/[<>]/, "", ret_path);
+		} else {
+			header[hc++] = $0;
+		}
+		next;
+	}
+	in_header && $0 == "" {
+		in_header = 0;
+		pipe_cmd = deliver_cmd "-f \"" ret_path "\" " user;
+		for (i = 1; i <= hc; i++) {
+			print header[i] | pipe_cmd;
+		}
+		print "" | pipe_cmd;
+		next;
+	}
+	! in_header {
+		last_line = $0;
+		print $0 | pipe_cmd;
+	}' $1
Index: doc/install-sieve.html
===================================================================
RCS file: /cvs/src/cyrus/doc/install-sieve.html,v
retrieving revision 1.4
diff -u -r1.4 install-sieve.html
--- doc/install-sieve.html	23 Oct 2001 18:14:48 -0000	1.4
+++ doc/install-sieve.html	14 Jul 2008 20:44:35 -0000
@@ -19,19 +19,19 @@
 
 <h3>Configure outgoing mail</h3>
 
-<p>Some Sieve actions (redirect, vacation) can send outgoing mail.</p>
+<p>Some Sieve actions (redirect, vacation) can (unfortunately) send outgoing mail.</p>
 
 <p>You'll need to make sure that "<tt>lmtpd</tt>" can send outgoing
-messages.  Currently, it invokes "<tt>/usr/lib/sendmail</tt>" by
+messages.  Currently, it invokes "<tt>/usr/sbin/sendmail</tt>" by
 default to send messages.  Change this by adding a line like:
 
 <pre>
-   sendmail: /usr/sbin/sendmail
+   sendmail: /usr/local/sbin/sendmail
 </pre>
 
-in your "<tt>/etc/imapd.conf</tt>".  If you're using Postfix or another
-MTA, make sure that the sendmail referenced in
-"<tt>/etc/imapd.conf</tt>" is Sendmail-compatible.</p>
+in your "<tt>/etc/imapd.conf</tt>".  If you are using Postfix or another
+MTA, make sure that the sendmail command referenced in
+"<tt>/etc/imapd.conf</tt>" is reasonably Sendmail-compatible.</p>
 
 <h3>Managing Sieve Scripts</h3>
 
@@ -85,7 +85,8 @@
 <li>Next test authenticating to the sieve server. To do this run the
 "<tt>sieveshell</tt>" utility. You must specify the server.  If you
 run this utility from a different machine without the "sieve" entry in
-"/etc/services", port 2000 will be used.
+"/etc/services", the very arbitrary port number 2000 will be used.
+(Note this port is actually assigned as the "callbook" service.)
 
 <pre>
   "<kbd>sieveshell foobar</kbd>"
Index: doc/overview.html
===================================================================
RCS file: /cvs/src/cyrus/doc/overview.html,v
retrieving revision 1.25
diff -u -r1.25 overview.html
--- doc/overview.html	30 Nov 2006 17:11:16 -0000	1.25
+++ doc/overview.html	14 Jul 2008 20:44:36 -0000
@@ -90,6 +90,7 @@
 <li><a href="#duplicate">Duplicate Delivery Suppression</a>
 <li><a href="#sieve">Sieve, a Mail Filtering Language</a>
 </ul>
+<li><a href="#aggregator">Cyrus Murder, the IMAP Aggregator</a>
 </UL>
 
 <H2><a name="mboxname">Mailbox Namespace</a></H2>
@@ -620,7 +621,7 @@
 When the POP3 server is invoked with the "<TT>-k</TT>" switch, the
 server exports MIT's KPOP protocol instead of generic POP3.
 
-<h3><a name="syslog">The <TT>syslog</TT> facility</a></h3>
+<h2><a name="syslog">The <TT>syslog</TT> facility</a></h2>
 
 The Cyrus IMAP server software sends log messages to the "<TT>local6</TT>"
 syslog facility.  The severity levels used are:
@@ -643,109 +644,115 @@
 
 <h3><a name="recoverymboxdir">Reconstructing Mailbox Directories</a></h3>
 
-The largest database is the mailbox directories.  Each
-mailbox directory contains the following files:
+<p>The largest database is the mailbox directories.  Each
+mailbox directory contains the following files:</p>
 
 <DL>
-<DT>message files 
-<DD> There is one file per message, containing the
+<DT>message files</DT>
+<DD> <P>There is one file per message, containing the
    message in RFC 822 format.  Lines in the message are separated by
    CRLF, not just LF.  The file name of each message is the message's
-   UID followed by a dot (.). 
+   UID followed by a dot (.). </p>
 
 <P>In netnews newsgroups, the message files instead follow the
-   format and naming conventions imposed by the netnews software. <P>
+   format and naming conventions imposed by the netnews software. </P>
 
-<DT><TT>cyrus.header</TT> 
-<DD>This file contains a magic number and variable-length
-   information about the mailbox itself.  <P>
-
-<DT><TT>cyrus.index</TT>
-<DD>This file contains fixed-length information about the
-   mailbox itself and each message in the mailbox.  <P>
-
-<DT><TT>cyrus.cache</TT>
-<DD>This file contans variable-length information about
-   each message in the mailbox. <P>
-
-<DT><TT>cyrus.seen</TT>
-<DD>This file contains variable-length state information about
-   each reader of the mailbox who has "<TT>s</TT>" permissions.  
+<DT><TT>cyrus.header</TT></DT>
+<DD><p>This file contains a magic number and variable-length
+   information about the mailbox itself.</p></DD>
+
+<DT><TT>cyrus.index</TT></DT>
+<DD><p>This file contains fixed-length information about the
+   mailbox itself and each message in the mailbox.  </P></DD>
+
+<DT><TT>cyrus.cache</TT></DT>
+<DD><p>This file contans variable-length information about
+   each message in the mailbox. </P></DD>
+
+<DT><TT>cyrus.seen</TT></DT>
+<DD><p>This file contains variable-length state information about
+   each reader of the mailbox who has "<TT>s</TT>" permissions.  </p></DD>
 </DL>
 
-The "<TT>reconstruct</TT>" program can be used to recover from
+<p>The "<TT>reconstruct</TT>" program can be used to recover from
 corruption in mailbox directories.  If "<TT>reconstruct</TT>" can find
 existing header and index files, it attempts to preserve any data in
 them that is not derivable from the message files themselves.  The
 state "<TT>reconstruct</TT>" attempts to preserve includes the flag
 names, flag state, and internal date.  "<TT>Reconstruct</TT>"
-derives all other information from the message files.
+derives all other information from the message files.</p>
 
 <p>An administrator may recover from a damaged disk by restoring message
 files from a backup and then running reconstruct to regenerate what it
-can of the other files.
+can of the other files.</p>
 
 <p>The "<TT>reconstruct</TT>" program does not adjust the quota usage
 recorded in any quota root files.  After running reconstruct, it is
 advisable to run "<TT>quota -f</TT>" (described below) in order to fix
-the quota root files.
+the quota root files.  It is not advisable to run "<TT>quota -f</TT>"
+without first running "<TT>reconstruct</TT>" (unless it is known that
+the only manual change has been directly to the quota files).</p>
 
 <h3><a name="recoverymbox">Reconstructing the Mailboxes File</a></h3>
 
-<B><I> NOTE: CURRENTLY UNAVAILABLE </I></B> <p>
+<p>
+<center>
+<B><EM> NOTE: MAILBOX RECONSTRUCTION IS CURRENTLY UNAVAILABLE </EM></B> <p>
+</center>
+</p>
 
-The mailboxes file in the configuration directory is the most critical
+<p>The mailboxes file in the configuration directory is the most critical
 file in the entire Cyrus IMAP system.  It contains a sorted list of
 each mailbox on the server, along with the mailboxes quota root and
-ACL.
+ACL.</p>
 
-To reconstruct a corrupted mailboxes file, run the "<TT>reconstruct
+<p>To reconstruct a corrupted mailboxes file, run the "<TT>reconstruct
 -m</TT>" command.  The "<TT>reconstruct</TT>" program, when invoked
 with the "<TT>-m</TT>" switch, scavenges and corrects whatever data it
 can find in the existing mailboxes file.  It then scans all partitions
 listed in the imapd.conf file for additional mailbox directories to
-put in the mailboxes file.
+put in the mailboxes file.</p>
 
 <p>The <TT>cyrus.header</TT> file in each mailbox directory stores a
 redundant copy of the mailbox ACL, to be used as a backup when
-rebuilding the mailboxes file.
+rebuilding the mailboxes file.</p>
 
 <h3><a name="recoveryquotas">Reconstructing Quota Roots</a></h3>
 
-The subdirectory "<TT>quota</TT>" of the configuration directory (specified in
+<p>The subdirectory "<TT>quota</TT>" of the configuration directory (specified in
 the "<TT>configdirectory</TT>" configuration option) contains one file per
 quota root, with the file name being the name of the quota root.  These
-files store the quota usage and limits of each of the quota roots.
+files store the quota usage and limits of each of the quota roots.</p>
 
 <p>The "<TT>quota</TT>" program, when invoked with the "<TT>-f</TT>"
 switch, recalculates the quota root of each mailbox and the quota
-usage of each <a href="#quotaroots">quota root</a>.
+usage of each <a href="#quotaroots">quota root</a>.</p>
 
 <h4><a name="recoveryquotasrm">Removing Quota Roots</a></h4>
 
-To remove a quota root, remove the quota root's file.  Then run 
-"<TT>quota -f</TT>" to make the quota files consistent again.
+<p>To remove a quota root, remove the quota root's file.  Then run 
+"<TT>quota -f</TT>" to make the quota files consistent again.</p>
 
 <h3><a name="recoverysubs">Subscriptions</a></h3>
 
-The subdirectory "<TT>user</TT>" of the configuration directory contains user
+<p>The subdirectory "<TT>user</TT>" of the configuration directory contains user
 subscriptions.  There is one file per user, with a filename of the
 userid followed by "<TT>.sub</TT>".  Each file contains a sorted list of
-subscribed mailboxes.
+subscribed mailboxes.</p>
 
 <p>There is no program to recover from damaged subscription files.  A
 site may recover from lost subscription files by restoring from backups.
 
 <h2><a name="configdir">Configuration Directory</a></h2>
 
-Many objects in the configuration directory are discussed in
+<p>Many objects in the configuration directory are discussed in
 the Database Recovery section. This section documents two
-other directories that reside in the configuration directory.
+other directories that reside in the configuration directory.</p>
 
 <h3><a name="configdirlog">"<TT>log</TT>" Directory</a></h3>
 
-The subdirectory "<TT>log</TT>" under the configuration directory permits
-administrators to keep protocol telemetry logs on a per-user basis.
+<p>The subdirectory "<TT>log</TT>" under the configuration directory permits
+administrators to keep protocol telemetry logs on a per-user basis.</p>
 
 <p>If a subdirectory of "<TT>log</TT>" exists with the same name as a user, the
 IMAP and POP3 servers will keep a telemetry log of protocol sessions
@@ -755,22 +762,24 @@
 
 <h3><a name="configdirproc">"<TT>proc</TT>" Directory</a></h3>
 
-The subdirectory "<TT>proc</TT>" under the configuration directory 
+<p>The subdirectory "<TT>proc</TT>" under the configuration directory 
 contains one file per active server process.  The file name is the ASCII
 representation of the process id and the file contains the following
-tab-separated fields:
+tab-separated fields:</p>
 
+<p>
 <UL>
 <LI>hostname of the client
 <LI>login name of the user, if logged in
 <LI>selected mailbox, if a mailbox is selected
 </UL>
+</p>
 
-The file may contain arbitrary characters after the first newline
-character.
+<p>The file may contain arbitrary characters after the first newline
+character.</p>
 
 <p>The "<TT>proc</TT>" subdirectory is normally be cleaned out on
-server reboot.
+server reboot.</p>
 
 <h2>Message Delivery</h2><a name="messagedelivery"></a>
 
@@ -778,7 +787,7 @@
 with the Cyrus server via LMTP (the Local Mail Transport Protocol)
 implemented by the LMTP daemon.  This can be done either directly by the
 MTA (prefered, for performance reasons) or via the <tt>deliver</tt> LMTP
-client.
+client.</p>
 
 <h3>Local Mail Transfer Protocol</h3><a name="lmtp"></a>
 
@@ -821,25 +830,26 @@
 
 <h3>Duplicate Delivery Suppression</h3><a name="duplicate"></a>
 
-A message is considered a duplicate if two copies of a message with
+<p>A message is considered a duplicate if two copies of a message with
 the same message-id and the same envelope receipient are received.
 Cyrus uses the duplicate delivery database to hold this information,
-and it looks approximately 3 days back in the default install. 
+and it looks approximately 3 days back in the default install.</p>
 
 <p>Duplicate delivery suppression can be turned off by using the
 "duplicatesuppression" flag in the configuration file.</p>
 
 <h3>Sieve, a Mail Filtering Language</h3><a name="sieve"></a>
 
-Sieve is a mail filtering language that can filter mail into an appropriate
-IMAP mailbox as it is delivered via lmtp.  For more information, look
-<A HREF="sieve.html">here</a>.
+<p>Sieve is a mail filtering language that can filter mail into an appropriate
+IMAP mailbox as it is delivered via LMTP.  For more information, see
+<A HREF="sieve.html"><I>Sieve: A Mail Filtering Language</I></a>.</p>
 
-<h3>Cyrus Murder, the IMAP Aggregator</h3><a name="aggregator"></a>
+<h2>Cyrus Murder, the IMAP Aggregator</h2><a name="aggregator"></a>
 
-Cyrus now supports the distribution of mailboxes across a number of IMAP
+<p>Cyrus now supports the distribution of mailboxes across a number of IMAP
 servers to allow for horizontal scalability.  For information on setting
-up this configuration, see <A href="install-murder.html">here</A>.
+up this configuration, see <A href="install-murder.html"><I>Installing
+The Cyrus Murder</I></A>.</p>
 
 <P><HR><P>
 <A HREF="index.html">Return</A> to the Cyrus IMAP Server Home Page
Index: doc/sieve.html
===================================================================
RCS file: /cvs/src/cyrus/doc/sieve.html,v
retrieving revision 1.1
diff -u -r1.1 sieve.html
--- doc/sieve.html	25 Apr 2000 02:56:46 -0000	1.1
+++ doc/sieve.html	14 Jul 2008 20:44:36 -0000
@@ -1,16 +1,36 @@
-<HTML><HEAD>
+<HTML>
+<HEAD>
 <TITLE>Sieve: A mail filtering language</TITLE>
 <!-- $Id: sieve.html,v 1.1 2000/04/25 02:56:46 leg Exp $ -->
-</HEAD><BODY>
+</HEAD>
+<BODY>
 <H1>                Sieve: A mail filtering language</H1>
 
-Sieve is a Internet standards-track protocol for filtering messages on
-delivery.  The Cyrus Sieve implementation supports filing messages
-into specific folders, forwarding messages, rejecting messages, and
-the standard vacation function.  It can reply to messages based on
-headers or envelope information.
+<P>
+Sieve is a Internet standards-track protocol
+(<A HREF="http://www.ietf.org/rfc/rfc3028.txt">RFC 3028</A>)
+for filtering messages on delivery.
+</P>
 
 <H2>Cyrus Sieve</H2>
 
+<P>
+The Cyrus Sieve implementation supports filing messages into specific
+folders, forwarding messages, rejecting messages, the sub-address
+extension, regular expression matching and relational tests, the
+imapflags extension, and the vacation extension.  It can also reply to
+messages based on headers or envelope information.
+</P>
+
 <H2>Some simple sample Sieve scripts</H2>
 
+<P>
+<EM>ToDo</EM>
+</P>
+
+<HR>
+
+<P>
+last modified: $Date: 2001/10/23 18:14:48 $
+</P>
+</BODY></HTML>
Index: doc/specs.html
===================================================================
RCS file: /cvs/src/cyrus/doc/specs.html,v
retrieving revision 1.68
diff -u -r1.68 specs.html
--- doc/specs.html	4 Oct 2007 01:24:50 -0000	1.68
+++ doc/specs.html	14 Jul 2008 20:44:36 -0000
@@ -214,3 +214,8 @@
 <TR><TD><A HREF="http://www.ietf.org/rfc/rfc3656.txt">RFC 3656</a></TD>
 <TD>MUPDATE Protocol (For Cyrus Murder)</TD></TR>
 </TABLE>
+<HR>
+<P>
+last modified: $Date: 2001/10/23 18:14:48 $
+</P>
+</BODY></HTML>
Index: imap/deliver.c
===================================================================
RCS file: /cvs/src/cyrus/imap/deliver.c,v
retrieving revision 1.180
diff -u -r1.180 deliver.c
--- imap/deliver.c	22 Apr 2008 13:11:17 -0000	1.180
+++ imap/deliver.c	14 Jul 2008 20:44:36 -0000
@@ -243,6 +243,7 @@
     prot_settimeout(deliver_in, 300);
 
     cyrus_init(alt_config, "deliver", CYRUSINIT_NODB);
+    global_sasl_init(1, 0, NULL);
 
     sockaddr = config_getstring(IMAPOPT_LMTPSOCKET);
     if (!sockaddr) {	
Index: imap/duplicate.c
===================================================================
RCS file: /cvs/src/cyrus/imap/duplicate.c,v
retrieving revision 1.47
diff -u -r1.47 duplicate.c
--- imap/duplicate.c	24 Mar 2008 17:09:16 -0000	1.47
+++ imap/duplicate.c	14 Jul 2008 20:44:36 -0000
@@ -156,8 +156,10 @@
 	mark = 0;
     }
 
+#ifdef DUPLICATE_DEBUG
     syslog(LOG_DEBUG, "duplicate_check: %-40s %-20s %ld",
 	   buf, buf+idlen+1, mark);
+#endif
 
     return mark;
 }
@@ -192,8 +194,10 @@
 		      data, sizeof(mark)+sizeof(uid), NULL);
     } while (r == CYRUSDB_AGAIN);
 
+#ifdef DUPLICATE_DEBUG
     syslog(LOG_DEBUG, "duplicate_mark: %-40s %-20s %ld %lu",
 	   buf, buf+idlen+1, mark, uid);
+#endif
 
     return;
 }
Index: imap/fud.c
===================================================================
RCS file: /cvs/src/cyrus/imap/fud.c,v
retrieving revision 1.56
diff -u -r1.56 fud.c
--- imap/fud.c	24 Mar 2008 17:09:16 -0000	1.56
+++ imap/fud.c	14 Jul 2008 20:44:37 -0000
@@ -104,24 +104,28 @@
 
 char who[16];
 
+#ifndef MAXLOGNAME
 #define MAXLOGNAME 16		/* should find out for real */
-#define MAXDOMNAME 20		/* should find out for real */
+#endif
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 256
+#endif
 
 int begin_handling(void)
 {
         struct sockaddr_storage sfrom;
         socklen_t sfromsiz = sizeof(sfrom);
         int r;
-        char    buf[MAXLOGNAME + MAXDOMNAME+ MAX_MAILBOX_NAME + 1];
-        char    username[MAXLOGNAME + MAXDOMNAME];
+        char    buf[MAXLOGNAME + MAXHOSTNAMELEN + MAX_MAILBOX_NAME + 1];
+        char    username[MAXLOGNAME + MAXHOSTNAMELEN]; /* XXX +1? */
         char    mbox[MAX_MAILBOX_NAME+1];
         char    *q;
         int     off;
-	int     maxuserlen = MAXLOGNAME + config_virtdomains ? MAXDOMNAME : 0;
+	int     maxuserlen = MAXLOGNAME + config_virtdomains ? MAXHOSTNAMELEN : 0;
 
         while(1) {
             /* For safety */
-            memset(username,'\0',MAXLOGNAME + MAXDOMNAME);	
+            memset(username, '\0', MAXLOGNAME + MAXHOSTNAMELEN);	
             memset(mbox,'\0',MAX_MAILBOX_NAME+1);
             memset(buf, '\0', MAXLOGNAME + MAX_MAILBOX_NAME + 1);
 
Index: imap/global.c
===================================================================
RCS file: /cvs/src/cyrus/imap/global.c,v
retrieving revision 1.27
diff -u -r1.27 global.c
--- imap/global.c	22 Apr 2008 11:06:03 -0000	1.27
+++ imap/global.c	14 Jul 2008 20:44:37 -0000
@@ -148,7 +148,7 @@
     }
 
     /* Look up default partition */
-    config_defpartition = config_getstring(IMAPOPT_DEFAULTPARTITION);
+    config_defpartition = xstrdup(config_getstring(IMAPOPT_DEFAULTPARTITION));
     for (p = (char *)config_defpartition; *p; p++) {
 	if (!isalnum((unsigned char) *p))
 	  fatal("defaultpartition option contains non-alphanumeric character",
@@ -365,7 +365,8 @@
 {
     char *domain = NULL;
     int len = strlen(user);
-    char buf[81];
+    char buf[81];		/* XXX  MAXHOSTNAMELEN + MAXLOGNAME at least!!!!  */
+				/* but then of course zillions of other similarly stupid assumptions break */
 
     /* check for domain */
     if (config_virtdomains &&
@@ -392,6 +393,7 @@
 	else if (loginid) { /* used for LISTRIGHTS */
 	    if ((domain = strrchr(loginid, '@'))) {
 		/* append the domain from the login id */
+		/* XXX should really use asprintf()! */
 		snprintf(buf, sizeof(buf), "%s@%s", user, domain+1);
 		user = buf;
 	    }
@@ -409,6 +411,7 @@
 		if (error == 0 && (domain = strchr(hbuf, '.')) &&
 		    !(config_defdomain && !strcasecmp(config_defdomain, domain+1))) {
 		    /* append the domain from our IP */
+		    /* XXX should really use asprintf()! */
 		    snprintf(buf, sizeof(buf), "%s@%s", user, domain+1);
 		    user = buf;
 		    
Index: imap/imapd.c
===================================================================
RCS file: /cvs/src/cyrus/imap/imapd.c,v
retrieving revision 1.548
diff -u -r1.548 imapd.c
--- imap/imapd.c	22 Apr 2008 13:11:17 -0000	1.548
+++ imap/imapd.c	14 Jul 2008 20:44:42 -0000
@@ -730,6 +730,7 @@
     protgroup_insert(protin, imapd_in);
 
     /* Find out name of client host */
+    /* XXX this could be refactored into a helper function */
     salen = sizeof(imapd_remoteaddr);
     if (getpeername(0, (struct sockaddr *)&imapd_remoteaddr, &salen) == 0 &&
 	(imapd_remoteaddr.ss_family == AF_INET ||
@@ -905,6 +906,7 @@
     exit(code);
 }
 
+/* XXX this function should be stdargs and call vsyslog() */
 void fatal(const char *s, int code)
 {
     static int recurse_code = 0;
@@ -936,7 +938,7 @@
 	free(stage);
     }
 
-    syslog(LOG_ERR, "Fatal error: %s", s);
+    syslog(LOG_ERR, "Fatal imapd error: %s", s);
     shut_down(code);
 }
 
@@ -2124,8 +2126,8 @@
     /* Set namespace */
     if ((r = mboxname_init_namespace(&imapd_namespace,
 				     imapd_userisadmin || imapd_userisproxyadmin)) != 0) {
-	syslog(LOG_ERR, error_message(r));
-	fatal(error_message(r), EC_CONFIG);
+	syslog(LOG_ERR, "login: mboxname_init_namespace: %s", error_message(r));
+	fatal("login: mboxname_init_namespace failed", EC_CONFIG);
     }
 
     /* Make a copy of the external userid for use in proxying */
@@ -2282,8 +2284,8 @@
     /* Set namespace */
     if ((r = mboxname_init_namespace(&imapd_namespace,
 				     imapd_userisadmin || imapd_userisproxyadmin)) != 0) {
-	syslog(LOG_ERR, error_message(r));
-	fatal(error_message(r), EC_CONFIG);
+	syslog(LOG_ERR, "login: (auth) mobxname_init_namespace: %s", error_message(r));
+	fatal("login: (auth) mobxname_init_namespace failed", EC_CONFIG);
     }
 
     /* Make a copy of the external userid for use in proxying */
Index: imap/imapd.conf
===================================================================
RCS file: imap/imapd.conf
diff -N imap/imapd.conf
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ imap/imapd.conf	14 Jul 2008 20:44:43 -0000
@@ -0,0 +1,357 @@
+# $Id$
+#
+#	Cyrus IMAP server configuration file.
+#
+# Most lines in this file are commented; in this case the default is used. 
+# The commented lines (usually) contain the default value
+#
+#        Each line of the /etc/imapd.conf file has the form
+#
+#              option: value
+#
+#       where option is the name of the configuration option being
+#       set  and  value is the value that the configuration option
+#       is being set to.
+#
+#       Blank lines and lines beginning with ``#'' are ignored.
+#
+#       For boolean options, the values  ``yes'',  ``on'',  ``t[rue]'',
+#       and  ``1'' turn the option on, the values ``no'', ``off'',
+#       ``f[alse]'', and ``0'' turn the option off.
+#
+# Refer to imapd.conf(5) for more options and other details.
+
+# The pathname of the IMAP configuration directory
+#
+# This directory, and the associated partition directory listed below,
+# can be created with the ${PREFIX}/cyrus/bin/mkimap script.
+#
+# This directory should only be readable and writable by the user-id
+# configured for the daemon, and readable only by the group-id
+# configured for the daemon.  This directory should not be world
+# readable or writable or searchable.
+#
+configdirectory: /var/imap
+
+# The partition name used by default for new mailboxes
+# 
+# The naming convention is such that partition-<name> where <name> is
+# replaced by the value of following setting will specify the
+# configuration entry which defines the pathname to the default
+# partition.
+#
+defaultpartition: default
+
+# The directory pathname for the default partition
+#
+# Other partitions can be defined with entries like partition-<name>.
+# 
+# Partition directories should only be readable and writable by the
+# user-id configured for the daemon, and readable only by the group-id
+# configured for the daemon.  This directory should not be world
+# readable or writable or searchable.
+#
+partition-default: /var/spool/imap
+
+### NOTE: the rest of the options below are kept sorted.
+
+# The list of userids with administrative rights.  Separate each userid
+# with a space.  We recommend that administrator userids be separate from 
+# standard userids.  Sites using Kerberos authentication may use separate
+# "admin" instances.
+#
+#admins: <none>
+admins: cyrus
+
+# If nonzero, normal users may create their own IMAP accounts by
+# creating the mailbox INBOX.  Incoming e-mails also automatically
+# create an INBOX for the user.  The user's quota is set to the value,
+# in kilobytes if it is positive, otherwise the user has unlimited
+# quota.
+#
+#autocreatequota: 0
+autocreatequota: 10000
+
+# If enabled, the partitions will also be hashed, in addition to the
+# hashing done on configuration directories.  This is recommended if
+# one partition has a very bushy mailbox tree.
+#
+# If you are upgrading a previous instance which did not have hashing
+# enabled you can fix the existing configdirectory and partition
+# directory with the ${PREFIX}/cyrus/bin/dohash tool.
+# 
+#hashimapspool: false
+hashimapspool: true
+
+# If enabled, lmtpd returns a permanent failure code when a user's
+# mailbox is over quota.  By default, the failure is temporary, which
+# means your users would get to use your MTA's queue to extend their
+# quota!
+#
+#lmtp_overquota_perm_failure: no
+lmtp_overquota_perm_failure: yes
+
+# The pathname of the Unix domain socket, or the hostname, that
+# lmtpd(8) listens on.  This value is used by deliver(8).  This should
+# match the path specified in cyrus.conf(5), or be the name of the
+# host running the master(8) daemon listening on the LMTP service.
+#
+#lmtpsocket: /var/imap/socket/lmtp
+
+# To run LMTP over TCP the special user "proxy" must authenticate to lmtpd,
+# and this user must be listed as an admin:
+#
+#lmtp_admins: proxy
+
+# To run LMTP over TCP the password for the "proxy" user must be
+# included (in plain text) here using a config variable formed from
+# the short name of the lmtpsocket hostname (i.e. the part up to the
+# first ".")
+#
+#<LMTPSOCKETUNQALIFIEDHOST>_password: <some_secret_string>
+
+# Include notations in the protocol telemetry logs indicating the
+# number of seconds since the last command or response.
+#
+#logtimestamps: no
+logtimestamps: yes
+
+# Maximum incoming LMTP message size.  If set, lmtpd will reject
+# messages larger than maxmessagesize bytes.  The default is to allow
+# messages of any size.  4MB is the most smail can realistically carry,
+# all things considered.
+#
+#maxmessagesize: <unlimited>
+maxmessagesize: 4000000
+
+# If enabled at compile time, this specifies a URL to reply when
+# Netscape asks the server where the mail administration HTTP server
+# is.  Administrators should set this to a local resource with some
+# useful information for end users.  If not set, no URL is advertised.
+#
+#netscapeurl: <no default>
+
+# The alternate namespace allows a user's personal mailboxes to appear as
+# if they reside at the same level as that user's INBOX
+#
+# WARNING:  This is a _REALLY_ bad idea with PINE.
+#
+#altnamespace: no
+
+# Use the UNIX separator character '/' for delimiting levels of
+# mailbox hierarchy.  The default is to use the netnews separator
+# character '.', which is far less pleasing to the eye.
+#
+unixhierarchysep: yes
+
+# Permit logins by the user "anonymous" using any password.
+#
+# Also  allows use of the SASL ANONYMOUS mechanism unless sasl_mech_list is
+# specified explicitly below
+#
+allowanonymouslogin: yes
+
+# Permit use of the POP3 APOP authentication command
+#
+# Note that this command requires that SASL is compiled with APOP
+# support, that the plaintext passwords are available in a SASL
+# auxprop backend (eg. sasldb), and that the system can provide enough
+# entropy (eg. from /dev/urandom) to create a challenge in the banner.
+#
+allowapop: 0
+
+# Set the minimum amount of time the server forces users to wait
+# between successive POP logins, in minutes.
+#
+# Note that some POP3 clients, e.g. some version of M$ Outlook and/or
+# Outlook/Express, ignore the reason for the authentication error and
+# will simply ask the user for the password again.
+#
+#popminpoll: 0
+
+# Create a softer minimum poll restriction.  Allows 'poppollpadding'
+# connections before the minpoll restriction is triggered.
+# Additionally, one padding entry is recovered every 'popminpoll'
+# minutes.
+#
+# This allows for the occasional polling rate faster than 'popminpoll', 
+# (i.e. for clients that require a send/recieve to send mail) but still 
+# enforces the rate long-term.  Default is 1 (disabled).
+#
+# The easiest way to think of it is a queue of past connections, with
+# one slot being filled for every connection, and one slot being
+# cleared every 'popminpoll' minutes.  When the queue is full, the
+# user will not be able to check mail again until a slot is cleared.
+# If the user waits a sufficent amount of time, they will get back
+# many or all of the slots.
+#
+#poppollpadding: 1
+
+# Use the saslauthd daemon to verify plaintext passwords.  Please ensure that
+# the saslauthd daemon is running before trying to authenticate.
+#
+sasl_pwcheck_method: saslauthd
+
+# Use these SASL authentication mechanisms.
+#
+# Don't use CRAM-MD5 or DIGEST-MD5 if you don't have a local sasldb
+# and you start saslauthd with "-a getpwent"
+#
+# Don't use OTP or ANONYMOUS unless you really need them -- it causes some
+# clients to prefer it, such as "cyradm".
+#
+# Don't put PLAIN before LOGIN -- it buggers Mozilla.
+#
+sasl_mech_list: LOGIN PLAIN
+
+# Convert usernames to all lowercase before login/authenticate.  This
+# is useful with authentication backends which ignore case during
+# username lookups (such as LDAP).
+#
+#username_tolower: 0
+
+# Enable virtual domain support.
+#
+# If enabled (set to "on"), the user's domain will be determined by
+# splitting a fully qualified userid at the last '@' or '%' symbol.
+#
+# Each mailbox exists in only one domain, domains are mutually
+# exclusive, and there can be both global and domain-specific
+# administrators.
+#
+# Note: use 'saslauthd -a getpwent -r' to include the domain (realm)
+# in the login name for authenticating virtual domain users.  (Some
+# other mechanisms already use the realm.)
+#
+# If the supplied userid is unqualified, and the virtdomains option is
+# set to "on", then the domain will be determined by doing a reverse
+# lookup on the IP address of the incoming network interface and using
+# the PTR value, less the first/local part (e.g. "mailbox.domain"
+# becomes just "domain"), as the domain for the userid, provided it is
+# not the same as the value of 'defaultdomain'.
+#
+# If the virtdomains option is set to "userid" then the reverse lookup
+# is disabled and unqualified userids are treated as local.
+#
+# If the userid is qualified with the value of 'defaultdomain', and this
+# feature is enabled (set ot "on" or "userid"), then the domain name is
+# stripped off (and thus treated as local).
+#
+#virtdomains: off
+
+# The default domain for virtual domain support
+#
+#defaultdomain: <none>
+
+# If enabled, deliver will look for Sieve scripts in user's home
+# directories: ~user/.sieve.
+# 
+#sieveusehomedir: false
+sieveusehomedir: true
+
+# If sieveusehomedir is false, this directory is searched for Sieve
+# scripts.
+#
+#sievedir: /var/imap/sieve
+
+# The pathname of the sendmail executable.  Sieve uses sendmail for
+# sending rejections, redirects and vacation responses.
+#
+#sendmail: /usr/sbin/sendmail
+
+# Size (in kilobytes) of the shared memory buffer pool (cache) used by
+# the berkeley database environment.
+#
+# The minimum allowed value is 20.  The maximum  allowed  value
+# is 4194303 (4GB).
+#
+# See imapd.conf(5) for a complete listing of berkeley_* options.
+#
+#berkeley_cachesize: 512
+berkeley_cachesize: 4096
+
+# The cyrusdb backend to use for mailbox annotations.
+#
+#annotation_db: skiplist
+
+# The cyrusdb backend to use for the duplicate delivery suppression and sieve.
+#
+# This database stores _all_ message-ID values and so a hash-style db
+# is most efficient.
+#
+#duplicate_db: berkeley-nosync
+
+# lmtpd will suppress delivery of a message to a mailbox if a message
+# with the same message-id (or resent-message-id) is recorded as
+# having already been delivered to the destination mailbox.
+#
+#duplicatesuppression: 1
+
+# The cyrusdb backend to use for the mailbox list.
+#
+# This database stores a list of all valid mailboxes.  The data part
+# is short so if it can be bsearch()ed efficiently then it is best as
+# a "flat" file, else a "skiplist" is next best to avoid lock contention.
+#
+#mboxlist_db: flat
+
+# The cyrusdb backend to use for quotas.
+# 
+# This database stores the quotas for all valid mailbox roots.  This
+# should be a "skiplist" for efficient updating and to avoid lock
+# contention.
+#
+# WARNING: updating a record in a "flat" DB type requires copying The
+# whole damn file, and possibly re-sorting it too, since neither the
+# record lengths, nor updatable field widths, are fixed length.  The
+# "skiplist" DB type can be updated much more quickly and is re-sorted
+# when it is chekpointed.
+#
+# Use the default of "quotalegacy" if upgrading from an older release.
+# (Beware this format requires one file per mailbox root!)
+#
+#quota_db: quotalegacy
+quota_db: skiplist
+
+# The cyrusdb backend to use for the seen state.
+#
+# This database contains one record for every mailbox and lists the
+# unique-IDs of the last-read and all previously read messages.
+#
+#seenstate_db: skiplist
+
+# The cyrusdb backend to use for the subscriptions list.
+#
+#subscription_db: flat
+
+# The cyrusdb backend to use for the TLS cache.
+#
+#tlscache_db: berkeley-nosync
+
+
+# See imapd.conf(5) for a complete listing of tls_* options.
+
+# File containing one or more Certificate Authority (CA) certificates.
+#
+#tls_ca_file:
+#tls_ca_file: /var/imap/private/CAcert.pem
+
+# Path to directory with certificates of CAs.
+#
+#tls_ca_path:
+
+# The file containing the global certificate, and the private key
+# belonging to the global server certificate, which will be used for
+# ALL services (imap, pop3, lmtp, sieve).
+#
+#    openssl req -new -x509 -nodes -out /var/imap/server.pem -keyout /var/imap/server.pem -days 365
+#
+# Note you must give the hostname any SSL clients will use to access
+# the server as the "Common Name (CN)" when running the above.
+#
+# To decode and view an existing x509 PEM file:
+#
+#    openssl x509 -in /var/imap/server.pem -text
+#
+tls_cert_file: /var/imap/server.pem
+tls_key_file: /var/imap/server.pem
Index: imap/lmtp_sieve.c
===================================================================
RCS file: /cvs/src/cyrus/imap/lmtp_sieve.c,v
retrieving revision 1.17
diff -u -r1.17 lmtp_sieve.c
--- imap/lmtp_sieve.c	24 Mar 2008 17:09:17 -0000	1.17
+++ imap/lmtp_sieve.c	14 Jul 2008 20:44:43 -0000
@@ -287,6 +287,11 @@
 	    "automatic-action/MDN-sent-automatically; deleted\r\n");
     fprintf(sm, "\r\n");
 
+    /*
+     * XXX This should proably always be just the headers, never the body too!
+     * (See send_forward() below for how to find the start of the body.)
+     * The MIME content-type should also be "message/rfc822-headers"
+     */
     /* this is the original message */
     fprintf(sm, "--%d/%s\r\nContent-Type: message/rfc822\r\n\r\n",
 	    (int) p, config_servername);
Index: imap/lmtpd.c
===================================================================
RCS file: /cvs/src/cyrus/imap/lmtpd.c,v
retrieving revision 1.161
diff -u -r1.161 lmtpd.c
--- imap/lmtpd.c	22 Apr 2008 13:11:18 -0000	1.161
+++ imap/lmtpd.c	14 Jul 2008 20:44:44 -0000
@@ -108,7 +108,7 @@
 /* forward declarations */
 static int deliver(message_data_t *msgdata, char *authuser,
 		   struct auth_state *authstate);
-static int verify_user(const char *user, const char *domain, char *mailbox,
+static int verify_user(char *user, const char *domain, char *mailbox,
 		       long quotacheck, struct auth_state *authstate);
 static char *generate_notify(message_data_t *m);
 
@@ -976,11 +976,12 @@
     exit(code);
 }
 
-static int verify_user(const char *user, const char *domain, char *mailbox,
+static int verify_user(char *user, const char *domain, char *mailbox,
 		       long quotacheck, struct auth_state *authstate)
 {
     char namebuf[MAX_MAILBOX_NAME+1] = "";
     int r = 0;
+    int autocreatequota = config_getint(IMAPOPT_AUTOCREATEQUOTA);
 
     if ((!user && !mailbox) ||
 	(domain && (strlen(domain) + 1 > sizeof(namebuf)))) {
@@ -1046,6 +1047,33 @@
 			     || config_getswitch(IMAPOPT_LMTP_STRICT_QUOTA) ?
 			     quotacheck : 0);
 	}
+#if 0
+	/*
+	 * This is a very simple little patch to allow Cyrus IMAP to
+	 * automatically create non-existant mailboxes when incoming mail is
+	 * first posted to it.
+	 *
+	 * Note a somewhat more complete patch is here:
+	 *
+	 *	http://email.uoa.gr/projects/cyrus/autocreate/
+	 */
+	if (r == IMAP_MAILBOX_NONEXISTENT && autocreatequota > 0) {
+	    syslog(LOG_INFO, "attempting to auto-create mailbox '%s' for user '%s'", namebuf, user ? user : "(shared)");
+	    r = mboxlist_createmailbox(namebuf, 0, (char *) NULL, 1,
+				       user, authstate, 0, 1, 0);
+	    if (!r) {
+		(void) mboxlist_setquota(namebuf, autocreatequota, 0);
+	    } else {
+		syslog(LOG_NOTICE, "auto-create of mailbox '%s' for user '%s' failed!", namebuf, user ? user : "(shared)");
+	    }
+	    if (!r) {
+		r = append_check(namebuf, MAILBOX_FORMAT_NORMAL, authstate,
+				 aclcheck, (quotacheck < 0)
+				 || config_getswitch(IMAPOPT_LMTP_STRICT_QUOTA) ?
+				 quotacheck : 0);
+	    }
+	}
+#endif
     }
 
     if (r) syslog(LOG_DEBUG, "verify_user(%s) failed: %s", namebuf,
Index: imap/lmtpengine.c
===================================================================
RCS file: /cvs/src/cyrus/imap/lmtpengine.c,v
retrieving revision 1.127
diff -u -r1.127 lmtpengine.c
--- imap/lmtpengine.c	22 Apr 2008 13:11:18 -0000	1.127
+++ imap/lmtpengine.c	14 Jul 2008 20:44:45 -0000
@@ -234,20 +234,24 @@
 	break;
 
     case IMAP_MESSAGE_CONTAINSNL:
-	prot_printf(pout, "554 5.6.0 Message contains bare newlines\r\n");
+	prot_printf(pout, "554 5.6.1 Message contains bare newlines\r\n");
 	break;
 
     case IMAP_MESSAGE_CONTAINS8BIT:
-	prot_printf(pout, "554 5.6.0 Message contains non-ASCII characters in headers\r\n");
+	prot_printf(pout, "554 5.6.2 Message contains non-ASCII characters in headers\r\n");
 	break;
 
     case IMAP_MESSAGE_BADHEADER:
-	prot_printf(pout, "554 5.6.0 Message contains invalid header\r\n");
+	prot_printf(pout, "554 5.6.3 Message contains invalid header\r\n");
 	break;
 
     case IMAP_MESSAGE_NOBLANKLINE:
+	prot_printf(pout, "554 5.6.4 Message has no header/body separator\r\n");
+	break;
+
+    case IMAP_MAILBOX_BADNAME:
 	prot_printf(pout, 
-		    "554 5.6.0 Message has no header/body separator\r\n");
+		    "550 5.1.1 Bad mail box name\r\n");
 	break;
 
     case IMAP_MAILBOX_NONEXISTENT:
@@ -262,14 +266,23 @@
 	}
 	break;
 
+    case IMAP_PARTITION_UNKNOWN:
+	prot_printf(pout, 
+		    "550 5.1.1 Internal configuration error: partition unknown, please inform %s\r\n",
+		    config_getstring(IMAPOPT_POSTMASTER));
+	break;
+
     case IMAP_PROTOCOL_BAD_PARAMETERS:
 	prot_printf(pout, "501 5.5.4 Syntax error in parameters\r\n");
 	break;
 
     case MUPDATE_BADPARAM:
+	prot_printf(pout, "501 5.5.4 Unspecified bad mailbox update parameter\r\n");
+	break;
+
     default:
 	/* Some error we're not expecting. */
-	prot_printf(pout, "554 5.0.0 Unexpected internal error\r\n");
+	prot_printf(pout, "554 5.0.0 Unexpected internal error [%d]\r\n", r);
 	break;
     }
 }
@@ -700,6 +713,7 @@
     p += sprintf(p, " %s", datestr);
  
     fprintf(f, "Received: ");
+    /* XXX should skip past any space char(s) at the beginning of each string */
     for (i = 0, p = addbody; i < nfold; p = fold[i], i++) {
 	fprintf(f, "%.*s\r\n\t", fold[i] - p, p);
     }
@@ -806,7 +820,7 @@
    on failure, return the error. */
 static int process_recipient(char *addr, struct namespace *namespace,
 			     int ignorequota,
-			     int (*verify_user)(const char *, const char *,
+			     int (*verify_user)(char *, const char *,
 						char *, long,
 						struct auth_state *),
 			     message_data_t *msg)
@@ -1034,6 +1048,7 @@
     }
 
     /* determine who we're talking to */
+    /* XXX this could be refactored into a helper function */
     salen = sizeof(remoteaddr);
     r = getpeername(fd, (struct sockaddr *)&remoteaddr, &salen);
     if (!r &&
@@ -1717,8 +1732,22 @@
 	}
 	return IMAP_QUOTA_EXCEEDED;
     case 554:
-	return IMAP_MESSAGE_BADHEADER; /* sigh, pick one */
-
+	if (code[4] == '5' && code[6] == '6') {
+	    if (code[8] == '0') {
+		return IMAP_MESSAGE_BADHEADER;
+	    } else if (code[8] == '1') {
+		return IMAP_MESSAGE_CONTAINSNL;
+	    } else if (code[8] == '2') {
+		return IMAP_MESSAGE_CONTAINS8BIT;
+	    } else if (code[8] == '3') {
+		return IMAP_MESSAGE_BADHEADER;
+	    } else if (code[8] == '4') {
+		return IMAP_MESSAGE_NOBLANKLINE;
+	    }
+	} else if (code[4] == '5' && code[6] == '0') {
+	    return IMAP_PROTOCOL_ERROR;
+	}
+	return IMAP_PROTOCOL_ERROR;
     default:
 	if (ISGOOD(c)) return 0;
 	else if (TEMPFAIL(c)) return IMAP_AGAIN;
Index: imap/lmtpengine.h
===================================================================
RCS file: /cvs/src/cyrus/imap/lmtpengine.h,v
retrieving revision 1.25
diff -u -r1.25 lmtpengine.h
--- imap/lmtpengine.h	3 Apr 2008 21:09:52 -0000	1.25
+++ imap/lmtpengine.h	14 Jul 2008 20:44:45 -0000
@@ -108,7 +108,7 @@
 struct lmtp_func {
     int (*deliver)(message_data_t *m, 
 		   char *authuser, struct auth_state *authstate);
-    int (*verify_user)(const char *user, const char *domain, char *mailbox,
+    int (*verify_user)(char *user, const char *domain, char *mailbox,
 		       long quotacheck, /* user must have this much quota left
 					   (-1 means don't care about quota) */
 		       struct auth_state *authstate);
Index: imap/mailbox.h
===================================================================
RCS file: /cvs/src/cyrus/imap/mailbox.h,v
retrieving revision 1.91
diff -u -r1.91 mailbox.h
--- imap/mailbox.h	24 Mar 2008 17:09:17 -0000	1.91
+++ imap/mailbox.h	14 Jul 2008 20:44:45 -0000
@@ -145,7 +145,7 @@
     time_t last_appenddate;
     unsigned long last_uid;
     uquota_t quota_mailbox_used;
-    unsigned long pop3_last_login;
+    unsigned long pop3_last_login;	/* XXX time_t */
     unsigned long uidvalidity;
 
     unsigned long deleted;
Index: imap/mbexamine.c
===================================================================
RCS file: /cvs/src/cyrus/imap/mbexamine.c,v
retrieving revision 1.19
diff -u -r1.19 mbexamine.c
--- imap/mbexamine.c	24 Mar 2008 17:09:17 -0000	1.19
+++ imap/mbexamine.c	14 Jul 2008 20:44:45 -0000
@@ -311,7 +311,7 @@
 	printf("\n");
     }
     printf("  Last POP3 Login: (%ld) %s", mailbox.pop3_last_login,
-	   ctime((const long *) &mailbox.pop3_last_login));
+	   ctime((time_t *) &mailbox.pop3_last_login));
     if (mailbox.minor_version >= 8) {
 	printf("  Highest Mod Sequence: " MODSEQ_FMT "\n",
 	       mailbox.highestmodseq);
Index: imap/mupdate.c
===================================================================
RCS file: /cvs/src/cyrus/imap/mupdate.c,v
retrieving revision 1.102
diff -u -r1.102 mupdate.c
--- imap/mupdate.c	24 Mar 2008 17:09:18 -0000	1.102
+++ imap/mupdate.c	14 Jul 2008 20:44:47 -0000
@@ -280,6 +280,7 @@
     pthread_mutex_unlock(&connection_count_mutex); /* UNLOCK */
 
     /* Find out name of client host */
+    /* XXX this could be refactored into a helper function */
     salen = sizeof(remoteaddr);
     if (getpeername(C->fd, (struct sockaddr *)&remoteaddr, &salen) == 0 &&
 	(remoteaddr.ss_family == AF_INET ||
Index: imap/nntpd.c
===================================================================
RCS file: /cvs/src/cyrus/imap/nntpd.c,v
retrieving revision 1.68
diff -u -r1.68 nntpd.c
--- imap/nntpd.c	22 Apr 2008 13:11:18 -0000	1.68
+++ imap/nntpd.c	14 Jul 2008 20:44:49 -0000
@@ -563,6 +563,7 @@
     protgroup_insert(protin, nntp_in);
 
     /* Find out name of client host */
+    /* XXX this could be refactored into a helper function */
     salen = sizeof(nntp_remoteaddr);
     if (getpeername(0, (struct sockaddr *)&nntp_remoteaddr, &salen) == 0 &&
 	(nntp_remoteaddr.ss_family == AF_INET ||
Index: imap/pop3d.c
===================================================================
RCS file: /cvs/src/cyrus/imap/pop3d.c,v
retrieving revision 1.189
diff -u -r1.189 pop3d.c
--- imap/pop3d.c	22 Apr 2008 13:11:18 -0000	1.189
+++ imap/pop3d.c	14 Jul 2008 20:44:50 -0000
@@ -124,7 +124,7 @@
 struct protstream *popd_in = NULL;
 static int popd_logfd = -1;
 unsigned popd_exists = 0;
-unsigned popd_login_time;
+unsigned long popd_login_time;		/* XXX time_t */
 struct msg {
     unsigned uid;
     unsigned size;
@@ -425,7 +425,7 @@
 
     /* Set namespace */
     if ((r = mboxname_init_namespace(&popd_namespace, 1)) != 0) {
-	syslog(LOG_ERR, error_message(r));
+	syslog(LOG_ERR, "login: mboxname_init_namespace: %s", error_message(r));
 	fatal(error_message(r), EC_CONFIG);
     }
 
@@ -477,6 +477,7 @@
     popd_out = prot_new(1, 1);
 
     /* Find out name of client host */
+    /* XXX this could be refactored into a helper function */
     salen = sizeof(popd_remoteaddr);
     if (getpeername(0, (struct sockaddr *)&popd_remoteaddr, &salen) == 0 &&
 	(popd_remoteaddr.ss_family == AF_INET ||
@@ -633,6 +634,7 @@
     exit(code);
 }
 
+/* XXX this function should be stdargs and call vsyslog() */
 void fatal(const char* s, int code)
 {
     static int recurse_code = 0;
@@ -647,7 +649,7 @@
 	prot_printf(popd_out, "-ERR [SYS/PERM] Fatal error: %s\r\n", s);
 	prot_flush(popd_out);
     }
-    syslog(LOG_ERR, "Fatal error: %s", s);
+    syslog(LOG_ERR, "Fatal pop3d error: %s", s);
     shut_down(code);
 }
 
@@ -1635,7 +1637,7 @@
 	int minpoll;
 	int doclose = 0;
 
-	popd_login_time = time(0);
+	popd_login_time = time((time_t *) 0);
 
 	r = mailbox_open_header(inboxname, popd_authstate, &mboxstruct);
 	if (!r) {
@@ -1671,6 +1673,8 @@
 
 	if ((minpoll = config_getint(IMAPOPT_POPMINPOLL)) &&
 	    mboxstruct.pop3_last_login + 60*minpoll > popd_login_time) {
+	    syslog(LOG_NOTICE, "User exceeded popminpoll delay: %s",
+		   popd_userid);
 	    prot_printf(popd_out,
 			"-ERR [LOGIN-DELAY] Logins must be at least %d minute%s apart\r\n",
 			minpoll, minpoll > 1 ? "s" : "");
Index: imap/search_engines.c
===================================================================
RCS file: /cvs/src/cyrus/imap/search_engines.c,v
retrieving revision 1.10
diff -u -r1.10 search_engines.c
--- imap/search_engines.c	24 Mar 2008 17:09:19 -0000	1.10
+++ imap/search_engines.c	14 Jul 2008 20:44:50 -0000
@@ -258,11 +258,11 @@
   strlcpy(index_file_name, path, sizeof(index_file_name));
   strlcat(index_file_name, FNAME_SQUAT_INDEX, sizeof(index_file_name));
   if ((fd = open(index_file_name, O_RDONLY)) < 0) {
-    syslog(LOG_DEBUG, "SQUAT failed to open index file");
+    syslog(LOG_DEBUG, "SQUAT index file %s: %m", index_file_name);
     return -1;   /* probably not found. Just bail */
   }
   if ((index = squat_search_open(fd)) == NULL) {
-    syslog(LOG_DEBUG, "SQUAT failed to open index");
+    syslog(LOG_INFO, "SQUAT failed to open index in %s", index_file_name);
     close(fd);
     return -1;
   }
@@ -315,11 +315,15 @@
   if (SQUAT_ENGINE) {
     count = search_squat(msg_list, mailbox, searchargs);
     if (count >= 0) {
+#ifdef DEBUG_SQUAT
       syslog(LOG_DEBUG, "SQUAT returned %d messages", count);
+#endif
       return count;
     } else {
 	/* otherwise, we failed for some reason, so do the default */
+#ifdef DEBUG_SQUAT
 	syslog(LOG_DEBUG, "SQUAT failed");
+#endif
     }
   }
   
Index: imap/squat_build.c
===================================================================
RCS file: /cvs/src/cyrus/imap/squat_build.c,v
retrieving revision 1.16
diff -u -r1.16 squat_build.c
--- imap/squat_build.c	24 Mar 2008 17:09:19 -0000	1.16
+++ imap/squat_build.c	14 Jul 2008 20:44:51 -0000
@@ -609,7 +609,7 @@
     for (i = 0; i < VECTOR_SIZE(t->entries); i++) {
       SquatWordTableEntry* e = &(t->entries[i]);
       
-      if (e->leaf_presence != NULL && ((int)e->leaf_presence & 1) == 0) {
+      if (e->leaf_presence != NULL && ((unsigned long int)e->leaf_presence & 1) == 0) {
         free(e->leaf_presence);
       }
     }
@@ -698,7 +698,7 @@
 
   if (word_entry == NULL) {
     /* We are in "per document" mode. */
-    if (((int)e->leaf_presence & 1) != 0) {
+    if (((unsigned long int)e->leaf_presence & 1) != 0) {
       /* We currently have a singleton here. */
       int oldch = e->leaf_presence_singleton >> 1;
 
@@ -917,7 +917,7 @@
 
       word[0] = (char)i;
 
-      if (((int)e->leaf_presence & 1) != 0) {
+      if (((unsigned long int)e->leaf_presence & 1) != 0) {
 	/* Got a singleton at this branch point. Just output the single word. */
         word[1] = (char)(e->leaf_presence_singleton >> 1);
         e->leaf_presence = NULL; /* clear the leaf out */
Index: imap/tls.c
===================================================================
RCS file: /cvs/src/cyrus/imap/tls.c,v
retrieving revision 1.65
diff -u -r1.65 tls.c
--- imap/tls.c	15 Apr 2008 17:58:08 -0000	1.65
+++ imap/tls.c	14 Jul 2008 20:44:52 -0000
@@ -223,7 +223,7 @@
     return (rsa_tmp);
 }
 
-#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
+#if (OPENSSL_VERSION_NUMBER >= 0x0090806fL) /* XXX hack for netbsd-4 with busted libcrypto build! */
 /* Logic copied from OpenSSL apps/s_server.c: give the TLS context
  * DH params to work with DHE-* cipher suites. Hardcoded fallback
  * in case no DH params in tls_key_file or tls_cert_file.
@@ -735,7 +735,7 @@
     }
     SSL_CTX_set_tmp_rsa_callback(s_ctx, tmp_rsa_cb);
 
-#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
+#if (OPENSSL_VERSION_NUMBER >= 0x0090806fL)
     /* Load DH params for DHE-* key exchanges */
     SSL_CTX_set_tmp_dh(s_ctx, load_dh_param(s_key_file, s_cert_file));
     /* FIXME: Load ECDH params for ECDHE suites when 0.9.9 is released */
@@ -753,7 +753,7 @@
 
     if (askcert || requirecert) {
       if (CAfile == NULL) {
-	  syslog(LOG_ERR, 
+	  syslog(LOG_NOTICE, 
 		 "TLS server engine: No CA file specified. "
 		 "Client side certs may not work");
       } else {
@@ -775,14 +775,14 @@
 	return (ret);
 
     if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) {
-	printf("read from %08X [%08lX] (%d bytes => %ld (0x%X))",
-	       (unsigned int) bio, (long unsigned int) argp,
+	printf("read from %0lX [%0lX] (%d bytes => %ld (0x%X))",
+	       (long unsigned int) bio, (long unsigned int) argp,
 	       argi, ret, (unsigned int) ret);
 	tls_dump(argp, (int) ret);
 	return (ret);
     } else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) {
-	printf("write to %08X [%08lX] (%d bytes => %ld (0x%X))",
-	       (unsigned int) bio, (long unsigned int)argp,
+	printf("write to %0X [%0lX] (%d bytes => %ld (0x%X))",
+	       (long unsigned int) bio, (long unsigned int)argp,
 	       argi, ret, (unsigned int) ret);
 	tls_dump(argp, (int) ret);
     }
Index: imtest/imtest.c
===================================================================
RCS file: /cvs/src/cyrus/imtest/imtest.c,v
retrieving revision 1.118
diff -u -r1.118 imtest.c
--- imtest/imtest.c	22 Apr 2008 13:11:18 -0000	1.118
+++ imtest/imtest.c	14 Jul 2008 20:44:53 -0000
@@ -630,15 +630,15 @@
 	return (ret);
     
     if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) {
-	printf("read from %08X [%08lX] (%d bytes => %ld (0x%X))\n",
-	       (unsigned int) bio, (long unsigned int) argp,
-	       argi, ret, (unsigned int) ret);
+	printf("read from %0lX [%0lX] (%d bytes => %ld (0x%lX))\n",
+	       (unsigned long int) bio, (unsigned long int) argp,
+	       argi, ret, (unsigned long int) ret);
 	tls_dump(argp, (int) ret);
 	return (ret);
     } else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) {
-	printf("write to %08X [%08lX] (%d bytes => %ld (0x%X))\n",
-	       (unsigned int) bio, (long unsigned int) argp,
-	       argi, ret, (unsigned int) ret);
+	printf("write to %0X [%0lX] (%d bytes => %ld (0x%lX))\n",
+	       (unsigned long int) bio, (unsigned long int) argp,
+	       argi, ret, (unsigned long int) ret);
 	tls_dump(argp, (int) ret);
     }
     return (ret);
Index: lib/auth_unix.c
===================================================================
RCS file: /cvs/src/cyrus/lib/auth_unix.c,v
retrieving revision 1.50
diff -u -r1.50 auth_unix.c
--- lib/auth_unix.c	24 Mar 2008 17:43:08 -0000	1.50
+++ lib/auth_unix.c	14 Jul 2008 20:44:53 -0000
@@ -54,7 +54,7 @@
 #include "xmalloc.h"
 
 struct auth_state {
-    char userid[81];
+    char userid[81];			/* XXX for proper virtual domain support should be MAXHOSTNAMELEN + MAXLOGNAME + 1 */
     char **group;
     int ngroups;
 };
Index: lib/cyrusdb_berkeley.c
===================================================================
RCS file: /cvs/src/cyrus/lib/cyrusdb_berkeley.c,v
retrieving revision 1.22
diff -u -r1.22 cyrusdb_berkeley.c
--- lib/cyrusdb_berkeley.c	24 Mar 2008 17:43:08 -0000	1.22
+++ lib/cyrusdb_berkeley.c	14 Jul 2008 20:44:54 -0000
@@ -479,7 +479,7 @@
 		       db_strerror(r));
 		return CYRUSDB_IOERROR;
 	    }
-	    if (CONFIG_DB_VERBOSE)
+	    if (CONFIG_DB_VERBOSE > 1)
 		syslog(LOG_DEBUG, "%s: starting txn %lu", where,
 		       (unsigned long) txn_id(*tid));
 	}
@@ -759,7 +759,7 @@
 		   db_strerror(r));
 	    return CYRUSDB_IOERROR;
 	}
-	if (CONFIG_DB_VERBOSE)
+	if (CONFIG_DB_VERBOSE > 1)
 	    syslog(LOG_DEBUG, "mystore: starting txn %lu",
 		   (unsigned long) txn_id(tid));
     }
@@ -783,7 +783,7 @@
 		goto restart;
 	    }
 	} else {
-	    if (CONFIG_DB_VERBOSE)
+	    if (CONFIG_DB_VERBOSE > 1)
 		syslog(LOG_DEBUG, "mystore: committing txn %lu",
 		       (unsigned long) txn_id(tid));
 	    r = txn_commit(tid, txnflags);
@@ -869,7 +869,7 @@
 		   db_strerror(r));
 	    return CYRUSDB_IOERROR;
 	}
-	if (CONFIG_DB_VERBOSE)
+	if (CONFIG_DB_VERBOSE > 1)
 	    syslog(LOG_DEBUG, "mydelete: starting txn %lu",
 		   (unsigned long) txn_id(tid));
     }
@@ -892,7 +892,7 @@
 		goto restart;
 	    }
 	} else {
-	    if (CONFIG_DB_VERBOSE)
+	    if (CONFIG_DB_VERBOSE > 1)
 		syslog(LOG_DEBUG, "mydelete: committing txn %lu",
 		       (unsigned long) txn_id(tid));
 	    r = txn_commit(tid, txnflags);
@@ -940,7 +940,7 @@
 
     assert(dbinit && tid);
 
-    if (CONFIG_DB_VERBOSE)
+    if (CONFIG_DB_VERBOSE > 1)
 	syslog(LOG_DEBUG, "mycommit: committing txn %lu",
 	       (unsigned long) txn_id(t));
     r = txn_commit(t, txnflags);
Index: lib/imapoptions
===================================================================
RCS file: /cvs/src/cyrus/lib/imapoptions,v
retrieving revision 1.53
diff -u -r1.53 imapoptions
--- lib/imapoptions	22 Apr 2008 11:06:03 -0000	1.53
+++ lib/imapoptions	14 Jul 2008 20:44:55 -0000
@@ -99,7 +99,7 @@
 /* The list of userids with administrative rights.  Separate each userid
    with a space.  Sites using Kerberos authentication may use
    separate "admin" instances.
-.PP
+.IP
    Note that accounts used by users should not be administrators.
    Administrative accounts should not receive mail.  That is, if user
    "jbRo" is a user reading mail, he should not also be in the admins line.
@@ -130,15 +130,15 @@
 
 { "allowapop", 1, SWITCH }
 /* Allow use of the POP3 APOP authentication command.
-.PP
+.IP
   Note that this command requires that SASL is compiled with APOP
   support, that the plaintext passwords are available in a SASL auxprop
   backend (eg. sasldb), and that the system can provide enough entropy
-  (eg. from /dev/urandom) to create a challenge in the banner. */
+  (e.g. from /dev/urandom) to create a challenge in the banner. */
 
 { "allownewnews", 0, SWITCH }
 /* Allow use of the NNTP NEWNEWS command.
-.PP
+.IP
   Note that this is a very expensive command and should only be
   enabled when absolutely necessary. */
 
@@ -148,7 +148,7 @@
 { "allowusermoves", 0, SWITCH }
 /* Allow moving user accounts (with associated meta-data) via RENAME
    or XFER.
-.PP
+.IP
   Note that measures should be taken to make sure that the user being
   moved is not logged in, and can not login during the move.  Failure
   to do so may result in the user's meta-data (seen state,
@@ -157,7 +157,7 @@
 { "altnamespace", 0, SWITCH }
 /* Use the alternate IMAP namespace, where personal folders reside at the
    same level in the hierarchy as INBOX.
-.PP
+.IP
    This option ONLY applies where interaction takes place with the
    client/user.  Currently this is limited to the IMAP protocol (imapd)
    and Sieve scripts (lmtpd).  This option does NOT apply to admin tools
@@ -166,7 +166,8 @@
    plus-addressing. */
 
 { "annotation_db", "skiplist", STRINGLIST("berkeley", "berkeley-hash", "skiplist")}
-/* The cyrusdb backend to use for mailbox annotations. */
+/* The cyrusdb backend to use for mailbox annotations.  This database
+   contains mailbox and server (blank mailbox key) annotation texts. */
 
 { "anyoneuseracl", 1, SWITCH }
 /* Should non-admin users be allowed to set ACLs for the 'anyone'
@@ -238,7 +239,8 @@
 
 { "duplicate_db", "berkeley-nosync", STRINGLIST("berkeley", "berkeley-nosync", "berkeley-hash", "berkeley-hash-nosync", "skiplist")}
 /* The cyrusdb backend to use for the duplicate delivery suppression
-   and sieve. */
+   and sieve.  This database stores all message-ID values and so a
+   hash-style DB like "berkeley-nosync" is most efficient.  */
 
 { "duplicatesuppression", 1, SWITCH }
 /* If enabled, lmtpd will suppress delivery of a message to a mailbox if
@@ -278,9 +280,9 @@
 { "fulldirhash", 0, SWITCH }
 /* If enabled, uses an improved directory hashing scheme which hashes
    the entire username instead of using just the first letter.  This
-   changes hash algorithm used for quota and user directories and if
-   \fIhashimapspool\fR is enabled, the entire mail spool.
-.PP
+   changes hash algorithm used for quota, sieve, and user directories
+   and, if \fIhashimapspool\fR is enabled, the entire mail spool.
+.IP
    Note that this option can NOT be changed on a live system.  The
    server must be quiesced and then the directories moved with the
    \fBrehash\fR utility. */
@@ -515,8 +517,20 @@
    failure won't occur until the mailbox is already over quota. */
 
 { "lmtpsocket", "{configdirectory}/socket/lmtp", STRING }
-/* Unix domain socket that lmtpd listens on, used by deliver(8). This should
-   match the path specified in cyrus.conf(5). */
+/* The pathname of the Unix domain socket, or the hostname, that
+   lmtpd(8) listens on.  This value is used by deliver(8).  This
+   should match the path specified in cyrus.conf(5), or be the name of
+   the host running the master(8) daemon listening on the LMTP
+   service.
+
+   Note that only admins (or lmtp_admins) may authenticate to lmtpd(8), and for
+   AUTH PLAIN you'll need allowplaintext or at least lmtp_allowplaintext turned
+   on too.  lmtpd(8) must _not_ be run with '-a' either.
+
+   deliver(8) will deliver to a remote LMTP server if this option is set, and
+   it will authenticate (using AUTH PLAIN(?)) using the name given in
+   proxy_authname and the password given by
+   <LMTPSOCKETUNQALIFIEDHOST>_password, or proxy_password. */
 
 # xxx how does this tie into virtual domains?
 { "loginrealms", "", STRING }
@@ -546,7 +560,9 @@
 /* The cyrusdb backend to use for mailbox keys. */
 
 { "mboxlist_db", "skiplist", STRINGLIST("flat", "berkeley", "berkeley-hash", "skiplist")}
-/* The cyrusdb backend to use for the mailbox list. */
+/* The cyrusdb backend to use for the mailbox list.  The data part
+   is short so if it can be bsearch()ed efficiently then it is best as
+   a "flat" file, else a "skiplist" is next best to avoid lock contention. */
 
 { "metapartition_files", "", BITFIELD("header", "index", "cache", "expunge", "squat") }
 /* Space-separated list of metadata files to be stored on a
@@ -767,8 +783,9 @@
    "+shared.blah" would be used. */ 
 
 { "proxy_authname", "proxy", STRING }
-/* The authentication name to use when authenticating to a backend server
-   in the Cyrus Murder. */
+/* The authentication name to use when authenticating to a backend server in
+   the Cyrus Murder, and also by deliver(8) (since deliver(8) uses the same
+   backend client code for lmtpsocket connections to remote hosts) . */
 
 { "proxy_password", NULL, STRING }
 /* The default password to use when authenticating to a backend server
@@ -803,7 +820,8 @@
    (defaults to configdir/ptclient/ptsock) */
 
 { "ptscache_db", "berkeley", STRINGLIST("berkeley", "berkeley-hash", "skiplist")}
-/* The cyrusdb backend to use for the pts cache. */
+/* The cyrusdb backend to use for the PTS cache when using the
+   auth_krb_pts authorization method (default: berkeley). */
 
 { "ptscache_timeout", 10800, INT }
 /* The timeout (in seconds) for the PTS cache database when using the
@@ -820,7 +838,11 @@
    of realms specified by the afspts_localrealms option) */
 
 { "quota_db", "quotalegacy", STRINGLIST("flat", "berkeley", "berkeley-hash", "skiplist", "quotalegacy")}
-/* The cyrusdb backend to use for quotas. */
+/* The cyrusdb backend to use for quotas.  This database stores the
+   quotas for all valid mailbox roots.  The data part is short so if
+   it can be bsearch()ed efficiently then it is best as a "flat" file,
+   else a "skiplist" is next best to avoid lock contention.
+   Use the default of "quotalegacy" if upgrading from an older release. */
 
 { "quotawarn", 90, INT }
 /* The percent of quota utilization over which the server generates
@@ -876,9 +898,13 @@
    Possible values include "auxprop", "saslauthd", and "pwcheck". */
 
 { "seenstate_db", "skiplist", STRINGLIST("flat", "berkeley", "berkeley-hash", "skiplist")}
-/* The cyrusdb backend to use for the seen state. */
+/* The cyrusdb backend to use for the seen state.  This database
+   contains one record for every mailbox and lists the unique-IDs of
+   the last-read and all previously read messages.  The default of
+   "skiplist" avoids lock contention best, and a "flat" DB would suffice
+   if most mailboxes contain few (read) messages. */
 
-{ "sendmail", "/usr/lib/sendmail", STRING }
+{ "sendmail", "/usr/sbin/sendmail", STRING }
 /* The pathname of the sendmail executable.  Sieve invokes sendmail
    for sending rejections, redirects and vacation responses. */
 
@@ -928,19 +954,22 @@
 /* Maximum number of sieve scripts any user may have, enforced at
    submission by timsieved(8). */
    
-{ "sievedir", "/usr/sieve", STRING }
+{ "sievedir", "/var/imap/sieve", STRING }
 /* If sieveusehomedir is false, this directory is searched for Sieve
    scripts. */
 
 { "sievenotifier", NULL, STRING }
 /* Notifyd(8) method to use for "SIEVE" notifications.  If not set, "SIEVE"
    notifications are disabled.
-.PP
+.IP
    This method is only used when no method is specified in the script. */
 
 { "sieveusehomedir", 0, SWITCH }
 /* If enabled, lmtpd will look for Sieve scripts in user's home
-   directories: ~user/.sieve. */
+   directories: ~user/.sieve.  These scripts must be readable by the
+   Cyrus user.  This option overrides siveusehomedir.
+   NOTE:  This option is incompatible with timesieved(8) (and thus
+   sieveshell(1) as well). */
 
 { "singleinstancestore", 1, SWITCH }
 /* If enabled, imapd, lmtpd and nntpd attempt to only write one copy
@@ -968,7 +997,8 @@
    use with caution. */ 
 
 { "subscription_db", "flat", STRINGLIST("flat", "berkeley", "berkeley-hash", "skiplist")}
-/* The cyrusdb backend to use for the subscriptions list. */
+/* The cyrusdb backend to use for the subscriptions list.  This is a
+   per-user database just listing the mailboxes the user is subscribed to. */
 
 { "statuscache", 0, SWITCH }
 /* Enable/disable the imap status cache. */
@@ -1052,7 +1082,7 @@
 { "umask", "077", STRING }
 /* The umask value used by various Cyrus IMAP programs. */
 
-{ "username_tolower", 1, SWITCH }
+{ "username_tolower", 0, SWITCH }
 /* Convert usernames to all lowercase before login/authenticate.  This
    is useful with authentication backends which ignore case during
    username lookups (such as LDAP).  */
Index: lib/libconfig.c
===================================================================
RCS file: /cvs/src/cyrus/lib/libconfig.c,v
retrieving revision 1.20
diff -u -r1.20 libconfig.c
--- lib/libconfig.c	22 May 2008 16:01:57 -0000	1.20
+++ lib/libconfig.c	14 Jul 2008 20:44:55 -0000
@@ -70,8 +70,8 @@
 /* cached configuration variables accessible to the external world */
 const char *config_filename= NULL;       /* filename of configuration file */
 const char *config_dir = NULL;		 /* ie /var/imap */
-const char *config_defpartition = NULL;  /* /var/spool/imap */
-const char *config_servername= NULL;	 /* gethostname() */
+char *config_defpartition = NULL;	/* /var/spool/imap */
+char *config_servername= NULL;		/* gethostname() */
 enum enum_value config_serverinfo;	 /* on */
 const char *config_mupdate_server = NULL;/* NULL */
 const char *config_defdomain = NULL;     /* NULL */
@@ -260,8 +260,8 @@
     }
 
     /* Look up default partition */
-    config_defpartition = config_getstring(IMAPOPT_DEFAULTPARTITION);
-    for (p = (char *)config_defpartition; *p; p++) {
+    config_defpartition = xstrdup(config_getstring(IMAPOPT_DEFAULTPARTITION));
+    for (p = config_defpartition; *p; p++) {
 	if (!isalnum((unsigned char) *p))
 	  fatal("defaultpartition option contains non-alphanumeric character",
 		EC_CONFIG);
@@ -283,10 +283,10 @@
     config_defdomain = config_getstring(IMAPOPT_DEFAULTDOMAIN);
 
     /* look up the hostname and info we should present to the user */
-    config_servername = config_getstring(IMAPOPT_SERVERNAME);
+    config_servername = xstrdup(config_getstring(IMAPOPT_SERVERNAME));
     if (!config_servername) {
 	config_servername = xmalloc(sizeof(char) * 256);
-	gethostname((char *) config_servername, 256);
+	gethostname(config_servername, 256);
     }
     config_serverinfo = config_getenum(IMAPOPT_SERVERINFO);
 
@@ -333,7 +333,7 @@
 	fatal(buf, EC_CONFIG);
     }
     else {
-	hash_insert(filename, (void*) 0xDEADBEEF, &includehash);
+	hash_insert(filename, (void*) 0xDEADBEEFU, &includehash);
     }
     
     len = 0;
@@ -487,10 +487,10 @@
 	    }
 	    case OPT_INT:
 	    {
-		long val;
+		long ival;
 		char *ptr;
 		
-		val = strtol(p, &ptr, 0);
+		ival = strtol(p, &ptr, 0);
 		if (!ptr || *ptr != '\0') {
 		    /* error during conversion */
 		    sprintf(errbuf, "non-integer value for %s in line %d",
@@ -498,7 +498,7 @@
 		    fatal(errbuf, EC_CONFIG);
 		}
 
-		imapopts[opt].val.i = val;
+		imapopts[opt].val.i = ival;
 		break;
 	    }
 	    case OPT_SWITCH:
Index: lib/libconfig.h
===================================================================
RCS file: /cvs/src/cyrus/lib/libconfig.h,v
retrieving revision 1.8
diff -u -r1.8 libconfig.h
--- lib/libconfig.h	11 Apr 2008 20:07:00 -0000	1.8
+++ lib/libconfig.h	14 Jul 2008 20:44:55 -0000
@@ -68,8 +68,8 @@
 /* cached configuration variables accessable to external world */
 extern const char *config_filename;
 extern const char *config_dir;
-extern const char *config_defpartition;
-extern const char *config_servername;
+extern char *config_defpartition;
+extern char *config_servername;
 extern enum enum_value config_serverinfo;
 extern const char *config_mupdate_server;
 extern const char *config_defdomain;
Index: master/master.c
===================================================================
RCS file: /cvs/src/cyrus/master/master.c,v
retrieving revision 1.111
diff -u -r1.111 master.c
--- master/master.c	15 Apr 2008 18:11:52 -0000	1.111
+++ master/master.c	14 Jul 2008 20:44:57 -0000
@@ -1286,9 +1286,8 @@
     free(cmd);
 }
 
-void add_service(const char *name, struct entry *e, void *rock)
+void add_service(const char *name, struct entry *e, void *ignore_err)
 {
-    int ignore_err = (int) rock;
     char *cmd = xstrdup(masterconf_getstring(e, "cmd", ""));
     int prefork = masterconf_getint(e, "prefork", 0);
     int babysit = masterconf_getswitch(e, "babysit", 0);
@@ -1420,9 +1419,8 @@
 	       (int) Services[i].maxfds);
 }
 
-void add_event(const char *name, struct entry *e, void *rock)
+void add_event(const char *name, struct entry *e, void *ignore_err)
 {
-    int ignore_err = (int) rock;
     char *cmd = xstrdup(masterconf_getstring(e, "cmd", ""));
     int period = 60 * masterconf_getint(e, "period", 0);
     int at = masterconf_getint(e, "at", -1), hour, min;
Index: master/service-thread.c
===================================================================
RCS file: /cvs/src/cyrus/master/service-thread.c,v
retrieving revision 1.21
diff -u -r1.21 service-thread.c
--- master/service-thread.c	24 Mar 2008 17:47:41 -0000	1.21
+++ master/service-thread.c	14 Jul 2008 20:44:57 -0000
@@ -154,6 +154,8 @@
 {
     int fdflags;
     int fd;
+    struct sockaddr_in from;		/* the accept socket address */
+    size_t len;
     char *p = NULL, *service;
     struct request_info request;
     int opt;
@@ -230,7 +232,7 @@
 	    syslog(LOG_DEBUG, "debugger returned exit status: %d", ret);
 	}
     }
-    syslog(LOG_DEBUG, "executed");
+    syslog(LOG_DEBUG, "started new %s service-thread process", service);
 
     /* set close on exec */
     fdflags = fcntl(LISTEN_FD, F_GETFD, 0);
@@ -262,7 +264,7 @@
 	/* ok, listen to this socket until someone talks to us */
 	fd = -1;
 	while (fd < 0) { /* loop until we succeed */
-	    fd = accept(LISTEN_FD, NULL, NULL);
+	    fd = accept(LISTEN_FD, (struct sockaddr *) &from, (socklen_t *) &len);
 	    if (fd < 0) {
 		switch (errno) {
 		case ENETDOWN:
@@ -299,7 +301,8 @@
 	    continue;
 	}
 	
-	syslog(LOG_DEBUG, "accepted connection");
+	/* XXX should use getnameinfo(..., NI_NUMERICHOST) */
+	syslog(LOG_DEBUG, "accepted connection from [%s]", inet_ntoa(from.sin_addr));
 
 	use_count++;
 	notify_master(STATUS_FD, MASTER_SERVICE_CONNECTION_MULTI);
Index: master/service.c
===================================================================
RCS file: /cvs/src/cyrus/master/service.c,v
retrieving revision 1.59
diff -u -r1.59 service.c
--- master/service.c	24 Mar 2008 17:47:41 -0000	1.59
+++ master/service.c	14 Jul 2008 20:44:57 -0000
@@ -262,6 +262,8 @@
     ino_t start_ino;
     off_t start_size;
     time_t start_mtime;
+    struct sockaddr_in from;		/* the accept socket address */
+    size_t len;
     
     opterr = 0; /* disable error reporting,
 		   since we don't know about service-specific options */
@@ -358,7 +360,7 @@
 	    syslog(LOG_DEBUG, "debugger returned exit status: %d", ret);
 	}
     }
-    syslog(LOG_DEBUG, "executed");
+    syslog(LOG_DEBUG, "started new %s service process", service);
 
     /* set close on exec */
     fdflags = fcntl(LISTEN_FD, F_GETFD, 0);
@@ -433,7 +435,13 @@
 	    }
 
 	    if (soctype == SOCK_STREAM) {
-		fd = accept(LISTEN_FD, NULL, NULL);
+		/*
+		 * clear these
+		 */
+		len = sizeof(from);
+		(void) memset((char *) &from, '\0', len);
+
+		fd = accept(LISTEN_FD, (struct sockaddr *) &from, (socklen_t *) &len);
 		if (fd < 0) {
 		    switch (errno) {
 		    case ENETDOWN:
@@ -515,7 +523,8 @@
 	}
 	
 	notify_master(STATUS_FD, MASTER_SERVICE_UNAVAILABLE);
-	syslog(LOG_DEBUG, "accepted connection");
+	/* XXX should use getnameinfo(..., NI_NUMERICHOST) */
+	syslog(LOG_DEBUG, "accepted connection from [%s]", inet_ntoa(from.sin_addr));
 
 	if (fd != 0 && dup2(fd, 0) < 0) {
 	    syslog(LOG_ERR, "can't duplicate accepted socket: %m");
Index: master/conf/normal.conf
===================================================================
RCS file: /cvs/src/cyrus/master/conf/normal.conf,v
retrieving revision 1.12
diff -u -r1.12 normal.conf
--- master/conf/normal.conf	30 Mar 2006 16:01:39 -0000	1.12
+++ master/conf/normal.conf	14 Jul 2008 20:44:57 -0000
@@ -5,7 +5,7 @@
   recover	cmd="ctl_cyrusdb -r"
 
   # this is only necessary if using idled for IMAP IDLE
-#  idled		cmd="idled"
+  idled		cmd="idled"
 }
 
 # UNIX sockets start with a slash and are put into /var/imap/socket
@@ -14,19 +14,20 @@
   imap		cmd="imapd" listen="imap" prefork=0
   imaps		cmd="imapd -s" listen="imaps" prefork=0
   pop3		cmd="pop3d" listen="pop3" prefork=0
-  pop3s		cmd="pop3d -s" listen="pop3s" prefork=0
+# pop3s 	cmd="pop3d -s" listen="pop3s" prefork=0
+
   sieve		cmd="timsieved" listen="sieve" prefork=0
 
   # these are only necessary if receiving/exporting usenet via NNTP
-#  nntp		cmd="nntpd" listen="nntp" prefork=0
-#  nntps		cmd="nntpd -s" listen="nntps" prefork=0
+# nntp		cmd="nntpd" listen="nntp" prefork=0
+# nntps		cmd="nntpd -s" listen="nntps" prefork=0
 
   # at least one LMTP is required for delivery
-#  lmtp		cmd="lmtpd" listen="lmtp" prefork=0
+# lmtp		cmd="lmtpd" listen="lmtp" prefork=0
   lmtpunix	cmd="lmtpd" listen="/var/imap/socket/lmtp" prefork=0
 
   # this is required if using notifications
-#  notify	cmd="notifyd" listen="/var/imap/socket/notify" proto="udp" prefork=1
+# notify	cmd="notifyd" listen="/var/imap/socket/notify" proto="udp" prefork=1
 }
 
 EVENTS {
@@ -35,8 +36,11 @@
 
   # this is only necessary if using duplicate delivery suppression,
   # Sieve or NNTP
-  delprune	cmd="cyr_expire -E 3" at=0400
+  delprune	cmd="cyr_expire -E 3" at=0200
 
   # this is only necessary if caching TLS sessions
-  tlsprune	cmd="tls_prune" at=0400
+  tlsprune	cmd="tls_prune" at=0200
+
+  # run the SQUAT indexer once per day at 5am
+  squatter	cmd="squatter -s -r user" at=0500
 }
Index: sieve/script.c
===================================================================
RCS file: /cvs/src/sieve/script.c,v
retrieving revision 1.67
diff -u -r1.67 script.c
--- sieve/script.c	24 Mar 2008 20:08:46 -0000	1.67
+++ sieve/script.c	14 Jul 2008 20:44:58 -0000
@@ -50,6 +50,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
+#include <errno.h>
 #include <syslog.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -526,7 +527,11 @@
     if (!fname || !ret) return SIEVE_FAIL;
     
     if (stat(fname, &sbuf) == -1) {
-	syslog(LOG_DEBUG, "IOERROR: fstating sieve script %s: %m", fname);
+	if (errno == ENOENT) {
+	    syslog(LOG_DEBUG, "no sieve script %s", fname); /* XXX just noise? */
+	} else {
+	    syslog(LOG_ERR, "IOERROR: error stating sieve script %s: %m", fname);
+	}
 	return SIEVE_FAIL;
     }
 
Index: sieve/sieved.c
===================================================================
RCS file: /cvs/src/sieve/sieved.c,v
retrieving revision 1.8
diff -u -r1.8 sieved.c
--- sieve/sieved.c	24 Mar 2008 20:08:46 -0000	1.8
+++ sieve/sieved.c	14 Jul 2008 20:44:58 -0000
@@ -75,19 +75,19 @@
 /*this is called by xmalloc*/
 void fatal(const char *s, int code)
 {  
-    printf("Fatal error: %s (%d)\r\n", s, code);
+    fprintf(stderr, "Fatal error: %s (%d)\r\n", s, code);
                            
     exit(1);
 }
 
-static int load(int fd, bytecode_input_t ** d)
+static int load(char *fname, int fd, bytecode_input_t ** d)
 {  
     const char * data=NULL;
     struct stat sbuf;
     unsigned long len=0;
     
     if (fstat(fd, &sbuf) == -1) {
-	printf("IOERROR: fstating sieve script: %m");
+	fprintf(stderr, "cannot fstat sieve script %s: %m", fname);
 	return SIEVE_FAIL;
     }
     
@@ -116,14 +116,17 @@
 
     /*get script*/
     script_fd = open(argv[1], O_RDONLY);
-    if (script_fd == -1) 
-    {
-	printf("can not open script '%s'\n", argv[1]);
+    if (script_fd == -1) {
+	fprintf(stderr, "can not open script '%s'\n", argv[1]);
 	exit(1);
     }
     
-    len=load(script_fd,&bc);
+    len=load(argv[1], script_fd, &bc);
     close(script_fd);
+    if (len == SIEVE_FAIL) {
+	fprintf(stderr, "can not load script '%s'\n", argv[1]);
+	exit(1);
+    }
     
     if (bc) {
 	dump2(bc, len );
Index: sieve/sievetest.1
===================================================================
RCS file: sieve/sievetest.1
diff -N sieve/sievetest.1
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sieve/sievetest.1	14 Jul 2008 20:44:58 -0000
@@ -0,0 +1,28 @@
+.Dd December 1, 2006
+.Dt SIEVETEST 1
+.Os Cyrus IMAPd
+.Sh NAME
+.Nm sievetest
+.Nd test SIEVE scripts
+.Sh SYNOPSIS
+.Nm
+.Op Fl f
+.Ar message-file
+.Ar script
+.Nm
+.Op Fl f
+.Fl v Ar script
+.Ar message-file
+.Sh DESCRIPTION
+The
+.Nm
+program tests SIEVE scripts.
+.Sh EXIT STATUS
+.Sh EXAMPLES
+.Sh DIAGNOSTICS
+.Sh ERRORS
+.Sh SEE ALSO
+.Sh STANDARDS
+.Sh HISTORY
+.Sh AUTHORS
+.Sh BUGS
Index: timsieved/actions.c
===================================================================
RCS file: /cvs/src/cyrus/timsieved/actions.c,v
retrieving revision 1.44
diff -u -r1.44 actions.c
--- timsieved/actions.c	22 Apr 2008 13:11:19 -0000	1.44
+++ timsieved/actions.c	14 Jul 2008 20:44:59 -0000
@@ -97,7 +97,7 @@
       sieve_dir = (char *) config_getstring(IMAPOPT_SIEVEDIR);
   } else {
       /* can't use home directories with timsieved */
-      syslog(LOG_ERR, "can't use home directories");
+      syslog(LOG_ERR, "can't use home directories and '%s' not set", IMAPOPT_SIEVEDIR);
 
       return TIMSIEVE_FAIL;
   }
Index: tools/dohash
===================================================================
RCS file: /cvs/src/cyrus/tools/dohash,v
retrieving revision 1.13
diff -u -r1.13 dohash
--- tools/dohash	24 Mar 2008 20:25:22 -0000	1.13
+++ tools/dohash	14 Jul 2008 20:44:59 -0000
@@ -1,5 +1,6 @@
-#!/bin/sh
-#
+#! /bin/sh
+# -*-perl-*-
+# 
 # Copyright (c) 1994-2008 Carnegie Mellon University.  All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without


More information about the Cyrus-devel mailing list