Драйверы устройств Linux являются другим хорошим ресурсом. Это дало бы Вам другой способ войти во внутренние работы. От предисловия:
Это, на поверхности, книге о записи драйверов устройств для системы Linux. Это - достойная цель, конечно; поток новых изделий вряд ли замедлится в ближайшее время, и кто-то оказывается перед необходимостью заставлять все те новые гаджеты работать с Linux. Но эта книга также о том, как ядро Linux работает и как адаптировать его работы к Вашим потребностям или интересам. Linux является открытой системой; с этой книгой мы надеемся, это более открыто и доступно для более многочисленного сообщества разработчиков.
В .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"
Форматированием в индексе управляют index_format
установка - это сгенерировано дураком. Date
заголовком не управляет дурак, это - заголовок, включенный с сообщением, которое просто отображено. Если это показывает время UTC, это - потому что передающий сервер решил использовать UTC при генерации заголовка. Единственный способ изменить его состоит в том, чтобы на самом деле изменить само сообщение, или когда Вы получаете его или когда Вы просматриваете его.
Изменение его, как это прибывает в средства, добавляющие фильтр к агенту доставки почты, но это должно быть достаточно сложно для парсинга существующего Date
заголовок и переписывает его. Почти наверняка лучше просто сделать, чтобы дурак переформатировал сообщение, при рассмотрении его. Можно установить display_filter
свойство к исполняемому файлу, и это передаст по каналу любое сообщение, которое Вы открываете через исполняемый файл прежде, чем отобразить его.
Необходимо будет записать программу или сценарий оболочки, который читает каждую строку сообщения и заменяет то заголовком Даты, или найдите существующий сценарий (существует тот здесь, который мог бы работать, хотя не кажется, что должно действительно быть необходимо включить временный файл),
Слушая совет Жабр, вот версия, которая использует временный файл и 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"
Я сделал сценарий оболочки, как описано в конце ответа 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:
заголовок и помещенный новый на месте. Заботьтесь о пограничных случаях, таких как отсутствие или malformatted Date:
заголовок.
– Gilles 'SO- stop being evil'
15.08.2011, 19:29
http://www.mail-archive.com/mutt-users@mutt.org/msg44341.html
Это предлагает использовать 'pager_format', заставить его показать дату буквы в локальном часовом поясе:
набор pager_format = "% 4C %Z % [! %b %e в %I: % M %p] %.20n %s %* - (%P)"
Обязательное решение для Perl, которое сохраняет заголовок "Даты" при добавлении дополнительного заголовка "Локальной Даты" для содержания localtime версии:
#!/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;
Вот решение для 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"
И отобразите LocalDate: в muttrc:
unignore localdate
установить 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)