faqs.org.ru

 Главная > Программное обеспечение > Программы для BBS >

FAQ по MEX - языку для Maximus

From: Alex Shiloff <Alex.Shiloff@f152.n5080.z2.fidonet.org>
Date: Mon, 25 Sep 2000 13:05:00 +0400


       XXX+   XXX+ XXXXXXX+ XX+  XX+          XXXXXXX+  XXXXX+   XXXXXX+
       XXXX+ XXXX| XX+====+ +XX+XX++          XX+====+ XX+==XX+ XX+===XX+
       XX+XXXX+XX| XXXXX+    +XXX++           XXXXX+   XXXXXXX| XX|   XX|
       XX|+XX++XX| XX+==+    XX+XX+           XX+==+   XX+==XX| XX|-- XX|
       XX| +=+ XX| XXXXXXX+ XX++ XX+          XX|      XX|  XX| +XXXXXX++
       +=+     +=+ +======+ +=+  +=+          +=+      +=+  +=+  +==--=+

               Наиболее часто задаваемые вопросы и ответы на них.
                      By Alex Shiloff, 2:5080/152@FidoNet

                           Редакция от 10.09.1998

   Последний вариант постится в SU.CBCS раз в две недели или по получению
                           интересного материала

+--------       -------------------------------------------------------------+
|По сравнению с предыдущей версией дополнен вопрос 11                        |
+---------------------------------------------------------------      -------+

                                Содержание
                                ==========

 1. Что же это вообще такое - MEX ?
 2. Что такое параметры и зачем их куда-то передавать?
 3. Как сделать, чтобы при вызове MEX проги она находила переданные ей пара-
    метры?
 4. Как из файла языковой поддержки *.MAD вызывать МЕХ программу?
 5. Запускаю МАКС с ключем -nX. Как в МЕX узнать номер задачи?
 6. Как запустить из под МЕХ Ехе-шник и батник?
 7. Как избежать переполнения сегмента данных?
 8. А есть ли ограничение по размеру программы на MEX?
 9. А нельзя ли запускать из МАКСа две МЕХ программы одновременно?
10. Можно ли переписать какой-нибудь символ на экране (или строку) не трогая
    все остальные.
11. Как из МЕХ сделать hangup юзера?
12. Как  добавить времени пользователю?
13. Почему при считывании функциональных клавиш коды, получаемые с локальной
    и удаленной консоли различаются?
14. Что такое #операторы?
15. Чем отличаются функции timeadjust() от timeadjustsoft() ?
16. Как мне унифицировать свою MEXу, чтобы она не была привязана, например, к
    конкретным каталогам?
17. Окей! Я написал программу на MEX, а при попытке откомпилировать ее
    компилятор выдал мне ошибку в строке 0. Он что, идиот? Ведь такой строки
    нет!!! Что делать?
18. Мне не нравится, что новым юзерам предоставляется слишком большая свобода
    в выборе параметров при начальной регистрации. Как-бы не дать им отвечать
    на все эти слишком умные для них вопросы?
19. Как можно не пyскать новых пользователей, y котоpых скоpость  ниже,
    чем , к пpимеpy, 21600, но пpи этом, чтобы стаpые заходили без  пpоблем,
    даже на 9600.
