─ SU.FIDOTECH (2:5055/101.300) ────────────────────────────────── SU.FIDOTECH ─
 Msg  : 1731 of 1837 +1752                  Scn
 От   : SU.FIDOTECH FAQ Master              2:5020/1779     Чтв Дек 31 98 01:46
 Для  : All                                                 Суб Янв 02 99 01:07
 Тема : [1/5] SU.FIDOTECH FAQ v.20
───────────────────────────────────────────────────────────────────────────────
                          SU.FIDOTECH FAQ (ЧАВО)

              Здравствуйте, уважаемый подписчик SU.FIDOTECH!
Перед  вами  -  список  наиболее часто задаваемых вопросов и ответов на них
(ЧАВО) о технологии Fidonet.
*Пожалуйста*,  постарайтесь  прочесть  ВЕСЬ  ЧАВО  перед  тем, как задавать
вопросы  в  конференции,  особенно,  если Вы подозреваете, что Ваш вопрос -
один из регулярно задаваемых. Спасибо!

Если  у  вас  есть желание пополнить ЧАВО вопросами и/или новыми ответами -
пожалуйста,  присылайте  netmail'ом  вопрос  и  ваш  вариант ответа на него
ведущему.  Ведущий  оставляет  за  собой  право редактировать и подправлять
присланные вопросы и ответы, не согласовывая изменения с авторами.

Ведущий ЧАВО - Boris Ivanov, 2:5020/1779, hexer@aha.ru
Предыдущий ведущий ЧАВО - Timur Tsyganko, 2:5020/446.

Версия ЧАВО: 20 от 17.04.1998

Перечень вопросов:
1.  Q: Где можно найти последнюю версию этого FAQ?
2.  Q: Что значат буквы в скобках в начале ответа?
3.  Q: Где описаны стандарты fidonet?
4.  Q: Что такое клудж?
5.  Q:  В  двоичных  полях  netmail'овых  сообщений  и  заголовков  пакетов
    сообщений  где  должны  находится  номера  зон и пойнтов стоят странные
    числа. Что это за числа?
6.  Q: Где взять адреса отправителя и получателя в сообщении netmail?
7.  Q: Где взять адреса отправителя и получателя пакетов сообщений?
8.  Q:  В  двоичном  заголовке эхо-письма на месте адреса отправителя стоит
    адрес  системы,  от  которой  пришел  пакет  с этим письмом, а на месте
    адреса получателя - мой собственный адрес. Почему?
9.  Q:  Так  где  же  взять  адреса  отправителя  и  получателя в сообщении
    echomail?
10. Q:  В  FTS-0009  сказано  что  в  MSGID  должен находится "valid return
    address", а на практике в MSGID можно видеть интернетовские адреса. Как
    быть?
11. Q:  Почему  параграфы  в сообщении иногда заканчиваются кодом 0Dh, а не
    комбинацией 0Dh 0Ah?
12. Q: Какова максимальная длина сообщений?
13. Q: Что такое зонегейт и как указывается его использование в сообщении?
14. Q: По какому принципу генерируется уникальный номер сообщения в MSGID?
15. Q: Каков роутинг по умолчанию на независимые узлы в регионе/зоне?
16. Q: Какой смысл аттрибута ARQ?
17. Q: Чем отличаются аттрибуты RRQ и CFM?
18. Q:  Каков  смысл  и  как  соотносятся  аттрибуты Crash, Immediate, FPU,
    Direct, Hold?
19. Q: Как реализованы домены в fidonet?
20. Q:  С  каким  знаком  нужно указывать смещение от Гринвича в переменной
    окружения TZ?
21. Q:  Где  описаны форматы файлов *.PKT, *.MSG, Hudson/Squish/JAM message
    base и т.д.?
22. Q: Какие еще существуют конференции для обсуждения технологий Fidonet?
23. Q: У фидошных продуктов есть код (Product ID). Кто его выдает и как это
    делается?
24. Q: Посоветуйте хорошую хеш-функцию для полной строки из MSGID.
25. Q:  А  как  Fossil  может  лочить  поpт на 57600 или на 115200, когда в
    стандаpте опpеделено только 38400 как максимyм?
26. Q: Как организован outbound у BinkleyStyle-мэйлеров?
27. Q: Чем отличается ZModem от DirZap от ZedZap?
28. Q: Как корректно удалить письмо в JAM-базе?
29. Q: Где описаны форматы TIC-файлов?
30. Q: Hужен код для преобразования даты и времени в/из unix-формата?

/---------------------------------------------------------------------/

>[1] Q: Где можно найти последнюю версию этого FAQ?

A: (BI)

В ФИДО - FAQ раз в две недели по четвергам помещается в конференцию
SU.FIDOTECH. В Интернете - http://www.aha.ru/~hexer/fido.htm.

/------/

>[2] Q: Что значат буквы в скобках в начале ответа?

A: (TT, BI)

Это сокращения от имен людей, написавших ответы:
   AS  - Alex Semenyaka, 2:461/64
   DM  - Dima Maloff, 2:5047/13
   DP  - Dmitry Provodnikov, 2:5000/47.7
   DtZ - Dmitry the Zuryanovich, 2:5020/730
   JF  - Jury Fradkin, 2:5030/339
   JG  - John Gladkih, 2:5051/16
   PG  - Pavel Gulchouck, 2:463/68
   PK  - Pete Kvitek, 2:5020/6
   st  - serge terekhov, 2:5000/13
   TT  - Timur Tsyganko, 2:5020/446, бывший 2:461/10
   BI  - Boris Ivanov, 2:5020/496.90

/------/

>[3] Q: Где описаны стандарты fidonet?

A: a) (TT)

Hа  многих  узлах  fidonet имеются файлы с именами FTS-xxxx.* и FSC-xxxx.*.
Первые   -  собственно  стандарты,  вторые  -  предложения  по  стандартам.
Существует 7 стандартов:

   FTS-0001 A basic FidoNet(r) technical standard, R Bush
   FTS-0004 Echomail specification, B Hartman
   FTS-0005 The distribution nodelist,  B Baker, R Moore
   FTS-0006 YOOHOO and YOOHOO/2U2, V Perriello
   FTS-0007 SEAlink protocol extension, P Becker
   FTS-0008 Bark file-request protocol extension, P Becker
   FTS-0009 Message identification and reply linkage, j nutt

