• Арматура А1 д12 ГОСТ5781-82
  • ОСБ 9*2440*1220 Румыния (Кроношпан) 16 кг (95л)
  •  Песок 40кг (строительный)
  • Доска обрезная 25х100х4
  •  Цемент Себряковский М-500
  • ТеплоКНАУФ ДОМ и TS 040 плита
  • Цементно стружечная плита
  • Кирпич М-100
  • Лист оцинкованый
  • Имитация бруса
  • Гипсокартон
  • Щебень

<?php

/**
 * Программное обеспечение AddSite защищено законами и международными
 * соглашениями об авторских правах, а также другими законами и договорами,
 * регулирующими отношения авторского права.
 * Всеми авторскими правами на ПО AddSite владеет – ООО "Инновационные Системы"
 * на основании свидетельства об официальной регистрации
 * программы для ЭВМ №2007612900 от 5 июля 2007 г.
 * 2003-2010 - ООО "Инновационные Системы"
 *
 * © Все права и торговые марки защищены
 *
 *
 * Данный скрипт предназначен для обхода верификации установленной ссылки на каталог сайтов.
 * Принцип действия:
 *   - Для скрипта создают базу кнопок, которые нужно показывать каталогам, при
 *     этом указывают IP-адреса роботов, которые будут проверять наличие ссылок.
 *   - Каждой кнопке присваивается ID, а каталогу в качестве обратной ссылки
 *     дается ссылка вида http://www.example.com/links.php?act=view&id=[ID кнопки]
 *   - Когда робот каталога заходит по указанную ему страницу, проверяется его IP-адрес.
 *     Если он совпадает с тем, что указали при добавлении кнопки, то код показывается,
 *     иначе нет.
 *   - Таким образом, даже если каталог добавит указанную ему обратную ссылку в
 *     поисковые системы, код обратной ссылки роботу показан не будет.
 *
 * Установка:
 *   - Для установки скрипта нужно воспользоваться FTP-клиентом (FAR, Total Commander)
 *     и закачать его в любую директорию, доступную по HTTP.
 *   - Скрипту нужно будет создать директорию для хранения логов, для этого нужно либо
 *     установить права на запись в директории, в которой находится скрипт, либо
 *     создать директорию для хранения логов самому и установить права на запись в ней.
 *     - По умолчанию скрипт будет пытаться создать директорию со своим именем,
 *       только без расширения ".php".
 *   - Если у Вас уже создана данная директория, это имя можно поменять, отредактировав
 *     переменную $work_dir чуть ниже.
 *     - Пароль доступа к скрипту хранится в переменной $access_password. Не забудьте указать новый
 *     - пароль в программе AddSite.
 *     - Также можно задать шаблон HTML-страницы, которая будет отдаваться роботам каталогов.
 *       Это можно сделать 2-мя путями, задать в переменной $template_file путь к файлу-шаблону
 *       страницы или указать код прямо в скрипте в переменной $template, для этого нужно
 *       вставить ваш код между строками "$template=<<<TEMPLATE" и "TEMPLATE;".
 *       ОБЯЗАТЕЛЬНО! Нужно в html-код вставить ключевое слово %%code%%, вместо которого
 *       будут выводиться коды кнопок для роботов.
 *
 * Пример настройки:
 *   - Когда Вы подключились по FTP, скорее всего будет видна директория public_html.
 *   - Перейдя в нее, Вы увидите список файлов Вашего сайта.
 *   - Нужно либо создать отдельную директорию, либо скопировать файл links.php
 *     в корень сайта (в большинстве FTP-клиентов для создания директории
 *     используется клавиша F7).
 *   - Лучше, если Вы создадите отдельную директорию (например, backlinks). И назначите
 *     ей права на запись. В FAR нужно выбрать директорию, нажать CTRL+A и отметить
 *     все пункты. В Total Commander (и других) можно набрать команду "chmod 777 backlinks"
 *     в командной строке (без кавычек).
 *   - Если Вы будете закачивать файл в корень сайта, то нужно создать директорию links
 *     и установить ей права на запись. Если директория links уже существует, то найдите
 *     ниже строку
 *         $work_dir = '';
 *     и укажите любое имя рабочей директори, например
 *      $work_dir = 'backlinks';
 */


# Имя директории, в которой будет храниться служебная информация.
# Если оставить пустой, создастся каталог с именем данного файла.
$work_dir = '';

# Пароль доступа к скрипту
$access_password = '123456';

# Путь к файлу-шаблону HTML-страницы, отдаваемой роботам
$template_file = '';

