2 messages in net.sourceforge.lists.courier-maildrop[maildropl] Fw: [PATCH] More quotawar...
FromSent OnAttachments
Gian Piero CarrubbaSep 29, 2006 12:17 pm.diff
Gian Piero CarrubbaOct 2, 2006 11:12 pm 
Actions with this message:
Paste this link in email or IM:
Paste this link in email or IM:
Atom feed for this thread
Paste this URL into your reader:
Subject:[maildropl] Fw: [PATCH] More quotawarn levelsActions...
From:Gian Piero Carrubba (gp-@rm-rf.it)
Date:Sep 29, 2006 12:17:14 pm
List:net.sourceforge.lists.courier-maildrop
Attachments:

Second try, this time subscribed to the list in order to let the message pass.

Ciao, Gian Piero.

Inizio messsaggio inviato:

Data: Wed, 27 Sep 2006 08:04:22 +0200 Da: Gian Piero Carrubba <gp-@rm-rf.it> A: cour@lists.sourceforge.net Oggetto: [PATCH] More quotawarn levels

Hi all,

the company i'm working for need two levels of quota warning, so that the user can be warned at, say, 90% and 95% of maildir usage. A way to do that is patching maildrop, but they decided they can't afford the development and maintenance effort, so i've developed the attached patch in my spare time and tested it in my home environment. As a consequence, the patch hasn't been extensively tested and basic tests haven't been conducted in a real production-like environment. However, it should ( almost ) work.

