maildir support in email conduit



I have coded a patch to add maildir folder support to the email conduit.

maildir is the format used by Qmail (and Evolution, mutt, ...); it
claims to be more reliable than mbox or mh. 
Details are at http://www.qmail.org/man/man5/maildir.html ; what matters
is that a maildir directory has 3 subdirectories new, cur and tmp which
contain mail messages as files with strange names in standard (bare)
format. So this was basically a cut-and-paste job on the mh sync code.

email_conduit.h:
add maildirDirectory member to ConduitCfg structure

email_conduit.c:
#include <dirent.h> to browse maildir subdirectories
(load_configuration), (save_configuration), (dupe_configuration),
(destroy_configuration), (createCfgWindow), (setOptionsCfg),
(readOptionsCfg): deal with the maildirDirectory member and associated
config key ("maildir_directory"). Uses same textbox as mbox and mh; a
simple heuristic decides whether a directory is mh or maildir, choosing
maildir only if directory has "cur" subdirectory and no "1" entry.
(process_mh_message): new function to process mh and maildir files
(synchronize): deal with maildir, and alter mh sync code to use
process_mh_message(). A change in behaviour results: if mh sync
encounters a read() error it will try next file instead of aborting mail
sync.

Patch has been generated against latest cvs and tested against recent
tarball - I can't get latest cvs to configure, trying to get needed
files sends me into circular dependency hell :(

Would someone be willing to test (for compilation against cvs) and
checkin this patch? It compiles and works fine on my machine, I'm using
it daily and it is a feature I'd like to see become part of gnome-pilot.

Thanks

ed catmur co uk

diff -u gnome-pilot-conduits-old/email/email_conduit.h
gnome-pilot-conduits-0.10/email/email_conduit.h
--- gnome-pilot-conduits-old/email/email_conduit.h	2002-09-16
17:16:22.000000000 +0000
+++ gnome-pilot-conduits/email/email_conduit.h	2003-01-28
01:39:18.000000000 +0000
@@ -12,6 +12,7 @@
   gchar *fromAddr;
   gchar *sendAction;
   gchar *mhDirectory;
+  gchar *maildirDirectory;
   gchar *mboxFile;
   gchar *receiveAction;
   guint32 pilotId;
diff -u gnome-pilot-conduits-old/email/email_conduit.c
gnome-pilot-conduits/email/email_conduit.c
--- gnome-pilot-conduits-old/email/email_conduit.c	2003-01-26
22:29:20.000000000 +0000
+++ gnome-pilot-conduits/email/email_conduit.c	2003-01-28
01:41:20.000000000 +0000
@@ -11,6 +11,7 @@
 
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <dirent.h>
 #include <fcntl.h>
 #include <utime.h>
 #include <unistd.h>
@@ -51,6 +52,7 @@
 	(*c)->fromAddr = gnome_config_get_string( "from_address" );
 	(*c)->sendAction = gnome_config_get_string( "send_action=file");
 	(*c)->mhDirectory = gnome_config_get_string( "mh_directory" );
+	(*c)->maildirDirectory = gnome_config_get_string( "maildir_directory"
);
 	(*c)->mboxFile = gnome_config_get_string ( "mbox_file" );
 	(*c)->receiveAction = gnome_config_get_string( "receive_action=copy"
);
 	gnome_config_pop_prefix();
@@ -73,6 +75,7 @@
 	gnome_config_set_string("from_address", c->fromAddr);
 	gnome_config_set_string("send_action", c->sendAction);
 	gnome_config_set_string("mh_directory", c->mhDirectory);
+	gnome_config_set_string("maildir_directory", c->maildirDirectory);
 	gnome_config_set_string("mbox_file", c->mboxFile);
 	gnome_config_set_string("receive_action", c->receiveAction);
 	gnome_config_pop_prefix();
@@ -93,17 +96,19 @@
 	g_free(d->fromAddr);
 	g_free(d->sendAction);
 	g_free(d->mhDirectory);
+	g_free(d->maildirDirectory);
 	g_free(d->mboxFile);
 	g_free(d->receiveAction);
 
-	d->sendmail      = g_strdup(c->sendmail);
-	d->fromAddr      = g_strdup(c->fromAddr);
-	d->sendAction    = g_strdup(c->sendAction);
-	d->mhDirectory   = g_strdup(c->mhDirectory);
-	d->mboxFile      = g_strdup(c->mboxFile);
-	d->receiveAction = g_strdup(c->receiveAction);
+	d->sendmail         = g_strdup(c->sendmail);
+	d->fromAddr         = g_strdup(c->fromAddr);
+	d->sendAction       = g_strdup(c->sendAction);
+	d->mhDirectory      = g_strdup(c->mhDirectory);
+	d->maildirDirectory = g_strdup(c->maildirDirectory);
+	d->mboxFile         = g_strdup(c->mboxFile);
+	d->receiveAction    = g_strdup(c->receiveAction);
 
-	d->pilotId       = c->pilotId;
+	d->pilotId          = c->pilotId;
 }
 
 static ConduitCfg*