# Шаблон веб-страницы
$template=<<<TEMPLATE
<html>
<head>
    <title>Наши партнеры</title>
</head>
<body>
  <div>Наши партнеры</div>
  <div>%%code%%</div>
</body>
</html>
TEMPLATE;

error_reporting(0);

header('Content-type: text/html; charset=utf-8');

DEFINE("ACCESS_PASSWORD", $access_password);

if($template_file && is_file($template_file))
    $template = join('', file($template_file));

if($work_dir)
    DEFINE("WORK_DIR", dirname(__FILE__) . DIRECTORY_SEPARATOR . $work_dir . DIRECTORY_SEPARATOR);
else
    DEFINE("WORK_DIR", dirname(__FILE__) . DIRECTORY_SEPARATOR . basename(__FILE__, '.php') . DIRECTORY_SEPARATOR);

# Файл со статистикой посещений
DEFINE("LOG_FILE", WORK_DIR . "log.db");

$xml_header=<<<HEADER
<?xml version="1.0" encoding="utf-8"?>
<root>

HEADER;

$log_xml_item=<<<ITEM
<record>
    <referer>%s</referer>
    <id>%s</id>
    <useragent>%s</useragent>
    <ip>%s</ip>
    <time>%s</time>
    <status>%s</status>
</record>

ITEM;

$buttons_xml_item=<<<ITEM
<record>
    <id>%s</id>
    <domain>%s</domain>
    <code>%s</code>
    <iplist>%s</iplist>
</record>

ITEM;

$xml_footer=<<<FOOTER

</root>
FOOTER;

if(@$_REQUEST['password'] != ACCESS_PASSWORD && $_REQUEST['act'] != 'view')
    print_error("Неверный пароль");


/**
 * Класс для работы с базой логов
 *
 * @author PromoSoft
 */
class MyDB
{
    var $fid = false;
    var $mode = "write";
    
    /**
     * Конструктор
     *
     * @param string $file - имя файла
     * @param string $mode - режим открытия файла (чтение или запись)
     */
    function __construct($file, $mode="write")
    {
        $this->mode = $mode;
        if(!$this->open($file))
            print_error("Не могу открыть файл " . $file);
    }
    
    /**
     * Деструктор
     *
     */
    function __destruct()
    {
        if($this->mode == "write")
        {
            fflush($this->fid);
            flock($this->fid, LOCK_UN);
        }
        fclose($this->fid);        
    }
    
    /**
     * Метод открытия файла
     *
     * Если режим открытия "для записи", то на файл ставится блокировка.
     *
     * @param string $file - имя файла
     * @return bool - успешно или нет
     */
    function open($file)
    {
        $fmode = ($this->mode=="write") ? "a" : "r";
        if($this->fid = fopen($file, $fmode))
        {    
            if($this->mode=="write")
            {
                $try = 0;
                while (!flock($this->fid, LOCK_EX | LOCK_NB))
                {
                    $try++;
                     usleep(round(rand(0, 100)*1000));
                     if($try > 50) return false;
                }
            }else $this->rewind();
            return true;
        }else{
            return false;
        }
    }

    /**
     * Метод очистки базы
     *
     * @return void
     */
    function clear_all()
    {
        ftruncate($this->fid, 0);
    }
    
    /**
     * Метод получения следующей записи
     *
     * @return struct - запись из лога
     */
    function get()
    {
        if(!feof($this->fid))
        {
            return unserialize(base64_decode(fgets($this->fid)));
        }else
            return false;
    }
    
    /**
     * Перемотка указателя на первый элемент базы
     *
     * @return void
     */
    function rewind()
    {
        rewind($this->fid);
    }
    
    /**
     * Добавление элемента в конец базы
     *
     * @param struct $item - запись из лога
     * @return void
     */
    function add($item)
    {
        $data = base64_encode(serialize($item));
        fseek($this->fid, 0, SEEK_END);
        fwrite($this->fid, $data."\n");
    }

}

/**
 * Вывод ошибки и завершение работы скрипта
 *
 * @param string $error - текст ошибки
 */
function print_error($error)
{
    printf("error\n%s", $error);
    die();
}

/**
 * Функция поиска кнопки по ID
 *
 * @param string $id - ID кнопки
 * @return struct - параметры кнопки
 */
function get_button($id)
{
    if(!is_file(WORK_DIR . $id))
        return false;
    $button = unserialize(base64_decode(join('', file(WORK_DIR . $id))));
    return $button;
}

