a8e4fd07f9
- Fix fetchmailconf to compile with python{2,3} [bsc#1082694] OBS-URL: https://build.opensuse.org/request/show/587587 OBS-URL: https://build.opensuse.org/package/show/server:mail/fetchmail?expand=0&rev=82
3075 lines
126 KiB
Diff
3075 lines
126 KiB
Diff
From 2a23b1b8f3f8d73ba65f2109b0b496bc3d13f59a Mon Sep 17 00:00:00 2001
|
|
From: Samuel Martin <s.martin49@gmail.com>
|
|
Date: Wed, 8 Jun 2016 21:36:28 +0200
|
|
Subject: [PATCH] fetchmailconf.py: fix tabs/spaces mixup preventing from compiling the pyc module
|
|
|
|
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.martin49@gmail.com>
|
|
Signed-off-by: Matthias Andree <matthias.andree@gmx.de>
|
|
---
|
|
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()
|
|
+ self.destruct()
|
|
|
|
#
|
|
# Server editing stuff.
|
|
@@ -1063,217 +1063,217 @@ user's options on that site.
|
|
|
|
class ServerEdit(Frame, MyWidget):
|
|
def __init__(self, host, parent):
|
|
- self.parent = parent
|
|
- self.server = None
|
|
- self.subwidgets = {}
|
|
- for site in parent.configuration.servers:
|
|
- if site.pollname == host:
|
|
- self.server = site
|
|
- if (self.server == None):
|
|
- self.server = Server()
|
|
- self.server.pollname = host
|
|
- self.server.via = None
|
|
- parent.configuration.servers.append(self.server)
|
|
+ self.parent = parent
|
|
+ self.server = None
|
|
+ self.subwidgets = {}
|
|
+ for site in parent.configuration.servers:
|
|
+ if site.pollname == host:
|
|
+ self.server = site
|
|
+ if (self.server == None):
|
|
+ self.server = Server()
|
|
+ self.server.pollname = host
|
|
+ self.server.via = None
|
|
+ parent.configuration.servers.append(self.server)
|
|
|
|
def edit(self, mode, master=None):
|
|
- Frame.__init__(self, master)
|
|
- Pack.config(self)
|
|
- self.master.title('Fetchmail host ' + self.server.pollname);
|
|
- self.master.iconname('Fetchmail host ' + self.server.pollname);
|
|
- self.post(Server, 'server')
|
|
- self.makeWidgets(self.server.pollname, mode)
|
|
- self.keepalive = [] # Use this to anchor the PhotoImage object
|
|
- make_icon_window(self, fetchmail_icon)
|
|
+ Frame.__init__(self, master)
|
|
+ Pack.config(self)
|
|
+ self.master.title('Fetchmail host ' + self.server.pollname);
|
|
+ self.master.iconname('Fetchmail host ' + self.server.pollname);
|
|
+ self.post(Server, 'server')
|
|
+ self.makeWidgets(self.server.pollname, mode)
|
|
+ self.keepalive = [] # Use this to anchor the PhotoImage object
|
|
+ make_icon_window(self, fetchmail_icon)
|
|
# self.grab_set()
|
|
# self.focus_set()
|
|
# self.wait_window()
|
|
- return self
|
|
+ return self
|
|
|
|
def destruct(self):
|
|
- for username in self.subwidgets.keys():
|
|
- self.subwidgets[username].destruct()
|
|
- del self.parent.subwidgets[self.server.pollname]
|
|
- self.master.destroy()
|
|
+ for username in self.subwidgets.keys():
|
|
+ self.subwidgets[username].destruct()
|
|
+ del self.parent.subwidgets[self.server.pollname]
|
|
+ self.master.destroy()
|
|
|
|
def nosave(self):
|
|
- if ConfirmQuit(self, 'server option editing'):
|
|
- self.destruct()
|
|
+ if ConfirmQuit(self, 'server option editing'):
|
|
+ self.destruct()
|
|
|
|
def save(self):
|
|
- self.fetch(Server, 'server')
|
|
- for username in self.subwidgets.keys():
|
|
- self.subwidgets[username].save()
|
|
- self.destruct()
|
|
+ self.fetch(Server, 'server')
|
|
+ for username in self.subwidgets.keys():
|
|
+ self.subwidgets[username].save()
|
|
+ self.destruct()
|
|
|
|
def defaultPort(self):
|
|
- proto = self.protocol.get()
|
|
- # Callback to reset the port number whenever the protocol type changes.
|
|
- # We used to only reset the port if it had a default (zero) value.
|
|
- # This turns out to be a bad idea especially in Novice mode -- if
|
|
- # you set POP3 and then set IMAP, the port invisibly remained 110.
|
|
- # Now we reset unconditionally on the theory that if you're setting
|
|
- # a custom port number you should be in expert mode and playing
|
|
- # close enough attention to notice this...
|
|
- self.service.set(defaultports[proto])
|
|
- if not proto in ("POP3", "APOP", "KPOP"): self.uidl.state = DISABLED
|
|
+ proto = self.protocol.get()
|
|
+ # Callback to reset the port number whenever the protocol type changes.
|
|
+ # We used to only reset the port if it had a default (zero) value.
|
|
+ # This turns out to be a bad idea especially in Novice mode -- if
|
|
+ # you set POP3 and then set IMAP, the port invisibly remained 110.
|
|
+ # Now we reset unconditionally on the theory that if you're setting
|
|
+ # a custom port number you should be in expert mode and playing
|
|
+ # close enough attention to notice this...
|
|
+ self.service.set(defaultports[proto])
|
|
+ if not proto in ("POP3", "APOP", "KPOP"): self.uidl.state = DISABLED
|
|
|
|
def user_edit(self, username, mode):
|
|
- self.subwidgets[username] = UserEdit(username, self).edit(mode, Toplevel())
|
|
+ self.subwidgets[username] = UserEdit(username, self).edit(mode, Toplevel())
|
|
|
|
def user_delete(self, username):
|
|
- if self.subwidgets.has_key(username):
|
|
- self.subwidgets[username].destruct()
|
|
- del self.server[username]
|
|
+ if self.subwidgets.has_key(username):
|
|
+ self.subwidgets[username].destruct()
|
|
+ del self.server[username]
|
|
|
|
def makeWidgets(self, host, mode):
|
|
- topwin = dispose_window(self, "Server options for querying " + host, serverhelp)
|
|
-
|
|
- leftwin = Frame(self);
|
|
- leftwidth = '25';
|
|
-
|
|
- if mode != 'novice':
|
|
- ctlwin = Frame(leftwin, relief=RAISED, bd=5)
|
|
- Label(ctlwin, text="Run Controls").pack(side=TOP)
|
|
- Checkbutton(ctlwin, text='Poll ' + host + ' normally?', variable=self.active).pack(side=TOP)
|
|
- Checkbutton(ctlwin, text='Pass messages with bad headers?',
|
|
- variable=self.badheader).pack(side=TOP)
|
|
- LabeledEntry(ctlwin, 'True name of ' + host + ':',
|
|
- self.via, leftwidth).pack(side=TOP, fill=X)
|
|
- LabeledEntry(ctlwin, 'Cycles to skip between polls:',
|
|
- self.interval, leftwidth).pack(side=TOP, fill=X)
|
|
- LabeledEntry(ctlwin, 'Server timeout (seconds):',
|
|
- self.timeout, leftwidth).pack(side=TOP, fill=X)
|
|
- Button(ctlwin, text='Help', fg='blue',
|
|
- command=lambda: helpwin(controlhelp)).pack(side=RIGHT)
|
|
- ctlwin.pack(fill=X)
|
|
-
|
|
- # Compute the available protocols from the compile-time options
|
|
- protolist = ['auto']
|
|
- if 'pop2' in feature_options:
|
|
- protolist.append("POP2")
|
|
- if 'pop3' in feature_options:
|
|
- protolist = protolist + ["POP3", "APOP", "KPOP"]
|
|
- if 'sdps' in feature_options:
|
|
- protolist.append("SDPS")
|
|
- if 'imap' in feature_options:
|
|
- protolist.append("IMAP")
|
|
- if 'etrn' in feature_options:
|
|
- protolist.append("ETRN")
|
|
- if 'odmr' in feature_options:
|
|
- protolist.append("ODMR")
|
|
-
|
|
- protwin = Frame(leftwin, relief=RAISED, bd=5)
|
|
- Label(protwin, text="Protocol").pack(side=TOP)
|
|
- ButtonBar(protwin, '',
|
|
- self.protocol, protolist, 2,
|
|
- self.defaultPort)
|
|
- if mode != 'novice':
|
|
- LabeledEntry(protwin, 'On server TCP/IP service:',
|
|
- self.service, leftwidth).pack(side=TOP, fill=X)
|
|
- self.defaultPort()
|
|
- Checkbutton(protwin,
|
|
- text="POP3: track `seen' with client-side UIDLs?",
|
|
- variable=self.uidl).pack(side=TOP)
|
|
- Button(protwin, text='Probe for supported protocols', fg='blue',
|
|
- command=self.autoprobe).pack(side=LEFT)
|
|
- Button(protwin, text='Help', fg='blue',
|
|
- command=lambda: helpwin(protohelp)).pack(side=RIGHT)
|
|
- protwin.pack(fill=X)
|
|
-
|
|
- userwin = Frame(leftwin, relief=RAISED, bd=5)
|
|
- Label(userwin, text="User entries for " + host).pack(side=TOP)
|
|
- ListEdit("New user: ",
|
|
- map(lambda x: x.remote, self.server.users),
|
|
- lambda u, m=mode, s=self: s.user_edit(u, m),
|
|
- lambda u, s=self: s.user_delete(u),
|
|
- userwin, suserhelp)
|
|
- userwin.pack(fill=X)
|
|
-
|
|
- leftwin.pack(side=LEFT, anchor=N, fill=X);
|
|
-
|
|
- if mode != 'novice':
|
|
- rightwin = Frame(self);
|
|
-
|
|
- mdropwin = Frame(rightwin, relief=RAISED, bd=5)
|
|
- Label(mdropwin, text="Multidrop options").pack(side=TOP)
|
|
- LabeledEntry(mdropwin, 'Envelope address header:',
|
|
- self.envelope, '22').pack(side=TOP, fill=X)
|
|
- LabeledEntry(mdropwin, 'Envelope headers to skip:',
|
|
- self.envskip, '22').pack(side=TOP, fill=X)
|
|
- LabeledEntry(mdropwin, 'Name prefix to strip:',
|
|
- self.qvirtual, '22').pack(side=TOP, fill=X)
|
|
- Checkbutton(mdropwin, text="Enable multidrop DNS lookup?",
|
|
- variable=self.dns).pack(side=TOP)
|
|
- Label(mdropwin, text="DNS aliases").pack(side=TOP)
|
|
- ListEdit("New alias: ", self.server.aka, None, None, mdropwin, None)
|
|
- Label(mdropwin, text="Domains to be considered local").pack(side=TOP)
|
|
- ListEdit("New domain: ",
|
|
- self.server.localdomains, None, None, mdropwin, multihelp)
|
|
- mdropwin.pack(fill=X)
|
|
-
|
|
- if os_type in ('linux', 'freebsd'):
|
|
- secwin = Frame(rightwin, relief=RAISED, bd=5)
|
|
- Label(secwin, text="Security").pack(side=TOP)
|
|
- # Don't actually let users set this. KPOP sets it implicitly
|
|
- ButtonBar(secwin, 'Authorization mode:',
|
|
- self.auth, authlist, 2, None).pack(side=TOP)
|
|
- if os_type == 'linux' or os_type == 'freebsd' or 'interface' in dictmembers:
|
|
- LabeledEntry(secwin, 'IP range to check before poll:',
|
|
- self.interface, leftwidth).pack(side=TOP, fill=X)
|
|
- if os_type == 'linux' or os_type == 'freebsd' or 'monitor' in dictmembers:
|
|
- LabeledEntry(secwin, 'Interface to monitor:',
|
|
- self.monitor, leftwidth).pack(side=TOP, fill=X)
|
|
- # Someday this should handle Kerberos 5 too
|
|
- if 'kerberos' in feature_options:
|
|
- LabeledEntry(secwin, 'Principal:',
|
|
- self.principal, '12').pack(side=TOP, fill=X)
|
|
- # ESMTP authentication
|
|
- LabeledEntry(secwin, 'ESMTP name:',
|
|
- self.esmtpname, '12').pack(side=TOP, fill=X)
|
|
- LabeledEntry(secwin, 'ESMTP password:',
|
|
- self.esmtppassword, '12').pack(side=TOP, fill=X)
|
|
- Button(secwin, text='Help', fg='blue',
|
|
- command=lambda: helpwin(sechelp)).pack(side=RIGHT)
|
|
- secwin.pack(fill=X)
|
|
-
|
|
- rightwin.pack(side=LEFT, anchor=N);
|
|
+ topwin = dispose_window(self, "Server options for querying " + host, serverhelp)
|
|
+
|
|
+ leftwin = Frame(self);
|
|
+ leftwidth = '25';
|
|
+
|
|
+ if mode != 'novice':
|
|
+ ctlwin = Frame(leftwin, relief=RAISED, bd=5)
|
|
+ Label(ctlwin, text="Run Controls").pack(side=TOP)
|
|
+ Checkbutton(ctlwin, text='Poll ' + host + ' normally?', variable=self.active).pack(side=TOP)
|
|
+ Checkbutton(ctlwin, text='Pass messages with bad headers?',
|
|
+ variable=self.badheader).pack(side=TOP)
|
|
+ LabeledEntry(ctlwin, 'True name of ' + host + ':',
|
|
+ self.via, leftwidth).pack(side=TOP, fill=X)
|
|
+ LabeledEntry(ctlwin, 'Cycles to skip between polls:',
|
|
+ self.interval, leftwidth).pack(side=TOP, fill=X)
|
|
+ LabeledEntry(ctlwin, 'Server timeout (seconds):',
|
|
+ self.timeout, leftwidth).pack(side=TOP, fill=X)
|
|
+ Button(ctlwin, text='Help', fg='blue',
|
|
+ command=lambda: helpwin(controlhelp)).pack(side=RIGHT)
|
|
+ ctlwin.pack(fill=X)
|
|
+
|
|
+ # Compute the available protocols from the compile-time options
|
|
+ protolist = ['auto']
|
|
+ if 'pop2' in feature_options:
|
|
+ protolist.append("POP2")
|
|
+ if 'pop3' in feature_options:
|
|
+ protolist = protolist + ["POP3", "APOP", "KPOP"]
|
|
+ if 'sdps' in feature_options:
|
|
+ protolist.append("SDPS")
|
|
+ if 'imap' in feature_options:
|
|
+ protolist.append("IMAP")
|
|
+ if 'etrn' in feature_options:
|
|
+ protolist.append("ETRN")
|
|
+ if 'odmr' in feature_options:
|
|
+ protolist.append("ODMR")
|
|
+
|
|
+ protwin = Frame(leftwin, relief=RAISED, bd=5)
|
|
+ Label(protwin, text="Protocol").pack(side=TOP)
|
|
+ ButtonBar(protwin, '',
|
|
+ self.protocol, protolist, 2,
|
|
+ self.defaultPort)
|
|
+ if mode != 'novice':
|
|
+ LabeledEntry(protwin, 'On server TCP/IP service:',
|
|
+ self.service, leftwidth).pack(side=TOP, fill=X)
|
|
+ self.defaultPort()
|
|
+ Checkbutton(protwin,
|
|
+ text="POP3: track `seen' with client-side UIDLs?",
|
|
+ variable=self.uidl).pack(side=TOP)
|
|
+ Button(protwin, text='Probe for supported protocols', fg='blue',
|
|
+ command=self.autoprobe).pack(side=LEFT)
|
|
+ Button(protwin, text='Help', fg='blue',
|
|
+ command=lambda: helpwin(protohelp)).pack(side=RIGHT)
|
|
+ protwin.pack(fill=X)
|
|
+
|
|
+ userwin = Frame(leftwin, relief=RAISED, bd=5)
|
|
+ Label(userwin, text="User entries for " + host).pack(side=TOP)
|
|
+ ListEdit("New user: ",
|
|
+ map(lambda x: x.remote, self.server.users),
|
|
+ lambda u, m=mode, s=self: s.user_edit(u, m),
|
|
+ lambda u, s=self: s.user_delete(u),
|
|
+ userwin, suserhelp)
|
|
+ userwin.pack(fill=X)
|
|
+
|
|
+ leftwin.pack(side=LEFT, anchor=N, fill=X);
|
|
+
|
|
+ if mode != 'novice':
|
|
+ rightwin = Frame(self);
|
|
+
|
|
+ mdropwin = Frame(rightwin, relief=RAISED, bd=5)
|
|
+ Label(mdropwin, text="Multidrop options").pack(side=TOP)
|
|
+ LabeledEntry(mdropwin, 'Envelope address header:',
|
|
+ self.envelope, '22').pack(side=TOP, fill=X)
|
|
+ LabeledEntry(mdropwin, 'Envelope headers to skip:',
|
|
+ self.envskip, '22').pack(side=TOP, fill=X)
|
|
+ LabeledEntry(mdropwin, 'Name prefix to strip:',
|
|
+ self.qvirtual, '22').pack(side=TOP, fill=X)
|
|
+ Checkbutton(mdropwin, text="Enable multidrop DNS lookup?",
|
|
+ variable=self.dns).pack(side=TOP)
|
|
+ Label(mdropwin, text="DNS aliases").pack(side=TOP)
|
|
+ ListEdit("New alias: ", self.server.aka, None, None, mdropwin, None)
|
|
+ Label(mdropwin, text="Domains to be considered local").pack(side=TOP)
|
|
+ ListEdit("New domain: ",
|
|
+ self.server.localdomains, None, None, mdropwin, multihelp)
|
|
+ mdropwin.pack(fill=X)
|
|
+
|
|
+ if os_type in ('linux', 'freebsd'):
|
|
+ secwin = Frame(rightwin, relief=RAISED, bd=5)
|
|
+ Label(secwin, text="Security").pack(side=TOP)
|
|
+ # Don't actually let users set this. KPOP sets it implicitly
|
|
+ ButtonBar(secwin, 'Authorization mode:',
|
|
+ self.auth, authlist, 2, None).pack(side=TOP)
|
|
+ if os_type == 'linux' or os_type == 'freebsd' or 'interface' in dictmembers:
|
|
+ LabeledEntry(secwin, 'IP range to check before poll:',
|
|
+ self.interface, leftwidth).pack(side=TOP, fill=X)
|
|
+ if os_type == 'linux' or os_type == 'freebsd' or 'monitor' in dictmembers:
|
|
+ LabeledEntry(secwin, 'Interface to monitor:',
|
|
+ self.monitor, leftwidth).pack(side=TOP, fill=X)
|
|
+ # Someday this should handle Kerberos 5 too
|
|
+ if 'kerberos' in feature_options:
|
|
+ LabeledEntry(secwin, 'Principal:',
|
|
+ self.principal, '12').pack(side=TOP, fill=X)
|
|
+ # ESMTP authentication
|
|
+ LabeledEntry(secwin, 'ESMTP name:',
|
|
+ self.esmtpname, '12').pack(side=TOP, fill=X)
|
|
+ LabeledEntry(secwin, 'ESMTP password:',
|
|
+ self.esmtppassword, '12').pack(side=TOP, fill=X)
|
|
+ Button(secwin, text='Help', fg='blue',
|
|
+ command=lambda: helpwin(sechelp)).pack(side=RIGHT)
|
|
+ secwin.pack(fill=X)
|
|
+
|
|
+ rightwin.pack(side=LEFT, anchor=N);
|
|
|
|
def autoprobe(self):
|
|
- # Note: this only handles case (1) near fetchmail.c:1032
|
|
- # We're assuming people smart enough to set up ssh tunneling
|
|
- # won't need autoprobing.
|
|
- if self.server.via:
|
|
- realhost = self.server.via
|
|
- else:
|
|
- realhost = self.server.pollname
|
|
- greetline = None
|
|
- for protocol in ("IMAP","POP3","POP2"):
|
|
- service = defaultports[protocol]
|
|
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
- try:
|
|
- sock.connect((realhost, ianaservices[service]))
|
|
- greetline = sock.recv(1024)
|
|
- sock.close()
|
|
- except:
|
|
- pass
|
|
- else:
|
|
- break
|
|
- confwin = Toplevel()
|
|
- if greetline == None:
|
|
- title = "Autoprobe of " + realhost + " failed"
|
|
- confirm = """
|
|
+ # Note: this only handles case (1) near fetchmail.c:1032
|
|
+ # We're assuming people smart enough to set up ssh tunneling
|
|
+ # won't need autoprobing.
|
|
+ if self.server.via:
|
|
+ realhost = self.server.via
|
|
+ else:
|
|
+ realhost = self.server.pollname
|
|
+ greetline = None
|
|
+ for protocol in ("IMAP","POP3","POP2"):
|
|
+ service = defaultports[protocol]
|
|
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
+ try:
|
|
+ sock.connect((realhost, ianaservices[service]))
|
|
+ greetline = sock.recv(1024)
|
|
+ sock.close()
|
|
+ except:
|
|
+ pass
|
|
+ else:
|
|
+ break
|
|
+ confwin = Toplevel()
|
|
+ if greetline == None:
|
|
+ title = "Autoprobe of " + realhost + " failed"
|
|
+ confirm = """
|
|
Fetchmailconf didn't find any mailservers active.
|
|
This could mean the host doesn't support any,
|
|
or that your Internet connection is down, or
|
|
that the host is so slow that the probe timed
|
|
out before getting a response.
|
|
"""
|
|
- else:
|
|
- warnings = ''
|
|
- # OK, now try to recognize potential problems
|
|
+ else:
|
|
+ warnings = ''
|
|
+ # OK, now try to recognize potential problems
|
|
|
|
- if protocol == "POP2":
|
|
- warnings = warnings + """
|
|
+ if protocol == "POP2":
|
|
+ warnings = warnings + """
|
|
It appears you have somehow found a mailserver running only POP2.
|
|
Congratulations. Have you considered a career in archaeology?
|
|
|
|
@@ -1286,8 +1286,8 @@ switch --enable-POP2.
|
|
|
|
### POP3 servers start here
|
|
|
|
- if string.find(greetline, "1.003") > 0 or string.find(greetline, "1.004") > 0:
|
|
- warnings = warnings + """
|
|
+ if string.find(greetline, "1.003") > 0 or string.find(greetline, "1.004") > 0:
|
|
+ warnings = warnings + """
|
|
This appears to be an old version of the UC Davis POP server. These are
|
|
dangerously unreliable (among other problems, they may drop your mailbox
|
|
on the floor if your connection is interrupted during the session).
|
|
@@ -1296,8 +1296,8 @@ It is strongly recommended that you find a better POP3 server. The fetchmail
|
|
FAQ includes pointers to good ones.
|
|
|
|
"""
|
|
- if string.find(greetline, "comcast.net") > 0:
|
|
- warnings = warnings + """
|
|
+ if string.find(greetline, "comcast.net") > 0:
|
|
+ warnings = warnings + """
|
|
The Comcast Maillennium POP3 server only returns the first 80K of a long
|
|
message retrieved with TOP. Its response to RETR is normal, so use the
|
|
`fetchall' option.
|
|
@@ -1321,8 +1321,8 @@ message retrieved with TOP. Its response to RETR is normal, so use the
|
|
#
|
|
# +OK Cubic Circle's v1.31 1998/05/13 POP3 ready <6229000062f95036@wakko>
|
|
#
|
|
- if string.find(greetline, "Cubic Circle") > 0:
|
|
- warnings = warnings + """
|
|
+ if string.find(greetline, "Cubic Circle") > 0:
|
|
+ warnings = warnings + """
|
|
I see your server is running cucipop. Better make sure the server box
|
|
isn't a SunOS 4.1.4 machine; cucipop tickles a bug in SunOS realloc()
|
|
under that version, and doesn't cope with the result gracefully. Newer
|
|
@@ -1332,8 +1332,8 @@ Also, some versions of cucipop don't assert an exclusive lock on your
|
|
mailbox when it's being queried. This means that if you have more than
|
|
one fetchmail query running against the same mailbox, bad things can happen.
|
|
"""
|
|
- if string.find(greetline, "David POP3 Server") > 0:
|
|
- warnings = warnings + """
|
|
+ if string.find(greetline, "David POP3 Server") > 0:
|
|
+ warnings = warnings + """
|
|
This POP3 server is badly broken. You should get rid of it -- and the
|
|
brain-dead Microsoft operating system it rode in on.
|
|
|
|
@@ -1341,20 +1341,20 @@ brain-dead Microsoft operating system it rode in on.
|
|
# The greeting line on the server known to be buggy is:
|
|
# +OK POP3 server ready (running FTGate V2, 2, 1, 0 Jun 21 1999 09:55:01)
|
|
#
|
|
- if string.find(greetline, "FTGate") > 0:
|
|
- warnings = warnings + """
|
|
+ if string.find(greetline, "FTGate") > 0:
|
|
+ warnings = warnings + """
|
|
This POP server has a weird bug; it says OK twice in response to TOP.
|
|
Its response to RETR is normal, so use the `fetchall' option.
|
|
|
|
"""
|
|
- if string.find(greetline, " geonet.de") > 0:
|
|
- warnings = warnings + """
|
|
+ if string.find(greetline, " geonet.de") > 0:
|
|
+ warnings = warnings + """
|
|
You appear to be using geonet. As of late 2002, the TOP command on
|
|
geonet's POP3 is broken. Use the fetchall option.
|
|
|
|
"""
|
|
- if string.find(greetline, "OpenMail") > 0:
|
|
- warnings = warnings + """
|
|
+ if string.find(greetline, "OpenMail") > 0:
|
|
+ warnings = warnings + """
|
|
You appear to be using some version of HP OpenMail. Many versions of
|
|
OpenMail do not process the "TOP" command correctly; the symptom is that
|
|
only the header and first line of each message is retrieved. To work
|
|
@@ -1362,16 +1362,16 @@ around this bug, turn on `fetchall' on all user entries associated with
|
|
this server.
|
|
|
|
"""
|
|
- if string.find(greetline, "Escape character is") > 0:
|
|
- warnings = warnings + """
|
|
+ if string.find(greetline, "Escape character is") > 0:
|
|
+ warnings = warnings + """
|
|
Your greeting line looks like it was written by a fetid pile of
|
|
camel dung identified to me as `popa3d written by Solar Designer'.
|
|
Beware! The UIDL support in this thing is known to be completely broken,
|
|
and other things probably are too.
|
|
|
|
"""
|
|
- if string.find(greetline, "MercuryP/NLM v1.48") > 0:
|
|
- warnings = warnings + """
|
|
+ if string.find(greetline, "MercuryP/NLM v1.48") > 0:
|
|
+ warnings = warnings + """
|
|
This is not a POP3 server. It has delusions of being one, but after
|
|
RETR all messages are automatically marked to be deleted. The only
|
|
way to prevent this is to issue an RSET before leaving the server.
|
|
@@ -1379,8 +1379,8 @@ Fetchmail does this, but we suspect this is probably broken in lots
|
|
of other ways, too.
|
|
|
|
"""
|
|
- if string.find(greetline, "POP-Max") > 0:
|
|
- warnings = warnings + """
|
|
+ if string.find(greetline, "POP-Max") > 0:
|
|
+ warnings = warnings + """
|
|
The Mail Max POP3 server screws up on mail with attachments. It
|
|
reports the message size with attachments included, but doesn't
|
|
download them on a RETR or TOP (this violates the IMAP RFCs). It also
|
|
@@ -1388,14 +1388,14 @@ doesn't implement TOP correctly. You should get rid of it -- and the
|
|
brain-dead NT server it rode in on.
|
|
|
|
"""
|
|
- if string.find(greetline, "POP3 Server Ready") > 0:
|
|
- warnings = warnings + """
|
|
+ if string.find(greetline, "POP3 Server Ready") > 0:
|
|
+ warnings = warnings + """
|
|
Some server that uses this greeting line has been observed to choke on
|
|
TOP %d 99999999. Use the fetchall option. if necessary, to force RETR.
|
|
|
|
"""
|
|
- if string.find(greetline, "QPOP") > 0:
|
|
- warnings = warnings + """
|
|
+ if string.find(greetline, "QPOP") > 0:
|
|
+ warnings = warnings + """
|
|
This appears to be a version of Eudora qpopper. That's good. Fetchmail
|
|
knows all about qpopper. However, be aware that the 2.53 version of
|
|
qpopper does something odd that causes fetchmail to hang with a socket
|
|
@@ -1404,16 +1404,16 @@ it has been observed with fetchpop. The fix is to upgrade to qpopper
|
|
3.0beta or a more recent version. Better yet, switch to IMAP.
|
|
|
|
"""
|
|
- if string.find(greetline, " sprynet.com") > 0:
|
|
- warnings = warnings + """
|
|
+ if string.find(greetline, " sprynet.com") > 0:
|
|
+ warnings = warnings + """
|
|
You appear to be using a SpryNet server. In mid-1999 it was reported that
|
|
the SpryNet TOP command marks messages seen. Therefore, for proper error
|
|
recovery in the event of a line drop, it is strongly recommended that you
|
|
turn on `fetchall' on all user entries associated with this server.
|
|
|
|
"""
|
|
- if string.find(greetline, "TEMS POP3") > 0:
|
|
- warnings = warnings + """
|
|
+ if string.find(greetline, "TEMS POP3") > 0:
|
|
+ warnings = warnings + """
|
|
Your POP3 server has "TEMS" in its header line. At least one such
|
|
server does not process the "TOP" command correctly; the symptom is
|
|
that fetchmail hangs when trying to retrieve mail. To work around
|
|
@@ -1421,8 +1421,8 @@ this bug, turn on `fetchall' on all user entries associated with this
|
|
server.
|
|
|
|
"""
|
|
- if string.find(greetline, " spray.se") > 0:
|
|
- warnings = warnings + """
|
|
+ if string.find(greetline, " spray.se") > 0:
|
|
+ warnings = warnings + """
|
|
Your POP3 server has "spray.se" in its header line. In May 2000 at
|
|
least one such server did not process the "TOP" command correctly; the
|
|
symptom is that messages are treated as headerless. To work around
|
|
@@ -1430,8 +1430,8 @@ this bug, turn on `fetchall' on all user entries associated with this
|
|
server.
|
|
|
|
"""
|
|
- if string.find(greetline, " usa.net") > 0:
|
|
- warnings = warnings + """
|
|
+ if string.find(greetline, " usa.net") > 0:
|
|
+ warnings = warnings + """
|
|
You appear to be using USA.NET's free mail service. Their POP3 servers
|
|
(at least as of the 2.2 version in use mid-1998) are quite flaky, but
|
|
fetchmail can compensate. They seem to require that fetchall be switched on
|
|
@@ -1444,15 +1444,15 @@ Therefore, it is strongly recommended that you turn on `fetchall' on all
|
|
user entries associated with this server.
|
|
|
|
"""
|
|
- if string.find(greetline, " Novonyx POP3") > 0:
|
|
- warnings = warnings + """
|
|
+ if string.find(greetline, " Novonyx POP3") > 0:
|
|
+ warnings = warnings + """
|
|
Your mailserver is running Novonyx POP3. This server, at least as of
|
|
version 2.17, seems to have problems handling and reporting seen bits.
|
|
You may have to use the fetchall option.
|
|
|
|
"""
|
|
- if string.find(greetline, " IMS POP3") > 0:
|
|
- warnings = warnings + """
|
|
+ if string.find(greetline, " IMS POP3") > 0:
|
|
+ warnings = warnings + """
|
|
Some servers issuing the greeting line 'IMS POP3' have been known to
|
|
do byte-stuffing incorrectly. This means that if a message you receive
|
|
has a . (period) at start of line, fetchmail will become confused and
|
|
@@ -1462,8 +1462,8 @@ probably wedge itself. (This bug was recorded on IMS POP3 0.86.)
|
|
|
|
### IMAP servers start here
|
|
|
|
- if string.find(greetline, "GroupWise") > 0:
|
|
- warnings = warnings + """
|
|
+ if string.find(greetline, "GroupWise") > 0:
|
|
+ warnings = warnings + """
|
|
The Novell GroupWise IMAP server would be better named GroupFoolish;
|
|
it is (according to the designer of IMAP) unusably broken. Among
|
|
other things, it doesn't include a required content length in its
|
|
@@ -1475,8 +1475,8 @@ with code as shoddy as GroupWise seems to be, you will probably pay
|
|
for it with other problems.<p>
|
|
|
|
"""
|
|
- if string.find(greetline, "InterChange") > 0:
|
|
- warnings = warnings + """
|
|
+ if string.find(greetline, "InterChange") > 0:
|
|
+ warnings = warnings + """
|
|
|
|
The InterChange IMAP server at release levels below 3.61.08 screws up
|
|
on mail with attachments. It doesn't fetch them if you give it a
|
|
@@ -1487,16 +1487,16 @@ Exchange (quite legally under RFC2062) rejectsit. The InterChange
|
|
folks claim to have fixed this bug in 3.61.08.
|
|
|
|
"""
|
|
- if string.find(greetline, "Imail") > 0:
|
|
- warnings = warnings + """
|
|
+ if string.find(greetline, "Imail") > 0:
|
|
+ warnings = warnings + """
|
|
We've seen a bug report indicating that this IMAP server (at least as of
|
|
version 5.0.7) returns an invalid body size for messages with MIME
|
|
attachments; the effect is to drop the attachments on the floor. We
|
|
recommend you upgrade to a non-broken IMAP server.
|
|
|
|
"""
|
|
- if string.find(greetline, "Domino IMAP4") > 0:
|
|
- warnings = warnings + """
|
|
+ if string.find(greetline, "Domino IMAP4") > 0:
|
|
+ warnings = warnings + """
|
|
Your IMAP server appears to be Lotus Domino. This server, at least up
|
|
to version 4.6.2a, has a bug in its generation of MIME boundaries (see
|
|
the details in the fetchmail FAQ). As a result, even MIME aware MUAs
|
|
@@ -1507,16 +1507,16 @@ POP3 facility is enabled, we recommend you fall back on it.
|
|
|
|
### Checks for protocol variants start here
|
|
|
|
- closebrak = string.find(greetline, ">")
|
|
- if closebrak > 0 and greetline[closebrak+1] == "\r":
|
|
- warnings = warnings + """
|
|
+ closebrak = string.find(greetline, ">")
|
|
+ if closebrak > 0 and greetline[closebrak+1] == "\r":
|
|
+ warnings = warnings + """
|
|
It looks like you could use APOP on this server and avoid sending it your
|
|
password in clear. You should talk to the mailserver administrator about
|
|
this.
|
|
|
|
"""
|
|
- if string.find(greetline, "IMAP2bis") > 0:
|
|
- warnings = warnings + """
|
|
+ if string.find(greetline, "IMAP2bis") > 0:
|
|
+ warnings = warnings + """
|
|
IMAP2bis servers have a minor problem; they can't peek at messages without
|
|
marking them seen. If you take a line hit during the retrieval, the
|
|
interrupted message may get left on the server, marked seen.
|
|
@@ -1529,30 +1529,30 @@ To fix this bug, upgrade to an IMAP4 server. The fetchmail FAQ includes
|
|
a pointer to an open-source implementation.
|
|
|
|
"""
|
|
- if string.find(greetline, "IMAP4rev1") > 0:
|
|
- warnings = warnings + """
|
|
+ if string.find(greetline, "IMAP4rev1") > 0:
|
|
+ warnings = warnings + """
|
|
I see an IMAP4rev1 server. Excellent. This is (a) the best kind of
|
|
remote-mail server, and (b) the one the fetchmail author uses. Fetchmail
|
|
has therefore been extremely well tested with this class of server.
|
|
|
|
"""
|
|
- if warnings == '':
|
|
- warnings = warnings + """
|
|
+ if warnings == '':
|
|
+ warnings = warnings + """
|
|
Fetchmail doesn't know anything special about this server type.
|
|
|
|
"""
|
|
|
|
- # Display success window with warnings
|
|
- title = "Autoprobe of " + realhost + " succeeded"
|
|
- confirm = "The " + protocol + " server said:\n\n" + greetline + warnings
|
|
- self.protocol.set(protocol)
|
|
- self.service.set(defaultports[protocol])
|
|
- confwin.title(title)
|
|
- confwin.iconname(title)
|
|
- Label(confwin, text=title).pack()
|
|
- Message(confwin, text=confirm, width=600).pack()
|
|
- Button(confwin, text='Done',
|
|
- command=lambda x=confwin: x.destroy(), bd=2).pack()
|
|
+ # Display success window with warnings
|
|
+ title = "Autoprobe of " + realhost + " succeeded"
|
|
+ confirm = "The " + protocol + " server said:\n\n" + greetline + warnings
|
|
+ self.protocol.set(protocol)
|
|
+ self.service.set(defaultports[protocol])
|
|
+ confwin.title(title)
|
|
+ confwin.iconname(title)
|
|
+ Label(confwin, text=title).pack()
|
|
+ Message(confwin, text=confirm, width=600).pack()
|
|
+ Button(confwin, text='Done',
|
|
+ command=lambda x=confwin: x.destroy(), bd=2).pack()
|
|
|
|
#
|
|
# User editing stuff
|
|
@@ -1597,193 +1597,193 @@ of sending it to your local system.
|
|
|
|
class UserEdit(Frame, MyWidget):
|
|
def __init__(self, username, parent):
|
|
- self.parent = parent
|
|
- self.user = None
|
|
- for user in parent.server.users:
|
|
- if user.remote == username:
|
|
- self.user = user
|
|
- if self.user == None:
|
|
- self.user = User()
|
|
- self.user.remote = username
|
|
- self.user.localnames = [username]
|
|
- parent.server.users.append(self.user)
|
|
+ self.parent = parent
|
|
+ self.user = None
|
|
+ for user in parent.server.users:
|
|
+ if user.remote == username:
|
|
+ self.user = user
|
|
+ if self.user == None:
|
|
+ self.user = User()
|
|
+ self.user.remote = username
|
|
+ self.user.localnames = [username]
|
|
+ parent.server.users.append(self.user)
|
|
|
|
def edit(self, mode, master=None):
|
|
- Frame.__init__(self, master)
|
|
- Pack.config(self)
|
|
- self.master.title('Fetchmail user ' + self.user.remote
|
|
- + ' querying ' + self.parent.server.pollname);
|
|
- self.master.iconname('Fetchmail user ' + self.user.remote);
|
|
- self.post(User, 'user')
|
|
- self.makeWidgets(mode, self.parent.server.pollname)
|
|
- self.keepalive = [] # Use this to anchor the PhotoImage object
|
|
- make_icon_window(self, fetchmail_icon)
|
|
+ Frame.__init__(self, master)
|
|
+ Pack.config(self)
|
|
+ self.master.title('Fetchmail user ' + self.user.remote
|
|
+ + ' querying ' + self.parent.server.pollname);
|
|
+ self.master.iconname('Fetchmail user ' + self.user.remote);
|
|
+ self.post(User, 'user')
|
|
+ self.makeWidgets(mode, self.parent.server.pollname)
|
|
+ self.keepalive = [] # Use this to anchor the PhotoImage object
|
|
+ make_icon_window(self, fetchmail_icon)
|
|
# self.grab_set()
|
|
# self.focus_set()
|
|
# self.wait_window()
|
|
- return self
|
|
+ return self
|
|
|
|
def destruct(self):
|
|
- # Yes, this test can fail -- if you delete the parent window.
|
|
- if self.parent.subwidgets.has_key(self.user.remote):
|
|
- del self.parent.subwidgets[self.user.remote]
|
|
- self.master.destroy()
|
|
+ # Yes, this test can fail -- if you delete the parent window.
|
|
+ if self.parent.subwidgets.has_key(self.user.remote):
|
|
+ del self.parent.subwidgets[self.user.remote]
|
|
+ self.master.destroy()
|
|
|
|
def nosave(self):
|
|
- if ConfirmQuit(self, 'user option editing'):
|
|
- self.destruct()
|
|
+ if ConfirmQuit(self, 'user option editing'):
|
|
+ self.destruct()
|
|
|
|
def save(self):
|
|
- ok = 0
|
|
- for x in self.user.localnames: ok = ok + (string.find(x, '@') != -1)
|
|
- if ok == 0 or Dialog(self,
|
|
- title = "Really accept an embedded '@' ?",
|
|
- text = "Local names with an embedded '@', such as in foo@bar "
|
|
- "might result in your mail being sent to foo@bar.com "
|
|
- "instead of your local system.\n Are you sure you want "
|
|
- "a local user name with an '@' in it?",
|
|
- bitmap = 'question',
|
|
- strings = ('Yes', 'No'),
|
|
- default = 1).num == 0:
|
|
- self.fetch(User, 'user')
|
|
- self.destruct()
|
|
+ ok = 0
|
|
+ for x in self.user.localnames: ok = ok + (string.find(x, '@') != -1)
|
|
+ if ok == 0 or Dialog(self,
|
|
+ title = "Really accept an embedded '@' ?",
|
|
+ text = "Local names with an embedded '@', such as in foo@bar "
|
|
+ "might result in your mail being sent to foo@bar.com "
|
|
+ "instead of your local system.\n Are you sure you want "
|
|
+ "a local user name with an '@' in it?",
|
|
+ bitmap = 'question',
|
|
+ strings = ('Yes', 'No'),
|
|
+ default = 1).num == 0:
|
|
+ self.fetch(User, 'user')
|
|
+ self.destruct()
|
|
|
|
def makeWidgets(self, mode, servername):
|
|
- dispose_window(self,
|
|
- "User options for " + self.user.remote + " querying " + servername,
|
|
- userhelp)
|
|
-
|
|
- if mode != 'novice':
|
|
- leftwin = Frame(self);
|
|
- else:
|
|
- leftwin = self
|
|
-
|
|
- secwin = Frame(leftwin, relief=RAISED, bd=5)
|
|
- Label(secwin, text="Authentication").pack(side=TOP)
|
|
- LabeledEntry(secwin, 'Password:',
|
|
- self.password, '12').pack(side=TOP, fill=X)
|
|
- secwin.pack(fill=X, anchor=N)
|
|
-
|
|
- if 'ssl' in feature_options or 'ssl' in dictmembers:
|
|
- sslwin = Frame(leftwin, relief=RAISED, bd=5)
|
|
- Checkbutton(sslwin, text="Use SSL?",
|
|
- variable=self.ssl).pack(side=TOP, fill=X)
|
|
- LabeledEntry(sslwin, 'SSL key:',
|
|
- self.sslkey, '14').pack(side=TOP, fill=X)
|
|
- LabeledEntry(sslwin, 'SSL certificate:',
|
|
- self.sslcert, '14').pack(side=TOP, fill=X)
|
|
- Checkbutton(sslwin, text="Check server SSL certificate?",
|
|
- variable=self.sslcertck).pack(side=TOP, fill=X)
|
|
- LabeledEntry(sslwin, 'SSL trusted certificate directory:',
|
|
- self.sslcertpath, '14').pack(side=TOP, fill=X)
|
|
- LabeledEntry(sslwin, 'SSL CommonName:',
|
|
- self.sslcommonname, '14').pack(side=TOP, fill=X)
|
|
- LabeledEntry(sslwin, 'SSL key fingerprint:',
|
|
- self.sslfingerprint, '14').pack(side=TOP, fill=X)
|
|
- sslwin.pack(fill=X, anchor=N)
|
|
-
|
|
- names = Frame(leftwin, relief=RAISED, bd=5)
|
|
- Label(names, text="Local names").pack(side=TOP)
|
|
- ListEdit("New name: ",
|
|
- self.user.localnames, None, None, names, localhelp)
|
|
- names.pack(fill=X, anchor=N)
|
|
-
|
|
- if mode != 'novice':
|
|
- targwin = Frame(leftwin, relief=RAISED, bd=5)
|
|
- Label(targwin, text="Forwarding Options").pack(side=TOP)
|
|
- Label(targwin, text="Listeners to forward to").pack(side=TOP)
|
|
- ListEdit("New listener:",
|
|
- self.user.smtphunt, None, None, targwin, None)
|
|
- Label(targwin, text="Domains to fetch from (ODMR/ETRN only)").pack(side=TOP)
|
|
- ListEdit("Domains:",
|
|
- self.user.fetchdomains, None, None, targwin, None)
|
|
- LabeledEntry(targwin, 'Use domain on RCPT TO line:',
|
|
- self.smtpaddress, '26').pack(side=TOP, fill=X)
|
|
- LabeledEntry(targwin, 'Set fixed RCPT TO address:',
|
|
- self.smtpname, '26').pack(side=TOP, fill=X)
|
|
- LabeledEntry(targwin, 'Connection setup command:',
|
|
- self.preconnect, '26').pack(side=TOP, fill=X)
|
|
- LabeledEntry(targwin, 'Connection wrapup command:',
|
|
- self.postconnect, '26').pack(side=TOP, fill=X)
|
|
- LabeledEntry(targwin, 'Local delivery agent:',
|
|
- self.mda, '26').pack(side=TOP, fill=X)
|
|
- LabeledEntry(targwin, 'BSMTP output file:',
|
|
- self.bsmtp, '26').pack(side=TOP, fill=X)
|
|
- LabeledEntry(targwin, 'Listener spam-block codes:',
|
|
- self.antispam, '26').pack(side=TOP, fill=X)
|
|
- LabeledEntry(targwin, 'Pass-through properties:',
|
|
- self.properties, '26').pack(side=TOP, fill=X)
|
|
- Checkbutton(targwin, text="Use LMTP?",
|
|
- variable=self.lmtp).pack(side=TOP, fill=X)
|
|
- targwin.pack(fill=X, anchor=N)
|
|
-
|
|
- if mode != 'novice':
|
|
- leftwin.pack(side=LEFT, fill=X, anchor=N)
|
|
- rightwin = Frame(self)
|
|
- else:
|
|
- rightwin = self
|
|
-
|
|
- optwin = Frame(rightwin, relief=RAISED, bd=5)
|
|
- Label(optwin, text="Processing Options").pack(side=TOP)
|
|
- Checkbutton(optwin, text="Suppress deletion of messages after reading",
|
|
- variable=self.keep).pack(side=TOP, anchor=W)
|
|
- Checkbutton(optwin, text="Fetch old messages as well as new",
|
|
- variable=self.fetchall).pack(side=TOP, anchor=W)
|
|
- if mode != 'novice':
|
|
- Checkbutton(optwin, text="Flush seen messages before retrieval",
|
|
- variable=self.flush).pack(side=TOP, anchor=W)
|
|
- Checkbutton(optwin, text="Flush oversized messages before retrieval",
|
|
- variable=self.limitflush).pack(side=TOP, anchor=W)
|
|
- Checkbutton(optwin, text="Rewrite To/Cc/Bcc messages to enable reply",
|
|
- variable=self.rewrite).pack(side=TOP, anchor=W)
|
|
- Checkbutton(optwin, text="Force CR/LF at end of each line",
|
|
- variable=self.forcecr).pack(side=TOP, anchor=W)
|
|
- Checkbutton(optwin, text="Strip CR from end of each line",
|
|
- variable=self.stripcr).pack(side=TOP, anchor=W)
|
|
- Checkbutton(optwin, text="Pass 8 bits even though SMTP says 7BIT",
|
|
- variable=self.pass8bits).pack(side=TOP, anchor=W)
|
|
- Checkbutton(optwin, text="Undo MIME armoring on header and body",
|
|
- variable=self.mimedecode).pack(side=TOP, anchor=W)
|
|
- Checkbutton(optwin, text="Drop Status lines from forwarded messages",
|
|
- variable=self.dropstatus).pack(side=TOP, anchor=W)
|
|
- Checkbutton(optwin, text="Drop Delivered-To lines from forwarded messages",
|
|
- variable=self.dropdelivered).pack(side=TOP, anchor=W)
|
|
- optwin.pack(fill=X)
|
|
-
|
|
- if mode != 'novice':
|
|
- limwin = Frame(rightwin, relief=RAISED, bd=5)
|
|
- Label(limwin, text="Resource Limits").pack(side=TOP)
|
|
- LabeledEntry(limwin, 'Message size limit:',
|
|
- self.limit, '30').pack(side=TOP, fill=X)
|
|
- LabeledEntry(limwin, 'Size warning interval:',
|
|
- self.warnings, '30').pack(side=TOP, fill=X)
|
|
- LabeledEntry(limwin, 'Max messages to fetch per poll:',
|
|
- self.fetchlimit, '30').pack(side=TOP, fill=X)
|
|
- LabeledEntry(limwin, 'Max message sizes to fetch per transaction:',
|
|
- self.fetchsizelimit, '30').pack(side=TOP, fill=X)
|
|
- if self.parent.server.protocol not in ('ETRN', 'ODMR'):
|
|
- LabeledEntry(limwin, 'Use fast UIDL:',
|
|
- self.fastuidl, '30').pack(side=TOP, fill=X)
|
|
- LabeledEntry(limwin, 'Max messages to forward per poll:',
|
|
- self.batchlimit, '30').pack(side=TOP, fill=X)
|
|
- if self.parent.server.protocol not in ('ETRN', 'ODMR'):
|
|
- LabeledEntry(limwin, 'Interval between expunges:',
|
|
- self.expunge, '30').pack(side=TOP, fill=X)
|
|
- Checkbutton(limwin, text="Idle after each poll (IMAP only)",
|
|
- variable=self.idle).pack(side=TOP, anchor=W)
|
|
- limwin.pack(fill=X)
|
|
-
|
|
- if self.parent.server.protocol == 'IMAP':
|
|
- foldwin = Frame(rightwin, relief=RAISED, bd=5)
|
|
- Label(foldwin, text="Remote folders (IMAP only)").pack(side=TOP)
|
|
- ListEdit("New folder:", self.user.mailboxes,
|
|
- None, None, foldwin, None)
|
|
- foldwin.pack(fill=X, anchor=N)
|
|
-
|
|
- if mode != 'novice':
|
|
- rightwin.pack(side=LEFT)
|
|
- else:
|
|
- self.pack()
|
|
+ dispose_window(self,
|
|
+ "User options for " + self.user.remote + " querying " + servername,
|
|
+ userhelp)
|
|
+
|
|
+ if mode != 'novice':
|
|
+ leftwin = Frame(self);
|
|
+ else:
|
|
+ leftwin = self
|
|
+
|
|
+ secwin = Frame(leftwin, relief=RAISED, bd=5)
|
|
+ Label(secwin, text="Authentication").pack(side=TOP)
|
|
+ LabeledEntry(secwin, 'Password:',
|
|
+ self.password, '12').pack(side=TOP, fill=X)
|
|
+ secwin.pack(fill=X, anchor=N)
|
|
+
|
|
+ if 'ssl' in feature_options or 'ssl' in dictmembers:
|
|
+ sslwin = Frame(leftwin, relief=RAISED, bd=5)
|
|
+ Checkbutton(sslwin, text="Use SSL?",
|
|
+ variable=self.ssl).pack(side=TOP, fill=X)
|
|
+ LabeledEntry(sslwin, 'SSL key:',
|
|
+ self.sslkey, '14').pack(side=TOP, fill=X)
|
|
+ LabeledEntry(sslwin, 'SSL certificate:',
|
|
+ self.sslcert, '14').pack(side=TOP, fill=X)
|
|
+ Checkbutton(sslwin, text="Check server SSL certificate?",
|
|
+ variable=self.sslcertck).pack(side=TOP, fill=X)
|
|
+ LabeledEntry(sslwin, 'SSL trusted certificate directory:',
|
|
+ self.sslcertpath, '14').pack(side=TOP, fill=X)
|
|
+ LabeledEntry(sslwin, 'SSL CommonName:',
|
|
+ self.sslcommonname, '14').pack(side=TOP, fill=X)
|
|
+ LabeledEntry(sslwin, 'SSL key fingerprint:',
|
|
+ self.sslfingerprint, '14').pack(side=TOP, fill=X)
|
|
+ sslwin.pack(fill=X, anchor=N)
|
|
+
|
|
+ names = Frame(leftwin, relief=RAISED, bd=5)
|
|
+ Label(names, text="Local names").pack(side=TOP)
|
|
+ ListEdit("New name: ",
|
|
+ self.user.localnames, None, None, names, localhelp)
|
|
+ names.pack(fill=X, anchor=N)
|
|
+
|
|
+ if mode != 'novice':
|
|
+ targwin = Frame(leftwin, relief=RAISED, bd=5)
|
|
+ Label(targwin, text="Forwarding Options").pack(side=TOP)
|
|
+ Label(targwin, text="Listeners to forward to").pack(side=TOP)
|
|
+ ListEdit("New listener:",
|
|
+ self.user.smtphunt, None, None, targwin, None)
|
|
+ Label(targwin, text="Domains to fetch from (ODMR/ETRN only)").pack(side=TOP)
|
|
+ ListEdit("Domains:",
|
|
+ self.user.fetchdomains, None, None, targwin, None)
|
|
+ LabeledEntry(targwin, 'Use domain on RCPT TO line:',
|
|
+ self.smtpaddress, '26').pack(side=TOP, fill=X)
|
|
+ LabeledEntry(targwin, 'Set fixed RCPT TO address:',
|
|
+ self.smtpname, '26').pack(side=TOP, fill=X)
|
|
+ LabeledEntry(targwin, 'Connection setup command:',
|
|
+ self.preconnect, '26').pack(side=TOP, fill=X)
|
|
+ LabeledEntry(targwin, 'Connection wrapup command:',
|
|
+ self.postconnect, '26').pack(side=TOP, fill=X)
|
|
+ LabeledEntry(targwin, 'Local delivery agent:',
|
|
+ self.mda, '26').pack(side=TOP, fill=X)
|
|
+ LabeledEntry(targwin, 'BSMTP output file:',
|
|
+ self.bsmtp, '26').pack(side=TOP, fill=X)
|
|
+ LabeledEntry(targwin, 'Listener spam-block codes:',
|
|
+ self.antispam, '26').pack(side=TOP, fill=X)
|
|
+ LabeledEntry(targwin, 'Pass-through properties:',
|
|
+ self.properties, '26').pack(side=TOP, fill=X)
|
|
+ Checkbutton(targwin, text="Use LMTP?",
|
|
+ variable=self.lmtp).pack(side=TOP, fill=X)
|
|
+ targwin.pack(fill=X, anchor=N)
|
|
+
|
|
+ if mode != 'novice':
|
|
+ leftwin.pack(side=LEFT, fill=X, anchor=N)
|
|
+ rightwin = Frame(self)
|
|
+ else:
|
|
+ rightwin = self
|
|
+
|
|
+ optwin = Frame(rightwin, relief=RAISED, bd=5)
|
|
+ Label(optwin, text="Processing Options").pack(side=TOP)
|
|
+ Checkbutton(optwin, text="Suppress deletion of messages after reading",
|
|
+ variable=self.keep).pack(side=TOP, anchor=W)
|
|
+ Checkbutton(optwin, text="Fetch old messages as well as new",
|
|
+ variable=self.fetchall).pack(side=TOP, anchor=W)
|
|
+ if mode != 'novice':
|
|
+ Checkbutton(optwin, text="Flush seen messages before retrieval",
|
|
+ variable=self.flush).pack(side=TOP, anchor=W)
|
|
+ Checkbutton(optwin, text="Flush oversized messages before retrieval",
|
|
+ variable=self.limitflush).pack(side=TOP, anchor=W)
|
|
+ Checkbutton(optwin, text="Rewrite To/Cc/Bcc messages to enable reply",
|
|
+ variable=self.rewrite).pack(side=TOP, anchor=W)
|
|
+ Checkbutton(optwin, text="Force CR/LF at end of each line",
|
|
+ variable=self.forcecr).pack(side=TOP, anchor=W)
|
|
+ Checkbutton(optwin, text="Strip CR from end of each line",
|
|
+ variable=self.stripcr).pack(side=TOP, anchor=W)
|
|
+ Checkbutton(optwin, text="Pass 8 bits even though SMTP says 7BIT",
|
|
+ variable=self.pass8bits).pack(side=TOP, anchor=W)
|
|
+ Checkbutton(optwin, text="Undo MIME armoring on header and body",
|
|
+ variable=self.mimedecode).pack(side=TOP, anchor=W)
|
|
+ Checkbutton(optwin, text="Drop Status lines from forwarded messages",
|
|
+ variable=self.dropstatus).pack(side=TOP, anchor=W)
|
|
+ Checkbutton(optwin, text="Drop Delivered-To lines from forwarded messages",
|
|
+ variable=self.dropdelivered).pack(side=TOP, anchor=W)
|
|
+ optwin.pack(fill=X)
|
|
+
|
|
+ if mode != 'novice':
|
|
+ limwin = Frame(rightwin, relief=RAISED, bd=5)
|
|
+ Label(limwin, text="Resource Limits").pack(side=TOP)
|
|
+ LabeledEntry(limwin, 'Message size limit:',
|
|
+ self.limit, '30').pack(side=TOP, fill=X)
|
|
+ LabeledEntry(limwin, 'Size warning interval:',
|
|
+ self.warnings, '30').pack(side=TOP, fill=X)
|
|
+ LabeledEntry(limwin, 'Max messages to fetch per poll:',
|
|
+ self.fetchlimit, '30').pack(side=TOP, fill=X)
|
|
+ LabeledEntry(limwin, 'Max message sizes to fetch per transaction:',
|
|
+ self.fetchsizelimit, '30').pack(side=TOP, fill=X)
|
|
+ if self.parent.server.protocol not in ('ETRN', 'ODMR'):
|
|
+ LabeledEntry(limwin, 'Use fast UIDL:',
|
|
+ self.fastuidl, '30').pack(side=TOP, fill=X)
|
|
+ LabeledEntry(limwin, 'Max messages to forward per poll:',
|
|
+ self.batchlimit, '30').pack(side=TOP, fill=X)
|
|
+ if self.parent.server.protocol not in ('ETRN', 'ODMR'):
|
|
+ LabeledEntry(limwin, 'Interval between expunges:',
|
|
+ self.expunge, '30').pack(side=TOP, fill=X)
|
|
+ Checkbutton(limwin, text="Idle after each poll (IMAP only)",
|
|
+ variable=self.idle).pack(side=TOP, anchor=W)
|
|
+ limwin.pack(fill=X)
|
|
+
|
|
+ if self.parent.server.protocol == 'IMAP':
|
|
+ foldwin = Frame(rightwin, relief=RAISED, bd=5)
|
|
+ Label(foldwin, text="Remote folders (IMAP only)").pack(side=TOP)
|
|
+ ListEdit("New folder:", self.user.mailboxes,
|
|
+ None, None, foldwin, None)
|
|
+ foldwin.pack(fill=X, anchor=N)
|
|
+
|
|
+ if mode != 'novice':
|
|
+ rightwin.pack(side=LEFT)
|
|
+ else:
|
|
+ self.pack()
|
|
|
|
|
|
#
|
|
@@ -1793,162 +1793,162 @@ class UserEdit(Frame, MyWidget):
|
|
|
|
class Configurator(Frame):
|
|
def __init__(self, outfile, master, onexit, parent):
|
|
- Frame.__init__(self, master)
|
|
- self.outfile = outfile
|
|
- self.onexit = onexit
|
|
- self.parent = parent
|
|
- self.master.title('fetchmail configurator');
|
|
- self.master.iconname('fetchmail configurator');
|
|
- Pack.config(self)
|
|
- self.keepalive = [] # Use this to anchor the PhotoImage object
|
|
- make_icon_window(self, fetchmail_icon)
|
|
-
|
|
- Message(self, text="""
|
|
+ Frame.__init__(self, master)
|
|
+ self.outfile = outfile
|
|
+ self.onexit = onexit
|
|
+ self.parent = parent
|
|
+ self.master.title('fetchmail configurator');
|
|
+ self.master.iconname('fetchmail configurator');
|
|
+ Pack.config(self)
|
|
+ self.keepalive = [] # Use this to anchor the PhotoImage object
|
|
+ make_icon_window(self, fetchmail_icon)
|
|
+
|
|
+ Message(self, text="""
|
|
Use `Novice Configuration' for basic fetchmail setup;
|
|
with this, you can easily set up a single-drop connection
|
|
to one remote mail server.
|
|
""", width=600).pack(side=TOP)
|
|
- Button(self, text='Novice Configuration',
|
|
- fg='blue', command=self.novice).pack()
|
|
+ Button(self, text='Novice Configuration',
|
|
+ fg='blue', command=self.novice).pack()
|
|
|
|
- Message(self, text="""
|
|
+ Message(self, text="""
|
|
Use `Expert Configuration' for advanced fetchmail setup,
|
|
including multiple-site or multidrop connections.
|
|
""", width=600).pack(side=TOP)
|
|
- Button(self, text='Expert Configuration',
|
|
- fg='blue', command=self.expert).pack()
|
|
+ Button(self, text='Expert Configuration',
|
|
+ fg='blue', command=self.expert).pack()
|
|
|
|
- Message(self, text="""
|
|
+ Message(self, text="""
|
|
Or you can just select `Quit' to leave the configurator now and
|
|
return to the main panel.
|
|
""", width=600).pack(side=TOP)
|
|
- Button(self, text='Quit', fg='blue', command=self.leave).pack()
|
|
- master.protocol("WM_DELETE_WINDOW", self.leave)
|
|
+ Button(self, text='Quit', fg='blue', command=self.leave).pack()
|
|
+ master.protocol("WM_DELETE_WINDOW", self.leave)
|
|
|
|
def novice(self):
|
|
- self.master.destroy()
|
|
- ConfigurationEdit(Fetchmailrc, self.outfile, Toplevel(), self.onexit).edit('novice')
|
|
+ self.master.destroy()
|
|
+ ConfigurationEdit(Fetchmailrc, self.outfile, Toplevel(), self.onexit).edit('novice')
|
|
|
|
def expert(self):
|
|
- self.master.destroy()
|
|
- ConfigurationEdit(Fetchmailrc, self.outfile, Toplevel(), self.onexit).edit('expert')
|
|
+ self.master.destroy()
|
|
+ ConfigurationEdit(Fetchmailrc, self.outfile, Toplevel(), self.onexit).edit('expert')
|
|
|
|
def leave(self):
|
|
- self.master.destroy()
|
|
- self.onexit()
|
|
+ self.master.destroy()
|
|
+ self.onexit()
|
|
|
|
# Run a command in a scrolling text widget, displaying its output
|
|
|
|
class RunWindow(Frame):
|
|
def __init__(self, command, master, parent):
|
|
- Frame.__init__(self, master)
|
|
- self.master = master
|
|
- self.master.title('fetchmail run window');
|
|
- self.master.iconname('fetchmail run window');
|
|
- Pack.config(self)
|
|
- Label(self,
|
|
- text="Running "+command,
|
|
- bd=2).pack(side=TOP, pady=10)
|
|
- self.keepalive = [] # Use this to anchor the PhotoImage object
|
|
- make_icon_window(self, fetchmail_icon)
|
|
-
|
|
- # This is a scrolling text window
|
|
- textframe = Frame(self)
|
|
- scroll = Scrollbar(textframe)
|
|
- self.textwidget = Text(textframe, setgrid=TRUE)
|
|
- textframe.pack(side=TOP, expand=YES, fill=BOTH)
|
|
- self.textwidget.config(yscrollcommand=scroll.set)
|
|
- self.textwidget.pack(side=LEFT, expand=YES, fill=BOTH)
|
|
- scroll.config(command=self.textwidget.yview)
|
|
- scroll.pack(side=RIGHT, fill=BOTH)
|
|
- textframe.pack(side=TOP)
|
|
-
|
|
- Button(self, text='Quit', fg='blue', command=self.leave).pack()
|
|
-
|
|
- self.update() # Draw widget before executing fetchmail
|
|
-
|
|
- # Always look for a runnable command in the directory we're running in
|
|
- # first. This avoids some obscure version-skew errors that can occur
|
|
- # if you pick up an old fetchmail from the standard system locations.
|
|
- os.environ["PATH"] = os.path.dirname(sys.argv[0]) + ":" + os.environ["PATH"]
|
|
- child_stdout = os.popen(command + " 2>&1 </dev/null", "r")
|
|
- while 1:
|
|
- ch = child_stdout.read(1)
|
|
- if not ch:
|
|
- break
|
|
- self.textwidget.insert(END, ch)
|
|
- self.textwidget.insert(END, "Done.")
|
|
- self.textwidget.see(END);
|
|
+ Frame.__init__(self, master)
|
|
+ self.master = master
|
|
+ self.master.title('fetchmail run window');
|
|
+ self.master.iconname('fetchmail run window');
|
|
+ Pack.config(self)
|
|
+ Label(self,
|
|
+ text="Running "+command,
|
|
+ bd=2).pack(side=TOP, pady=10)
|
|
+ self.keepalive = [] # Use this to anchor the PhotoImage object
|
|
+ make_icon_window(self, fetchmail_icon)
|
|
+
|
|
+ # This is a scrolling text window
|
|
+ textframe = Frame(self)
|
|
+ scroll = Scrollbar(textframe)
|
|
+ self.textwidget = Text(textframe, setgrid=TRUE)
|
|
+ textframe.pack(side=TOP, expand=YES, fill=BOTH)
|
|
+ self.textwidget.config(yscrollcommand=scroll.set)
|
|
+ self.textwidget.pack(side=LEFT, expand=YES, fill=BOTH)
|
|
+ scroll.config(command=self.textwidget.yview)
|
|
+ scroll.pack(side=RIGHT, fill=BOTH)
|
|
+ textframe.pack(side=TOP)
|
|
+
|
|
+ Button(self, text='Quit', fg='blue', command=self.leave).pack()
|
|
+
|
|
+ self.update() # Draw widget before executing fetchmail
|
|
+
|
|
+ # Always look for a runnable command in the directory we're running in
|
|
+ # first. This avoids some obscure version-skew errors that can occur
|
|
+ # if you pick up an old fetchmail from the standard system locations.
|
|
+ os.environ["PATH"] = os.path.dirname(sys.argv[0]) + ":" + os.environ["PATH"]
|
|
+ child_stdout = os.popen(command + " 2>&1 </dev/null", "r")
|
|
+ while 1:
|
|
+ ch = child_stdout.read(1)
|
|
+ if not ch:
|
|
+ break
|
|
+ self.textwidget.insert(END, ch)
|
|
+ self.textwidget.insert(END, "Done.")
|
|
+ self.textwidget.see(END);
|
|
|
|
def leave(self):
|
|
- self.master.destroy()
|
|
+ self.master.destroy()
|
|
|
|
# Here's where we choose either configuration or launching
|
|
|
|
class MainWindow(Frame):
|
|
def __init__(self, outfile, master=None):
|
|
- Frame.__init__(self, master)
|
|
- self.outfile = outfile
|
|
- self.master.title('fetchmail launcher');
|
|
- self.master.iconname('fetchmail launcher');
|
|
- Pack.config(self)
|
|
- Label(self,
|
|
- text='Fetchmailconf ' + version,
|
|
- bd=2).pack(side=TOP, pady=10)
|
|
- self.keepalive = [] # Use this to anchor the PhotoImage object
|
|
- make_icon_window(self, fetchmail_icon)
|
|
- self.debug = 0
|
|
-
|
|
- ## Test icon display with the following:
|
|
- # icon_image = PhotoImage(data=fetchmail_icon)
|
|
- # Label(self, image=icon_image).pack(side=TOP, pady=10)
|
|
- # self.keepalive.append(icon_image)
|
|
-
|
|
- Message(self, text="""
|
|
+ Frame.__init__(self, master)
|
|
+ self.outfile = outfile
|
|
+ self.master.title('fetchmail launcher');
|
|
+ self.master.iconname('fetchmail launcher');
|
|
+ Pack.config(self)
|
|
+ Label(self,
|
|
+ text='Fetchmailconf ' + version,
|
|
+ bd=2).pack(side=TOP, pady=10)
|
|
+ self.keepalive = [] # Use this to anchor the PhotoImage object
|
|
+ make_icon_window(self, fetchmail_icon)
|
|
+ self.debug = 0
|
|
+
|
|
+ ## Test icon display with the following:
|
|
+ # icon_image = PhotoImage(data=fetchmail_icon)
|
|
+ # Label(self, image=icon_image).pack(side=TOP, pady=10)
|
|
+ # self.keepalive.append(icon_image)
|
|
+
|
|
+ Message(self, text="""
|
|
Use `Configure fetchmail' to tell fetchmail about the remote
|
|
servers it should poll (the host name, your username there,
|
|
whether to use POP or IMAP, and so forth).
|
|
""", width=600).pack(side=TOP)
|
|
- self.configbutton = Button(self, text='Configure fetchmail',
|
|
- fg='blue', command=self.configure)
|
|
- self.configbutton.pack()
|
|
+ self.configbutton = Button(self, text='Configure fetchmail',
|
|
+ fg='blue', command=self.configure)
|
|
+ self.configbutton.pack()
|
|
|
|
- Message(self, text="""
|
|
+ Message(self, text="""
|
|
Use `Run fetchmail' to run fetchmail with debugging enabled.
|
|
This is a good way to test out a new configuration.
|
|
""", width=600).pack(side=TOP)
|
|
- Button(self, text='Run fetchmail',fg='blue', command=self.test).pack()
|
|
+ Button(self, text='Run fetchmail',fg='blue', command=self.test).pack()
|
|
|
|
- Message(self, text="""
|
|
+ Message(self, text="""
|
|
Use `Run fetchmail' to run fetchmail in foreground.
|
|
Progress messages will be shown, but not debug messages.
|
|
""", width=600).pack(side=TOP)
|
|
- Button(self, text='Run fetchmail', fg='blue', command=self.run).pack()
|
|
+ Button(self, text='Run fetchmail', fg='blue', command=self.run).pack()
|
|
|
|
- Message(self, text="""
|
|
+ Message(self, text="""
|
|
Or you can just select `Quit' to exit the launcher now.
|
|
""", width=600).pack(side=TOP)
|
|
- Button(self, text='Quit', fg='blue', command=self.leave).pack()
|
|
+ Button(self, text='Quit', fg='blue', command=self.leave).pack()
|
|
|
|
def configure(self):
|
|
- self.configbutton.configure(state=DISABLED)
|
|
- Configurator(self.outfile, Toplevel(),
|
|
- lambda self=self: self.configbutton.configure(state=NORMAL),
|
|
- self)
|
|
+ self.configbutton.configure(state=DISABLED)
|
|
+ Configurator(self.outfile, Toplevel(),
|
|
+ lambda self=self: self.configbutton.configure(state=NORMAL),
|
|
+ self)
|
|
def test(self):
|
|
- cmd = "fetchmail -N -d0 --nosyslog -v"
|
|
- if rcfile:
|
|
- cmd = cmd + " -f " + rcfile
|
|
- RunWindow(cmd, Toplevel(), self)
|
|
+ cmd = "fetchmail -N -d0 --nosyslog -v"
|
|
+ if rcfile:
|
|
+ cmd = cmd + " -f " + rcfile
|
|
+ RunWindow(cmd, Toplevel(), self)
|
|
|
|
def run(self):
|
|
- cmd = "fetchmail -N -d0"
|
|
- if rcfile:
|
|
- cmd = cmd + " -f " + rcfile
|
|
- RunWindow(cmd, Toplevel(), self)
|
|
+ cmd = "fetchmail -N -d0"
|
|
+ if rcfile:
|
|
+ cmd = cmd + " -f " + rcfile
|
|
+ RunWindow(cmd, Toplevel(), self)
|
|
|
|
def leave(self):
|
|
- self.quit()
|
|
+ self.quit()
|
|
|
|
# Functions for turning a dictionary into an instantiated object tree.
|
|
|
|
@@ -1956,51 +1956,51 @@ def intersect(list1, list2):
|
|
# Compute set intersection of lists
|
|
res = []
|
|
for x in list1:
|
|
- if x in list2:
|
|
- res.append(x)
|
|
+ if x in list2:
|
|
+ res.append(x)
|
|
return res
|
|
|
|
def setdiff(list1, list2):
|
|
# Compute set difference of lists
|
|
res = []
|
|
for x in list1:
|
|
- if not x in list2:
|
|
- res.append(x)
|
|
+ if not x in list2:
|
|
+ res.append(x)
|
|
return res
|
|
|
|
def copy_instance(toclass, fromdict):
|
|
# Initialize a class object of given type from a conformant dictionary.
|
|
for fld in fromdict.keys():
|
|
- if not fld in dictmembers:
|
|
- dictmembers.append(fld)
|
|
+ if not fld in dictmembers:
|
|
+ dictmembers.append(fld)
|
|
# The `optional' fields are the ones we can ignore for purposes of
|
|
# conformability checking; they'll still get copied if they are
|
|
# present in the dictionary.
|
|
optional = ('interface', 'monitor',
|
|
- 'esmtpname', 'esmtppassword',
|
|
- 'ssl', 'sslkey', 'sslcert', 'sslproto', 'sslcertck',
|
|
- 'sslcertpath', 'sslcommonname', 'sslfingerprint', 'showdots')
|
|
+ 'esmtpname', 'esmtppassword',
|
|
+ 'ssl', 'sslkey', 'sslcert', 'sslproto', 'sslcertck',
|
|
+ 'sslcertpath', 'sslcommonname', 'sslfingerprint', 'showdots')
|
|
class_sig = setdiff(toclass.__dict__.keys(), optional)
|
|
class_sig.sort()
|
|
dict_keys = setdiff(fromdict.keys(), optional)
|
|
dict_keys.sort()
|
|
common = intersect(class_sig, dict_keys)
|
|
if 'typemap' in class_sig:
|
|
- class_sig.remove('typemap')
|
|
+ class_sig.remove('typemap')
|
|
if tuple(class_sig) != tuple(dict_keys):
|
|
- print "Fields don't match what fetchmailconf expected:"
|
|
+ print "Fields don't match what fetchmailconf expected:"
|
|
# print "Class signature: " + `class_sig`
|
|
# print "Dictionary keys: " + `dict_keys`
|
|
- diff = setdiff(class_sig, common)
|
|
- if diff:
|
|
- print "Not matched in class `" + toclass.__class__.__name__ + "' signature: " + `diff`
|
|
- diff = setdiff(dict_keys, common)
|
|
- if diff:
|
|
- print "Not matched in dictionary keys: " + `diff`
|
|
- sys.exit(1)
|
|
+ diff = setdiff(class_sig, common)
|
|
+ if diff:
|
|
+ print "Not matched in class `" + toclass.__class__.__name__ + "' signature: " + `diff`
|
|
+ diff = setdiff(dict_keys, common)
|
|
+ if diff:
|
|
+ print "Not matched in dictionary keys: " + `diff`
|
|
+ sys.exit(1)
|
|
else:
|
|
- for x in fromdict.keys():
|
|
- setattr(toclass, x, fromdict[x])
|
|
+ for x in fromdict.keys():
|
|
+ setattr(toclass, x, fromdict[x])
|
|
|
|
#
|
|
# And this is the main sequence. How it works:
|
|
@@ -2028,8 +2028,8 @@ def copy_instance(toclass, fromdict):
|
|
if __name__ == '__main__':
|
|
|
|
if not os.environ.has_key("DISPLAY"):
|
|
- print "fetchmailconf must be run under X"
|
|
- sys.exit(1)
|
|
+ print "fetchmailconf must be run under X"
|
|
+ sys.exit(1)
|
|
|
|
fetchmail_icon = """
|
|
R0lGODdhPAAoAPcAAP///wgICBAQEISEhIyMjJSUlKWlpa2trbW1tcbGxs7Ozufn5+/v7//39yEY
|
|
@@ -2073,31 +2073,31 @@ gUSiYASJpMEHhilJTEnhAlGoQqYAZQ1AiqEMZ0jDGtqQImhwwA13yMMevoQAGvGhEAWHGMOAAAA7
|
|
|
|
# Process options
|
|
(options, arguments) = getopt.getopt(sys.argv[1:], "df:hV", ["help",
|
|
- "version"])
|
|
+ "version"])
|
|
dump = rcfile = None;
|
|
for (switch, val) in options:
|
|
- if (switch == '-d'):
|
|
- dump = TRUE
|
|
- elif (switch == '-f'):
|
|
- rcfile = val
|
|
- elif (switch == '-h' or switch == '--help'):
|
|
- print """
|
|
+ if (switch == '-d'):
|
|
+ dump = TRUE
|
|
+ elif (switch == '-f'):
|
|
+ rcfile = val
|
|
+ elif (switch == '-h' or switch == '--help'):
|
|
+ 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 """
|
|
+ sys.exit(0)
|
|
+ elif (switch == '-V' or switch == '--version'):
|
|
+ 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."""
|
|
- sys.exit(0)
|
|
+ sys.exit(0)
|
|
|
|
# Get client host's FQDN
|
|
hostname = socket.gethostbyaddr(socket.gethostname())[0]
|
|
@@ -2112,26 +2112,26 @@ COPYING in the source or documentation directory for details."""
|
|
# want crackers to snoop password information out of the tempfile.
|
|
tmpfile = tempfile.mktemp()
|
|
if rcfile:
|
|
- cmd = "umask 077 && fetchmail </dev/null -f " + rcfile + " --configdump --nosyslog >" + tmpfile
|
|
+ cmd = "umask 077 && fetchmail </dev/null -f " + rcfile + " --configdump --nosyslog >" + tmpfile
|
|
else:
|
|
- cmd = "umask 077 && fetchmail </dev/null --configdump --nosyslog >" + tmpfile
|
|
+ cmd = "umask 077 && fetchmail </dev/null --configdump --nosyslog >" + tmpfile
|
|
|
|
try:
|
|
- s = os.system(cmd)
|
|
- if s != 0:
|
|
- print "`" + cmd + "' run failure, status " + `s`
|
|
- raise SystemExit
|
|
+ s = os.system(cmd)
|
|
+ if s != 0:
|
|
+ print "`" + cmd + "' run failure, status " + `s`
|
|
+ raise SystemExit
|
|
except:
|
|
- print "Unknown error while running fetchmail --configdump"
|
|
- os.remove(tmpfile)
|
|
- sys.exit(1)
|
|
+ print "Unknown error while running fetchmail --configdump"
|
|
+ os.remove(tmpfile)
|
|
+ sys.exit(1)
|
|
|
|
try:
|
|
- execfile(tmpfile)
|
|
+ execfile(tmpfile)
|
|
except:
|
|
- print "Can't read configuration output of fetchmail --configdump."
|
|
- os.remove(tmpfile)
|
|
- sys.exit(1)
|
|
+ print "Can't read configuration output of fetchmail --configdump."
|
|
+ os.remove(tmpfile)
|
|
+ sys.exit(1)
|
|
|
|
os.remove(tmpfile)
|
|
|
|
@@ -2145,23 +2145,23 @@ COPYING in the source or documentation directory for details."""
|
|
copy_instance(Fetchmailrc, fetchmailrc)
|
|
Fetchmailrc.servers = [];
|
|
for server in fetchmailrc['servers']:
|
|
- Newsite = Server()
|
|
- copy_instance(Newsite, server)
|
|
- Fetchmailrc.servers.append(Newsite)
|
|
- Newsite.users = [];
|
|
- for user in server['users']:
|
|
- Newuser = User()
|
|
- copy_instance(Newuser, user)
|
|
- Newsite.users.append(Newuser)
|
|
+ Newsite = Server()
|
|
+ copy_instance(Newsite, server)
|
|
+ Fetchmailrc.servers.append(Newsite)
|
|
+ Newsite.users = [];
|
|
+ for user in server['users']:
|
|
+ Newuser = User()
|
|
+ copy_instance(Newuser, user)
|
|
+ Newsite.users.append(Newuser)
|
|
|
|
# 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"+`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.
|
|
if not rcfile and not dump:
|
|
- rcfile = os.environ["HOME"] + "/.fetchmailrc"
|
|
+ rcfile = os.environ["HOME"] + "/.fetchmailrc"
|
|
|
|
# OK, now run the configuration edit
|
|
root = MainWindow(rcfile)
|
|
--
|
|
libgit2 0.26.0
|
|
|