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