diff --git a/ChangeLog b/ChangeLog index 114485d..81da2fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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 ============= diff --git a/README b/README index fa64b4a..21efce4 100644 --- a/README +++ b/README @@ -40,6 +40,8 @@ Copyright (C) 2009-2013 Peter Marschall - rename to fetchmail_wakeup.c - configuration via dovecot.config +Copyright (C) 2016-2016 Bernhard Bablok +- re-introduced per command rate-limits License ------- @@ -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 @@ -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). @@ -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 diff --git a/contrib/release-bananian/lib_fetchmail_wakeup_plugin.so b/contrib/release-bananian/lib_fetchmail_wakeup_plugin.so new file mode 100755 index 0000000..c320caf Binary files /dev/null and b/contrib/release-bananian/lib_fetchmail_wakeup_plugin.so differ diff --git a/contrib/release-raspbian/lib_fetchmail_wakeup_plugin.so b/contrib/release-raspbian/lib_fetchmail_wakeup_plugin.so new file mode 100755 index 0000000..ceff9f4 Binary files /dev/null and b/contrib/release-raspbian/lib_fetchmail_wakeup_plugin.so differ diff --git a/example-config/conf.d/90-fetchmail_wakeup.conf b/example-config/conf.d/90-fetchmail_wakeup.conf index 4de0bc4..e623316 100644 --- a/example-config/conf.d/90-fetchmail_wakeup.conf +++ b/example-config/conf.d/90-fetchmail_wakeup.conf @@ -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. diff --git a/fetchmail_wakeup.7.in b/fetchmail_wakeup.7.in index bf66ca4..c2b60d3 100644 --- a/fetchmail_wakeup.7.in +++ b/fetchmail_wakeup.7.in @@ -1,5 +1,6 @@ .\" manual page for fetchmail_wakeup .\" Copyright (C) 2009-2013 Peter Marschall +.\" 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 @@ -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 @@ -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). diff --git a/fetchmail_wakeup.c b/fetchmail_wakeup.c index 63da96b..ae2222a 100644 --- a/fetchmail_wakeup.c +++ b/fetchmail_wakeup.c @@ -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) */ @@ -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; } @@ -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) @@ -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.");