/**
 * Добавление кнопки
 *
 * @param string $id - ID кнопки
 * @param struct $content - параметры кнопки
 * @return bool - успешно или нет
 */
function write_button($id, $content)
{
    $f = fopen(WORK_DIR . $id, 'w');
    if(!$f)
        return false;
    fwrite($f, base64_encode(serialize($content)));
    fclose($f);
    return true;
}

/**
 * Добавление события в лог
 *
 * @param struct $item - параметры события
 * @return void
 */
function log_event($item)
{
    $item['type'] = 'event';
    $db = new MyDB(LOG_FILE, "write");
    $db->add($item);
    unset($db);
}

/**
 * Вывод страницы для роботов
 *
 * @param string $code - код html-кнопки
 * @return void
 */
function show_page($code)
{
    GLOBAL $template;
    echo str_replace('%%code%%', $code, $template);
}

/**
 * Проверка IP на корректность
 *
 * @param string $ip - IP адрес
 * @return bool - является ли $ip IP-адресом
 */
function is_ip($ip)
{
    return preg_match("~\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}~", $ip);
}

/**
 * Проверка на существование кнопки с данным ID
 *
 * @param string $id - ID кнопки
 * @return bool - существует или нет
 */
function check_id($id)
{
    if(preg_match("~(\d+)~", $id))
        return true;
    else
        print_error("Неверный ID кнопки");
}

/**
 * Получение списка IP-адресов для для домена
 *
 * @param string $domain - домен
 * @return array - список IP-адресов
 */
function get_host_by_name($domain)
{
    for($i=0;$i<5;$i++)
    {
        $ips = gethostbynamel($domain);
        if($ips)
            return $ips;
        usleep(round(rand(0, 100)*100));
    }
    return false;
}

/**
 * Генерация ID кнопки
 *
 * @return int
 */
function generate_id()
{
    return time() . rand(100, 999);
}

/**
 * Генерация диапазона IP-адресов
 *
 * @param string $ip - IP-адрес
 * @param int $range - количество IP-адресов
 * @return array
 */
function gen_ip_range($ip, $range)
{
    $u32 = ip2long($ip);
    $from = $u32 - $range;
    if($from < 0)
        $from = 0;
    $to = $u32 + $range;
    $result = array();
    for($i=$from;$i<=$to;$i++)
        $result[] = long2ip($i);
    return $result;
}

