summaryrefslogtreecommitdiffstats
path: root/src/maildir.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/maildir.c')
-rw-r--r--src/maildir.c210
1 files changed, 210 insertions, 0 deletions
diff --git a/src/maildir.c b/src/maildir.c
new file mode 100644
index 0000000..8d379cc
--- /dev/null
+++ b/src/maildir.c
@@ -0,0 +1,210 @@
+/* $Id$ */
+
+/***
+ This file is part of libnewmail
+
+ libnewmail is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ libnewmail is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libnewmail; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA
+***/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <dirent.h>
+
+#include "module.h"
+#include "newmail.h"
+#include "util.h"
+
+struct data {
+ char *path;
+ enum nm_query query;
+ nm_query_cb_t cb;
+ void *user;
+ oop_source *oop;
+};
+
+static int _is_maildir(char *p) {
+ static char fn[PATH_MAX];
+ static struct stat st;
+
+
+ if (stat(p, &st) == 0 && S_ISDIR(st.st_mode)) {
+ snprintf(fn, sizeof(fn), "%s/cur", p);
+
+ if (stat(fn, &st) == 0 && S_ISDIR(st.st_mode))
+ return 0;
+ }
+
+ return -1;
+}
+
+static int _query(struct nm_spool *s, enum nm_query query, struct nm_status *status) {
+ struct data *data = (struct data*) s->data;
+ DIR* d;
+ static char c[PATH_MAX];
+ status->new = status->cur = -1;
+
+ if (_is_maildir(data->path)) {
+ nm_error(NM_ERROR_NOFILE, "Mailbox not maildir");
+ return -1;
+ }
+
+
+ snprintf(c, sizeof(c), "%s/new", data->path);
+ if ((d = opendir(c))) {
+ int n = 0;
+ struct dirent *de;
+
+ while ((de = readdir(d))) {
+ if (de->d_name[0] == '.')
+ continue;
+ n++;
+ if (!(query & NM_QUERY_NNEW))
+ break;
+ }
+
+ closedir(d);
+
+ snprintf(c, sizeof(c), "%s/cur", data->path);
+ if ((d = opendir(c))) {
+ int n2 = 0;
+
+ while ((de = readdir(d))) {
+ if (de->d_name[0] == '.')
+ continue;
+ n2++;
+ if (!(query & NM_QUERY_NCUR))
+ break;
+ }
+
+ closedir(d);
+
+ status->new = n;
+ status->cur = query & NM_QUERY_NCUR ? (n+n2) : (n||n2 ? 1 : 0);
+
+ return 0;
+ } else
+ nm_error(NM_ERROR_SYSTEM|NM_ERROR_NOFILE, NULL);
+
+ } else
+ nm_error(NM_ERROR_SYSTEM|NM_ERROR_NOFILE, NULL);
+
+ return -1;
+}
+
+static void * _cb(oop_source *source, struct timeval tv, void *user) {
+ struct nm_status status;
+ struct nm_spool *s = (struct nm_spool *) user;
+ struct data *data = (struct data*) s->data;
+
+ if (_query(s, data->query, &status) < 0)
+ data->cb(s, NULL, data->user);
+ else
+ data->cb(s, &status, data->user);
+
+ data->cb = NULL;
+ data->query = 0;
+ data->user = NULL;
+ data->oop = NULL;
+
+ return OOP_CONTINUE;
+}
+
+static int _query_submit(struct nm_spool *s, enum nm_query query, oop_source *oop, nm_query_cb_t cb, void *user) {
+ struct data *data = (struct data*) s->data;
+
+ if (data->cb) {
+ nm_error(NM_ERROR_ALREADY, NULL);
+ return -1;
+ }
+
+ data->cb = cb;
+ data->query = query;
+ data->user = user;
+ data->oop = oop;
+
+ data->oop->on_time(data->oop, OOP_TIME_NOW, _cb, s);
+
+ return 0;
+}
+
+static int _configure(struct nm_spool *s) {
+ return -1;
+}
+
+static int _info(struct nm_spool *s, struct nm_info *i) {
+ struct data *data = (struct data*) s->data;
+
+ snprintf(i->text, sizeof(i->text), "qmail Maildir %s", data->path);
+ i->flags = NM_FLAG_SYNCHRONOUS;
+
+ return 0;
+}
+
+static void _done(struct nm_spool *s) {
+ struct data *data = (struct data*) s->data;
+ if (data) {
+ if (data->cb && data->oop)
+ data->oop->cancel_time(data->oop, OOP_TIME_NOW, _cb, s);
+
+ nm_free(data->path);
+ nm_free(data);
+ }
+}
+
+
+int nm_init(struct nm_spool *s) {
+ struct data *data;
+ char *def;
+
+ def = NULL;
+ if (!(def = getenv("MAILDIR")))
+ if ((def = getenv("MAIL")))
+ if (_is_maildir(def) != 0) {
+ if (!s->config)
+ return -1;
+
+ def = NULL;
+ }
+
+ if (!def) {
+ static char fn[PATH_MAX];
+ snprintf(fn, sizeof(fn), "%s/Maildir", getenv("HOME"));
+ if (s->config || _is_maildir(fn) == 0)
+ def = fn;
+ else
+ return -1;
+ }
+
+
+ s->query = _query;
+ s->query_submit = _query_submit;
+ s->configure = _configure;
+ s->info = _info;
+ s->done = _done;
+
+ if (!s->path)
+ s->path = nm_strdup("@AUTOMATIC@.maildir");
+
+ data = nm_malloc(sizeof(struct data));
+ memset(data, 0, sizeof(struct data));
+
+ data->path = nm_strdup(nm_specials(nm_config_get(s->config, "Path", def)));
+ s->data = (void*) data;
+ return 0;
+}