20. Kак дeфолтом юзвeрям Z-modem cтавить?
21. Как сделать в МЕКСе быстрое обновление информации о юзвере?
22. Люди!!!!!!!,как на mex`e прописать,чтобы времечко показывалось? Не то
    которое осталось до конца сеанса,а реальное.
23. Почему-то MEX'ова функция readln(int, ref string); некорректно работает
    с файлами размером больше чем 32 кбайта. MAX v3.00.
24. Пример отслеживания наличия ANSI на удаленном терминале, с тем чтобы
    корректно отображать Logo.bbs
25. Числовые типы языка MEX (просто рекомендация, или обзор "камушков",
    чтобы вам не натыкаться на это в дальнейшем)
26. Как в Mex'е заставить ожидать нажатия на enter ? Или на другую конкретную
    клавишу?
27. Остроумный  пример  динамического  выбора  и  запуска  MEX  на  основе
    информации, полученной в MEX (фактически это почти MEX из MEX ;)
28. Как правильно употребить INPUT_DEFAULT?
29. Почему-то при выводе на экран из Мексов  все  через  строчку  пишется. =:(
    MAX/NT. В MAX/DOS все нормально.
30. Пример прикручивания АОН'а к Максу.

                                Вопросы и ответы
                                ================

- 1 -

Q: Что же это вообще такое - MEX ?
A: MEX - Maximus Extension Language  -  (язык  -  расширение  МАКСИМУСа)  -
   улучшенный язык, разработанный  для  взаимодействия  с  МАКСИМУС-CBCS  и
   обеспечивающий написание собственных программ. МЕХ состоит из компонент,
   набранных из разных  языков  программирования  -  C,  Pascal,  Basic.  В
   основном идеи MEX'а заимствованы из языка  C.  Примерно  90%.  Остальное
   (например знак присваивания) из Паскаля, и Бейсика.

- 2 -

Q: Что такое параметры и зачем их куда-то передавать (к вопросу #2) ?
A: Параметры передаются в  МЕХ  программу  из  оболочки  МАКСы  (обычно  ее
   представляет активное в данный момент меню или работающий МЕККА - скрипт
   Параметр - это такая штука, которая позволит вам разнообразить  действие
   вашей МЕХ'ы, не прибегая к созданию ее идентичных  копий,  использованию
   дополнительных файлов с данными (хотя это тоже неплохой выход). Параметр
   может быть чем угодно, то есть строкой, числом, буквой и  т.п.  -  любым
   понимаемым MEX'ом типом данных. Фактически вы наверняка уже сталкивались
   с параметрами,  когда  использовали  *.BAT  или  *.CMD  файлы.  Здесь  -
   практически то же самое.
   Единственная особенность связана с форматом CTL файла.  так  как  в  нем
   может быть только определенное количество колонок (а они  по  неписанным
   законам разделяются просто одним  или  кучей  символов  Space,  а  проще
   говоря пробелами), то непосредственно строка параметра не должна  давать
   повод думать, что она - уже следующая колонка.

   например:

колонка #1         колонка #2        колонка #3         колонка #4
тип команды    путь и имя команды   уровень доступа      описание

   MEX              M\MyProg            SysOp         "M - моя программа"

   Видим, что для программы MyProg параметры не передаются.  В случае, если
   нам требуется передать один или несколько параметров, следует писать:

   MEX              M\MyProg_Param1_Param2   SysOp    "M - моя программа"

   То есть разделителями должны служить символы  "_",  а  иначе  компилятор
   решит, что слово Param1 - уже  в  следующей  колонке  и  сопоставит  ему
   уровень доступа.

- 3 -

Q: Как сделать, чтобы при вызове  MEX  проги  она  находила  переданные  ей
   параметры?
A: В заголовке процедуры main прописать примерно следующее:

int main(string : my_parametr)
{
 ...
 print(my_parametr);
 return 1;
}
вместо string можно использовать любой нужный тип.

- 4 -

Q: Как из файла языковой поддержки *.MAD вызывать МЕХ программу?
A: Никак. (ограничение производителя - Lanius)

- 5 -

Q: Запускаю МАКС с ключем -nX. Как в МЕX узнать номер таска?
A: Есть такая запись: id. вот в ней и надо смотреть, то есть:

   id.task_num - в ней хранится истинное значение номера задачи.

- 6 -

Q: Как запустить из под МЕХ Ехе-шник и батник?
A: Чтобы запустить EXE (COM) файл из МЕХ прописывается такая строка:

menu_cmd(MNU_XTERN_RUN,"parametrs");

   а для *.bat или стандартной комманды оболочки:

menu_cmd(MNU_XTERN_DOS,"parametrs");

A: (Fedor Lizunkov 2:5020/960)
   Еще существует очень хорошая функция

   int shell(int method, string: cmd); (*)

   Которая позволяет запускать программы (согласно константам method)
   - непосредственно (IOUTSIDE_RUN)
   - через комманднй процессор (IOUTSIDE_DOS)
   - с пересчитыванием после возвращения записи юзера (IOUTSIDE_REREAD)

   У нее есть очень хорошее свойство - она возвращает в качестве значения
   код выхода вынешней программы (aka ErrorLevel)

   (*) cmd - строка с путем, именем программы и передаваемыми параметрами.

- 7 -

Q: Как избежать переполнения сегмента данных? (к вопросу #8) ?
A: (Mike Petrov 2:5020/1413) Только экспортируя часть функций (а
   особенно относящихся к видео) в файлы *.mec (*.bbs в конечном случае)
   и вызывая их в нужных местах командой:

   display_file("имя_файла",nonstop);

- 8 -

Q: А есть ли ограничение по размеру программы на MEX?
A: Да, один сегмент данных для  ДОСового  МАКСА  -  то  есть  64кил.  После
   переполнения МАКС начнет выдавать ошибку типа:

   fatal cs:ffffffff: Patch bounds exception.
   fatal cs:000004bf: Out of string space.

- 9 -

Q: А нельзя ли запускать из МАКСа две МЕХ программы одновременно?
A: Увы, не только две программы, но и одну из другой запустить не удастся.

- 10 -

Q: Можно ли переписать какой-нибудь символ на экране (или строку) не трогая
   все остальные.
A: Вот таким способом:

print(AVATAR_GOTO,(char)<row>,(char)<column>,"что вы тут хотите");

где <row> - номер строки; <column> - номер столбца, откуда начинать.

- 11 -

Q: Как из МЕХ сделать hangup юзера?
A (Fedor Lizunkov 2:5020/960.1) : можно так:

   menu_cmd(MNU_GOODBYE,"");

  - как выяснили, это несколько некорректно,
  так как интересен _немедленный_ hangup.

A: а просто взять, да обнулить время юзеру, а потом МАКС сам доделает ;)

   Вот пример программы, автор Fedor Lizunkov (2:5020/960)

   #include <max.mh>

   #include <max.mh>

void main()
{
 long: time;
 time := timeleft();
 time := (time - (timeleft() * 2)) * 60;
 timeadjust(time);
 return;
}

A: (Alexander Shevelev 2:5015/65):
  легко...
  ну скажем так :
  создаешь hangupus.mec , в него пишешь

  _______cut_____________
  щас вешаю тpубу 8)
  [hangup]
  _______cut_____________

  конвеpтишь в hangupus.bbs
  далее в своем *.mex вызываешь этот mec(bbs)

  _______cut_____________
  display_file(prm_string(PRM_MISCPATH)+"hangupus.bbs",tempint);
  _______cut_____________

A: Самое изящное решение (Evgeniy Demenuk 2:5064/7.31)

  mdm_command("+++~~~~~~ATH0|~");

- 12 -

Q: Как добавить времени пользователю?
A: (Fedor Lizunkov 2:5020/960.1) Например так:

#include <max.mh>

int main()
{
long: delta;
delta := timeadjust(600);
}

A: можно использовать внешний (EXE) модуль и вызывать его из MEX программы.

- 13 -

Q: Почему при считывании функциональных клавиш коды, получаемые с локальной
   и удаленной консоли различаются?
A: Это происходит от того,  что  с  локальной  консоли  приходят  скан-коды
   клавиш, а с удаленной - в зависимости от  терминальной  программы.  Если
   терминальная программа старая или работает  в  режиме  DOORWAY,  то  она
   будет передавать то, что юзер ввел с клавиатуры, то  есть  те  же  самые
   скан коды.  Новые терминалки преобразуют скан коды в ANSI коды  и  затем
   посылают их.  ANSI коды стрелок, например имют  вид:  [A,  [B,  [C,  [D.
   Поэтому при обслуживании функциональных клавиш следует  делать  "двойную
   проверку", то есть:

int keydet()                  // <-=1 ^=2 ->=3 v=4 Enter=5
{
 int: ch,chh,chl;
 while (1<>2)
  {
   ch:=input_ch(CINPUT_SCAN,"");
   chh:=((ch&0xFF00) shr 8);
   chl:=ch&0x00FF;
   if ((chl=91) or (chl=0)) {
      if (chl=91) chl:=input_ch(CINPUT_SCAN,"");
      if (chh=72 or chl=65) return 2; else
              ^^ скан   ^^ANSI
                 -код     -код  клавиши "стрелка вверх"

      if (chh=80 or chl=66) return 4; else
      if (chh=75 or chl=68) return 1; else
      if (chh=77 or chl=67) return 3;
   } else
   if (chl=124) return 5;
  }
}

- 14 -

Q: Что такое #операторы?
A: #операторы, а именно

    #define X Y
    #include <Z>

   являются стандартными  указаниями  компилятору  произвести  замену  всех
   найденных в тексте программы строк X на  строки  Y  и  приписать  текст,
   взятый из файла Z.  Смысловой нагрузки не несут и служат  для  повышения
   универсальности и удобочитаемости программы, так как  позволяют  разбить
   длинную  "портянку"  на  несколько  частей  и  создать  общие  модули  и
   библиотеки.

- 15 -

Q: Чем отличаются функции timeadjust() от timeadjustsoft() ?
A: Первая производит все операции, не учитывая ограничения  по  событиям  и
   ограничения, заданные в параметре МАКСа -t<TIME>, вторая - учитывает.

- 16 -

Q: Как мне унифицировать свою MEXу, чтобы она не была привязана, например, к
   конкретным каталогам?
A: Для этого есть специальные PRM-константы, которым сопоставляются
   строки из MAX.PRM файла, в том числе и стандартные МАКСовы каталоги,
   например:

   #include <prm.mh>
   print("А вот каталог МАКСА у нас: ",prm_string(PRM_SYSPATH));

   Таким образом, добраться до каталога с МАКСом, заранее не зная его и,
   например запустить вашу любимую дверку или батничек можно так:

   menu_cmd(MNU_XTERN_DOS,prm_string(PRM_SYSPATH)+"\\MYBATCH.BAT");

   ... А просмотреть MEККА-скрипт так:

   display_file(prm_string(PRM_MISCPATH)+"\\MYMECCA.BBS");

   Видим, что нигде не упоминается ни диск, не путь к файлам.

   Примечание1: эта система не распространяется на кривоположенные тупым
   ламером-сисопом файлы, и на те каталоги, которые не прописаны в PRM.
   Предполагается, что файл MAX.CTL составлен правильно. Например, если
   в качестве MISC прописан каталог MYMISCA, то в MAX.CTL должно быть
   следующее заявление:

   Path MISC    MYMISCA\

   Примечание2: каталог с МЕХ'ами в MAX.CTL не прописывается, поэтому его
   подстановка с помощью PRM-констант, увы, не пройдет.

- 17 -

Q: Окей! Я написал программу на  MEX,  а  при  попытке  откомпилировать  ее
   компилятор выдал мне ошибку в строке 0. Он что, идиот? Ведь такой строки
   нет!!! Что делать?
A: Нет, безусловно компилятор не идиот.  Просто дело в том, что  Вы  забыли
   где-то поставить завершающую скобку (скорее всего  в  конце  процедуры).
   Естественно так как скобки нет, то  строки  с  этой  скобкой  тоже  нет.
   Поэтому компилятор присваивает этой несуществующей строке номер  "0",  и
   выводит сообщение:

   myprog.mex(0) : error 2000: syntax error near XXX

   где XXX последний символ (строка), за которым ожидалась искомая скобка.

- 18 -

Q: Мне не нравится, что новым юзерам предоставляется слишком большая свобода
   в выборе параметров при начальной регистрации. Как-бы не дать им отвечать
   на все эти слишком умные для них вопросы?
A: Вот прекрасный образец МЕКС'ы которая решает этот вопрос:

// CONFIG.MEX by Mike Petrov. 2:5020/1413
//
// Задает  конфигуpацию  новому  пользователю,тем  самым  отключая  вопpосы
// Maximus.
// Пpи  использовании    CONFIG.MEX    можно    использовать    цвета    в
// APPLIC,NEW_USER1.MEC
//
// Инсталяция:  Из APPLIC.MEC вызвать M\CONFIG.

                #include <max.mh>
                int main()
                {
                usr.tabs:=TRUE;       // Использовать псевдогpафику
                usr.cls:=TRUE;        // Использовать CleanScrean
                usr.rip:=FALSE;       // HE использовать RIP
                usr.hotkeys:=TRUE;    // Использовать Hot Keys
                usr.bored:=FALSE;     // Использовать MaxEd.
                usr.video:=VIDEO_ANSI;// Использовать ANSI
                usr.ibmchars:=TRUE;   // Использовать IBMchars
                usr.configured:=TRUE; // (!)
                  return 0;
                }

(!) Обратите внимание на эту строчку.  Она  сама  по  себе  весьма  важная.
    Именно в ней МАКС'у указывается, что юзер  уже  _сконфигурировал_  свои
    установки  и  нет  необходимости  запускать    стандартную    процедуру
    регистрации.  Иначе после вашей прораммы МАКС как ни в  чем  не  бывало
    запустит свою и все труды пропадут даром.

- 19 -

Q: Как можно не пyскать новых пользователей, y котоpых скоpость ниже, чем ,
   к пpимеpy, 21600, но пpи этом, чтобы стаpые заходили без  пpоблем,  даже
   на 9600.
A: (Fedor Lizunkov 2:5020/960.1)

Включаем в самое начало файла NOTFOUND.MEC

[isremote][mex]m\speed %b

Сам файл speed.mex выглядит так

#include <max.mh>

void main(string: speed)
{
char: nonstop;
long: baud;
nonstop := 0;
baud := strtol(speed);
if (baud < 21600) display_file("misc\\speed.bbs", nonstop);
return;
}

А файл speed.mec содеpжит некотоpый текст, объясняющий, почемy сюда нельзя,
или ничего не объясняющий, но содеpжащий в конце.

[hangup]

Все ;-)

- 20 -

Q: Kак дeфолтоm узвeряm Z-modem cтавить?
A: (Mike Petrov 2:5020/1413)

   1. В config.mex дописать стpоку:
      usr.def_proto:=PROTOCOL_ZMODEM; // Юзать Z-modem
   2. В нужное место впиндиpить [menu_cmd chg_protocol].

- 21 -

Q: Как сделать в МЕКСе быстрое обновление информации о юзвере?
A: Для этого используется функция

   userupdate();

- 22 -

Q: Люди!!!!!!!,как на mex`e прописать,чтобы времечко показывалось? Не то
   которое осталось до конца сеанса,а реальное.
