The usual.
diff --git a/Lib/dos-8x3/cgihttps.py b/Lib/dos-8x3/cgihttps.py
index bb8cb2d..24bdeef 100755
--- a/Lib/dos-8x3/cgihttps.py
+++ b/Lib/dos-8x3/cgihttps.py
@@ -133,7 +133,10 @@
             # AUTH_TYPE
             # REMOTE_USER
             # REMOTE_IDENT
-            env['CONTENT_TYPE'] = self.headers.type
+            if self.headers.typeheader is None:
+                env['CONTENT_TYPE'] = self.headers.type
+            else:
+                env['CONTENT_TYPE'] = self.headers.typeheader
             length = self.headers.getheader('content-length')
             if length:
                 env['CONTENT_LENGTH'] = length
diff --git a/Lib/dos-8x3/configpa.py b/Lib/dos-8x3/configpa.py
index 957222c..89e2d85 100644
--- a/Lib/dos-8x3/configpa.py
+++ b/Lib/dos-8x3/configpa.py
@@ -2,10 +2,11 @@
 
 A setup file consists of sections, lead by a "[section]" header,
 and followed by "name: value" entries, with continuations and such in
-the style of rfc822.
+the style of RFC 822.
 
-The option values can contain format strings which refer to other
-values in the same section, or values in a special [DEFAULT] section.
+The option values can contain format strings which refer to other values in
+the same section, or values in a special [DEFAULT] section.
+
 For example:
 
     something: %(dir)s/whatever
@@ -27,7 +28,7 @@
                                dictionary of intrinsic defaults.  The
                                keys must be strings, the values must
                                be appropriate for %()s string
-                               interpolation.  Note that `name' is
+                               interpolation.  Note that `__name__' is
                                always an intrinsic default; it's value
                                is the section's name.
 
@@ -55,14 +56,7 @@
 
 import sys
 import string
-import regex
-from types import ListType
-
-
-SECTHEAD_RE = "^\[\([-A-Za-z0-9]*\)\][" + string.whitespace + "]*$"
-secthead_cre = regex.compile(SECTHEAD_RE)
-OPTION_RE = "^\([-A-Za-z0-9.]+\)\(:\|[" + string.whitespace + "]*=\)\(.*\)$"
-option_cre = regex.compile(OPTION_RE)
+import re
 
 DEFAULTSECT = "DEFAULT"
 
@@ -71,9 +65,9 @@
 # exception classes
 class Error:
     def __init__(self, msg=''):
-        self.__msg = msg
+        self._msg = msg
     def __repr__(self):
-        return self.__msg
+        return self._msg
 
 class NoSectionError(Error):
     def __init__(self, section):
@@ -93,14 +87,38 @@
         self.section = section
 
 class InterpolationError(Error):
-    def __init__(self, reference, option, section):
+    def __init__(self, reference, option, section, rawval):
         Error.__init__(self,
-                       "Bad value substitution: sect `%s', opt `%s', ref `%s'"
-                       % (section, option, reference))
+                       "Bad value substitution:\n"
+                       "\tsection: [%s]\n"
+                       "\toption : %s\n"
+                       "\tkey    : %s\n"
+                       "\trawval : %s\n"
+                       % (section, option, reference, rawval))
         self.reference = reference
         self.option = option
         self.section = section
 
+class MissingSectionHeaderError(Error):
+    def __init__(self, filename, lineno, line):
+        Error.__init__(
+            self,
+            'File contains no section headers.\nfile: %s, line: %d\n%s' %
+            (filename, lineno, line))
+        self.filename = filename
+        self.lineno = lineno
+        self.line = line
+
+class ParsingError(Error):
+    def __init__(self, filename):
+        Error.__init__(self, 'File contains parsing errors: %s' % filename)
+        self.filename = filename
+        self.errors = []
+
+    def append(self, lineno, line):
+        self.errors.append((lineno, line))
+        self._msg = self._msg + '\n\t[line %2d]: %s' % (lineno, line)
+
 
 
 class ConfigParser:
@@ -159,7 +177,8 @@
         """Get an option value for a given section.
 
         All % interpolations are expanded in the return values, based
-        on the defaults passed into the constructor.
+        on the defaults passed into the constructor, unless the optional
+        argument `raw' is true.
 
         The section DEFAULT is special.
         """
@@ -183,7 +202,7 @@
         try:
             return rawval % d
         except KeyError, key:
-            raise InterpolationError(key, option, section)
+            raise InterpolationError(key, option, section, rawval)
 
     def __get(self, section, conv, option):
         return conv(self.get(section, option))
@@ -201,6 +220,24 @@
             raise ValueError, 'Not a boolean: %s' % v
         return val
 
+    #
+    # Regular expressions for parsing section headers and options.  Note a
+    # slight semantic change from the previous version, because of the use
+    # of \w, _ is allowed in section header names.
+    __SECTCRE = re.compile(
+        r'\['                                 # [
+        r'(?P<header>[-\w]+)'                 # `-', `_' or any alphanum
+        r'\]'                                 # ]
+        )
+    __OPTCRE = re.compile(
+        r'(?P<option>[-.\w]+)'                # - . _ alphanum
+        r'[ \t]*[:=][ \t]*'                   # any number of space/tab,
+                                              # followed by separator
+                                              # (either : or =), followed
+                                              # by any # space/tab
+        r'(?P<value>.*)$'                     # everything up to eol
+        )
+
     def __read(self, fp):
         """Parse a sectioned setup file.
 
@@ -211,9 +248,10 @@
         leading whitespace.  Blank lines, lines beginning with a '#',
         and just about everything else is ignored.
         """
-        cursect = None                  # None, or a dictionary
+        cursect = None                            # None, or a dictionary
         optname = None
         lineno = 0
+        e = None                                  # None, or an exception
         while 1:
             line = fp.readline()
             if not line:
@@ -226,31 +264,47 @@
                and line[0] == "r":      # no leading whitespace
                 continue
             # continuation line?
-            if line[0] in ' \t' and cursect <> None and optname:
+            if line[0] in ' \t' and cursect is not None and optname:
                 value = string.strip(line)
                 if value:
-                    cursect = cursect[optname] + '\n ' + value
-            # a section header?
-            elif secthead_cre.match(line) >= 0:
-                sectname = secthead_cre.group(1)
-                if self.__sections.has_key(sectname):
-                    cursect = self.__sections[sectname]
-                elif sectname == DEFAULTSECT:
-                    cursect = self.__defaults
-                else:
-                    cursect = {'name': sectname}
-                    self.__sections[sectname] = cursect
-                # So sections can't start with a continuation line.
-                optname = None
-            # an option line?
-            elif option_cre.match(line) >= 0:
-                optname, optval = option_cre.group(1, 3)
-                optname = string.lower(optname)
-                optval = string.strip(optval)
-                # allow empty values
-                if optval == '""':
-                    optval = ''
-                cursect[optname] = optval
-            # an error
+                    cursect[optname] = cursect[optname] + '\n ' + value
+            # a section header or option header?
             else:
-                print 'Error in %s at %d: %s', (fp.name, lineno, `line`)
+                # is it a section header?
+                mo = self.__SECTCRE.match(line)
+                if mo:
+                    sectname = mo.group('header')
+                    if self.__sections.has_key(sectname):
+                        cursect = self.__sections[sectname]
+                    elif sectname == DEFAULTSECT:
+                        cursect = self.__defaults
+                    else:
+                        cursect = {'__name__': sectname}
+                        self.__sections[sectname] = cursect
+                    # So sections can't start with a continuation line
+                    optname = None
+                # no section header in the file?
+                elif cursect is None:
+                    raise MissingSectionHeaderError(fp.name, lineno, `line`)
+                # an option line?
+                else:
+                    mo = self.__OPTCRE.match(line)
+                    if mo:
+                        optname, optval = mo.group('option', 'value')
+                        optname = string.lower(optname)
+                        optval = string.strip(optval)
+                        # allow empty values
+                        if optval == '""':
+                            optval = ''
+                        cursect[optname] = optval
+                    else:
+                        # a non-fatal parsing error occurred.  set up the
+                        # exception but keep going. the exception will be
+                        # raised at the end of the file and will contain a
+                        # list of all bogus lines
+                        if not e:
+                            e = ParsingError(fp.name)
+                        e.append(lineno, `line`)
+        # if any parsing errors occurred, raise an exception
+        if e:
+            raise e
diff --git a/Lib/dos-8x3/exceptio.py b/Lib/dos-8x3/exceptio.py
index ba63be6..28711df 100644
--- a/Lib/dos-8x3/exceptio.py
+++ b/Lib/dos-8x3/exceptio.py
@@ -80,15 +80,44 @@
     def __str__(self):
         return str(self.msg)
 
-class IOError(StandardError):
+class EnvironmentError(StandardError):
+    """Base class for exceptions that occur outside the Python system.
+    Primarily used as a base class for OSError and IOError."""
     def __init__(self, *args):
         self.args = args
         self.errno = None
         self.strerror = None
+        self.filename = None
+        if len(args) == 3:
+            # open() errors give third argument which is the filename.  BUT,
+            # so common in-place unpacking doesn't break, e.g.:
+            #
+            # except IOError, (errno, strerror):
+            #
+            # we hack args so that it only contains two items.  This also
+            # means we need our own __str__() which prints out the filename
+            # when it was supplied.
+            self.errno, self.strerror, self.filename = args
+            self.args = args[0:2]
         if len(args) == 2:
             # common case: PyErr_SetFromErrno()