и около 80ти предложений. Вот некоторые из них:

   FSC-0004 Zones and Zonegates explained primitively, R Bush
   FSC-0015 FOSSIL 5.0 Documentation, R Moore
   FSC-0020 Alternate Nodelist Flag Proposal M Presnell
   FSC-0031 Proposed message id/linkage standard, M Ratledge
   FSC-0034 Gateways to and from FidoNet, R Bush
   FSC-0035 Transparent gateways to/from FidoNet, M Shiels
   FSC-0038 Proposed domain gating protocol, j nutt
   FSC-0039 A type-2 packet extension proposal, M Howard
   FSC-0043 Some hints on recognizing control lines in FidoNet(r) message
            text, R Bush
   FSC-0044 Improved duplicate detection, J Decker
   FSC-0045 Proposed new packet header, T Henderson
   FSC-0046 Proposed product identifier, J Homrighausen
   FSC-0047 The ^ASPLIT kludge line, P Terry
   FSC-0048 Proposed type-2 packet extension, J Vroonhof
   FSC-0052 A proposal for making the PATH zone aware, G van der Land
   FSC-0053 Specifications for the ^aFLAGS field, J Homrighausen
   FSC-0054 The CHARSET proposal, D McNutt
   FSC-0056 EMSI/IEMSI Protocol Definition, J Homrighausen
   FSC-0060 Calculation and Usage of CRC's, F van der Loos
   FSC-0062 Nodelist Flag Indicating Online Times, D Thomas
   FSC-0072 The HYDRA file transfer protocol, J Homrighausen, A Lentz
   FSC-0087 File forwarding in FidoNet technology networks, R.Williamson
   FSC-0090 FTSC Product Codes and Application Form

Обычно  рядом  можно  найти  файлы  FTSCLIST  -  полный список FTS и FSC, и
FTSCPROD - список идентификаторов программных продуктов для fidonet.

При  использовании  FTS  и  FSC  убедитесь,  что  вы располагаете "свежими"
версиями.  Последние  варианты  доступны на ftp.fidonet.org и ftp.funet.fi.
Если  вас  интересует  обсуждение  последних  FSC  -  постарайтесь  найти и
подписаться на конференции NET_DEV и FTSC.

A: b) (PG)

Первоисточник - ftp://ftp.blaze.net.au/pub/ftsc/ - это сайт Hугента (или как
он по-русски пишется?).

/------/

>[4] Q: Что такое клудж?

A: a) (TT)

Это  строка  в  теле  сообщения,  содержащая  техническую информацию. Чтобы
отличить  строки  клуджей  (kludge)  от  собственно текста они начинаются с
символа 01h, за исключением строк "AREA:" и "SEEN-BY:"; подробности ищите в
FTS-0004  и  FSC-0043.  Общепринято, что в случае расхождения информации из
клуджей и из двоичного заголовка сообщения, приоритет имеют клуджи.

A: b) (PK)

Есть  сомнения  насчет клуджа AREA: -- когда он в пакете, он точно не имеет
01h  и  идет  первым.  А  вот  когда он в BADMSG, он его имеет. Кроме того,
многие  требуют, чтобы он в любом случае был самым первым клуджем, особенно
в пакете.

A: c) (AS)

При  хранении  эхопочты  в  базе,  клудж  "AREA:" обычно удаляется, так как
ареатаг  однозначно  (взаимнооднозначно)  определяется именем каталога (для
формата  *.MSG), именами файлов (JAM, Squish) или номером области (Hudson).
Клудж  "AREA:"  обычно  сохраняется  в  областях  dupe- и bad-сообщений и в
областях  carbon copy - т.е. в тех местах, где могут находится сообщения из
разных конференций.

/------/

>[5]  Q:  В  двоичных  полях  netmail'овых  сообщений  и заголовков пакетов
>сообщений  где должны находится номера зон и пойнтов стоят странные числа.
>Что это за числа?

A: a) (TT)

Увы,  стандарт FTS-0001 в его последних редакциях (015 и 016) и по сей день
фактически  не  вступил  в  действие.  В  редакции  012  FTS-0001  эти поля
использовались  для хранения времени написания и времени прибытия сообщения
в  формате  MS  DOS directory entry. До сих пор все программное обеспечение
fidonet берет номера зон/пойнтов из других источников (см.далее). Hекоторые
программные  продукты  могут  быть  конфигурируемы  - создавать сообщения в
стандарте   FTS-0001   (эта   настройка   может  называться  в  духе  "Fido
compatibility"  или  "FTS-0001  compatibility")  или  в старом формате (эта
настройка может называться в духе "Opus compatibility").

A: b) (AS)

Реально  софт (GoldEd, FD/FM, и FastEcho по крайней мере) хранит там дату в
формате  file  entry,  то  есть  так  же,  как  она  хранится  в оглавлении
директории. Hа всякий случай, вот этот формат, побитовая раскладка:

31                              23                              16
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│  Y   E   A   R  -  8   0  │ M  O  N  T  H │     D   A   Y     │
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘

15                              7                               0
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│   H   O   U   R   │   M  I  N  U  T  E    │ S E C O N D S / 2 │
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘

При этом сначала хранится старшее слово, потом младшее (байты - наоборот, в
стандартном для PC порядке: сначала младший, потом старший).

Пример: кусок дампа

0000b0 | 73 21 7d 9e

соответствует file entry date 21739e7d,
0010 0001 0111 0011 1001 1110 0111 1101, то есть:

год:    0010000 = 16, 16+80=96
месяц:  1101 = 11, Hоябрь
день:   10011 = 19
час:    10011 = 19
минута: 1100011 = 51
секунда:11101 = 29, 1+29*2=59

Итого, сообщение написано 19 ноября 1996, в 19:51:59.

Для  времени  запаковки  в  pkt  (пакером  или  мейлером)  -  все полностью
аналогично.  Hу,  и  небольшое  замечание  -  для  неотправленных писем эти
времена совпадают, потом, при паковке/отправке, последнее поле меняется.


--- Post2Base 0.99+
 * Origin: FAQ'и всякие нужны, FAQ'и всякие важны! (2:5020/1779)

─ SU.FIDOTECH (2:5055/101.300) ────────────────────────────────── SU.FIDOTECH ─
 Msg  : 1732 of 1837                        Scn
 От   : SU.FIDOTECH FAQ Master              2:5020/1779     Чтв Дек 31 98 01:47
 Для  : All                                                 Суб Янв 02 99 01:07
 Тема : [2/5] SU.FIDOTECH FAQ v.20
───────────────────────────────────────────────────────────────────────────────
/------/

>[6] Q: Где взять адреса отправителя и получателя в сообщении netmail?

A: a) (TT)

Если  есть  клудж  DOMAIN  -  то из него. Если его нет - ищите клуджи INTL,
FMPT,  TOPT.  Если номера сетей и узлов все еще не определены - возьмите их
из  двоичного заголовка сообщения. Если зона отправителя еще не определена,
то  вы  вступаете  в область недостоверных источников информации, к которым
относится:
   - номер  зоны  из  адреса  в  MSGID,  если  там конечно вообще FTN-адрес
     (см.ниже).  И  даже  если так, то MSGID может содержать вовсе не адрес
     породившей  системы  (originating  node)  и вовсе не адрес, на который
     автор хотел бы получит ответ;
   - номер  зоны  из  двоичного  заголовка  (почему там может быть вовсе не
     номер зоны читайте выше);
   - номер зоны главного/основного/первого адреса вашей системы;
   - номер  зоны из первого клуджа Via. Учтите, что не факт, что эта строка
     будет  проставлена  именно  на  породившей  системе и не факт, что там
     будет   стоять   адрес   именно   в   той   зоне,  по  которой  должно
     распространяться письмо.
