ページャーでメッセージを表示すると、ローカルゾーンではなくUTCで日付ヘッダーに時刻が表示されます。インデックスビューには、現地時間が正しく表示されます。画面の下部にあるステータスバーに現地時間を表示する方法を説明するこの古いメーリングリストの投稿を見つけましたが、これでも画面上部のDateヘッダーの時刻を「修正」しません。ページャーにDateヘッダー時間を現地時間に変換する方法はありますか?
ページャーでメッセージを表示すると、ローカルゾーンではなくUTCで日付ヘッダーに時刻が表示されます。インデックスビューには、現地時間が正しく表示されます。画面の下部にあるステータスバーに現地時間を表示する方法を説明するこの古いメーリングリストの投稿を見つけましたが、これでも画面上部のDateヘッダーの時刻を「修正」しません。ページャーにDateヘッダー時間を現地時間に変換する方法はありますか?
回答:
あなたに.muttrc
追加次の行:
set display_filter="exec sed -r \"s/^Date:\\s*(([F-Wa-u]{3},\\s*)?[[:digit:]]{1,2}\\s+[A-Sa-y]{3}\\s+[[:digit:]]{4}\\s+[[:digit:]]{1,2}:[[:digit:]]{1,2}(:[[:digit:]]{1,2})?\\s+[+-][[:digit:]]{4})/date +'Date: %a, %d %b %Y %H:%M:%S %z' -d '\\1'/e\""
これにより、Date:
ヘッダーに有効なRFC形式の日付が含まれている場合、メッセージのヘッダー(表示のみ)がローカルタイムゾーンに変更されます。指定された日付形式が間違っていた場合(結局、信頼できないユーザー入力を処理しています)、それは保持されます。ヘッダーを介してシェルコードを挿入する可能性のある試みに対抗するために、sed
パターンはRFC 5322(このRFCはDate:
フィールドの形式を定義しています)に基づいてホワイトリストを実装します。
mutt
コマンドラインの長さは255文字以下に制限されていることに注意してください。したがって、sed
より厳しいホワイトリストを持つ元のコマンドを255バイトに収まるように最適化しました。メッセージを使用して他のことを行う場合sed
、スクリプトに含めることができる完全なコマンドは次のとおりです。
sed -r "s/^Date:\s*(((Mon|Tue|Wed|Thu|Fri|Sat|Sun),\s*)?[[:digit:]]{1,2}\s+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+[[:digit:]]{4}\s+[[:digit:]]{1,2}:[[:digit:]]{1,2}(:[[:digit:]]{1,2})?\s+[+-][[:digit:]]{4})/date +'Date: %a, %d %b %Y %H:%M:%S %z' -d '\1'/e"
sed
コマンドはコマンドのe
修飾子に依存していますs
。その修飾子はGNU拡張機能であり、macOSのsed
ものはBSD 拡張機能です。
インデックスのフォーマットはindex_format
設定によって制御されます。これはmuttによって生成されます。Date
ヘッダは雑種犬によって制御されていない、それだけで表示されますメッセージに含まれるヘッダです。UTC時間を示している場合は、送信サーバーがヘッダーの生成時にUTCを使用することを決定したためです。変更する唯一の方法は、受信時または表示時にメッセージ自体を実際に変更することです。
それを変更するということは、メール配信エージェントにフィルターを追加することを意味しますが、既存のDate
ヘッダーを解析して書き換えるには十分に洗練されている必要があります。メッセージを見るときに、メッセージをmuttで再フォーマットする方がほぼ確実に優れています。display_filter
プロパティを実行可能ファイルに設定すると、表示する前に実行可能ファイルを介して開いたすべてのメッセージがパイプされます。
メッセージの各行を読み取り、Dateヘッダーで置き換えるプログラムまたはシェルスクリプトを作成するか、既存のスクリプトを見つける必要があります(実際に動作する可能性があるようには見えませんが、ここにあります)一時ファイルを含める必要がある)
http://www.mail-archive.com/mutt-users@mutt.org/msg44341.html
これは、「pager_format」を使用して、ローカルのタイムゾーンで日付を表示することをお勧めします。
set pager_format = "%4C%Z%[!%b%e at%I:%M%p]%.20n%s%*-(%P)"
Gillesのアドバイスを受けて、ここに一時ファイルとを使用するバージョンがありformail
ます。
#!/bin/bash
TMPFILE=$(mktemp)
# save the message to a file
cat - >"$TMPFILE"
# extract the date header
DATE=$( formail -xDate: < "$TMPFILE" )
# convert to the current timezone (defined by TZ)
DATE=$( date -R -d "$DATE" )
# output the modified message
echo "Date: $DATE"
formail -fI Date < "$TMPFILE"
# clean up
rm -f "$TMPFILE"
Date:
ヘッダーを介したコードインジェクション攻撃を受けやすくなります。サブシェルを使用する場合は、入力を検証/サニタイズする必要があります。
procmailソリューションは次のとおりです。
# extract date from mail
:0
TMPDATE=| formail -x Date
# get local date
LOCALDATE=`date --rfc-2822 -d "$TMPDATE"`
# add it new header to the mail
:0 f
| formail -I "LocalDate: $LOCALDATE"
そして、muttrcにLocalDate:を表示します。
unignore localdate
display_filter
inに割り当てると思います.muttrc
。
set display_filter="/PATH/TO/THIS/PYTHON/FILE"
あなたの.muttrc
。
Python 3.3:
#!/usr/bin/env python3
import sys
import re
# import subprocess
from email.utils import format_datetime, parsedate_to_datetime
in_headers = True
for line in sys.stdin.readlines():
if line == "\n": in_headers = False
match = re.match(r'^Date: (.+)', line)
if not in_headers or not match:
print(line, end="")
continue
date_string = match.group(1)
# use this if you do not have python 3.3+
# converted_date = subprocess.Popen(['date','-d',date_string], stdout=subprocess.PIPE).communicate()[0].strip()
converted_date = format_datetime(parsedate_to_datetime(date_string).astimezone(tz=None))
print('Date:', converted_date)
Date:
ヘッダーを介したコードインジェクション攻撃を受けやすくなります。サブシェルに入った場合、入力を検証/サニタイズする必要があります。そうでない場合、スクリプトはセキュリティの観点から問題ありません。ただし、参照するすべてのメッセージで実行されるスクリプトの場合は非常に重くなります。
「Date」ヘッダーを保持すると同時に、「Local-Date」ヘッダーを追加してlocaltimeバージョンを含める必須のPerlソリューション:
#!/usr/bin/perl -n
use Date::Parse;
use POSIX;
use strict;
if (/^Date: (.*)$/) {
my $datestr = $1;
my $date = strftime ("%a, %d %b %Y %H:%M:%S",
localtime (str2time ($datestr)));
print "Local-Date: $date\n";
}
print;
Michaelの答えの最後に記載されているシェルスクリプトを作成しました。
#!/bin/bash
while IFS= read -r LINE; do
if [[ "${LINE}" =~ ^Date:\ .* ]]; then
DATE=${LINE#Date: }
# convert to the current timezone (defined by TZ)
DATE=$(date -d "${DATE}")
printf '%s' "Date: ${DATE}"
elif [[ -n $LINE ]]; then
# We've reach the end of the headers, so stop parsing
echo
exec cat
else
printf '%s\n' "${LINE}"
fi
done
formail
(procmailパッケージのreformail
一部)や(maildropの一部)などの専用ツールを使用して、既存のDate:
ヘッダーを抽出し、新しいヘッダーを配置することをお勧めします。Date:
ヘッダーの欠落や不正な形式などのエッジケースに注意してください。
filter.sed
ファイルに含めたいと思います。ありがとう!