From 518654df61488d454c051951a18c7793b935a7d4 Mon Sep 17 00:00:00 2001
From: Paul Rodger <paul@paulrodger.com>
Date: Mon, 20 May 2002 06:14:54 +0000
Subject: We now call mkdir() to create a temporary directory to store any
 generated tempfiles. This should be a lot more secure.

---
 CHANGELOG           |  3 +++
 Makefile            |  2 +-
 TODO                |  1 +
 archivemail.py      | 49 ++++++++++++++++++++-----------------------------
 setup.py            |  2 +-
 test_archivemail.py | 37 -------------------------------------
 6 files changed, 26 insertions(+), 68 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 51a040c..3b48b20 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,6 @@
+Version 0.4.8   - 20 May 2002
+  * Call mkdir() to create a container directory in which we can place any
+    created tempfiles 
 
 Version 0.4.7   - 9 May 2002
   * Fixed a bug where archivemail would abort if it received a date header
diff --git a/Makefile b/Makefile
index 8979dee..288089a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 
-VERSION=0.4.7
+VERSION=0.4.8
 VERSION_TAG=v$(subst .,_,$(VERSION))
 TARFILE=archivemail-$(VERSION).tar.gz
 
diff --git a/TODO b/TODO
index f11f40c..77013d6 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,7 @@
 
 Goals for next minor release (0.4.8):
 -------------------------------------
+* When you get a file-not-found in the 6th mailbox of 10, it aborts
 * Think about the best way to specify the names of archives created with
   possibly an --archive-name option.
 * Add more tests (see top of test_archivemail.py)
diff --git a/archivemail.py b/archivemail.py
index dd19e0d..d82892e 100755
--- a/archivemail.py
+++ b/archivemail.py
@@ -22,7 +22,7 @@ Website: http://archivemail.sourceforge.net/
 """
 
 # global administrivia 
-__version__ = "archivemail v0.4.7"
+__version__ = "archivemail v0.4.8"
 __cvs_id__ = "$Id$"
 __copyright__ = """Copyright (C) 2002  Paul Rodger <paul@paulrodger.com>
 This is free software; see the source for copying conditions. There is NO
@@ -112,6 +112,7 @@ class StaleFiles:
     archive            = None  # tempfile for messages to be archived
     procmail_lock      = None  # original_mailbox.lock
     retain             = None  # tempfile for messages to be retained
+    temp_dir           = None  # our tempfile directory container
 
     def clean(self):
         """Delete any temporary files or lockfiles that exist"""
@@ -127,6 +128,10 @@ class StaleFiles:
             vprint("removing stale archive file '%s'" % self.archive)
             try: os.remove(self.archive)
             except (IOError, OSError): pass
+        if self.temp_dir:
+            vprint("removing stale tempfile directory '%s'" % self.temp_dir)
+            try: os.rmdir(self.temp_dir)
+            except (IOError, OSError): pass
 
 
 class Options:
