Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Release 2.2.0
=============

2016-10-26 Bernhard Bablok (mail@bablokb.de)
* re-introduce per command interval configuration variables

Release 2.1.1
=============

Expand Down
21 changes: 20 additions & 1 deletion README
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ Copyright (C) 2009-2013 Peter Marschall <peter@adpm.de>
- rename to fetchmail_wakeup.c
- configuration via dovecot.config

Copyright (C) 2016-2016 Bernhard Bablok <mail@bablokb.de>
- re-introduced per command rate-limits

License
-------
Expand Down Expand Up @@ -76,6 +78,17 @@ Installation of the plugin is essentially a 3-step process:
That's it.


Shortcut Installation for Raspbian
----------------------------------

Raspbian users will find a precompiled version of the plugin in the
directory `contrib/release-raspbian`. The plugin was compiled running
Raspbian Jessie. Just copy the plugin-file to the directory
`/usr/lib/dovecot/modules/`. A sample configuration-file
is in `example-config/conf.d/90-fetchmail_wakeup.conf` und should go
into `/etc/dovecot/conf.d/`.


Configuration
-------------
After the plugin library is installed and ready to be used, Dovecot's
Expand Down Expand Up @@ -103,8 +116,13 @@ This is a 2-step process:

fetchmail_wakeup supports six configuration options:
- fetchmail_interval = NUMBER
Set minimal interval between two fetchmail invocations to NUMBER seconds.
Set global minimal interval between two fetchmail invocations
to NUMBER seconds.
If it is not given, the interval defaults to 60.
- fetchmail_interval_COMMAND = NUMBER
Set minimal interval between two fetchmail invocations
for COMMAND to NUMBER seconds.
If it is not given, the interval defaults to the global fetchmail_interval.
- fetchmail_helper = COMMAND
Execute COMMAND to either start fetchmail (or any other mail fetching tool),
or to awaken a running fetchmail daemon (or any other mail fetching tool).
Expand All @@ -123,6 +141,7 @@ This is a 2-step process:
# minimal interval (in seconds) between two awakenings of fetchmail
# (this setting is optional and defaults to 60)
fetchmail_interval = 60
fetchmail_interval_NOOP = 600

# a helper program to notify fetchmail accordingly
fetchmail_helper = /usr/bin/awaken-fetchmail
Expand Down
Binary file not shown.
Binary file not shown.
9 changes: 8 additions & 1 deletion example-config/conf.d/90-fetchmail_wakeup.conf
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,17 @@
# by adding it to the mail_plugins= settings.

