【问题标题】:procmail recipe causes wrong timestampprocmail 配方导致错误的时间戳
【发布时间】:2015-01-29 00:24:02
【问题描述】:

这个原本有效的方法会导致邮件客户端将“接收”时间误解为快 5 小时。这是唯一使用的配方。在比较写入两个标题的日期/时间时,基本上没有区别。有什么好的解决方法?食谱可以补偿吗?

LOGFILE=$HOME/proclog
VERBOSE=YES 

# prevent qmail (the program that is calling procmail 
# as a filter) from delivering the original mail.

EXITCODE=99 

MAILDIR=$HOME/boxes/mydomain.com
INBOX=$MAILDIR/bob
GREY=$MAILDIR/bob^/.imap/grey
JUNK=$MAILDIR/bob^/.imap/Junk
TEST=$MAILDIR/bob^/.imap/Test 

:0
* ^Subject:.*test
${TEST}

# Spam level < 2.0: it's probably real email, deliver as normal 
:0
${INBOX}

以下是下午 4:05 发送的电子邮件的标题,但显示在桌面电子邮件客户端和 iOS 上是在晚上 9:05 收到的。

Return-Path: <from_email@domain.com>
Delivered-To: username-domain:com-bob@domain.com
X-Envelope-To: bob@domain.com
Received: (qmail 16283 invoked from network); 29 Jan 2015 00:05:59 -0000
Received: from mailwash46.pair.com (IP ADDRESS)
  by tanha.pair.com with SMTP; 29 Jan 2015 00:05:59 -0000
Received: from localhost (localhost [127.0.0.1])
    by mailwash46.pair.com (Postfix) with SMTP id 31958EBC17
    for <bob@domain.com>; Wed, 28 Jan 2015 19:05:59 -0500 (EST)
Received: from tanha.pair.com (tanha.pair.com [IP ADDRESS])
    by mailwash46.pair.com (Postfix) with ESMTP id 0E9EBEBFB5
    for <bob@domain.com>; Wed, 28 Jan 2015 19:05:59 -0500 (EST)
Received: from [192.168.1.230] (c-IP ADDRESS.hsd1.wa.comcast.net [IP ADDRESS])
    by tanha.pair.com (Postfix) with ESMTPSA id BE211F1D10
    for <bob@domain.com>; Wed, 28 Jan 2015 19:05:58 -0500 (EST)
User-Agent: Microsoft-Entourage/12.20.0.xxxx
Date: Wed, 28 Jan 2015 16:05:57 -0800
Subject: 405pm test
From: "Robert" <from_email@domain.com>
To: "bob@domain.com" <bob@domain.com>
Message-ID: <D0EEB965.49C7D%from_email@domain.com>
Thread-Topic: 405pm test
Thread-Index: AdA7V1sU8z5udBOZSUyJx4az1tpIXA==
Mime-version: 1.0
Content-type: multipart/alternative;
    boundary="B_3505305958_xxxxxx"

还有一封显示正确时间的电子邮件(基本相同):

Return-Path: <from_email@domain.com>
Delivered-To: username-domain:com-bob@domain.com
X-Envelope-To: bob@domain.com
Received: (qmail 22574 invoked from network); 30 Jan 2015 02:35:23 -0000
Received: from mailwash46.pair.com (IP ADDRESS)
  by tanha.pair.com with SMTP; 30 Jan 2015 02:35:23 -0000
Received: from localhost (localhost [127.0.0.1])
    by mailwash46.pair.com (Postfix) with SMTP id 4CF3BEBF9D
    for <bob@domain.com>; Thu, 29 Jan 2015 21:35:23 -0500 (EST)
Received: from tanha.pair.com (tanha.pair.com [IP ADDRESS])
    by mailwash46.pair.com (Postfix) with ESMTP id 4C278EBF97
    for <bob@domain.com>; Thu, 29 Jan 2015 21:35:23 -0500 (EST)