@@ -418,7 +423,7 @@ class RetainMbox(Mbox):
 
         """
         assert(final_name)
-        temp_name = tempfile.mktemp("archivemail_retain")
+        temp_name = tempfile.mktemp("retain")
         self.mbox_file = open(temp_name, "w")
         self.mbox_file_name = temp_name
         _stale.retain = temp_name
@@ -490,7 +495,7 @@ class ArchiveMbox(Mbox):
             unexpected_error("""There is already a file named '%s'!
 Have you been previously compressing this archive? You probably should 
 uncompress it manually, and try running me again.""" % compressed_archive)
-        temp_name = tempfile.mktemp("archivemail_archive")
+        temp_name = tempfile.mktemp("archive")
         if os.path.isfile(final_name):
             vprint("file already exists that is named: %s" % final_name)
             shutil.copy2(final_name, temp_name)
@@ -507,7 +512,7 @@ uncompress it manually, and try running me again.""" % compressed_archive)
 Have you been reading this archive? You probably should re-compress it
 manually, and try running me again.""" % final_name)
 
-        temp_name = tempfile.mktemp("archivemail_archive.gz")
+        temp_name = tempfile.mktemp("archive.gz")
         if os.path.isfile(compressed_filename):
             vprint("file already exists that is named: %s" %  \
                 compressed_filename)
@@ -923,10 +928,16 @@ def archive(mailbox_name):
                 os.path.basename(final_archive_name))
     vprint("archiving '%s' to '%s' ..." % (mailbox_name, final_archive_name))
 
+    # create a temporary directory for us to work in securely
     old_temp_dir = tempfile.tempdir
-    tempfile.tempdir = choose_temp_dir(mailbox_name)
-    assert(tempfile.tempdir)
-    vprint("set tempfile directory to '%s'" % tempfile.tempdir)
+    tempfile.tempdir = None
+    new_temp_dir = tempfile.mktemp('archivemail')
+    assert(new_temp_dir)
+    os.mkdir(new_temp_dir)
+    _stale.temp_dir = new_temp_dir
+    tempfile.tempdir = new_temp_dir
+
+    vprint("set tempfile directory to '%s'" % new_temp_dir)
 
     # check to see if we are running as root -- if so, change our effective
     # userid and groupid to that of the original mailbox
@@ -961,6 +972,8 @@ def archive(mailbox_name):
         vprint("changing effective groupid and userid back to root")
         os.setegid(0)
         os.seteuid(0)
+    os.rmdir(new_temp_dir)
+    _stale.temp_dir = None
     tempfile.tempdir = old_temp_dir
 
 
@@ -1103,28 +1116,6 @@ def _archive_dir(mailbox_name, final_archive_name, type):
 ###############  misc  functions  ###############
 
 
-def choose_temp_dir(mailbox_name):
-    """Return a suitable temporary directory to use for a given mailbox name"""
-    assert(mailbox_name)
-    mailbox_dirname = os.path.dirname(mailbox_name)
-    temp_dir = None
-
-    if options.output_dir:
-        temp_dir = options.output_dir
-    elif mailbox_dirname:
-        temp_dir = mailbox_dirname
-    else:
-        temp_dir = os.curdir
-    assert(temp_dir)
-    if is_world_writable(temp_dir):
-        unexpected_error(("temporary directory is world-writable: " + \
-            "%s -- I feel nervous!") % temp_dir)
-    if not os.access(temp_dir, os.W_OK):
-        user_error("no write permission on temporary directory: '%s'" % \
-            temp_dir)
-    return temp_dir
-
-
 def set_signal_handlers():
     """set signal handlers to clean up temporary files on unexpected exit"""
     # Make sure we clean up nicely - we don't want to leave stale procmail
diff --git a/setup.py b/setup.py
index 43743ec..9e79173 100755
--- a/setup.py
+++ b/setup.py
@@ -19,7 +19,7 @@ check_python_version()  # define & run this early - 'distutils.core' is new
 from distutils.core import setup
 
 setup(name="archivemail",
-      version="0.4.7",
+      version="0.4.8",
       description="archive and compress old email",
       license="GNU GPL",
       url="http://archivemail.sourceforge.net/",
diff --git a/test_archivemail.py b/test_archivemail.py
index 0af5f7a..96f0cf6 100755
--- a/test_archivemail.py
+++ b/test_archivemail.py
@@ -300,43 +300,6 @@ class TestIsTooOld(unittest.TestCase):
             assert(not archivemail.is_older_than_days(time_message=time_msg, 
                 max_days=1))
 
-################ archivemail.choose_temp_dir() unit testing #############
-
-class TestChooseTempDir(unittest.TestCase):
-    def setUp(self):
-        self.output_dir = tempfile.mktemp()
-        os.mkdir(self.output_dir)
-        self.sub_dir = tempfile.mktemp()
-        os.mkdir(self.sub_dir)
-
-    def testCurrentDir(self):
-        """use the current directory as a temp directory with no output dir"""
-        archivemail.options.output_dir = None
-        dir = archivemail.choose_temp_dir("dummy")
-        self.assertEqual(dir, os.curdir)
-
-    def testSubDir(self):
-        """use the mailbox parent directory as a temp directory"""
-        archivemail.options.output_dir = None
-        dir = archivemail.choose_temp_dir(os.path.join(self.sub_dir, "dummy"))
-        self.assertEqual(dir, self.sub_dir)
-
-    def testOutputDir(self):
-        """use the output dir as a temp directory when specified"""
-        archivemail.options.output_dir = self.output_dir
-        dir = archivemail.choose_temp_dir("dummy")
-        self.assertEqual(dir, self.output_dir)
-
-    def testSubDirOutputDir(self):
-        """use the output dir as temp when given a mailbox directory"""
-        archivemail.options.output_dir = self.output_dir
-        dir = archivemail.choose_temp_dir(os.path.join(self.sub_dir, "dummy"))
-        self.assertEqual(dir, self.output_dir)
-
-    def tearDown(self):
-        os.rmdir(self.output_dir)
-        os.rmdir(self.sub_dir)
-
 
 ########## acceptance testing ###########
 
-- 
cgit v1.2.3