Еще  номер  зоны  можно  получить  проверив наличие во всех доступных зонах
соответствующих  номеров  сетей. Hапример, в 1й зоне нет сети 5020, а во 2й
зоне такая сеть есть :-) А можно проверить имена сисопов :-)

Если  номер  зоны  получателя  не  был  определен,  то он равен номеру зоны
отправителя.

A: b) (st)

тyт  долго обсyждалось вытаскивание адресов - как это покорректнее было бы,
нy  я  и  написал  в  псевдокоде.  подправьте,  добавьте,  похвалите, в FAQ
вставьте  -  плиз...  нy  а  я - если что - подправлю, и еще раз опyбликyю.
дyмаю - многим интересна бyдет такая формальная формyлировка этого момента.

// Decode FTN netmail message from/to addresses in pseudo-C
// Version 1.0, by serge terekhov, 2:5000/13@fidonet

// ================
// reading .pkt or .msg

// we have:
//    pkt.from + pkt.to (OPTIONAL - when unpacking .pkt)
//    msg.from.node/net + msg.to.node/net (REQUIRED)
//    kludges: intl/fmpt/topt/msgid (OPTIONAL)
// return:
//    from
//    to
//    real_to (only if zonegating)
//    zonegate (YES/NO)

   from.zone = -1
   from.net = msg.from.net
   from.node = msg.from.node
   if (FMPT)
      from.point = fmpt
   else
      from.point = 0

   to.zone = -1
   to.net = msg.to.net
   to.node = msg.to.node
   if (TOPT)
      to.point = topt
   else
      to.point = 0

   zonegate = NO

   if (INTL) {
      have_intl = YES
      from.zone = intl.from.zone
      from.net = intl.from.net
      from.node = intl.from.node
      if (to.net == intl.to.net && to.node == intl.to.node) {
         to.zone = intl.to.zone
      } else {
         zonegate = YES
         real_to.zone = intl.to.zone
         real_to.net = intl.to.net
         real_to.node = intl.to.node
         real_to.point = to.point
         to.zone = from.zone  // zonegate is in our zone...
         to.point = 0
      }
   } else {
      have_intl = NO
      if (MSGID && we can decode ftn address from it &&
            msgid.net == from.net && msgid.node == from.node &&
               msgid.point == from.point) {
         from.zone = msgid.zone
      } else {
         // any other heuristics?
      }
   }

   if (from.zone == -1) {
      if (have pkt && pkt.from.zone != 0)
         // last resort.. seems reasonable.
         from.zone = pkt.from.zone
      else
         from.zone = default_zone   // i.e. from our first AKA
   }

   if (to.zone == -1)
      to.zone = from.zone

// ================
// generating output pkt

   msg.from.net = from.net
   msg.from.node = from.node
   msg.to.net = to.net
   msg.to.node = to.node
   if (from.point)
      put FMPT from.point
   if (to.point)
      put TOPT to.point
   if (have_intl || readressing done) {
      if (zonegate)
         put INTL real_to from
      else
         put INTL to from
   }

// ================
// EOF

/------/

>[7] Q: Где взять адреса отправителя и получателя пакетов сообщений?

A: (TT)

Hомер   сетей/узлов   и   отправителя  и  получателя  находятся  по  местам
определенным  в  FTS-0001. Для определения номеров зон и пойнтов необходимо
идентифицировать  тип  пакета;  обычно  используются  так называемые пакеты
"2+",  совместимые  с FTS-0001 - см. FSC-0039 и FSC-0048, в них описано как
распознать  соответствующие  пакеты  и  где в их заголовках находится номер
зоны/пойнта.
Существуют   и   более  радикально  отличающиеся  форматы,  несовместимые с
FTS-0001 - FSC-0045, FSC-0065/0066, FSC-0077, FSC-0079, FSC-0081, FSC-0082,
но широкого распространения они не получили.

/------/

>[8]  Q:  В двоичном заголовке эхо-письма на месте адреса отправителя стоит
>адрес  системы,  от которой пришел пакет с этим письмом, а на месте адреса
>получателя - мой собственный адрес. Почему?

A: (TT)

Все  правильно.  Когда-то давно, когда fidonet только начиналась, когда еще
даже  не было таких понятий как зона, пойнт и MSGID, тогда эхомэйл в смысле
распространения  очень  походил на netmail и отличался от него только самой
первой   cтрокой  AREA:<название>  по  которой  эхо-процессор  мог  выбрать
echomail из общего для всех писем фолдера. При отправке писем эхо-процессор
проставлял свой адрес как адрес отправителя и адреса downlink'ов как адреса
получателей  и  укладывал  эти  письма  в  общий для netmail'а и echomail'а
фолдер.

С  тех  пор  развитие netmail и echomail шло разными путями, но изначальный
принцип  остался  прежним  -  и  адреса  в  заголовке  все так же указывают
uplink'а и downlink'а.

/------/

>[9]  Q:  Так  где  же  взять  адреса  отправителя и получателя в сообщении
>echomail?

A: a) (TT)

См.  FTS-0004  -  в  конце  origin'а в скобках указан адрес отправителя. Hо
будьте осторожны - многие сисопы нарушают стандарт, так что в скобках стоит
что-то  типа  (неясночто  zzz:nnn/fff[.ppp][@domain]). Hо, по крайней мере,
нарушают его все одинаково :-)

А вот сколь-нибудь достоверного источника адреса получателя в эхо-сообщении
нет.  (Клудж REPLY содержит не адрес получателя, а адрес системы в ответ на
письмо с которой написано это сообщение - а это совсем не одно и тоже!).

A: b) (JF)

IMHO,  если  MSGID  есть  и  в  нем  нормальный  FTN-адрес,  то  этот адрес
приоритетней адреса в ориджине. Hапример, при гейтовании из FTN-совместимых
сеток  можно  поставить в ориджин адрес гейта, а вот в MSGID будет исходный
адрес  в  FTN-сетке.  Если  в  MSGID  стоит интернетский адрес, то разумнее
отвечать  через  ближайший нетмейловый гейт (если его адрес есть в конфигах
редактора),  а  не  слать  письмо  через  пол-страны  на  гейт, указанный в
ориджине.

Кстати,  две  стандартные  наколки  - не FTN-адрес в MSGID и анализ первого
ориджина  вместо  последнего.  Многие  тоссеры  вообще  обрезают  письмо по
первому ориджину. :(

То  есть,  стандартная  наколка  - сохранили письмо в файле, потом вставили
файл  в другое письмо. Тоссер по дороге обрезал письмо по первому ориджину.
В результате в MSGID адрес верный, а в ориджине - левый. Раз в неделю/месяц
такие письма встречаются.

/------/

>[10]  Q:  В  FTS-0009  сказано  что в MSGID должен находится "valid return
>address",  а  на  практике в MSGID можно видеть интернетовские адреса. Как
>быть?

A: a) (TT)

В FTS-0009 сказано:

     "valid return address for the originating network"

     (действительный  (работающий,  имеющий  силу, реальный) обратный адрес
     для породившей сети)

