---
 Makefile.am          |    2 +-
 db.c                 |   11 +++-----
 dbmail-imapsession.c |   71 ++++++++++++++++++++++++++++++++++++++++++++++++-
 dbmail-mailbox.c     |   21 +++++++++++---
 dbmailtypes.h        |    1 +
 dm_imaputil.c        |   72 --------------------------------------------------
 dm_imaputil.h        |    5 ---
 export.c             |   56 ++++++++++++++++++++++++++++++++-------
 imap4.c              |    3 --
 modules/dbmysql.c    |    5 +++-
 modules/dbpgsql.c    |    5 +++-
 modules/dbsqlite.c   |    5 +++-
 12 files changed, 150 insertions(+), 107 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 5f02ac6..aaa4d95 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -88,7 +88,7 @@ dbmail_util_LDADD = libdbmail.la
 dbmail_users_SOURCES = user.c
 dbmail_users_LDADD = libdbmail.la
 
-dbmail_export_SOURCES = export.c
+dbmail_export_SOURCES = export.c memblock.c dbmail-imapsession.c
 dbmail_export_LDADD = libdbmail.la
 
 dbmail_lmtpd_SOURCES = lmtp.c lmtpd.c
diff --git a/db.c b/db.c
index 55211c0..100c2bd 100644
--- a/db.c
+++ b/db.c
@@ -4368,14 +4368,11 @@ char *date2char_str(const char *column)
 
 char *char2date_str(const char *date)
 {
-	unsigned len;
-	char *s;
-
-	len = strlen(db_get_sql(SQL_TO_DATE)) + MAX_DATE_LEN;
-	if (! (s = g_new0(char,len)))
-		return NULL;
+	char *s, *qs;
 
-	snprintf(s, len, db_get_sql(SQL_TO_DATE), date);
+	qs = g_strdup_printf("'%s'", date);
+	s = g_strdup_printf(db_get_sql(SQL_TO_DATETIME), qs);
+	g_free(qs);
 
 	return s;
 }
diff --git a/dbmail-imapsession.c b/dbmail-imapsession.c
index 88fe66b..ae20ad7 100644
--- a/dbmail-imapsession.c
+++ b/dbmail-imapsession.c
@@ -36,7 +36,7 @@ extern db_param_t _db_params;
 #define DBPFX _db_params.pfx
 
 /* cache */
-extern cache_t cached_msg;
+cache_t cached_msg;
 
 extern const char *month_desc[];
 /* returned by date_sql2imap() */
@@ -60,6 +60,75 @@ static void _fetch_envelopes(struct ImapSession *self);
 static int _imap_show_body_section(body_fetch_t *bodyfetch, gpointer data);
 	
 
+/*
+ * send_data()
+ *
+ * sends cnt bytes from a MEM structure to a FILE stream
+ * uses a simple buffering system
+ */
+static void send_data(FILE * to, MEM * from, int cnt)
+{
+	char buf[SEND_BUF_SIZE];
+
+	for (cnt -= SEND_BUF_SIZE; cnt >= 0; cnt -= SEND_BUF_SIZE) {
+		mread(buf, SEND_BUF_SIZE, from);
+		fwrite(buf, SEND_BUF_SIZE, 1, to);
+	}
+
+	if (cnt < 0) {
+		mread(buf, cnt + SEND_BUF_SIZE, from);
+		fwrite(buf, cnt + SEND_BUF_SIZE, 1, to);
+	}
+
+	fflush(to);
+}
+
+/* 
+ * init cache 
+ */
+static int init_cache(void)
+{
+	int serr;
+	cached_msg.dmsg = NULL;
+	cached_msg.num = -1;
+	cached_msg.msg_parsed = 0;
+	if (! (cached_msg.memdump = mopen())) {
+		serr = errno;
+		TRACE(TRACE_ERROR,"mopen() failed [%s]", strerror(serr));
+		errno = serr;
+		return -1;
+	}
+
+	
+	if (! (cached_msg.tmpdump = mopen())) {
+		serr = errno;
+		TRACE(TRACE_ERROR,"mopen() failed [%s]", strerror(serr));
+		errno = serr;
+		mclose(&cached_msg.memdump);
+		return -1;
+	}
+
+	cached_msg.file_dumped = 0;
+	cached_msg.dumpsize = 0;
+	return 0;
+}
+/*
+ * closes the msg cache
+ */
+static void close_cache(void)
+{
+	if (cached_msg.dmsg)
+		dbmail_message_free(cached_msg.dmsg);
+
+	cached_msg.num = -1;
+	cached_msg.msg_parsed = 0;
+	mclose(&cached_msg.memdump);
+	mclose(&cached_msg.tmpdump);
+}
+
+
+
+
 static u64_t get_dumpsize(body_fetch_t *bodyfetch, u64_t tmpdumpsize); 
 
 static void _imap_fetchitem_free(struct ImapSession * self)
