[PATCH] Maildir support

Martin Johansson martin at fatbob.nu
Tue Aug 14 00:42:23 EST 2001


Hi!

Here is a patch against openssh-2.9.p2 that adds support for Maildir style
mailboxes, the way which qmail prefers to store mails in.

The changes/additions are the following:
1) $MAIL env. variable is set to $HOME/Maildir if it exists, or else to
   _PATH_MAIL/$USER.
2) Mail checking (the main purpose of this patch) is done by first checking
   whether $MAIL is a regular file or directory. If it is a file, it is assumed
   to be an mbox format mailbox, if it is a directory it is assumed to be a
   Maildir format mailbox, and the checking is done accordingly.
3) A new configure option: --enable-maildir

mbox functionality should be unaffected (if $HOME/Maildir doesn't exist) even
if Maildir support is enabled (untested, since I only use Maildir on my system).

The status of the patch is Works For Me (TM), and I haven't tested all possible
configurations.
BTW, I tested this on a RedHat 7.1 box with glibc 2.2.2.

Regards
/Martin Johansson

diff -ur --exclude=configure openssh-2.9p2/config.h.in openssh-2.9p2.maildir/config.h.in
--- openssh-2.9p2/config.h.in	Sun Jun 17 06:09:47 2001
+++ openssh-2.9p2.maildir/config.h.in	Fri Aug 10 12:53:30 2001
@@ -237,8 +237,11 @@
 /* to the conversation function with an extra level of indirection */
 #undef PAM_SUN_CODEBASE
 
-/* Set this to your mail directory if you don't have maillock.h */
+/* Set this to your mail directory if you don't have maillock.h or paths.h */
 #undef MAIL_DIRECTORY
+
+/* Set this to enable support for Maildir style mailboxes. */
+#undef MAILDIR_FORMAT
 
 /* Data types */
 #undef HAVE_U_INT
diff -ur --exclude=configure openssh-2.9p2/configure.in openssh-2.9p2.maildir/configure.in
--- openssh-2.9p2/configure.in	Mon May 28 19:21:44 2001
+++ openssh-2.9p2.maildir/configure.in	Mon Aug 13 14:38:26 2001
@@ -1632,6 +1632,23 @@
 )
 AC_SUBST(SSHMODE)
 
+AC_MSG_CHECKING(whether to enable support for Maildir style mailboxes)
+AC_ARG_ENABLE(maildir,
+[  --enable-maildir	  Enable support for Maildir format mailbox in \$HOME/Maildir
+  --disable-maildir       Disable support for Maildir format mailbox (default)],
+[ case "$enableval" in
+  no)
+       AC_MSG_RESULT(no)
+       MAILDIR_FORMAT=no
+       ;;
+  *)   AC_MSG_RESULT(yes)
+       MAILDIR_FORMAT=yes
+       AC_DEFINE(MAILDIR_FORMAT)
+       ;;
+  esac ],
+  AC_MSG_RESULT(no)
+  MAILDIR_FORMAT=no
+)
 
 # Where to place sshd.pid
 piddir=/var/run
@@ -1940,6 +1957,7 @@
 echo "   IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
 echo "      Use IPv4 by default hack: $IPV4_HACK_MSG"
 echo "       Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
+echo "         Maildir style mailbox: $MAILDIR_FORMAT"
 
 if test ! -z "$bsd_auth"; then
 	echo "              BSD Auth support: yes"
diff -ur --exclude=configure openssh-2.9p2/session.c openssh-2.9p2.maildir/session.c
--- openssh-2.9p2/session.c	Sun Jun 17 05:40:51 2001
+++ openssh-2.9p2.maildir/session.c	Mon Aug 13 14:32:47 2001
@@ -1019,6 +1019,82 @@
 }
 #endif /* defined(HAVE_GETUSERATTR) */
 