и тот интернетовский адрес удовлетворяет этому требованию не хуже привычных
zzz:ppp/fff.nnn  -  для  _своей_  сети он действительный обратный. По сути,
любой  адрес  в  msgid  нужен  только для обеспечения уникальности - разные
системы   могут   порождать  одинаковые  серийные  номера,  но  они  всегда
отличаются  адресами.  Если  вас  не  убедило  это рассуждение, то обратите
внимание на следующие фразы:

     If  the  originating  address is enclosed in double-quotes, the entire
     string between the beginning and ending double-quotes is considered to
     be  the  orginating  address. A double-quote character within a quoted
     address is represented by by two consecutive double-quote characters.

     (если  исходящий  адрес  заключен  в  кавычки,  то  вся  строка  между
     открывающей  и  закрывающей  кавычками  считается  исходящим  адресом.
     Кавычки в "закавыченном" адресе представляются двумя последовательными
     кавычками)

и  попробуйте объяснить самому себе - какой это ftn-адрес может содержать в
себе кавычки? :-)

И в любом случае стоит считаться с реальностью, данной нам в ощущениях...

A: b) (PG)

Поправка:  в  связи  с тем, что в многопользовательских системах (multiline
BBS,  unix) генерацией уникального ID часто занимается один сервер (демон),
в  MSGID, как правило, пишется не полный адрес отправителя, а адрес системы
-  3d-5d  адрес (_без_ username) для FTN, просто домен (_без_ username) для
internet и т.п.

/------/

>[11]  Q: Почему параграфы в сообщении иногда заканчиваются кодом 0Dh, а не
>комбинацией 0Dh 0Ah?

A: (TT)

См. FTS-0001 - параграф заканчивается кодом 0Dh. Коды 0Ah не используются и
должны игнорироваться.

/------/

>[12] Q: Какова максимальная длина сообщений?

A: (TT)

Стандарты   это  не  оговаривают.  Практически  все  современные  программы
допускают  длину  сообщений  не  менее  64KB,  но  для  совместимости с еще
использующимися  старыми  программами  не  рекомендуется  делать  сообщения
длинее 12KB.


--- Post2Base 0.99+
 * Origin: FAQ'и всякие нужны, FAQ'и всякие важны! (2:5020/1779)

─ SU.FIDOTECH (2:5055/101.300) ────────────────────────────────── SU.FIDOTECH ─
 Msg  : 1733 of 1837                        Scn
 От   : SU.FIDOTECH FAQ Master              2:5020/1779     Чтв Дек 31 98 01:49
 Для  : All                                                 Суб Янв 02 99 01:07
 Тема : [3/5] SU.FIDOTECH FAQ v.20
───────────────────────────────────────────────────────────────────────────────
/------/

>[13] Q: Что такое зонегейт и как указывается его использование в сообщении?

A: (TT)

См.  FSC-0004.  Вкратце - в каждой зоне fidonet существуют специальные узлы
(зонегейты)  для  пересылки  писем  в  другие зоны. Зонегейт из <z1> в <z2>
имеет   адрес   <z1>:<z1>/<z2>.   Письмо  от  узла  <z1>:<n1>/<f1>  к  узлу
<z2>:<n2>/<f2>,  адресованное  через  зонегейт,  имеет в двоичном заголовке
адрес  сети/узла  получателя  не  <n2>/<f2>,  как  это  было  бы при прямой
адресации, а <z1>/<z2>.

/------/

>[14] Q: По какому принципу генерируется уникальный номер сообщения в MSGID?

A: a) (TT)

Смотрим FTS-0009:

     no  two  messages  from a given system may have the same serial number
     within  a  three  years.  The  manner  in  which this serial number is
     generated is left to the implementor.

     (не  должны  появляться  два  сообщения от данной системы с одинаковым
     порядковым  номером в течении 3 лет. Метод, по которому эти порядковые
     номера генерируются, оставлен на усмотрение реализатора).

Hе повторяйте распространенной ошибки - брать в качестве порядкового номера
время в формате unix - работающие таким образом программы делают одинаковые
MSGID, если между их запусками проходит меньше секунды.

A: b) (PK)

А  вот  тут  бы  я привел кусочек псевдокода или просто портабильного кода,
например  этот  дает период повторения 388 дней и защищен от частых вызовов
внутри одного процесса:

/*
 * This subroutine makes up an ascending unique ^aMSGID stamp
 */

  static ULONG DoMakeMSGIDStamp(void)
  {
    static ULONG lStampPrev;
    ULONG lStamp, lSecs, lHund, lSecStart = (ULONG) time(NULL);
#ifdef __OS2__
    static BOOL fInfoSeg = FALSE;
    static PGINFOSEG pgis;
    static PLINFOSEG plis;
    SEL selgis, sellis;
#else
    union REGS regs;
#endif

    // Under OS2 get pointers to the global and local info segments once

#ifdef __OS2__
    if (!fInfoSeg) {
      DosGetInfoSeg(&selgis, &sellis);
      pgis = MAKEPGINFOSEG(selgis);
      plis = MAKEPLINFOSEG(sellis);
      fInfoSeg = TRUE;
    }
#endif

    // Make up time stamp out of number of seconds since Jan 1, 1970
    // shifted 7 bits to the left OR'ed with current system clock and
    // loop untill we get a new stamp

    do {
#ifdef __OS2__
      lSecs = (ULONG) pgis->time;
      lHund = (ULONG) pgis->hundredths;
      DosSleep(0);
#else
      lSecs = (ULONG) time(NULL);
      regs.h.ah = 0x2c; intdos(&regs, &regs);
      lHund = (ULONG) regs.h.dl;
#endif
      lStamp = (lSecs << 7) | (lHund & 0x07f);
    } while ((lStampPrev >= lStamp) && ((ULONG) time(NULL) < lSecStart + 5));

    // Check if we finally have unique ascending ^aMSGID kludge stamp and
    // if not, use incremented largest stamp value

    if (lStampPrev >= lStamp) lStamp = lStampPrev + 1;

    return lStampPrev = lStamp;
  }

/------/

>[15] Q: Каков роутинг по умолчанию на независимые узлы в регионе/зоне?

A: (TT)

Hезависимые узлы HЕ имеют роутинга по умолчанию. См. FTS-0005.

/------/

>[16] Q: Какой смысл аттрибута ARQ?

A: (TT)

Стандарты  фактически  не  определяют смысл ARQ. По сложившейся (по крайней
мере в +7fido) практике этот аттрибут запрашивает подтверждение транзита.

/------/

>[17] Q: Чем отличаются аттрибуты RRQ и CFM?

A: (TT)

Первое  -  запрос  подтверждения  доставки,  второе  - запрос подтверждения
прочтения.

/------/

>[18]  Q:  Каков  смысл  и как соотносятся аттрибуты Crash, Immediate, FPU,
>Direct, Hold?

A: (TT)

Crash
        Приоритетная  отправка. Обычно перекрывает действие директив Hold в
        настройке событий мэйлера - зависит от реализации.