Received: from [192.168.1.230] (c-IP ADDRESS.hsd1.wa.comcast.net [IP ADDRESS])
    by tanha.pair.com (Postfix) with ESMTPSA id 55E98F1BF8
    for <bob@domain.com>; Thu, 29 Jan 2015 21:35:21 -0500 (EST)
User-Agent: Microsoft-Entourage/12.20.0.xxxxxxxx
Date: Thu, 29 Jan 2015 18:35:16 -0800
Subject: test
From: "Robert." <from_email@domain.com>
To: "bob@domain.com" <bob@domain.com>
Message-ID: <D0F02DE4.49D82%from_email@domain.com>
Thread-Topic: test
Thread-Index: AdA8NWF58VbsQ1XhgkuMBHgxsaYksg==
Mime-version: 1.0
Content-type: multipart/alternative;
    boundary="B_3505401322_xxxxxxxx"

【问题讨论】:

  • 邮件客户端不应以任何方式解释Received: 标头。您能否举例说明它的外观以及您希望它的外观?我怀疑这只是 UTC 与本地的对比,完全没有错。
  • 我的邮件客户端有一个发送和接收栏。发送列显示正确的时间。在 ios (Mail) 上,它仅显示 +5hr 时间。我应该注意到(据我所知)没有调用 EXITCODE=99,系统会发送原始电子邮件(我认为是通过 qmail),然后将同一电子邮件的 procmail 过滤版本发送到它被告知去的任何地方。这是显示时间差异的第二封过滤电子邮件。
  • 听起来好像不是Received: 标头,但无论哪种方式,请在您的问题中包含示例消息的标头并指出哪一部分是错误的。
  • 我不确定标题的哪一部分负责在接收列中显示时间(考虑到 PST)。旁注:奇怪的是,当没有调用 EXITCODE=99 时,系统生成了两封最上面的电子邮件(405pm 测试),一封显示正确的时间,另一封显示 5 小时快。这些电子邮件的两个标题完全相同。
  • ...tanha.pair.com 的 IP 地址又不是保密的。

标签: procmail


【解决方案1】:

我正在发布第二个答案,以从 Procmail 的角度解决 IMAP 服务器端的猜测。

如果 Qmail 在发送到您的收件箱时做了一些特别的事情,您需要从您的 Procmail 食谱中做同样的事情。那么你在哪里

:0
$INBOX

你应该有

:0
| whatever it is that qmail is doing to deliver into "$INBOX"

很抱歉,我不能更具体地说明应该在管道中做什么。根据 IMAP 服务器,您可以查找 Dovecot、Courier(但似乎更喜欢 maildrop 而不是 procmail)、Cyrus 等的流行交付操作;或者只是查看您的 ISP 的 Qmail 配置,看看它在做什么。

【讨论】:

  • 非常感谢。我会继续努力解决这个问题。
【解决方案2】:

我试图寻找“接收日期”的正确规范,但找不到。但是,我偶然发现了https://bugzilla.mozilla.org/show_bug.cgi?id=402594,它在两行之间表明邮件客户端实际上正在解析Received: 标头以获取此信息。现在,问题仍然存在,他们查看的是哪个 Received: 标头,在您的问题案例中这个标头有什么问题?那里没有任何内容专门转换为 21:05(IMAP 客户端显示的时间戳的精确副本将便于诊断),因此这完全是推测性的 - 但如果您能提出更好的推测,请参阅至少我可以向您展示如何解决如何替换标题中的某些内容的技术问题。

我假设我们应该查看最顶部的 Received: 标头并将其时区标准化为您希望看到的任何时间(似乎是 -0800 PST)。

