호출기의 현지 시간대로 날짜 헤더를 표시하도록 mutt를 구성하려면 어떻게해야합니까?


13

호출기에서 메시지를 볼 때 mutt는 현지 시간대가 아닌 UTC로 날짜 헤더의 시간을 표시합니다. 인덱스 뷰는 현지 시간을 올바르게 표시합니다. 화면 하단의 상태 표시 줄에 현지 시간을 표시하는 방법을 설명하는 이 오래된 메일 링리스트 게시물 을 찾았 지만 여전히 화면 상단의 날짜 헤더에 시간이 "고정"되지 않습니다. 호출기에서 Date 헤더 시간을 현지 시간으로 변환하는 방법이 있습니까?

답변:


3

당신에 .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 이상의 문자로 명령 행을 제한 긴, 그래서 나는 원래 최적화 된 sed255 바이트에 맞게 화이트리스트 엄격한 있었다 명령을 사용합니다. 메시지로 다른 작업을 수행하려는 경우 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"

macOS에서 작동시킬 가능성이 있습니까? 내 filter.sed파일 에 포함하고 싶습니다 . 감사!
Philipp L.

GNU sed를 사용하지 않는 한 (예 : Homebrew 등) 위의 sed명령은 명령에 e수정자를 사용합니다 s. 이 수정자는 GNU 확장이고 macOS sed는 BSD입니다.
갤럭시

@viric의 답변이 좋습니다. 필터를 통해 메시지를 변경할 필요가 없습니다.
Jangid

@Jangid, 원래 요청을 읽고 특히 상태 표시 줄이 아니라 페이지 상단 에 로컬 영역을 올바르게 표시하도록 요청 하십시오.
은하

@ 갤럭시 오! 예. 방금 알아 차렸어요 옳은.
Jangid

11

인덱스의 서식은 index_format설정에 의해 제어 되며 뮤트에 의해 생성됩니다. Date헤더가 잡종에 의해 제어되지 않으며, 단지 표시됩니다 메시지에 포함 된 헤더입니다. UTC 시간이 표시되면 보내는 서버가 헤더를 생성 할 때 UTC를 사용하기로 결정했기 때문입니다. 메시지를 변경하는 유일한 방법은 메시지를 받거나 볼 때 실제로 메시지 자체를 변경하는 것입니다.

들어올 때 변경한다는 것은 메일 전달 에이전트에 필터를 추가하는 것을 의미하지만 기존 Date헤더 를 구문 분석 하고 다시 작성할 수 있을 정도로 정교해야 합니다. 메시지를 볼 때 음소거 형식을 변경하는 것이 거의 확실합니다. display_filter속성을 실행 파일로 설정할 수 있으며 , 실행하기 전에 열어 놓은 메시지를 표시하기 전에 파이프합니다.

당신은 메시지의 각 라인을 읽고 Date 헤더와 하나를 대체하는 프로그램이나 쉘 스크립트를 작성하거나 기존 스크립트를 찾아야합니다 (하나를 거기에 여기 가 정말해야처럼 보이지 않지만, 힘의 작동하는지 임시 파일을 포함해야합니다.)



5

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:헤더를 통한 코드 삽입 공격에 취약합니다 . 서브 쉘에 들어가면 입력의 유효성을 검사 / 소독해야합니다.
은하

2

프록 메일 솔루션은 다음과 같습니다.

# 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

이걸 어떻게 불러?
Janus Troelsen

@JanusTroelsen, 나는 당신이 스크립트를 할당하는 생각 display_filter에서 .muttrc.
은하

2

set display_filter="/PATH/TO/THIS/PYTHON/FILE"당신의 .muttrc.

파이썬 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:헤더를 통한 코드 삽입 공격에 취약합니다 . 서브 쉘로 들어가면 입력의 유효성을 검사 / 염소 처리해야합니다. 그렇지 않으면 보안 관점에서 스크립트가 정상입니다. 그러나 찾아 보는 모든 메시지에서 실행되는 스크립트는 상당히 무겁습니다.
은하

2

현지 시간 버전을 포함하기 위해 추가 "Local-Date"헤더를 추가하면서 "Date"헤더를 유지하는 필수 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;

0

나는 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

1
이메일 파싱은 꽤 까다 롭습니다. formail( procmail 패키지의 reformail일부 ) 또는 ( maildrop의 일부 ) 와 같은 전용 도구 를 사용하여 기존 Date:헤더 를 추출하고 새 헤더를 제자리에 배치하는 것이 좋습니다. Date:헤더 가 없거나 형식이 잘못된 경우와 같은 엣지 케이스를 처리하십시오 .
Gilles 'SO- 악마 그만해'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.