You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(73) |
Jul
(22) |
Aug
(42) |
Sep
(11) |
Oct
(23) |
Nov
(40) |
Dec
(2) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
|
Feb
|
Mar
(17) |
Apr
(26) |
May
(6) |
Jun
(21) |
Jul
(133) |
Aug
(25) |
Sep
(40) |
Oct
(12) |
Nov
(71) |
Dec
(57) |
2006 |
Jan
(23) |
Feb
(22) |
Mar
(43) |
Apr
(27) |
May
(13) |
Jun
(7) |
Jul
(3) |
Aug
(20) |
Sep
(16) |
Oct
(17) |
Nov
(31) |
Dec
(10) |
2007 |
Jan
(12) |
Feb
(17) |
Mar
(26) |
Apr
(13) |
May
(4) |
Jun
(1) |
Jul
(1) |
Aug
(21) |
Sep
(3) |
Oct
(8) |
Nov
(8) |
Dec
(5) |
2008 |
Jan
(5) |
Feb
(1) |
Mar
(3) |
Apr
(10) |
May
(3) |
Jun
(11) |
Jul
(5) |
Aug
(1) |
Sep
(6) |
Oct
|
Nov
(10) |
Dec
(2) |
2009 |
Jan
(17) |
Feb
(2) |
Mar
(1) |
Apr
(9) |
May
(23) |
Jun
(22) |
Jul
(32) |
Aug
(30) |
Sep
(11) |
Oct
(24) |
Nov
(4) |
Dec
|
2010 |
Jan
(12) |
Feb
(56) |
Mar
(32) |
Apr
(41) |
May
(36) |
Jun
(14) |
Jul
(7) |
Aug
(10) |
Sep
(13) |
Oct
(16) |
Nov
|
Dec
(14) |
2011 |
Jan
(3) |
Feb
|
Mar
(1) |
Apr
(16) |
May
(36) |
Jun
(2) |
Jul
|
Aug
(9) |
Sep
(2) |
Oct
(1) |
Nov
(8) |
Dec
(3) |
2012 |
Jan
(1) |
Feb
(5) |
Mar
(1) |
Apr
(1) |
May
(2) |
Jun
|
Jul
|
Aug
(7) |
Sep
(9) |
Oct
(2) |
Nov
(8) |
Dec
(9) |
2013 |
Jan
(11) |
Feb
(6) |
Mar
(14) |
Apr
(10) |
May
|
Jun
(12) |
Jul
(2) |
Aug
(2) |
Sep
(2) |
Oct
|
Nov
(7) |
Dec
(4) |
2014 |
Jan
(1) |
Feb
|
Mar
(2) |
Apr
(1) |
May
|
Jun
|
Jul
(1) |
Aug
(1) |
Sep
(1) |
Oct
(1) |
Nov
|
Dec
|
2015 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2016 |
Jan
|
Feb
|
Mar
|
Apr
(4) |
May
|
Jun
(7) |
Jul
|
Aug
(8) |
Sep
(8) |
Oct
|
Nov
|
Dec
(2) |
2017 |
Jan
|
Feb
|
Mar
(2) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(3) |
Nov
|
Dec
|
2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(2) |
Oct
(2) |
Nov
|
Dec
|
2019 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(3) |
Jun
|
Jul
|
Aug
(6) |
Sep
(3) |
Oct
|
Nov
|
Dec
|
2020 |
Jan
(2) |
Feb
(3) |
Mar
(5) |
Apr
(2) |
May
(3) |
Jun
(3) |
Jul
(3) |
Aug
(2) |
Sep
(3) |
Oct
(4) |
Nov
(3) |
Dec
|
2021 |
Jan
(5) |
Feb
(2) |
Mar
(3) |
Apr
(3) |
May
|
Jun
|
Jul
(2) |
Aug
(14) |
Sep
(3) |
Oct
(4) |
Nov
(4) |
Dec
(3) |
2022 |
Jan
|
Feb
(2) |
Mar
(2) |
Apr
(1) |
May
|
Jun
|
Jul
(3) |
Aug
(1) |
Sep
|
Oct
(2) |
Nov
|
Dec
|
2023 |
Jan
(3) |
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2024 |
Jan
(2) |
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
(1) |
Aug
|
Sep
(2) |
Oct
(1) |
Nov
(1) |
Dec
(1) |
2025 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(3) |
Jul
(1) |
Aug
(1) |
Sep
(2) |
Oct
|
Nov
|
Dec
|
From: Samuel M. <s.m...@gm...> - 2016-06-08 19:36:53
|
This whitespace-only change substitutes all leading tabulations with the right number of spaces to get the standard 4-space indentation. This bug was triggered by the Buildroot farms: http://autobuild.buildroot.org/results/700/7009445dd116a1c02db82a351d38db44db8dad16/build-end.log Signed-off-by: Samuel Martin <s.m...@gm...> --- fetchmailconf.py | 2532 +++++++++++++++++++++++++++--------------------------- 1 file changed, 1266 insertions(+), 1266 deletions(-) diff --git a/fetchmailconf.py b/fetchmailconf.py index 2dc02d8..d64556e 100755 --- a/fetchmailconf.py +++ b/fetchmailconf.py @@ -16,416 +16,416 @@ import sys, time, os, string, socket, getopt, tempfile # class Configuration: def __init__(self): - self.poll_interval = 0 # Normally, run in foreground - self.logfile = None # No logfile, initially - self.idfile = os.environ["HOME"] + "/.fetchids" # Default idfile, initially - self.postmaster = None # No last-resort address, initially - self.bouncemail = TRUE # Bounce errors to users - self.spambounce = FALSE # Bounce spam errors - self.softbounce = TRUE # Treat permanent error as temporary - self.properties = None # No exiguous properties - self.invisible = FALSE # Suppress Received line & spoof? - self.syslog = FALSE # Use syslogd for logging? - self.servers = [] # List of included sites - Configuration.typemap = ( - ('poll_interval', 'Int'), - ('logfile', 'String'), - ('idfile', 'String'), - ('postmaster', 'String'), - ('bouncemail', 'Boolean'), - ('spambounce', 'Boolean'), - ('softbounce', 'Boolean'), - ('properties', 'String'), - ('syslog', 'Boolean'), - ('invisible', 'Boolean')) + self.poll_interval = 0 # Normally, run in foreground + self.logfile = None # No logfile, initially + self.idfile = os.environ["HOME"] + "/.fetchids" # Default idfile, initially + self.postmaster = None # No last-resort address, initially + self.bouncemail = TRUE # Bounce errors to users + self.spambounce = FALSE # Bounce spam errors + self.softbounce = TRUE # Treat permanent error as temporary + self.properties = None # No exiguous properties + self.invisible = FALSE # Suppress Received line & spoof? + self.syslog = FALSE # Use syslogd for logging? + self.servers = [] # List of included sites + Configuration.typemap = ( + ('poll_interval', 'Int'), + ('logfile', 'String'), + ('idfile', 'String'), + ('postmaster', 'String'), + ('bouncemail', 'Boolean'), + ('spambounce', 'Boolean'), + ('softbounce', 'Boolean'), + ('properties', 'String'), + ('syslog', 'Boolean'), + ('invisible', 'Boolean')) def __repr__(self): - str = ""; - if self.syslog != ConfigurationDefaults.syslog: - str = str + ("set syslog\n") - elif self.logfile: - str = str + ("set logfile \"%s\"\n" % (self.logfile,)); - if self.idfile != ConfigurationDefaults.idfile: - str = str + ("set idfile \"%s\"\n" % (self.idfile,)); - if self.postmaster != ConfigurationDefaults.postmaster: - str = str + ("set postmaster \"%s\"\n" % (self.postmaster,)); - if self.bouncemail: - str = str + ("set bouncemail\n") - else: - str = str + ("set nobouncemail\n") - if self.spambounce: - str = str + ("set spambounce\n") - else: - str = str + ("set no spambounce\n") - if self.softbounce: - str = str + ("set softbounce\n") - else: - str = str + ("set no softbounce\n") - if self.properties != ConfigurationDefaults.properties: - str = str + ("set properties \"%s\"\n" % (self.properties,)); - if self.poll_interval > 0: - str = str + "set daemon " + `self.poll_interval` + "\n" - if self.invisible: - str = str + ("set invisible\n") - for site in self.servers: - str = str + repr(site) - return str + str = ""; + if self.syslog != ConfigurationDefaults.syslog: + str = str + ("set syslog\n") + elif self.logfile: + str = str + ("set logfile \"%s\"\n" % (self.logfile,)); + if self.idfile != ConfigurationDefaults.idfile: + str = str + ("set idfile \"%s\"\n" % (self.idfile,)); + if self.postmaster != ConfigurationDefaults.postmaster: + str = str + ("set postmaster \"%s\"\n" % (self.postmaster,)); + if self.bouncemail: + str = str + ("set bouncemail\n") + else: + str = str + ("set nobouncemail\n") + if self.spambounce: + str = str + ("set spambounce\n") + else: + str = str + ("set no spambounce\n") + if self.softbounce: + str = str + ("set softbounce\n") + else: + str = str + ("set no softbounce\n") + if self.properties != ConfigurationDefaults.properties: + str = str + ("set properties \"%s\"\n" % (self.properties,)); + if self.poll_interval > 0: + str = str + "set daemon " + `self.poll_interval` + "\n" + if self.invisible: + str = str + ("set invisible\n") + for site in self.servers: + str = str + repr(site) + return str def __delitem__(self, name): - for si in range(len(self.servers)): - if self.servers[si].pollname == name: - del self.servers[si] - break + for si in range(len(self.servers)): + if self.servers[si].pollname == name: + del self.servers[si] + break def __str__(self): - return "[Configuration: " + repr(self) + "]" + return "[Configuration: " + repr(self) + "]" class Server: def __init__(self): - self.pollname = None # Poll label - self.via = None # True name of host - self.active = TRUE # Poll status - self.interval = 0 # Skip interval - self.protocol = 'auto' # Default to auto protocol - self.service = None # Service name to use - self.uidl = FALSE # Don't use RFC1725 UIDLs by default - self.auth = 'any' # Default to password authentication - self.timeout = 300 # 5-minute timeout - self.envelope = 'Received' # Envelope-address header - self.envskip = 0 # Number of envelope headers to skip - self.qvirtual = None # Name prefix to strip - self.aka = [] # List of DNS aka names - self.dns = TRUE # Enable DNS lookup on multidrop - self.localdomains = [] # Domains to be considered local - self.interface = None # IP address and range - self.monitor = None # IP address and range - self.plugin = None # Plugin command for going to server - self.plugout = None # Plugin command for going to listener - self.principal = None # Kerberos principal - self.esmtpname = None # ESMTP 2554 name - self.esmtppassword = None # ESMTP 2554 password - self.tracepolls = FALSE # Add trace-poll info to headers - self.badheader = FALSE # Pass messages with bad headers on? - self.users = [] # List of user entries for site - Server.typemap = ( - ('pollname', 'String'), - ('via', 'String'), - ('active', 'Boolean'), - ('interval', 'Int'), - ('protocol', 'String'), - ('service', 'String'), - ('uidl', 'Boolean'), - ('auth', 'String'), - ('timeout', 'Int'), - ('envelope', 'String'), - ('envskip', 'Int'), - ('qvirtual', 'String'), - # leave aka out - ('dns', 'Boolean'), - # leave localdomains out - ('interface', 'String'), - ('monitor', 'String'), - ('plugin', 'String'), - ('plugout', 'String'), - ('esmtpname', 'String'), - ('esmtppassword', 'String'), - ('principal', 'String'), - ('tracepolls','Boolean'), - ('badheader', 'Boolean')) + self.pollname = None # Poll label + self.via = None # True name of host + self.active = TRUE # Poll status + self.interval = 0 # Skip interval + self.protocol = 'auto' # Default to auto protocol + self.service = None # Service name to use + self.uidl = FALSE # Don't use RFC1725 UIDLs by default + self.auth = 'any' # Default to password authentication + self.timeout = 300 # 5-minute timeout + self.envelope = 'Received' # Envelope-address header + self.envskip = 0 # Number of envelope headers to skip + self.qvirtual = None # Name prefix to strip + self.aka = [] # List of DNS aka names + self.dns = TRUE # Enable DNS lookup on multidrop + self.localdomains = [] # Domains to be considered local + self.interface = None # IP address and range + self.monitor = None # IP address and range + self.plugin = None # Plugin command for going to server + self.plugout = None # Plugin command for going to listener + self.principal = None # Kerberos principal + self.esmtpname = None # ESMTP 2554 name + self.esmtppassword = None # ESMTP 2554 password + self.tracepolls = FALSE # Add trace-poll info to headers + self.badheader = FALSE # Pass messages with bad headers on? + self.users = [] # List of user entries for site + Server.typemap = ( + ('pollname', 'String'), + ('via', 'String'), + ('active', 'Boolean'), + ('interval', 'Int'), + ('protocol', 'String'), + ('service', 'String'), + ('uidl', 'Boolean'), + ('auth', 'String'), + ('timeout', 'Int'), + ('envelope', 'String'), + ('envskip', 'Int'), + ('qvirtual', 'String'), + # leave aka out + ('dns', 'Boolean'), + # leave localdomains out + ('interface', 'String'), + ('monitor', 'String'), + ('plugin', 'String'), + ('plugout', 'String'), + ('esmtpname', 'String'), + ('esmtppassword', 'String'), + ('principal', 'String'), + ('tracepolls','Boolean'), + ('badheader', 'Boolean')) def dump(self, folded): - res = "" - if self.active: res = res + "poll" - else: res = res + "skip" - res = res + (" " + self.pollname) - if self.via: - res = res + (" via " + str(self.via) + "\n"); - if self.protocol != ServerDefaults.protocol: - res = res + " with proto " + self.protocol - if self.service and self.protocol and self.service != defaultports[self.protocol] and defaultports[self.protocol] and self.service != ianaservices[defaultports[self.protocol]]: - res = res + " service " + self.service - if self.timeout != ServerDefaults.timeout: - res = res + " timeout " + `self.timeout` - if self.interval != ServerDefaults.interval: - res = res + " interval " + `self.interval` - if self.envelope != ServerDefaults.envelope or self.envskip != ServerDefaults.envskip: - if self.envskip: - res = res + " envelope " + `self.envskip` + " " + self.envelope - else: - res = res + " envelope " + self.envelope - if self.qvirtual: - res = res + (" qvirtual " + str(self.qvirtual) + "\n"); - if self.auth != ServerDefaults.auth: - res = res + " auth " + self.auth - if self.dns != ServerDefaults.dns or self.uidl != ServerDefaults.uidl: - res = res + " and options" - if self.dns != ServerDefaults.dns: - res = res + flag2str(self.dns, 'dns') - if self.uidl != ServerDefaults.uidl: - res = res + flag2str(self.uidl, 'uidl') - if folded: res = res + "\n " - else: res = res + " " - - if self.aka: - res = res + "aka" - for x in self.aka: - res = res + " " + x - if self.aka and self.localdomains: res = res + " " - if self.localdomains: - res = res + ("localdomains") - for x in self.localdomains: - res = res + " " + x - if (self.aka or self.localdomains): - if folded: - res = res + "\n " - else: - res = res + " " - - if self.tracepolls: - res = res + "tracepolls\n" - - if self.interface: - res = res + " interface " + str(self.interface) - if self.monitor: - res = res + " monitor " + str(self.monitor) - if self.plugin: - res = res + " plugin " + `self.plugin` - if self.plugout: - res = res + " plugout " + `self.plugout` - if self.principal: - res = res + " principal " + `self.principal` - if self.esmtpname: - res = res + " esmtpname " + `self.esmtpname` - if self.esmtppassword: - res = res + " esmtppassword " + `self.esmtppassword` - if self.interface or self.monitor or self.principal or self.plugin or self.plugout: - if folded: - res = res + "\n" - if self.badheader: - res = res + "bad-header accept " - - if res[-1] == " ": res = res[0:-1] - - for user in self.users: - res = res + repr(user) - res = res + "\n" - return res; + res = "" + if self.active: res = res + "poll" + else: res = res + "skip" + res = res + (" " + self.pollname) + if self.via: + res = res + (" via " + str(self.via) + "\n"); + if self.protocol != ServerDefaults.protocol: + res = res + " with proto " + self.protocol + if self.service and self.protocol and self.service != defaultports[self.protocol] and defaultports[self.protocol] and self.service != ianaservices[defaultports[self.protocol]]: + res = res + " service " + self.service + if self.timeout != ServerDefaults.timeout: + res = res + " timeout " + `self.timeout` + if self.interval != ServerDefaults.interval: + res = res + " interval " + `self.interval` + if self.envelope != ServerDefaults.envelope or self.envskip != ServerDefaults.envskip: + if self.envskip: + res = res + " envelope " + `self.envskip` + " " + self.envelope + else: + res = res + " envelope " + self.envelope + if self.qvirtual: + res = res + (" qvirtual " + str(self.qvirtual) + "\n"); + if self.auth != ServerDefaults.auth: + res = res + " auth " + self.auth + if self.dns != ServerDefaults.dns or self.uidl != ServerDefaults.uidl: + res = res + " and options" + if self.dns != ServerDefaults.dns: + res = res + flag2str(self.dns, 'dns') + if self.uidl != ServerDefaults.uidl: + res = res + flag2str(self.uidl, 'uidl') + if folded: res = res + "\n " + else: res = res + " " + + if self.aka: + res = res + "aka" + for x in self.aka: + res = res + " " + x + if self.aka and self.localdomains: res = res + " " + if self.localdomains: + res = res + ("localdomains") + for x in self.localdomains: + res = res + " " + x + if (self.aka or self.localdomains): + if folded: + res = res + "\n " + else: + res = res + " " + + if self.tracepolls: + res = res + "tracepolls\n" + + if self.interface: + res = res + " interface " + str(self.interface) + if self.monitor: + res = res + " monitor " + str(self.monitor) + if self.plugin: + res = res + " plugin " + `self.plugin` + if self.plugout: + res = res + " plugout " + `self.plugout` + if self.principal: + res = res + " principal " + `self.principal` + if self.esmtpname: + res = res + " esmtpname " + `self.esmtpname` + if self.esmtppassword: + res = res + " esmtppassword " + `self.esmtppassword` + if self.interface or self.monitor or self.principal or self.plugin or self.plugout: + if folded: + res = res + "\n" + if self.badheader: + res = res + "bad-header accept " + + if res[-1] == " ": res = res[0:-1] + + for user in self.users: + res = res + repr(user) + res = res + "\n" + return res; def __delitem__(self, name): - for ui in range(len(self.users)): - if self.users[ui].remote == name: - del self.users[ui] - break + for ui in range(len(self.users)): + if self.users[ui].remote == name: + del self.users[ui] + break def __repr__(self): - return self.dump(TRUE) + return self.dump(TRUE) def __str__(self): - return "[Server: " + self.dump(FALSE) + "]" + return "[Server: " + self.dump(FALSE) + "]" class User: def __init__(self): - if os.environ.has_key("USER"): - self.remote = os.environ["USER"] # Remote username - elif os.environ.has_key("LOGNAME"): - self.remote = os.environ["LOGNAME"] - else: - print "Can't get your username!" - sys.exit(1) - self.localnames = [self.remote,]# Local names - self.password = None # Password for mail account access - self.mailboxes = [] # Remote folders to retrieve from - self.smtphunt = [] # Hosts to forward to - self.fetchdomains = [] # Domains to fetch from - self.smtpaddress = None # Append this to MAIL FROM line - self.smtpname = None # Use this for RCPT TO - self.preconnect = None # Connection setup - self.postconnect = None # Connection wrapup - self.mda = None # Mail Delivery Agent - self.bsmtp = None # BSMTP output file - self.lmtp = FALSE # Use LMTP rather than SMTP? - self.antispam = "" # Listener's spam-block code - self.keep = FALSE # Keep messages - self.flush = FALSE # Flush messages - self.limitflush = FALSE # Flush oversized messages - self.fetchall = FALSE # Fetch old messages - self.rewrite = TRUE # Rewrite message headers - self.forcecr = FALSE # Force LF -> CR/LF - self.stripcr = FALSE # Strip CR - self.pass8bits = FALSE # Force BODY=7BIT - self.mimedecode = FALSE # Undo MIME armoring - self.dropstatus = FALSE # Drop incoming Status lines - self.dropdelivered = FALSE # Drop incoming Delivered-To lines - self.idle = FALSE # IDLE after poll - self.limit = 0 # Message size limit - 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 - self.fastuidl = 4 # Do fast uidl 3 out of 4 times - self.batchlimit = 0 # Max message forwarded per batch - self.expunge = 0 # Interval between expunges (IMAP) - self.ssl = 0 # Enable Seccure Socket Layer - self.sslkey = None # SSL key filename - self.sslcert = None # SSL certificate filename - self.sslproto = None # Force SSL? - self.sslcertck = 0 # Enable strict SSL cert checking - self.sslcertpath = None # Path to trusted certificates - self.sslcommonname = None # SSL CommonName to expect - self.sslfingerprint = None # SSL key fingerprint to check - self.properties = None # Extension properties - User.typemap = ( - ('remote', 'String'), - # leave out mailboxes and localnames - ('password', 'String'), - # Leave out smtphunt, fetchdomains - ('smtpaddress', 'String'), - ('smtpname', 'String'), - ('preconnect', 'String'), - ('postconnect', 'String'), - ('mda', 'String'), - ('bsmtp', 'String'), - ('lmtp', 'Boolean'), - ('antispam', 'String'), - ('keep', 'Boolean'), - ('flush', 'Boolean'), - ('limitflush', 'Boolean'), - ('fetchall', 'Boolean'), - ('rewrite', 'Boolean'), - ('forcecr', 'Boolean'), - ('stripcr', 'Boolean'), - ('pass8bits', 'Boolean'), - ('mimedecode', 'Boolean'), - ('dropstatus', 'Boolean'), - ('dropdelivered', 'Boolean'), - ('idle', 'Boolean'), - ('limit', 'Int'), - ('warnings', 'Int'), - ('fetchlimit', 'Int'), - ('fetchsizelimit', 'Int'), - ('fastuidl', 'Int'), - ('batchlimit', 'Int'), - ('expunge', 'Int'), - ('ssl', 'Boolean'), - ('sslkey', 'String'), - ('sslcert', 'String'), - ('sslcertck', 'Boolean'), - ('sslcertpath', 'String'), - ('sslcommonname', 'String'), - ('sslfingerprint', 'String'), - ('properties', 'String')) + if os.environ.has_key("USER"): + self.remote = os.environ["USER"] # Remote username + elif os.environ.has_key("LOGNAME"): + self.remote = os.environ["LOGNAME"] + else: + print "Can't get your username!" + sys.exit(1) + self.localnames = [self.remote,]# Local names + self.password = None # Password for mail account access + self.mailboxes = [] # Remote folders to retrieve from + self.smtphunt = [] # Hosts to forward to + self.fetchdomains = [] # Domains to fetch from + self.smtpaddress = None # Append this to MAIL FROM line + self.smtpname = None # Use this for RCPT TO + self.preconnect = None # Connection setup + self.postconnect = None # Connection wrapup + self.mda = None # Mail Delivery Agent + self.bsmtp = None # BSMTP output file + self.lmtp = FALSE # Use LMTP rather than SMTP? + self.antispam = "" # Listener's spam-block code + self.keep = FALSE # Keep messages + self.flush = FALSE # Flush messages + self.limitflush = FALSE # Flush oversized messages + self.fetchall = FALSE # Fetch old messages + self.rewrite = TRUE # Rewrite message headers + self.forcecr = FALSE # Force LF -> CR/LF + self.stripcr = FALSE # Strip CR + self.pass8bits = FALSE # Force BODY=7BIT + self.mimedecode = FALSE # Undo MIME armoring + self.dropstatus = FALSE # Drop incoming Status lines + self.dropdelivered = FALSE # Drop incoming Delivered-To lines + self.idle = FALSE # IDLE after poll + self.limit = 0 # Message size limit + 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 + self.fastuidl = 4 # Do fast uidl 3 out of 4 times + self.batchlimit = 0 # Max message forwarded per batch + self.expunge = 0 # Interval between expunges (IMAP) + self.ssl = 0 # Enable Seccure Socket Layer + self.sslkey = None # SSL key filename + self.sslcert = None # SSL certificate filename + self.sslproto = None # Force SSL? + self.sslcertck = 0 # Enable strict SSL cert checking + self.sslcertpath = None # Path to trusted certificates + self.sslcommonname = None # SSL CommonName to expect + self.sslfingerprint = None # SSL key fingerprint to check + self.properties = None # Extension properties + User.typemap = ( + ('remote', 'String'), + # leave out mailboxes and localnames + ('password', 'String'), + # Leave out smtphunt, fetchdomains + ('smtpaddress', 'String'), + ('smtpname', 'String'), + ('preconnect', 'String'), + ('postconnect', 'String'), + ('mda', 'String'), + ('bsmtp', 'String'), + ('lmtp', 'Boolean'), + ('antispam', 'String'), + ('keep', 'Boolean'), + ('flush', 'Boolean'), + ('limitflush', 'Boolean'), + ('fetchall', 'Boolean'), + ('rewrite', 'Boolean'), + ('forcecr', 'Boolean'), + ('stripcr', 'Boolean'), + ('pass8bits', 'Boolean'), + ('mimedecode', 'Boolean'), + ('dropstatus', 'Boolean'), + ('dropdelivered', 'Boolean'), + ('idle', 'Boolean'), + ('limit', 'Int'), + ('warnings', 'Int'), + ('fetchlimit', 'Int'), + ('fetchsizelimit', 'Int'), + ('fastuidl', 'Int'), + ('batchlimit', 'Int'), + ('expunge', 'Int'), + ('ssl', 'Boolean'), + ('sslkey', 'String'), + ('sslcert', 'String'), + ('sslcertck', 'Boolean'), + ('sslcertpath', 'String'), + ('sslcommonname', 'String'), + ('sslfingerprint', 'String'), + ('properties', 'String')) def __repr__(self): - res = " " - res = res + "user " + `self.remote` + " there "; - if self.password: - res = res + "with password " + `self.password` + " " - if self.localnames: - res = res + "is" - for x in self.localnames: - res = res + " " + `x` - res = res + " here" - if (self.keep != UserDefaults.keep - or self.flush != UserDefaults.flush - or self.limitflush != UserDefaults.limitflush - or self.fetchall != UserDefaults.fetchall - or self.rewrite != UserDefaults.rewrite - or self.forcecr != UserDefaults.forcecr - or self.stripcr != UserDefaults.stripcr - or self.pass8bits != UserDefaults.pass8bits - or self.mimedecode != UserDefaults.mimedecode - or self.dropstatus != UserDefaults.dropstatus - or self.dropdelivered != UserDefaults.dropdelivered - or self.idle != UserDefaults.idle): - res = res + " options" - if self.keep != UserDefaults.keep: - res = res + flag2str(self.keep, 'keep') - if self.flush != UserDefaults.flush: - res = res + flag2str(self.flush, 'flush') - if self.limitflush != UserDefaults.limitflush: - res = res + flag2str(self.limitflush, 'limitflush') - if self.fetchall != UserDefaults.fetchall: - res = res + flag2str(self.fetchall, 'fetchall') - if self.rewrite != UserDefaults.rewrite: - res = res + flag2str(self.rewrite, 'rewrite') - if self.forcecr != UserDefaults.forcecr: - res = res + flag2str(self.forcecr, 'forcecr') - if self.stripcr != UserDefaults.stripcr: - res = res + flag2str(self.stripcr, 'stripcr') - if self.pass8bits != UserDefaults.pass8bits: - res = res + flag2str(self.pass8bits, 'pass8bits') - if self.mimedecode != UserDefaults.mimedecode: - res = res + flag2str(self.mimedecode, 'mimedecode') - if self.dropstatus != UserDefaults.dropstatus: - res = res + flag2str(self.dropstatus, 'dropstatus') - if self.dropdelivered != UserDefaults.dropdelivered: - res = res + flag2str(self.dropdelivered, 'dropdelivered') - if self.idle != UserDefaults.idle: - res = res + flag2str(self.idle, 'idle') - if self.limit != UserDefaults.limit: - res = res + " limit " + `self.limit` - if self.warnings != UserDefaults.warnings: - res = res + " warnings " + `self.warnings` - if self.fetchlimit != UserDefaults.fetchlimit: - res = res + " fetchlimit " + `self.fetchlimit` - if self.fetchsizelimit != UserDefaults.fetchsizelimit: - res = res + " fetchsizelimit " + `self.fetchsizelimit` - if self.fastuidl != UserDefaults.fastuidl: - res = res + " fastuidl " + `self.fastuidl` - if self.batchlimit != UserDefaults.batchlimit: - res = res + " batchlimit " + `self.batchlimit` - if self.ssl and self.ssl != UserDefaults.ssl: - res = res + flag2str(self.ssl, 'ssl') - if self.sslkey and self.sslkey != UserDefaults.sslkey: - res = res + " sslkey " + `self.sslkey` - if self.sslcert and self.sslcert != UserDefaults.sslcert: - res = res + " sslcert " + `self.sslcert` - if self.sslproto and self.sslproto != UserDefaults.sslproto: - res = res + " sslproto " + `self.sslproto` - if self.sslcertck and self.sslcertck != UserDefaults.sslcertck: - res = res + flag2str(self.sslcertck, 'sslcertck') - if self.sslcertpath and self.sslcertpath != UserDefaults.sslcertpath: - res = res + " sslcertpath " + `self.sslcertpath` - if self.sslcommonname and self.sslcommonname != UserDefaults.sslcommonname: - res = res + " sslcommonname " + `self.sslcommonname` - if self.sslfingerprint and self.sslfingerprint != UserDefaults.sslfingerprint: - res = res + " sslfingerprint " + `self.sslfingerprint` - if self.expunge != UserDefaults.expunge: - res = res + " expunge " + `self.expunge` - res = res + "\n" - trimmed = self.smtphunt; - if trimmed != [] and trimmed[len(trimmed) - 1] == "localhost": - trimmed = trimmed[0:len(trimmed) - 1] - if trimmed != [] and trimmed[len(trimmed) - 1] == hostname: - trimmed = trimmed[0:len(trimmed) - 1] - if trimmed != []: - res = res + " smtphost " - for x in trimmed: - res = res + " " + x - res = res + "\n" - trimmed = self.fetchdomains - if trimmed != [] and trimmed[len(trimmed) - 1] == hostname: - trimmed = trimmed[0:len(trimmed) - 1] - if trimmed != []: - res = res + " fetchdomains " - for x in trimmed: - res = res + " " + x - res = res + "\n" - if self.mailboxes: - res = res + " folder" - for x in self.mailboxes: - res = res + ' "%s"' % x - res = res + "\n" - for fld in ('smtpaddress', 'preconnect', 'postconnect', 'mda', 'bsmtp', 'properties'): - if getattr(self, fld): - res = res + " %s %s\n" % (fld, `getattr(self, fld)`) - if self.lmtp != UserDefaults.lmtp: - res = res + flag2str(self.lmtp, 'lmtp') - if self.antispam != UserDefaults.antispam: - res = res + " antispam " + self.antispam + "\n" - return res; + res = " " + res = res + "user " + `self.remote` + " there "; + if self.password: + res = res + "with password " + `self.password` + " " + if self.localnames: + res = res + "is" + for x in self.localnames: + res = res + " " + `x` + res = res + " here" + if (self.keep != UserDefaults.keep + or self.flush != UserDefaults.flush + or self.limitflush != UserDefaults.limitflush + or self.fetchall != UserDefaults.fetchall + or self.rewrite != UserDefaults.rewrite + or self.forcecr != UserDefaults.forcecr + or self.stripcr != UserDefaults.stripcr + or self.pass8bits != UserDefaults.pass8bits + or self.mimedecode != UserDefaults.mimedecode + or self.dropstatus != UserDefaults.dropstatus + or self.dropdelivered != UserDefaults.dropdelivered + or self.idle != UserDefaults.idle): + res = res + " options" + if self.keep != UserDefaults.keep: + res = res + flag2str(self.keep, 'keep') + if self.flush != UserDefaults.flush: + res = res + flag2str(self.flush, 'flush') + if self.limitflush != UserDefaults.limitflush: + res = res + flag2str(self.limitflush, 'limitflush') + if self.fetchall != UserDefaults.fetchall: + res = res + flag2str(self.fetchall, 'fetchall') + if self.rewrite != UserDefaults.rewrite: + res = res + flag2str(self.rewrite, 'rewrite') + if self.forcecr != UserDefaults.forcecr: + res = res + flag2str(self.forcecr, 'forcecr') + if self.stripcr != UserDefaults.stripcr: + res = res + flag2str(self.stripcr, 'stripcr') + if self.pass8bits != UserDefaults.pass8bits: + res = res + flag2str(self.pass8bits, 'pass8bits') + if self.mimedecode != UserDefaults.mimedecode: + res = res + flag2str(self.mimedecode, 'mimedecode') + if self.dropstatus != UserDefaults.dropstatus: + res = res + flag2str(self.dropstatus, 'dropstatus') + if self.dropdelivered != UserDefaults.dropdelivered: + res = res + flag2str(self.dropdelivered, 'dropdelivered') + if self.idle != UserDefaults.idle: + res = res + flag2str(self.idle, 'idle') + if self.limit != UserDefaults.limit: + res = res + " limit " + `self.limit` + if self.warnings != UserDefaults.warnings: + res = res + " warnings " + `self.warnings` + if self.fetchlimit != UserDefaults.fetchlimit: + res = res + " fetchlimit " + `self.fetchlimit` + if self.fetchsizelimit != UserDefaults.fetchsizelimit: + res = res + " fetchsizelimit " + `self.fetchsizelimit` + if self.fastuidl != UserDefaults.fastuidl: + res = res + " fastuidl " + `self.fastuidl` + if self.batchlimit != UserDefaults.batchlimit: + res = res + " batchlimit " + `self.batchlimit` + if self.ssl and self.ssl != UserDefaults.ssl: + res = res + flag2str(self.ssl, 'ssl') + if self.sslkey and self.sslkey != UserDefaults.sslkey: + res = res + " sslkey " + `self.sslkey` + if self.sslcert and self.sslcert != UserDefaults.sslcert: + res = res + " sslcert " + `self.sslcert` + if self.sslproto and self.sslproto != UserDefaults.sslproto: + res = res + " sslproto " + `self.sslproto` + if self.sslcertck and self.sslcertck != UserDefaults.sslcertck: + res = res + flag2str(self.sslcertck, 'sslcertck') + if self.sslcertpath and self.sslcertpath != UserDefaults.sslcertpath: + res = res + " sslcertpath " + `self.sslcertpath` + if self.sslcommonname and self.sslcommonname != UserDefaults.sslcommonname: + res = res + " sslcommonname " + `self.sslcommonname` + if self.sslfingerprint and self.sslfingerprint != UserDefaults.sslfingerprint: + res = res + " sslfingerprint " + `self.sslfingerprint` + if self.expunge != UserDefaults.expunge: + res = res + " expunge " + `self.expunge` + res = res + "\n" + trimmed = self.smtphunt; + if trimmed != [] and trimmed[len(trimmed) - 1] == "localhost": + trimmed = trimmed[0:len(trimmed) - 1] + if trimmed != [] and trimmed[len(trimmed) - 1] == hostname: + trimmed = trimmed[0:len(trimmed) - 1] + if trimmed != []: + res = res + " smtphost " + for x in trimmed: + res = res + " " + x + res = res + "\n" + trimmed = self.fetchdomains + if trimmed != [] and trimmed[len(trimmed) - 1] == hostname: + trimmed = trimmed[0:len(trimmed) - 1] + if trimmed != []: + res = res + " fetchdomains " + for x in trimmed: + res = res + " " + x + res = res + "\n" + if self.mailboxes: + res = res + " folder" + for x in self.mailboxes: + res = res + ' "%s"' % x + res = res + "\n" + for fld in ('smtpaddress', 'preconnect', 'postconnect', 'mda', 'bsmtp', 'properties'): + if getattr(self, fld): + res = res + " %s %s\n" % (fld, `getattr(self, fld)`) + if self.lmtp != UserDefaults.lmtp: + res = res + flag2str(self.lmtp, 'lmtp') + if self.antispam != UserDefaults.antispam: + res = res + " antispam " + self.antispam + "\n" + return res; def __str__(self): - return "[User: " + repr(self) + "]" + return "[User: " + repr(self) + "]" # # Helper code @@ -433,24 +433,24 @@ class User: # IANA port assignments and bogus 1109 entry ianaservices = {"pop2":109, - "pop3":110, - "1109":1109, - "imap":143, - "smtp":25, - "odmr":366} + "pop3":110, + "1109":1109, + "imap":143, + "smtp":25, + "odmr":366} # fetchmail protocol to IANA service name defaultports = {"auto":None, - "POP2":"pop2", - "POP3":"pop3", - "APOP":"pop3", - "KPOP":"1109", - "IMAP":"imap", - "ETRN":"smtp", - "ODMR":"odmr"} + "POP2":"pop2", + "POP3":"pop3", + "APOP":"pop3", + "KPOP":"1109", + "IMAP":"imap", + "ETRN":"smtp", + "ODMR":"odmr"} authlist = ("any", "password", "gssapi", "kerberos", "ssh", "otp", - "msn", "ntlm") + "msn", "ntlm") listboxhelp = { 'title' : 'List Selection Help', @@ -463,23 +463,23 @@ def flag2str(value, string): # make a string representation of a .fetchmailrc flag or negated flag str = "" if value != None: - str = str + (" ") - if value == FALSE: str = str + ("no ") - str = str + string; + str = str + (" ") + if value == FALSE: str = str + ("no ") + str = str + string; return str class LabeledEntry(Frame): # widget consisting of entry field with caption to left def bind(self, key, action): - self.E.bind(key, action) + self.E.bind(key, action) def focus_set(self): - self.E.focus_set() + self.E.focus_set() def __init__(self, Master, text, textvar, lwidth, ewidth=12): - Frame.__init__(self, Master) - self.L = Label(self, {'text':text, 'width':lwidth, 'anchor':'w'}) - self.E = Entry(self, {'textvar':textvar, 'width':ewidth}) - self.L.pack({'side':'left'}) - self.E.pack({'side':'left', 'expand':'1', 'fill':'x'}) + Frame.__init__(self, Master) + self.L = Label(self, {'text':text, 'width':lwidth, 'anchor':'w'}) + self.E = Entry(self, {'textvar':textvar, 'width':ewidth}) + self.L.pack({'side':'left'}) + self.E.pack({'side':'left', 'expand':'1', 'fill':'x'}) def ButtonBar(frame, legend, ref, alternatives, depth, command): # array of radio buttons, caption to left, picking from a string list @@ -487,20 +487,20 @@ def ButtonBar(frame, legend, ref, alternatives, depth, command): width = (len(alternatives)+1) / depth; Label(bar, text=legend).pack(side=LEFT) for column in range(width): - subframe = Frame(bar) - for row in range(depth): - ind = width * row + column - if ind < len(alternatives): - Radiobutton(subframe, - {'text':alternatives[ind], - 'variable':ref, - 'value':alternatives[ind], - 'command':command}).pack(side=TOP, anchor=W) - else: - # This is just a spacer - Radiobutton(subframe, - {'text':" ",'state':DISABLED}).pack(side=TOP, anchor=W) - subframe.pack(side=LEFT) + subframe = Frame(bar) + for row in range(depth): + ind = width * row + column + if ind < len(alternatives): + Radiobutton(subframe, + {'text':alternatives[ind], + 'variable':ref, + 'value':alternatives[ind], + 'command':command}).pack(side=TOP, anchor=W) + else: + # This is just a spacer + Radiobutton(subframe, + {'text':" ",'state':DISABLED}).pack(side=TOP, anchor=W) + subframe.pack(side=LEFT) bar.pack(side=TOP); return bar @@ -520,142 +520,142 @@ def helpwin(helpdict): scroll.pack(side=RIGHT, fill=BOTH) helpwin.textwidget.insert(END, helpdict['text']); Button(helpwin, text='Done', - command=lambda x=helpwin: x.destroy(), bd=2).pack() + command=lambda x=helpwin: x.destroy(), bd=2).pack() textframe.pack(side=TOP) def make_icon_window(base, image): try: - # Some older pythons will error out on this - icon_image = PhotoImage(data=image) - icon_window = Toplevel() - Label(icon_window, image=icon_image, bg='black').pack() - base.master.iconwindow(icon_window) - # Avoid TkInter brain death. PhotoImage objects go out of - # scope when the enclosing function returns. Therefore - # we have to explicitly link them to something. - base.keepalive.append(icon_image) + # Some older pythons will error out on this + icon_image = PhotoImage(data=image) + icon_window = Toplevel() + Label(icon_window, image=icon_image, bg='black').pack() + base.master.iconwindow(icon_window) + # Avoid TkInter brain death. PhotoImage objects go out of + # scope when the enclosing function returns. Therefore + # we have to explicitly link them to something. + base.keepalive.append(icon_image) except: - pass + pass class ListEdit(Frame): # edit a list of values (duplicates not allowed) with a supplied editor hook def __init__(self, newlegend, list, editor, deletor, master, helptxt): - self.editor = editor - self.deletor = deletor - self.list = list - - # Set up a widget to accept new elements - self.newval = StringVar(master) - newwin = LabeledEntry(master, newlegend, self.newval, '12') - newwin.bind('<Double-1>', self.handleNew) - newwin.bind('<Return>', self.handleNew) - newwin.pack(side=TOP, fill=X, anchor=E) - - # Edit the existing list - listframe = Frame(master) - scroll = Scrollbar(listframe) - self.listwidget = Listbox(listframe, height=0, selectmode='browse') - if self.list: - for x in self.list: - self.listwidget.insert(END, x) - listframe.pack(side=TOP, expand=YES, fill=BOTH) - self.listwidget.config(yscrollcommand=scroll.set) - self.listwidget.pack(side=LEFT, expand=YES, fill=BOTH) - scroll.config(command=self.listwidget.yview) - scroll.pack(side=RIGHT, fill=BOTH) - self.listwidget.config(selectmode=SINGLE, setgrid=TRUE) - self.listwidget.bind('<Double-1>', self.handleList); - self.listwidget.bind('<Return>', self.handleList); - - bf = Frame(master); - if self.editor: - Button(bf, text='Edit', command=self.editItem).pack(side=LEFT) - Button(bf, text='Delete', command=self.deleteItem).pack(side=LEFT) - if helptxt: - self.helptxt = helptxt - Button(bf, text='Help', fg='blue', - command=self.help).pack(side=RIGHT) - bf.pack(fill=X) + self.editor = editor + self.deletor = deletor + self.list = list + + # Set up a widget to accept new elements + self.newval = StringVar(master) + newwin = LabeledEntry(master, newlegend, self.newval, '12') + newwin.bind('<Double-1>', self.handleNew) + newwin.bind('<Return>', self.handleNew) + newwin.pack(side=TOP, fill=X, anchor=E) + + # Edit the existing list + listframe = Frame(master) + scroll = Scrollbar(listframe) + self.listwidget = Listbox(listframe, height=0, selectmode='browse') + if self.list: + for x in self.list: + self.listwidget.insert(END, x) + listframe.pack(side=TOP, expand=YES, fill=BOTH) + self.listwidget.config(yscrollcommand=scroll.set) + self.listwidget.pack(side=LEFT, expand=YES, fill=BOTH) + scroll.config(command=self.listwidget.yview) + scroll.pack(side=RIGHT, fill=BOTH) + self.listwidget.config(selectmode=SINGLE, setgrid=TRUE) + self.listwidget.bind('<Double-1>', self.handleList); + self.listwidget.bind('<Return>', self.handleList); + + bf = Frame(master); + if self.editor: + Button(bf, text='Edit', command=self.editItem).pack(side=LEFT) + Button(bf, text='Delete', command=self.deleteItem).pack(side=LEFT) + if helptxt: + self.helptxt = helptxt + Button(bf, text='Help', fg='blue', + command=self.help).pack(side=RIGHT) + bf.pack(fill=X) def help(self): - helpwin(self.helptxt) + helpwin(self.helptxt) def handleList(self, event): - self.editItem(); + self.editItem(); def handleNew(self, event): - item = self.newval.get() - if item: - entire = self.listwidget.get(0, self.listwidget.index('end')); - if item and (not entire) or (not item in self.listwidget.get(0, self.listwidget.index('end'))): - self.listwidget.insert('end', item) - if self.list != None: self.list.append(item) - if self.editor: - apply(self.editor, (item,)) - self.newval.set('') + item = self.newval.get() + if item: + entire = self.listwidget.get(0, self.listwidget.index('end')); + if item and (not entire) or (not item in self.listwidget.get(0, self.listwidget.index('end'))): + self.listwidget.insert('end', item) + if self.list != None: self.list.append(item) + if self.editor: + apply(self.editor, (item,)) + self.newval.set('') def editItem(self): - select = self.listwidget.curselection() - if not select: - helpwin(listboxhelp) - else: - index = select[0] - if index and self.editor: - label = self.listwidget.get(index); - if self.editor: - apply(self.editor, (label,)) + select = self.listwidget.curselection() + if not select: + helpwin(listboxhelp) + else: + index = select[0] + if index and self.editor: + label = self.listwidget.get(index); + if self.editor: + apply(self.editor, (label,)) def deleteItem(self): - select = self.listwidget.curselection() - if not select: - helpwin(listboxhelp) - else: - index = string.atoi(select[0]) - label = self.listwidget.get(index); - self.listwidget.delete(index) - if self.list != None: - del self.list[index] - if self.deletor != None: - apply(self.deletor, (label,)) + select = self.listwidget.curselection() + if not select: + helpwin(listboxhelp) + else: + index = string.atoi(select[0]) + label = self.listwidget.get(index); + self.listwidget.delete(index) + if self.list != None: + del self.list[index] + if self.deletor != None: + apply(self.deletor, (label,)) def ConfirmQuit(frame, context): ans = Dialog(frame, - title = 'Quit?', - text = 'Really quit ' + context + ' without saving?', - bitmap = 'question', - strings = ('Yes', 'No'), - default = 1) + title = 'Quit?', + text = 'Really quit ' + context + ' without saving?', + bitmap = 'question', + strings = ('Yes', 'No'), + default = 1) return ans.num == 0 def dispose_window(master, legend, help, savelegend='OK'): dispose = Frame(master, relief=RAISED, bd=5) Label(dispose, text=legend).pack(side=TOP,pady=10) Button(dispose, text=savelegend, fg='blue', - command=master.save).pack(side=LEFT) + command=master.save).pack(side=LEFT) Button(dispose, text='Quit', fg='blue', - command=master.nosave).pack(side=LEFT) + command=master.nosave).pack(side=LEFT) Button(dispose, text='Help', fg='blue', - command=lambda x=help: helpwin(x)).pack(side=RIGHT) + command=lambda x=help: helpwin(x)).pack(side=RIGHT) dispose.pack(fill=X) return dispose class MyWidget: # Common methods for Tkinter widgets -- deals with Tkinter declaration def post(self, widgetclass, field): - for x in widgetclass.typemap: - if x[1] == 'Boolean': - setattr(self, x[0], BooleanVar(self)) - elif x[1] == 'String': - setattr(self, x[0], StringVar(self)) - elif x[1] == 'Int': - setattr(self, x[0], IntVar(self)) - source = getattr(getattr(self, field), x[0]) - if source: - getattr(self, x[0]).set(source) + for x in widgetclass.typemap: + if x[1] == 'Boolean': + setattr(self, x[0], BooleanVar(self)) + elif x[1] == 'String': + setattr(self, x[0], StringVar(self)) + elif x[1] == 'Int': + setattr(self, x[0], IntVar(self)) + source = getattr(getattr(self, field), x[0]) + if source: + getattr(self, x[0]).set(source) def fetch(self, widgetclass, field): - for x in widgetclass.typemap: - setattr(getattr(self, field), x[0], getattr(self, x[0]).get()) + for x in widgetclass.typemap: + setattr(getattr(self, field), x[0], getattr(self, x[0]).get()) # # First, code to set the global fetchmail run controls. @@ -708,46 +708,46 @@ In the `Run Controls' panel, you can set the following options that control how fetchmail runs: Poll interval - Number of seconds to wait between polls in the background. - If zero, fetchmail will run in foreground. + Number of seconds to wait between polls in the background. + If zero, fetchmail will run in foreground. Logfile - If empty, emit progress and error messages to stderr. - Otherwise this gives the name of the files to write to. - This field is ignored if the "Log to syslog?" option is on. + If empty, emit progress and error messages to stderr. + Otherwise this gives the name of the files to write to. + This field is ignored if the "Log to syslog?" option is on. Idfile - If empty, store seen-message IDs in .fetchids under user's home - directory. If nonempty, use given file name. + If empty, store seen-message IDs in .fetchids under user's home + directory. If nonempty, use given file name. Postmaster - Who to send multidrop mail to as a last resort if no address can - be matched. Normally empty; in this case, fetchmail treats the - invoking user as the address of last resort unless that user is - root. If that user is root, fetchmail sends to `postmaster'. + Who to send multidrop mail to as a last resort if no address can + be matched. Normally empty; in this case, fetchmail treats the + invoking user as the address of last resort unless that user is + root. If that user is root, fetchmail sends to `postmaster'. Bounces to sender? - If this option is on (the default) error mail goes to the sender. - Otherwise it goes to the postmaster. + If this option is on (the default) error mail goes to the sender. + Otherwise it goes to the postmaster. Send spam bounces? - If this option is on, spam bounces are sent to the sender or - postmaster (depending on the "Bounces to sender?" option. Otherwise, - spam bounces are not sent (the default). + If this option is on, spam bounces are sent to the sender or + postmaster (depending on the "Bounces to sender?" option. Otherwise, + spam bounces are not sent (the default). Use soft bounces? - If this option is on, permanent delivery errors are treated as - temporary, i. e. mail is kept on the upstream server. Useful - during testing and after configuration changes, and on by - default. - If this option is off, permanent delivery errors delete - undeliverable mail from the upstream. + If this option is on, permanent delivery errors are treated as + temporary, i. e. mail is kept on the upstream server. Useful + during testing and after configuration changes, and on by + default. + If this option is off, permanent delivery errors delete + undeliverable mail from the upstream. Invisible - If false (the default) fetchmail generates a Received line into - each message and generates a HELO from the machine it is running on. - If true, fetchmail generates no Received line and HELOs as if it were - the remote site. + If false (the default) fetchmail generates a Received line into + each message and generates a HELO from the machine it is running on. + If true, fetchmail generates no Received line and HELOs as if it were + the remote site. In the `Remote Mail Configurations' panel, you can: @@ -767,155 +767,155 @@ This will take you to a site configuration dialogue. class ConfigurationEdit(Frame, MyWidget): def __init__(self, configuration, outfile, master, onexit): - self.subwidgets = {} - self.configuration = configuration - self.outfile = outfile - self.container = master - self.onexit = onexit - ConfigurationEdit.mode_to_help = { - 'novice':configure_novice_help, 'expert':configure_expert_help - } + self.subwidgets = {} + self.configuration = configuration + self.outfile = outfile + self.container = master + self.onexit = onexit + ConfigurationEdit.mode_to_help = { + 'novice':configure_novice_help, 'expert':configure_expert_help + } def server_edit(self, sitename): - self.subwidgets[sitename] = ServerEdit(sitename, self).edit(self.mode, Toplevel()) + self.subwidgets[sitename] = ServerEdit(sitename, self).edit(self.mode, Toplevel()) def server_delete(self, sitename): - try: - for user in self.subwidgets.keys(): - user.destruct() - del self.configuration[sitename] - except: - pass + try: + for user in self.subwidgets.keys(): + user.destruct() + del self.configuration[sitename] + except: + pass def edit(self, mode): - self.mode = mode - Frame.__init__(self, self.container) - self.master.title('fetchmail ' + self.mode + ' configurator'); - self.master.iconname('fetchmail ' + self.mode + ' configurator'); - self.master.protocol('WM_DELETE_WINDOW', self.nosave) - self.keepalive = [] # Use this to anchor the PhotoImage object - make_icon_window(self, fetchmail_icon) - Pack.config(self) - self.post(Configuration, 'configuration') - - dispose_window(self, - 'Configurator ' + self.mode + ' Controls', - ConfigurationEdit.mode_to_help[self.mode], - 'Save') - - gf = Frame(self, relief=RAISED, bd = 5) - Label(gf, - text='Fetchmail Run Controls', - bd=2).pack(side=TOP, pady=10) - - df = Frame(gf) - - ff = Frame(df) - if self.mode != 'novice': - # Set the postmaster - log = LabeledEntry(ff, ' Postmaster:', self.postmaster, '14') - log.pack(side=RIGHT, anchor=E) - - # Set the poll interval - de = LabeledEntry(ff, ' Poll interval:', self.poll_interval, '14') - de.pack(side=RIGHT, anchor=E) - ff.pack() - - df.pack() - - if self.mode != 'novice': - pf = Frame(gf) - Checkbutton(pf, - {'text':'Bounces to sender?', - 'variable':self.bouncemail, - 'relief':GROOVE}).pack(side=LEFT, anchor=W) - pf.pack(fill=X) - - sb = Frame(gf) - Checkbutton(sb, - {'text':'Send spam bounces?', - 'variable':self.spambounce, - 'relief':GROOVE}).pack(side=LEFT, anchor=W) - sb.pack(fill=X) - - sb = Frame(gf) - Checkbutton(sb, - {'text':'Treat permanent errors as temporary?', - 'variable':self.softbounce, - 'relief':GROOVE}).pack(side=LEFT, anchor=W) - sb.pack(fill=X) - - sf = Frame(gf) - Checkbutton(sf, - {'text':'Log to syslog?', - 'variable':self.syslog, - 'relief':GROOVE}).pack(side=LEFT, anchor=W) - log = LabeledEntry(sf, ' Logfile:', self.logfile, '14') - log.pack(side=RIGHT, anchor=E) - sf.pack(fill=X) - - Checkbutton(gf, - {'text':'Invisible mode?', - 'variable':self.invisible, - 'relief':GROOVE}).pack(side=LEFT, anchor=W) - # Set the idfile - log = LabeledEntry(gf, ' Idfile:', self.idfile, '14') - log.pack(side=RIGHT, anchor=E) - - gf.pack(fill=X) - - # Expert mode allows us to edit multiple sites - lf = Frame(self, relief=RAISED, bd=5) - Label(lf, - text='Remote Mail Server Configurations', - bd=2).pack(side=TOP, pady=10) - ListEdit('New Server:', - map(lambda x: x.pollname, self.configuration.servers), - lambda site, self=self: self.server_edit(site), - lambda site, self=self: self.server_delete(site), - lf, remotehelp) - lf.pack(fill=X) + self.mode = mode + Frame.__init__(self, self.container) + self.master.title('fetchmail ' + self.mode + ' configurator'); + self.master.iconname('fetchmail ' + self.mode + ' configurator'); + self.master.protocol('WM_DELETE_WINDOW', self.nosave) + self.keepalive = [] # Use this to anchor the PhotoImage object + make_icon_window(self, fetchmail_icon) + Pack.config(self) + self.post(Configuration, 'configuration') + + dispose_window(self, + 'Configurator ' + self.mode + ' Controls', + ConfigurationEdit.mode_to_help[self.mode], + 'Save') + + gf = Frame(self, relief=RAISED, bd = 5) + Label(gf, + text='Fetchmail Run Controls', + bd=2).pack(side=TOP, pady=10) + + df = Frame(gf) + + ff = Frame(df) + if self.mode != 'novice': + # Set the postmaster + log = LabeledEntry(ff, ' Postmaster:', self.postmaster, '14') + log.pack(side=RIGHT, anchor=E) + + # Set the poll interval + de = LabeledEntry(ff, ' Poll interval:', self.poll_interval, '14') + de.pack(side=RIGHT, anchor=E) + ff.pack() + + df.pack() + + if self.mode != 'novice': + pf = Frame(gf) + Checkbutton(pf, + {'text':'Bounces to sender?', + 'variable':self.bouncemail, + 'relief':GROOVE}).pack(side=LEFT, anchor=W) + pf.pack(fill=X) + + sb = Frame(gf) + Checkbutton(sb, + {'text':'Send spam bounces?', + 'variable':self.spambounce, + 'relief':GROOVE}).pack(side=LEFT, anchor=W) + sb.pack(fill=X) + + sb = Frame(gf) + Checkbutton(sb, + {'text':'Treat permanent errors as temporary?', + 'variable':self.softbounce, + 'relief':GROOVE}).pack(side=LEFT, anchor=W) + sb.pack(fill=X) + + sf = Frame(gf) + Checkbutton(sf, + {'text':'Log to syslog?', + 'variable':self.syslog, + 'relief':GROOVE}).pack(side=LEFT, anchor=W) + log = LabeledEntry(sf, ' Logfile:', self.logfile, '14') + log.pack(side=RIGHT, anchor=E) + sf.pack(fill=X) + + Checkbutton(gf, + {'text':'Invisible mode?', + 'variable':self.invisible, + 'relief':GROOVE}).pack(side=LEFT, anchor=W) + # Set the idfile + log = LabeledEntry(gf, ' Idfile:', self.idfile, '14') + log.pack(side=RIGHT, anchor=E) + + gf.pack(fill=X) + + # Expert mode allows us to edit multiple sites + lf = Frame(self, relief=RAISED, bd=5) + Label(lf, + text='Remote Mail Server Configurations', + bd=2).pack(side=TOP, pady=10) + ListEdit('New Server:', + map(lambda x: x.pollname, self.configuration.servers), + lambda site, self=self: self.server_edit(site), + lambda site, self=self: self.server_delete(site), + lf, remotehelp) + lf.pack(fill=X) def destruct(self): - for sitename in self.subwidgets.keys(): - self.subwidgets[sitename].destruct() - self.master.destroy() - self.onexit() + for sitename in self.subwidgets.keys(): + self.subwidgets[sitename].destruct() + self.master.destroy() + self.onexit() def nosave(self): - if ConfirmQuit(self, self.mode + " configuration editor"): - self.destruct() + if ConfirmQuit(self, self.mode + " configuration editor"): + self.destruct() def save(self): - for sitename in self.subwidgets.keys(): - self.subwidgets[sitename].save() - self.fetch(Configuration, 'configuration') - fm = None - if not self.outfile: - fm = sys.stdout - elif not os.path.isfile(self.outfile) or Dialog(self, - title = 'Overwrite existing run control file?', - text = 'Really overwrite existing run control file?', - bitmap = 'question', - strings = ('Yes', 'No'), - default = 1).num == 0: - try: - os.rename(self.outfile, self.outfile + "~") - # Pre-1.5.2 compatibility... - except os.error: - pass - oldumask = os.umask(077) - fm = open(self.outfile, 'w') - os.umask(oldumask) - if fm: - # be paranoid - if fm != sys.stdout: - os.chmod(self.outfile, 0600) - fm.write("# Configuration created %s by fetchmailconf %s\n" % (time.ctime(time.time()), version)) - fm.write(`self.configuration`) - if self.outfile: - fm.close() - self.destruct() + for sitename in self.subwidgets.keys(): + self.subwidgets[sitename].save() + self.fetch(Configuration, 'configuration') + fm = None + if not self.outfile: + fm = sys.stdout + elif not os.path.isfile(self.outfile) or Dialog(self, + title = 'Overwrite existing run control file?', + text = 'Really overwrite existing run control file?', + bitmap = 'question', + strings = ('Yes', 'No'), + default = 1).num == 0: + try: + os.rename(self.outfile, self.outfile + "~") + # Pre-1.5.2 compatibility... + except os.error: + pass + oldumask = os.umask(077) + fm = open(self.outfile, 'w') + os.umask(oldumask) + if fm: + # be paranoid + if fm != sys.stdout: + os.chmod(self.outfile, 0600) + fm.write("# Configuration created %s by fetchmailconf %s\n" % (time.ctime(time.time()), version)) + fm.write(`self.configuration`) + if self.outfile: + fm.close() + ... [truncated message content] |
From: Samuel M. <s.m...@gm...> - 2016-06-08 19:36:47
|
This change does: - use repr(...) instead of `...` (see [1]); - fix print call; - fix octal numbers. [1] https://docs.python.org/release/3.0.1/whatsnew/3.0.html#removed-syntax Signed-off-by: Samuel Martin <s.m...@gm...> --- fetchmailconf.py | 94 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 48 insertions(+), 46 deletions(-) diff --git a/fetchmailconf.py b/fetchmailconf.py index d64556e..697e4f7 100755 --- a/fetchmailconf.py +++ b/fetchmailconf.py @@ -5,6 +5,8 @@ # Matthias Andree <mat...@gm...> # Requires Python with Tkinter, and the following OS-dependent services: # posix, posixpath, socket +from __future__ import print_function + version = "1.57" from Tkinter import * @@ -64,7 +66,7 @@ class Configuration: if self.properties != ConfigurationDefaults.properties: str = str + ("set properties \"%s\"\n" % (self.properties,)); if self.poll_interval > 0: - str = str + "set daemon " + `self.poll_interval` + "\n" + str = str + "set daemon " + repr(self.poll_interval) + "\n" if self.invisible: str = str + ("set invisible\n") for site in self.servers: @@ -145,12 +147,12 @@ class Server: if self.service and self.protocol and self.service != defaultports[self.protocol] and defaultports[self.protocol] and self.service != ianaservices[defaultports[self.protocol]]: res = res + " service " + self.service if self.timeout != ServerDefaults.timeout: - res = res + " timeout " + `self.timeout` + res = res + " timeout " + repr(self.timeout) if self.interval != ServerDefaults.interval: - res = res + " interval " + `self.interval` + res = res + " interval " + repr(self.interval) if self.envelope != ServerDefaults.envelope or self.envskip != ServerDefaults.envskip: if self.envskip: - res = res + " envelope " + `self.envskip` + " " + self.envelope + res = res + " envelope " + repr(self.envskip) + " " + self.envelope else: res = res + " envelope " + self.envelope if self.qvirtual: @@ -189,15 +191,15 @@ class Server: if self.monitor: res = res + " monitor " + str(self.monitor) if self.plugin: - res = res + " plugin " + `self.plugin` + res = res + " plugin " + repr(self.plugin) if self.plugout: - res = res + " plugout " + `self.plugout` + res = res + " plugout " + repr(self.plugout) if self.principal: - res = res + " principal " + `self.principal` + res = res + " principal " + repr(self.principal) if self.esmtpname: - res = res + " esmtpname " + `self.esmtpname` + res = res + " esmtpname " + repr(self.esmtpname) if self.esmtppassword: - res = res + " esmtppassword " + `self.esmtppassword` + res = res + " esmtppassword " + repr(self.esmtppassword) if self.interface or self.monitor or self.principal or self.plugin or self.plugout: if folded: res = res + "\n" @@ -230,7 +232,7 @@ class User: elif os.environ.has_key("LOGNAME"): self.remote = os.environ["LOGNAME"] else: - print "Can't get your username!" + print("Can't get your username!") sys.exit(1) self.localnames = [self.remote,]# Local names self.password = None # Password for mail account access @@ -316,13 +318,13 @@ class User: def __repr__(self): res = " " - res = res + "user " + `self.remote` + " there "; + res = res + "user " + repr(self.remote) + " there "; if self.password: - res = res + "with password " + `self.password` + " " + res = res + "with password " + repr(self.password) + " " if self.localnames: res = res + "is" for x in self.localnames: - res = res + " " + `x` + res = res + " " + repr(x) res = res + " here" if (self.keep != UserDefaults.keep or self.flush != UserDefaults.flush @@ -362,35 +364,35 @@ class User: if self.idle != UserDefaults.idle: res = res + flag2str(self.idle, 'idle') if self.limit != UserDefaults.limit: - res = res + " limit " + `self.limit` + res = res + " limit " + repr(self.limit) if self.warnings != UserDefaults.warnings: - res = res + " warnings " + `self.warnings` + res = res + " warnings " + repr(self.warnings) if self.fetchlimit != UserDefaults.fetchlimit: - res = res + " fetchlimit " + `self.fetchlimit` + res = res + " fetchlimit " + repr(self.fetchlimit) if self.fetchsizelimit != UserDefaults.fetchsizelimit: - res = res + " fetchsizelimit " + `self.fetchsizelimit` + res = res + " fetchsizelimit " + repr(self.fetchsizelimit) if self.fastuidl != UserDefaults.fastuidl: - res = res + " fastuidl " + `self.fastuidl` + res = res + " fastuidl " + repr(self.fastuidl) if self.batchlimit != UserDefaults.batchlimit: - res = res + " batchlimit " + `self.batchlimit` + res = res + " batchlimit " + repr(self.batchlimit) if self.ssl and self.ssl != UserDefaults.ssl: res = res + flag2str(self.ssl, 'ssl') if self.sslkey and self.sslkey != UserDefaults.sslkey: - res = res + " sslkey " + `self.sslkey` + res = res + " sslkey " + repr(self.sslkey) if self.sslcert and self.sslcert != UserDefaults.sslcert: - res = res + " sslcert " + `self.sslcert` + res = res + " sslcert " + repr(self.sslcert) if self.sslproto and self.sslproto != UserDefaults.sslproto: - res = res + " sslproto " + `self.sslproto` + res = res + " sslproto " + repr(self.sslproto) if self.sslcertck and self.sslcertck != UserDefaults.sslcertck: res = res + flag2str(self.sslcertck, 'sslcertck') if self.sslcertpath and self.sslcertpath != UserDefaults.sslcertpath: - res = res + " sslcertpath " + `self.sslcertpath` + res = res + " sslcertpath " + repr(self.sslcertpath) if self.sslcommonname and self.sslcommonname != UserDefaults.sslcommonname: - res = res + " sslcommonname " + `self.sslcommonname` + res = res + " sslcommonname " + repr(self.sslcommonname) if self.sslfingerprint and self.sslfingerprint != UserDefaults.sslfingerprint: - res = res + " sslfingerprint " + `self.sslfingerprint` + res = res + " sslfingerprint " + repr(self.sslfingerprint) if self.expunge != UserDefaults.expunge: - res = res + " expunge " + `self.expunge` + res = res + " expunge " + repr(self.expunge) res = res + "\n" trimmed = self.smtphunt; if trimmed != [] and trimmed[len(trimmed) - 1] == "localhost": @@ -417,7 +419,7 @@ class User: res = res + "\n" for fld in ('smtpaddress', 'preconnect', 'postconnect', 'mda', 'bsmtp', 'properties'): if getattr(self, fld): - res = res + " %s %s\n" % (fld, `getattr(self, fld)`) + res = res + " %s %s\n" % (fld, repr(getattr(self, fld))) if self.lmtp != UserDefaults.lmtp: res = res + flag2str(self.lmtp, 'lmtp') if self.antispam != UserDefaults.antispam: @@ -904,15 +906,15 @@ class ConfigurationEdit(Frame, MyWidget): # Pre-1.5.2 compatibility... except os.error: pass - oldumask = os.umask(077) + oldumask = os.umask(0o77) fm = open(self.outfile, 'w') os.umask(oldumask) if fm: # be paranoid if fm != sys.stdout: - os.chmod(self.outfile, 0600) + os.chmod(self.outfile, 0o600) fm.write("# Configuration created %s by fetchmailconf %s\n" % (time.ctime(time.time()), version)) - fm.write(`self.configuration`) + fm.write(repr(self.configuration)) if self.outfile: fm.close() self.destruct() @@ -1988,15 +1990,15 @@ def copy_instance(toclass, fromdict): if 'typemap' in class_sig: class_sig.remove('typemap') if tuple(class_sig) != tuple(dict_keys): - print "Fields don't match what fetchmailconf expected:" -# print "Class signature: " + `class_sig` -# print "Dictionary keys: " + `dict_keys` + print("Fields don't match what fetchmailconf expected:") +# print("Class signature: " + repr(class_sig)) +# print("Dictionary keys: " + repr(dict_keys)) diff = setdiff(class_sig, common) if diff: - print "Not matched in class `" + toclass.__class__.__name__ + "' signature: " + `diff` + print("Not matched in class `" + toclass.__class__.__name__ + "' signature: " + repr(diff)) diff = setdiff(dict_keys, common) if diff: - print "Not matched in dictionary keys: " + `diff` + print("Not matched in dictionary keys: " + repr(diff)) sys.exit(1) else: for x in fromdict.keys(): @@ -2028,7 +2030,7 @@ def copy_instance(toclass, fromdict): if __name__ == '__main__': if not os.environ.has_key("DISPLAY"): - print "fetchmailconf must be run under X" + print("fetchmailconf must be run under X") sys.exit(1) fetchmail_icon = """ @@ -2068,7 +2070,7 @@ gUSiYASJpMEHhilJTEnhAlGoQqYAZQ1AiqEMZ0jDGtqQImhwwA13yMMevoQAGvGhEAWHGMOAAAA7 # The base64 data in the string above was generated by the following procedure: # # import base64 -# print base64.encodestring(open("fetchmail.gif", "rb").read()) +# print(base64.encodestring(open("fetchmail.gif", "rb").read())) # # Process options @@ -2081,22 +2083,22 @@ gUSiYASJpMEHhilJTEnhAlGoQqYAZQ1AiqEMZ0jDGtqQImhwwA13yMMevoQAGvGhEAWHGMOAAAA7 elif (switch == '-f'): rcfile = val elif (switch == '-h' or switch == '--help'): - print """ + print(""" Usage: fetchmailconf {[-d] [-f fetchmailrc]|-h|--help|-V|--version} -d - dump configuration (for debugging) -f fmrc - read alternate fetchmailrc file --help, -h - print this help text and quit --version, -V - print fetchmailconf version and quit -""" +""") sys.exit(0) elif (switch == '-V' or switch == '--version'): - print "fetchmailconf %s" % version - print """ + print("fetchmailconf %s" % version) + print(""" Copyright (C) 1997 - 2003 Eric S. Raymond Copyright (C) 2005, 2006, 2008, 2009 Matthias Andree fetchmailconf comes with ABSOLUTELY NO WARRANTY. This is free software, you are welcome to redistribute it under certain conditions. Please see the file -COPYING in the source or documentation directory for details.""" +COPYING in the source or documentation directory for details.""") sys.exit(0) # Get client host's FQDN @@ -2119,17 +2121,17 @@ COPYING in the source or documentation directory for details.""" try: s = os.system(cmd) if s != 0: - print "`" + cmd + "' run failure, status " + `s` + print("`" + cmd + "' run failure, status " + repr(s)) raise SystemExit except: - print "Unknown error while running fetchmail --configdump" + print("Unknown error while running fetchmail --configdump") os.remove(tmpfile) sys.exit(1) try: execfile(tmpfile) except: - print "Can't read configuration output of fetchmail --configdump." + print("Can't read configuration output of fetchmail --configdump.") os.remove(tmpfile) sys.exit(1) @@ -2156,7 +2158,7 @@ COPYING in the source or documentation directory for details.""" # We may want to display the configuration and quit if dump: - print "This is a dump of the configuration we read:\n"+`Fetchmailrc` + print("This is a dump of the configuration we read:\n" + repr(Fetchmailrc)) # The theory here is that -f alone sets the rcfile location, # but -d and -f together mean the new configuration should go to stdout. -- 2.8.3 |
From: Samuel M. <s.m...@gm...> - 2016-06-08 19:36:41
|
Hi all, Here is a couple of patchs fixing only python code formating in the fetchmailconf.py file. After this series, fetchmailconf.py is compatible with python-2 and python-3. Regards, Samuel Martin (2): fetchmailconf.py: fix tabs/spaces mixup preventing from compiling the pyc module fetchmailconf.py: make fetchmailconf.py python{2,3}-compliant fetchmailconf.py | 2544 +++++++++++++++++++++++++++--------------------------- 1 file changed, 1273 insertions(+), 1271 deletions(-) -- 2.8.3 |
From: Matthias A. <mat...@gm...> - 2016-04-27 19:56:58
|
Am 27.04.2016 um 21:36 schrieb grarpamp: > On 4/27/16, Vitezslav Crhonek <vcr...@re...> wrote: >> I also removed '-A' option (which required an argument). It seems >> to do nothing at all and didn't find any documentation about it. >> Or is it useful somehow? > > May have been related / intended for...? > > {"auth", required_argument, (int *) 0, LA_AUTH}, Possibly, but I'll rather not use short names for dangerous matters. I checked Eric's last release, 6.2.5, which also appeared to ignore 'A <arg>' if I read the code properly. |
From: Matthias A. <mat...@gm...> - 2016-04-27 19:50:52
|
Am 27.04.2016 um 14:07 schrieb Vitezslav Crhonek: > Hello Matthias, > > I went through usage message/man page and added a few missing option > descriptions, fixed wrong indentation ("The ISP can make the...") > and minor inaccuracy ("bsmtp" option is not associated with '-o'). > > I also removed '-A' option (which required an argument). It seems > to do nothing at all and didn't find any documentation about it. > Or is it useful somehow? > > Patch attached. Feel free to tweak it as you need (e. g. better > wording). > > Best regards, > Vitezslav Crhonek Hi Vitezslav, Thank you. I've applied the patch on the legacy_64 branch, but it does have a different has now because I had to recreate it, "git am" did not take it (missing reference to the tree it was generated from I presume). -A wasn't parsed out as far as I can see, so either it was a typo or some kind of mistake - seems this was silently ignored. Thanks again. Best regards, Matthias |
From: grarpamp <gra...@gm...> - 2016-04-27 19:36:56
|
On 4/27/16, Vitezslav Crhonek <vcr...@re...> wrote: > I also removed '-A' option (which required an argument). It seems > to do nothing at all and didn't find any documentation about it. > Or is it useful somehow? May have been related / intended for...? {"auth", required_argument, (int *) 0, LA_AUTH}, |
From: Vitezslav C. <vcr...@re...> - 2016-04-27 12:07:29
|
Hello Matthias, I went through usage message/man page and added a few missing option descriptions, fixed wrong indentation ("The ISP can make the...") and minor inaccuracy ("bsmtp" option is not associated with '-o'). I also removed '-A' option (which required an argument). It seems to do nothing at all and didn't find any documentation about it. Or is it useful somehow? Patch attached. Feel free to tweak it as you need (e. g. better wording). Best regards, Vitezslav Crhonek |
From: Matthias A. <mat...@gm...> - 2015-04-08 00:02:26
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Git's new legacy_64 branch, as of c3c106ac, now has code to check for this situation and report it as "Server shut down connection prematurely during SSL_connect().", and has other SSL changes and fixes. I need to merge some of the SSL code between legacy_64 and master branches and will then try to do a 6.4.0 beta2 release with updated SSL code shortly. Note that the repository has moved from gitorious.org to https://gitlab.com/groups/fetchmail and the sourceforge.net and my homepage mirrors remain in place and active. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iEYEARECAAYFAlUkcAgACgkQvmGDOQUufZUdYACeNFxS59nuB3V+rbSPwNe/weTf g+MAn30lPPXKT7fB+jTtuHJ+7EonswyB =bV63 -----END PGP SIGNATURE----- |
From: Matthias A. <mat...@gm...> - 2014-10-17 07:50:26
|
Greetings, I have hacked a bit on the SSL/TLS configuration options in the Git repository's master branch (that the 7.0.0-alpha previews get snapshot from). This is a bleeding-edge preview for skilled users who have developer toolchains (recent GNU autoconf/automake/gettext, C99 or C++ compiler, git, openssl) installed and are comfortable with trying out bleeding edge versions and providing technical feedback and can get the usual quirks solved. Note: I will not educate users on how this all works - this is an early preview, we will have formal -alpha snapshots as tarballs later on in the process, once things stabilize a bit and I have addressed some of the FIXME's in code. Contribution welcome, and to be discussed on the fetchmail-devel@ mailing list. I have also made my life easy and now the fetchmail 7.0.0-development branch requires that OpenSSL 1.0.1 be used so that TLS v1.2 is available. Ubuntu 12.04LTS, Fedora 20, FreeBSD 9.3 are fine, Ubuntu 10.04LTS is too old. Changes are: SSL/TLS options are changed in incompatible ways (names changed, semantics changed). They are now more independent of one another. The configuration of the SSL/TLS protocol version no longer implies wrapped versus STARTTLS mode, so you can now combine STARTTLS with SSLv3, or, more importantly, TLSv1 or newer with SSL-wrapped mode. Omitting the sslproto should now do the right thing by default. There is a new --sslmode option to pick the mode. sslcertck is now on by default. SSLv2 is now forbidden altogether, with no way for users to enable it in fetchmail. SSLv3 is now forbidden by default, meaning fetchmail will not automatically negotiate SSLv3, unless the user explicitly forces it with the (revised) --sslprotocolversion SSLv3 option. I should also like to disable TLSv1 and require 1.1+ be used, but that would seem to be premature and lock out too many sites. fetchmail's cipher lists can be configured through an environment variable (for now, meant to become a formal option later on), so for instance, env FETCHMAIL_SSL_CIPHERS='ALL:!EXPORT:!LOW:+RC4:@STRENGTH' \ fetchmail -vv --other --options If you want to tighten this up a bit more and can get away without RC4 and all your upstream servers permit TLSv1.2, you may want to try this instead: env FETCHMAIL_SSL_CIPHERS='ALL:!EXPORT:!LOW:!MEDIUM:@STRENGTH' \ fetchmail -vv --sslprotocolversion TLSv1.2 --other --options For me, half of the sites can no longer be polled with these options (for instance, Microsoft's freemailers no longer work). If this all seems worth the hassle, I have two Git repositories on public sites, you can pick either one to clone from: https://gitorious.org/fetchmail (Norway) http://sourceforge.net/p/fetchmail/git/ci/master/tree/ (USA) Both contain the same data, so pick the one you're more comfortable with. Quickstart to try fetchmail from Git (I do not offer support for this, but I'm happy to receive your feedback, or answer questions that give a strong hint that you are in fact a programmer): - install requisites (you must find the packages out by yourself, I do NOT support this) - git clone from one of the two Git repositories - run: git checkout master # the default checkout goes onto legacy_63 - run: autoreconf -isvf - mkdir build && cd build && ../configure -C && make check - in doubt, make sure you use GNU make for the build (called gmake on some systems) Some of the auto-maintenance in automake output does not work on non-GNU make implementations. The output will then be in build/fetchmail. |
From: Matthias A. <mat...@gm...> - 2014-09-10 06:30:54
|
Am 10.09.2014 um 08:22 schrieb J. Roeleveld: > I have not looked into the code yet, but if I were to provide a patch making > this possible, would you be willing to work with me to get it included? > > One other option I was thinking off would be to move the entire email into the > body of a "new" email and add headers to have it delivered to the user as > such. That should avoid any security issues. Hi Joost, The second proposal seems OK with me, but I would not enable it by default. I am planning to switch off the softbounce feature, so that fetchmail would delete such nondeliverable mail by default, in fetchmail 7. We can discuss integration, code, and thereabouts on the -devel@ mailing list, and I will not add features to the legacy_63 branch - please make sure you work against the master branch, which is currently a 7.0.0-alpha version. Best, Matthias |
From: Matthias A. <mat...@gm...> - 2014-08-31 20:10:40
|
Am 30.08.2014 um 15:59 schrieb Alex DuBois: > I've noticed that over the last several years Microsoft Exchange has > been replacing other corporate email solutions at a steady pace. When > I say that, I'm referring to client access, not the core. That in > itself is not a problem since, as you mentioned, it has built-in IMAP > and POP support. The problem that I've run into is that many IT > departments are refusing to enable IMAP or POP capability. Because of > that, many Exchange users can only access their email accounts with MS > Outlook or Outlook Web Access/App. > > I've tried Davmail, but I think that a native solution built into Mutt > would perform better and would be easier for Mutt users to set up. > > Would adding MAPI support to fetchmail only enable receiving via MAPI, > or would support be added for sending as well? The former - fetchmail purely fetches. However I'm not sure if it even builds these days. If you want to give it a spin, you need to check out from Git, or have me generate a tarball for you. You need OpenChange and its developer stuff installed, along with the usual C compilers and GNU autoconf, automake and gettext, and openssl developer files. If you want to try it, clone from one of the addresses shown in the box at the top of https://gitorious.org/fetchmail/fetchmail/commits/BRANCH_MAPI If you haven't cloned, try git clone --branch BRANCH_MAPI URL-FROM-GITORIOUS LOCAL_DIR (replace the last two strings here!) Then do: autoreconf -i mkdir _build cd _build ../configure -C --enable-MAPI > I am able to test against an Exchange 2010 installation. Let me know what you get; best to do this through the fet...@li... mailing list. The list has an information page at <https://lists.sourceforge.net/lists/listinfo/fetchmail-devel/>. |
From: Matthias A. <mat...@gm...> - 2014-07-02 08:16:48
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Greetings, the previous fetchmail hosting service, berlios.de, has shut down two months ago, and the easily-transferable data have been moved to Sourceforge.net. This includes the web space, downloads, project overview, Git repository, and now the mailing lists. After a long hiatus of nearly two months, the three fetchmail mailing lists are apparently back; I requested an import on May 21st and apparently sourceforge.net just imported them, without closing the support ticket yet. Still I will post now to avoid further confusion. YOU MAY NEED TO CHANGE LIST SETTINGS OR YOUR WORK FLOWS: 1. the list addresses now all end in @lists.sourceforge.net, no longer in @lists.berlios.de. 2. the only settings we could preserve from former lists are whether you were receiving a. plain messages, or b. digests, or c. no messages at all. You may have to adjust your inbound mail filters and aliases or address books that you use to post to the list, or file messages into folders. You may have to re-configure personal subscriber customization. The entry pages to do that latter are: https://lists.sourceforge.net/lists/listinfo/fetchmail-announce https://lists.sourceforge.net/lists/listinfo/fetchmail-devel https://lists.sourceforge.net/lists/listinfo/fetchmail-users QUICK MAILING LIST OVERVIEW (LIST PURPOSE) The fetchmail-announce@ list is reserved for the project admins for release/errata/security and other similarly important announcements, in order to be a very low traffic list with only a few posts per year. The fetchmail-users@ list is for general discussion of use, function, integration with other software from the end user's perspective, support inquiries, and thereabouts. The fetchmail-devel@ list is for discussion of the code, development, and integration with other software from a developer's perspective. FURTHER SERVICES The unmaintained Wiki contents were mostly of interest to developers and have been dropped. The tracker data could not yet be imported. I downloaded the data, but it would take major efforts to import things. The website contents are more or less unchanged, and I need to update them to reflect the mailing list migration. The Git repository has been and continues to be at <https://gitorious.org/fetchmail/> and gets manually mirrored to <https://sourceforge.net/p/fetchmail/git/>. If you have any concerns, troubles, thoughts, let me know, either through the fetchmail-users@ list, or directly if it's sensitive. Best, Matthias - - fetchmail maintainer - -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iEYEARECAAYFAlOzv+UACgkQvmGDOQUufZU1SQCfZZGyFQUA4jj6TAR3RmXMD9E5 Y0wAoOGGB04chmix3Djn+rc+v/SeJv4n =hfm1 -----END PGP SIGNATURE----- |
From: Matthias A. <mat...@gm...> - 2014-04-30 00:57:30
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Dear fetchmail mailing list subscribers, BerliOS is shutting down end of this month, and their mailing list export is broken, so I may not be able to obtain subscriber rosters in a timely manner. I will move downloads to sourceforge.net, but I have not yet decided if I want to move the mailing lists there because their list archive interface is awkward to use and inconcise. If the move of the list goes well, I will follow up with a new announcement message in a few days. If such an action does not happen, please check the fetchmail website at http://www.fetchmail.info/ or http://fetchmail.sourceforge.net/ for updated mailing list instructions in May 2014. You may have to resubscribe in the future. Sorry for the inconvenience - if any. Best regards Matthias -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iEYEARECAAYFAlNgLlcACgkQvmGDOQUufZUgUgCeLTz8ey8Opjx0pLQzxiWhJ/4l EuUAn0mEcjkcwno4uvTtoR8vMatB/MEN =FWME -----END PGP SIGNATURE----- |
From: <ad...@be...> - 2014-03-15 11:19:21
|
Feature Request #5736, was updated on 2014-Mar-14 12:36 You can respond by visiting: http://developer.berlios.de/feature/?func=detailfeature&feature_id=5736&group_id=1824 Category: None Status: Open Priority: 1 Summary: Add support for EAS By: m-a Date: 2014-Mar-15 11:19 Message: Logged In: YES user_id=2007 Browser: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:27.0) Gecko/20100101 Firefox/27.0 This is rather unlikely to happen because there is a precedent that did not work out: I have had a Google Summer of Code contribution that added MAPI access, but it was not properly integrated at the time, and I have never received - in spite of multiple calls for help - a test account so I could integrate the code and test. Plus given the little spare time I have, I would rather not waste that on proprietary stuff when we have open protocol like IMAP. I have my mobile client (K9mail on Android) use IMAP and don't feel the need to switch to legacy stuff - I'd expect that someone offering mail services also offers standard access ports. I would consider adding stuff for the "master" branch in Git if someone offered the code, providing that - I have made bad experience in other projects, that's why it looks restrictive and is restrictive: * There is sufficient evidence that the protocol is not patent-encumbered * Requisite libraries are under OSI approved and GPL-compatible licenses, and should be AGPLv3 compatible. * I get a permanent royalty and restriction free copyright and patent license to the code that permits me to relicense the code and permits users of open-source licensed derivatives to use any involved patents royalty-free * there is a sustainable commitment of the contributor to answer questions to the code and help maintain it (I am not accepting Google summer of code contributions or other way that I suspect to me of a hit-and-run style) * I get a reliable communications channel, and the address of a backup person (family, friend) that I can ask why the EAS contributor is not responding * I get a personal long-term EAS test account, with contractual guarantee for at least five years, so I can keep checking the code still works before releases. I am not going to pay for the account, it has to be sponsored or donated in some way. * Integration into fetchmail must be in a way that EAS support easily be disabled at build-time with no ill effects at run-time. The code would, however, be permitted to use standards-compliant langauges that offer C linkage, such as C++11, given sufficient cross-platform support (which I consider as Linux, BSD, Solaris, Cygwin). ---------------------------------------------------------------------- By: dbesler Date: 2014-Mar-14 12:36 Message: Logged In: YES user_id=65358 Browser: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.1; .NET CLR 3.0.04506.30; MS-RTC LM 8; .NET CLR 3.0.04506.648; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E; Zune 4.7; McAfee) Add support for the EAS (Exchange Active Sync) protocol for: a) retrieval of mail from an EAS service b) deliver mail to an EAS service EAS has become a standard supported protocol for mobile e-mail clients. Although the initial merit of this feature request may seem to be far fetched, EAS has addressed some of the issues that are present in the legacy protocols of POP, IMAP, etc A collection of Exchange Interoperability Technical Articles can be found here: http://msdn.microsoft.com/en-us/library/hh285606 (v=exchg.140).aspx If the project members are interested and willing, I would be interested in particpating in the development and testing of this feature. ---------------------------------------------------------------------- You can respond by visiting: http://developer.berlios.de/feature/?func=detailfeature&feature_id=5736&group_id=1824 |
From: <ad...@be...> - 2014-03-14 12:36:31
|
Feature Request #5736, was updated on 2014-Mar-14 06:36 You can respond by visiting: http://developer.berlios.de/feature/?func=detailfeature&feature_id=5736&group_id=1824 Category: None Status: Open Priority: 5 Summary: Add support for EAS By: dbesler Date: 2014-Mar-14 06:36 Message: Logged In: YES user_id=65358 Browser: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.1; .NET CLR 3.0.04506.30; MS-RTC LM 8; .NET CLR 3.0.04506.648; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E; Zune 4.7; McAfee) Add support for the EAS (Exchange Active Sync) protocol for: a) retrieval of mail from an EAS service b) deliver mail to an EAS service EAS has become a standard supported protocol for mobile e-mail clients. Although the initial merit of this feature request may seem to be far fetched, EAS has addressed some of the issues that are present in the legacy protocols of POP, IMAP, etc A collection of Exchange Interoperability Technical Articles can be found here: http://msdn.microsoft.com/en-us/library/hh285606 (v=exchg.140).aspx If the project members are interested and willing, I would be interested in particpating in the development and testing of this feature. ---------------------------------------------------------------------- You can respond by visiting: http://developer.berlios.de/feature/?func=detailfeature&feature_id=5736&group_id=1824 |
From: Translation P. R. <ro...@tr...> - 2014-01-27 13:06:22
|
Hello, gentle maintainer. This is a message from the Translation Project robot. A revised PO file for textual domain 'fetchmail' has been submitted by the Indonesian team of translators. The file is available at: http://translationproject.org/latest/fetchmail/id.po (We can arrange things so that in the future such files are automatically e-mailed to you when they arrive. Ask at the address below if you want this.) All other PO files for your package are available in: http://translationproject.org/latest/fetchmail/ Please consider including all of these in your next release, whether official or a pretest. Whenever you have a new distribution with a new version number ready, containing a newer POT file, please send the URL of that distribution tarball to the address below. The tarball may be just a pretest or a snapshot, it does not even have to compile. It is just used by the translators when they need some extra translation context. The following HTML page has been updated: http://translationproject.org/domain/fetchmail.html If any question arises, please contact the translation coordinator. Thank you for all your work, The Translation Project robot, in the name of your translation coordinator. <coo...@tr...> |
From: <ad...@be...> - 2013-12-13 00:51:00
|
Bug #18853, was updated on 2013-Jan-03 22:49 Here is a current snapshot of the bug. Project: fetchmail Category: None Status: Open Resolution: None Bug Group: None Priority: 4 Submitted by: w-f Assigned to : m-a Summary: IMAP IDLE + SSL: Error: re-poll failed Details: I use fetchmail with SSL and IMAP IDLE. The IMAP connection freezes after some time and the re-poll failed after 28 min. It looks like there is a ssl socket timeout before a IMAP IDLE re-poll is issued. ----- Jan 3 20:31:35 mini2 fetchmail[14842]: IMAP> A0005 IDLE Jan 3 20:31:35 mini2 fetchmail[14842]: IMAP< + OK Jan 3 20:59:35 mini2 fetchmail[14842]: IMAP> DONE Jan 3 20:59:35 mini2 fetchmail[14842]: re-poll failed Jan 3 20:59:35 mini2 fetchmail[14842]: socket error while fetching from web...@fi...@imap.strato.de Jan 3 20:59:35 mini2 fetchmail[14842]: 6.3.24 querying imap.strato.de (protocol IMAP) at Thu, 03 Jan 2013 20:59:35 +0100 (CET): poll completed Jan 3 20:59:35 mini2 fetchmail[14842]: Query status=2 (SOCKET) ----- The re-poll does not fail, when the idle timeout is reduced from 28 min to 10 minutes. This should also fulfil the RFC 2177, because the RFC suggests to re-issue a IDLE command at LEAST every 29 minutes. RFC 2177 "The server MAY consider a client inactive if it has an IDLE command running, and if such a server has an inactivity timeout it MAY log the client off implicitly at the end of its timeout period. Because of that, clients using IDLE are advised to terminate the IDLE and re-issue it at least every 29 minutes to avoid being logged off. This still allows a client to receive immediate mailbox updates even though it need only "poll" at half hour intervals." Other IMAP Clients uses a shorter IDLE re-poll timer or issues a NOOP Command. Microsoft Outlook: 10 min Apple Mail: IMAP NOOP every 1 minute (RFC 3501: "The NOOP command can also be used to reset any inactivity autologout timer on the server.") ------ Patch (Reduce idle_timeout to 600) diff fetchmail-6.3.24-patched/imap.c fetchmail-6.3.24/imap.c 718,719c718 < /* mytimeout = idle_timeout = 1680; */ /* 28 min */ < mytimeout = idle_timeout = 600; /* reduce to 10 min to prevent ssl socket timeout */ --- > mytimeout = idle_timeout = 1680; /* 28 min */ Enviroment: fetchmail 6.3.24 OS: Mac OS 10.7.5 IMAP Server: Provider Strato (imap.strato.de) --- Best regards, Wolfgang Follow-Ups: Date: 2013-Dec-13 00:51 By: m-a Comment: It's six unanswered probes, of course. ------------------------------------------------------- Date: 2013-Dec-13 00:47 By: m-a Comment: Well, it's quite clear from the tcpdump logs that the server has silently gone down, i. e. there was not the usual FIN / FIN|ACK handshake to shut down the connection orderly. When fetchmail tried to re-poll after 28 minutes, it sent out data, and then the server responded with a RST - a sign that it knew of no connection. I can imagine two ways how this may fail: 1. some firewall (including your router) erases its connection record, and does not let the FIN packages from the server back through. Probably not Linux netfilter, my Ubuntu 3.8 kernel on 12.04LTS has a timeout of 5 days for established TCP connections. 2. some firewall on the server's end erases the connection record, so that fetchmail's "DONE" triggers the connection reset from the remote end fetchmail has been setting the SO_KEEPALIVE option since release 6.3.20, and OpenSSL does not apparently flip that switch. However, the default keepalive timer on Linux and FreeBSD kicks in after two hours - so it's not useful for checking IDLE. You'd have to lower that, see if running these commands helps, this set is for Linux: sysctl net.ipv4.tcp_keepalive_time=300 sysctl net.ipv4.tcp_keepalive_intvl=24 sysctl net.ipv4.tcp_keepalive_probes=6 On FreeBSD and maybe on Darwin/MacOS X, try these (milliseconds here): sysctl -w net.inet.tcp.keepidle=300000 sysctl -w net.inet.tcp.keepintvl=24000 sysctl -w net.inet.tcp.keepcnt=6 On the next connection, sockets will start probing keepalives after 5, rather than 120, minutes, and resent probes at 24, rather than 75, second intervals, and tolerate five (rather than nine) unanswered probes. Meaning that some seven minutes after a silent disconnect, the kernel would detect that the connection is gone and issue an error code. It would be interesting to see a tcpdump around that time then, to conclude what the new error mode would then be. Can both of you rule out that your firewall loses the connection early? The firewall timeouts for erasing TCP connections without traffic must obviously be 30 minutes or longer. If so, has either of you ever contacted the server's operator and asked if their IMAP server and firewalls are fit to support idle times of up to 30 minutes? ------------------------------------------------------- Date: 2013-Dec-12 23:13 By: rainforest1155 Comment: I'm also using Strato and am seeing exactly the same problem. Every 28 min after the poll started, I'm getting the same error like Wolfgang. For example: Dec 11 19:11:45 beagle fetchmail[32718]: re-poll failed Dec 11 19:11:45 beagle fetchmail[32718]: socket error while fetching from my...@my...@imap.strato.de Dec 11 19:11:45 beagle fetchmail[32718]: Query status=2 (SOCKET) Any chance this issue could be revisited? Let me know if I can provide you with any further details. system: Debian 7.2 fetchmail 6.3.21-4 Just note that I'm still a newbie at this. Thanks, Sebastian ------------------------------------------------------- Date: 2013-Apr-29 21:37 By: w-f Comment: the Link with the complete dtrace files is active again. https://www.hidrive.strato.com/lnk/RBTrVUhJ Best regards, Wolfgang ------------------------------------------------------- Date: 2013-Apr-26 19:34 By: m-a Comment: I was about to revisit your bug report; unfortunately, the log file link has expired. Can you re-upload the logs? Thank you. ------------------------------------------------------- Date: 2013-Jan-06 22:43 By: w-f Comment: Hello Matthias, I did a dtrace for the SSL case and non-SSL case. In both variants the TCP KeepAlive is enabled. 199552 20 14 socket(0x2, 0x1, 0x6) = 5 0 199559 8 2 setsockopt(0x5, 0xFFFF, 0x8) = 0 0 199634 21589 72 connect(0x5, 0x7FAF0AC01320, 0x10) = 0 0 But there is an other difference: The non-ssl socket uses the system call recvfrom to wait for data from the imap server during the idle time. The ssl socket uses the system call "read" to wait for data from the imap server during the idle time. The tcp stack sends no KeepAlive Packets during the system call read. You can download the complete dtrace files for both variants from https://www.hidrive.strato.com/lnk/RBTrVUhJ Best regards, Wolfgang ------------------------------------------------------- Date: 2013-Jan-06 13:29 By: m-a Comment: Wolfgang, could you dtrace setsockopt and/or all socket option, for (1) the SSL case, (2) the non-SSL case? I unconditionally enable SO_KEEPALIVE after the socket has been opened, and never see them disabled - perhaps your OpenSSL library behaves differently. Best regards, Matthias ------------------------------------------------------- Date: 2013-Jan-06 13:20 By: m-a Comment: Thanks for the detailed information. However, this pretty much looks like a networking issue. The server just hung up, but there was no FIN|ACK handshake from closing down the connection, so fetchmail was not informed of the shutdown or close until it tried to send the next packet. This pretty much looks like a networking issue, broken router or NAT or Masquerading. I'll grant that TCP keepalives might help. Unfortunately, strato does not appear to support STARTTLS, so we cannot test that. ------------------------------------------------------- Date: 2013-Jan-05 19:50 By: w-f Comment: The issue is not an server imap timeout. There are no problems when using an unencrypted imap session. The dtruss shows no activity during the idle time: 22867/0xaf6c4: 629137 33 24 write(0x5, "\027\003\0", 0x25) = 37 0 22867/0xaf6c4: 629147 9 3 __sysctl(0x7FFF60CF8FE8, 0x2, 0x7FFF60CF8FFF) = 0 0 22867/0xaf6c4: 629150 5 0 getuid(0x0, 0x7FFF60CF8C58, 0x0) = 273 0 22867/0xaf6c4: 629152 5 0 getgid(0x0, 0x7FFF60CF8C58, 0x0) = 1 0 22867/0xaf6c4: 629184 9 3 setitimer(0x0, 0x7FFF60CF7E00, 0x0) = 0 0 dtrace: error on enabled probe ID 1791 (ID 778: syscall::read:return): out of scratch space in action #13 at DIF offset 44 dtrace: error on enabled probe ID 1791 (ID 778: syscall::read:return): out of scratch space in action #13 at DIF offset 44 dtrace: error on enabled probe ID 1789 (ID 780: syscall::write:return): out of scratch space in action #13 at DIF offset 44 22867/0xaf6c4: 629354 343 20 sigreturn(0x7FFF60CF7B50, 0x1E, 0x7FFF60CF7B50) = 0 Err#-2 22867/0xaf6c4: 629358 8 0 __pthread_canceled(0x0, 0x7FE06C015000, 0x7FFF60CF7C08) = -1 Err#22 22867/0xaf6c4: 629372 8 1 setitimer(0x0, 0x7FFF60CF7E00, 0x0) = 0 0 22867/0xaf6c4: 629454 66 58 write(0x5, "\027\003\0", 0x1F) = 31 0 22867/0xaf6c4: 629481 15 8 __sysctl(0x7FFF60CFB0F8, 0x2, 0x7FFF60CFB10F) = 0 0 22867/0xaf6c4: 629485 6 0 getuid(0x0, 0x7FFF60CFAD68, 0x0) = 273 0 22867/0xaf6c4: 629487 6 0 getgid(0x0, 0x7FFF60CFAD68, 0x0) = 1 0 22867/0xaf6c4: 629533 10 4 setitimer(0x0, 0x7FFF60CF9F30, 0x0) = 0 0 22867/0xaf6c4: 629566 13 1 setitimer(0x0, 0x7FFF60CF9F30, 0x0) = 0 0 22867/0xaf6c4: 629569 5 0 setitimer(0x0, 0x7FFF60CFBFD0, 0x0) = 0 0 22867/0xaf6c4: 629596 14 7 __sysctl(0x7FFF60CFB118, 0x2, 0x7FFF60CFB12F) = 0 0 22867/0xaf6c4: 629600 5 0 getuid(0x0, 0x7FFF60CFAD88, 0x0) = 273 0 22867/0xaf6c4: 629602 5 0 getgid(0x0, 0x7FFF60CFAD88, 0x0) = 1 0 22867/0xaf6c4: 629648 10 2 sigaction(0xE, 0x7FFF60D00098, 0x7FFF60D000C0) = 0 0 22867/0xaf6c4: 629653 8 2 setitimer(0x0, 0x7FFF60D00278, 0x0) = 0 0 22867/0xaf6c4: 629849 18 9 close(0x5) = 0 0 22867/0xaf6c4: 629852 6 1 setitimer(0x0, 0x7FFF60D00298, 0x0) = 0 0 22867/0xaf6c4: 629854 6 0 sigaction(0xE, 0x7FFF60D00098, 0x7FFF60D000C0) = 0 0 22867/0xaf6c4: 629867 9 3 __sysctl(0x7FFF60CFF1E8, 0x2, 0x7FFF60CFF1FF) = 0 0 Also there is no network traffic during the idle time. And the response for first packet TCP Push from fetchmail to the imap server is a Reset. tcp dump IMAPS Session: ------ 18:42:48.547781 IP (tos 0x0, ttl 64, id 25398, offset 0, flags [DF], proto TCP (6), length 77) mini2.home.fischer-net.net.60975 > imap.strato.de.imaps: Flags [P.], cksum 0x4c5f (incorrect -> 0x2baf), seq 743:780, ack 4504, win 33396, length 37 18:42:48.568631 IP (tos 0x0, ttl 248, id 36786, offset 0, flags [DF], proto TCP (6), length 71) imap.strato.de.imaps > mini2.home.fischer-net.net.60975: Flags [P.], cksum 0x5a30 (correct), seq 4504:4535, ack 780, win 5135, length 31 18:42:48.568693 IP (tos 0x0, ttl 64, id 64318, offset 0, flags [DF], proto TCP (6), length 40) mini2.home.fischer-net.net.60975 > imap.strato.de.imaps: Flags [.], cksum 0x4c3a (incorrect -> 0xd50a), seq 780, ack 4535, win 33380, length 0 19:10:48.624932 IP (tos 0x0, ttl 64, id 12889, offset 0, flags [DF], proto TCP (6), length 71) mini2.home.fischer-net.net.60975 > imap.strato.de.imaps: Flags [P.], cksum 0x4c59 (incorrect -> 0xfd06), seq 780:811, ack 4535, win 33396, length 31 19:10:48.646571 IP (tos 0x0, ttl 248, id 18517, offset 0, flags [DF], proto TCP (6), length 40) imap.strato.de.imaps > mini2.home.fischer-net.net.60975: Flags [R.], cksum 0x574c (correct), seq 4535, ack 811, win 0, length 0 19:11:49.041641 IP (tos 0x0, ttl 64, id 1235, offset 0, flags [DF], proto TCP (6), length 64) mini2.home.fischer-net.net.61035 > imap.strato.de.imaps: Flags [S], cksum 0x4c52 (incorrect -> 0x0b3e), seq 771336041, win 65535, options [mss 1460,nop,wscale 1,nop,nop,TS val 1029692052 ecr 0,sackOK,eol], length 0 19:11:49.063272 IP (tos 0x0, ttl 248, id 26043, offset 0, flags [DF], proto TCP (6), length 52) imap.strato.de.imaps > mini2.home.fischer-net.net.61035: Flags [S.], cksum 0x1718 (correct), seq 2700448559, ack 771336042, win 4356, options [mss 1452,nop,wscale 0,sackOK,eol], length 0 ----- Now for me looks like the issue is, fetchmail opens the Socket for the SSL Session without a TCP KeepAlive. When I use an unencrypted imap session, the TCP KeepAlive is active. The tcpdump shows the TCP KeepAlive packets during the imap idle time. Best Regards, Wolfgang ------------------------------------------------------- Date: 2013-Jan-03 23:02 By: m-a Comment: Have Strato fix their server timeouts instead, the 30 minute timer is a "MUST" clause in RFC-3501 section 5.4, see http://tools.ietf.org/html/rfc3501#section-5.4 If there is a socket timeout, I'd like to see an strace or truss trace proving it, and possibly an accompanying tcpdump or wireshark/tshark dump of the protocol with timestamps, to see when the connection gets closed. Chances are that there is a problem on your end - are you using IPv4 NAT or Masquerading? ------------------------------------------------------- For detailed info, follow this link: http://developer.berlios.de/bugs/?func=detailbug&bug_id=18853&group_id=1824 |
From: <ad...@be...> - 2013-12-13 00:47:31
|
Bug #18853, was updated on 2013-Jan-03 22:49 Here is a current snapshot of the bug. Project: fetchmail Category: None Status: Open Resolution: None Bug Group: None Priority: 4 Submitted by: w-f Assigned to : m-a Summary: IMAP IDLE + SSL: Error: re-poll failed Details: I use fetchmail with SSL and IMAP IDLE. The IMAP connection freezes after some time and the re-poll failed after 28 min. It looks like there is a ssl socket timeout before a IMAP IDLE re-poll is issued. ----- Jan 3 20:31:35 mini2 fetchmail[14842]: IMAP> A0005 IDLE Jan 3 20:31:35 mini2 fetchmail[14842]: IMAP< + OK Jan 3 20:59:35 mini2 fetchmail[14842]: IMAP> DONE Jan 3 20:59:35 mini2 fetchmail[14842]: re-poll failed Jan 3 20:59:35 mini2 fetchmail[14842]: socket error while fetching from web...@fi...@imap.strato.de Jan 3 20:59:35 mini2 fetchmail[14842]: 6.3.24 querying imap.strato.de (protocol IMAP) at Thu, 03 Jan 2013 20:59:35 +0100 (CET): poll completed Jan 3 20:59:35 mini2 fetchmail[14842]: Query status=2 (SOCKET) ----- The re-poll does not fail, when the idle timeout is reduced from 28 min to 10 minutes. This should also fulfil the RFC 2177, because the RFC suggests to re-issue a IDLE command at LEAST every 29 minutes. RFC 2177 "The server MAY consider a client inactive if it has an IDLE command running, and if such a server has an inactivity timeout it MAY log the client off implicitly at the end of its timeout period. Because of that, clients using IDLE are advised to terminate the IDLE and re-issue it at least every 29 minutes to avoid being logged off. This still allows a client to receive immediate mailbox updates even though it need only "poll" at half hour intervals." Other IMAP Clients uses a shorter IDLE re-poll timer or issues a NOOP Command. Microsoft Outlook: 10 min Apple Mail: IMAP NOOP every 1 minute (RFC 3501: "The NOOP command can also be used to reset any inactivity autologout timer on the server.") ------ Patch (Reduce idle_timeout to 600) diff fetchmail-6.3.24-patched/imap.c fetchmail-6.3.24/imap.c 718,719c718 < /* mytimeout = idle_timeout = 1680; */ /* 28 min */ < mytimeout = idle_timeout = 600; /* reduce to 10 min to prevent ssl socket timeout */ --- > mytimeout = idle_timeout = 1680; /* 28 min */ Enviroment: fetchmail 6.3.24 OS: Mac OS 10.7.5 IMAP Server: Provider Strato (imap.strato.de) --- Best regards, Wolfgang Follow-Ups: Date: 2013-Dec-13 00:47 By: m-a Comment: Well, it's quite clear from the tcpdump logs that the server has silently gone down, i. e. there was not the usual FIN / FIN|ACK handshake to shut down the connection orderly. When fetchmail tried to re-poll after 28 minutes, it sent out data, and then the server responded with a RST - a sign that it knew of no connection. I can imagine two ways how this may fail: 1. some firewall (including your router) erases its connection record, and does not let the FIN packages from the server back through. Probably not Linux netfilter, my Ubuntu 3.8 kernel on 12.04LTS has a timeout of 5 days for established TCP connections. 2. some firewall on the server's end erases the connection record, so that fetchmail's "DONE" triggers the connection reset from the remote end fetchmail has been setting the SO_KEEPALIVE option since release 6.3.20, and OpenSSL does not apparently flip that switch. However, the default keepalive timer on Linux and FreeBSD kicks in after two hours - so it's not useful for checking IDLE. You'd have to lower that, see if running these commands helps, this set is for Linux: sysctl net.ipv4.tcp_keepalive_time=300 sysctl net.ipv4.tcp_keepalive_intvl=24 sysctl net.ipv4.tcp_keepalive_probes=6 On FreeBSD and maybe on Darwin/MacOS X, try these (milliseconds here): sysctl -w net.inet.tcp.keepidle=300000 sysctl -w net.inet.tcp.keepintvl=24000 sysctl -w net.inet.tcp.keepcnt=6 On the next connection, sockets will start probing keepalives after 5, rather than 120, minutes, and resent probes at 24, rather than 75, second intervals, and tolerate five (rather than nine) unanswered probes. Meaning that some seven minutes after a silent disconnect, the kernel would detect that the connection is gone and issue an error code. It would be interesting to see a tcpdump around that time then, to conclude what the new error mode would then be. Can both of you rule out that your firewall loses the connection early? The firewall timeouts for erasing TCP connections without traffic must obviously be 30 minutes or longer. If so, has either of you ever contacted the server's operator and asked if their IMAP server and firewalls are fit to support idle times of up to 30 minutes? ------------------------------------------------------- Date: 2013-Dec-12 23:13 By: rainforest1155 Comment: I'm also using Strato and am seeing exactly the same problem. Every 28 min after the poll started, I'm getting the same error like Wolfgang. For example: Dec 11 19:11:45 beagle fetchmail[32718]: re-poll failed Dec 11 19:11:45 beagle fetchmail[32718]: socket error while fetching from my...@my...@imap.strato.de Dec 11 19:11:45 beagle fetchmail[32718]: Query status=2 (SOCKET) Any chance this issue could be revisited? Let me know if I can provide you with any further details. system: Debian 7.2 fetchmail 6.3.21-4 Just note that I'm still a newbie at this. Thanks, Sebastian ------------------------------------------------------- Date: 2013-Apr-29 21:37 By: w-f Comment: the Link with the complete dtrace files is active again. https://www.hidrive.strato.com/lnk/RBTrVUhJ Best regards, Wolfgang ------------------------------------------------------- Date: 2013-Apr-26 19:34 By: m-a Comment: I was about to revisit your bug report; unfortunately, the log file link has expired. Can you re-upload the logs? Thank you. ------------------------------------------------------- Date: 2013-Jan-06 22:43 By: w-f Comment: Hello Matthias, I did a dtrace for the SSL case and non-SSL case. In both variants the TCP KeepAlive is enabled. 199552 20 14 socket(0x2, 0x1, 0x6) = 5 0 199559 8 2 setsockopt(0x5, 0xFFFF, 0x8) = 0 0 199634 21589 72 connect(0x5, 0x7FAF0AC01320, 0x10) = 0 0 But there is an other difference: The non-ssl socket uses the system call recvfrom to wait for data from the imap server during the idle time. The ssl socket uses the system call "read" to wait for data from the imap server during the idle time. The tcp stack sends no KeepAlive Packets during the system call read. You can download the complete dtrace files for both variants from https://www.hidrive.strato.com/lnk/RBTrVUhJ Best regards, Wolfgang ------------------------------------------------------- Date: 2013-Jan-06 13:29 By: m-a Comment: Wolfgang, could you dtrace setsockopt and/or all socket option, for (1) the SSL case, (2) the non-SSL case? I unconditionally enable SO_KEEPALIVE after the socket has been opened, and never see them disabled - perhaps your OpenSSL library behaves differently. Best regards, Matthias ------------------------------------------------------- Date: 2013-Jan-06 13:20 By: m-a Comment: Thanks for the detailed information. However, this pretty much looks like a networking issue. The server just hung up, but there was no FIN|ACK handshake from closing down the connection, so fetchmail was not informed of the shutdown or close until it tried to send the next packet. This pretty much looks like a networking issue, broken router or NAT or Masquerading. I'll grant that TCP keepalives might help. Unfortunately, strato does not appear to support STARTTLS, so we cannot test that. ------------------------------------------------------- Date: 2013-Jan-05 19:50 By: w-f Comment: The issue is not an server imap timeout. There are no problems when using an unencrypted imap session. The dtruss shows no activity during the idle time: 22867/0xaf6c4: 629137 33 24 write(0x5, "\027\003\0", 0x25) = 37 0 22867/0xaf6c4: 629147 9 3 __sysctl(0x7FFF60CF8FE8, 0x2, 0x7FFF60CF8FFF) = 0 0 22867/0xaf6c4: 629150 5 0 getuid(0x0, 0x7FFF60CF8C58, 0x0) = 273 0 22867/0xaf6c4: 629152 5 0 getgid(0x0, 0x7FFF60CF8C58, 0x0) = 1 0 22867/0xaf6c4: 629184 9 3 setitimer(0x0, 0x7FFF60CF7E00, 0x0) = 0 0 dtrace: error on enabled probe ID 1791 (ID 778: syscall::read:return): out of scratch space in action #13 at DIF offset 44 dtrace: error on enabled probe ID 1791 (ID 778: syscall::read:return): out of scratch space in action #13 at DIF offset 44 dtrace: error on enabled probe ID 1789 (ID 780: syscall::write:return): out of scratch space in action #13 at DIF offset 44 22867/0xaf6c4: 629354 343 20 sigreturn(0x7FFF60CF7B50, 0x1E, 0x7FFF60CF7B50) = 0 Err#-2 22867/0xaf6c4: 629358 8 0 __pthread_canceled(0x0, 0x7FE06C015000, 0x7FFF60CF7C08) = -1 Err#22 22867/0xaf6c4: 629372 8 1 setitimer(0x0, 0x7FFF60CF7E00, 0x0) = 0 0 22867/0xaf6c4: 629454 66 58 write(0x5, "\027\003\0", 0x1F) = 31 0 22867/0xaf6c4: 629481 15 8 __sysctl(0x7FFF60CFB0F8, 0x2, 0x7FFF60CFB10F) = 0 0 22867/0xaf6c4: 629485 6 0 getuid(0x0, 0x7FFF60CFAD68, 0x0) = 273 0 22867/0xaf6c4: 629487 6 0 getgid(0x0, 0x7FFF60CFAD68, 0x0) = 1 0 22867/0xaf6c4: 629533 10 4 setitimer(0x0, 0x7FFF60CF9F30, 0x0) = 0 0 22867/0xaf6c4: 629566 13 1 setitimer(0x0, 0x7FFF60CF9F30, 0x0) = 0 0 22867/0xaf6c4: 629569 5 0 setitimer(0x0, 0x7FFF60CFBFD0, 0x0) = 0 0 22867/0xaf6c4: 629596 14 7 __sysctl(0x7FFF60CFB118, 0x2, 0x7FFF60CFB12F) = 0 0 22867/0xaf6c4: 629600 5 0 getuid(0x0, 0x7FFF60CFAD88, 0x0) = 273 0 22867/0xaf6c4: 629602 5 0 getgid(0x0, 0x7FFF60CFAD88, 0x0) = 1 0 22867/0xaf6c4: 629648 10 2 sigaction(0xE, 0x7FFF60D00098, 0x7FFF60D000C0) = 0 0 22867/0xaf6c4: 629653 8 2 setitimer(0x0, 0x7FFF60D00278, 0x0) = 0 0 22867/0xaf6c4: 629849 18 9 close(0x5) = 0 0 22867/0xaf6c4: 629852 6 1 setitimer(0x0, 0x7FFF60D00298, 0x0) = 0 0 22867/0xaf6c4: 629854 6 0 sigaction(0xE, 0x7FFF60D00098, 0x7FFF60D000C0) = 0 0 22867/0xaf6c4: 629867 9 3 __sysctl(0x7FFF60CFF1E8, 0x2, 0x7FFF60CFF1FF) = 0 0 Also there is no network traffic during the idle time. And the response for first packet TCP Push from fetchmail to the imap server is a Reset. tcp dump IMAPS Session: ------ 18:42:48.547781 IP (tos 0x0, ttl 64, id 25398, offset 0, flags [DF], proto TCP (6), length 77) mini2.home.fischer-net.net.60975 > imap.strato.de.imaps: Flags [P.], cksum 0x4c5f (incorrect -> 0x2baf), seq 743:780, ack 4504, win 33396, length 37 18:42:48.568631 IP (tos 0x0, ttl 248, id 36786, offset 0, flags [DF], proto TCP (6), length 71) imap.strato.de.imaps > mini2.home.fischer-net.net.60975: Flags [P.], cksum 0x5a30 (correct), seq 4504:4535, ack 780, win 5135, length 31 18:42:48.568693 IP (tos 0x0, ttl 64, id 64318, offset 0, flags [DF], proto TCP (6), length 40) mini2.home.fischer-net.net.60975 > imap.strato.de.imaps: Flags [.], cksum 0x4c3a (incorrect -> 0xd50a), seq 780, ack 4535, win 33380, length 0 19:10:48.624932 IP (tos 0x0, ttl 64, id 12889, offset 0, flags [DF], proto TCP (6), length 71) mini2.home.fischer-net.net.60975 > imap.strato.de.imaps: Flags [P.], cksum 0x4c59 (incorrect -> 0xfd06), seq 780:811, ack 4535, win 33396, length 31 19:10:48.646571 IP (tos 0x0, ttl 248, id 18517, offset 0, flags [DF], proto TCP (6), length 40) imap.strato.de.imaps > mini2.home.fischer-net.net.60975: Flags [R.], cksum 0x574c (correct), seq 4535, ack 811, win 0, length 0 19:11:49.041641 IP (tos 0x0, ttl 64, id 1235, offset 0, flags [DF], proto TCP (6), length 64) mini2.home.fischer-net.net.61035 > imap.strato.de.imaps: Flags [S], cksum 0x4c52 (incorrect -> 0x0b3e), seq 771336041, win 65535, options [mss 1460,nop,wscale 1,nop,nop,TS val 1029692052 ecr 0,sackOK,eol], length 0 19:11:49.063272 IP (tos 0x0, ttl 248, id 26043, offset 0, flags [DF], proto TCP (6), length 52) imap.strato.de.imaps > mini2.home.fischer-net.net.61035: Flags [S.], cksum 0x1718 (correct), seq 2700448559, ack 771336042, win 4356, options [mss 1452,nop,wscale 0,sackOK,eol], length 0 ----- Now for me looks like the issue is, fetchmail opens the Socket for the SSL Session without a TCP KeepAlive. When I use an unencrypted imap session, the TCP KeepAlive is active. The tcpdump shows the TCP KeepAlive packets during the imap idle time. Best Regards, Wolfgang ------------------------------------------------------- Date: 2013-Jan-03 23:02 By: m-a Comment: Have Strato fix their server timeouts instead, the 30 minute timer is a "MUST" clause in RFC-3501 section 5.4, see http://tools.ietf.org/html/rfc3501#section-5.4 If there is a socket timeout, I'd like to see an strace or truss trace proving it, and possibly an accompanying tcpdump or wireshark/tshark dump of the protocol with timestamps, to see when the connection gets closed. Chances are that there is a problem on your end - are you using IPv4 NAT or Masquerading? ------------------------------------------------------- For detailed info, follow this link: http://developer.berlios.de/bugs/?func=detailbug&bug_id=18853&group_id=1824 |
From: <ad...@be...> - 2013-12-12 23:13:53
|
Bug #18853, was updated on 2013-Jan-03 22:49 Here is a current snapshot of the bug. Project: fetchmail Category: None Status: Open Resolution: None Bug Group: None Priority: 4 Submitted by: w-f Assigned to : m-a Summary: IMAP IDLE + SSL: Error: re-poll failed Details: I use fetchmail with SSL and IMAP IDLE. The IMAP connection freezes after some time and the re-poll failed after 28 min. It looks like there is a ssl socket timeout before a IMAP IDLE re-poll is issued. ----- Jan 3 20:31:35 mini2 fetchmail[14842]: IMAP> A0005 IDLE Jan 3 20:31:35 mini2 fetchmail[14842]: IMAP< + OK Jan 3 20:59:35 mini2 fetchmail[14842]: IMAP> DONE Jan 3 20:59:35 mini2 fetchmail[14842]: re-poll failed Jan 3 20:59:35 mini2 fetchmail[14842]: socket error while fetching from web...@fi...@imap.strato.de Jan 3 20:59:35 mini2 fetchmail[14842]: 6.3.24 querying imap.strato.de (protocol IMAP) at Thu, 03 Jan 2013 20:59:35 +0100 (CET): poll completed Jan 3 20:59:35 mini2 fetchmail[14842]: Query status=2 (SOCKET) ----- The re-poll does not fail, when the idle timeout is reduced from 28 min to 10 minutes. This should also fulfil the RFC 2177, because the RFC suggests to re-issue a IDLE command at LEAST every 29 minutes. RFC 2177 "The server MAY consider a client inactive if it has an IDLE command running, and if such a server has an inactivity timeout it MAY log the client off implicitly at the end of its timeout period. Because of that, clients using IDLE are advised to terminate the IDLE and re-issue it at least every 29 minutes to avoid being logged off. This still allows a client to receive immediate mailbox updates even though it need only "poll" at half hour intervals." Other IMAP Clients uses a shorter IDLE re-poll timer or issues a NOOP Command. Microsoft Outlook: 10 min Apple Mail: IMAP NOOP every 1 minute (RFC 3501: "The NOOP command can also be used to reset any inactivity autologout timer on the server.") ------ Patch (Reduce idle_timeout to 600) diff fetchmail-6.3.24-patched/imap.c fetchmail-6.3.24/imap.c 718,719c718 < /* mytimeout = idle_timeout = 1680; */ /* 28 min */ < mytimeout = idle_timeout = 600; /* reduce to 10 min to prevent ssl socket timeout */ --- > mytimeout = idle_timeout = 1680; /* 28 min */ Enviroment: fetchmail 6.3.24 OS: Mac OS 10.7.5 IMAP Server: Provider Strato (imap.strato.de) --- Best regards, Wolfgang Follow-Ups: Date: 2013-Dec-12 23:13 By: rainforest1155 Comment: I'm also using Strato and am seeing exactly the same problem. Every 28 min after the poll started, I'm getting the same error like Wolfgang. For example: Dec 11 19:11:45 beagle fetchmail[32718]: re-poll failed Dec 11 19:11:45 beagle fetchmail[32718]: socket error while fetching from my...@my...@imap.strato.de Dec 11 19:11:45 beagle fetchmail[32718]: Query status=2 (SOCKET) Any chance this issue could be revisited? Let me know if I can provide you with any further details. system: Debian 7.2 fetchmail 6.3.21-4 Just note that I'm still a newbie at this. Thanks, Sebastian ------------------------------------------------------- Date: 2013-Apr-29 21:37 By: w-f Comment: the Link with the complete dtrace files is active again. https://www.hidrive.strato.com/lnk/RBTrVUhJ Best regards, Wolfgang ------------------------------------------------------- Date: 2013-Apr-26 19:34 By: m-a Comment: I was about to revisit your bug report; unfortunately, the log file link has expired. Can you re-upload the logs? Thank you. ------------------------------------------------------- Date: 2013-Jan-06 22:43 By: w-f Comment: Hello Matthias, I did a dtrace for the SSL case and non-SSL case. In both variants the TCP KeepAlive is enabled. 199552 20 14 socket(0x2, 0x1, 0x6) = 5 0 199559 8 2 setsockopt(0x5, 0xFFFF, 0x8) = 0 0 199634 21589 72 connect(0x5, 0x7FAF0AC01320, 0x10) = 0 0 But there is an other difference: The non-ssl socket uses the system call recvfrom to wait for data from the imap server during the idle time. The ssl socket uses the system call "read" to wait for data from the imap server during the idle time. The tcp stack sends no KeepAlive Packets during the system call read. You can download the complete dtrace files for both variants from https://www.hidrive.strato.com/lnk/RBTrVUhJ Best regards, Wolfgang ------------------------------------------------------- Date: 2013-Jan-06 13:29 By: m-a Comment: Wolfgang, could you dtrace setsockopt and/or all socket option, for (1) the SSL case, (2) the non-SSL case? I unconditionally enable SO_KEEPALIVE after the socket has been opened, and never see them disabled - perhaps your OpenSSL library behaves differently. Best regards, Matthias ------------------------------------------------------- Date: 2013-Jan-06 13:20 By: m-a Comment: Thanks for the detailed information. However, this pretty much looks like a networking issue. The server just hung up, but there was no FIN|ACK handshake from closing down the connection, so fetchmail was not informed of the shutdown or close until it tried to send the next packet. This pretty much looks like a networking issue, broken router or NAT or Masquerading. I'll grant that TCP keepalives might help. Unfortunately, strato does not appear to support STARTTLS, so we cannot test that. ------------------------------------------------------- Date: 2013-Jan-05 19:50 By: w-f Comment: The issue is not an server imap timeout. There are no problems when using an unencrypted imap session. The dtruss shows no activity during the idle time: 22867/0xaf6c4: 629137 33 24 write(0x5, "\027\003\0", 0x25) = 37 0 22867/0xaf6c4: 629147 9 3 __sysctl(0x7FFF60CF8FE8, 0x2, 0x7FFF60CF8FFF) = 0 0 22867/0xaf6c4: 629150 5 0 getuid(0x0, 0x7FFF60CF8C58, 0x0) = 273 0 22867/0xaf6c4: 629152 5 0 getgid(0x0, 0x7FFF60CF8C58, 0x0) = 1 0 22867/0xaf6c4: 629184 9 3 setitimer(0x0, 0x7FFF60CF7E00, 0x0) = 0 0 dtrace: error on enabled probe ID 1791 (ID 778: syscall::read:return): out of scratch space in action #13 at DIF offset 44 dtrace: error on enabled probe ID 1791 (ID 778: syscall::read:return): out of scratch space in action #13 at DIF offset 44 dtrace: error on enabled probe ID 1789 (ID 780: syscall::write:return): out of scratch space in action #13 at DIF offset 44 22867/0xaf6c4: 629354 343 20 sigreturn(0x7FFF60CF7B50, 0x1E, 0x7FFF60CF7B50) = 0 Err#-2 22867/0xaf6c4: 629358 8 0 __pthread_canceled(0x0, 0x7FE06C015000, 0x7FFF60CF7C08) = -1 Err#22 22867/0xaf6c4: 629372 8 1 setitimer(0x0, 0x7FFF60CF7E00, 0x0) = 0 0 22867/0xaf6c4: 629454 66 58 write(0x5, "\027\003\0", 0x1F) = 31 0 22867/0xaf6c4: 629481 15 8 __sysctl(0x7FFF60CFB0F8, 0x2, 0x7FFF60CFB10F) = 0 0 22867/0xaf6c4: 629485 6 0 getuid(0x0, 0x7FFF60CFAD68, 0x0) = 273 0 22867/0xaf6c4: 629487 6 0 getgid(0x0, 0x7FFF60CFAD68, 0x0) = 1 0 22867/0xaf6c4: 629533 10 4 setitimer(0x0, 0x7FFF60CF9F30, 0x0) = 0 0 22867/0xaf6c4: 629566 13 1 setitimer(0x0, 0x7FFF60CF9F30, 0x0) = 0 0 22867/0xaf6c4: 629569 5 0 setitimer(0x0, 0x7FFF60CFBFD0, 0x0) = 0 0 22867/0xaf6c4: 629596 14 7 __sysctl(0x7FFF60CFB118, 0x2, 0x7FFF60CFB12F) = 0 0 22867/0xaf6c4: 629600 5 0 getuid(0x0, 0x7FFF60CFAD88, 0x0) = 273 0 22867/0xaf6c4: 629602 5 0 getgid(0x0, 0x7FFF60CFAD88, 0x0) = 1 0 22867/0xaf6c4: 629648 10 2 sigaction(0xE, 0x7FFF60D00098, 0x7FFF60D000C0) = 0 0 22867/0xaf6c4: 629653 8 2 setitimer(0x0, 0x7FFF60D00278, 0x0) = 0 0 22867/0xaf6c4: 629849 18 9 close(0x5) = 0 0 22867/0xaf6c4: 629852 6 1 setitimer(0x0, 0x7FFF60D00298, 0x0) = 0 0 22867/0xaf6c4: 629854 6 0 sigaction(0xE, 0x7FFF60D00098, 0x7FFF60D000C0) = 0 0 22867/0xaf6c4: 629867 9 3 __sysctl(0x7FFF60CFF1E8, 0x2, 0x7FFF60CFF1FF) = 0 0 Also there is no network traffic during the idle time. And the response for first packet TCP Push from fetchmail to the imap server is a Reset. tcp dump IMAPS Session: ------ 18:42:48.547781 IP (tos 0x0, ttl 64, id 25398, offset 0, flags [DF], proto TCP (6), length 77) mini2.home.fischer-net.net.60975 > imap.strato.de.imaps: Flags [P.], cksum 0x4c5f (incorrect -> 0x2baf), seq 743:780, ack 4504, win 33396, length 37 18:42:48.568631 IP (tos 0x0, ttl 248, id 36786, offset 0, flags [DF], proto TCP (6), length 71) imap.strato.de.imaps > mini2.home.fischer-net.net.60975: Flags [P.], cksum 0x5a30 (correct), seq 4504:4535, ack 780, win 5135, length 31 18:42:48.568693 IP (tos 0x0, ttl 64, id 64318, offset 0, flags [DF], proto TCP (6), length 40) mini2.home.fischer-net.net.60975 > imap.strato.de.imaps: Flags [.], cksum 0x4c3a (incorrect -> 0xd50a), seq 780, ack 4535, win 33380, length 0 19:10:48.624932 IP (tos 0x0, ttl 64, id 12889, offset 0, flags [DF], proto TCP (6), length 71) mini2.home.fischer-net.net.60975 > imap.strato.de.imaps: Flags [P.], cksum 0x4c59 (incorrect -> 0xfd06), seq 780:811, ack 4535, win 33396, length 31 19:10:48.646571 IP (tos 0x0, ttl 248, id 18517, offset 0, flags [DF], proto TCP (6), length 40) imap.strato.de.imaps > mini2.home.fischer-net.net.60975: Flags [R.], cksum 0x574c (correct), seq 4535, ack 811, win 0, length 0 19:11:49.041641 IP (tos 0x0, ttl 64, id 1235, offset 0, flags [DF], proto TCP (6), length 64) mini2.home.fischer-net.net.61035 > imap.strato.de.imaps: Flags [S], cksum 0x4c52 (incorrect -> 0x0b3e), seq 771336041, win 65535, options [mss 1460,nop,wscale 1,nop,nop,TS val 1029692052 ecr 0,sackOK,eol], length 0 19:11:49.063272 IP (tos 0x0, ttl 248, id 26043, offset 0, flags [DF], proto TCP (6), length 52) imap.strato.de.imaps > mini2.home.fischer-net.net.61035: Flags [S.], cksum 0x1718 (correct), seq 2700448559, ack 771336042, win 4356, options [mss 1452,nop,wscale 0,sackOK,eol], length 0 ----- Now for me looks like the issue is, fetchmail opens the Socket for the SSL Session without a TCP KeepAlive. When I use an unencrypted imap session, the TCP KeepAlive is active. The tcpdump shows the TCP KeepAlive packets during the imap idle time. Best Regards, Wolfgang ------------------------------------------------------- Date: 2013-Jan-03 23:02 By: m-a Comment: Have Strato fix their server timeouts instead, the 30 minute timer is a "MUST" clause in RFC-3501 section 5.4, see http://tools.ietf.org/html/rfc3501#section-5.4 If there is a socket timeout, I'd like to see an strace or truss trace proving it, and possibly an accompanying tcpdump or wireshark/tshark dump of the protocol with timestamps, to see when the connection gets closed. Chances are that there is a problem on your end - are you using IPv4 NAT or Masquerading? ------------------------------------------------------- For detailed info, follow this link: http://developer.berlios.de/bugs/?func=detailbug&bug_id=18853&group_id=1824 |
From: Matthias A. <mat...@gm...> - 2013-12-11 00:43:19
|
I am sending a copy to fetchmail-users because this is of general interest, and also a recurring issue with Google Mail. Am 15.11.2013 16:02, schrieb Joe M: > Hello Matthias, > > I am missing emails. Is there anyway to correlate the id's from > .fetchids with the email in the gmail inbox? > > I tried both pop and imap and in both instances, a few emails were not > downloaded. > > I tried with --uidl and no --startnum. > >>> As an update, I just polled my pop3.live.com accounts and figured that >>> --uidl works for me on that account. Note that using --keep without >>> --uidl is a dangerous endeavor, meaning that if you use LAST or a >>> locally recorded message number, this setup is prone to mail loss or >>> skipping, should messages before the designated start number disappear >>> or should a downloaded message fail to be forwarded. >> >> This seems to have happened and I did not get your email. > > Any thoughts, please? Sorry for the late response, somehow missed your followup. Up front: gmail is quirky by design. Google did not model traditional mailboxes for POP3 or IMAP, but invented their own stuff around archiving and folders, and to add insult to injury, some of their help pages defame POP3 as unreliable when the fault lies with implementations, not the protocol. POP3 + UIDL can be made reliable - if you don't abuse it, that is. Still, I link to Google documentation (apparently the first two links now redirect to the same contents): <http://www.fetchmail.info/fetchmail-FAQ.html#I9> has a few links to Google documentation - check the "recent:" trick described there and see if that helps. <https://support.google.com/mail/answer/47948?hl=en> in particular explains that. The correlation between UIDs and messages is technically possible but yields only the POP3 message numbers for the .fetchids stored - and message numbers can change with every login (especially as messages are removed, or sometimes added, example below), and are therefore not really useful in your situation. If you still want to see them, all it takes is running fetchmail with -vv added on the command line. This logs the transcript of the POP3 exchange, which might look like this (this is from a Dovecot POP3 server, not from Gmail's POP3 interface): > fetchmail: POP3> USER joe > fetchmail: POP3< +OK > fetchmail: POP3> PASS * > fetchmail: POP3< +OK Logged in. > fetchmail: POP3> STAT > fetchmail: POP3< +OK 1314 77621905 > fetchmail: POP3> UIDL > fetchmail: POP3< +OK > fetchmail: POP3< 1 000000014eb1c89a > fetchmail: POP3< 2 000000034eb1c89a > fetchmail: POP3< 3 000000054eb1c89a > fetchmail: POP3< 4 000000064eb1c89a > fetchmail: POP3< 5 000000074eb1c89a ... That's all there is. You get a temporary message number (which is a count that may occasionally skip ahead over deleted messages) and the UID that you would also find in .fetchids after successful fetch + shipping. Deleting message 2 would then remove the 000000034eb1c89a, and on the next login you'd see the output below, so for 000000054eb1c89a the message number changed from 3 to 2. > fetchmail: POP3< 1 000000014eb1c89a > fetchmail: POP3< 2 000000054eb1c89a > fetchmail: POP3< 3 000000064eb1c89a > fetchmail: POP3< 4 000000074eb1c89a As said above, this is not very useful to hunt down missing messages. The best bet, given Google's documentation, would probably be to try reconfiguring your user name for Google's recent: mode, and run fetchmail with a --fetchall --keep --uidl once. That may cause duplicate message retrieval due to --fetchall, but better duplicate than none. |
From: Joe M <joe...@gm...> - 2013-11-15 16:02:23
|
Hello Matthias, I am missing emails. Is there anyway to correlate the id's from .fetchids with the email in the gmail inbox? I tried both pop and imap and in both instances, a few emails were not downloaded. I tried with --uidl and no --startnum. >> As an update, I just polled my pop3.live.com accounts and figured that >> --uidl works for me on that account. Note that using --keep without >> --uidl is a dangerous endeavor, meaning that if you use LAST or a >> locally recorded message number, this setup is prone to mail loss or >> skipping, should messages before the designated start number disappear >> or should a downloaded message fail to be forwarded. > > This seems to have happened and I did not get your email. Any thoughts, please? Thanks Joe |
From: Joe M <joe...@gm...> - 2013-11-15 15:59:38
|
I inadvertently forwarded the below email to Mr. Matthias instead of the list. Hence, sending to the list now. ---------- Forwarded message ---------- From: Joe M <joe...@gm...> Date: Thu, Nov 14, 2013 at 8:36 PM Subject: Re: [fetchmail-devel] Fwd: fetchmail downloading with message number as a parameter To: Matthias Andree <mat...@gm...> Hello Matthias, > As an update, I just polled my pop3.live.com accounts and figured that > --uidl works for me on that account. Note that using --keep without > --uidl is a dangerous endeavor, meaning that if you use LAST or a > locally recorded message number, this setup is prone to mail loss or > skipping, should messages before the designated start number disappear > or should a downloaded message fail to be forwarded. This seems to have happened and I did not get your email. > That comment above does not rule out my taking your patch, it may be > useful to re-setup things if the UID database should ever get damaged > (although I have not had reports of corruption of the .fetchids file in > a long time), we may however need to extend your patch so that if you > say "--startnum 1001", fetchmail could optionally record the first 1000 > POP3 UIDs as seen. > > > Hope that passes for a comment for the nonce :-) Thanks for responding. It makes sense to use --uidl. I was downloading from multiple email accounts with different fetchmailrc (but, did not change the FETCHMAILHOME) and I guess the .fetchids was getting overwritten or something like that. Hence, I thought that there was no such functionality in fetchmail. > Thanks again! Thank you and Sorry for the delay. Thanks again, Joe |
From: Matthias A. <mat...@gm...> - 2013-11-12 10:28:30
|
Am 12.11.2013 10:20, schrieb Matthias Andree: > Am 12.11.2013 06:51, schrieb Joe M: >> Joe M wrote: >>> I am attaching a patch to add a --startnum option to fetchmail. >> >> Attached is an updated patch which adds this option to fetchmail.man >> >> Any comments, please? >> >> Thanks >> Joe > > Joe, > > thanks a bunch for your contribution. > > I am only wondering what limitations of either hotmail or your SMTP sink > this is trying to work around that are not already solved -- and if it > will remain useful at all for 7.x when make UIDL support mandatory. The > code is there, on the "master" branch in Git. > > The URL is https://gitorious.org/fetchmail/fetchmail/ > > Would you be able to check if the code is fit for fetchmail's master branch? > > Thank you. > > Best regards > Matthias Joe, As an update, I just polled my pop3.live.com accounts and figured that --uidl works for me on that account. Note that using --keep without --uidl is a dangerous endeavor, meaning that if you use LAST or a locally recorded message number, this setup is prone to mail loss or skipping, should messages before the designated start number disappear or should a downloaded message fail to be forwarded. That comment above does not rule out my taking your patch, it may be useful to re-setup things if the UID database should ever get damaged (although I have not had reports of corruption of the .fetchids file in a long time), we may however need to extend your patch so that if you say "--startnum 1001", fetchmail could optionally record the first 1000 POP3 UIDs as seen. Hope that passes for a comment for the nonce :-) Thanks again! Best regards Matthias |
From: Matthias A. <mat...@gm...> - 2013-11-12 10:20:03
|
Am 12.11.2013 06:51, schrieb Joe M: > Joe M wrote: >> I am attaching a patch to add a --startnum option to fetchmail. > > Attached is an updated patch which adds this option to fetchmail.man > > Any comments, please? > > Thanks > Joe Joe, thanks a bunch for your contribution. I am only wondering what limitations of either hotmail or your SMTP sink this is trying to work around that are not already solved -- and if it will remain useful at all for 7.x when make UIDL support mandatory. The code is there, on the "master" branch in Git. The URL is https://gitorious.org/fetchmail/fetchmail/ Would you be able to check if the code is fit for fetchmail's master branch? Thank you. Best regards Matthias |
From: Joe M <joe...@gm...> - 2013-11-12 07:41:03
|
> Joe M wrote: > > I am attaching a patch to add a --startnum option to fetchmail. > > Attached is an updated patch which adds this option to fetchmail.man Attached is the updated patch fixing a compilation issue and it seems to be working when I test it. Below is output from my test run: FETCHMAILHOME=/home/j/etc/mail/username/ fetchmail --fetchmailrc ~/etc/mail/username/fetchmailrc --verbose -B 30 --startnum 302 fetchmail: 6.3.26 querying pop3.live.com (protocol POP3) at Tue 12 Nov 2013 12:27:44 AM CST: poll started Trying to connect to 65.54.51.39/995...connected. fetchmail: Server certificate: fetchmail: Issuer Organization: GlobalSign nv-sa fetchmail: Issuer CommonName: GlobalSign Organization Validation CA - G2 fetchmail: Subject CommonName: *.hotmail.com fetchmail: Subject Alternative Name: *.hotmail.com fetchmail: Subject Alternative Name: *.live.com fetchmail: Subject Alternative Name: *.outlook.com fetchmail: Subject Alternative Name: hotmail.com fetchmail: pop3.live.com key fingerprint: 86:60:F6:38:1C:84:A6:AC:94:92:51:2F:67:9A:7D:76 fetchmail: POP3< +OK snt0-pop60 POP3 server ready fetchmail: POP3> CAPA fetchmail: POP3< -ERR unrecognized command fetchmail: unrecognized command fetchmail: Repoll immediately on use...@ho...@pop3.glbdns2.microsoft.com Trying to connect to 65.54.51.39/995...connected. fetchmail: Server certificate: fetchmail: Issuer Organization: GlobalSign nv-sa fetchmail: Issuer CommonName: GlobalSign Organization Validation CA - G2 fetchmail: Subject CommonName: *.hotmail.com fetchmail: Subject Alternative Name: *.hotmail.com fetchmail: Subject Alternative Name: *.live.com fetchmail: Subject Alternative Name: *.outlook.com fetchmail: Subject Alternative Name: hotmail.com fetchmail: pop3.live.com key fingerprint: 86:60:F6:38:1C:84:A6:AC:94:92:51:2F:67:9A:7D:76 fetchmail: POP3< +OK snt0-pop125 POP3 server ready fetchmail: POP3> USER use...@ho... fetchmail: POP3< +OK password required fetchmail: POP3> PASS * fetchmail: POP3< +OK mailbox has 2521 messages fetchmail: POP3> STAT fetchmail: POP3< +OK 2521 503162348 2521 messages for use...@ho... at pop3.live.com (503162348 octets). fetchmail: POP3> LIST 302 fetchmail: POP3< +OK 302 10944 fetchmail: POP3> RETR 302 fetchmail: POP3< +OK reading message use...@ho...@pop3.glbdns2.microsoft.com:302 of 2521 (10944 octets) #*****************************************.******************************************* ***.**********************************.************************************.*************************.***************************.***************************.*********************** *.**************************.************* not flushed fetchmail: POP3> LIST 303 fetchmail: POP3< +OK 303 5596 fetchmail: POP3> RETR 303 fetchmail: POP3< +OK reading message use...@ho...@pop3.glbdns2.microsoft.com:303 of 2521 (5596 octets) #************************************.*****************************************.******* **********************************.********************************.****************** Thanks Joe |