-            self.errno = args[0]
-            self.strerror = args[1]
+            self.errno, self.strerror = args
+
+    def __str__(self):
+        if self.filename is not None:
+            return '[Errno %s] %s: %s' % (self.errno, self.strerror,
+                                          repr(self.filename))
+        elif self.errno and self.strerror:
+            return '[Errno %s] %s' % (self.errno, self.strerror)
+        else:
+            return StandardError.__str__(self)
+
+class IOError(EnvironmentError):
+    pass
+
+class OSError(EnvironmentError):
+    """Used by the posix module."""
+    pass
 
 class RuntimeError(StandardError):
     pass
diff --git a/Lib/dos-8x3/fileinpu.py b/Lib/dos-8x3/fileinpu.py
index 2f895e9..2e26b5b 100644
--- a/Lib/dos-8x3/fileinpu.py
+++ b/Lib/dos-8x3/fileinpu.py
@@ -142,6 +142,7 @@
         self._filelineno = 0
         self._file = None
         self._isstdin = 0
+        self._backupfilename = None
 
     def __del__(self):
         self.close()
diff --git a/Lib/dos-8x3/macurl2p.py b/Lib/dos-8x3/macurl2p.py
index dced58a..7d273bc 100755
--- a/Lib/dos-8x3/macurl2p.py
+++ b/Lib/dos-8x3/macurl2p.py
@@ -29,7 +29,7 @@
             i = i+1
     if not components[0]:
         # Absolute unix path, don't start with colon
-        return string.join(components[1:], ':')
+        rv = string.join(components[1:], ':')
     else:
         # relative unix path, start with colon. First replace
         # leading .. by empty strings (giving ::file)
@@ -37,7 +37,9 @@
         while i < len(components) and components[i] == '..':
             components[i] = ''
             i = i + 1
-        return ':' + string.join(components, ':')
+        rv = ':' + string.join(components, ':')
+    # and finally unquote slashes and other funny characters
+    return urllib.unquote(rv)
 
 def pathname2url(pathname):
     "convert mac pathname to /-delimited pathname"
@@ -54,13 +56,17 @@
         if components[i] == '':
             components[i] = '..'
     # Truncate names longer than 31 bytes
-    components = map(lambda x: x[:31], components)
+    components = map(_pncomp2url, components)
 
     if os.path.isabs(pathname):
         return '/' + string.join(components, '/')
     else:
         return string.join(components, '/')