A: (Fedor Lizunkov 2:5020/960.1) Напpимеp так:

void main()
{
struct _stamp: now;

int: hh, mm;
string: buf;

timestamp(now);

hh := now.time.hh;
mm := now.time.mm;

buf := itostr(hh);
if (strlen(buf) = 1) buf := "0" + buf;
print(buf,":");
buf := itostr(mm);
if (strlen(buf) = 1) buf := "0" + buf;
print(buf);
return;
}

- 23 -

Q: Почему-то MEX'ова функция readln(int, ref string); некорректно  работает
   с файлами размером больше чем 32 кбайта. MAX v3.00.
A: Это баг Максимуса v3.00.  Надо проапгрейдить до версии 3.01 и все  будет
   ок.

- 24 -

Q: Пример отслеживания наличия ANSI на удаленном  терминале,  с  тем  чтобы
   корректно отображать Logo.bbs
A: (from German FAQ)
   В первую строку Logo.mec вставить: [mex]m\ansi

   // текст ANSI.MEX
   //
   #include <max.mh>
   int main() {
      if (id.local OR id.speed > 2400) {
         if(ansi_detect()) {
            usr.video:=VIDEO_ANSI;
         }
      }
      return 0;
   }

- 25 -

Q: Числовые типы языка MEX (краткий обзор)