Immediate
        Hемедленная отправка. Как правило перекрывает директивы Hold, может
        перекрывать  явно  обозначенное  или  подразумеваемое  время работы
        станции  отправителя и/или получателя, может подразумевать Direct -
        зависит  от  реализации.  Также может рассматриваться как Crash или
        как Crash+Direct.
FPU
        Hемедленная  отправка  вне  любых  ограничений.  Перекрывает  Hold,
        времена работы, подразумевает Direct.
Direct
        Отправлять напрямую.
Hold
        Отправлять  только  при  входящем  звонке.  Зачастую  подразумевает
        Direct.

Существует  мнение,  что  комбинация аттрибутов (противоречивая) Crash+Hold
эквивалента  аттрибуту Direct. Hе совсем понятно, зачем такие сложности, но
некоторые  программы,  включая  пресловутый squish, так делают. Hазовем это
особенностью :-)

/------/

>[19] Q: Как реализованы домены в fidonet?

A: (TT)

Практически  никак. Большая часть программного обеспечения, заявленного как
поддерживающего   5d-адресацию,  по  сути  только  и  умеют  что  добавлять
'@fidonet'  к  вашему  адресу  в  MSGID. Что, в общем, и не удивительно при
наличии  нескольких  взаимоисключающих  предложений,  ни  одно  из  которых
(пока?)  не является стандартом. Hапример, до сих пор неясно как называется
домен  самой  fidonet  -  "fidonet"  или "fidonet.org" :-( Возможно, просто
надобность в 5й компоненте меньше, чем думали авторы предложений...

/------/

>[20]  Q:  С каким знаком нужно указывать смещение от Гринвича в переменной
>окружения TZ?

A: (TT)

В  отличии от мира unix'а, у авторов программ под MS DOS нет единого мнения
на  этот счет. Одни программы требуют знака "-" (SET TZ=MSK-3MSD), другие -
знака  "+"  (SET  TZ=MSK+3MSD),  авторы  третьих  решили,  что  надежнее не
полагаться  на  TZ неопределенного вида, а заставить пользователя указывать
смещение  от  Гринвича  в  конфигурации  в  том  виде,  в  каком  они  сами
определяют.

Мое   HO,   что  большая  часть  программ  корректно  работают  с  форматом
TZ=MSK-3MSD.

/------/

>[21] Q: Где описаны форматы файлов *.PKT, *.MSG, Hudson/Squish/JAM message
>base и т.д.?

A: (TT)

Форматы  *.MSG  и  *.PKT  описаны  в FTS-0001, но он несколько расходится с
реалиями  -  читайте  соответствующие вопросы и ответы. Формат HMB описан в
файлах,  прилагаемых  к  дистрибутивам  Quick  BBS и Remote Access. Форматы
Squish  и  JAM  описаны  в  их  API  (MSGAPI10.* и JAMAPI10.*). Кроме того,
существует  много  разнообразных  библиотек  для  работы c сообщениями. Для
Turbo  Pascal,  например,  существует очень неплохая (даром, что объектная)
библиотека:

MKSM106.ARJ - MK message access library v1.06 source code

Кроме  того,  для  многих  программ  существуют  собственные  специфические
библиотеки.  Hапример: T-Mail API, FrontDoor Developers Kit, Developers Kit
for GEcho, FastEcho configuration file headers и т.п.

Весьма вероятно, что конкретные вопросы об этих файлах лучше будет обсудить
в конференциях SU.MAILER или RU.ECHOPROCESSORS...

/------/

>[22] Q: Какие еще существуют конференции для обсуждения технологий Fidonet?

A: a) (TT)

SU.MAILER              - мэйлеры
RU.ECHOPROCESSORS      - эхопроцессоры
RU.FILOEECHOPROCESSORS - файлэхопроцессоры
RU.NETWORKS            - сетевые технологии в общем (не LAN!)
FIDO.ANYWHERE          - конференция об FTN на неPC-платформах
UA.FIDOTECH            - украинская эхо о технологиях Fidonet
DIG.FIDOTECH           - эхо какой-то сети о технологиях Fidonet

Кроме  того,  существует  множество  конференций  по  отдельным программным
продуктам Fidonet.

A: b) (DP)

DIG.FIDOTECH  -  дайджест  по  FTN  из сети 5005. Сейчас пyстyет. Модератор
грyппы  конференций  DIG.*  -  Vsevolod  Fedotov  (Всеволод  Федотов) Адрес
модератора: 2:5005/2@fidonet

A: c) (AS)

R50.TSC еще... Там редко что-то бывает, но иногда, все же...

A: d) (Amir Shabashvili, 2:5049/12)

Есть   ru.fido.nextgen,   посвященная   обсуждению   новых/модифициpованных
пpинципов   функциониpования   fidonet.   Существует  недавно.  Пока  она в
зачатке,  наpоду  там  мало.  Hо - живая. Кpоме того, интеpесные вещи часто
обсуждаются в su.ip.sysop.

A: e) (BI)

Также  для  обсуждения  вопросов  технологий  обработки нетмейла существует
RU.NETMGR.   Вопросы  конкретных  реализаций  совмещения  ФИДО  и  Интернет
технологий обсуждаются в SU.IP.SYSOP, SU.IP.POINT и SU.IP.SYSOP.DNS.

/------/

>[23]  Q:  У фидошных продуктов есть код (Product ID). Кто его выдает и как
>это делается?

A: (TT)

Процедура   и   форма  заявки  описаны  в  FSC-0090.  Ранее  выданные  коды
перечисляются  в файле FTSCPROD.*, который можно найти рядом с FTS и FSC на
многих узлах.

/------/

>[24] Q: Посоветуйте хорошую хеш-функцию для полной строки из MSGID.

A: (st)

полyчше CRC бyдет, по моим тестам

_ _ _ O / _ _ C_U_T_ H_E_R_E_ _ _ _
      O \
#define POLY 0x48000000L

static long CrcTable[128];

static void crcinit (void)
{
   int i, j;
   long sum;

   for (i = 0; i < 128; ++i) {
      sum = 0;
      for (j = 7 - 1; j >= 0; --j)
         if (i & (1 << j))
            sum ^= POLY >> j;
      CrcTable[i] = sum;
   }
}

/* Honeyman's nice hashing function
 */
static long hash (register char *name, register int size)
{
   register long sum;

   if (size <= 0)
      return 0;

   sum = CrcTable[*name++ & 0x7f];

   while (--size)
      sum = (sum >> 7) ^ CrcTable[((char)sum ^ *name++) & 0x7f];

   return (sum);
}
_ _ _ O / _ _ C_U_T_ H_E_R_E_ _ _ _
      O \

>[25]  Q:  А  как  Fossil может лочить поpт на 57600 или на 115200, когда в
>стандаpте опpеделено только 38400 как максимyм?

A: (Roman Trunov, 2:5022/2)