-
+        
+def _pncomp2url(component):
+	component = urllib.quote(component[:31], safe='')  # We want to quote slashes
+	return component
+	
 def test():
     for url in ["index.html",
                 "bar/index.html",
diff --git a/Lib/dos-8x3/mimetool.py b/Lib/dos-8x3/mimetool.py
index 5489aa0..fc72c79 100755
--- a/Lib/dos-8x3/mimetool.py
+++ b/Lib/dos-8x3/mimetool.py
@@ -109,7 +109,7 @@
 def choose_boundary():
 	global _prefix
 	import time
-	import rand
+	import random
 	if _prefix == None:
 		import socket
 		import os
@@ -122,10 +122,9 @@
 		    pid = `os.getpid()`
 		except:
 		    pid = '1'
-		seed = `rand.rand()`
 		_prefix = hostid + '.' + uid + '.' + pid
-	timestamp = `int(time.time())`
-	seed = `rand.rand()`
+	timestamp = '%.3f' % time.time()
+	seed = `random.randint(0, 32767)`
 	return _prefix + '.' + timestamp + '.' + seed
 
 
diff --git a/Lib/dos-8x3/mimetype.py b/Lib/dos-8x3/mimetype.py
index 296c0ca..b35d0ff 100644
--- a/Lib/dos-8x3/mimetype.py
+++ b/Lib/dos-8x3/mimetype.py
@@ -1,9 +1,11 @@
 """Guess the MIME type of a file.
 
-This module defines one useful function:
+This module defines two useful functions:
 
 guess_type(url) -- guess the MIME type and encoding of a URL.
 
+guess_extension(type) -- guess the extension for a given MIME type.
+
 It also contains the following, for tuning the behavior:
 
 Data:
@@ -27,6 +29,8 @@
 knownfiles = [
     "/usr/local/etc/httpd/conf/mime.types",
     "/usr/local/lib/netscape/mime.types",
+    "/usr/local/etc/httpd/conf/mime.types",	# Apache 1.2
+    "/usr/local/etc/mime.types",		# Apache 1.3
     ]
 
 inited = 0
@@ -44,7 +48,7 @@
 
     The suffixes .tgz, .taz and .tz (case sensitive!) are all mapped
     to ".tar.gz".  (This is table-driven too, using the dictionary
-    suffixes_map).
+    suffix_map).
 
     """
     if not inited:
@@ -64,6 +68,24 @@
     else:
         return None, encoding
 
+def guess_extension(type):
+    """Guess the extension for a file based on its MIME type.
+
+    Return value is a string giving a filename extension, including the
+    leading dot ('.').  The extension is not guaranteed to have been
+    associated with any particular data stream, but would be mapped to the
+    MIME type `type' by guess_type().  If no extension can be guessed for
+    `type', None is returned.
+    """
+    global inited
+    if not inited:
+        init()
+    type = string.lower(type)
+    for ext, stype in types_map.items():
+        if type == stype:
+            return ext
+    return None
+
 def init(files=None):
     global inited
     for file in files or knownfiles:
@@ -184,6 +206,7 @@
     '.ustar': 'application/x-ustar',
     '.wav': 'audio/x-wav',
     '.xbm': 'image/x-xbitmap',
+    '.xml': 'text/xml',
     '.xpm': 'image/x-xpixmap',
     '.xwd': 'image/x-xwindowdump',
     '.zip': 'application/zip',
diff --git a/Lib/dos-8x3/mimewrit.py b/Lib/dos-8x3/mimewrit.py
index 0f8b990..754576b 100644
--- a/Lib/dos-8x3/mimewrit.py
+++ b/Lib/dos-8x3/mimewrit.py
@@ -125,4 +125,4 @@
 
 
 if __name__ == '__main__':
-    print "To test the MimeWriter module, run TestMimeWriter.py."
+    import test.test_MimeWriter
diff --git a/Lib/dos-8x3/multifil.py b/Lib/dos-8x3/multifil.py
index 8ba88e4..ce84087 100755
--- a/Lib/dos-8x3/multifil.py
+++ b/Lib/dos-8x3/multifil.py
@@ -18,26 +18,30 @@
 #
 # The latter sequence may be used recursively at (A).
 # It is also allowed to use multiple push()...pop() sequences.
-# Note that if a nested multipart message is terminated by a separator
-# for an outer message, this is not reported, even though it is really
-# illegal input.
+#
+# If seekable is given as 0, the class code will not do the bookeeping
+# it normally attempts in order to make seeks relative to the beginning of the
+# current file part.  This may be useful when using MultiFile with a non-
+# seekable stream object.
 
 import sys
 import string
 
-err = sys.stderr.write
-
 Error = 'multifile.Error'
 
 class MultiFile:
 	#
-	def __init__(self, fp):
+	seekable = 0
+	#
+	def __init__(self, fp, seekable=1):
 		self.fp = fp
 		self.stack = [] # Grows down
 		self.level = 0
 		self.last = 0
-		self.start = self.fp.tell()
-		self.posstack = [] # Grows down
+		if seekable:
+			self.seekable = 1
+			self.start = self.fp.tell()
+			self.posstack = [] # Grows down
 	#
 	def tell(self):
 		if self.level > 0:
@@ -62,36 +66,44 @@
 		self.last = 0
 	#
 	def readline(self):
-		if self.level > 0: return ''
+		if self.level > 0:
+			return ''
 		line = self.fp.readline()
+		# Real EOF?
 		if not line:
 			self.level = len(self.stack)
 			self.last = (self.level > 0)
 			if self.last:
-				err('*** Sudden EOF in MultiFile.readline()\n')
+				raise Error, 'sudden EOF in MultiFile.readline()'
 			return ''
-		if line[:2] <> '--': return line
-		n = len(line)
-		k = n
-		while k > 0 and line[k-1] in string.whitespace: k = k-1
-		mark = line[2:k]
-		if mark[-2:] == '--': mark1 = mark[:-2]
-		else: mark1 = None
+		assert self.level == 0
+		# Fast check to see if this is just data
+		if self.is_data(line):
+			return line
+		else:
+			# Ignore trailing whitespace on marker lines 
+			k = len(line) - 1;
+			while line[k] in string.whitespace:
+				k = k - 1
+			marker = line[:k+1]
+		# No?  OK, try to match a boundary.
+		# Return the line (unstripped) if we don't.
 		for i in range(len(self.stack)):
 			sep = self.stack[i]
-			if sep == mark:
+			if marker == self.section_divider(sep):
 				self.last = 0
 				break
-			elif mark1 <> None and sep == mark1:
+			elif marker == self.end_marker(sep):
 				self.last = 1
 				break
 		else:
 			return line
-		# Get here after break out of loop
-		self.lastpos = self.tell() - len(line)
+		# We only get here if we see a section divider or EOM line
+		if self.seekable:
+			self.lastpos = self.tell() - len(line)
 		self.level = i+1
 		if self.level > 1:
-			err('*** Missing endmarker in MultiFile.readline()\n')
+			raise Error,'Missing endmarker in MultiFile.readline()'
 		return ''
 	#
 	def readlines(self):
@@ -111,15 +123,17 @@
 			return 0
 		self.level = 0
 		self.last = 0
-		self.start = self.fp.tell()
+		if self.seekable:
+			self.start = self.fp.tell()
 		return 1
 	#
 	def push(self, sep):
 		if self.level > 0:
 			raise Error, 'bad MultiFile.push() call'
 		self.stack.insert(0, sep)
-		self.posstack.insert(0, self.start)
-		self.start = self.fp.tell()
+		if self.seekable:
+			self.posstack.insert(0, self.start)
+			self.start = self.fp.tell()
 	#
 	def pop(self):
 		if self.stack == []:
@@ -130,8 +144,17 @@
 			abslastpos = self.lastpos + self.start
 		self.level = max(0, self.level - 1)
 		del self.stack[0]
-		self.start = self.posstack[0]
-		del self.posstack[0]
-		if self.level > 0:
-			self.lastpos = abslastpos - self.start
+		if self.seekable:
+			self.start = self.posstack[0]
+			del self.posstack[0]
+			if self.level > 0:
+				self.lastpos = abslastpos - self.start
 	#
+	def is_data(self, line):
+		return line[:2] <> '--'
+	#
+	def section_divider(self, str):
+		return "--" + str
+	#
+	def end_marker(self, str):
+		return "--" + str + "--"
diff --git a/Lib/dos-8x3/posixpat.py b/Lib/dos-8x3/posixpat.py
index 1166881..a5c0de2 100755
--- a/Lib/dos-8x3/posixpat.py
+++ b/Lib/dos-8x3/posixpat.py
@@ -128,6 +128,24 @@
     return prefix
 
 
+# Get size, mtime, atime of files.
+
+def getsize(filename):
+    """Return the size of a file, reported by os.stat()."""
+    st = os.stat(filename)
+    return st[stat.ST_SIZE]
+
+def getmtime(filename):
+    """Return the last modification time of a file, reported by os.stat()."""
+    st = os.stat(filename)
+    return st[stat.ST_MTIME]
+
+def getatime(filename):
+    """Return the last access time of a file, reported by os.stat()."""
+    st = os.stat(filename)
+    return st[stat.ST_MTIME]
+
+
 # Is a path a symbolic link?
 # This will always return false on systems where os.lstat doesn't exist.
 
diff --git a/Lib/dos-8x3/py_compi.py b/Lib/dos-8x3/py_compi.py
index 949de6c..98b3b21 100755
--- a/Lib/dos-8x3/py_compi.py
+++ b/Lib/dos-8x3/py_compi.py
@@ -65,4 +65,3 @@
     if os.name == 'mac':
         import macfs
         macfs.FSSpec(cfile).SetCreatorType('Pyth', 'PYC ')
-        macfs.FSSpec(file).SetCreatorType('Pyth', 'TEXT')
diff --git a/Lib/dos-8x3/queue.py b/Lib/dos-8x3/queue.py
index 843b9dc..5e698ea 100755
--- a/Lib/dos-8x3/queue.py
+++ b/Lib/dos-8x3/queue.py
@@ -19,28 +19,28 @@
         self._init(maxsize)
         self.mutex = thread.allocate_lock()
         self.esema = thread.allocate_lock()
-        self.esema.acquire_lock()
+        self.esema.acquire()
         self.fsema = thread.allocate_lock()
 
     def qsize(self):
         """Returns the approximate size of the queue (not reliable!)."""
-        self.mutex.acquire_lock()
+        self.mutex.acquire()
         n = self._qsize()
-        self.mutex.release_lock()
+        self.mutex.release()
         return n
 
     def empty(self):
         """Returns 1 if the queue is empty, 0 otherwise (not reliable!)."""
-        self.mutex.acquire_lock()
+        self.mutex.acquire()
         n = self._empty()
-        self.mutex.release_lock()
+        self.mutex.release()
         return n
 
     def full(self):
         """Returns 1 if the queue is full, 0 otherwise (not reliable!)."""
-        self.mutex.acquire_lock()
+        self.mutex.acquire()
         n = self._full()
-        self.mutex.release_lock()
+        self.mutex.release()
         return n
 
     def put(self, item):
@@ -48,30 +48,30 @@
 
 	If the queue is full, block until a free slot is avaiable.
 	"""
-        self.fsema.acquire_lock()
-        self.mutex.acquire_lock()
+        self.fsema.acquire()
+        self.mutex.acquire()
         was_empty = self._empty()
         self._put(item)
         if was_empty:
-            self.esema.release_lock()
+            self.esema.release()
         if not self._full():
-            self.fsema.release_lock()
-        self.mutex.release_lock()
+            self.fsema.release()
+        self.mutex.release()
 
     def get(self):
         """Gets and returns an item from the queue.
 
         This method blocks if necessary until an item is available.
         """
-        self.esema.acquire_lock()
-        self.mutex.acquire_lock()
+        self.esema.acquire()
+        self.mutex.acquire()
         was_full = self._full()
         item = self._get()
         if was_full:
-            self.fsema.release_lock()
+            self.fsema.release()
         if not self._empty():
-            self.esema.release_lock()
-        self.mutex.release_lock()
+            self.esema.release()
+        self.mutex.release()
         return item
 
     # Get an item from the queue if one is immediately available,
@@ -83,27 +83,27 @@
         this raises the Empty exception if the queue is empty or
         temporarily unavailable.
         """
-        locked = self.esema.acquire_lock(0)
-        self.mutex.acquire_lock()
+        locked = self.esema.acquire(0)
+        self.mutex.acquire()
         if self._empty():
             # The queue is empty -- we can't have esema
-            self.mutex.release_lock()
+            self.mutex.release()
             raise Empty
         if not locked:
-            locked = self.esema.acquire_lock(0)
+            locked = self.esema.acquire(0)
             if not locked:
                 # Somebody else has esema
                 # but we have mutex --
                 # go out of their way
-                self.mutex.release_lock()
+                self.mutex.release()
                 raise Empty
         was_full = self._full()
         item = self._get()
         if was_full:
-            self.fsema.release_lock()
+            self.fsema.release()
         if not self._empty():
-            self.esema.release_lock()
-        self.mutex.release_lock()
+            self.esema.release()
+        self.mutex.release()
         return item
 
     # XXX Need to define put_nowait() as well.
diff --git a/Lib/dos-8x3/rlcomple.py b/Lib/dos-8x3/rlcomple.py
index e0ae72c..92633ab 100644
--- a/Lib/dos-8x3/rlcomple.py
+++ b/Lib/dos-8x3/rlcomple.py
@@ -58,7 +58,10 @@
                 self.matches = self.attr_matches(text)
             else:
                 self.matches = self.global_matches(text)
-        return self.matches[state]
+        try:
+            return self.matches[state]
+        except IndexError:
+            return None
 
     def global_matches(self, text):
         """Compute matches when text is a simple name.
diff --git a/Lib/dos-8x3/socketse.py b/Lib/dos-8x3/socketse.py
index cf8a365..0d0caac 100755
--- a/Lib/dos-8x3/socketse.py
+++ b/Lib/dos-8x3/socketse.py
@@ -265,7 +265,12 @@
     max_packet_size = 8192
 
     def get_request(self):
-        return self.socket.recvfrom(self.max_packet_size)
+        data, client_addr = self.socket.recvfrom(self.max_packet_size)
+        return (data, self.socket), client_addr
+
+    def server_activate(self):
+        # No need to call listen() for UDP.
+        pass
 
 
 if hasattr(socket, 'AF_UNIX'):
@@ -411,4 +416,4 @@
         self.wfile = StringIO.StringIO(self.packet)
 
     def finish(self):
-        self.socket.send(self.wfile.getvalue())
+        self.socket.sendto(self.wfile.getvalue(), self.client_address)
diff --git a/Lib/dos-8x3/test_arr.py b/Lib/dos-8x3/test_arr.py
index 6a0d17c..1e0f1be 100644
--- a/Lib/dos-8x3/test_arr.py
+++ b/Lib/dos-8x3/test_arr.py
@@ -3,7 +3,7 @@
    Roger E. Masse
 """
 import array
-from test_support import verbose, TESTFN, unlink
+from test_support import verbose, TESTFN, unlink, TestFailed
 
 def main():
 
@@ -54,6 +54,33 @@
             print 'array of %s converted to a string: ' \
                    % a.typecode, `a.tostring()`
 
+        if type == 'c':
+            a = array.array(type, "abcde")
+            a[:-1] = a
+            if a != array.array(type, "abcdee"):
+                raise TestFailed, "array(%s) self-slice-assign (head)" % `type`
+            a = array.array(type, "abcde")
+            a[1:] = a
+            if a != array.array(type, "aabcde"):
+                raise TestFailed, "array(%s) self-slice-assign (tail)" % `type`
+            a = array.array(type, "abcde")
+            a[1:-1] = a
+            if a != array.array(type, "aabcdee"):
+                raise TestFailed, "array(%s) self-slice-assign (cntr)" % `type`
+        else:
+            a = array.array(type, [1, 2, 3, 4, 5])
+            a[:-1] = a
+            if a != array.array(type, [1, 2, 3, 4, 5, 5]):
+                raise TestFailed, "array(%s) self-slice-assign (head)" % `type`
+            a = array.array(type, [1, 2, 3, 4, 5])
+            a[1:] = a
+            if a != array.array(type, [1, 1, 2, 3, 4, 5]):
+                raise TestFailed, "array(%s) self-slice-assign (tail)" % `type`
+            a = array.array(type, [1, 2, 3, 4, 5])
+            a[1:-1] = a
+            if a != array.array(type, [1, 1, 2, 3, 4, 5, 5]):
+                raise TestFailed, "array(%s) self-slice-assign (cntr)" % `type`
+
 
 main()
         
diff --git a/Lib/dos-8x3/test_fcn.py b/Lib/dos-8x3/test_fcn.py
index 2ae6b99..f2d4537 100644
--- a/Lib/dos-8x3/test_fcn.py
+++ b/Lib/dos-8x3/test_fcn.py
@@ -16,7 +16,7 @@
 if verbose:
     print 'Status from fnctl with O_NONBLOCK: ', rv
     
-if sys.platform in ('netbsd1', 'freebsd2', 'freebsd3'):
+if sys.platform in ('netbsd1', 'freebsd2', 'freebsd3', 'bsdos2', 'bsdos3'):
     lockdata = struct.pack('lxxxxlxxxxlhh', 0, 0, 0, FCNTL.F_WRLCK, 0)
 elif sys.platform in ['aix3', 'aix4']:
     lockdata = struct.pack('hhlllii', FCNTL.F_WRLCK, 0, 0, 0, 0, 0, 0)
diff --git a/Lib/dos-8x3/test_img.py b/Lib/dos-8x3/test_img.py
index aa9c414..b074320 100644
--- a/Lib/dos-8x3/test_img.py
+++ b/Lib/dos-8x3/test_img.py
@@ -4,7 +4,7 @@
    Roger E. Masse
 """
 
-from test_support import verbose, unlink
+from test_support import verbose, unlink, findfile
 
 import imgfile, uu, os
 
@@ -23,14 +23,6 @@
     unlink('test.rgb')
     unlink('greytest.rgb')
 
-def findfile(file):
-        if os.path.isabs(file): return file
-        import sys
-        for dn in sys.path:
-                fn = os.path.join(dn, file)
-                if os.path.exists(fn): return fn
-        return file
-
 def testimage(name):
     """Run through the imgfile's battery of possible methods
        on the image passed in name.
diff --git a/Lib/dos-8x3/test_rgb.py b/Lib/dos-8x3/test_rgb.py
index 0c449da..38bcdf5 100755
--- a/Lib/dos-8x3/test_rgb.py
+++ b/Lib/dos-8x3/test_rgb.py
@@ -2,25 +2,12 @@
 
 import rgbimg, os, uu
 
-from test_support import verbose, unlink
+from test_support import verbose, unlink, findfile
 
 error = 'test_rgbimg.error'
 
 print 'RGBimg test suite:'
 
-def findfile(file):
-        if os.path.isabs(file): return file
-        import sys
-        path = sys.path
-        try:
-            path = [os.path.dirname(__file__)] + path
-        except NameError:
-            pass
-        for dn in path:
-                fn = os.path.join(dn, file)
-                if os.path.exists(fn): return fn
-        return file
-
 def testimg(rgb_file, raw_file):
         rgb_file = findfile(rgb_file)
         raw_file = findfile(raw_file)
diff --git a/Lib/dos-8x3/test_sun.py b/Lib/dos-8x3/test_sun.py
index 1438c09..af18761 100644
--- a/Lib/dos-8x3/test_sun.py
+++ b/Lib/dos-8x3/test_sun.py
@@ -1,20 +1,7 @@
-from test_support import verbose, TestFailed
+from test_support import verbose, findfile, TestFailed
 import sunaudiodev
 import os
 
-def findfile(file):
-        if os.path.isabs(file): return file
-        import sys
-        path = sys.path
-        try:
-                path = [os.path.dirname(__file__)] + path
-        except NameError:
-                pass
-        for dn in path:
-                fn = os.path.join(dn, file)
-                if os.path.exists(fn): return fn
-        return file
-
 def play_sound_file(path):
     fp = open(path, 'r')
     data = fp.read()
diff --git a/Lib/dos-8x3/test_sup.py b/Lib/dos-8x3/test_sup.py
index 7dc1940..3839c79 100755
--- a/Lib/dos-8x3/test_sup.py
+++ b/Lib/dos-8x3/test_sup.py
@@ -41,3 +41,15 @@
 
 TESTFN = '@test' # Filename used for testing
 from os import unlink
+
+def findfile(file, here=__file__):
+	import os
+	if os.path.isabs(file):
+		return file
+	import sys
+	path = sys.path
+	path = [os.path.dirname(here)] + path
+	for dn in path:
+		fn = os.path.join(dn, file)
+		if os.path.exists(fn): return fn
+	return file
diff --git a/Lib/dos-8x3/test_thr.py b/Lib/dos-8x3/test_thr.py
index 113135b..710fb89 100755
--- a/Lib/dos-8x3/test_thr.py
+++ b/Lib/dos-8x3/test_thr.py
@@ -3,12 +3,12 @@
 # Create a bunch of threads, let each do some work, wait until all are done
 
 from test_support import verbose
-import whrandom
+import random
 import thread
 import time
 
 mutex = thread.allocate_lock()
-whmutex = thread.allocate_lock() # for calls to whrandom
+rmutex = thread.allocate_lock() # for calls to random
 running = 0
 done = thread.allocate_lock()
 done.acquire()
@@ -17,9 +17,9 @@
 
 def task(ident):
 	global running
-	whmutex.acquire()
-	delay = whrandom.random() * numtasks
-	whmutex.release()
+	rmutex.acquire()
+	delay = random.random() * numtasks
+	rmutex.release()
 	if verbose:
 	    print 'task', ident, 'will run for', round(delay, 1), 'sec'
 	time.sleep(delay)
@@ -85,9 +85,9 @@
 			# of the current one
 			delay = 0.001
 		else:
-			whmutex.acquire()
-			delay = whrandom.random() * numtasks
-			whmutex.release()
+			rmutex.acquire()
+			delay = random.random() * numtasks
+			rmutex.release()
 		if verbose:
 		    print 'task', ident, 'will run for', round(delay, 1), 'sec'
 		time.sleep(delay)
diff --git a/Lib/dos-8x3/test_tok.py b/Lib/dos-8x3/test_tok.py
index 34a7bfb..cd97e9a 100644
--- a/Lib/dos-8x3/test_tok.py
+++ b/Lib/dos-8x3/test_tok.py
@@ -1,18 +1,6 @@
-from test_support import verbose
+from test_support import verbose, findfile
 import tokenize, os, sys
 
-def findfile(file):
-	if os.path.isabs(file): return file
-	path = sys.path
-	try:
-	    path = [os.path.dirname(__file__)] + path
-	except NameError:
-	    pass
-	for dn in path:
-		fn = os.path.join(dn, file)
-		if os.path.exists(fn): return fn
-	return file
-
 if verbose:
     print 'starting...'
 file = open(findfile('tokenize_tests.py'))
diff --git a/Lib/dos-8x3/test_typ.py b/Lib/dos-8x3/test_typ.py
index 6be66ca..072e6d2 100755
--- a/Lib/dos-8x3/test_typ.py
+++ b/Lib/dos-8x3/test_typ.py
@@ -78,6 +78,18 @@
 if (-12L) + (-24L) <> -36L: raise TestFailed, 'long op'
 if not 12L < 24L: raise TestFailed, 'long op'
 if not -24L < -12L: raise TestFailed, 'long op'
+x = sys.maxint
+if int(long(x)) != x: raise TestFailed, 'long op'
+try: int(long(x)+1L)
+except OverflowError: pass
+else:raise TestFailed, 'long op'
+x = -x
+if int(long(x)) != x: raise TestFailed, 'long op'
+x = x-1
+if int(long(x)) != x: raise TestFailed, 'long op'
+try: int(long(x)-1L)
+except OverflowError: pass
+else:raise TestFailed, 'long op'
 print '6.4.3 Floating point numbers'
 if 12.0 + 24.0 <> 36.0: raise TestFailed, 'float op'
 if 12.0 + (-24.0) <> -12.0: raise TestFailed, 'float op'
@@ -122,6 +134,19 @@
 if min([1,2]) <> 1 or max([1,2]) <> 2: raise TestFailed, 'min/max list'
 if 0 in [0,1,2] and 1 in [0,1,2] and 2 in [0,1,2] and 3 not in [0,1,2]: pass
 else: raise TestFailed, 'in/not in list'
+a = [1, 2, 3, 4, 5]
+a[:-1] = a
+if a != [1, 2, 3, 4, 5, 5]:
+	raise TestFailed, "list self-slice-assign (head)"
+a = [1, 2, 3, 4, 5]
+a[1:] = a
+if a != [1, 1, 2, 3, 4, 5]:
+	raise TestFailed, "list self-slice-assign (tail)"
+a = [1, 2, 3, 4, 5]
+a[1:-1] = a
+if a != [1, 1, 2, 3, 4, 5, 5]:
+	raise TestFailed, "list self-slice-assign (center)"
+
 
 print '6.5.3a Additional list operations'
 a = [0,1,2,3,4]
diff --git a/Lib/dos-8x3/test_zli.py b/Lib/dos-8x3/test_zli.py
index 72dbcfa..047e985 100644
--- a/Lib/dos-8x3/test_zli.py
+++ b/Lib/dos-8x3/test_zli.py
@@ -11,9 +11,9 @@
 buf = file.read() * 8
 file.close()
 
-# test the chucksums
-print zlib.crc32('penguin'), zlib.crc32('penguin', 1)
-print zlib.adler32('penguin'), zlib.adler32('penguin', 1)
+# test the chucksums (hex so the test doesn't break on 64-bit machines)
+print hex(zlib.crc32('penguin')), hex(zlib.crc32('penguin', 1))
+print hex(zlib.adler32('penguin')), hex(zlib.adler32('penguin', 1))
 
 # make sure we generate some expected errors
 try:
diff --git a/Lib/dos-8x3/userlist.py b/Lib/dos-8x3/userlist.py
index 1f19ad9..5dfd182 100755
--- a/Lib/dos-8x3/userlist.py
+++ b/Lib/dos-8x3/userlist.py
@@ -43,6 +43,7 @@
 	__rmul__ = __mul__
 	def append(self, item): self.data.append(item)
 	def insert(self, i, item): self.data.insert(i, item)
+	def pop(self, i=-1): return self.data.pop(i)
 	def remove(self, item): self.data.remove(item)
 	def count(self, item): return self.data.count(item)
 	def index(self, item): return self.data.index(item)