switch($_REQUEST['act'])
{
/******** Добавление новой кнопки ********/
    case "add":
        @$_POST['domain'] = trim(@$_POST['domain']);
        @$_POST['domain'] = str_replace('/', '', trim(@$_POST['domain']));
        if($_POST['ip'])
            $ip_list = explode("|", $_POST['ip']);
        else
            $ip_list = is_ip($_POST['domain']) ? array($_POST['domain']) : get_host_by_name($_POST['domain']);
        $item = array(
                'domain' => $_POST['domain'],
                'htmlcode' => $_POST['htmlcode'],
                'id' => generate_id(),
                'ip_list' => $ip_list
            );
        if(!$item['ip_list'])
        {
            die("error\nНевозможно получить IP-адрес домена");
        }
        
        if( write_button($item['id'], $item) )
        {
            if(@$_POST['form'])
                echo $_SERVER['SCRIPT_URI'] . '?act=view&id=' . ($_POST['id'] ? $_POST['id'] : $_POST['domain']);
            else
                echo $item['id'];
        } else {
            die("error\nНе могу открыть файл " . (WORK_DIR . $item['id']) . '. Проверьте права доступа.');
            //die('Не могу открыть файл '.$db_file.'. Проверьте права доступа.');
        }
    break;

/******** Отображение кнопок ********/
    case "view":
        $_REQUEST['id'] = trim(@$_REQUEST['id']);
        if(!preg_match('~\d+~', @$_REQUEST['id']))
            $_REQUEST['id'] = '';
        if(is_file(WORK_DIR . $_REQUEST['id']))
            $item = get_button($_REQUEST['id']);
        else
            $item = '';
        $z = array(
                "status" => "false",
                "referrer" => @$_SERVER['HTTP_REFERER'],
                "id" => @$_REQUEST['id'],
                "ip" => @$_SERVER['REMOTE_ADDR'],
                "time" => time(),
                'user_agent' => @$_SERVER['HTTP_USER_AGENT']
                #"url" => 'http://'.@$_SERVER['HTTP_HOST'].@$_SERVER['REQUEST_URI']
            );
        if(!$item)
            log_event($z);
        else{
            $html = '';
            $flag = true;
            foreach($item['ip_list'] as $ip) {
                $ip = trim($ip);
                if(in_array(@$_SERVER['REMOTE_ADDR'], gen_ip_range($ip, 5))) {
                    # Показать кнопку
                    $z['status'] = 'true';
                    log_event($z);
                    $html = $item['htmlcode'].'<br />';
                    $flag = false;
                }
            }
            if($flag) {
                $z['status'] = 'false';
                log_event($z);
            }
            if($html) {
                show_page($html);
                die();
            }
        }
    break;

/******** Очищаем лог ********/
    case "clear_log":
        $db = new MyDB(LOG_FILE, 'write');
        $db->clear_all();
        unset($db);
        echo 'ok';
    break;

/******** Очищаем кнопки и лог ********/
    case "clear":
        $flag = true;
        $d = opendir(WORK_DIR);
        while($file = readdir($d))
            if($file != '.' && $file != '..')
                if(!unlink(WORK_DIR . $file)) $flag = false;
        if($flag)
            echo 'ok';
        else
            echo 'error';
    break;

/******** Показываем лог ********/
    case "log":
        echo $xml_header;
            
        $db = new MyDB(LOG_FILE, "read");
        while($item = $db->get())
        {
            foreach($item as $key => $v)
                $item[$key] = htmlspecialchars($item[$key]);
            printf($log_xml_item,
                $item['referrer'],
                $item['id'],
                $item['user_agent'],
                $item['ip'],
                $item['time'] / 86400 + 25569,
                $item['status']
            );
        }
        unset($db);
        
        echo $xml_footer;
    break;

/******** Просматриваем список кнопок ********/
    case "buttons":
        echo $xml_header;
            
        $d = opendir(WORK_DIR);
        while($file = readdir($d))
        {
            if($file == '.' || $file == '..' || $file == basename(LOG_FILE))
                continue;
            $item = get_button($file);
            if(!$item)
                continue;
            foreach($item as $key => $v)
                if(!is_array($v))
                    $item[$key] = htmlspecialchars($item[$key]);
            printf($buttons_xml_item,
                    $item['id'],
                    $item['domain'],
                    $item['htmlcode'],
                    @join("\n", @$item['ip_list'])
                );
        }
        
        echo $xml_footer;
    break;

/******** Проверка прав необходимых для работы скрипта ********/
    case "check":
        if(!is_dir(WORK_DIR) && !mkdir(WORK_DIR))
            print_error(sprintf("Нет прав создать директорию \"%s\"", WORK_DIR));
        
        if(!is_writeable(WORK_DIR) || !chmod(WORK_DIR, 0777)) {
            print_error(sprintf("Директория \"%s\" должна быть доступна для записи", WORK_DIR));
        }
        if(!is_file(LOG_FILE)) {
            $f = fopen(LOG_FILE, 'w');
            fclose($f);
            chmod(LOG_FILE, 0777);
        }
        if(!is_writeable(LOG_FILE) || !is_readable(LOG_FILE)) {
            print_error(sprintf("Файл \"%s\" должен быть доступен для записи", LOG_FILE));
        }
        if($template_file && !is_file($template_file))
            print_error("Указан неверный путь к файлу шаблона", LOG_FILE);
        echo 'checked';
    break;

/******** Удаление кнопки ********/
    case "delete":
        check_id($_REQUEST['id']);
        if(is_file(WORK_DIR . @$_REQUEST['id'])) {
            if(unlink(WORK_DIR . @$_REQUEST['id']))
                echo 'ok';
            else
                print_error(sprintf('Не могу удалить кнопку с ID=%s', $_REQUEST['id']));
        } else {
            #print_error(sprintf('Кнопка с ID=%s не найдена', $_REQUEST['id']));
            echo 'ok';
        }
    break;

/******** Редактирование кнопки ********/
    case "edit":
        check_id($_REQUEST['id']);
        if(is_file(WORK_DIR . @$_REQUEST['id'])) {
            $button = get_button($_REQUEST['id']);
            if(!$button)
                print_error(sprintf("Кнопка с ID=\"%s\" не найдена", $_REQUEST['id']));
            $button['ip_list'] = explode("|", $_REQUEST['ip']);
            $button['htmlcode'] = $_REQUEST['htmlcode'];
            $button['domain'] = $_REQUEST['domain'];
            write_button($button['id'], $button);
            echo 'ok';
        } else {
            print_error('Кнопка не найдена');
        }
    break;
}

?>