Проблема: функция strtoi("65535") возвращает отрицательные значения! Глюк?
Нет, это не глюк, а вполне логичные действия MEX. Связаны они вот с чем:

Как известно, в МЕХ есть три числовых типа: char, int и long. Каждый из них
в свою очередь имеет два варианта:  signed  (со  знаком)  и  unsigned  (без
знака) Места же для этих переменных отводится всегда одинаково, несмотря на
их "знаковость". то есть:

unsigned char (8 бит ) может изменяться от 0 до 255,
unsigned int  (16 бит) - от 0 до 65535,
unsigned long (32 бит) - от 0 до 4294967296.

В знаковом варианте для знаков + и - отведен один  бит  (старший).  Поэтому
для самого  числа  остается  на  один  бит  меньше,  и  соответственно  оно
уменьшается вдвое, то есть:

signed char (1+7  бит) может изменяться от -128 до 127,
signed int  (1+15 бит) - от -23768 до 32767,
signed long (1+31 бит) - от -2147483648 до 2147483648.

например беззнаковое двоичное число 11111111 = 256
а знаковое 1 1111111 = -128, хотя выглядят единицы совершенно одинаково. ;)
(напомню, что 1 соответствует "-" а 0 - "+")

функция int strtoi(string); осуществляет преобразование строки в число типа
int, причем _знаковое_, так как в стандарте mex отсутствие знакового префикса
перед числовым типом подразумевает, что тип будет в _знаковом_ варианте!
Таким образом, мы получаем в нашем примере:

