cvs commit: qpsmtpd/t tempstuff.t
[email protected] (John Peacock) 22 Feb 2005 02:47:39 -0000
| Newsgroups | perl.cvs.qpsmtpd |
|---|---|
| Message-ID | <[email protected]> |
cvsuser 05/02/21 18:47:39
Modified: . Changes README.plugins
lib Qpsmtpd.pm
lib/Qpsmtpd Plugin.pm Transaction.pm
Added: t tempstuff.t
Log:
Abstracted spool_dir creation and added temp_file() and temp_dir() subs to
make it easier for plugins to manage temporary workspace. Also add POD and
tests for the new functions. Still need to add tests to the temp_*() calls
from a plugin.
Revision Changes Path
1.82 +7 -0 qpsmtpd/Changes
Index: Changes
===================================================================
RCS file: /cvs/public/qpsmtpd/Changes,v
retrieving revision 1.81
retrieving revision 1.82
diff -u -r1.81 -r1.82
--- Changes 15 Feb 2005 21:42:52 -0000 1.81
+++ Changes 22 Feb 2005 02:47:38 -0000 1.82
@@ -1,6 +1,13 @@
0.29
+ New temp_file() and temp_dir() methods; when used by plugins, they create
+ a filename or directory which will last only as long as the current
+ transaction. Also created a spool_dir() method which checks/creates the
+ spool_dir when the application starts up. All three methods are also
+ available in the base class where the temp_* objects are not automatically
+ limited to the transaction's lifetime. (John Peacock)
+
Added Gavin Carr's greylisting plugin
Renamed config/ to config.sample/
1.12 +29 -0 qpsmtpd/README.plugins
Index: README.plugins
===================================================================
RCS file: /cvs/public/qpsmtpd/README.plugins,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- README.plugins 9 Nov 2004 15:29:10 -0000 1.11
+++ README.plugins 22 Feb 2005 02:47:38 -0000 1.12
@@ -200,3 +200,32 @@
file. So if you have a plugin called xyz but want it to come early on,
you call it's config file 00_xyz, but that file still refers to the
plugin called xyz.
+
+=head1 Temporary Files
+
+The temporary file and directory functions can be used for plugin specific
+workfiles and will automatically be deleted at the end of the current
+transaction.
+
+=over 4
+
+=item temp_file()
+
+Returns a unique name of a file located in the default spool directory, but
+does not open that file (i.e. it is the name not a file handle).
+
+=item temp_dir()
+
+Returns the name of a unique directory located in the default spool
+directory, after creating the directory with 0700 rights. If you need a
+directory with different rights (say for an antivirus daemon), you will
+need to use the base function $self->qp->temp_dir() which takes a single
+parameter for the permissions requested (see L<mkdir> for details). A
+directory created like this will B<not> be deleted when the transaction is
+ended.
+
+=item spool_dir()
+
+Returns the configured system-wide spool directory.
+
+=back
1.47 +48 -0 qpsmtpd/lib/Qpsmtpd.pm
Index: Qpsmtpd.pm
===================================================================
RCS file: /cvs/public/qpsmtpd/lib/Qpsmtpd.pm,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -r1.46 -r1.47
--- Qpsmtpd.pm 27 Nov 2004 06:46:21 -0000 1.46
+++ Qpsmtpd.pm 22 Feb 2005 02:47:38 -0000 1.47
@@ -255,4 +255,52 @@
}
}
+sub spool_dir {
+ my $self = shift;
+
+ unless ( $self->{_spool_dir} ) { # first time through
+ my $spool_dir = $self->config('spool_dir')
+ || Qpsmtpd::Utils::tildeexp('~/tmp/');
+
+ $spool_dir .= "/" unless ($spool_dir =~ m!/$!);
+
+ $spool_dir =~ /^(.+)$/ or die "spool_dir not configured properly";
+ $spool_dir = $1; # cleanse the taint
+ $self->{_spool_dir} = $spool_dir;
+
+ # Make sure the spool dir has appropriate rights
+ if (-e $spool_dir) {
+ my $mode = (stat($spool_dir))[2];
+ warn "Permissions on spool_dir $spool_dir are not 0700" if $mode & 07077;
+ }
+
+ # And finally, create it if it doesn't already exist
+ -d $spool_dir or mkdir($spool_dir, 0700)
+ or die "Could not create spool_dir $spool_dir: $!";
+ }
+
+ return $self->{_spool_dir};
+}
+
+# For unique filenames. We write to a local tmp dir so we don't need
+# to make them unpredictable.
+my $transaction_counter = 0;
+
+sub temp_file {
+ my $self = shift;
+ my $filename = $self->spool_dir()
+ . join(":", time, $$, $transaction_counter++);
+ $filename =~ tr!A-Za-z0-9:/_-!!cd;
+ return $filename;
+}
+
+sub temp_dir {
+ my $self = shift;
+ my $mask = shift || 0700;
+ my $dirname = $self->temp_file();
+ -d $dirname or mkdir($dirname, $mask)
+ or die "Could not create temporary directory $dirname: $!";
+ return $dirname;
+}
+
1;
1.15 +18 -0 qpsmtpd/lib/Qpsmtpd/Plugin.pm
Index: Plugin.pm
===================================================================
RCS file: /cvs/public/qpsmtpd/lib/Qpsmtpd/Plugin.pm,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- Plugin.pm 18 Nov 2004 19:47:10 -0000 1.14
+++ Plugin.pm 22 Feb 2005 02:47:39 -0000 1.15
@@ -53,6 +53,24 @@
shift->qp->connection;
}
+sub spool_dir {
+ shift->qp->spool_dir;
+}
+
+sub temp_file {
+ my $self = shift;
+ my $tempfile = $self->qp->temp_file;
+ push @{$self->qp->transaction->{_temp_files}}, $tempfile;
+ return $tempfile;
+}
+
+sub temp_dir {
+ my $self = shift;
+ my $tempdir = $self->qp->temp_dir();
+ push @{$self->qp->transaction->{_temp_dirs}}, $tempdir;
+ return $tempdir;
+}
+
# plugin inheritance:
# usage:
# sub register {
1.19 +20 -20 qpsmtpd/lib/Qpsmtpd/Transaction.pm
Index: Transaction.pm
===================================================================
RCS file: /cvs/public/qpsmtpd/lib/Qpsmtpd/Transaction.pm,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- Transaction.pm 23 Sep 2004 18:54:58 -0000 1.18
+++ Transaction.pm 22 Feb 2005 02:47:39 -0000 1.19
@@ -7,10 +7,6 @@
use IO::File qw(O_RDWR O_CREAT);
-# For unique filenames. We write to a local tmp dir so we don't need
-# to make them unpredictable.
-my $transaction_counter = 0;
-
sub new { start(@_) }
sub start {
@@ -71,22 +67,7 @@
my $self = shift;
my $data = shift;
unless ($self->{_body_file}) {
- my $spool_dir = $self->config('spool_dir') ? $self->config('spool_dir')
- : Qpsmtpd::Utils::tildeexp('~/tmp/');
-
- $spool_dir .= "/" unless ($spool_dir =~ m!/$!);
-
- $spool_dir =~ /^(.+)$/ or die "spool_dir not configured properly";
- $spool_dir = $1;
-
- if (-e $spool_dir) {
- my $mode = (stat($spool_dir))[2];
- die "Permissions on spool_dir $spool_dir are not 0700" if $mode & 07077;
- }
-
- -d $spool_dir or mkdir($spool_dir, 0700) or die "Could not create spool_dir $spool_dir: $!";
- $self->{_filename} = $spool_dir . join(":", time, $$, $transaction_counter++);
- $self->{_filename} =~ tr!A-Za-z0-9:/_-!!cd;
+ $self->{_filename} = $self->temp_file();
$self->{_body_file} = IO::File->new($self->{_filename}, O_RDWR|O_CREAT, 0600)
or die "Could not open file $self->{_filename} - $! "; # . $self->{_body_file}->error;
}
@@ -129,6 +110,25 @@
if ($self->{_filename} and -e $self->{_filename}) {
unlink $self->{_filename} or $self->log(LOGERROR, "Could not unlink ", $self->{_filename}, ": $!");
}
+
+ # These may not exist
+ if ( $self->{_temp_files} ) {
+ $self->log(LOGDEBUG, "Cleaning up temporary transaction files");
+ foreach my $file ( @{$self->{_temp_files}} ) {
+ next unless -e $file;
+ unlink $file or $self->log(LOGERROR,
+ "Could not unlink temporary file", $file, ": $!");
+ }
+ }
+ # Ditto
+ if ( $self->{_temp_dirs} ) {
+ eval {use File::Path};
+ $self->log(LOGDEBUG, "Cleaning up temporary directories");
+ foreach my $dir ( @{$self->{_temp_dirs}} ) {
+ rmtree($dir) or $self->log(LOGERROR,
+ "Could not unlink temporary dir", $dir, ": $!");
+ }
+ }
}
1.1 qpsmtpd/t/tempstuff.t
Index: tempstuff.t
===================================================================
#!/usr/bin/perl -w
use Test::More qw(no_plan);
use File::Path;
use strict;
use lib 't';
use_ok('Test::Qpsmtpd');
BEGIN { # need this to happen before anything else
my $cwd = `pwd`;
chomp($cwd);
open my $spooldir, '>', "./config.sample/spool_dir";
print $spooldir "$cwd/t/tmp";
close $spooldir;
}
ok(my ($smtpd, $conn) = Test::Qpsmtpd->new_conn(), "get new connection");
my ($spool_dir,$tempfile,$tempdir) = ( $smtpd->spool_dir,
$smtpd->temp_file(), $smtpd->temp_dir() );
ok( $spool_dir =~ m!t/tmp/$!, "Located the spool directory");
ok( $tempfile =~ /^$spool_dir/, "Temporary filename" );
ok( $tempdir =~ /^$spool_dir/, "Temporary directory" );
ok( -d $tempdir, "And that directory exists" );
unlink "./config.sample/spool_dir";
rmtree($spool_dir);