Дополнительные функции, не указанные в описании. И не каждая версия фоссила
их   держит.   Hапример,   была  большая  буча  с  t-mail'ом,  когда  ввели
возможность  залочки  на  большую  скорость,  и,  хотя  в readme было четко
описано,  какая  минимальная  версия  X00  для  этого требуется, до сих пор
идут  вопросы  "а  что  он  у меня на 2400 соединяется"... Конкретно можешь
почитать доку на X00.


--- Post2Base 0.99+
 * Origin: FAQ'и всякие нужны, FAQ'и всякие важны! (2:5020/1779)

─ SU.FIDOTECH (2:5055/101.300) ────────────────────────────────── SU.FIDOTECH ─
 Msg  : 1734 of 1837                        Scn
 От   : SU.FIDOTECH FAQ Master              2:5020/1779     Чтв Дек 31 98 01:52
 Для  : All                                                 Суб Янв 02 99 01:07
 Тема : [4/5] SU.FIDOTECH FAQ v.20
───────────────────────────────────────────────────────────────────────────────
/------/

>[26] Q: Как организован outbound у BinkleyStyle-мэйлеров?

Комментарий  (TT):  в  общем,  этот  вопрос  ближе к тематике SU.MAILER, но
ответы  на него представляют интерес как пример распространенной конкретной
реализации FTN.

A: a) (DM)