int strtoi("65535") == | 65535 | ==  |  11111111  11111111  |  то  есть  на
первом слева месте 1! А это   - ЗНАК! следовательно на выходе функция даст

-32768!!! то есть отрицательное число, хотя строка описывает положительное.

Вот собственно и все. Пожалуйста не забывайте про это свойство MEX!

- 26 -

Q: Как в Mex'е заставить ожидать нажатия на enter ? Или на другую конкретную
   клавишу?
A: 1 способ (от Бэйсика ;) , by Nikolay Karnauh 2:5064/28 )

Loop_1: Ch := getch();
        if (Ch <> (char)13) goto Loop_1;

В данном случае цифра 13 как раз соответствует коду CR (или Enter), если вы
хотите проверять какую нибудь другую клавишу, то  соответственно  поместите
13 ее код.

Способ #2 (от Паскаля) Вообще говоря, в структурных языках применение меток
и операторов goto  является  плохим  стилем,  так  как  нарушает  структуру
программы.  Поэтому если вы - (o01 pR0gr/-\mMer, то  используйте  следующую
строку:

while (getch()<>13) ;

- 27 -

Q: Остроумный  пример  динамического  выбора  и  запуска  MEX  на   основе
   информации, полученной в MEX (фактически это почти MEX из MEX ;)
A: (идея Kirill K. 2:5063/53, комментарии мои ;)

=== test1.mec ===
[mex]m\rndmec
[link]misc\test2.bbs
=== EOF test1.mec ===

=== rndmec.mex ===
#define RNDMEX 5            // Количество "дочерних", вызываемых MEX'ов
#define MYMEX "M\\cursor"   // А это перфикс MEX'ов
#include <max.mh>
#include <rand.mh>
#include <intpad.mh>

void main() {
  int: which,f;

  f:=open("\\MECC\\test2.bbs",IOPEN_CREATE | IOPEN_WRITE);
  if (f<0) return;

  srand(time());
// выбираем (случайно) часть имени файла
  which:=(rand()%RNDMEX)+1;
// этой строкой формируется файл test2.bbs, который содержит строку
// с прописанным дочерним MEX'ом
  writeln(f,"/x17/x6E"+MYMEX+intpadleft(which, 2, '0'));
}
=== EOF rndmec.mex ===

(*) С помощью этой конструкции можно разумеется вызывать не только MEX,  но
и MECCA, или любой внешний файл (*.bat или *.exe).

Основное достоинство  в  том,  что  имя  вызываемой  программы  формируется
динамически в процессе работы этого "менеджера".

- 28 -

Q: Как правильно употребить INPUT_DEFAULT?
A: (Sergey Korowkin 2:5031/27)
Следует воспользоваться специальной зарезервированной переменной

string: input;

В которой Максимус будет искать содержимое введенной строки. Например:

 string:s;
 input:=usr.dataphone;
 input_str(usr.dataphone,INPUT_NLB_LINE|INPUT_DEFAULT,
           0, 18, "Модемный телефон:");

- 29 -

Q: Почему-то при выводе на экран из Мексов все через строчку  пишется.  =:(
   MAX/NT. В MAX/DOS все нормально.

A: (Andrew Kornilov 2:5045/46.24) Я немного подyмал, и нашел решение: в MEX
   программе  текстовой  файл  надо  открывать  как  бинарный,  то  есть  с
   добавлением  IOPEN_BINARY,  тогда  в  MaxNT  все  бyдет  нормально,  сам
   проверил и  избавился  от  этой  неприятности,  так  что  пожелание  для
   программеров на MEX- разделяйте, плиз, версии Макса, то есть например:

   #ifdef NT open(fd,IOPEN_READ|IOPEN_BINARY)
   #else  open(fd,IOPEN_READ)

   Как выяснилось, открытие файла как Binary избавляет и от других  нелепых
   ошибок, возникающих при работе с файлами для MAX/NT.

- 30 -

Q: Прикручивание АОН'а к Максу.
A: На примере IDC-АОН'а, и SF-Mail.

Фактически работа  программы  заключается  в  получении  и  анализе  номера
телефона юзера, уже определенного АОН'ом и  записанная  в  некоторый  файл,
обычно в лог мейлера.

Алгоритм работы:
1) Открыть лог мейлера;
2) Прочитать _последний_ записанный  туда  телефонный  номер  в  переменную
   string : phone;
