]>
Commit | Line | Data |
---|---|---|
c4ecf106 ER |
1 | # Description: do not overwrite <mailbox>_archive.gz when it is a symbolic link |
2 | # Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=349068 | |
3 | # Author: Serafeim Zanikolas <serzan@hellug.gr> | |
4 | # Last-Update: 2009-02-22 | |
5 | Index: archivemail/archivemail | |
6 | =================================================================== | |
7 | --- archivemail.orig/archivemail 2008-08-15 21:41:37.000000000 +0100 | |
8 | +++ archivemail/archivemail 2008-08-15 22:00:20.000000000 +0100 | |
9 | @@ -487,6 +487,20 @@ | |
10 | """Return the current size of the mbox file""" | |
11 | return os.path.getsize(self.mbox_file_name) | |
12 | ||
13 | + def get_link_target(self, file_name): | |
14 | + """Return the supplied file name if not a link; else its target.""" | |
15 | + if not os.path.islink(file_name): | |
16 | + return file_name | |
17 | + orig_file_name = prev = file_name | |
18 | + while os.path.islink(file_name): | |
19 | + prev = file_name | |
20 | + file_name = os.readlink(file_name) | |
21 | + if not os.path.isabs(file_name): | |
22 | + file_name = os.path.abspath(os.path.join(os.path.dirname(prev), | |
23 | + file_name)) | |
24 | + if not os.path.exists(file_name): | |
25 | + unexpected_error("%s is a broken symbolic link" % orig_file_name) | |
26 | + return file_name | |
27 | ||
28 | class RetainMbox(Mbox): | |
29 | """Class for holding messages that will be retained from the original | |
30 | @@ -525,6 +539,7 @@ | |
31 | mode = os.stat(self.__final_name)[stat.ST_MODE] | |
32 | os.chmod(self.mbox_file_name, mode) | |
33 | ||
34 | + self.__final_name = self.get_link_target(self.__final_name) | |
35 | vprint("renaming '%s' to '%s'" % (self.mbox_file_name, self.__final_name)) | |
36 | try: | |
37 | os.rename(self.mbox_file_name, self.__final_name) | |
38 | @@ -615,6 +630,7 @@ | |
39 | final_name = self.__final_name | |
40 | if not options.no_compress: | |
41 | final_name = final_name + ".gz" | |
42 | + final_name = self.get_link_target(final_name) | |
43 | vprint("renaming '%s' to '%s'" % (self.mbox_file_name, | |
44 | final_name)) | |
45 | try: | |
46 | @@ -1145,9 +1161,6 @@ | |
47 | tempfile.tempdir = new_temp_dir | |
48 | vprint("set tempfile directory to '%s'" % new_temp_dir) | |
49 | ||
50 | - if os.path.islink(mailbox_name): | |
51 | - unexpected_error("'%s' is a symbolic link -- I feel nervous!" % | |
52 | - mailbox_name) | |
53 | if imap_scheme == 'imap' or imap_scheme == 'imaps': | |
54 | vprint("guessing mailbox is of type: imap(s)") | |
55 | _archive_imap(mailbox_name, final_archive_name) | |
56 | Index: archivemail/test_archivemail.py | |
57 | =================================================================== | |
58 | --- archivemail.orig/test_archivemail.py 2008-08-15 21:40:56.000000000 +0100 | |
59 | +++ archivemail/test_archivemail.py 2008-08-15 21:59:10.000000000 +0100 | |
60 | @@ -99,6 +99,37 @@ | |
61 | ||
62 | ############ Mbox Class testing ############## | |
63 | ||
64 | +class TestMboxSymLinkResolution(TestCaseInTempdir): | |
65 | + def setUp(self): | |
66 | + super(TestMboxSymLinkResolution, self).setUp() | |
67 | + self.mbox_file_name = make_mbox() | |
68 | + self.mbox = archivemail.Mbox(self.mbox_file_name) | |
69 | + | |
70 | + def testAbsoluteSymlink(self): | |
71 | + """Resolve an absolute symlink in a different directory""" | |
72 | + link_name = "%s/symlink-to-mbox" % tempfile.mkdtemp() | |
73 | + os.symlink(self.mbox_file_name, link_name) | |
74 | + link_target = self.mbox.get_link_target(link_name) | |
75 | + self.assertEqual(self.mbox_file_name, link_target) | |
76 | + | |
77 | + def testRelativeSymlink(self): | |
78 | + """Resolve a relative symlink in a different directory""" | |
79 | + link_dir = tempfile.mkdtemp() | |
80 | + link_name = "%s/symlink-to-mbox" % link_dir | |
81 | + run = "cd %s && ln -s ../%s %s" % (link_dir,\ | |
82 | + os.path.basename(self.mbox_file_name),\ | |
83 | + os.path.basename(link_name)) | |
84 | + self.assertEqual(os.system(run), 0) | |
85 | + link_target = self.mbox.get_link_target(link_name) | |
86 | + self.assertEqual(self.mbox_file_name, link_target) | |
87 | + | |
88 | + def testBrokenSymlink(self): | |
89 | + """Archive name that is a broken link should raise an error""" | |
90 | + link_name = "%s/symlink-to-mbox" % tempfile.mkdtemp() | |
91 | + os.symlink("%s-missing" % self.mbox_file_name, link_name) | |
92 | + self.assertRaises(archivemail.UnexpectedError, | |
93 | + self.mbox.get_link_target, link_name) | |
94 | + | |
95 | class TestMboxIsEmpty(TestCaseInTempdir): | |
96 | def setUp(self): | |
97 | super(TestMboxIsEmpty, self).setUp() |