The patch applies to maildrop 2.0.2 released as standalone tarball ( not bundled with courier-mta ). It modifies the -w option, so that it accepts a list of comma separated values ( by default max 3, but customizable at compile time setting QUOTA_WARN_LEVELS ). When the maildir usage exceeds one of the supplied percentage, the @sysconfdir/<msgfile>_<perc> ( or the default @sysconfdir/<msgfile> ) get copied into the maildir. So, i.e., using '-w 30,60,90' let the user be warned at 30%, 60% and 90% of maildir usage ( using the /etc/quotawarnmsg_(30|60|90) files or /etc/quotawarnmsg if one of the former isn't available ). The warning is delivered no more than once in a day, unless a higher level got exceeded. Patch to the documentation hasn't been made, yet.

Comments and suggestions welcome, please cc me as i'm not subscribed to the list.

Ciao, Gian Piero.

diff -rN -u old-maildrop-2.0.2/maildir/deliverquota.c
new-maildrop-2.0.2/maildir/deliverquota.c --- old-maildrop-2.0.2/maildir/deliverquota.c 2006-09-26 20:09:43.000000000
+0200 +++ new-maildrop-2.0.2/maildir/deliverquota.c 2006-09-26 20:09:49.000000000
+0200 @@ -47,10 +47,14 @@ #define EX_NOPERM 77 #endif

+#ifndef QUOTA_WARN_LEVELS +#define QUOTA_WARN_LEVELS 3 +#endif + static const char rcsid[]="$Id: deliverquota.c,v 1.22 2005/01/30 14:50:37 mrsam
Exp $";

static long deliver(int fdin, const char *dir, long s, - int auto_create, int quota_warn_percent, const char *pfix, + int auto_create, const int *quota_warn_percent, const char *pfix, const char *newquota) { struct maildir_tmpcreate_info createInfo; @@ -149,7 +153,7 @@ } maildir_tmpcreate_free(&createInfo);

- if (quota_warn_percent >= 0) + if (quota_warn_percent[0] >= 0) maildir_deliver_quota_warning(dir, quota_warn_percent);

return (ss); @@ -160,9 +164,13 @@ const char *dir; struct stat stat_buf; int auto_create = 0; - int quota_warn_percent = -1; - int i; + int quota_warn_percent[QUOTA_WARN_LEVELS] ; + int i, j, k, l; const char *quota=NULL; + char *str, *tok, *saveptr; + + for ( i=0; i<QUOTA_WARN_LEVELS; i++) + quota_warn_percent[i] = -1;

for (i=1; i<argc; i++) { @@ -174,15 +182,53 @@

if (strcmp(argv[i], "-w") == 0 && argc - i > 1) { - quota_warn_percent = atoi(argv[i+1]); + + for ( j=0, str = argv[i+1] ; j < QUOTA_WARN_LEVELS ; j++, str = NULL ) + { + tok = strtok_r ( str, ",", &saveptr ); + + if (tok == NULL) + break; + + quota_warn_percent[j] = atoi ( tok ); + + if ( quota_warn_percent[j] < -1 || quota_warn_percent[j] > 100 ) + { + fprintf(stderr, + "Usage: %s [-c] [-w percent[,percent[..]]] maildir\n", + argv[0]); + exit(73); + } + + } + + // sort quota_warn_percent[] in descending order + for ( j=0; j < QUOTA_WARN_LEVELS - 1 ; j++ ) + { + l = -2 ; + + for ( k=0; k < QUOTA_WARN_LEVELS - j - 1 ; k++ ) + { + if ( quota_warn_percent[k] < quota_warn_percent[k+1] ) + { + l = quota_warn_percent[k] ; + quota_warn_percent[k] = quota_warn_percent[k+1]; + quota_warn_percent[k+1] = l ; + } + } + + if ( l == -2 ) + break ; + } + ++i; continue; } break; } - if (i >= argc || quota_warn_percent < -1 || quota_warn_percent > 100) + if (i >= argc) { - fprintf(stderr, "Usage: %s [-c] [-w percent] maildir\n", + fprintf(stderr, "Usage: %s [-c] [-w percent[,percent[..]]] maildir\n", argv[0]); exit(73); } @@ -203,7 +249,7 @@ maildir_quota_add_start(dir, &info, stat_buf.st_size, 1, quota)) { - if (quota_warn_percent >= 0) + if (quota_warn_percent[0] >= 0) maildir_deliver_quota_warning(dir, quota_warn_percent); printf("Mail quota exceeded.\n"); exit(77); diff -rN -u old-maildrop-2.0.2/maildir/maildirquota.c
new-maildrop-2.0.2/maildir/maildirquota.c --- old-maildrop-2.0.2/maildir/maildirquota.c 2006-09-26 20:09:43.000000000
+0200 +++ new-maildrop-2.0.2/maildir/maildirquota.c 2006-09-26 20:09:50.000000000
+0200 @@ -48,6 +48,10 @@ #include <ctype.h> #include <numlib/numlib.h>

+#ifndef QUOTA_WARN_LEVELS +#define QUOTA_WARN_LEVELS 3 +#endif + static const char rcsid[]="$Id: maildirquota.c,v 1.29 2006/02/08 02:25:07 mrsam
Exp $";

static void parsequotastr(const char *, struct maildirquota *); @@ -980,7 +984,7 @@ }

-static void do_deliver_warning(const char *msgfile, const char *dir) +static void do_deliver_warning(const char *msgfile, const char *dir, const int
percent) { int fdin, fd, ret; FILE *fpout; @@ -993,10 +997,30 @@ size_t n; struct maildirsize info; struct maildir_tmpcreate_info createInfo; +char *msgfile_priv = NULL; +int i;

- if ((fdin=open(msgfile, O_RDONLY)) < 0) + // Use the right msgfile, if found + sprintf ( buf, "%d", percent ) ; + l = strlen(msgfile)+sizeof("_")+strlen(buf); + + if ((msgfile_priv = malloc(l)) == 0) return;

+ strcat(strcat(strcpy(msgfile_priv, msgfile), "_"), buf); + + if ( ( (stat(msgfile_priv, &sb)) >= 0 && + (fdin=open(msgfile_priv, O_RDONLY)) >= 0 ) || + ( (stat(msgfile, &sb)) >= 0 && + (fdin=open(msgfile, O_RDONLY)) >= 0 ) ) + { + free(msgfile_priv); + msg_len=sb.st_size; + } else { + free(msgfile_priv); + return; + } + l = strlen(dir)+sizeof("/quotawarn");

/* Send only one warning every 24 hours */ @@ -1009,14 +1033,35 @@ strcat(strcpy(qname, dir), "/quotawarn"); time(&t); ret = stat(qname, &sb); - if ((ret == -1 && errno != ENOENT) || - (ret == 0 && (sb.st_mtime + 86400) > t)) + if (ret == -1 && errno != ENOENT) { free(qname); close(fdin); return; }

+ if (ret == 0 && (sb.st_mtime + 86400) > t) + { + if ( (fd = open(qname, O_RDONLY)) > 0 ) + { + + /* sb.st_size <= 3 : check to avoid an overflow + * TODO: what about multi-byte encoding ? + */ + if ( sb.st_size <= 3 && + (read(fd, &i, sb.st_size)) != -1 && + i >= percent && i <= 100 ) + { + free(qname); + close(fd); + close(fdin); + return; + } + + close(fd); + } + } + fd = open(qname, O_WRONLY|O_CREAT|O_TRUNC, 0644); free(qname); if (fd == -1) @@ -1024,7 +1069,7 @@ close(fdin); return; } - write(fd, buf, 1); + write(fd, buf, strlen(buf)); close(fd);

strcpy(buf, "Date: "); @@ -1037,11 +1082,7 @@ sprintf(buf+strlen(buf), "Message-Id: <%lu.overquota@%-1.256s>\n", (unsigned long)t, hostname);

- if (stat(msgfile, &sb) < 0) { - close(fdin); - return; - } - msg_len=strlen(buf)+sb.st_size; + msg_len += strlen(buf);

@@ -1097,11 +1138,12 @@ maildir_tmpcreate_free(&createInfo); }

-void maildir_deliver_quota_warning(const char *dir, const int percent) +void maildir_deliver_quota_warning(const char *dir, const int *percent) { size_t l; char *p; struct stat sb; + int i;

/* If we delivered to a folder, dump the warning message into INBOX */

@@ -1122,18 +1164,24 @@ } free(p);

- if (percent >= 0) + if (percent[0] >= 0) { struct maildirsize info;

if (maildir_openquotafile(&info, dir) == 0) { - if (maildir_readquota(&info) >= percent) + + for (i=0; i<QUOTA_WARN_LEVELS && percent[i] >= 0; i++) { - maildir_closequotafile(&info); - do_deliver_warning(QUOTAWARNMSG, dir); - return; + + if (maildir_readquota(&info) >= percent[i]) + { + maildir_closequotafile(&info); + do_deliver_warning(QUOTAWARNMSG, dir, percent[i]); + return; + } } + maildir_closequotafile(&info); } } diff -rN -u old-maildrop-2.0.2/maildir/maildirquota.h
new-maildrop-2.0.2/maildir/maildirquota.h --- old-maildrop-2.0.2/maildir/maildirquota.h 2006-09-26 20:09:43.000000000
+0200 +++ new-maildrop-2.0.2/maildir/maildirquota.h 2006-09-26 20:09:50.000000000
+0200 @@ -140,7 +140,7 @@ int maildirquota_countfolder(const char *folder); int maildirquota_countfile(const char *filename);

-void maildir_deliver_quota_warning(const char *dir, const int percent); +void maildir_deliver_quota_warning(const char *dir, const int *percent);

#ifdef __cplusplus } diff -rN -u old-maildrop-2.0.2/maildrop/maildir.C
new-maildrop-2.0.2/maildrop/maildir.C --- old-maildrop-2.0.2/maildrop/maildir.C 2006-09-26 20:09:44.000000000 +0200 +++ new-maildrop-2.0.2/maildrop/maildir.C 2006-09-26 20:09:50.000000000 +0200 @@ -30,7 +30,7 @@ static const char rcsid[]="$Id: maildir.C,v 1.19 2004/01/15 03:12:13 mrsam Exp
$";

#include "../maildir/maildirquota.h" -extern int quota_warn_percent; +extern int quota_warn_percent[];

Maildir::Maildir() : is_open(0) , is_afs(0) { diff -rN -u old-maildrop-2.0.2/maildrop/main.C
new-maildrop-2.0.2/maildrop/main.C --- old-maildrop-2.0.2/maildrop/main.C 2006-09-26 20:09:44.000000000 +0200 +++ new-maildrop-2.0.2/maildrop/main.C 2006-09-26 20:09:50.000000000 +0200 @@ -42,13 +42,16 @@ extern "C" int gethostname(const char *, size_t); #endif

+#ifndef QUOTA_WARN_LEVELS +#define QUOTA_WARN_LEVELS 3 +#endif

extern void setprocgroup();

static Message m1, m2; extern char **environ; static int errexit=EX_TEMPFAIL; -int quota_warn_percent = -1; +int quota_warn_percent[QUOTA_WARN_LEVELS] ; static const char *defaults_vars[]={"LOCKEXT","LOCKSLEEP","LOCKTIMEOUT", "LOCKREFRESH", "PATH", "SENDMAIL", "MAILDIRQUOTA"}; @@ -435,7 +438,52 @@ case 'w': if (!*optarg && argn < argc) optarg=argv[argn++]; if (*optarg) - quota_warn_percent=atoi(optarg); + { + + int i, j, k; + char *str, *tok, *saveptr; + + for ( i=0; i<QUOTA_WARN_LEVELS; i++) + quota_warn_percent[i] = -1; + + for ( i=0, str = argv[argn-1] ; i < QUOTA_WARN_LEVELS ; i++, str = NULL ) + { + + tok = strtok_r ( str, ",", &saveptr ); + + if (tok == NULL) + break; + + quota_warn_percent[i] = atoi ( tok ); + + } + + // sort quota_warn_percent[] in descending order + for ( i=0; i < QUOTA_WARN_LEVELS - 1 ; i++ ) + { + + j = -2 ; + + for ( k=0; k < QUOTA_WARN_LEVELS - i - 1 ; k++ ) + { + + if ( quota_warn_percent[k] < quota_warn_percent[k+1] ) + { + + j = quota_warn_percent[k] ; + quota_warn_percent[k] = quota_warn_percent[k+1]; + quota_warn_percent[k+1] = j ; + + } + + } + + if ( j == -2 ) + break ; + + } + + } break; case 'h': help();