3) Привести строку с  номером  к  некоему  стандартному  виду  и  отследить
   ситуацию, если номер не определился.
4) Сравнить полученный номер с номерами из badphone.bbs
5) Пропустить или не пропустить юзверя на BBS

Кусок примерного текста программы, обслуживающий лог SF-Mail'а для IDC-AON :

 fd:=open("c:\\bbs\\logs\\sf-mail.log",IOPEN_READ);
 seek(fd,-230,SEEK_END);
// открыли  файл лога _с конца_ и спозиционировались на 230 символов назад,
// то есть  заведомо  дальше  последнего  запомненного  номера  телефона  и
// заведомо  ближе  предпоследнего...  (подбирается  для  каждого   мейлера
// экспериментально или расчитывается).
 s:=""; log("LStartPhoneSel");
 while (strfind(s,"CALLER")=0) readln(fd,s);
// Ищем в логе мейлера строку с подстрокой "CALLER", для IDC это будет
// строка "CALLER`S NUMBER +2ABCDEF1", либо "CALLER`S NUBER ?"
 phone:=substr(s,strfind(s,"CALLER")+17,9);
 close(fd);
 log("LPhone:"+phone);
// Швырнули в MAX.LOG полученный номер телефона (для контроля)
 if ((phone[1]='?') or (phone[2]=' ')) return 2;
