diff -Naur fetchmail-6.2.4.orig/conf.c fetchmail-6.2.4.new/conf.c --- fetchmail-6.2.4.orig/conf.c 2003-10-03 12:10:36.000000000 +0530 +++ fetchmail-6.2.4.new/conf.c 2003-10-03 12:27:04.000000000 +0530 @@ -374,6 +374,7 @@ stringdump("preconnect", ctl->preconnect); stringdump("postconnect", ctl->postconnect); numdump("limit", ctl->limit); + numdump("limitflush", ctl->limitflush); numdump("warnings", ctl->warnings); numdump("fetchlimit", ctl->fetchlimit); numdump("fetchsizelimit", ctl->fetchsizelimit); diff -Naur fetchmail-6.2.4.orig/driver.c fetchmail-6.2.4.new/driver.c --- fetchmail-6.2.4.orig/driver.c 2003-10-03 12:10:36.000000000 +0530 +++ fetchmail-6.2.4.new/driver.c 2003-10-10 13:52:56.000000000 +0530 @@ -335,7 +335,7 @@ stuff_warning(ctl, GT_("Subject: Fetchmail oversized-messages warning.\n" "\n" - "The following oversized messages remain on the mail server %s:"), + "The following oversized messages were skipped/flushed on the mail server %s:"), ctl->server.pollname); if (run.poll_interval == 0) @@ -350,9 +350,14 @@ { nbr = current->val.status.mark; size = atoi(current->id); - stuff_warning(ctl, - GT_("\t%d msg %d octets long skipped by fetchmail.\n"), + if (size > 0) + stuff_warning(ctl, + GT_("\t%d msg %d octets long skipped by fetchmail."), nbr, size); + else /* a negative size indicates that the mail was flushed due to "limitflush" */ + stuff_warning(ctl, + GT_("\t%d msg %d octets long flushed by fetchmail."), + nbr, -size); } current->val.status.num++; current->val.status.mark = 0; @@ -394,16 +399,9 @@ cnt = current ? current->val.status.num : 0; /* if entry exists, increment the count */ - if (current && str_in_list(¤t, sizestr, FALSE)) + if (current && (tmp = str_in_list(¤t, sizestr, FALSE))) { - for ( ; current; current = current->next) - { - if (strcmp(current->id, sizestr) == 0) - { - current->val.status.mark++; - break; - } - } + tmp->val.status.mark++; } /* otherwise, create a new entry */ /* initialise with current poll count */ @@ -422,10 +420,12 @@ flag force_retrieval; int num, firstnum = 1, lastnum = 0, err, len; int fetchsizelimit = ctl->fetchsizelimit; - int msgsize; + flag has_msgsizes = (msgsizes != NULL); if (ctl->server.base_protocol->getpartialsizes && NUM_NONZERO(fetchsizelimit)) { + has_msgsizes = FALSE; + /* for POP3, we can get the size of one mail only! Unfortunately, this * protocol specific test cannot be done elsewhere as the protocol * could be "auto". */ @@ -472,9 +472,10 @@ flag suppress_readbody = FALSE; flag retained = FALSE; int msgcode = MSGLEN_UNKNOWN; + /* the size of the message may not be known here */ + int msgsize = has_msgsizes ? msgsizes[num-firstnum] : 0; - /* check if the message is old - * Note: the size of the message may not be known here */ + /* check if the message is old */ if (ctl->fetchall || force_retrieval) ; else if (ctl->server.base_protocol->is_old && (ctl->server.base_protocol->is_old)(mailserver_socket,ctl,num)) @@ -490,7 +491,12 @@ (outlevel > O_SILENT && !run.use_syslog) ) { - report_build(stdout, + if (has_msgsizes) + report_build(stdout, + GT_("skipping message %s(_at_)%s:%d (%d octets)"), + ctl->remotename, ctl->server.truename, num, msgsize); + else + report_build(stdout, GT_("skipping message %s(_at_)%s:%d"), ctl->remotename, ctl->server.truename, num); } @@ -534,7 +540,8 @@ if (msgcode < 0) { - if ((msgcode == MSGLEN_TOOLARGE) && !check_only) + if (msgcode == MSGLEN_TOOLARGE && + !(NUM_NONZERO(ctl->limitflush) && msgsize > ctl->limitflush)) { mark_oversized(ctl, num, msgsize); suppress_delete = TRUE; @@ -775,6 +782,19 @@ if (err != 0) return(err); } + else if (ctl->server.base_protocol->delete + && !suppress_delete + && (NUM_NONZERO(ctl->limitflush) && + msgsize > ctl->limitflush)) + { + mark_oversized(ctl, num, -msgsize); + (*deletions)++; + if (outlevel > O_SILENT) + report_complete(stdout, GT_(" flushed oversized\n")); + err = (ctl->server.base_protocol->delete)(mailserver_socket, ctl, num); + if (err != 0) + return(err); + } else { if ( (outlevel >= O_VERBOSE) || @@ -1605,10 +1625,11 @@ return(PS_SYNTAX); } } - if (!proto->getsizes && NUM_SPECIFIED(ctl->limit)) + if (!(proto->getsizes || proto->getpartialsizes) && + (NUM_SPECIFIED(ctl->limit) || NUM_SPECIFIED(ctl->limitflush))) { report(stderr, - GT_("Option --limit is not supported with %s\n"), + GT_("Option --limit/--limitflush is not supported with %s\n"), proto->name); return(PS_SYNTAX); } diff -Naur fetchmail-6.2.4.orig/fetchmail.c fetchmail-6.2.4.new/fetchmail.c --- fetchmail-6.2.4.orig/fetchmail.c 2003-10-03 12:10:36.000000000 +0530 +++ fetchmail-6.2.4.new/fetchmail.c 2003-10-03 14:16:03.000000000 +0530 @@ -877,6 +877,7 @@ FLAG_MERGE(mimedecode); FLAG_MERGE(idle); FLAG_MERGE(limit); + FLAG_MERGE(limitflush); FLAG_MERGE(warnings); FLAG_MERGE(fetchlimit); FLAG_MERGE(fetchsizelimit); @@ -1624,12 +1625,17 @@ ctl->dropdelivered ? GT_("discarded") : GT_("kept"), ctl->dropdelivered ? "on" : "off"); if (NUM_NONZERO(ctl->limit)) + printf(GT_(" Message size limit is %d octets (--limit %d).\n"), + ctl->limit, ctl->limit); + else if (outlevel >= O_VERBOSE) + printf(GT_(" No message size limit (--limit 0).\n")); + if (NUM_NONZERO(ctl->limitflush)) + printf(GT_(" Message size limit flush is %d octets (--limitflush %d).\n"), + ctl->limitflush, ctl->limitflush); + else if (outlevel >= O_VERBOSE) + printf(GT_(" No message size limit flush (--limitflush 0).\n")); + if (NUM_NONZERO(ctl->limit) || NUM_NONZERO(ctl->limitflush)) { - if (NUM_NONZERO(ctl->limit)) - printf(GT_(" Message size limit is %d octets (--limit %d).\n"), - ctl->limit, ctl->limit); - else if (outlevel >= O_VERBOSE) - printf(GT_(" No message size limit (--limit 0).\n")); if (run.poll_interval > 0) printf(GT_(" Message size warning interval is %d seconds (--warnings %d).\n"), ctl->warnings, ctl->warnings); diff -Naur fetchmail-6.2.4.orig/fetchmail.h fetchmail-6.2.4.new/fetchmail.h --- fetchmail-6.2.4.orig/fetchmail.h 2003-10-03 12:10:36.000000000 +0530 +++ fetchmail-6.2.4.new/fetchmail.h 2003-10-03 12:40:39.000000000 +0530 @@ -289,6 +289,7 @@ flag mimedecode; /* if TRUE, decode MIME-armored messages */ flag idle; /* if TRUE, idle after each poll */ int limit; /* limit size of retrieved messages */ + int limitflush; /* delete mails over this size */ int warnings; /* size warning interval */ int fetchlimit; /* max # msgs to get in single poll */ int fetchsizelimit; /* max # msg sizes to get in a request */ diff -Naur fetchmail-6.2.4.orig/fetchmail.man fetchmail-6.2.4.new/fetchmail.man --- fetchmail-6.2.4.orig/fetchmail.man 2003-10-03 12:10:36.000000000 +0530 +++ fetchmail-6.2.4.new/fetchmail.man 2003-10-10 13:52:48.000000000 +0530 @@ -164,8 +164,12 @@ .B \-F | \-\-flush POP3/IMAP only. Delete old (previously retrieved) messages from the mailserver before retrieving new messages. This option does not work with ETRN or -ODMR. In combination with the --limit option, --flush can be used to -delete oversized messages waiting on the server. +ODMR. + +Note: To delete oversized mails, use the +.B limitflush +option. + Warning: if your local MTA hangs and fetchmail is aborted, the next time you run fetchmail, it will delete mail that was never delivered to you. What you probably want is the default setting: if you don't specify `-k', then @@ -448,16 +452,39 @@ marked seen An explicit --limit of 0 overrides any limits set in your run control file. This option is intended for those needing to strictly control fetch time due to expensive and variable phone rates. -Combined with --flush, it can be used to delete oversized messages -waiting on a server. In daemon mode, oversize notifications are -mailed to the calling user (see the --warnings option). This option -does not work with ETRN or ODMR. +In daemon mode, oversize notifications are mailed to the calling user +(see the --warnings option). This option does not work with ETRN or +ODMR. + +Note: To delete mails bigger than a particular size, use the +.B limitflush +option. +.TP +.B \-\-limitflush +(Keyword: limitflush) Takes a maximum octet size argument. Messages larger +than this size will be deleted from the server even if +.B keep +and/or +.B limit +options are enabled. The progress messages will note that they are +"flushed oversized". An explicit --limitflush of 0 overrides any +limits set in your run control file. This option does not work with +ETRN or ODMR. + +Note: The mail will still be downloaded first, unless the size of the +mail is bigger than the size given with the +.B limit +option. .TP .B \-w | \-\-warnings (Keyword: warnings) Takes an interval in seconds. When you call .I fetchmail -with a `limit' option in daemon mode, this controls the interval at +with a +.B limit +and/or +.B limitflush +option in daemon mode, this controls the interval at which warnings about oversized messages are mailed to the calling user (or the user specified by the `postmaster' option). One such notification is always mailed at the end of the the first poll that @@ -1492,6 +1519,9 @@ limit -l T{ Set message size limit T} +limitflush -l T{ +Set message size limit for deletion +T} warnings -w T{ Set message size warning interval T} diff -Naur fetchmail-6.2.4.orig/fetchmailconf fetchmail-6.2.4.new/fetchmailconf --- fetchmail-6.2.4.orig/fetchmailconf 2003-10-03 12:10:36.000000000 +0530 +++ fetchmail-6.2.4.new/fetchmailconf 2003-10-03 13:32:18.000000000 +0530 @@ -248,6 +248,7 @@ self.dropdelivered = FALSE # Drop incoming Delivered-To lines self.idle = FALSE # IDLE after poll self.limit = 0 # Message size limit + self.limitflush = 0 # Message size limit for flush self.warnings = 3600 # Size warning interval (see tunable.h) self.fetchlimit = 0 # Max messages fetched per batch self.fetchsizelimit = 100 # Max message sizes fetched per transaction @@ -287,6 +288,7 @@ ('dropdelivered', 'Boolean'), ('idle', 'Boolean'), ('limit', 'Int'), + ('limitflush', 'Int'), ('warnings', 'Int'), ('fetchlimit', 'Int'), ('fetchsizelimit', 'Int'), @@ -347,6 +349,8 @@ res = res + flag2str(self.idle, 'idle') if self.limit != UserDefaults.limit: res = res + " limit " + `self.limit` + if self.limitflush != UserDefaults.limitflush: + res = res + " limitflush " + `self.limitflush` if self.warnings != UserDefaults.warnings: res = res + " warnings " + `self.warnings` if self.fetchlimit != UserDefaults.fetchlimit: @@ -1705,6 +1709,8 @@ Label(limwin, text="Resource Limits").pack(side=TOP) LabeledEntry(limwin, 'Message size limit:', self.limit, '30').pack(side=TOP, fill=X) + LabeledEntry(limwin, 'Message size limit for deletion:', + self.limitflush, '30').pack(side=TOP, fill=X) LabeledEntry(limwin, 'Size warning interval:', self.warnings, '30').pack(side=TOP, fill=X) LabeledEntry(limwin, 'Max messages to fetch per poll:', diff -Naur fetchmail-6.2.4.orig/options.c fetchmail-6.2.4.new/options.c --- fetchmail-6.2.4.orig/options.c 2003-10-03 12:10:36.000000000 +0530 +++ fetchmail-6.2.4.new/options.c 2003-10-03 13:45:30.000000000 +0530 @@ -89,6 +89,10 @@ #define LA_FETCHSIZELIMIT 61 #define LA_FASTUIDL 62 +/* don't use 63-122: they could clash with short options */ + +#define LA_LIMITFLUSH 128 + /* options still left: CDgGhHjJoORwWxXYz */ static const char *shortoptions = "?Vcsvd:NqL:f:i:p:UP:A:t:E:Q:u:akKFnl:r:S:Z:b:B:e:m:T:I:M:yw:D:"; @@ -131,6 +135,7 @@ {"flush", no_argument, (int *) 0, LA_FLUSH }, {"norewrite", no_argument, (int *) 0, LA_NOREWRITE }, {"limit", required_argument, (int *) 0, LA_LIMIT }, + {"limitflush", required_argument, (int *) 0, LA_LIMITFLUSH }, {"warnings", required_argument, (int *) 0, LA_WARNINGS }, {"folder", required_argument, (int *) 0, LA_FOLDER }, @@ -474,6 +479,10 @@ c = xatoi(optarg, &errflag); ctl->limit = NUM_VALUE_IN(c); break; + case LA_LIMITFLUSH: + c = xatoi(optarg, &errflag); + ctl->limitflush = NUM_VALUE_IN(c); + break; case 'r': case LA_FOLDER: xalloca(buf, char *, strlen(optarg) + 1); @@ -705,6 +714,7 @@ P(GT_(" -F, --flush delete old messages from server\n")); P(GT_(" -n, --norewrite don't rewrite header addresses\n")); P(GT_(" -l, --limit don't fetch messages over given size\n")); + P(GT_(" --limitflush delete messages over given size\n")); P(GT_(" -w, --warnings interval between warning mail notification\n")); #if NET_SECURITY diff -Naur fetchmail-6.2.4.orig/rcfile_l.l fetchmail-6.2.4.new/rcfile_l.l --- fetchmail-6.2.4.orig/rcfile_l.l 2003-10-03 12:10:36.000000000 +0530 +++ fetchmail-6.2.4.new/rcfile_l.l 2003-10-03 13:45:56.000000000 +0530 @@ -181,6 +181,7 @@ checkalias { return CHECKALIAS; } limit { return LIMIT; } +limitflush { return LIMITFLUSH; } with {/* EMPTY */} and {/* EMPTY */} diff -Naur fetchmail-6.2.4.orig/rcfile_y.y fetchmail-6.2.4.new/rcfile_y.y --- fetchmail-6.2.4.orig/rcfile_y.y 2003-10-03 12:10:36.000000000 +0530 +++ fetchmail-6.2.4.new/rcfile_y.y 2003-10-03 13:46:26.000000000 +0530 @@ -64,7 +64,7 @@ %token DEFAULTS POLL SKIP VIA AKA LOCALDOMAINS PROTOCOL %token AUTHENTICATE TIMEOUT KPOP SDPS ENVELOPE QVIRTUAL %token USERNAME PASSWORD FOLDER SMTPHOST FETCHDOMAINS MDA BSMTP LMTP -%token SMTPADDRESS SMTPNAME SPAMRESPONSE PRECONNECT POSTCONNECT LIMIT WARNINGS +%token SMTPADDRESS SMTPNAME SPAMRESPONSE PRECONNECT POSTCONNECT LIMIT LIMITFLUSH WARNINGS %token NETSEC INTERFACE MONITOR PLUGIN PLUGOUT %token IS HERE THERE TO MAP WILDCARD %token BATCHLIMIT FETCHLIMIT FETCHSIZELIMIT FASTUIDL EXPUNGE PROPERTIES @@ -372,6 +372,7 @@ | NO SSL {current.use_ssl = FLAG_FALSE;} | LIMIT NUMBER {current.limit = NUM_VALUE_IN($2);} + | LIMITFLUSH NUMBER {current.limitflush = NUM_VALUE_IN($2);} | WARNINGS NUMBER {current.warnings = NUM_VALUE_IN($2);} | FETCHLIMIT NUMBER {current.fetchlimit = NUM_VALUE_IN($2);} | FETCHSIZELIMIT NUMBER {current.fetchsizelimit = NUM_VALUE_IN($2);}