From 05daf55279d8ce4029a141b356f00f7a1db5a5ed Mon Sep 17 00:00:00 2001 From: Bernhard Bablok Date: Fri, 21 Oct 2016 20:37:51 +0200 Subject: [PATCH 1/9] added support for command-specific intervals --- fetchmail_wakeup.c | 53 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 16 deletions(-) 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."); From 282612559c6445213feb9cea00554bd15ea6bcff Mon Sep 17 00:00:00 2001 From: Bernhard Bablok Date: Wed, 26 Oct 2016 07:45:33 +0200 Subject: [PATCH 2/9] added per command interval variables --- example-config/conf.d/90-fetchmail_wakeup.conf | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) 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. From 151c9a5ffc54f1522faecad38710b5a55b500c37 Mon Sep 17 00:00:00 2001 From: Bernhard Bablok Date: Wed, 26 Oct 2016 07:47:41 +0200 Subject: [PATCH 3/9] added changelog for 2.2.0 --- ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) 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 ============= From c8d9f5002c4e28aab5f1f759a743133bba9a0bc6 Mon Sep 17 00:00:00 2001 From: Bernhard Bablok Date: Wed, 26 Oct 2016 07:57:48 +0200 Subject: [PATCH 4/9] documented new options --- fetchmail_wakeup.7.in | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) 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). From 85c9b884df0fc39e9af14caff00345c17a60ecca Mon Sep 17 00:00:00 2001 From: Bernhard Bablok Date: Tue, 1 Nov 2016 14:22:07 +0100 Subject: [PATCH 5/9] documented new features (command-specific intervals, Raspbian installation) --- README | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/README b/README index fa64b4a..9d9b90b 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-arm`. The plugin was compiled running Raspbian Jessie +and should also work on other armhf-platforms. 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 From f5886949c42fa0645333c76562dd079493f9998d Mon Sep 17 00:00:00 2001 From: Bernhard Bablok Date: Fri, 4 Nov 2016 08:51:39 +0100 Subject: [PATCH 6/9] initial entry --- .../release-arm/lib_fetchmail_wakeup_plugin.so | Bin 0 -> 11600 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100755 contrib/release-arm/lib_fetchmail_wakeup_plugin.so diff --git a/contrib/release-arm/lib_fetchmail_wakeup_plugin.so b/contrib/release-arm/lib_fetchmail_wakeup_plugin.so new file mode 100755 index 0000000000000000000000000000000000000000..ceff9f48cc9a74a94186921b2290cbcd591aa748 GIT binary patch literal 11600 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 Date: Wed, 7 Dec 2016 14:44:09 +0100 Subject: [PATCH 7/9] renamed directory --- .../lib_fetchmail_wakeup_plugin.so | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename contrib/{release-arm => release-raspbian}/lib_fetchmail_wakeup_plugin.so (100%) diff --git a/contrib/release-arm/lib_fetchmail_wakeup_plugin.so b/contrib/release-raspbian/lib_fetchmail_wakeup_plugin.so similarity index 100% rename from contrib/release-arm/lib_fetchmail_wakeup_plugin.so rename to contrib/release-raspbian/lib_fetchmail_wakeup_plugin.so From 5047673360f9049bc8706c4003afcee0adb9b11a Mon Sep 17 00:00:00 2001 From: Bernhard Bablok Date: Wed, 7 Dec 2016 19:08:09 +0100 Subject: [PATCH 8/9] updated path of precompiled plugin --- README | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README b/README index 9d9b90b..21efce4 100644 --- a/README +++ b/README @@ -82,9 +82,9 @@ Shortcut Installation for Raspbian ---------------------------------- Raspbian users will find a precompiled version of the plugin in the -directory `contrib/release-arm`. The plugin was compiled running Raspbian Jessie -and should also work on other armhf-platforms. Just copy the plugin-file -to the directory `/usr/lib/dovecot/modules/`. A sample configuration-file +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/`. From a0a8962bc25a1d435893abf9f5dd50ac68018a5c Mon Sep 17 00:00:00 2001 From: Bernhard Bablok Date: Sat, 26 Dec 2020 13:24:29 +0100 Subject: [PATCH 9/9] initial commit --- .../lib_fetchmail_wakeup_plugin.so | Bin 0 -> 12484 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100755 contrib/release-bananian/lib_fetchmail_wakeup_plugin.so 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 0000000000000000000000000000000000000000..c320caf260d49cb02aab2a7e3eee392de5fcc089 GIT binary patch literal 12484 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 literal 0 HcmV?d00001