// Если номер неопределен, заканчиваем работу.
 phone:=substr(phone,3,6);
 log("LPhoneSel:"+phone);
// Швырнули  в  MAX.LOG  отселектированные  значащие  цифры  номера,    без
// плюсиков и категории абонента, то есть в виде ABCDEF (для 5080 :)
 fd:=open("c:\\bbs\\max\\badphone.bbs",IOPEN_READ);     while
 (readln(fd,s)>0) if (s=phone) {
    userremove(usr);
    log("!Phone found in BLACKLOG:"+phone);
    display_file("Misc\\BlackLog",nonstop);
 }
 close(fd);
// Пощупали телефон на предмет нахождения в черном списке
 if (strfind(usr.xkeys,"T")<>0) {
    log("LLaw User've came. First cycle of protection not activated!");
    return 60;
 }
// Пропустили, если юзер благонадежен и указал правильный номер
 userfindopen("","",tu);
 while(userfindnext(tu)=TRUE)
   if ((tu.phone=phone) and (usr.name<>tu.name))
      display_file("Misc\\DPhone",nonstop);

 if (phone<>usr.phone) {
    log("!Phone Unstable:"+usr.phone);
    display_file("Misc\\BadPhone",nonstop);
    input_str(usr.phone,INPUT_WORD,0,6,"Телефон (6 цифр без дефисов) :");
    if (phone<>usr.phone) {
       log("!Phone Unstable after input:"+usr.phone);
       if (strfind(usr.xkeys,"V")<>0) {
         fd:=open("c:\\bbs\\max\\badphone.bbs",IOPEN_WRITE | IOPEN_APPEND);
         writeln(fd,phone+"\n");
         close(fd);
         usr.priv:=0;
         display_file("Misc\\BadUser",nonstop);
         return 1;
       }
       if (strfind(usr.xkeys,"U")<>0) usr.xkeys:=usr.xkeys+"V";
       else usr.xkeys:=usr.xkeys+"U";
       return 1;
    };
  log("!Phone changed to correct after input:"+usr.phone);
// Здесь если юзер попался хитрый, ему было дадено  три  попытки  исправить
// ситуацию и ввести нормальный номер... это кстати полезно  еще  и  если
// не дай бог был просто сбой в работе АОН'а
 } else usr.xkeys:=usr.xkeys+"T"; return 0; }
// если все ок, присваиваем юзеру ключик "благонадежности"

============================================================================
 Уважаемые коллеги!  Если  в  обнаружили  в  данном  документе  ошибку  или
 неточные, устаревшие сведения; если вам  хочется  сделать  добавление  или
 исправление в тексте FAQа, пожалуйста напишите об этом мне - нетмейлом на
                            2:5080/78.6@FidoNet

Большое спасибо всем, приславшим поправки, дополнения и советы.
На данный момент это:
Mike Petrov 2:5020/1413
Fedor Lizunkov 2:5020/960
Kirill K. 2:5063/53

Отдельное спасибо:
George Jot'у (2:5080/52.56) за его советы при настройке МАКСа

Lanius Corp. за прекрасную BBS - MAXIMUS.


                     Автор этого текста - Alex Shiloff, 2:5080/152@FidoNet

Вернуться в раздел "Программы для BBS" - Обсудить эту статью на Форуме
Главная - Поиск по сайту - О проекте - Форум - Обратная связь

© faqs.org.ru