Читаем дату SMS из бекапа iOS

Известно, что в файле 3d0d7e5fb2ce288813306e4d4636395e047a3d28 содержится SQLite-БД с сообщениями, несложные таблицы.

А чтобы перенести бекап этих сообщений на Android, надо немного сплясать с бубном. Я не нашёл ни одной апки, которая бы грамотно конвертировала дату в сообщениях — и немного погуглив — нашёл, как привести таймштамп в пристойный вид.

1. Эпл записывает слишком много нулей в конец строки. Это связано с их хитрым подсчётом секунд.
2. Эпл считает, что юникс-эпоха пошла с 2001, а не с 1970.

В итоге корректный запрос на выборку человеческих дат примерно такой:

SELECT DATETIME(`date`/1000000000 + 978307200,"unixepoch","localtime") FROM message LIMIT 10;

Ну а чтобы перенести бекап так, чтобы даты не поломались —

UPDATE message SET `date` = `date`/1000000000, date_read = date_read/1000000000, date_delivered = date_delivered / 1000000000. Ну, в зависимости от типа программы, которой вы будете пользоваться, или добавляем 30 лет дополнительно, или нет. iSMS2droid достаточно просто деления.

Всем привет

Проект не закрыт, но заброшен ввиду смены интересов.

Меня можно читать в Фейсбуке — там же следить за новостями моей компании.

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

Спасибо, что вы здесь. Регистрация отключена.

Windows — не работает клавиатура и мышь

Удивительный зверек — этот ваш Касперский.

Я даже не сразу связал одно с другим — после того как компьютер как-то с утра включился — просто и тупо перестали реагировать мышь и клавиатура.

Если опустить подробности — то я сразу перейду к лечению этой гадости.

При перезагрузке компьютера жмем F8 — переходим в экран диагностики и восстановления.
Там открываем командную строку, — я дальше делал все через regedit.

Идем в

HKEY_LOCAL_MACHINE

Загружаем куст реестра (меню Файл) из файла (у меня это был диск E:) Windows\System32\Config\system

Именуем как хотим — например, xxx.

В этом кусте идем в
CurrentControlSet\Control\Class\{4D36E96B-E325-11CE-BFC1-08002BE10318}

Там убиваем из UpperFilters все кроме kbdclass

Аналогично шагаем рядышком в 4D36E96F-E325-11CE-BFC1-08002BE10318, там оставляем в этом ключе mouclass — остальное — тлен от Касперского.

Выгружаем куст, перезагружаемся, радуемся жизни.

Два вечера ушло чтобы разобраться. Даже PS/2 клавиатуру нашел для проверки. Мда.

Добавлю что эта ошибка очень распространена после сноса Касперского — секурити или антивируса — все равно. Эта падаль записывает свои определения девайсов в реестр и забывает их вычистить — в связи с чем можно отложить кирпича. И бесполезно копировать кусты из regbackup — фактически, если Касперский стоял хотя бы неделю — эти кусты тоже загажены.

Windows 8 и Google Chrome — убираем Metro.

Очень просто сделать так чтобы все ссылки из аппов открывались не в метро-стайл.

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\ChromeHTML\shell\open\command]
"DelegateExecute"=-

[HKEY_CLASSES_ROOT\Chrome\.exe\shell\open\command]
"DelegateExecute"=-

[HKEY_CLASSES_ROOT\Chrome\.exe\shell\opennewwindow\command]
"DelegateExecute"=-

[HKEY_CLASSES_ROOT\Chrome\.exe\shell\run\command]
"DelegateExecute"=-

Сохранить в файл fuckmetrochromestyle.reg. Запустить. Согласиться со всем что предложат. Наслаждаться.

Вычистить текст от тегов MS Word

Внезапно случается, что когда текст вносится напрямую из Word в WYSWYG-редактор — получается плохо.

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

В итоге:


<?

if(!mysql_connect('host', 'user', 'password')){
    die(mysql_error());
}

if(!mysql_select_db('db')){
    die(mysql_error());
}

mysql_query("SET NAMES UTF8");

