В данный момент Hi-Track представляет собой довольно мощный трекер нетмейловых и эхомейловых сообщений со средствами роутинга нетмейла в BSO. При проектировании очень хотелось следовать принципу адекватности целей и средств: по этой идее простые решения должны достигаться несколькими интуитивно понятными строками конфига, а более сложные сущности привлекаться только по мере необходимости решить пропорционально более сложную задачу. Настолько это удалось - судите сами .)
hitrack -pkt backup
равносилен добавлению в начало конфига такого текста:
#define -pkt
#define backup
Далее в тексте конфига Вы можете анализировать наличие соответствующей
макропеременной директивами #ifdef
или #ifndef
,
либо использовать значение переменной для макроподстановки.
"Содержательную" часть конфига (т.е. то, что получается на выходе препроцессора) условно можно разделить на раздел параметров и раздел сценариев. Раздел параметров определяет несколько общих для всей системы значений - таких, как FTN-адрес, пути к требуемым каталогам, смещение UTC и т.п. Раздел сценариев содержит описание алгоритма обработки входящих сообщений на некотором встроенном скриптоподобном языке.
Перейти к описаниям:
Создаёт макропеременную с именем SYMBOL и значением VALUE. Если значение не указано, переменная создаётся с пустым значением. Повторное определение переменной не считается ошибкой, а просто изменяет её значение.#define SYMBOL
[VALUE
]
#undef SYMBOL
Уничтожает макропеременную с именем SYMBOL. Если такой переменной не существует,
никаких действий не производится.
#ifdef SYMBOL
...SOMETHING...
#else
...SOMETHING...
#endif
Если макропеременная с именем SYMBOL существует, препроцессор переходит к разбору
последовательности строк, заключенной между #ifdef
и #else
,
иначе - к последовательности между #else
и #endif
.
Если ветка "иначе" не нужна, оператор #else
можно опустить.
Все другие операторы вида #ifчто-то
работают аналогично,
разница лишь в смысле аргументов.
Срабатывает, если переменная с именем SYMBOL не существует.
#ifndef SYMBOL
TIME_INTERVAL - временной промежуток по правилам SF-Mail/T-Mail. Оператор
срабатывает, если текущее системное время попадает в указанный промежуток.
#iftime TIME_INTERVAL
FILE_NAME - имя файла-семафора, при существовании которого сребатывает данный if.
#ifflag FILE_NAME
Создаёт файл-семафор с именем FILE_NAME.
#raise FILE_NAME
Удаляет файл-семафор с именем FILE_NAME.
#drop FILE_NAME
Итак, описание параметров с их дефолтовыми значениями:
Первичный FTN-адрес Вашей системы. AKA пока не предусмотрены, но если нужно - сделаем :)
Address 2:461/79
Адрес робота, который будет проставлен, например, в поле ORIG создаваемых PKT-шников.
Может совпадать с первичным адресом.
Robot_Addr 2:461/79.99
Имя, которое будет проставлено в поле FROM создаваемых от имени робота сообщений.
Robot_Name Hi-Track
Путь к каталогу инбаунда Вашей системы. Здесь будут порождаться создаваемые PKT-шники и этот
каталог будет использован по-умолчанию для сканировнания PKT-базы сообщений
(
Inbound c:\fido\inbound
target PKT
).
Путь к корневому каталогу Binkley-Style Outbound Вашей системы. Сюда будут упаковываться
сообщения при выполнении Action Route, и отсюда же будут
по-умолчанию распаковываться соообщения из BSO-базы (target BSO).
Outbound c:\fido\outbound
Путь к первичному каталогу нетмейла Вашей системы. Здесь будут порождаться созаваемые
нетмейловые сообщения и этот каталог будет использован по-умолчанию для сканирования
MSG-базы сообщений (target MSG).
Netmail c:\fido\netmail
Полнопутевая маска нодлистов, из которых будет выбран наиболее свежий по дате. Параметров
Nodelist c:\fido\nodelist\nodelist.*
Nodelist
может быть несколько (порядок важен!), результирующий
индекс будет построен, как замещающее объединение всех объявленых нодлистов. Средства
роутинга текущей версии Hi-Track работают только в пределах одной FTN-зоны, соответственно,
мультизональные нодлисты не поддерживаются (строка Zone игнорируется).
Никаких специальных действий для компиляции нодлистов предпренимать не нужно. Индекс нодлиста
подключается автоматически по первому фактическому требованию основаной на нодлисте
информации. Перекомпиляция происходит также автоматом: отслеживаются даты нодлистов и файла
индекса (HITRACK.NLI в том же каталоге, что и HITRACK.EXE). Если всё-же
индекс необходимо принудительно обновить, просто удалите файл HITRACK.NLI.
Смещение UTC (в положительную сторону :)
UTC 3
Где создавать файл протокола. По-умолчанию используется HITRACK.LOG в том же каталоге,
что и HITRACK.EXE.
Log c:\fido\log\hi-track.log
Текст, который будет использован при необходимости генерации нового ориджина. Параметров
Origin Тебя нашла себе во мне
Origin
может быть несколько, в этом случае из них всякий раз
будет выбираться случайный вариант. Если же этот параметр вообще не указан, используется
некий предопределённый нейтральный текст.
Все сценарии (и операторы внутри них) выполняются строго последовательно в порядке их записи. Каждый сценарий состоит из обязательного списка целей (атакуемых почтовых баз) и необязательного списка ловушек, через которые просеиваются все атакуемые сообщения.
Перейти к описанию:
target
, имеющих следующий формат:
Первый аргумент оператораtarget
{MSG
|PKT
|BSO
} [MAINTENANCE
] [PATH
]
target
является обязательным и
определяет тип почтовой базы:
MSG
- Нетмейловая база в формате Fido/MSG;
PKT
- База почтовых пакетов PKT-2/2+ (обычно инбаунд);
BSO
- Binkley-Style Outbound.
Необязательный параметр MAINTENANCE представляет собой опцию обслуживания, которая определяет некоторые служебные действия, которые необходимо произвести с почтовой базой прежде, чем подавать из неё сообщения на вход ловушек. Опции обслуживания специфичны для каждого типа базы, и на данный момент определены следующим образом:
target MSG
:
+renumber
target PKT
:
target BSO
:
+force
Netmail
. Собственно, именно таким образом (распаковкой)
осуществляется доступ к базе BSO.
+auto
target BSO
без опций обслуживания не вызывает
никаких действий.
Необязательный параметр PATH задаёт путь к базе сообщений, являющейся целью данного
оператора target
. Если параметр PATH опущен, будут использованы значения
по-умолчанию, заданные в разделе параметров:
target MSG
- значение параметра Netmail
;
target PKT
- значение параметра Inbound
;
target BSO
- значение параметра Outbound
.
Сейчас Hi-Track поддерживает два типа ловушек:
EasyRoute
, предназначенный для простого и быстрого задания
правил роутинга нетмейла, если не требуются функции собственно трекера.
Подробнее >>
catch
, внутри которого можно записать довольно
сложную логику обработки проходящих сообщений (и роутинг в том числе).
Подробнее >>
Где:easyroute FLAVOR ROUTE-TO DEST
[DEST
...]
normal
|hold
|direct
}
Адресная маска записывается подобно обычному FTN-адресу, только вместо любых полей
(зоны, сети, узла, поинта) можно указывать символ *
(звёздочка) -
в этом случае значением поля будет соответствующее значение из адреса получателя
упаковываемого сообщения. Символ *
можно указать вместо адресной маски
целиком, в этом случае результатом будет целиком адрес получателя.
Модификатор определяется следующим образом:
MODIDIER ::= {boss
|host
|hub
}
Применение модификатора заменит предъявленный адрес на, соответственно, адрес его босса, сетевого хоста или хаба.
hub:
ADDR}hub:
определяет все системы,
хабом которых является система с адресом ADDR. Хабом узлов, находящихся в
подхостнике, считается сетевой хост; хабом независимых узлов в регионе - региональный
хост.
Kill-Sent
, оно после успешной
упаковки унижчтожается, иначе на него проставляется атрибут Sent
. Сообщения,
имеющие адресом назначения наш основной адрес, всегда игнорируются ловушкой
easyroute
.
easyroute hold * 2:461/79.*
Сообщения для поинтов узла 2:461/79 роутятся на них напрямую с флавором Hold.
easyroute direct 2:461/58 hub:2:461/58 hub:2:461/141
Сообщения, для узлов из подхабников 461/58 и 461/141 роутятся напрямую на 461/58.
easyroute direct hub 2:461/*
Сообщения для остальных услов сети 461 роутятся на их хабов.
easyroute direct 2:461/0 *
Всё остальное роутится на наш сетевой хост.
catch
предназначен для описания сложных манипуляций с проходящими
сообщениями. Более того, ловушка easyroute
фактически является макросом,
прозрачно для пользователя транслирующимся в блок catch
. Начнём с простого
примера:
target PKT c:\fido\inbound
catch
include kharkov.sysop
mask Bill Gates, 2:461/95.*
action delete
end
Смысл этой ловушки заключается в переводе некоего сисопа, пишущего под именем 'Bill Gates'
с любого из поинтовых адресов узла 2:461/95 (включая и нодовый адрес 2:461/95 == 2:461/95.0)
в режим ReadOnly по эхоконференции kharkov.sysop. Целью ловушки является PKT-база сообщений,
раположенная в каталоге 'c:\fido\inbound'.
Теперь попытаемся, отталкиваясь от этого примера, перейти к более общему описанию.
Итак, блок catch
представляет собой некую последовательность операторов,
заключённую в операторые скобки catch
-- end
. Операторы
записываются по одному в строке, регистр безразличен (кроме специальных случаев вроде
регулярных выражений :) Все операторы условно делятся на три раздела примерно так:
Перейти к описанию:
catch
Фильтр эхотегов
Фильтр сообщений
Список действий
end
Netmail
. Синтаксис операторов следующий:
include UNIX_MASK
exclude UNIX_MASK
где UNIX_MASK - это файловая маска (ну, там, где звёздочки с вопросительными
знаками:) эхотегов, соответственно, включаемых в список или исключаемых из списка
проверки для данной ловушки. При создании ловушки список эхотегов пуст, так что
exclude
без include
не имеет смысла. Количество этих
операторов в ловушке (равно как и любых других конструкций) ограничено только Вашим
здравым смыслом.
include kharkov.sysop
Активна единственная эхоконференция kharkov.sysop.
include kharkov.*
Активны все эхоконференции иерархии kharkov.
include *
exclude netmail
Активны все существующие в системе эхоконференции, нетмейл не активен.
mask
выглядит примерно так:
Смысл аргументов следующий:mask FROM
[, ORIG
[, TO
[, DEST
[,SUBJ
[, ATTR
]]]]]
Обилие квадратных скобок обозначает, что если значения последних нескольких аргументов безразлично, их можно не указывать :)
*
(звёздочка),
под этим понимается, что значение соответствующего поля проверяемого адреса может
быть любым. Кроме того, маска может состоять из единственного символа *
,
такой маске удовлетворит любой FTN-адрес.
2:461/79.*
Все поинтовые адреса (нулевой поинтовый равен нодовому) узла 2:461/79.
2:*/0
Все сетевые хосты второй зоны.
*
Любой FTN-адрес.
PVT
- Private
CRA
- Crash
RCV
- Received
SNT
- Sent
FIL
- File-attach
TRS
- Intransit (forward)
ORP
- Orphan
K/S
- Kill sent
LOC
- Local
HLD
- Hold
UNU
- Unused
FRQ
- File request
RRQ
- Return receipt request
RRC
- Return receipt
ARQ
- Audit request
URQ
- Update request
A/S
- Archive sent
DIR
- Direct
ZON
- Zone gate
HUB
- Hub-routing
IMM
- Immediate
XMA
- Xmail
TFS
- Truncate file sent
LOK
- Locked
CFM
- Confirm receipt request
FPU
- Force Pickup
+
(плюс), если наличие данного атрибута необходимо для
срабатывания ловушки, или -
(минус), если для срабатывания необходимо
отсутствие данного атрибута). Значение атрибутов, которые не указаны в маске,
считается безразличным. Если необходимо указать более одного атрибута, все
они (с необходимыми префиксами +
или -
) записываются
подряд, без пробелов.
-FIL-FRQ
Кроме аттачей и фреков.
Конструкция
эквивалентна последовательности двух операторов Mask:
name Vadim Marcus
mask Vadim Marcus
mask *, *, Vadim Marcus
xmask
dest 2:461/79.*
dest !2:461/79.0
dest !2:461/79.55
end
Перечисленые внутри блока условия считаются связаными по и, то есть
xmask
срабатывает, если сообщение удовлетворяет всем перечисленым в
блоке условиям. Условия внутри блока можно задавать следующим образом:
Аргументы - текстовые маски имён, соответственно, отправителя и получателя. Необязательный символfrom
[!
]TEXT_MASK
to
[!
]TEXT_MASK
!
(восклицательный знак) перед маской
обозначает инверсию, т.е. подходит сообщение, которое не удовлетворяет указаной маске.
Аргументы - aдресные маски, соответственно, для отправителя и адресата.orig
[!
]ADDR_MASK
dest
[!
]ADDR_MASK
Аргумент - текстовая маска для темы сообщения.subj
[!
]TEXT_MASK
attr ATTR_LIST
Аргумент - маска атрибутов сообщения.
older AGE
newer AGE
Аргумент - целое число, определяющее (в днях) возраст, соответственно, старше или моложе
которого должно быть сообщение, чтобы удовлетворить данному условию.
grep "REGEXP"
Поиск в теле сообщения хотя бы одной строки, подходящей под маску
регулярного выражения REGEXP.
hub ADDR
Подойдут сообщения, нетмейловым хабом адресата которых является система с
указанным адресом.
xmask
можно связать между собой по
или - для этого связываемую последовательность нужно заключить в операторные
скобки union
- end
, например:
xmask
orig 2:461/79
dest 2:461/79.*
dest !2:461/79.0
union
from AllFix*
from FastEcho
end
end
Сюда поймаются сообщения роботов узла 2:461/79, адресованые поинтам этого узла.
Результат "выполнения" union
можно проинвертировать, для этого после слова
union
нужно указать ключевое слово inverted
:
union inverted
from AllFix*
from FastEcho
end
Bounce
текущим
всё равно остаётся оригинальное сообщение, и последующие ловушки видят именно его,
а не только что родившееся баунсанутое .)
Текущая версия Hi-Track поддерживает следующие виды действий:
Результатом выполнения данного действия будет изменение соответствующих значений заголовка текущего сообщения. Смысл аргументов здесь тот же, что и в операторе Mask. Логика замены следующая: для текстовых аргументов (FROM, TO, SUBJ) подставляется значение, указаное в соответствующем поле оператораaction rewrite FROM
[, ORIG
[, TO
[, DEST
[,SUBJ
[, ATTR
]]]]]
action rewrite
, в котором каждое вхождение символа *
заменяется на первоначальное содержимое данного поля в обрабатываемом сообщении.
Для адресных аргументов ORIG и DEST логику проще выразить на псевдо-C, чем по-русски :)
if ( mask == NULL || mask == '*' ) out_addr = in_addr else { out_addr.zone = mask.zone == '*' ? in_addr.zone : mask.zone; out_addr.net = mask.net == '*' ? in_addr.net : mask.net; out_addr.node = mask.node == '*' ? in_addr.node : mask.node; out_addr.point = mask.point == '*' ? in_addr.point : mask.point; }Проще всего с аргументами FTN-атрибутов: для того, чтобы включить некоторый атрибут, нужно его указать с префиксом
+
, для того, чтобы атрибут погасить - с префиксом
-
.
mask *, *, Sysop, 2:461/79
mask *, *, *, 2:461/79.55
action rewrite *, *, Dmitry Liman, 2:461/79
Заменяет безликое Sysop для мого узла на моё настоящее имя, а также всю пришедшую на мой
поинтовый AKA почту перенаправляет на мой узловой адрес.
xmask
dest 2:461/79.*
dest !2:461/79.0
end
action rewrite *, *, *, 2:461/800.*
Переадресовывает всю почту, пришедшую на адреса поинтов узла 2:461/79 (но не на
нодовый адрес) на аналогичные поинтовые номера узла 2:461/800.
xmask
dest !2:461/79
attr -K/S
end
action rewrite *, *, *, *, *, +K/S
Проставляет kill-sent на всю не мою почту, если кто-то (как правило, какой-то робот)
забыл этот атрибут включить.
action bounce TEMPLATE
Возвращает отправителю нетмейлом текущее сообщение, используя файл шаблона (темплет),
имя которого задаётся аргументом TEMPLATE. Темплет представляет собой простой
текстовый файл, который копируется в выходной поток с учётом следующих макроподстановок:
%PID
| Program ID (Hi-Track); |
%NOW
| Текущая системная дата/время; |
%ATTR
| Список включённых FTN-атрибутов исходного сообщения; |
%DATE
| Дата создания исходного сообщения; |
%AREA
| Эхотег или Netmail для нетмейлового сообщения;
|
%SUBJ
| Тема исходного сообщения; |
%ORIG
| Адрес отправителя исходного сообщения; |
%DEST
| Адрес получателя, взятый из исходного сообщения; |
%FROM
| Полное имя отправителя исходного сообщения; |
%TO
| Полное имя получателя, взятое из исходного сообщения; |
%FFROM
| Только первое слово имени отправителя исходного сообщения; |
%FTO
| Только первое слово имени получателя, взятое из ... ; |
%BODY
| Текст (тело) исходного сообщения, приведённое к печатному виду |
catch
include netmail
xmask
dest 2:461/79.*
dest !2:461/79.0
dest !2:461/79.1
dest !2:461/79.2
dest !2:461/79.55
end
action bounce no_point.tpl
action delete
end
Темплет no_point.tpl может выглядеть, например, так:
Драстуй, %FFROM!
Тута от табе пришло письмишко на адрес %DEST,
так такого поинта у меня нету, поэтому оное возвращается взад .)
Оригинальная мессага:
---------------------------------------------------------------------
¦ * From : %FROM (%ORIG)
¦ * To : %TO (%DEST)
¦ * Subj : %SUBJ
¦ * Date : %DATE
¦ * Attr : %ATTR
==========
%BODY
•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
Использованный в данном примере оператор action delete описан ниже.
action delete
Текущее сообщение уничтожается. Если оным является нетмейловое сообщение из MSG-базы,
то уничтожение производится путём удаления соответствующего MSG-файла. Для PKT-базы
порождается новый PKT-файл, из которого выгрызено уничтожаемое сообщение. Исходный
PKT-шник, естественно, целиком прибивается. В списке действий оператор
action delete
должен стоять последним, так как после его выполнения
текущее сообщение не определено.
action save FILE_NAME
Сохраняет текущее сообщение в текстовом файле с именем FILE_NAME. Если указаный
файл существует, сообщение дописывается ему в хвост. Сохранение происходит со всей
служебной информацией, преобразованой к читабельному виду.
Копирует текущее сообщение в [эхо]область ECHOTAG. Исходное сообщение остаётся неизменным. Копирование осуществляется путём создания нового файла (MSG для нетмейла или PKT для эхомейла), в который помещается полная копия исходного сообщения (MSGID тоже остаётся прежним) с соответствующим кладжем AREA и включённым атрибутом LOC. Если необходимо, формируется строки Origin и Tearline.action copy
{ECHOTAG
|*
} [ALTERNATE_PATH
]
Необязательный параметр ALTERNATE_PATH указывает альтернативный путь для
размещения файла выходного сообщения, вместо заданного параметром inbound
или netmail
. Таким способом можно "откладывать" определенные сообщения
в виде готовых к тоссингу PKT-шников или разбрасывать нетмейловые сообщения по персональным
мейлбоксам. Если указан ALTERNATE_PATH, то вместо эхотега области можно указать
символ *
(звёздочка). В этом случае эхотег входного сообщения будет сохранен
в выходном.
Не советую использовать action copy
для переброски эхомейловых сообщений
в нетмейл: из них, вообще говоря, не всегда можно извлечь достаточно информации для
правильного определения FTN-адресов отправителя/получателя.
action copy
можно использовать для "гейтования" некоторой
нетмейловой рассылки в эхоконференцию таким вот образом:
catch
include netmail
mask *, *, CML Reader
action rewrite *, 2:461/79
action copy CML
action delete
end
Пересылает куда-то текущее сообщение :) Исходное сообщение остаётся без изменений. Смысл аргументов:action forward ECHOTAG
[,REWRITE
]
ECHOTAG
- Эхотег области, в которой создаётся форвардируемое (ой :)
сообщение;
REWRITE
- Последовательность параметров, идентичных по смыслу и
результату применения используемым в операторе
action rewrite.
action rewrite
. Генерируется новый MSGID,
если нужно - ориджин и тирлайн, в начало текста сообщения добавляются кладжи FWD
(FSC-0092); строки seen-by, path, via обрезаются.
action route FLAVOR TARGET
Осуществляет маршрутизацию текущего нетмейлового сообщения путём упаковки его согласно
правилам формирования Binkley-Style Outbound. Смысл аргументов:
FLAVOR
::= {normal
|hold
|direct
}TARGET
::= {boss
|hub
|host
|ADDR_MASK
}SNT
или прибивания сообщения с атрибутом K/S
не производится, для
этого есть action rewrite
или action kill-sent
.)
action kill-sent
Используется только непосредственно после action route
и удаляет текущее сообщение, если оно имеет атрибут K/S
, в противном случае
устанавливает ему атрибут SNT
.
regexp - Copyright (c) 1986 by University of Toronto. Written by Henry Spencer.
*** Syntax
A regular expression is zero or more branches, separated by `|'. It matches anything that matches one of the branches.
A branch is zero or more pieces, concatenated. It matches a match for the first, followed by a match for the second, etc.
A piece is an atom possibly followed by `*', `+', or `?'. An atom followed by `*' matches a sequence of 0 or more matches of the atom. An atom followed by `+' matches a sequence of 1 or more matches of the atom. An atom followed by `?' matches a match of the atom, or the null string.
An atom is a regular expression in parentheses (matching a match for the regular expression), a range (see below), `.' (matching any single character), `^' (matching the null string at the beginning of the input string), `$' (matching the null string at the end of the input string), a `\' followed by a single character (matching that character), or a single character with no other significance (matching that character).
A range is a sequence of characters enclosed in `[]'. It normally matches any single character from the sequence. If the sequence begins with `^', it matches any single character not from the rest of the sequence. If two characters in the sequence are separated by `-', this is shorthand for the full list of ASCII characters between them (e.g. `[0-9]' matches any decimal digit). To include a literal `]' in the sequence, make it the first character (following a possible `^'). To include a literal `-', make it the first or last character.
*** Ambiguity
If a regular expression could match two different parts of the input string, it will match the one which begins earliest. If both begin in the same place but match different lengths, or match the same length in different ways, life gets messier, as follows.
In general, the possibilities in a list of branches are considered in left-to-right order, the possibilities for `*', `+', and `?' are considered longest-first, nested constructs are considered from the outermost in, and concatenated constructs are considered leftmost-first. The match that will be chosen is the one that uses the earliest possibility in the first choice that has to be made. If there is more than one choice, the next will be made in the same manner (earliest possibility) subject to the decision on the first choice. And so forth.
For example, `(ab|a)b*c' could match `abc' in one of two ways. The first choice is between `ab' and `a'; since `ab' is earlier, and does lead to a successful overall match, it is chosen. Since the `b' is already spoken for, the `b*' must match its last possibility-the empty string-since it must respect the earlier choice.
In the particular case where no `|'s are present and there is only one `*', `+', or `?', the net effect is that the longest possible match will be chosen. So `ab*', presented with `xabbbby', will match `abbbb'. Note that if `ab*' is tried against `xabyabbbz', it will match `ab' just after `x', due to the begins-earliest rule. (In effect, the decision on where to start the match is the first choice to be made, hence subsequent choices must respect it even if this leads them to less-preferred alternatives.)