[Mimedefang] Re: replace_with_url with multiple small
Yizhar Hurwitz
yizhar at mail.com
Sat Dec 23 09:16:57 EST 2006
HI.
From: "Matthew S. Cramer" <mscramer at armstrong.com>
> I haven't really thought about it until now, so if anyone else wants
> to comment with suggestions or with sample code to handle this situation
> with all links together (in one text part replacement, ideally I
> guess), please do! That would be more elegant than what I've done.
>
>
I have also researched and played with this.
First - replace_with_url is really a great feature,
so one more thank to David.
Below is my custom implementation which is intended for the following goals:
* It works in a similar way to what "AddWarningsInline" does,
but AddWarningsInline breaks the html links and this is why I used a
custom code.
* Make it user friendly for those who use Microsoft Outlook,
by placing the links inline the message body.
MS Outlook doesn't display multiple inline text attachments.
* Place the links in both text and html parts.
* List all replaced attachments in a single list.
Currently in my script the generated message contains each link doubled
(once as another text/html attachment, and once again in the body).
* Create a subdirectory for each month,
this is to make maintenance easier.
For example:
rootpath/2006-12/filename.ext
My "sub custom_action_replace_with_url" code is a copy of the original
one with the addition of the lines:
### Begin modified section: ###
push (@DetachedFiles, $cd_data. "\n". $url. "\n");
### End modified section. ###
To David - when you find the right time,
please try to polish the built in replace_with_url function to work in a
similar way,
and test the generated output with MS Outlook in the eyes of an end user,
which doesn't know what to do unless he gets a clickable and easy to use
link.
=============== mimedefang-filter ====================
### Global variables (constants):
$HostName = hostname();
$DetachBigEnable = 0;
$DetachBigSizeMB = 10;
$DetachMultimediaEnable = 0;
$DetachMultimediaExt = 'asf|avi|mov|mpeg|mpg|wmv';
$DetachBasePath = '/var/www/detach';
$DetachBaseURL = 'http://'. $HostName;
$DetachText =
"\n\n".
"The following file was detached from the original message:\n".
"_FILENAME_\n".
"Size: _FILESIZE_\n".
"You can download it here:\n\n".
"_URL_\n\n".
"Please note that the download process can take some time.\n" .
"Please note that the files will later be deleted from the mail server.\n";
$DetachListTextTop =
"\n".
"The following files were detached:\n\n";
$DetachListTextBot =
"\n\n".
"Please note that the files will later be deleted from the mail server.\n";
######
sub filter_initialize {
$DetachSubdir = '/'. substr(time_str, 0, 7);
$DetachPath = $DetachBasePath. $DetachSubdir;
$DetachURL = $DetachBaseURL. $DetachSubdir;
if ($DetachBigEnable or $DetachMultimediaEnable) {
unless (-e $DetachPath) {
mkdir ($DetachPath);
chmod (0755, $DetachPath);
}
}
# Other code .....
}
######
sub filter_begin {
my($entity) = @_;
@DetachedFiles = ();
# other code...
}
sub custom_action_replace_with_url ($$$$;$$) {
my($entity, $doc_root, $base_url, $msg, $cd_data, $salt) = @_;
my($ctx);
my($path);
my($fname, $ext, $name, $url);
my $extension = "";
return 0 unless in_filter_context("action_replace_with_url");
return 0 unless defined($entity->bodyhandle);
$path = $entity->bodyhandle->path;
return 0 unless defined($path);
open(IN, "<$path") or return 0;
$ctx = Digest::SHA1->new;
$ctx->addfile(*IN);
$ctx->add($salt) if defined($salt);
close(IN);
$fname = takeStabAtFilename($entity);
$fname = "" unless defined($fname);
$extension = $1 if ($fname =~ /(\.[^.]*)$/);
# Use extension if it is .[alpha,digit,underscore]
$extension = "" unless ($extension =~ /^\.[A-Za-z0-9_]*$/);
# Filename to save
$name = $ctx->hexdigest . $extension;
$fname = $doc_root . "/" . $name;
$url = $base_url . "/" . $name;
if (-r $fname) {
# If file exists, then this is either a duplicate or someone
# has defeated SHA1. Just update the mtime on the file.
my($now);
$now = time;
utime($now, $now, $fname);
} else {
copy_or_link($path, $fname) or return 0;
# In case umask is whacked...
chmod 0644, $fname;
}
# save optional Content-Disposition data
if (defined($cd_data) and ($cd_data ne "")) {
if (open CDF, ">$doc_root/.$name") {
print CDF $cd_data;
close CDF;
chmod 0644, "$doc_root/.$name";
}
}
$msg =~ s/_URL_/$url/g;
action_replace_with_warning($msg);
### Begin modified section: ###
push (@DetachedFiles, $cd_data. "\n". $url. "\n");
### End modified section. ###
return 1;
}
######
sub filter {
my($entity, $fname, $ext, $type) = @_;
my $FileSize;
my $detach_msg;
# Other code ...
$FileSize = (stat($entity->bodyhandle->path))[7];
if (($DetachBigEnable and ($FileSize >= $DetachBigSizeMB*1000000))
or ($DetachMultimediaEnable and ($ext =~ /^\.($DetachMultimediaExt)$/i))) {
md_graphdefang_log('detached', $fname, $FileSize);
$detach_msg = $DetachText;
$detach_msg =~ s/_FILENAME_/$fname/g;
$detach_msg =~ s/_FILESIZE_/$FileSize/g;
return custom_action_replace_with_url($entity, $DetachPath,
$DetachURL, $detach_msg, $fname);
}
# Other code ...
}
#***********************************************************************
# %PROCEDURE: list_detached_files
#***********************************************************************
sub list_detached_files ($) {
my($entity) = @_;
my $plain = $DetachListTextTop. join("\n", @DetachedFiles).
$DetachListTextBot;
my $html = $plain;
$html =~ s|(http://\S*)|<a href="$1">$1</a>|g;
$html =~ s/\n/<br>\n/g;
append_text_boilerplate($entity, $plain, 0);
append_html_boilerplate($entity, $html, 0);
}
######
sub filter_end {
my($entity) = @_;
# No sense doing any extra work
return if message_rejected();
if (@DetachedFiles > 0) {
&list_detached_files($entity);
}
# Other code ...
}
=============== mimedefang-filter ====================
Comments are welcome.
BTW - Sample CGI scripts for downloading the files are welcome also,
as currently my users get the SHA1 filename instead of the original one.
I guess that it is easy but didn't play with it yet.
Yizhar Hurwitz
http://yizhar.mvps.org
More information about the MIMEDefang
mailing list