$tables = array(
                'news'  =>  array(
                                'id'        => 'id',
                                'content'   => 'content_field'
                            ),
                'pages' =>  array(
                                'id'        =>  'page_id',
                                'content'   => 'content_field'
                )
            );

$mask = array('mso', '\"');

foreach($tables as $table=>$data){
    
    foreach($mask as $mask_value){
        echo "Searching ".$mask_value."\n";
        $query = "SELECT COUNT(*) FROM ".$table." WHERE ".$data['content']." LIKE '%".$mask_value."%'";
        $result = mysql_query($query);
        $row = mysql_fetch_row($result);
        echo "\t".$row[0]." from ".$table."\n\n";
        while(true){
            
            $query = "
                    SELECT ".$data['id'].", ".$data['content']."
                    FROM ".$table."
                    WHERE ".$data['content']." LIKE '%mso%' LIMIT 1";
        
            $result = mysql_query($query);
            if($result && mysql_num_rows($result) == 1){
                $row = mysql_fetch_assoc($result);
                echo $row[$data['content']]."\n";
                echo "--------------------\n";
                $true_content = clean($row[$data['content']]);
                echo $true_content;
                echo "\n";
                echo 'Content is correct? [y\N] ';
                $d = trim(fgets(STDIN));
                if($d){
                    $query = "
                            UPDATE ".$table."
                            SET ".$data['content']." = '".mysql_real_escape_string($true_content)."'
                            WHERE ".$data['id']." = ".$row[$data['id']];
                    mysql_query($query);
                }
                continue;
            }
            break;
        }        
    }
}

function clean($content){
    $content = preg_replace("/\r/",'',$content);
    $content = stripslashes($content);
    $content = preg_replace('/<p[^>]+>(.+?)<\/p>/is', "<p>$1</p>", $content);
    $content = preg_replace('/<span[^>]+>(.+?)<\/span>/is', "<span>$1</span>", $content);
    $content = preg_replace('/<!.+?(?:\-\-|\])>/','',$content);
    $content = preg_replace('/<style.+?<\/style>/is','',$content);
    $content = preg_replace('/<xml.+?<\/xml>/is','',$content);
    $content = strip_tags($content,'<span><p><b><i><u><a><img><table><tr><th><td><thead><tbody><br>');
    $content = str_replace(" "," ", $content);
    $content = preg_replace("/<(?:span|p)>\s*<\/(?:span|p)>/is","",$content);
    $content = preg_replace("/\n\n+/","\n",$content);
    return $content;
}
?>

Логин и парсер Яндекс.Вебмастера

Волею судеб захотелось отфильтровать в одном дампе индексат от неиндексата — полез в Яндекс.Вебмастер.

Ну, сразу перейду к расстройству что даже в Я.Вебмастер показывается только первая 1000 проиндексированных страниц — но парсер уже был готов, допиливать его не стал.

С использованием Jum::Web::Crawler — функцию под него я уже постил


use strict;
use Jum::Web::Crawler;

my $login = q[];
my $password = q[];
my $cookie_file = q[./yandex.cookie];

print qq[Enter site ID: ];
my $site_id = <STDIN>;
chop $site_id;
print $site_id." in process..\n";

my $webmaster_href = q[http://webmaster.yandex.ru/site/indexed-pages.xml?host=%d&path=*&page_num=%d];
my $auth_href = q[https://passport.yandex.ru/passport?mode=auth];
my $post_data = q[display=page];
$post_data .= q[&from=passport];
$post_data .= q[&idkey=%s];
$post_data .= q[&retpath=http://webmaster.yandex.ru];
$post_data .= q[&login=]$login;
$post_data .= q[&passwd=].$password;
$post_data .= q[&twoweeks=yes];
$post_data .= q[&timestamp=].time().q[520];

my $login_data = Jum::Web::Crawler::getURL({href=>$auth_href, cookie_file=>$cookie_file});
my $idkey = $1 if $login_data->{content} =~ /"idkey" value="([^"]+)/;

$post_data = sprintf($post_data, $idkey);

$login_data = Jum::Web::Crawler::getURL({
href => $auth_href,
post => $post_data,
cookie_file => $cookie_file,
referer => $auth_href
});

if($login_data->{content} =~ /Refresh" content="0;/){
print qq[Success!\n];
}

my $i = 0;
open F,">".$site_id.".links";
while(1){
my $href = sprintf($webmaster_href, $site_id, $i);
print qq[Getting $href ...\n];
$i++;
my $content = Jum::Web::Crawler::getURL({href=>$href, cookie_file=>$cookie_file});
while($content->{content} =~ /target="_blank" href="([^"]+)/isg){
my $found_href = $1;
print "\t".$found_href."\n";
print F $found_href;
}
# Цикл бесконечный - имейте в виду. Надо останавливать когда дошли до конца.
}
close F;

