Парсинг конфига

xaker1

Новичок
Парсинг конфига

Здравствуйте уважаемые php программисты. Возникла необходимость в парсинге конфига.
Сейчас удалось вывести конфиг в массив, в итоге получился массив типа:
PHP:
Array
(
    [0] => Option NoMysqlQuota
Option Agree
....

Preset "Example package" 
    [1] => 
	Owner root
....
	MySQLConn 0

    [2] => 

path httpd  /usr/sbin/apache2

    [3] => "HTTP" 
    [4] => 
Process apache2
Start /etc/init.d/apache2 start
Stop /etc/init.d/apache2 stop
ConfName apache2
Type www
Monitored NO

    [5] => 

    [6] => "SMTP" 
    [7] => 
Process exim4
Start /etc/init.d/exim4 start
Stop /etc/init.d/exim4 stop
ConfName exim4
Type smtp
Monitored NO

    [8] => 

    [9] => "POP3" 
    [10] => 
Process dovecot
Start /etc/init.d/dovecot start
Stop /etc/init.d/dovecot stop
ConfName dovecot
Type pop3
Monitored NO

    [11] => 

    [12] => "FTP" 
    [13] => 
Process proftpd
Start /etc/init.d/proftpd start
Stop /etc/init.d/proftpd stop
ConfName proftpd
Type ftp
Monitored NO

    [14] => 

    [15] => "DNS" 
    [16] => 
Process named
Start /etc/init.d/bind9 start
Stop /etc/init.d/bind9 stop
ConfName bind9
Type dns
Monitored NO

    [17] => 

    [18] => "MySQL" 
    [19] => 
Process mysqld
Start /etc/init.d/mysql start
Stop /etc/init.d/mysql stop
ConfName mysql
Type mysql
Monitored NO
Ip /var/run/mysqld/mysqld.sock

    [20] => 
ApacheUid  33
ApacheGid  33
Меня интересуют блоки
PHP:
Process apache2
Start /etc/init.d/apache2 start
Stop /etc/init.d/apache2 stop
ConfName apache2
Type www
Monitored NO
в частности параметры Start и Stop в блоке, где Type = www. Подскажите, как можно выловить эти параметры, с условием что таких блоков (type www) в конфиге всего один.
Если не сложно, дайте код. Думаю, что здесь без регулярок не обойтись, а я с ними не очень дружу.
 

soines

Новичок
Если не сложно - дай денег за это :)
А вообще если хочешь чтобы тебе помогли, попробуй сначала сам.. Если не получится, то тогда уже выкладывай здесь что написал и тебе тогда подскажут.
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Никто так как ты конфиги не хранит. Либо хранят в нормально сформированном массиве, хотя бы с еще одним уровнем вложенности, либо в файле ini. Либо в константах. Либо в БД. Все зависит от задачи и ситуации. Пока что это изврат какой-то.
 

xaker1

Новичок
Автор оригинала: soines
Если не сложно - дай денег за это :)
А вообще если хочешь чтобы тебе помогли, попробуй сначала сам.. Если не получится, то тогда уже выкладывай здесь что написал и тебе тогда подскажут.
У меня получился такой код, но он почему-то не работает
PHP:
foreach($conf as $value)
{       
$value2 = explode("\n", $value);
foreach($value2 as $str_array)
{
$str_array = explode(" ", preg_replace("/\r|\n{2,}/", "", trim($str_array)), 2);
switch($value[0])
{
case "Process":
$process = $value[1];
break;

case "Start":
$start = $value[1];
break;

case "Stop":
$stop = $value[1];
break;

case "Type":
if($value[1]=="www") $type = $value[1];
break;

case "Monitored":
$monitored = $value[1];
break;

case "Ip":
$ip = $value[1];
break;
default:
break(2);
}
}
if($type = "www") break;
$type = "";
}
$apachectl_start = $start; $apachectl_stop = $stop;
Автор оригинала: c0dex Никто так как ты конфиги не хранит. Либо хранят в нормально сформированном массиве, хотя бы с еще одним уровнем вложенности, либо в файле ini. Либо в константах. Либо в БД. Все зависит от задачи и ситуации. Пока что это изврат какой-то.
Храню не я. Нужно из конфига одного ПО выдернуть нужные параметры.
 

xaker1

Новичок
О основном
имя_переменной значение (иногда значений у одной переменной несколько, все через запятую)

PHP:
Option Agree
Option ForcePhpFastCgi
Option AllowIpV6
path db4  db4_dump185 -p /usr/local/etc/sasldb2.db
extaction myadmin /myadmin/
path DefaultHomeDir  /home
path httpd.conf  /usr/local/etc/apache22/httpd.conf
path apachectl  /usr/local/sbin/apachectl start
но так же есть шаблоны, в конфиге выглядят как:

PHP:
Preset "имя_переменной" {
переменная значение
переменная2 значение2
переменная3 значение3
переменная4 значение4
и т.д.
}
и шаблоны сервисов:


PHP:
Service "HTTP" {
	Process httpd
	Start /usr/local/etc/rc.d/apache22 start
	Stop /usr/local/etc/rc.d/apache22 stop
	ConfName apache22
	Type www
	Monitored YES
	Ip 192.168.100.1 8080
}
Нужно в конфиге найти шаблон сервиса (Service "name" { ... }) у которого Type www (условно считать что такой шаблон один), и достать оттуда значения Start и Stop.
 

john.brown

просто кулибин
xaker1
т.е. как будет называться сервис, у которого тип "www", ты заранее не знаеш?
Тогда перебираеш файл построчно, ищеш строку, которая соответствует "Service чего то там {", и от туда до закрывающего } разбираеш строки на ключ=>значение. Т.к. тебя интересует 3 конкретных ключа, то можно регуляркой, ну, или explode - дело вкуса. Ну и смотриш тип - если www, то break, нет - так продолжаем....
 

xaker1

Новичок
Имя сервиса, которое к ковычках, мне неизвестно. Т.к. его можно в любой момент изменить, а вот то что type будет www, известно на 100%.
Мне удалось распарсить конфиг до состояния что указанно выше (в 1-м сообщении).

После этого я пытаюсь обработать каждый блок и выйти из цикла, если type www будет найдено. Код приведен в 4-м сообщении.

Но на выходе переменные $apachectl_start и $apachectl_stop пусты. В чем ошибка?

p.s. крайне скудные возможности трассировки кода, поэтому прошу вас помочь.
 

john.brown

просто кулибин
Да выкинь ты весь тот ужас. Не нужно тебе весь конфиг в массив запихивать (имею в виду распарсивать). Как делать я тебе написал, осталось в код перевести :)

Для дебага такого сложного кода в полне хватает возможностей var_dump() ;)
 

xaker1

Новичок
var_dump знаю, но привык к print_r и прямого вывода нету у скрипта, т.е. все что он выводит нельзя посмотреть. Только буферизация + запись в файл.

Вопрос возник, если использовать explode("Service ", $conf) то все что после Service будет обязательно в массиве под номером 1? даже если Service в самом начале конфига (а вдруг). Что-то сейчас не могу сообразить, а протестировать не могу, т.к. php под рукой ничего нет.
 

john.brown

просто кулибин
Зачем тебе explode("Service ", $conf)? Там, по хорошему, explode() вообще не нужно - 4 регулярки делает всю работу. А файл считывай в массив функцией file(). Потом построчный перебор...
 

xaker1

Новичок
В первом сообщении написал же что с регулярками не дружу :(
Если вырвать в массив только то что между Service "" {...} то дальше я достану нужные данные.
 

Krishna

Продался Java
А с каких пор тут стали кулхацкерам помогать домогаться до чужих серверов? :)
 

xaker1

Новичок
john.brown, огромное спасибо за помощь, уже получилось.
Принцип за основу взял подсказанный вами. Т.Е. получаем в массив конфиг, и начинаем обрабатывать. Каждую строчку делим по пробелу на 2-х элементный массив.
Потом смотрим что у нас в 0 параметре массива, если Service - ставим метку, если метка существует, то начинаем во временный массив писать данные. (опять же с делением по пробелу). Как только добираемся до строки с закрывающей фигурной скобкой, пишем все полученные данные в основной массив с данными сервисов.

В итоге получаем двумерный массив с нужными мне данными :).

Krishna, во первых читайте Википедию, там есть целая статья о хакерах, и том кто же они на самом деле. Во вторых, у меня есть собственный сервер и я разрабатываю плагины к панели управления. Чужые сервера мне не нужны - и так имею доступ (легальный) на несколько "чужых" серверов.
 

fixxxer

К.О.
Партнер клуба
че до человека докопались. очевидно что панельку пишет.

xaker1, если говорить в целом о панели, которая умеет парсить разные форматы конфигов, я бы задумался о написании более менее универсального парсера-конечного автомата, которому в итоге дается на вход нужная матрица переходов, а на выходе получаем вложенный массив с распарсенными конструкциями. (второй этап - валидация, если оно надо).

вложенные конструкции типа <VirtualHost><Location><FilesMatch> ты регулярками фиг пропарсишь.

почитай теорию короче :)

у практически всех написанных левой пяткой панелей (включая лидеров рынка ;)) есть огромный недостаток - если отредактировать конфиг того же апача вручную, то в лучшем случае оно эти правки угрогает, в худшем все встанет раком. зачем делать такое же дерьмо? =)
 

Активист

Активист
Команда форума
fixxxer
Вообще, ТС парсит конфиг ISPSystem'cких панелей, но нахрена их парсить - понимаю.
 

xaker1

Новичок
Активист, верно. Пишу плагин для панели, а перезагружать апач нужно после установки плагина. Поскольку сама панель однопоточная, вот и приходится парсить конфиг.

fixxxer, мне нужно только перезагрузить апач. Да и путь к конфигу апача найти намного легче в кофиге ispmgr, чем как перезагрузить этот самый апач.

p.s. ISPmanager не трогает все что сделано в конифге апача вручную, за исключением некоторых директив при изменении www домена.
 
Сверху