plugin {
# Set minimal interval between two fetchmail invocations to NUMBER seconds.
# Set global minimal interval between two fetchmail invocations to NUMBER seconds.
# If it is not given, the interval defaults to 60.
fetchmail_interval = 60

# Set command-specific minimal interval between two fetchmail
# invocations to NUMBER seconds. This interval defaults to
# fetchmail_interval (global default).
# fetchmail_interval_IDLE = 600
# fetchmail_interval_STATUS = 600
fetchmail_interval_NOOP = 600

# Execute COMMAND to either start fetchmail (or any other mail fetching tool),
# or to awaken a running fetchmail daemon (or any other mail fetching tool).
# This setting is used when a system-wide deamon is used to fetch mails.
Expand Down
23 changes: 20 additions & 3 deletions fetchmail_wakeup.7.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.\" manual page for fetchmail_wakeup
.\" Copyright (C) 2009-2013 Peter Marschall <peter@adpm.de>
.\" Copyright (C) 2016-2016 Bernhard Bablok (mail@bablokb.de>
.\"
.\" This program is free software; you can redistribute it and/or modify
.\" it under the terms of the GNU General Public License as published by
Expand All @@ -15,7 +16,7 @@
.\" with this program; if not, write to the Free Software Foundation, Inc.,
.\" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
.\"
.TH FETCHMAIL_WAKEUP 7 "21 May 2011" "" "Dovecot Plugins"
.TH FETCHMAIL_WAKEUP 7 "21 May 2016" "" "Dovecot Plugins"

.SH NAME
fetchmail_wakeup \- Dovecot plugin to trigger fetchmail wakeups
Expand Down Expand Up @@ -81,12 +82,28 @@ extending the mail_plugins variable by the plugin's name "fetchmail_wakeup"
Then, set the plugin's configuration options.
This is done in dovecot.conf's \fBplugin\fP section.

fetchmail_wakeup supports six configuration options:
fetchmail_wakeup supports nine configuration options:
.TP
.BR fetchmail_interval = \fINUMBER\fP
Set minimal interval between two fetchmail invocations to \fINUMBER\fP seconds.
Set global minimal interval between two fetchmail invocations
to \fINUMBER\fP seconds.
If it is not given, the interval defaults to \fB60\fP.
.TP
.BR fetchmail_interval_STATUS = \fINUMBER\fP
Set minimal interval between two fetchmail invocations for STATUS
to \fINUMBER\fP seconds.
If it is not given, the interval defaults to \fBfetchmail_interval\fP.
.TP
.BR fetchmail_interval_IDLE = \fINUMBER\fP
Set minimal interval between two fetchmail invocations for IDLE
to \fINUMBER\fP seconds.
If it is not given, the interval defaults to \fBfetchmail_interval\fP.
.TP
.BR fetchmail_interval_NOOP = \fINUMBER\fP
Set minimal interval between two fetchmail invocations for NOOP
to \fINUMBER\fP seconds.
If it is not given, the interval defaults to \fBfetchmail_interval\fP.
.TP
.BR fetchmail_helper = \fICOMMAND\fP
Execute \fICOMMAND\fP to either start fetchmail (or any other mail fetching tool),
or to awaken a running fetchmail daemon (or any other mail fetching tool).
Expand Down
53 changes: 37 additions & 16 deletions fetchmail_wakeup.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,34 @@ typedef void handler_t;

/* data structure for commands to be overridden */
struct overrides {
const char *name; /* the IMAPv4 command name */
struct command orig_cmd; /* copy of the original command's data structure */
const char *name; /* the IMAPv4 command name */
struct command orig_cmd; /* copy of the original command's data structure */
struct timeval last; /* last time this command was executed */
};


/* commands that can be overridden */
static struct overrides cmds[] = {
{ "IDLE", {} },
{ "NOOP", {} },
{ "STATUS", {} },
{ "NOTIFY", {} },
{ NULL, {} }
{ "IDLE", {}, {} },
{ "NOOP", {}, {} },
{ "STATUS", {}, {} },
{ "NOTIFY", {}, {} },
{ NULL, {}, {} }
};


/* get the index of the given command in cmds[] */

static int get_cmd_index(const char* name) {
int i=0;
for (i = 0; cmds[i].name != NULL; i++) {
if (strcasecmp(cmds[i].name,name) == 0) {
return i;
}
}
return i;
}

/*
* Get a interval value from config and parse it into a number (with fallback for failures)
*/
Expand All @@ -86,22 +99,24 @@ static long getenv_interval(struct mail_user *user, const char *name, long fallb
/*
* Don't bother waking up fetchmail too often
*/
static bool ratelimit(long interval)
static bool ratelimit(long interval, const char* name)
{
static struct timeval last_one;
struct timeval last_one;
struct timeval now;
int cmd_index;
long long millisec_delta;

if (gettimeofday(&now, NULL))
return FALSE;

cmd_index = get_cmd_index(name);
last_one = cmds[cmd_index].last;
millisec_delta = ((now.tv_sec - last_one.tv_sec) * 1000000LL +
now.tv_usec - last_one.tv_usec) / 1000LL;
if (millisec_delta > interval * 1000LL) {
last_one = now;
cmds[cmd_index].last = now;
return FALSE;
}

return TRUE;
}

Expand All @@ -112,7 +127,8 @@ static bool ratelimit(long interval)
static void fetchmail_wakeup(struct client_command_context *ctx)
{
struct client *client = ctx->client;
long fetchmail_interval = FETCHMAIL_INTERVAL;
long interval, fetchmail_interval = FETCHMAIL_INTERVAL;
char cfg_var[28];

/* make sure client->user is defined */
if (client == NULL || client->user == NULL)
Expand All @@ -125,12 +141,17 @@ static void fetchmail_wakeup(struct client_command_context *ctx)
/* convert config variable "fetchmail_interval" into a number */
fetchmail_interval = getenv_interval(client->user, "fetchmail_interval", FETCHMAIL_INTERVAL);

/* query per command interval setting */
strcpy(cfg_var,"fetchmail_interval_");
strncat(cfg_var,ctx->name,6);
interval = getenv_interval(client->user,cfg_var,fetchmail_interval);

#if defined(FETCHMAIL_WAKEUP_DEBUG)
i_debug("fetchmail_wakeup: interval %ld used for %s.", fetchmail_interval, ctx->name);
i_debug("fetchmail_wakeup: interval %ld used for %s.",interval, ctx->name);
#endif

if (ratelimit(fetchmail_interval))
return;
/* limit rate */
if (ratelimit(interval,ctx->name))
return;

#if defined(FETCHMAIL_WAKEUP_DEBUG)
i_debug("fetchmail_wakeup: rate limit passed.");
Expand Down