@@ -126,6 +131,7 @@
 	g_free( (*c)->fromAddr );
 	g_free( (*c)->sendAction );
 	g_free( (*c)->mhDirectory );
+	g_free( (*c)->maildirDirectory );
 	g_free( (*c)->mboxFile );
 	g_free( (*c)->receiveAction );
 	g_free(*c);
@@ -298,6 +304,58 @@
     }
 }
 
+static gboolean 
+process_mh_message( int mhmsg, char *filename, int *prec, int *pdupe,
+		GnomePilotConduit *c, GnomePilotDBInfo *dbi, int dbHandle, int i )
+{
+    int len;
+    int l;
+    struct Mail t;
+    guchar buffer[0xffff];
+
+    t.to = NULL;
+    t.from = NULL;
+    t.cc = NULL;
+    t.bcc = NULL;
+    t.subject = NULL;
+    t.replyTo = NULL;
+    t.sentTo = NULL;
+    t.body = NULL;
+    t.dated = 0;
+	    
+#ifdef EC_DEBUG 
+    fprintf( stderr, "Processing message %s", filename );
+#endif
+           
+    len = 0;
+    while ( ( len < sizeof(buffer) ) && ( ( l = read( mhmsg, 
+		(char *)(buffer+len), sizeof(buffer)-len ) ) > 0 ) ) {
+	len += l;
+    }
+    buffer[len] = 0;
+            
+    if ( l < 0 ) {
+	fprintf( stderr, "Error processing message %s\n", filename );
+	close( mhmsg );
+        return FALSE;
+    } 
+		
+    if (write_message_to_pilot (c, dbi, dbHandle, buffer, i)) {
+	(*prec)++;
+	if ( strcmp( GET_CONFIG(c)->receiveAction, "delete" ) == 0 ) {
+	    close( mhmsg );
+            if ( unlink( filename ) ) {
+		fprintf( stderr, "Error deleting message %s\n", filename );
+		(*pdupe)++;
+	    }
+	    return FALSE;
+	} else {
+	    (*pdupe)++;
+	}
+    }
+    return TRUE;
+}
+
 static gint synchronize( GnomePilotConduit *c, GnomePilotDBInfo *dbi ) 
 {
     int dbHandle;
@@ -499,63 +557,67 @@
 #endif
         
         for( i = 1; ; i++ ) {
-            int len;
-            int l;
-            struct Mail t;
             int mhmsg;
             
-            t.to = NULL;
-            t.from = NULL;
-            t.cc = NULL;
-            t.bcc = NULL;
-            t.subject = NULL;
-            t.replyTo = NULL;
-            t.sentTo = NULL;
-            t.body = NULL;
-            t.dated = 0;
-	    
             if ( ( mhmsg = openmhmsg( GET_CONFIG(c)->mhDirectory, i ) )
< 0 ) {
                 break;
             }
-           
-#ifdef EC_DEBUG 
-            fprintf( stderr, "Processing message %d", i );
-#endif
-            
-            len = 0;
-            while ( ( len < sizeof(buffer) ) &&
-                    ( ( l = read( mhmsg, (char *)(buffer+len),
-                                  sizeof(buffer)-len ) ) > 0 ) ) {
-                len += l;
-            }
-            buffer[len] = 0;
-            
-            if ( l < 0 ) {
-                fprintf( stderr, "Error processing message %d\n", i );
-                break;
-            } 
-		
-	    if (write_message_to_pilot (c, dbi, dbHandle, buffer, i)) {
-		rec++;
-                if ( strcmp( GET_CONFIG(c)->receiveAction, "delete" )
== 0 ) {
-                    char filename[1000];
-                    sprintf( filename, "%s/%d",
GET_CONFIG(c)->mhDirectory, 
-                             i );
-                    close( mhmsg );
-                    if ( unlink( filename ) ) {
-                        fprintf( stderr, "Error deleting message %d\n",
i );
-                        dupe++;
-                    }
-                    continue;
-                } else {
-                    dupe++;
-                }
-	    }
 
-            close( mhmsg );
+	    char filename[1000];
+	    sprintf( filename, "%s/%d", GET_CONFIG(c)->mhDirectory, i );
+	    if ( process_mh_message( mhmsg, filename, &rec, &dupe,
+				c, dbi, dbHandle, i ) ) {
+                close( mhmsg );
+	    }
         }
     }
     
