nmh-workers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Nmh-workers] Maildir support for inc


From: David Malone
Subject: [Nmh-workers] Maildir support for inc
Date: Tue, 27 Jul 2004 23:38:51 +0100

While searching for Maildir support for inc, I found that someone
here was looking for it. Since I didn't manage to find Maildir
support anywhere, I've whipped up this patch (against 1.0.4).  It
seems to work in my (very basic) tests and might be a useful starting
point if someone else wanted to work on it.

        David.

--- uip/inc.c.ORIG      Fri Mar 17 20:11:04 2000
+++ uip/inc.c   Tue Jul 27 23:14:05 2004
@@ -122,6 +122,7 @@
 #define INC_POP   1
 
 static int inc_type;
+static DIR *Maildir = NULL;
 static int snoop = 0;
 
 #ifdef POP
@@ -446,6 +447,18 @@
        }
        if (stat (newmail, &s1) == NOTOK || s1.st_size == 0)
            adios (NULL, "no mail to incorporate");
+       if (s1.st_mode & S_IFDIR) {
+           struct dirent *de;
+           cp = concat (newmail, "/new", NULL);
+           if ((Maildir = opendir(cp)) == NULL)
+               adios (NULL, "unable to open %s", cp);
+           free (cp);
+           while ((de = readdir(Maildir)) != NULL && de->d_name[0] == '.')
+                       continue;
+           if (de == NULL)
+               adios (NULL, "no mail to incorporate");
+           rewinddir(Maildir);
+       }
     }
 
 #ifdef POP
@@ -482,7 +495,7 @@
 go_to_it:
 #endif /* POP */
 
-    if (inc_type == INC_FILE) {
+    if (inc_type == INC_FILE && Maildir == NULL) {
        if (access (newmail, W_OK) != NOTOK) {
            locked++;
            if (trnflag) {
@@ -693,7 +706,7 @@
     /*
      * Get the mail from file (usually mail spool)
      */
-    if (inc_type == INC_FILE) {
+    if (inc_type == INC_FILE && Maildir == NULL) {
        m_unknown (in);         /* the MAGIC invocation... */
        hghnum = msgnum = mp->hghmsg;
        for (i = 0;;) {
@@ -764,6 +777,104 @@
            }
            break;
        }
+    } else { /* Maildir inbox to process */
+       char *sp;
+       struct dirent *de;
+       FILE *sf;
+
+       hghnum = msgnum = mp->hghmsg;
+       for (i = 0; (de = readdir(Maildir)) != NULL;i++) {
+           if (de->d_name[0] == '.')
+               continue;
+           msgnum++;
+           /*
+            * Check if we need to allocate more space for message status.
+            * If so, then add space for an additional 100 messages.
+            */
+           if (msgnum >= mp->hghoff
+               && !(mp = folder_realloc (mp, mp->lowoff, mp->hghoff + 100))) {
+               advise (NULL, "unable to allocate folder storage");
+               i = NOTOK;
+               break;
+           }
+
+           sp = concat (newmail, "/new/", de->d_name, NULL);
+           cp = getcpy (m_name (msgnum));
+           pf = NULL;
+           if (!trnflag || link(sp, cp) == -1) {
+               static char buf[65536];
+               size_t nrd;
+
+               if ((sf = fopen (sp, "r")) == NULL)
+                   adios (sp, "unable to read for copy");
+               if ((pf = fopen (cp, "w+")) == NULL)
+                   adios (cp, "unable to write for copy");
+               while ((nrd = fread(buf, 1, sizeof(buf), sf)) > 0)
+                   if (fwrite(buf, 1, nrd, pf) != nrd)
+                       break;
+               if (ferror(sf) || fflush(pf) || ferror(pf)) {
+                       int e = errno;
+                       fclose(pf); fclose(sf); unlink(cp);
+                       errno = e;
+                       adios(cp, "copy error %s -> %s", sp, cp);
+               }
+               fclose (sf);
+               sf = NULL;
+           } 
+           if (pf == NULL && (pf = fopen (cp, "r")) == NULL)
+               adios (cp, "not available");
+           chmod (cp, m_gmprot ());
+
+           fseek (pf, 0L, SEEK_SET);
+           switch (p = scan (pf, msgnum, 0, nfs, width,
+                             msgnum == mp->hghmsg + 1 && chgflag,
+                             1, NULL, stop - start, noisy)) {
+           case SCNEOF: 
+               printf ("%*d  empty\n", DMAXFOLDER, msgnum);
+               break;
+
+           case SCNFAT:
+               trnflag = 0;
+               noisy++;
+               /* advise (cp, "unable to read"); already advised */
+               /* fall thru */
+
+           case SCNERR:
+           case SCNNUM: 
+               break;
+
+           case SCNMSG: 
+           case SCNENC:
+           default: 
+               if (aud)
+                   fputs (scanl, aud);
+# ifdef MHE
+               if (mhe)
+                   fputs (scanl, mhe);
+# endif /* MHE */
+               if (noisy)
+                   fflush (stdout);
+               if (!packfile) {
+                   clear_msg_flags (mp, msgnum);
+                   set_exists (mp, msgnum);
+                   set_unseen (mp, msgnum);
+                   mp->msgflags |= SEQMOD;
+               }
+               break;
+           }
+           if (ferror(pf) || fclose (pf)) {
+               int e = errno;
+               unlink (cp);
+               errno = e;
+               adios (cp, "write error on");
+           }
+           pf = NULL;
+           free (cp);
+
+           if (trnflag && unlink (sp) == NOTOK)
+               adios (sp, "couldn't unlink");
+           free (sp);
+       }
     }
 
 #ifdef POP
@@ -808,7 +919,7 @@
     /*
      * truncate file we are incorporating from
      */
-    if (inc_type == INC_FILE) {
+    if (inc_type == INC_FILE && Maildir == NULL) {
        if (trnflag) {
            if (stat (newmail, &st) != NOTOK && s1.st_mtime != st.st_mtime)
                advise (NULL, "new messages have arrived!\007");
@@ -841,7 +952,7 @@
     /*
      * unlock the mail spool
      */
-    if (inc_type == INC_FILE) {
+    if (inc_type == INC_FILE && Maildir == NULL) {
        if (locked) {
 #ifdef MAILGROUP
            setgid(return_gid); /* Be sure we can unlock mail file */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]