+void
+do_mailcheck(const char *mailbox)
+{
+    struct stat mailstat;
+    
+	if (stat(mailbox, &mailstat) != 0) {
+		debug("Mailcheck failed: %s: %s", mailbox,
+			  strerror(errno));
+		return;
+	}
+	/* mbox format mailcheck */
+	if (S_ISREG(mailstat.st_mode)) {
+		if (mailstat.st_size == 0)
+			printf("No mail.\n");
+		else if (mailstat.st_mtime < mailstat.st_atime)
+			printf("You have mail.\n");
+		else
+			printf("You have new mail.\n");
+	}
+	
+#ifdef MAILDIR_FORMAT
+	/* Maildir format mailcheck */
+	else if (S_ISDIR(mailstat.st_mode)) {
+	    char *dirname;
+	    int pathlen;
+	    DIR *newdir, *curdir;
+	    
+	    pathlen = strlen(mailbox) + 5;
+	    dirname = malloc(pathlen);
+	    
+	    snprintf(dirname, pathlen, "%s/new", mailbox);
+	    newdir = opendir(dirname);
+	    
+	    snprintf(dirname, pathlen, "%s/cur", mailbox);
+	    curdir = opendir(dirname);
+	    free(dirname);
+	    
+	    if (newdir && curdir) {
+			long newmail = -2;
+			long curmail = -2;
+			char buf[64];
+			
+			while (readdir(newdir))
+				newmail++;
+			closedir(newdir);
+			while (readdir(curdir))
+				curmail++;
+			closedir(curdir);
+			
+			if (curmail > 0 || newmail > 0) {
+				sprintf(buf, "You have ");
+				if (newmail > 0) {
+					sprintf(buf + strlen(buf), "%ld new mail%s",
+							newmail, (newmail > 1) ? "s" : "");
+				}
+				if (curmail > 0 && newmail > 0)
+					sprintf(buf + strlen(buf), " and ");
+				if (curmail > 0) {
+					sprintf(buf + strlen(buf), "%ld read mail%s", curmail,
+							(curmail > 1) ? "s" : "");
+				}
+				printf("%s.\n", buf);
+			}
+			else
+				printf("No mail.\n");
+	    }
+	    else {
+			if (newdir) closedir(newdir);
+			if (curdir) closedir(curdir);
+			debug("Mailcheck failed: Invalid Maildir");
+	    }
+	}
+	
+#endif /* #ifdef MAILDIR_FORMAT */
+}
+
 /*
  * Performs common processing for the child, such as setting up the
  * environment, closing extra file descriptors, setting the user and group
@@ -1226,6 +1302,8 @@
 #endif
 
 	if (!options.use_login) {
+		struct stat mailstat;
+		
 		/* Set basic environment. */
 		child_set_env(&env, &envsize, "USER", pw->pw_name);
 		child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
@@ -1245,10 +1323,22 @@
 # endif /* HAVE_CYGWIN */
 #endif /* HAVE_LOGIN_CAP */
 
+#ifndef MAILDIR_FORMAT
 		snprintf(buf, sizeof buf, "%.200s/%.50s",
 			 _PATH_MAILDIR, pw->pw_name);
+#else
+		snprintf(buf, sizeof buf, "%.240s/Maildir",
+			 pw->pw_dir);
+		/*
+		 * Check if $HOME/Maildir exists, otherwise set $MAIL to
+		 * _PATH_MAILDIR/$USER
+		 */
+		if (stat(buf, &mailstat) != 0) {
+			snprintf(buf, sizeof buf, "%.200s/%.50s",
+					 _PATH_MAILDIR, pw->pw_name);
+		}
+#endif
 		child_set_env(&env, &envsize, "MAIL", buf);
-
 		/* Normal systems set SHELL by default. */
 		child_set_env(&env, &envsize, "SHELL", shell);
 	}
@@ -1471,19 +1561,12 @@
 			 */
 			if (s->ttyfd != -1 && options.check_mail) {
 				char *mailbox;
-				struct stat mailstat;
-
 				mailbox = getenv("MAIL");
 				if (mailbox != NULL) {
-					if (stat(mailbox, &mailstat) != 0 ||
-					    mailstat.st_size == 0)
-						printf("No mail.\n");
-					else if (mailstat.st_mtime < mailstat.st_atime)
-						printf("You have mail.\n");
-					else
-						printf("You have new mail.\n");
+					do_mailcheck(mailbox);
 				}
 			}
+			
 			/* Start the shell.  Set initial character to '-'. */
 			buf[0] = '-';
 			strncpy(buf + 1, cp, sizeof(buf) - 1);



More information about the openssh-unix-dev mailing list