TZ="America/Los_Angeles"
:0fhW
* ^Received:[   ]*from[         ]*.*($[         ].*)*; \
        ()\/(Mon|T(ue|hu)|Wed|Fri|S(at|un)), \
        [0-3 ][0-9] (A(pr|ug)|Dec|Feb|J(an|u[nl])|Ma[ry]|Oct|Sep) \
        20[1-9][0-9] [0-2][0-9]:[0-5][0-9]:[0-6][0-9] [-+][01][0-9][0134][05] \
        \([A-Z]+T\)
| d=`date -R -d "$MATCH"`; sed "s/$MATCH/$d/"

现在,这显然相当脆弱,但至少粗略地向您展示了如何做到这一点。对于更可移植和更健壮的方法,我可能会将其放入外部脚本(Python、Perl、你有什么)而不是在 Procmail 和 shell 脚本中编码。 (当然,您仍然可以从 Procmail 运行它——我只需制作一个脚本,该脚本可以在您收到的所有电子邮件上运行,它只会修改需要更改的电子邮件。)

这会从第一个匹配的标头中提取日期戳(也许您应该将其调整为仅匹配 -0500 时区?)并将该特定日期字符串上的任何匹配替换为通过调用 @ 生成的新字符串987654327@ 以捕获的日期作为参数,将其转换为正在运行的任何时区(我们使用 TZ 变量赋值进行设置——这是一个棘手的巫术,我永远记不起数字时区的正确语法所以我只是简单地查找了 -0800 的通用名称)。

日期戳正则表达式是临时的,但我似乎至少记得一个月中的个位数天的空格与零填充,以及闰秒和时区,它们与 UTC 的偶数小时不同。我确信我仍然缺少一些细节,或者只是愚蠢的想法。

我忽略了一个更顶级的 (qmail xxx invoked from network) 标头 - 它具有不同的非 RFC822 格式的时间戳,所以我猜你的 IMAP 客户端也会忽略它。

\/ 正则表达式捕获标记之前的古怪空括号是因为 Procmail 在涉及行首的反斜杠时很古怪。

【讨论】:

  • 另一种猜测是客户端以某种方式向 IMAP 服务器查询时间戳,该时间戳以某种方式保存在其内部数据库中。也许弄清楚这是哪个 IMAP 服务器,以及 Qmail 在传递到其消息存储时是否以某种方式做了一些特别的事情。
  • 好的,非常感谢。我承认这有点超出我的想象。消息未送达。这是日志,对不起,这不是更可读:procmail:执行“d =date -R -d "$MATCH"; sed“s/$MATCH/$d/”日期:非法选项--R用法:日期[-jnu] [- d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ... [-f fmt date | [[[[[cc]yy]mm]dd]HH]MM[.ss]] [+format] d=: 找不到命令。 d:未定义的变量。 procmail: 非零退出代码 (1) 来自 "d=date -R -d "$MATCH"; sed "s/$MATCH/$d/"" procmail: 未过滤数据的救援成功
  • GNU date 有一个 -R 选项,它产生 RFC822 日期格式,但显然你没有那个(或者你的 GNU coreutils 真的很旧)。用可移植的脚本语言编写它还有一点。
  • 但同样,对于具有相同标题的两条消息,您得到不同的结果这一事实强烈暗示这与您的 Procmail 配方完全无关。我实际上很想提名此迁移到serverfault.com,因为您的问题似乎与一般编程和特别是 Procmail 脚本无关。或者,也许,接受这个答案并在 SF 上再次询问,提供更多不同的细节。
  • 您可以使用date +'%a, %d %b %Y %H:%M:%S %z (%Z)' 获取RFC 822 日期,其中(%Z) 是可选的(它只是根据RFC822 的注释),前提是您的date 具有所有这些格式字符串。 (%z 可能会丢失,在这种情况下,再次尝试使用具有适当日期库的脚本语言。)
猜你喜欢
  • 2011-12-02
  • 2018-09-01
  • 2015-03-31
  • 2021-03-25
  • 1970-01-01
  • 1970-01-01
  • 2017-07-27
  • 1970-01-01
  • 2018-11-27
相关资源
最近更新 更多