diff --git a/dbmail-mailbox.c b/dbmail-mailbox.c
index 7a04c7e..9e472af 100644
--- a/dbmail-mailbox.c
+++ b/dbmail-mailbox.c
@@ -270,6 +270,7 @@ int dbmail_mailbox_dump(struct DbmailMailbox *self, FILE *file)
 	ostream = g_mime_stream_file_new(file);
 	
 	ids = g_tree_keys(self->ids);
+
 	while (ids) {
 		cids = g_list_append(cids,g_strdup_printf("%llu", *(u64_t *)ids->data));
 		if (! g_list_next(ids))
@@ -1122,10 +1123,12 @@ static gboolean _do_sort(GNode *node, struct DbmailMailbox *self)
 }
 static GTree * mailbox_search(struct DbmailMailbox *self, search_key_t *s)
 {
-	unsigned i, rows, date;
+	unsigned i, rows;
+	char *qs, *date, *field;
 	u64_t *k, *v, *w;
 	u64_t id;
 	char gt_lt = 0;
+	const char *op;
 	
 	GString *t;
 	GString *q;
@@ -1139,14 +1142,22 @@ static GTree * mailbox_search(struct DbmailMailbox *self, search_key_t *s)
 		case IST_HDRDATE_ON:
 		case IST_HDRDATE_SINCE:
 		case IST_HDRDATE_BEFORE:
+		
+		field = g_strdup_printf(db_get_sql(SQL_TO_DATE), s->hdrfld);
+		qs = g_strdup_printf("'%s'", date_imap2sql(s->search));
+		date = g_strdup_printf(db_get_sql(SQL_TO_DATE), qs);
+		g_free(qs);
 
-		date = num_from_imapdate(s->search);
 		if (s->type == IST_HDRDATE_SINCE)
-			g_string_printf(t,"%s >= %d", s->hdrfld, date);
+			op = ">=";
 		else if (s->type == IST_HDRDATE_BEFORE)
-			g_string_printf(t,"%s < %d", s->hdrfld, date);
+			op = "<";
 		else
-			g_string_printf(t,"%s >= %d AND %s < %d", s->hdrfld, date, s->hdrfld, date+1);
+			op = "=";
+
+		g_string_printf(t,"%s %s %s", field, op, date);
+		g_free(date);
+		g_free(field);
 		
 		g_string_printf(q,"SELECT message_idnr FROM %smessages m "
 			"JOIN %sphysmessage p ON m.physmessage_id=p.id "
diff --git a/dbmailtypes.h b/dbmailtypes.h
index 7ab17f1..52243c0 100644
--- a/dbmailtypes.h
+++ b/dbmailtypes.h
@@ -488,6 +488,7 @@ typedef enum {
 
 typedef enum {
 	SQL_TO_DATE,
+	SQL_TO_DATETIME,
 	SQL_TO_CHAR,
 	SQL_CURRENT_TIMESTAMP,
 	SQL_REPLYCACHE_EXPIRE,
diff --git a/dm_imaputil.c b/dm_imaputil.c
index 8b2b72a..d1d8eb0 100644
--- a/dm_imaputil.c
+++ b/dm_imaputil.c
@@ -38,9 +38,6 @@
 extern db_param_t _db_params;
 #define DBPFX _db_params.pfx
 
-/* cache */
-extern cache_t cached_msg;
-
 /* consts */
 const char AcceptedChars[] =
     "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
@@ -80,75 +77,6 @@ int checktag(const char *s)
 	return 1;
 }
 
-/*
- * send_data()
- *
- * sends cnt bytes from a MEM structure to a FILE stream
- * uses a simple buffering system
- */
-void send_data(FILE * to, MEM * from, int cnt)
-{
-	char buf[SEND_BUF_SIZE];
-
-	for (cnt -= SEND_BUF_SIZE; cnt >= 0; cnt -= SEND_BUF_SIZE) {
-		mread(buf, SEND_BUF_SIZE, from);
-		fwrite(buf, SEND_BUF_SIZE, 1, to);
-	}
-
-	if (cnt < 0) {
-		mread(buf, cnt + SEND_BUF_SIZE, from);
-		fwrite(buf, cnt + SEND_BUF_SIZE, 1, to);
-	}
-
-	fflush(to);
-}
-
-
-
-/* 
- * init cache 
- */
-int init_cache()
-{
-	int serr;
-	cached_msg.dmsg = NULL;
-	cached_msg.num = -1;
-	cached_msg.msg_parsed = 0;
-	if (! (cached_msg.memdump = mopen())) {
-		serr = errno;
-		TRACE(TRACE_ERROR,"mopen() failed [%s]", strerror(serr));
-		errno = serr;
-		return -1;
-	}
-
-	
-	if (! (cached_msg.tmpdump = mopen())) {
-		serr = errno;
-		TRACE(TRACE_ERROR,"mopen() failed [%s]", strerror(serr));
-		errno = serr;
-		mclose(&cached_msg.memdump);
-		return -1;
-	}
-
-	cached_msg.file_dumped = 0;
-	cached_msg.dumpsize = 0;
-	return 0;
-}
-/*
- * closes the msg cache
- */
-void close_cache()
-{
-	if (cached_msg.dmsg)
-		dbmail_message_free(cached_msg.dmsg);
-
-	cached_msg.num = -1;
-	cached_msg.msg_parsed = 0;
-	mclose(&cached_msg.memdump);
-	mclose(&cached_msg.tmpdump);
-}
-
-
 /* unwrap strings */
 int mime_unwrap(char *to, const char *from) 
 {
diff --git a/dm_imaputil.h b/dm_imaputil.h
index 96dc5b9..0cc100d 100644
--- a/dm_imaputil.h
+++ b/dm_imaputil.h
@@ -33,11 +33,6 @@ size_t stridx(const char *s, char ch);
 
 int checktag(const char *s);
 
-void send_data(FILE * to, MEM * from, int cnt);
-
-int init_cache(void);
-void close_cache(void);
-
 int mime_unwrap(char *to, const char *from); 
 
 #endif
diff --git a/export.c b/export.c
index 3536209..ae9ee2d 100644
--- a/export.c
+++ b/export.c
@@ -43,6 +43,7 @@ int do_showhelp(void) {
 	printf("     -u username   specify a user\n");
 	printf("     -m mailbox    specify a mailbox (default export all mailboxes)\n");
 	printf("     -o outfile    specify the destination mbox (default ./user/mailbox)\n");
+	printf("     -s set        specify the search criteria in IMAP SEARCH notation (default 1:*)\n");
 	printf("\n");
 	printf("Summary of options for all modes:\n");
 	printf("\n");
@@ -57,10 +58,11 @@ int do_showhelp(void) {
 	return 0;
 	
 }
-static int mailbox_dump(u64_t mailbox_idnr, const char *outfile)
+static int mailbox_dump(u64_t mailbox_idnr, const char *outfile, const char *search)
 {
 	FILE *ostream;
 	struct DbmailMailbox *mb = NULL;
+	struct ImapSession *s;
 	char *dir;
 
 	/* 
@@ -71,6 +73,26 @@ static int mailbox_dump(u64_t mailbox_idnr, const char *outfile)
 	 *
 	 * TODO: facilitate maildir type exports
 	 */
+	mb = dbmail_mailbox_new(mailbox_idnr);
+	if (search) {
+		s = dbmail_imap_session_new();
+		if (! (build_args_array_ext(s, search))) {
+			qerrorf("error parsing search string");
+			dbmail_imap_session_delete(s);
+			dbmail_mailbox_free(mb);
+			return 1;
+		}
+	
+		if (dbmail_mailbox_build_imap_search(mb, s->args, &(s->args_idx), SEARCH_UNORDERED) < 0) {
+			qerrorf("invalid search string");
+			dbmail_imap_session_delete(s);
+			dbmail_mailbox_free(mb);
+			return 1;
+		}
+		dbmail_mailbox_search(mb);
+		dbmail_imap_session_delete(s);	
+	}
+
 	dir = g_path_get_dirname(outfile);
 	if (g_mkdir_with_parents(dir,0700)) {
 		qerrorf("can't create directory [%s]\n", dir);
@@ -79,18 +101,20 @@ static int mailbox_dump(u64_t mailbox_idnr, const char *outfile)
 	}
 	g_free(dir);
 
-	if (! (ostream = fopen(outfile,"a"))) {
+	if (strncmp(outfile,"-",1)==0) {
+		ostream = stdout;
+	} else if (! (ostream = fopen(outfile,"a"))) {
 		int err=errno;
 		qerrorf("opening [%s] failed [%s]\n", outfile, strerror(err));
 		return -1;
 	}
 
-	mb = dbmail_mailbox_new(mailbox_idnr);
 	if (dbmail_mailbox_dump(mb,ostream) < 0)
 		qerrorf("exporing failed\n");
 
 	if (mb)
 		dbmail_mailbox_free(mb);
+
 	return 0;
 }
 	
@@ -100,7 +124,7 @@ int main(int argc, char *argv[])
 	int opt = 0, opt_prev = 0;
 	int show_help = 0;
 	int result = 0;
-	char *user = NULL,*mailbox=NULL, *outfile=NULL;
+	char *user = NULL,*mailbox=NULL, *outfile=NULL, *search=NULL;
 	u64_t useridnr = 0, mailbox_idnr = 0;
 
 	openlog(PNAME, LOG_PID, LOG_MAIL);
@@ -111,7 +135,7 @@ int main(int argc, char *argv[])
 	/* get options */
 	opterr = 0;		/* suppress error message from getopt() */
 	while ((opt = getopt(argc, argv,
-		"-u:m:o:" /* Major modes */
+		"-u:m:o:s:" /* Major modes */
 		"f:qvVh" /* Common options */ )) != -1) {
 		/* The initial "-" of optstring allows unaccompanied
 		 * options and reports them as the optarg to opt 1 (not '1') */
@@ -120,8 +144,7 @@ int main(int argc, char *argv[])
 		opt_prev = opt;
 
 		switch (opt) {
-		/* Major modes of operation
-		 * (exactly one of these is required) */
+		/* export specific options */
 		case 'u':
 			if (optarg && strlen(optarg))
 				user = optarg;
@@ -135,6 +158,14 @@ int main(int argc, char *argv[])
 			if (optarg && strlen(optarg))
 				outfile = optarg;
 			break;
+		case 's':
+			if (optarg && strlen(optarg))
+				search = optarg;
+			else {
+				qprintf("dbmail-mailbox: -s requires a value\n\n");
+				result = 1;
+			}
+			break;
 
 		/* Common options */
 		case 'f':
@@ -168,7 +199,6 @@ int main(int argc, char *argv[])
 			printf("This is DBMail version %s\n\n%s\n", VERSION, COPYRIGHT);
 			result = 1;
 			break;
-
 		default:
 			/* printf("unrecognized option [%c], continuing...\n",optopt); */
 			break;
@@ -186,6 +216,12 @@ int main(int argc, char *argv[])
 		result = 1;
 		goto freeall;
 	}
+	if (search && (! mailbox) ) {
+		qerrorf("Mailbox required if search is specified.\n");
+		result = 1;
+		goto freeall;
+
+	}
 	/* read the config file */
         if (config_read(configFile) == -1) {
                 qerrorf("Failed. Unable to read config file %s\n", configFile);
@@ -236,7 +272,7 @@ int main(int argc, char *argv[])
 		}
 		
 		qerrorf("  export mailbox /%s/%s -> %s\n", user, mailbox, outfile);
-		mailbox_dump(mailbox_idnr, outfile);
+		mailbox_dump(mailbox_idnr, outfile, search);
 
 	} else {
 		u64_t *children;
@@ -267,7 +303,7 @@ int main(int argc, char *argv[])
 
 			dumpfile = g_strdup_printf("%s/%s.mbox", user, mailbox);
 			qerrorf(" export mailbox /%s/%s -> %s/%s\n", user, mailbox, outfile, dumpfile);
-			if (mailbox_dump(mailbox_idnr, dumpfile)) {
+			if (mailbox_dump(mailbox_idnr, dumpfile, NULL)) {
 				g_free(dumpfile);
 				goto freeall;
 			}
diff --git a/imap4.c b/imap4.c
index 6184dd8..32e5f64 100644
--- a/imap4.c
+++ b/imap4.c
@@ -30,9 +30,6 @@
 
 #define THIS_MODULE "imap"
 
-/* cache */
-cache_t cached_msg;
-
 const char *IMAP_COMMANDS[] = {
 	"", "capability", "noop", "logout",
 	"authenticate", "login",
diff --git a/modules/dbmysql.c b/modules/dbmysql.c
index a1151f6..5e92d29 100644
--- a/modules/dbmysql.c
+++ b/modules/dbmysql.c
@@ -39,7 +39,10 @@ const char * db_get_sql(sql_fragment_t frag)
 			return "DATE_FORMAT(%s, '%%Y-%%m-%%d %%T')";
 		break;
 		case SQL_TO_DATE:
-			return "'%s'";
+			return "DATE(%s)";
+		break;
+		case SQL_TO_DATETIME:
+			return "TIMESTAMP(%s)";
 		break;
 		case SQL_CURRENT_TIMESTAMP:
 			return "CURRENT_TIMESTAMP";
diff --git a/modules/dbpgsql.c b/modules/dbpgsql.c
index 0986792..bd16fc9 100644
--- a/modules/dbpgsql.c
+++ b/modules/dbpgsql.c
@@ -37,7 +37,10 @@ const char * db_get_sql(sql_fragment_t frag)
 			return "TO_CHAR(%s, 'YYYY-MM-DD HH24:MI:SS' )";
 		break;
 		case SQL_TO_DATE:
-			return "TO_TIMESTAMP('%s', 'YYYY-MM-DD HH:MI:SS')";
+			return "TO_DATE(%s,'YYYY-MM-DD')";
+		break;
+		case SQL_TO_DATETIME:
+			return "TO_TIMESTAMP(%s, 'YYYY-MM-DD HH24:MI:SS')";
 		break;
 		case SQL_CURRENT_TIMESTAMP:
 			return "CURRENT_TIMESTAMP";
diff --git a/modules/dbsqlite.c b/modules/dbsqlite.c
index 49370af..c2bc643 100644
--- a/modules/dbsqlite.c
+++ b/modules/dbsqlite.c
@@ -47,7 +47,10 @@ const char * db_get_sql(sql_fragment_t frag)
 			return "%s";
 		break;
 		case SQL_TO_DATE:
-			return "'%s'";
+			return "DATE(%s)";
+		break;
+		case SQL_TO_DATETIME:
+			return "DATETIME(%s)";
 		break;
 		case SQL_CURRENT_TIMESTAMP:
 			return "STRFTIME('%Y-%m-%d %H:%M:%S','now','localtime')";
_______________________________________________
Dbmail-dev mailing list
[email protected]
http://twister.fastxs.net/mailman/listinfo/dbmail-dev

Reply via email to