imap什么时候使用
本文是“在Perl中使用IMAP,第1部分”的续篇,并再次讨论了ifrom.pl工具。 在处理本文之前,请阅读上一篇文章的介绍性材料,以了解ifrom.ipl的具体机制。 本文中的新主题包括Maildir邮件存储格式和隧道(也称为端口转发)。
作为IMAP用户,ifrom.pl的扩展已经满足了我自己的需求,因此我希望它们也对您有用。
在计算环境中,建立网络连接的隧道 (也称为端口转发 ,尽管从技术上讲两者并不完全相同)是一种常见的技术。 建立隧道连接就是通过一个或多个目的地(但不一定是远程计算机)重定向它。 隧道应用程序通常不知道其携带的数据。 使用隧道的程序不知道。 常见的UNIX隧道应用程序是tunnel和OpenSSH等。 (当然,OpenSSH还具有其他用途,但隧道与它们非常吻合。)可以使用网络端口的任何程序也可以使用隧道网络端口。 可以将它视为可以隔壁访问的电话连接,就像遍及全球的电话连接一样容易。
除OpenSSH以外的SSH版本均支持隧道传输,但是由于OpenSSH的普及和不受限制的可用性,本文中的讨论和示例都将使用它。
在限制性环境中,隧道化非常有用。 假设您不允许连接到外部IMAP服务器,因为防火墙已配置为限制该活动。 您可以在端口转发模式下运行OpenSSH,以便将外部IMAP服务器上的端口143(IMAP)转发到本地计算机上的XYZ端口。 您无需登录IMAP服务器本身即可执行此操作! 您只需要一个中间的跳转点即可接受SSH连接,并且可以依次连接到IMAP服务器。 当然,如果您可以直接SSH到IMAP服务器,则连接将更快且更可靠,因为将消除中间跳转点。
您还可以从IMAP服务器隧道传输到您自己的计算机,从而逆转连接过程。
隧道的另一用途是加密连接。 使用OpenSSH进行隧道传输时,如果IMAP服务器未提供安全连接,则可以使用其加密功能来加密IMAP通信。 如果IMAP服务器已经提供了安全连接,您甚至可以执行此操作,因此您将对连接进行两次加密。 去野外。
为了提供隧道,我在ifrom.pl中添加了一个TUNNEL选项。 令人尴尬的简单。 实际上,我10个月大的女儿可以用一半的时间写一个更好的女儿(如果她不先吃键盘的话)。 我只是增加了一个-tunnel
选项ifrom.pl和当选项,我用它运行system()
# use -tunnel like so with OpenSSH:
# ifrom.pl -tunnel "ssh REMOTEHOST.COM -N -T -n -L 2002:127.0.0.1:143 &"
# [other options to follow...]
# This forwards the REMOTE port 143 on REMOTEHOST.COM to the LOCAL
# port 2002. See the OpenSSH documentation for details and more
# examples. There is no intermediate jump point.
if ($config->TUNNEL())
{
system($config->TUNNEL());
}
之后,我继续执行ifrom.pl否则会执行的操作。 也就是说,我连接到IMAP服务器并检查邮件。 这就是为什么使用隧道方便的原因-使用它的程序不必执行任何异常操作,因为魔术完全在数据传输层中。 在我的情况下,必须对ifrom.pl进行一些修改,但是程序的主要逻辑没有被触及。
Maildir是一种邮件存储格式。 Courier IMAP和qmail等用于存储用户的邮件。 Maildir由具有子目录“ cur”,“ new”和“ tmp”的单个目录组成。 可以有其他子目录,但它们将被忽略。 为了简单起见,我将Maildir目录称为“ Maildir”。
在上一段提到的三个子目录中,只有“新”直接使我们感兴趣。 Maildir在每个子目录中存储消息,每个文件一个。 这些文件是唯一命名的。
“新”子目录包含Maildir的所有新消息。 新内容的语义取决于特定的邮件传递代理(MDA)和其他使用Maildir的程序。 例如,Courier IMAP通过将已查看的邮件移出Maildir的“新”子目录来对其进行标记。
首先,我将-maildir
开关添加到ifrom.pl。 它只是一个标量,告诉我不要尝试IMAP连接,而要执行Maildir逻辑。
Maildir处理通过glob()
调用完成。 这意味着将使用本地外壳程序的通配符匹配“ Maildir / new / *”。 我本可以使用opendir()
和readdir()
,但是glob()
调用要简单得多。
对于通过glob()
调用找到的每个文件,我抓住发送者和主题并进行打印。 然后,如果给出了-dump
或-print
开关,我将通过逐个打印相应的文件来整体打印所请求的消息。 文件的顺序由外壳的glob()
函数确定。 我不进行日期排序,因为Shelldir对Maildir文件的排序很好(当仅通过qmail传送文件时,它已经按日期对它们进行排序)。 对于更多的邮件传递代理,可能需要进行日期排序。
if ($config->MAILDIR())
{
my $count = 0;
foreach my $file (glob($config->MAILDIR() . '/new/*'))
{
$count++;
open M, "<$file";
my $address = 'UNKNOWN';
my $subject = 'UNKNOWN';
while (<M>)
{
$address = $1 if m/^From: (.*)/; # the sender of the message
$subject = $1 if m/^Subject: (.*)/; # the subject of the message
last if $_ eq "\n";
}
printf "%5d %-35.35s %s\n", $count, $address, $subject;
if ($config->DUMP || grep {$_ == $count} @{$config->PRINT})
{
close M;
open M, "<$file";
print MARKER();
print foreach <M>;
print MARKER();
}
}
}
作为邮件服务器管理员,我不得不将用户的邮件从所谓的mbox格式(其中一个包含邮件的大文件)迁移到IMAP服务器。 因为ifrom.pl已经具有必要的IMAP逻辑,所以我添加了-import
开关并使用Mail::Box
模块来处理从mbox文件读取邮件。
这是一种较慢的方法,因为必须通过网络连接移动每条消息。 对于许多用户的真正批量导入,您可能必须考虑针对您的站点量身定制的更复杂的方法。 例如,如果您的站点使用Maildirs进行邮件存储,并且您正在从mbox格式进行迁移,则只需使用mbox-to-Maildir转换器(例如safecat)(顺便说一下,safecat还有许多其他用途)。 见safecat网站上MBOX到Maildir的转换配方(参见相关主题 )。
该auto_mailbox
参数-mailbox
(存储在MAILBOX_AUTO
常数)告诉ifrom.pl挑基于文件名的邮箱名称。 我在-import
开关的值上使用basename()
函数,并结合使用PREFIX
参数。 如果未指定auto_mailbox
,则-mailbox
所说的将是将调用新邮箱的内容。 因此, -import A/B/C/FILE -mailbox auto_mailbox
将创建并填充一个名为“ FILE”的IMAP文件夹,而-import A/B/C/FILE -mailbox XYZ
将创建并填充一个名为“ XYZ”的文件夹。
此外,如果看到名为“ XYZ.msf”的文件(XYZ可以是任何东西,.msf是Mozilla mbox索引文件扩展名),则仅将“ XYZ”用作文件名。 这使您可以执行以下操作: find DIRECTORY -name "*.msf" -exec ifrom.pl -import {} ... \;
它将“查找”结果一一传递给ifrom.pl。 它将找到所有Mozilla索引文件,然后ifrom.pl将一个一个地导入相应的邮箱。
PREFIX
告诉ifrom.pl IMAP服务器的前缀。 该前缀实际上可以从IMAP服务器使用namespace()
函数获得,但是对于诸如ifrom.pl之类的简单脚本而言,获取前缀的逻辑过于复杂。 如果需要IMAP前缀或IMAP分隔符,则可通过namespace()
。 例如,常见的UW IMAP前缀和分隔符是“”和“ /”,因此邮箱看起来像“ a / b / c”(请注意与文件名和目录名的相似性)。 Courier IMAP服务器前缀和分隔符为“ INBOX”。 和“。”,因此邮箱看起来像“ INBOX.abc”(请注意平面结构-Courier文件夹都位于顶层Maildir下,没有子目录)。
-dryrun
选项非常有用。 它使您可以看到ifrom.pl导入时将执行的所有操作,但实际导入不会发生。
elsif ($config->IMPORT)
{
eval { require Mail::Box::Manager; };
die "You need to install the Mail::Box module, exiting" if $!;
my $file = $config->IMPORT;
if ($file =~ m/^(.*)\.msf$/i)
{
$file = $1;
print "MSF file detected, using $file as the file name\n";
}
die "Can't access import file $file" unless -r $file;
if ($config->MAILBOX eq MAILBOX_AUTO)
{
$box = $config->PREFIX . basename($file);
}
my $mgr = Mail::Box::Manager->new;
my $folder = $mgr->open(folder => $file);
my $i;
if ($config->DRYRUN)
{
print "Skipping folder check and creation because a dry run was requested\n";
}
else
{
if ($imap->select($box))
{
print "Selected folder successfully, ready to import.\n"
if $config->VERBOSE;
}
else
{
print "Could not select folder $box, trying to create it...\n";
$imap->create($box)
or die "Could not create import folder: $@\n";
}
}
# Iterate over the messages.
foreach ($folder->messages)
{
printf "Appending to mailbox %s, message %d: ID %s, %d lines\n",
$box, ++$i, $_->messageId, $_->nrLines;
if ($config->DRYRUN)
{
print "Skipping import because a dry run was requested\n";
}
else
{
$imap->append($box, $_->string);
}
}
}
我写了一个帮助部分。 它简短而翔实,您可以使用ifrom.pl -help
。
我添加了一个MARKER()
常量,因为“ \ n === \ n \ n”分隔符经常使用。
对于Maildirs,我没加所有花哨的代码,IMAP有,如-backup
或-delete_mailbox_really
切换。 由于Maildir是本地功能,因此您可以通过本地安装的文件系统访问Maildir中的数据,因此备份和邮箱删除是简单的shell操作。 例如,要备份Maildir,请遵循以下示例:
rsync -avP --delete MaildirLocation Destination
# so, for example, to back up /var/qmail/maildirs/tzz
# to /home/tzz/backups
rsync -avP --delete /var/qmail/maildirs/tzz /home/tzz/backups
阅读rsync文档-通常,它是备份和目录同步的好工具。 如果您不使用它,那么就会错过当今可用的最佳UNIX工具之一。
Maildir和IMAP循环的逻辑看似相似,但是它们的相似性不足以进行合并。 如果将另一个邮件源添加到ifrom.pl,则将所有循环合并为一个循环也许是有意义的。 实际上,我不认为合并两个循环是不值得的,因为这会使程序逻辑更加混乱,我们将一无所获。
我添加了从命令行仅用数字调用-print
的功能,因此,您可以说ifrom.pl 1 2
代替ifrom.pl -print 1 -print 2
,对用户来说要好得多。 代码很简单; 只要确保先调用$config->args()
。
# all non-switch command-line arguments are implied -print requests
if (scalar @ARGV)
{
$config->print($_) foreach @ARGV;
}
ifrom.pl是我编写过的最有用的工具之一。 它既简单又快速,可以满足我的所有需求。 我希望您喜欢阅读本文,并且ifrom.pl将为您提供良好的服务。 另外,我希望您所获得的有关IMAP和Maildirs的知识将来会有所帮助。
随时浏览ifrom.pl并给我发送您的改进建议。
翻译自: https://www.ibm.com/developerworks/opensource/library/l-cpimap2/index.html
imap什么时候使用