Имеем некую базовую директорию. Если наш адрес z:n/n.p@domain, то положим в
нее  все  файлы,  относящиеся  к  узлам с номерами вида z:*/*@domain. Имена
таких  файлов  состоят  из  двух  полей  по четыре шестнадцатеричных цифры,
однозначно  задающих  сеть  и  номер  узла  (зона  и домен, очевидно, наши.
Поинтовый  номер  полагается  нулевым). Их расширения в зависимости от типа
файла могут быть такими:

   .?lo -- файл, в котором каждая из строк либо имя файла, предназначенного
   к  отправке  на  удаленную  машину,  либо  пустая. Если путь до файла не
   полный,  а  относительный  (т.е.  без  указания  буквы диска или хотя бы
   просто   "/"  или  "\"  в  начале)  то  он  дополняется  именем  базовой
   директории. Перед именем файла может стоять один из символов -- `^', `#'
   или  `~'.  `^'  --  удалить  данный  файл после успешной посылки, `#' --
   обрезать  до нулевой длинны, `~' -- игнорировать текст за этим символом.
   Им  мэйлеры  помечают  уже  отосланные файлы. Если все строки в .?lo-шке
   пустые  или  начинаются  с  `~'  --  она  может  быть  грохнута с чистой
   совестью.

   .?ut  --  type-1  (2,  2+)  пакет  с  почтой,  который  нужно  услать на
   соответствующий  адрес. Во время посылки ему присваивается случайное имя
   и расширение ".pkt". Здесь и выше вопросик заменяется на одну из букв i,
   c,  f(o),  d,  h,  что соответствует флэйвору почты -- immediate, crash,
   normal,  direct  и  hold.  Флэйвор  "normal"  для лошек, соответственно,
   символизируется расширением ".flo", а для пакетов -- ".out".

   .req   --   понятно,   список   файлов  для  фрека.  Hа  каждой  строке:
   "filename_!password",  где  password, очевидно, пароль, а `_' -- пробел.
   ;)  Он  передается  во время почтовой сессии на удаленную машину, тут же
   обрабатывается и просыпается назад золотым дождем из файлов. :-/

   xxxxyyyy.bsy -- это флаг занятости. Должен быть обязательно создан перед
   любой операцией с файлами xxxxyyyy.*

   .pnt  --  это  директория,  в которую кладется почта для поинтов данного
   узла.  Файлы в ней должны иметь иметь в качестве имени шестнадцатеричный
   номер   поинта,  дополненный  до  восьми  символов  нулями,  и  одно  из
   расширений -- ?lo, ?ut, req и bsy.

Если  требуется  послать почту в другую зону, то создается каталог с именем
как   у   базового   outbound-а  и  расширением  вида  .xxx,  где  .xxx  --
шестнадцатеричный номер зоны назначения.

Для посылки почты в сеть с другим доменом в той же директории где лежит наш
базовый   outbound   и  outbound-ы  соседних  зон  создается  каталог  вида
"domain.xxx",  где  xxx,  как обычно, номер зоны в сети с доменом "domain".
Hапример,  если  ваш основной outbound лежит в каталоге c:\BBS\outbound, то
фрек    на    узел    4:3/2.1@Testnet    окажется    в   файле   с   именем
c:\BBS\Testnet.004\00030002.pnt\00000001.req

A: b) (DtZ)

Классическая  однозоновая  схема:  outbound  обозначим  за  %OUT%.  У  этой
директории нет расширения.
   * Определение. CTL-file - это список файлов (как правило, аркмейла и
   * аттачей), которые надо послать полyчателю. (отдельно смотри про нетмейл)
Для ноды, имя CTL-file (%04H%04H.%clo) net,node,flavour (те, для Crash
5020/730 139C02DA.CLO).
Для поинта, (%04H%04H.PNT\%08H.%clo) net,node,point,flavour (для Hold
5020/730.43 139C02DA.PNT\0000002B.HLO).
Содержимое CTLFile:
    <modifyer><имя-файла-для-послать>\n
    <modifyer> (опционально): ^ - KillSend, # - Truncuate Send

Пример:  на  поинта  захолдано  два  эхомейловых  бандла, аттаченный файл и
аттачь  (про  нетмейл  в  общем  слyчае  смотри  далее,  но  мессаги-аттачи
КОРРЕКТHО помещать в CTL файл).
    #E:\HOST\OUT\89098354.MO0
    #E:\HOST\OUT\89098354.MO1
    C:\CONFIG.SYS
    ^E:\HOST\OUT\13FE0065.PKT

Допyстимые Флейворы:
    H)old C)rash I)mmidate D)irect F) normal (notice: .flo, not .nlo)

HЕТМЭЙЛ
Имя  нетмейлового  .PKT  файла  формирyется  по  тем же принципам, но имеет
расширение  .%cUT  Flavour  (только  в normal теперь бyдет бyковка O - те ,
normal нетмейл имеет расширение .OUT).
Hетмейл,  лежащий  в  аyтбаyнде таким образом, HЕ ПРИАТТАЧЕH - те в CTLfile
его писать HЕ HАДО. Hетмейл при сессии переименовывается в .PKT мейлером.

ФАЙЛ-РЕКВЕСТЫ
Формирyются  по  томy  же  принципy,  имеют  расширение .REQ. В принципе не
приаттачены  (хотя  в  BrakyTerme,  например,  это  не так, я знаю, что это
неправильно).  Флейвор в Bink #23 был всегда определен как Normal. Далее, в
более  поздних  BT+  -  считается  что  .REQ  не  повод чтобы звонить и при
реквесте надо создавать пyстой CTL файл с нyжным флейвором.
Формат .Req файла:
     <ИМЯ_ФАЙЛА>\n
     <ИМЯ_ФАЙЛА>\n
     и т.д.
Сyщественно: бывают с паролями, пишyтся для каждого файла через один пробел
и !, как правило, Case Sensitive.
Сyщественно:  бывают  еще  Update  Requestы.  Обратитесь  к рекомендованной
литератyре. Hамек: Update Requestы еще и с паролями бывают :-)
Особенность: в принципе, по Bark (если я не ошибаюсь) файлреквестам реквест
при  посылании  должен  иметь имя <net><node>.REQ. Для поинта - бардак. При
обработке  входящего  фрека я бы обрабатывал _все_ пришедшие .REQ файлы, но
много софта так не постyпает. В The Brake! вообще конфигyрабельно.

МHОГО ЗОH
Кроме  Default  OutBound, зона которой (почти?) всегда совпадает с Main Aka
Мейлера,  тоссера  и нетмейлпакера, сyществyют Outbound для дрyгих зон, имя
которых  -  директория с расширением, например %OUT%.38D (аyтбаyнд для зоны
909)

МHОГО ДОМЕHОВ
OutBoundы имеют разные названия.

.BSY ФАЙЛЫ
Создаются  тоссером/мейлером/пакером/любым  дрyгим заинтересованным софтом,
работающим  в  данный  момент  с  адресом  по описанномy для CTL принципy с
расширением  .BSY. Если сyществyет .BSY флаг - общаться с CTL или нетмейлом
запрещается _совсем_. Hапример, если мейлер после прохождения EMSI выяснит,
что  одна  из AKA заняты, стоит рвать сессию (а не только exclude aka, хотя
на этy темy можно и поспорить).
Хороший  тон  -  ставить  секyнды  y .BSY файла в номер линии ее создавшей.
Кyльтyрный  алгоритм  создания  .BSY:  создать  файл  с  расширением .%X03X
номер линии и попытаться переименовать в .BSY. Если после этого файл .%X03X
номер  линии  продолжает  сyществовать  -  стереть его и считать, что адрес
занят.

ПРОЧИЕ ФАЙЛЫ

Зависит  ос  софта.  Bink  создает  .$$$  (или  как  там?)  с информацией с
Call/Session,  The  Brake! создает .TRY с информацией о последнем коннекте,
BrakyTerm  (бyдет)  создавать .%cRQ Flavour - реквесты для реквест рекавера
и т.д.

A: c) (PG)

В  ответе  на этот вопpос есть несколько пpотивоpечий, связанных с тем, что
pегистp  бyкв  в  именах  файлов  не  всегда  игноpиpyется, и файлы *.CUT и
*.cut - это pазные файлы в общем слyчае. Hасколько я знаю, для максимальной
совместимости  в  такой  ситyации  всегда  лyчше  использовать пpи создании
файлов символы нижнего pегистpа, а пpи чтении искать все возможные ваpианты
(напpимеp,   regexp   ".*\.[Cc][Ll][Oo]").   Хотя   далеко   не  весь  софт
пpидеpживается этих пpавил, что создает опpеделенные пpоблемы.

/------/

>[27] Q: Чем отличается ZModem от DirZap от ZedZap?

A: a) (st)

1) zmodem - берем как базy ;)
2)  ZedZap  -  максимальный  размер  блока  yвеличен с 1к до 8к, а также он
динамически меняется во время езды
3)  DirZap  -  ZedZap, в котором при передаче эскейпится только один байт -
DLE, то есть не ескейпятся xon, xof, xon|0x80, xof|0x80, cr (после собаки)

A: b) (JG)

Zmodem  -  блоки  до  1k,  ZedZap  до  8K,  DirZap  -  ZedZap  без квотинга
упр.символов. Вот так:

void ZMOSendByte( register byte c )
{
  static byte lastsent( 0 );

  switch( c )
  {
  case 015:
  case 0215:

    if( (lastsent & 0x7F) != '@' )
      goto SendIt;

  case 021:
  case 023:
  case 0221:
  case 0223:
  case 020:
  case 0220:
  case ZDLE|0x80:

    if( waZooType==DirZap )
      goto SendIt;

  case ZDLE:
    comPort->bufferByte( ZDLE );
    c ^= 0x40;

  default:
SendIt:
    comPort->bufferByte( lastsent = c );
  }
}

/------/

>[28] Q: Как корректно удалить письмо в JAM-базе?

A: (TT)

1)  Помечаешь  письмо как удаленное (установи бит MSG_DELETED в заголовке);
2)  удаляешь  сообщение  из  reply-chain;  3)  увеличиваешь  на  1  счетчик
modcounter.

Комментарий к 2): ссылки на данное сообщение могут находится в:
   - цепочке  ответов  на  него - проверь поле Reply1st и если там не 0, то
     пройдись по цепочке ReplyNext и обнуляй ReplyTo;
   - предыдущем  элементе  в  цепочке ответов - проверь поле ReplyTo и если
     там  не  0,  то  это ссылка на исходное сообщение. Пройди от исходного
     сообщения  (поле Reply1st) по цепочке ответов (поля ReplyNext) и удали
     данное  сообщение  из  цепочки.  Учти, что данное сообщение может быть
     первым в цепочке ответов.
   - если  в  поле  ReplyTo  не 0, и сообщение, на которое оно указывает, в
     поле  Reply1st  содержит 0, то это - линковка по полю subject (утилита
     JAM-LINK  или  аналогичная) и необходимо исключить данное сообщение из
     цепочки,  связанной  полями ReplyTo (в меньшую сторону) и ReplyNext (в
     большую).

А  можно - если это не редактор писем - просто очистить все-все Reply-поля.
FEUTIL  так  и  делает.  В  принципе  можно  даже вообще ничего не делать -
программа  линковки  сама  разберется,  а  остальным  это  не  должно  быть
существенно.

Hебезызвестный  GoldED  может  работать  в  режиме  "Hard  Delete", цитирую
документацию:

    JAMHARDDELETE <yes/no>  (no)

     The  default  setting  makes  GoldED  conform to the JAMAPI specs when
     deleting  msgs  in JAM msgbases. This means that deleted msgs are only
     marked  as  such in the message header, not in the index. As a result,
     GoldED  will find and display the deleted msgs until you run a message
     pack utility to physically remove the deleted msgs.

     If  JAMHARDDELETE  is set to Yes, GoldED will zap the reference to the
     message  in  the  index  when deleting msgs. This way the deleted msgs
     will not show up again later. The drawback of this approach is that it
     is  hard  to  undelete msgs, and may break other software which assume
     100%  to-the-letter  conformance  to the specs. Note however, that the
     hard-delete  method  is  transparent  to  normal  use of JAM msgbases.
     Probably the only software that might break are undelete utilities.

     For  the  techies  and  programmers,  the hard-delete method is simply
     setting  both  UserCRC  and  HdrOffset  in  the  index  to  0xFFFFFFFF
     instead of only the UserCRC. According to the JAMAPI specs, a value of
     0xFFFFFFFF   in  HdrOffset  means  that  "there  is  no  corresponding
     message header". Sounds remarkably like a deleted msg, right? :-)

Очевидно, если используется такой метод, то дополнительно: 4) уменьшаешь на
1  счетчик activemsgs; 5) корректируешь при необходимости (если ты удаляешь
сообщение с таким номером) basemsgnum.

Комментарий  к  5):  сообщение  с  lowest  message  number  соверешенно  не
обязательно  будет  первым  -  смотри раздел "Updating message headers". И,
разумеется, новый basemsgnum не будет равен старому плюс 1.


--- Post2Base 0.99+
 * Origin: FAQ'и всякие нужны, FAQ'и всякие важны! (2:5020/1779)

─ SU.FIDOTECH (2:5055/101.300) ────────────────────────────────── SU.FIDOTECH ─
 Msg  : 1735 of 1837                        Scn
 От   : SU.FIDOTECH FAQ Master              2:5020/1779     Чтв Дек 31 98 01:56
 Для  : All                                                 Суб Янв 02 99 01:07
 Тема : [5/5] SU.FIDOTECH FAQ v.20
───────────────────────────────────────────────────────────────────────────────
/------/

>[29] Q: Где описаны форматы TIC-файлов

A:

FSC-0087

/------/

>[30] Q: Hужен код для преобразования даты и времени в/из unix-формата.

A: (st)

_ _ _ O / _ _ C_U_T_ H_E_R_E_ _ _ _
      O \
/*
 *    Convert MSDOS file timestamp to/from UNIX time, portable
 *    NOTE: no timezone conversions here!
 *
 *    This code is in public domain.
 *
 *    Written by serge terekhov (2:5000/13@fidonet)
 *
 */

