Hi!

I find ksh's option of asynchronous mail notifications quite useful.
Unfortunately, common IMAP sync'ing tools all require Maildir as local storage
format, while ksh only supports mboxes.

I made a patch that brings maildir support to ksh. Though it works, it is
rather oversimplified and probably buggy, but I hope it could be of some use
to others.

Index: bin/ksh/mail.c
===================================================================
RCS file: /var/cvs/src/bin/ksh/mail.c,v
retrieving revision 1.16
diff -u -p -r1.16 mail.c
--- bin/ksh/mail.c      16 Apr 2013 22:13:14 -0000      1.16
+++ bin/ksh/mail.c      23 Sep 2013 14:51:12 -0000
@@ -8,6 +8,7 @@
 #include "config.h"
 
 #include "sh.h"
+#include <dirent.h>
 #include <sys/stat.h>
 #include <time.h>
 
@@ -35,6 +36,27 @@ static void     munset(mbox_t *); /* fre
 static mbox_t * mballoc(char *, char *); /* allocate a new mbox */
 static void     mprintit(mbox_t *);
 
+int
+mdcheck(mbox_t *mbp)
+{
+       DIR             *md;
+       struct dirent   *mdent;
+       struct stat     stbuf;
+
+       md = opendir(mbp->mb_path);
+       while ((mdent = readdir(md)) != NULL) {
+               if (mdent->d_type ^ DT_DIR) {
+                       fstat(mdent->d_fileno, &stbuf);
+                       if (mbp->mb_mtime < stbuf.st_mtime) {
+                               closedir(md);
+                               return 1;
+                       }
+               }
+       }
+       closedir(md);
+       return 0;
+}
+
 void
 mcheck(void)
 {
@@ -57,13 +79,15 @@ mcheck(void)
                        mbp = NULL;
 
                while (mbp) {
-                       if (mbp->mb_path && stat(mbp->mb_path, &stbuf) == 0 &&
-                           S_ISREG(stbuf.st_mode)) {
-                               if (stbuf.st_size &&
-                                   mbp->mb_mtime != stbuf.st_mtime &&
-                                   stbuf.st_atime <= stbuf.st_mtime)
-                                       mprintit(mbp);
-                               mbp->mb_mtime = stbuf.st_mtime;
+                       if (mbp->mb_path && stat(mbp->mb_path, &stbuf) == 0) {
+                               if (mbp->mb_mtime != stbuf.st_mtime) {
+                                       if (S_ISREG(stbuf.st_mode) && 
stbuf.st_size &&
+                                                       stbuf.st_atime <= 
stbuf.st_mtime)
+                                               mprintit(mbp);
+                                       else if (S_ISDIR(stbuf.st_mode) && 
mdcheck(mbp))
+                                               mprintit(mbp);
+          mbp->mb_mtime = stbuf.st_mtime;
+                               }
                        } else {
                                /*
                                 * Some mail readers remove the mail
@@ -166,10 +190,16 @@ mballoc(char *p, char *m)
        mbp->mb_next = NULL;
        mbp->mb_path = p;
        mbp->mb_msg = m;
-       if (stat(mbp->mb_path, &stbuf) == 0 && S_ISREG(stbuf.st_mode))
+       if (stat(mbp->mb_path, &stbuf) == 0 &&
+                       (S_ISDIR(stbuf.st_mode) || S_ISREG(stbuf.st_mode))) {
+               if (S_ISDIR(stbuf.st_mode)) {
+                       mbp->mb_path = (char *)alloc(strlen(p)+4, APERM);
+                       sprintf(mbp->mb_path, "%s/new", p);
+               }
                mbp->mb_mtime = stbuf.st_mtime;
-       else
+       } else
                mbp->mb_mtime = 0;
+
        return(mbp);
 }
 
@@ -177,6 +207,7 @@ static void
 mprintit(mbox_t *mbp)
 {
        struct tbl      *vp;
+       char *p;
 
 #if 0
        /*
@@ -187,8 +218,12 @@ mprintit(mbox_t *mbp)
         */
        if (!Flag(FSH))
 #endif
+       {
+               *(p = strrchr(mbp->mb_path, '/')) = '\0';
                /* Ignore setstr errors here (arbitrary) */
                setstr((vp = local("_", false)), mbp->mb_path, 
KSH_RETURN_ERROR);
+               *p = '/';
+       }
 
        shellf("%s\n", substitute(mbp->mb_msg ? mbp->mb_msg : MBMESSAGE, 0));
 

-- 
Dmitrij D. Czarkoff

Reply via email to