]> Pileus Git - ~andy/fetchmail/blobdiff - fetchmailconf
Bug fixes and internationalization improvements.
[~andy/fetchmail] / fetchmailconf
index 585f2235c977f6a5ea655ee38b84bd8ec48e3830..15ccc2fbf02234e060d0a15ecbd43983ae4d6a71 100755 (executable)
@@ -4,7 +4,7 @@
 # by Eric S. Raymond, <esr@snark.thyrsus.com>.
 # Requires Python with Tkinter, and the following OS-dependent services:
 #      posix, posixpath, socket
-version = "1.23"
+version = "1.28"
 
 from Tkinter import *
 from Dialog import *
@@ -216,6 +216,7 @@ class User:
        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 = 0              # Size warning interval
@@ -247,6 +248,7 @@ class User:
            ('pass8bits',   'Boolean'),
            ('mimedecode',  'Boolean'),
            ('dropstatus',  'Boolean'),
+            ('dropdelivered', 'Boolean'),
            ('idle',        'Boolean'),
            ('limit',       'Int'),
            ('warnings',    'Int'),
@@ -260,9 +262,9 @@ class User:
 
     def __repr__(self):
        res = "    "
-       res = res + "user " + str(self.remote) + " there ";
+       res = res + "user " + `self.remote` + " there ";
        if self.password:
-            res = res + "with password " + str(self.password) + " "
+            res = res + "with password " + `self.password` + " "
        if self.localnames:
             res = res + "is"
             for x in self.localnames:
@@ -277,6 +279,7 @@ class User:
                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:
@@ -297,6 +300,8 @@ class User:
            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:
@@ -312,7 +317,7 @@ class User:
        if self.sslkey and self.sslkey != UserDefaults.sslkey:
            res = res + " sslkey " + `self.sslkey`
        if self.sslcert and self.sslcert != UserDefaults.sslcert:
-           res = res + " ssl " + `self.sslcert`
+           res = res + " sslcert " + `self.sslcert`
        if self.expunge != UserDefaults.expunge:
            res = res + " expunge " + `self.expunge`
         res = res + "\n"
@@ -483,16 +488,18 @@ class ListEdit(Frame):
        helpwin(self.helptxt)
 
     def handleList(self, event):
-       self.editItem();
+        self.editItem();
 
     def handleNew(self, event):
        item = self.newval.get()
-       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)
-            apply(self.editor, (item,))
-       self.newval.set('')
+        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()
@@ -502,7 +509,8 @@ class ListEdit(Frame):
            index = select[0]
            if index and self.editor:
                label = self.listwidget.get(index);
-               apply(self.editor, (label,))
+                if self.editor:
+                    apply(self.editor, (label,))
 
     def deleteItem(self):
        select = self.listwidget.curselection()
@@ -664,6 +672,8 @@ class ConfigurationEdit(Frame, MyWidget):
 
     def server_delete(self, sitename):
         try:
+            for user in self.subwidgets.keys():
+                user.destruct()
             del self.configuration[sitename]
         except:
            pass
@@ -968,7 +978,7 @@ class ServerEdit(Frame, MyWidget):
 
     def user_delete(self, username):
         if self.subwidgets.has_key(username):
-            del self.subwidgets[username]
+            self.subwidgets[username].destruct()
         del self.server[username]
 
     def makeWidgets(self, host, mode):
@@ -1160,6 +1170,12 @@ 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
 SunOS and Solaris machines run cucipop OK.
 
+"""
+           if string.find(greetline, "David POP3 Server") > 0:
+                warnings = warnings + """
+This POP3 serrver is badly broken.  You should get rid of it -- and the
+brain-dead NT 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)
@@ -1181,10 +1197,11 @@ this server.
 """
            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).  You should get rid of it --
-and the brain-dead NT server it rode in on. 
+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
+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:
@@ -1203,7 +1220,7 @@ 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:
+            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
@@ -1220,7 +1237,16 @@ this bug, turn on `fetchall' on all user entries associated with this
 server.
 
 """
-            if string.find(greetline, "usa.net") > 0:
+            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
+this bug, turn on `fetchall' on all user entries associated with this
+server.
+
+"""
+            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
@@ -1233,6 +1259,13 @@ Turning on fetchall will disable the use of TOP.
 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 + """
+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.
+
 """
 
 ### IMAP servers start here
@@ -1261,10 +1294,10 @@ same messages will be downloaded over and over.
                 warnings = warnings + """
 The InterChange IMAP server screws up on mail with attachments.  It
 doesn't fetch them if you give it a BODY[TEXT] request, though it
-does if you request RFC822.TEXT (according to the IMAP RFCs and their
-maintainer these should be equivalent).  We have worked around this
-bug, but suspect InterChange is likely to be broken in other ways.
-You should get rid of it. 
+does if you request RFC822.TEXT.  According to the IMAP RFCs and their
+maintainer these should be equivalent -- and we can't drop the
+BODY[TEXT] form because M$ Exchange (quite legally under RFC2062)
+rejects it.
 
 """
             if string.find(greetline, "Imail") > 0:
@@ -1274,6 +1307,15 @@ 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 + """
+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
+will see attachments as part of the message text.  If your Domino server's
+POP3 facility is enabled, we recommend you fall back on it.
+
 """
 
 ### Checks for protocol variants start here
@@ -1389,7 +1431,9 @@ class UserEdit(Frame, MyWidget):
        return self
 
     def destruct(self):
-        del self.parent.subwidgets[self.user.remote]
+        # 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]
         Widget.destroy(self.master)
 
     def nosave(self):
@@ -1483,6 +1527,8 @@ class UserEdit(Frame, MyWidget):
                    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':
@@ -1496,8 +1542,8 @@ class UserEdit(Frame, MyWidget):
                      self.fetchlimit, '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 in ('IMAP', 'IMAP-K4', 'IMAP-GSS'):
-                LabeledEntry(limwin, 'Interval between expunges (IMAP):',
+            if self.parent.server.protocol != 'ETRN':
+                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)
@@ -1805,12 +1851,14 @@ gUSiYASJpMEHhilJTEnhAlGoQqYAZQ1AiqEMZ0jDGtqQImhwwA13yMMevoQAGvGhEAWHGMOAAAA7
     ServerDefaults = Server()
     UserDefaults = User()
 
-    # Read the existing configuration
+    # Read the existing configuration.  We set the umask to 077 to make sure
+    # that group & other read/write permissions are shut off -- we wouldn't
+    # want crackers to snoop password information out of the tempfile.
     tmpfile = "/tmp/fetchmailconf." + `os.getpid()`
     if rcfile:
-        cmd = "fetchmail -f " + rcfile + " --configdump --nosyslog >" + tmpfile
+        cmd = "umask 077; fetchmail -f " + rcfile + " --configdump --nosyslog >" + tmpfile
     else:
-        cmd = "fetchmail --configdump --nosyslog >" + tmpfile
+        cmd = "umask 077; fetchmail --configdump --nosyslog >" + tmpfile
         
     try:
         s = os.system(cmd)