#!/usr/bin/perl -w # # $Id: PKSFileReader.pm,v 1.2 2003/02/25 23:05:51 rlaager Exp $ # # Can be freely used - no warranties package PKSFileReader; use strict; # Parameter: # directory with all the files to read sub new { my $proto= shift; my $class= ref($proto) || $proto; my $self= {}; bless($self, $class); $self->initialize(@_); return $self; } # do the real initialisation sub initialize { my $self= shift; $self->{LARGEFILES}= []; $self->{SMALLFILES}= []; $self->{MINSIZEFORLARGEFILES}= 10000; $self->{MAXFILESINBUFFER}= 1000; $self->{DEBUG}= 0; # ----- directory to read from $self->{READDIR}= $_[0] . '/'; # assure having exactly one '/' at the end while ($self->{READDIR} =~ s!//$!/!) {}; $self->_openDirectory($self->{READDIR}); } sub setMaxFilesInBuffer() { my $self= shift; my ($size)= @_; if ($size > 0) { $self->{MAXFILESINBUFFER}= $size; } } sub setMinSizeForLargeFiles() { my $self= shift; my ($size)= @_; if ($size > 0) { $self->{MINSIZEFORLARGEFILES}= $size; } } sub setDebug() { my $self= shift; if ($_[0]) { $self->{DEBUG}= 1; } else { $self->{DEBUG}= 0; } } # open filehandle to read all files from this directory sub _openDirectory() { my $self= shift; my $dir= $_[0]; if (defined $self->{READDIR_FH}) { closedir($self->{READDIR_FH}) || print STDERR "Warning: could not close directoryhandle\n"; } opendir(FH, $dir) || die "could not open $dir for read: $!\n"; print "opened directory $dir for read\n" if $self->{DEBUG}; $self->{READDIR_FH}= \*FH; } # get a small file, return undef if no files are # avaiable at the moment sub getSmallFile { my $self= shift; if ($#{@{$self->{SMALLFILES}}} < 0) { $self->_readFiles(); } my $file= pop(@{$self->{SMALLFILES}}); return $file; } # get a large file, return undef if no files are # avaiable at the moment sub getLargeFile { my $self= shift; if ($#{@{$self->{LARGEFILES}}} < 0) { $self->_readFiles(); } my $file= pop(@{$self->{LARGEFILES}}); return $file; } # read filenames from directory, restart reading # the directory if end of directory reached # if directory has no (acceptable) files any more # return 0, else return number of file read in sub _readFiles { my $self= shift; my $filecount= $self->__readFiles(); if ($filecount == 0) { $self->_openDirectory($self->{READDIR}); $filecount= $self->__readFiles(); } return $filecount; } # read filenames from directory, return number of # (new) files read in sub __readFiles { my $self= shift; my $file= ''; my $filecount= 0; while (defined $file) { $file= $self->_getNextPKSFile(); if (defined $file) { stat($file); my $size= -s _; my $arr= undef; my $bufsize= 0; if ($size < $self->{MINSIZEFORLARGEFILES}) { $arr= $self->{SMALLFILES}; } else { $arr= $self->{LARGEFILES}; } if ((grep {$_ eq $file} @{$arr}) == 0) { $filecount++; push @{$arr}, $file; } else { print 'allready in the array (new size=' . $#{@{$arr}} . "): $file\n" if $self->{DEBUG}; } } my $bufsize= $#{@{$self->{SMALLFILES}}} + $#{@{$self->{LARGEFILES}}} + 2; if ($bufsize >= $self->{MAXFILESINBUFFER}) { print "buffer full\n" if $self->{DEBUG}; $file= undef; } } print "just readed $filecount files\n" if $self->{DEBUG}; return $filecount; } # get next file, returns undef if no more files are available sub _getNextPKSFile { my $self= shift; my $res= ''; my $fh= $self->{READDIR_FH}; while ((defined $res) && ($res eq '')) { my $entry= readdir($fh); if (! defined $entry) { $res= undef; } else { if ($entry =~ /^pks-mail/) { $res= $self->{READDIR} . $entry; } } } return $res; } 1; # so the require or use succeeds =head1 NAME PKSFileReader - class to read mail files =head1 DESCRIPTION Reads files from incoming directory and automatically rereads directory if necessary. =head1 USAGE $reader= PKSFileReader->new('/path/to/directory/'); $reader->setMaxFilesInBuffer(500); $file= $reader->getSmallFile(); $file= $reader->getLargeFile(); =cut