Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Помогите доработать сложный батник (http://forum.oszone.net/showthread.php?t=295528)

Kinkie Pinkie 14-02-2015 15:47 2471268

Помогите доработать сложный батник
 
Доброго времени суток. Есть один большой и сложный скрипт, который уже давно работает и приносит пользу (помогает модерировать один специфический форум), но недавно я столкнулся с тем, что туда нужно добавить функционал. У самого не вышло после нескольких попыток разобраться (я плохо знаю cmd), а тот человек, что его писал, уже несколько месяцев как пропал.
Что нужно сделать: У скрипта есть два вида уведомлений в джаббер, о жалобах пользователей и о айпишниках, на которые стоит обратить внимание (по региону или другим признакам, может быть нарушитель с прокси). Вот меня интересует как раз изменение уведомления о новых жалобах, туда нужно добавить такую же информацию о айпишнике отправившего жалобу (страна, провайдер) как и в уведомлении о прокси.
Может поможет кто-нибудь доработать? Или хотя бы поясните как оно работает, чтобы я сам ещё раз попробовал доделать.

Код:

@Echo Off
SetLocal EnableDelayedExpansion
Set Path=%Path%;%~dp0bin;%~dp0lib
Title PonyGuard v1.2 b140722
:: Applejack, Wishmaster, ~anonpony 2013-2014
:: submodules: proxymond v1.04, reportmond v1.06
:: required: grep, wget, jq, whois, subnetmask and it's dependencies
:: codepage: UTF-8 w/o BOM

:: Немного констант, которые нет смысла выводить в конфиг.
Set Prefix=https://
Set Domain=2ch.hk
Set Chan=%Prefix%%Domain%
Set Engine=%Chan%/makaba/makaba.fcgi

:: Инициализируем модули в нескольких процессах с выводом в общее окно
If "%1"=="" (
        Echo.
        :: Лого, yay!
        Call aj_logo 3

        Echo [SYSTEM]        Load configuration
        :: Читаем настройки
        For /F "usebackq eol=# tokens=1,2* delims==" %%A In ("config.txt") Do (Set %%A=%%B)
        For /F "tokens=1-3 delims=:@" %%A In ("!JID!") Do (
                Set "j_name=%%~A"
                Set "j_server=%%~B"
                Set "j_pass=%%~C"
        )

        Echo [SYSTEM]        Logging in
        :: Логинимся и получаем хэш пароля. Для совместимости со старыми форками движка оставлена авторизация через code
        For /F "delims=" %%A In ('wget "%Engine%?task=login&json=1&password=!ModPass!" -O- -q --no-check-certificate --user-agent="PonyGuard" 2^>nul^|jq ".Code"') Do (Set "Hash=%%~A")
        If Not Defined Hash (Echo [SYSTEM]        ERROR: Authorization failed. YOU SHALL NOT PASS&&Pause>nul&&Exit /B 3)
        Echo .%Domain%        TRUE        /        FALSE        1581499424        makabadmin        !Hash!>"data\cookie.txt"

        Echo [SYSTEM]        Initialization...
        Set /A TShift=Timeout/3
        Start "" /D "%~dp0" /B "%~nx0" ProxyService
        Ping -n !TShift! 127.0.0.1>nul
        Start "" /D "%~dp0" /B "%~nx0" ReportService
        rem Ping -n !TShift! 127.0.0.1>nul
        rem Start "" /D "%~dp0" /B "%~nx0" TorBlockerService
) Else GoTo :%~1
Exit /B

::======[ Модули ]==========================
:: Уведомления о прокси
:ProxyService
Echo [Proxy]        [%Time%] Checking...
Echo.>"%~dp0data\suspreport.tmp"
:: Получаем айпишники постеров
Set "IP[]="
For /L %%A In (0,1,%Pages%) Do (
        For /F "tokens=2 delims=,: " %%C In ('wget "%Engine%?task=posts_panel&json=1&board=%Board%&page=%%A&code=%Hash%" --load-cookies data\cookie.txt -O- -q --no-check-certificate --user-agent="PonyGuard (proxy detect module)" 2^>nul^|jq "."^|grep -E "\"ip\": "^|uniqline') Do (
                Set IP[]=%%~C,!IP[]!
        )
)
:: Обрабатываем данные
For %%A In (!IP[]!) Do (
        Set IPstatus=whitelisted
        Find "%%A" "%~dp0data\ipcache.dat">nul||(
                Call :Whois %%A
                Call :Whitelist IPstatus
                Echo [Proxy]        !$W_ip_address! !$W_country! !IPstatus!
                Echo %%A>>"%~dp0data\ipcache.dat"
        )
        If Not "!IPstatus!"=="whitelisted" (
                Call :FirstMessage !$W_ip_address! MsgLink
                Call :MakeMessageIP
        )
)
:: Отсылаем сформированное сообщение, если оно не пусто, и уходим на следующую итерацию
Find "%Chan%" "%~dp0data\suspreport.tmp">nul&&Call :SendNotify Proxy suspreport
Ping -n %Timeout% 127.0.0.1>nul
GoTo ProxyService

:: Временный бан выходных нод тора
:TorBlockerService
rem Вынесено в планировщик //Wishmaster
exit /B 0

:: Уведомления о новых жалобах
:ReportService
Echo [Reports]        [%Time%] Checking...
Echo.>"%~dp0data\message.tmp"
:: Получаем JSON с жалобами и разбираем его структуру
For /F "tokens=*" %%A In ('wget "%Engine%?task=reports&json=1&code=%Hash%" --load-cookies data\cookie.txt -O- -q --no-check-certificate --user-agent="PonyGuard (reports module)" 2^>nul^|jq ".reports[]"') Do (
        Set "Data=%%A"
        If "!Block!"=="true" If "!Data:~,1!"=="{" (
                Set Block=false
                If "!$report_board!"=="%Board%" Call :MakeMessageReport
::                Очищаем обработанную жалобу из памяти
                For /F "tokens=1 delims==" %%B In ('Set $report_') Do (Set %%B=)
        )
        If "!Data:~,1!"=="{" (
                Set Block=true
        )
::        Запись жалобы в память
        If "!Data:~-1!"=="," Set Data=!Data:~,-1!
        If Not "!Data:~,1!"=="{" If Not "!Data:~,1!"=="}" If "!Block!"=="true" (
                For /F "tokens=1,* delims=: " %%B In ("!Data!") Do (Set "$report_%%~B=%%~C")
        )
)
:: Отсылаем сформированное сообщение, если оно не пусто, и уходим на следующую итерацию
Find "%Chan%" "%~dp0data\message.tmp">nul&&Call :SendNotify Reports message
Ping -n %Timeout% 127.0.0.1>nul
GoTo ReportService

:: ======[ Функции ]===================
:: Формировка из найденных жалоб сообщения для последующей отправки
:MakeMessageReport
Set LastNum=0
Set Links[]=
:: Проверяем на то, обрабатывали ли мы эту жалобу раньше
For /F "usebackq delims=" %%A In ("%~dp0data\lastreport.dat") Do (Set "LastNum=%%A")
If !LastNum! GEQ !$report_num! Exit /B
:: Если в жалобе есть ссылки на конкретные номера постов, выделяем их и пишем в массив
For /F "delims=" %%A In ('Echo !$report_comment!^|grep -Eo "2[0-9]{6}"') Do (If %%~A GEQ !$report_thread! Set "Links[]=!Links[]!,%%~A")
        Echo !$report_comment!>>"%~dp0data\message.tmp"
        Echo IP: !$report_ip!>>"%~dp0data\message.tmp"
::        Формируем ссылку на тред или ссылки на конкретные посты
        If Defined Links[] (
                Echo Найдены ссылки на посты:>>"%~dp0data\message.tmp"
                For %%A In (!Links[]!) Do (
                        If Not "%%A"=="!$report_thread!" (
                                Echo %Chan%/!$report_board!/res/!$report_thread!.html#%%A>>"%~dp0data\message.tmp"
                        )
                )       
        ) Else (
                Echo %Chan%/!$report_board!/res/!$report_thread!.html>>"%~dp0data\message.tmp"
        )
        Echo _________________________>>"%~dp0data\message.tmp"
Echo !$report_num!>"%~dp0data\lastreport.dat"
Exit /B

:: Формировка из найденных IP сообщения для последующей отправки
:MakeMessageIP
Echo Обнаружен подозрительный IP: !$W_ip_address!>>"%~dp0data\suspreport.tmp"
Echo        Страна: !$W_country! (!$W_network_name!)>>"%~dp0data\suspreport.tmp"
Echo        Маска подсети: !$W_from_ip!\!$W_netmask! (!$W_hosts! машин в сети)>>"%~dp0data\suspreport.tmp"
Echo Whois: http://188.40.78.19/whois/whoisinfo.bat?ip=!$W_ip_address!>>"%~dp0data\suspreport.tmp"
Echo Сообщение: !MsgLink!>>"%~dp0data\suspreport.tmp"
Echo.>>"%~dp0data\suspreport.tmp"
Exit /B

:Whitelist (OUT:var_name)
Echo %Whitelist%|Find "[!$W_country_id!]">nul&&(Set "%~1=whitelisted")||(Set "%~1=suspicious")
Exit /B

:FirstMessage (ip, OUT:var_name)
ping -n 2 127.0.0.1>nul
Set "%~2=undefined"
For /F "tokens=1,2 delims=,: " %%A In ('wget "%Engine%?task=posts_panel&json=1&board=%Board%&action=sip&ip=%~1&code=%Hash%" --load-cookies data\cookie.txt -O- -q --no-check-certificate --user-agent="PonyGuard (proxy detect module)" 2^>nul^|jq ".posts[0]"') Do (
        If "%%~A"=="parent" Set parent=%%~B
        If "%%~A"=="num" Set num=%%~B
)
If "!parent!"=="0" (
        Set "%~2=%Chan%/%Board%/res/!num!.html"
) Else (
        Set "%~2=%Chan%/%Board%/res/!parent!.html#!num!"
)
Exit /B

::======[ Общие функции ]===================
:Whois (ip)
:: Вывод идёт в переменные, начинающиеся с префикса $W_
:: Список возможных значений: $W_whois_source, $W_ip_address, $W_country, $W_country_id, $W_network_name, $W_owner_name
:: $W_from_ip, $W_to_ip, $W_netmask, $W_hosts, $W_allocated, $W_contact_name, $W_address, $W_email, $W_abuse_email, $W_phone, $W_fax
For /F "tokens=1 delims==" %%A In ('Set $W_ 2^>nul') Do (Set "%%A=")
For /F "tokens=1,* delims=:" %%A In ('whois %~1') Do (
        If Not "%%~B"=="" (
                Set "Key=%%~A"
                Call :StringToLowerCase Key
                :: Чистим и экранируем данные
                For /F "tokens=*" %%C In ("%%B") Do (
                        Set "Value=%%C" && If Defined Value Set "Value=!Value:\=\\!"
                        If Defined Value Set "Value=!Value:(=!" && If Defined Value Set "Value=!Value:)=!"
                        If Defined Value Set "Value=!Value:<=!" && If Defined Value Set "Value=!Value:>=!"
                        If Defined Value Set "Value=!Value:&=!" && If Defined Value Set Value=!Value:"='!
                )
                Set "$W_!Key: =_!=!Value!"
        )
)
Echo !$W_country!|Find ", Republic Of">nul&&Set "$W_country=!$W_country:, Republic Of=!"
Echo !$W_country!|Find "USA">nul&&Set "$W_country=United States"
For /F "tokens=2 delims=:" %%A In ('Find "!$W_country!" "%~dp0data\country.dat"^|^|Echo unknown') Do (Set "$W_country_id=%%A")
For /F %%A In ('netmask !$W_from_ip! !$W_to_ip!') Do (Set "$W_netmask=%%A")
If Defined $W_netmask For /F "tokens=1-4 delims=." %%C In ("!$W_netmask!") Do (
        Set /A $W_hosts=^(256-%%C^)*^(256-%%D^)*^(256-%%E^)*^(256-%%F^)
)
If Not Defined $W_ip_address (Set "$W_ip_address=null" && Exit /B 1)
Exit /B

:StringToLowerCase (var_name)
Set "strData=!%~1!"
For %%A In (A:a B:b C:c D:d E:e F:f G:g H:h I:i J:j K:k L:l M:m N:n O:o P:p Q:q R:r S:s T:t U:u V:v W:w X:x Y:y Z:z) Do (
        For /F "tokens=1,2 delims=:" %%B In ("%%A") Do (Set "strData=!strData:%%B=%%C!")
)
Set "%~1=!strData!"
Exit /B

:: Рассылка jabber-оповещений на все адреса, перечисленные в конфиге
:SendNotify (title,file)
Echo [%~1]        [%Time%] Sending report
For %%A In (%NotificationList%) Do (
        Echo                ^>^> %%A
        sendxmpp -r "pony" -u "%j_name%" -j "%j_server%" -p "%j_pass%" %%A <"%~dp0data\%~2.tmp"
)
Exit /B


Kinkie Pinkie 14-02-2015 17:42 2471312

Когда 121 строку меняю с
Код:

Echo IP: !$report_ip!>>"%~dp0data\message.tmp"
на
Код:

Echo IP: !$report_ip! !$W_country! (!$W_network_name!)>>"%~dp0data\message.tmp"
по аналогии с тем другим уведомлением (откуда и скопипастил), то или не выводит вообще, или выводит неправильные.

Georgio 14-02-2015 18:06 2471333

Kinkie Pinkie, поскольку блок с этой строкой у Вас заключён в скобки, то закрывающую скобку надо экранировать:
Код:

Echo IP: !$report_ip! !$W_country! (!$W_network_name!^)>>"%~dp0data\message.tmp"
.

Kinkie Pinkie 14-02-2015 18:23 2471338

Georgio, если есть вложенные скобки, то нужно экранировать не обе, а только закрывающую?

Кажется, разобрался. На другом форуме подсказали, что перед той строчкой, которую я добавил, нужно ещё и "Call :Whois !$report_ip!". Теперь всё работает, всем спасибо.

Georgio 14-02-2015 18:40 2471343

Kinkie Pinkie, по всем канонам надо экранировать обе скобки, но я ни разу не сталкивался с тем, что неэкранированная открывающая скобка на что-либо влияла. Презумпция!..


Время: 04:53.

Время: 04:53.
© OSzone.net 2001-