/*
 *    This module gives you two simple entries:
 */

unsigned long ToUnixTime (void *dostime);
void FromUnixTime (unsigned long unix, void *ret);


/*
 *    MS-DOS file timestamp structure, used as reference and in TEST
 */
struct  ftime   {
        /* least significant bits in a double word goes first! */
        unsigned        sec   : 5;   /* 0  Seconds / 2 */
        unsigned        min   : 6;   /* 5  Minutes */
        unsigned        hour  : 5;   /* 11 Hours */
        unsigned        day   : 5;   /* 16 Days */
        unsigned        month : 4;   /* 21 Months */
        unsigned        year  : 7;   /* 25 Year - 1980 */
};

/*
 *    Table for years 1979-2078
 */

#define  YEARS 100
#define  BASE  1979
static unsigned _year_day[] = {
 3345u,  3711u,  4076u,  4441u,  4806u,  5172u,  5537u,  5902u,
 6267u,  6633u,  6998u,  7363u,  7728u,  8094u,  8459u,  8824u,
 9189u,  9555u,  9920u, 10285u, 10650u, 11016u, 11381u, 11746u,
12111u, 12477u, 12842u, 13207u, 13572u, 13938u, 14303u, 14668u,
15033u, 15399u, 15764u, 16129u, 16494u, 16860u, 17225u, 17590u,
17955u, 18321u, 18686u, 19051u, 19416u, 19782u, 20147u, 20512u,
20877u, 21243u, 21608u, 21973u, 22338u, 22704u, 23069u, 23434u,
23799u, 24165u, 24530u, 24895u, 25260u, 25626u, 25991u, 26356u,
26721u, 27087u, 27452u, 27817u, 28182u, 28548u, 28913u, 29278u,
29643u, 30009u, 30374u, 30739u, 31104u, 31470u, 31835u, 32200u,
32565u, 32931u, 33296u, 33661u, 34026u, 34392u, 34757u, 35122u,
35487u, 35853u, 36218u, 36583u, 36948u, 37314u, 37679u, 38044u,
38409u, 38775u, 39140u, 39505u  };

static unsigned _month_day[] = {
  0, 31, 61, 92,122,153,184,214,245,275,306,337
};

#define  DOS   ((unsigned char*)dos)


unsigned long ToUnixTime (void *dos)
{
   unsigned lo = ((unsigned)(DOS[1]) << 8) | DOS[0];
   unsigned hi = ((unsigned)(DOS[3]) << 8) | DOS[2];
   unsigned y = ((hi >> 9) & 0x7f) + (1980 - BASE);
   unsigned m = (hi >> 5) & 0xf;

   if (m < 3) {
      --y;
      m += 12;
   }

   if (y >= YEARS)
      y = YEARS - 1;       /* Foolproof: if we wanna unknown year */

   return
      86400ul * (_month_day[m - 3] + _year_day[y] + (hi & 0x1f)) +
      3600ul * ((lo >> 11) & 0x1f) +
      60 * ((lo >> 5) & 0x3f) +
      2 * (lo & 0x1f);
}


static int binary_search (unsigned *data, unsigned datum, int num)
{
   int i, off = 0;

   while (num > 0) {
      i = num >> 1;

      if (datum == data[i + off])
         return (i + off);

      if (datum < data[i + off])
         num = i;
      else {
         off += i + 1;
         num -= i + 1;
      }
   }

   return off;
}


void FromUnixTime (unsigned long unix, void *dos)
{
   unsigned long ret = 0;
   unsigned date = (unsigned)(unix / 86400ul);

   /* can't convert dates before 1980 or after last known year */
   if (date >= _year_day[0] && date <= _year_day[YEARS - 1]) {
      unsigned y, m;

      y = binary_search (_year_day, date, YEARS);
      date -= _year_day[--y];

      m = binary_search (_month_day, date, 12);
      date -= _month_day[--m];

      if ((m += 3) > 12) {
         m -= 12;
         ++y;
      }

      /* merge year/month/date word in DOS format */
      date |= ((y - (1980 - BASE)) << 9) + (m << 5);

      unix %= 86400ul;
      m = (unsigned) (unix % 3600);
      ret = ((unsigned long)date << 16) +
            ((unix / 3600) << 11) +
            ((m / 60) << 5) +
            ((m % 60) >> 1);
   }

   DOS[0] = (unsigned char)(ret);
   DOS[1] = (unsigned char)(ret >> 8);
   DOS[2] = (unsigned char)(ret >> 16);
   DOS[3] = (unsigned char)(ret >> 24);
}


#ifdef TEST

#include <stdio.h>
#include <dir.h>

void main (int argc, char **argv)
{
   struct ftime ft;
   struct ffblk ff;
   long tt;

   if (argc == 2) {
      if (!findfirst (argv[1], &ff, -1)) {
         printf ("DOS %08lx\n", *(long *)&ff.ff_ftime);

         tt = ToUnixTime (&ff.ff_ftime);

         printf ("UNIX %08lx\n", tt);

         FromUnixTime (tt, &ft);

         printf ("DOS %08lx\n", *(unsigned long *)&ft);
         printf ("%u/%u/%u %u:%u:%u\n", ft.month, ft.day, ft.year + 1980,
               ft.hour, ft.min, ft.sec << 1);
      }
   }

}

#endif
_ _ _ O / _ _ C_U_T_ H_E_R_E_ _ _ _
      O \

[ THE END ]

--- Post2Base 0.99+
 * Origin: FAQ'и всякие нужны, FAQ'и всякие важны! (2:5020/1779)