+    if ( GET_CONFIG(c)->maildirDirectory ) {
+#ifdef EC_DEBUG
+        fprintf( stderr, "Reading inbound mail from %s\n",
+                 GET_CONFIG(c)->maildirDirectory );
+#endif
+        DIR *mdRoot;
+	struct dirent *mdRootEntry;
+	char mdFolderPath[1000];
+	DIR *mdFolder;
+	struct dirent *mdFolderEntry;
+	char mdMsgPath[1000];
+	int mdMsg;
+	
+	i = 1;
+	if ( mdRoot = opendir( GET_CONFIG(c)->maildirDirectory ) ) {
+	    while ( mdRootEntry = readdir( mdRoot ) ) {
+		if ( strncmp( mdRootEntry->d_name, "cur", 3 ) == 0
+			||  strncmp( mdRootEntry->d_name, "new", 3 ) == 0 ) {
+		    sprintf( mdFolderPath, "%s/%s", 
+				GET_CONFIG(c)->maildirDirectory,
+				mdRootEntry->d_name );
+		    if ( mdFolder = opendir( mdFolderPath ) ) {
+			while ( mdFolderEntry = readdir( mdFolder ) ) {
+
+			    if ( strncmp( mdFolderEntry->d_name, ".", 1 ) != 0 ) {
+				sprintf( mdMsgPath, "%s/%s",
+					mdFolderPath,
+					mdFolderEntry->d_name );
+				mdMsg = open( mdMsgPath, O_RDONLY );
+				if ( mdMsg != -1 ) {
+				    if ( process_mh_message( 
+						mdMsg, mdMsgPath, &rec, &dupe,
+						c, dbi, dbHandle, i++ ) ) {
+                			close( mdMsg );
+				    }
+				}
+			    }
+			}
+			closedir( mdFolder );
+		    }
+		}
+	    }
+	    closedir( mdRoot );
+	}
+    }
+    
     if ( GET_CONFIG(c)->mboxFile ) {
 	FILE *f;
         LOG( "Reading inbound mail from %s", GET_CONFIG(c)->mboxFile );
@@ -772,8 +834,10 @@
      
     if (c->mboxFile && 0 != strcmp(c->mboxFile, "")) {
         gtk_entry_set_text(GTK_ENTRY(mbox_file), c->mboxFile);
-    } else if (c->mhDirectory) {
+    } else if (c->mhDirectory && 0 != strcmp(c->mhDirectory, "")) {
     	gtk_entry_set_text(GTK_ENTRY(mbox_file), c->mhDirectory);
+    } else if (c->maildirDirectory) {
+    	gtk_entry_set_text(GTK_ENTRY(mbox_file), c->maildirDirectory);
     } else {
     	gtk_entry_set_text(GTK_ENTRY(mbox_file), "");
     }
@@ -831,13 +895,26 @@
     c->mboxFile = NULL;
     g_free(c->mhDirectory);
     c->mhDirectory = NULL;
+    g_free(c->maildirDirectory);
+    c->maildirDirectory = NULL;
     if (str) {
-	 if (0 == stat(str, &mboxStat) && S_ISDIR(mboxStat.st_mode)) {
-	     c->mhDirectory = str;
-	 } else {
-             c->mboxFile = str;
-	 }
-     }
+	if (0 == stat(str, &mboxStat) && S_ISDIR(mboxStat.st_mode)) {
+	    char filename[1000];
+	    sprintf( filename, "%s/1", str );
+	    if (0 == stat(filename, &mboxStat)) {
+		c->mhDirectory = str;
+	    } else {
+		sprintf( filename, "%s/cur", str );
+		if (0 == stat(filename, &mboxStat) && S_ISDIR(mboxStat.st_mode)) {
+		    c->maildirDirectory = str;
+		} else {
+		    c->mhDirectory = str;
+		}
+	    }
+	} else {
+            c->mboxFile = str;
+	}
+    }
 }
 
 static gint




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