Одно расстройство с этой 1000 страниц. Прицельно бить Яндекс очень не хочется.

Восстановить софтверный RAID-1 в Hetzner

Чумовейшая чума.
Вчера вырубил все фильтры, которые блокировали разного рода рассылки в почте. И моментально свалилось три письма, с содержанием примерно о том что you have degraded array at /dev/mda0 и тому подобное — на все три партиции винта, стоящего в рейде и меньше года проработавшего. В Hetzner.

Просмотрел почту — валились такие письма уже месяца два. Написал в Hetzner — так мол и так — винт подох, не откликается по

hdparm -i /dev/sdb | grep SerialNo
HDIO_DRIVE_CMD(identify) failed: Input/output error
HDIO_GET_IDENTITY failed: No message of desired type

И пишут они мне человеческим языком — давайте, мол, запустим мы вам хардвар чек на 10 часов с отключением сервера.
Я так немножечко удивился — отвечаю — братюни, у меня винт из рейда выпал — вот, посмотрите —

cat /proc/mdstat

Personalities : [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md2 : active raid1 sda3[0]
1462516672 blocks [2/1] [U_]

md1 : active raid1 sda2[0]
524224 blocks [2/1] [U_]

md0 : active raid1 sda1[0]
2096064 blocks [2/1] [U_]

unused devices:

А они такие — ну отлично — давайте тогда мы вам винт поменяем просто. 20 минут работы всего делов.
Ну, я по scp слил бекапы /etc, /home и /var — и говорю — ну, меняйте, чертяки языкастые. Даром чтоль вам плачу-то.

Пишут через полчаса — поменяли, проверяйте. Проверяю — и вправду, диск подключили, серийник его высвечивается. А вот в рейд его не впихнули. Пишу — мол, своими руками-то в рейд его колбасить? Отвечают — ну, своими и колбась, вот тебе ссылка на нашу вики что и как там делать.

ОК. Посмотрел вики. Сделал первому винту fdisk /dev/sda -l — запомнил все, что написали. Начал делать такое же для второго, новенького.

А винты-то кстати на полтора тера оба.

И второй в GPT притом. Правда, не сразу заметил. Ну, в общем, шаманил и шаманил с fstab, sfstab, cfstab, — даже потом в parted полез, — чтоб убедиться что последний ext3 не знает как системы до сих пор.

Что-то вроде было:

sfdisk -d /dev/sda | sfdisk /dev/sdb
Checking that no-one is using this disk right now …
OK

Disk /dev/sdb: 182401 cylinders, 255 heads, 63 sectors/track

sfdisk: ERROR: sector 0 does not have an msdos signature
/dev/sdb: unrecognized partition table type
Old situation:
No partitions found
New situation:
Units = sectors of 512 bytes, counting from 0

Device Boot Start End #sectors Id System
/dev/sdb1 2048 4194303 4192256 fd Linux raid autodetect
/dev/sdb2 4194304 5242879 1048576 fd Linux raid autodetect
/dev/sdb3 5242880 2930276351 2925033472 fd Linux raid autodetect
/dev/sdb4 0 — 0 0 Empty
Warning: partition 1 does not end at a cylinder boundary

sfdisk: I don’t like these partitions — nothing changed.
(If you really want this, use the —force option.)
sfdisk -d /dev/sda | sfdisk /dev/sdb —force
Checking that no-one is using this disk right now …
OK

Disk /dev/sdb: 182401 cylinders, 255 heads, 63 sectors/track

sfdisk: ERROR: sector 0 does not have an msdos signature
/dev/sdb: unrecognized partition table type
Old situation:
No partitions found
New situation:
Units = sectors of 512 bytes, counting from 0

Device Boot Start End #sectors Id System
/dev/sdb1 2048 4194303 4192256 fd Linux raid autodetect
/dev/sdb2 4194304 5242879 1048576 fd Linux raid autodetect
/dev/sdb3 5242880 2930276351 2925033472 fd Linux raid autodetect
/dev/sdb4 0 — 0 0 Empty
Warning: partition 1 does not end at a cylinder boundary
Successfully wrote the new partition table

Re-reading the partition table …

If you created or changed a DOS partition, /dev/foo7, say, then use dd(1)
to zero the first 512 bytes: dd if=/dev/zero of=/dev/foo7 bs=512 count=1
(See fdisk(8).)
fdisk /dev/sda -l

Disk /dev/sda: 1500.3 GB, 1500301910016 bytes
64 heads, 32 sectors/track, 1430799 cylinders
Units = cylinders of 2048 * 512 = 1048576 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0005d36c

Device Boot Start End Blocks Id System
/dev/sda1 2 2048 2096128 fd Linux raid autodetect
/dev/sda2 2049 2560 524288 fd Linux raid autodetect
/dev/sda3 2561 1430799 1462516736 fd Linux raid autodetect
fdisk /dev/sdb -l

Disk /dev/sdb: 1500.3 GB, 1500301910016 bytes
255 heads, 63 sectors/track, 182401 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Device Boot Start End Blocks Id System
/dev/sdb1 1 262 2096128 fd Linux raid autodetect
Partition 1 does not end on cylinder boundary.
/dev/sdb2 262 327 524288 fd Linux raid autodetect
Partition 2 does not end on cylinder boundary.
/dev/sdb3 327 182402 1462516736 fd Linux raid autodetect

Ничем в общем все заканчивалось — видать, где-то сам дурак был, недоразметил ему шапку дисковую. Хотя и dd пробовал подтесать ему, и с fdisk ms-dos-ил.. В итоге просто в какой-то момент переписка моя с саппортом зашла в тупик и полез курить маны, куренные в последний раз года три назад.

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

dd if=/dev/sda of=/tmp/sda.mbr bs=512 count=1
dd if=/tmp/sda.mbr of=/dev/sdb bs=512 count=1
fdisk /dev/sdb

После чего сохранил разметку партиции — ну а дальше дело техники —

mdadm /dev/md0 -a /dev/sdb1
mdadm /dev/md1 -a /dev/sdb2
mdadm /dev/md2 -a /dev/sdb3

Осталось 3 часа до синхронизации последней партиции. Радуюсь.

Таймер отключения компьютера

Немногие отчего-то знают про программу shutdown.exe в Windows.

Далее — про Win7/Vista, не помню и лениво было смотреть документацию для прочих.

Суть в том, что эта программа позволяет задать таймер для выключения или перезагрузки компьютера. У нее даже GUI есть (shutdown -i)

А я лентяй и мне гуи дергать и настраивать лениво — и накидал прогу которая через заданное количество секунд-минут-часов-лет вырубит комп через этот самый шатдаун. Потому что когда я лежу в кровати и знаю что фильм кончится через час — вставать и выключать через час комп мне лениво.

WindowsShutdownTimer

Вычистить сайт от вируса iframe

очень просто, если иметь SSH.

$ find . | xargs grep -l «<iframe src=’badsite'» | xargs sed -i -e ‘s/bad_code_with_stripping_regex_chars//g’

Эта команда заменит весь вредоносный код на ничего.

Увести процесс из консоли в фон

Наконец-то погуглил как это сделать.

Если у вас что-то запущено в консоли и вам надо уходить, забрав с собой компьютер — то все очень просто.

Ctrl+Z
Процесс вешается в паузу
А потом продолжаем его уже в фоне (а лучше в скрине) — kill -s CONT $PID

Или попросту bg в текущем экране. Признак того, что процесс продолжился в фоне — это то что будет написано при выводе команды jobs.

Вуаля!