当前位置: 首页 > 工具软件 > UW IMAP > 使用案例 >

imap什么时候使用_将IMAP与Perl结合使用,第2部分

邢凌
2023-12-01

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()

清单1.使用ifrom.pl的TUNNEL选项
# 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支持

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传送文件时,它已经按日期对它们进行排序)。 对于更多的邮件传递代理,可能需要进行日期排序。

清单2. ifrom.pl中的Maildir支持
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导入时将执行的所有操作,但实际导入不会发生。

清单3.导入邮件
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,请遵循以下示例:

清单4.备份本地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()

清单5.将命令行参数放入-print开关
# 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什么时候使用

 类似资料: