воскресенье, 26 декабря 2010 г.

Обработка изображений в PHP

По дороге из мастерской Март нагнал Бэрка и пошел рядом с ним.
– Что там такое? – спросил он. – Уж не собираются ли они выдать нам по оловянной медали?
– Даже лучше, – сказал Бэрк. – Узнаешь сам.

Джоунс Рэймонд Ф. "Уровень шума"

А почему бы, собственно, не нарисовать оловянную медаль? В конце концов, вариант

выглядит весьма забавно, единственное - как-то коробит использование реальной боевой награды в качестве исходного образца. Попробуем нарисовать своё...

Итак, есть некое изображение, нужно превратить его в медаль. Для этого требуется:
1) Получить из изображения чеканку
2) Нарисовать колодку
А так как нужно стараться решать не задачи, а классы задач, то будем считать, что изображение - достаточно произвольное, и вообще пусть всё делает компьютер, а именно PHP с подключенным модулем gd2.

1а. Пусть у нас уже готова веб-форма для загрузки изображения, например:

<HTML>
<BODY>
<FORM method="POST" enctype="multipart/form-data" action="step2.php">
<INPUT type="file" name="">
</FORM>
</BODY>
</HTML>

Соответственно, в скрипте step2.php можно использовать имя сохраненной копии переданного файла в переменной $_FILES['userfile']['tmp_name']. С ним дальше и будем работать.

1б. Сначала надо открыть файл в PHP. Для этого воспользуемся способом, используемым в WR-Gallery:

$size = getimagesize($SrcFileName);
if ($size !== false)
{
$format = strtolower(substr($size['mime'], strpos($size['mime'], '/')+1));
$icfunc = "imagecreatefrom" . $format;
if (function_exists($icfunc))
$isrc = $icfunc($SrcFileName);
}

В результате получим в переменной $isrc ссылку на загруженное изображение.

1в. Дальше надо привести полученное изображение к нужному нам размеру. Это легко сделать при помощи функции imagecopyresampled:

$idest = imagecreatetruecolor($new_width, $new_height);
imagecopyresampled($idest, $isrc,
0, 0,
0, 0,
$new_width, $new_height,
$size[0], $size[1]);

После этой операции об $isrc можно забыть: imagedestroy($isrc);

1г. Для чеканки, как выяснилось, требуется изображение в оттенках серого. И вот тут начинается небольшое изобретение велосипеда. Да-да, все слышали об imagecopymergegrey и imagefilter, с помощью которых задача решается в два действия, но будем считать, что автор - дятел, и попробуем сделать всё вручную, заодно вспомнив, какая математика скрывается за всеми этими операциями.

Итак, оттенки серого. Как выяснилось, любой цветной пиксел (r,g,b) преобразуется в серый при помощи следующей формулы: h = 0.30*r + 0.59*g + 0.11*b. Таким образом, получив для каждой точки изображения ее составляющие мы вполне можем перевести эту точку в оттенки серого:

$rgb = imagecolorat($idest, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
$grey[$x][$y] = $r * 0.3 + $g * 0.59 + $b * 0.11;

Тут, казалось бы, и рисовать! Но, забегая вперед, скажем, что результат чеканки в целом с использованием палитры $color[$i] = imagecolorallocate($igrey,$i,$i,$i); оказался неудовлетворительным с точки зрения контрастности, поэтому при инициализации палитры эту самую контрастность лучше заранее повысить.

1д. С контрастностью всё оказалось просто. Во-первых, есть вот такая статья с готовыми алгоритмами, посвященными этой теме, и, во-вторых, отыскалась простая формула, пересчета палитры в заданную контрастность: H_new = (H_old - H_mid)*Contrast + H_mid, где H_new и H_old - новое и старое значения цвета соответственно, Contrast - коэффициент, задающий контрастность и H_mid - неподвижная точка преобразования.

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

$igrey = imagecreatetruecolor(240, 400);
for ($i = 0; $i < 256; $i++)
{
$v = ($i - 128) * 4 + 128;
if ($v < 0) $v = 0;
if ($v > 255) $v = 255;
$color[$i] = imagecolorallocate($igrey, $v,$v,$v);
}


1е. Теперь остается самое простое - имея двумерный массив интенсивностей $grey[$x][$y] реализовать то, что называется emboss. И тут возникло небольшое затруднение. Из далекого детства известно, что большинство преобразований - размытие, резкость и т.п. - это просто результат применения некого фильтра к исходному изображению. Что имеется в виду? Пусть задана некая матрица А=a(i,j), где i=-n..n, j=-m..m. Тогда применение фильтра к каждой точке изображения - это вычисление суммы слагаемых вида a(i,j)*$grey[$x+i][$y+j], деленной на сумму коэффициентов a(i,j).

Например, для размытия матрица А имеет вид:
1 1 1
1 1 1
1 1 1

для вычисления границ:
 1  1  1
0 0 0
-1 -1 -1

и т.п.

А вот для emboss почему-то разные источники предлагают разные матрицы. Во-первых встретилась такая матрица:
1  0  0
0 0 0
0 0 -1

или даже такая:
-1 -1  1
-1 -1 1
1 1 1

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

$grey[$x][$y] = ($grey[$x+1][$y+1] + (255 - $grey[$x][$y])) / 2;


Теперь уже можно со спокойной совестью превратить пересчитанный массив $grey в изображение при помощи функции:

imagesetpixel($igrey, $x, $y, $color[$grey[$x][$y]]);


1ё. В конце концов у нас получается прямоугольная чеканка. Следующий шаг - сделать из неё круглую медаль. К сожалению, на глаза вовремя не попалась функция PHP, которая могла бы копировать непрямоугольные области, поэтому пришлось тоже слегка пофантазировать.

Для этой цели заводим еще одно изображение, $itransp, на котором рисуем белым цветом кружок, делаем остальной фон прозрачным, и функцией imagecopymerge копируем полученный шаблон на $igrey:

$itransp = imagecreatetruecolor(240, 400);
$black_color = imagecolorallocate($itransp, 0,0,0);
$white_color = imagecolorallocate($itransp, 255,255,255);
imagefill($itransp, 0,0, $white_color);
imagefilledellipse($itransp, 120, 300, 200, 200, $black_color);
imagecolortransparent($itransp, $black_color);
imagecopymerge($igrey, $itransp, 0,0,0,0, 240, 400, 100);
imagedestroy($itransp);


Ура, каким-то чудом медаль получена.

2. Теперь осталось самое простое - нарисовать колодку. Собственно, она представляет собой закрашенный многоугольник, единственная тонкость - нанести на него какую-нибудь фактуру, чтобы было похоже на ткань. Для этой цели не придумалось ничего умнее, чем завести еще одно вспомогательное изображение $ibarpattern, в котором нарисовать фактуру ткани, и потом при помощи функции imagecopymerge наложить эту фактуру на колодку:

$ibarpattern = imagecreatetruecolor(240, 5);
$black_color = imagecolorallocate($ibarpattern, 0,0,0);
$white_color = imagecolorallocate($ibarpattern, 255,255,255);
imagefill($ibarpattern, 0,0, $white_color);
imagecolortransparent($ibarpattern, $white_color);
$dy = 0;
for ($i = 0; $i < 240; $i++)
{
$dy++;
if ($dy >=10) $dy = 0;
imagesetpixel($ibarpattern,
$i,
($dy < 5) ? 2 : 3,
$black_color);
imagesetpixel($ibarpattern,
$i,
($dy < 5) ? 1 : 4,
$black_color);
}
for ($i = 0; $i < 190; $i += 5)
imagecopymerge($ibar, $ibarpattern, 0, $i, 0, 0, 250, 5, 10);
imagedestroy($ibarpattern);


И вот - наконец-то! - после всех этих ухищрений получается то, что нужно:



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

Сохранить видео с youtube

Список вариантов

пятница, 3 декабря 2010 г.

Командная строка Windows XP

http://bozza.ru/art-128.html

rundll32 shell32,Control_RunDLL appwiz.cpl,,n - вызов диалогового окна "Установка и удаление программ", в котором будет открыта вкладка с номером "n" (от 1 до 3)

вторник, 9 ноября 2010 г.

Ошибка при взаимодействии с Excel

На одном компьютере (WinXP MSOffice 2007) при попытке выгрузить отчет из самописной (.NET 3.5) программы в Excel проявилась следующая ошибка: Невозможно привести COM-объект типа "Microsoft.Office.Interop.Excel.ApplicationClass" к интерфейсному типу "Microsoft.Office.Interop.Excel._Application". Операция завершилась со сбоем, поскольку вызов QueryInterface COM-объекта для интерфейса с IID "{000208D5-0000-0000-C000-000000000046}" возвратил следующую ошибку: Ошибка при загрузке библиотеки. (Исключение из HRESULT: 0x80029C4A (TYPE_E_CANTLOADLIBRARY)).

Ну да, программа компилировалась на компе с MSOffice 2003, и это наложило определенный отпечаток на набор ее библиотек. Но ведь на других станциях всё работает... Единственная особенность - на проблемной машине зачем-то были установлены primary interop assemblies 2007. В итоге помог метод грубой силы: деинсталляция этих самых assemblies и восстановление офиса.

UPD 2018-08-10: По крайней мере, в одном случае удалось установить причину этой ошибки. Как оказалось, по адресу HKEY_CLASSES_ROOT\Interface\{000208D5-0000-0000-C000-000000000046}\TypeLib лежит некий guid (в моём случае {00020813-0000-0000-C000-000000000046}) и номер версии, который нужно использовать (в моём случае 1.6).

Так вот, в ветке реестра HKCR\TypeLib\{00020813-0000-0000-C000-000000000046} перечислены разные версии, и среди них оказалась одна запись (1.9), оставшаяся от деинсталлированного офиса 2010. Если эту запись, отсылающую к несуществующей версии excel-а, удалить, то ошибка пропадает.

Навело на решение это обсуждение.

RDP + командная строка

Кстати, службой терминалов можно управлять не только с помощью графического интерфейса tsadmin.exe, но и через командную строку

ASUS O!Play Air HDP R-3

Так-то штука, конечно, забавная, но есть некоторое количество вопросов.
1. при подключении "тюльпанами" (композитное видео, что ли) засыпает на пятнадцатой минуте полета, причем хорошо так засыпает, практически намертво. Хотя, может, просто телевизор старый... Через HDMI всё нормально.
2. Русские буквы как-то не везде. В прошивке 1.21p по крайней мере глючит RSS, а при попытке поработать с прибором через телнет, соответственно слегка чудит встроенный линукс, не давая ввести русские названия радиостанций (видимо, из-за странного понимания UTF8).

воскресенье, 7 ноября 2010 г.

всякая всячина о линуксе

убрать мусор в приглашении mc:
echo PS1=\'\\u@\\h:\\w\\$ \' >> ~/.mc/bashrc

узнать размер папки:
du -sh bin/
-s, --summarize (display only a total for each argument)
-h, --human-readable ( print sizes in human readable format (e.g., 1K 234M 2G))

посмотреть открытые порты:
nmap -sT -O localhost
посмотреть, кто открыл порты:
netstat -anp
lsof -i

примонтировать флэшку:
подсмотреть в журнале, какое устройство нужно монтировать:
dmesg
смонтировать:
mount -t vfat -o codepage=866,iocharset=utf8 /dev/sdc /media/usb_flash1

получить адрес с DHCP:
sudo dhclient -r
sudo dhclient
или
ifdown eth0
ifup eth0
/etc/init.d/network restart

понедельник, 1 ноября 2010 г.

Чокнулся GSM-модем

Начал выдавать с завидной периодичностью вот такое:
^BOOT:78236782,0,0,0,87
^RSSI:7
^RSSI:7
^RSSI:7

Вылечилось командой AT^CURC=0 благодаря подсказке отсюда:
You might try to use this command
AT^CURC? Current setting of periodic status messages
AT^CURC=? See what you possible values are
AT^CURC=0 turn off periodic status messages

воскресенье, 24 октября 2010 г.

undefined video mode number

Надоело сообщение при загрузке: undefined video mode number 316
Решение оказалось простым:
1. Отредактировать /etc/lilo.conf (найти vga=790 и проставить что-то типа normal)
2. вызвать /sbin/lilo

Добрые люди вот такую табличку выложили...

# FRAMEBUFFER RESOLUTION SETTINGS
# +-------------------------------------------------+
# | 640x480 800x600 1024x768 1280x1024
# ----+--------------------------------------------
# 256 | 0x301=769 0x303=771 0x305=773 0x307=775
# 32K | 0x310=784 0x313=787 0x316=790 0x319=793
# 64K | 0x311=785 0x314=788 0x317=791 0x31A=794
# 16M | 0x312=786 0x315=789 0x318=792 0x31B=795
# +-------------------------------------------------+

всякая всячина о Slackware

Удалить KDE:
removepkg /var/log/packages/kde*

узнать версию:
cat `ls /etc/*{-,_}{release,version} 2>/dev/null | head -n 1`
(в нашем случае /etc/slackware-version)

выполнить скрипт при загрузке системы:
поместить в /etc/rc.d/rc.local такую конструкцию:
if [ -x /etc/rc.d/rc.scriptname ]; then
/etc/rc.d/rc.scriptname start
fi

установить локальную переменную окружения (зависит от шелла, но примерно так):
в файл ~/.bash_profile вносим строку export myVar=myValue, перелогиниваемся и проверяем echo $myVar

для использования lynx прокси можно прописать переменную окружения http_proxy. только все равно с ntlm работать не будет. правда, есть выход в виде ntlmaps

чтобы cron писал логи, нужно поправить /etc/rc.d/rc.M:
# Start crond (Dillon's crond):
# If you want cron to actually log activity to /var/log/cron, then change
# -l10 to -l8 to increase the logging level.
if [ -x /usr/sbin/crond ]; then
/usr/sbin/crond -l10 >>/var/log/cron 2>&1
fi
(сами задачи просматриваются через crontab -l, а редактируются через crondtab -e)

Книжки можно поискать тут

knigi.tr200.ru
www.bookshunt.ru

понедельник, 13 сентября 2010 г.

PIN-код для сервис-меню HPLJ3500-3700

HP Color LaserJet 3500 код – 10350003
HP Color LaserJet 3700 код - 10370003
и вообще, вот полезная ссылка.

пятница, 3 сентября 2010 г.

Как инсталлировать сервис .NET

Installutil MyService.exe

ну и, соответственно, деинсталлировать:
Installutil /u MyService.exe

воскресенье, 15 августа 2010 г.

Симпатичный ролик

Hayaku (A Time Lapse Journey Through Japan) by Brad Kremer:

(подсмотрел на oper.ru, музыка Röyksopp - Triumphant)

суббота, 31 июля 2010 г.

Отправлять длинные SMS из своей программы

Чудо, чудо! Если использовать конкатенацию SMS, то можно обойти жуткое ограничение в 70 символов на сообщение!

Но, конечно, пришлось разбивать сообщение на кусочки, к каждому из которых в начало прописывать по шесть байтов:

text =
"06" + // Length of User Data Header
"08" + // Concatenated short messages, 16-bit reference number
"04" + // Length of the header, excluding the first two fields
CSMS_reference_number + // уникальный номер длинного сообщения
chunks.Count.ToString("X2") + // число кусков сообщения
(i+1).ToString("X2") + // номер куска
text;

и в SMS-SUBMIT PDU устанавливать 6-й бит, так что он теперь стал не "11", а "51".

воскресенье, 25 июля 2010 г.

Отправлять SMS из своей программы

В общем-то, C# рулит...

1. Самой большой проблемой было добиться от сотового телефона на команду "AT" внятный ответ "OK".
Использовал System.IO.Ports.SerialPort:

System.IO.Ports.SerialPort serialPort = new SerialPort("COM5");
serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);
serialPort.BaudRate = 115200;
serialPort.Open();
serialPort.WriteLine("AT\r");

В обработчике serialPort_DataReceived получилось примерно следующее:

void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
this.SetText(serialPort.ReadExisting());
}

Соответственно, основные пляски с бубном - это позволить написать что-то в textBox1 из другой нитки:

delegate void SetTextCallback(string text);
private void SetText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.textBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.textBox1.Text += "\r\nrcv: " + text;
}
}

2. Теперь о собственно передаче сообщений. Очень заманчиво было бы воспользоваться советами, приведенными тут. В самом деле,

AT+CSCS="UCS2"\r
AT+CSMP=1,167,0,8\r
AT+CMGS="+31638740161"\r
06450631062D06280627 + Convert.ToChar(26)

и всё, sms-ка ушла, что может быть проще? Но почему-то оказалось не судьба. На второй команде Siemens CX75 взбрыкнул, и пришлось пойти длинным путем.

Вот тут и тут написана куча полезного. Получилось такое:

AT+CMGF=0\r
AT+CMGS= + (sms.Length/2-1).ToString() + \r
sms + Convert.ToChar(26)

Здесь строка sms конструируется так:

string text = TextToSMS("АБРАКАДАБРА");
string sms =
"00" + // длина SMSC информации (пусть телефон ее додумает сам)
"11" + // first octet of the SMS-SUBMIT PDU
// (установлен бит 0 -> вид сообщения=SMS-SUBMIT)
// (установлен бит 3 -> есть поле TP-VP )
"00" + // TP-Message-Reference. "00" lets the phone set the message reference number itself.
PhoneNumberToSMS("79030123456") + // номер получателя
"00" + // PID - идентификатор номера протокола
"08" + // DCS схема кодирования данных (08 - UCS2=кириллица)
"AA" + // TP-VP - Validity Period, время жизни сообщения на сервере (AA - установлен в 4 дня)
(text.Length/2).ToString("X2") + // длина сообшения
text;


Две функции, PhoneNumberToSMS и TextToSMS, служат для кодирования номера телефона и текста сообщения соответственно:

private string PhoneNumberToSMS(string number)
{
number += "F";
string result =
"0B" + // длина номера (12 цифр, включая F)
"91"; // международный формат номера
int i = 0;
while (i < number.Length)
{
result += number[i + 1].ToString() + number[i].ToString();
i += 2;
}
return result;
}

private string TextToSMS(string text)
{
byte[] b = (new System.Text.UnicodeEncoding()).GetBytes(text);
string result = "";
int i = 0;
while (i < b.Length)
{
result += b[i + 1].ToString("X2") + b[i].ToString("X2");
i += 2;
}
return result;
}

четверг, 1 июля 2010 г.

Хозяйке на заметку...

KEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon
значение UserEnvDebugLevel типа REG_DWORD ставим 0x10002
Перезагружаем... и в журнале %systemroot%\debug\userenv.log имеем задокументированные последовательности применения политики и профилей...

воскресенье, 23 мая 2010 г.

Запись ISO на CD-болванку

wodim dev=/dev/sr0 -v -eject speed=2 my_cd_or_dvd.iso
и вообще, RTFM или слушай умных людей

среда, 19 мая 2010 г.

Сбой при получении производства объектов класса COM (80070005)

Сегодня просто праздник какой-то на ошибки.

Спасибо добрым людям:
"попробуйте дать прав на локальный запуск и активацию для данного компонента локальному пользователю Network Service:
в командной строке dcomcnfg -> Component Services -> Computers -> My Computer -> DCOM Config -> ваш компонент -> Properties -> Security
ну и в первом разделе Customize."
И, разумеется, полезно смотреть в журнал безопасности...

UPD 2013-01-11:
Что-то хитрое произошло, и теперь ошибка стала с номером 80080005. Вышеприведенный способ привести компонент в чувство не увенчался успехом. Пришлось завести учетную запись, прописать её всё там же:
dcomcnfg -> Службы компонентов -> Компьютеры -> Мой компьютер -> Настройка DCOM -> ваш компонент -> Удостоверение, и дать этой учетке право входа в качестве пакетного задания в политиках:
в командной строке gpedit.msc -> Политика "Локальный компьютер" -> Конфигурация компьютера -> Конфигурация Windows -> Параметры безопасности -> Локальные политики -> Назначение прав пользователя -> Вход в качестве пакетного задания

IIS error (80090006)

Решение нашлось:
http://blogs.msdn.com/saurabh_singh/archive/2007/08/02/iisadmin-startup-issues.aspx
Вкратце:
надо восстановить файл:
\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys\c23..._XXX,
где XXX соответствует значению ключа HKLM\SOFTWARE\Microsoft\Cryptography\MachineGUID

воскресенье, 9 мая 2010 г.

Тяжело без gpedit.msc в Vista Home... Однако вот чего-то нашлось на замену:
Group Policy Settings Reference for Windows and Windows Server

вторник, 4 мая 2010 г.

как узнать версию MS SQL:
SELECT SERVERPROPERTY('productversion'), SERVERPROPERTY ('productlevel'), SERVERPROPERTY ('edition')

среда, 28 апреля 2010 г.

Запуск программы .NET из URL

Чудесное открытие. Работает:
<путь_до_фреймворка>/ieexec http://myhost/myapp.exe
Ну, правда, не стоит забывать о всяких граблях с безопасностью...

среда, 27 января 2010 г.

Русификация Slackware 13

Полезная заметка

Вкратце:

1. копируем http://mlclm.narod.ru/ru-utf.map.gz в /usr/share/kbd/keymaps/i386/qwerty

2. в /etc/rc.d/rc.font пишем:
#!/bin/sh
#
# This selects your default screen font from among the ones in
# /usr/share/kbd/consolefonts.
#
unicode_start LatArCyrHeb-16
for i in 1 2 3 4 5 6;do
echo -ne "\033%G" >/dev/tty$i
done

3. в /etc/rc.d/rc.keymap пишем:
#!/bin/sh
# Load the keyboard map. More maps are in /usr/share/kbd/keymaps.
if [ -x /usr/bin/loadkeys ]; then
/usr/bin/loadkeys /usr/share/kbd/keymaps/i386/qwerty/ru-utf.map.gz
fi

4. в /etc/profile.d/lang.sh пишем:
export LANG=ru_RU.UTF-8

5. в /usr/share/hal/fdi/policy/10osvendor/10-keymap.fdi правим параметры:
<merge key="input.xkb.options" type="string">terminate:ctrl_alt_bksp,grp:ctrl_shift_toggle,grp_led:scroll</merge>
<merge key="input.xkb.rules" type="string">base</merge>
<merge key="input.xkb.model" type="string">evdev</merge>
<merge key="input.xkb.layout" type="string">us,ru</merge>
<merge key="input.xkb.variant" type="string">,winkeys</merge>

5'. UPD 2012-10-31:
В Slackware 14 всё оказалось проще:
создаем, если его нет, файл /etc/X11/xorg.conf.d/90-keyboard-layout.conf, в котором прописываем следующее:
Section "InputClass"
Identifier "keyboard-all"
MatchIsKeyboard "on"
Driver "evdev"
Option "XkbLayout" "us,ru(winkeys)"
Option "XkbOptions" "terminate:ctrl_alt_bksp,grp:alt_shift_toggle,grp_led:scroll"
EndSection

6. Если же в страницах man выводятся вместо русских букв непонятные символы, то следует поправить /usr/lib/man.conf:
NROFF /usr/bin/iconv -f utf8 -t koi8r -c | /usr/bin/nroff -Tlatin1 -mandoc | /usr/bin/iconv -f koi8r -t utf8 -c

понедельник, 25 января 2010 г.

vi - ужас, летящий на крыльях ночи











iПерейти в режим вставки
<esc>Перейти в командный режим
:xЗаписать файл и выйти
:wЗаписать файл
:qВыйти


upd 2010-11-09: ой, гоню - вполне себе нормальный редактор. Давеча хотел слегка изменить подсветку синтаксиса в vim, всё оказалось не сильно сложно.
1. можно почитать :help highlight
2. можно посмотреть расцветочку групп командой :hi
3. можно очистить раздражающую группу командой :hi AnnoingGroup NONE
4. но лучше создать файл ~/.vimrc и прописать в нем что-то подобное:
hi AnnoingGroup term=bold cterm=bold ctermfg=7 ctermbg=0

Кстати, можно посмотреть файл в кодировке, отличной от utf-8:
:e! ++enc=cp1251 ++ff=dos

А тут - небольшой справочник команд: http://www.lagmonster.org/docs/vi2.html

Debian: Установка pure-ftpd

Хорошая статья про настройку pure-ftpd:
http://opennet.ru/base/net/linux_pureftp.txt.html
(а тут много интересных нюансов:
http://pureftpd.sourceforge.net/FAQ)

У меня, правда, дебиан, но тоже помогло. Вкратце:

1. Устанавливаем pure-ftpd. Из коробки эта штука будет пускать только под учетками, заведенными в системе, соответственно, в домашние каталоги этих учеток. Правда, это не помешает им шариться по всей файловой системе. Чтобы запереть пользователей в своих домашних каталогах, нужно создать файл /etc/pure-ftpd/ChrootEveryone со словом yes внутри (если же требуется запереть всех, кроме какой-то выделенной группы, следует вместо этого прописать её идентификатор в файле /etc/pure-ftpd/TrustedGID). Вообще, похоже, все настройки у этой штуки лежат по разным файлам с соответствующими именами(*). Непривычно как-то...

2. Для анонимного доступа нужны следующие вещи: учетная запись с именем ftp и слово no в файле /etc/pure-ftpd/NoAnonymous. С учетной записью я поступил следующим образом: создал, как это заведено в культурных домах, папки на чтение и запись:
mkdir /home/ftp/pubmkdir /home/ftp/incoming
раздал им права:
chmod -R 0777 /home/ftp/incomingchmod -R 0755 /home/ftp/pub
и создал пользователя с домашним каталогом /home/ftp:
/usr/sbin/useradd --home /home/ftp ftp

3. Для пассивного режима ещё можно указать интервал портов, по которым клиенты будут стучаться за данными, примерно так:
echo "40110 40210" > /etc/pure-ftpd/conf/PassivePortRange
Ну и не забываем прописать эти порты на роутере 8-)

4. Под дебианом не требуется, а вот под слакварью ещё приходилось запускать сервер командой:
pure-ftpd -4 -A -B -M -l unix -U 022:022 -O clf:/var/log/pureftpd.log
и добавлять эту команду в автозагрузку (/etc/rc.d/rc.local) с полным путем.

(*) Вот отсюда вытащил список этих имён. Ниже представлены они и соответствующие им параметры командной строки (полный список лежит тут):
-A     ChrootEveryone              no  # запереть всех, кроме рута в домашней директории
-a TrustedGID 10 # доверенная группа с этим номером может шариться везде по ФС
-b BrokenClientsCompatibility no # говорят, помогает клиентам, некорректно придерживающимся стандартам
-c MaxClientsNumber 10 # максимальное число клиентов
-B Daemonize yes # запуск в виде демона
-C MaxClientsPerIP 3 # максимальное число подключений с одного клиента
VerboseLog no
-z AllowDotFiles yes # разрешить читать файлы, начинающиеся с точки
-D DisplayDotFiles yes # показывать файлы, начинающиеся с точки
-e AnonymousOnly no # позволять только анонимный доступ
-E NoAnonymous yes # позволять доступ только зарегистрированным пользователям
SyslogFacility ftp
DontResolve no
-I MaxIdleTime 3600 # максимальное время простоя, после которого клиент отрубается
-l pam PAMAuthentication yes # способ аутентификации (есть ещё unix)
-L LimitRecursion 2000 8
-M AnonymousCanCreateDirs no # анонимные пользователи могут создавать каталоги
-m MaxLoad 4 # не позволяет перегружать сервер анонимными загрузками
-s AntiWarez yes # запрещает скачку файлов, загруженных анонимами (определяет такие файлы по их владельцу. если ftp, то считает его загруженным анонимом)
-u MinUID 100 # запрещает коннект пользователям с идентификатором меньше заданного (видимо, чтобы под рутом не коннектились)
-w AllowUserFXP yes # позволяет FXP протокол аутентифицированным пользователям
-W AllowAnonymousFXP no # позволяет FXP протокол анонимным пользователям
-x ProhibitDotFilesWrite yes # никто, кроме доверенной группы, не может писать файлы, начинающиеся с точки
-X ProhibitDotFilesRead no # запретить читать файлы, начинающиеся с точки
-r AutoRename no # переименовывает файл загружаемый файл (*.1, *.2 и т.п.), если файл с таким именем уже есть
-i AnonymousCantUpload yes # запрет анонимам загружать
-O AltLog clf:/var/log/pureftpd.log # записывает передачи файлов в заданный файл определенного формата (clf, stats и т.п.)
-R NoChmod no # запрещает делать команду chmod
-j CreateHomeDir yes # создает домашний каталог вновь создаваемым пользователям
-k MaxDiskUsage 99 # указывает в процентах, до какой степени может быть заполнен диск
-G NoRename no # запрет переименования файлов
-Z CustomerProof yes # не позволяет пользователем выстрелить себе в ногу chmod-ом
-4 IPV4Only yes # использовать только IPv4

Настройка LILO

После попытки установить линукс на компьютер с остатками винды в lilo появился лишний пункт. Чтобы его удалить воспользовался этим:
http://www.linux.org.ru/books/Distro/Slackware/html/conf_4.html

Вкратце:
Отредактировать /etc/lilo.conf
Выполнить /sbin/lilo

пятница, 22 января 2010 г.

Ошибка печати из Outlook Express

Проблема: При попытке распечатать почтовое сообщение выдается ошибка с упоминанием res://ieframe.dll/preview.dlg

Решение: почему-то помогло regsvr32 ole32.dll

среда, 20 января 2010 г.

Чтение-запись NTFS с использованием драйвера ntfs-3g

Полезная заметка: Чтение-запись NTFS с использованием драйвера ntfs-3g в Debian.

вкратце:
1. Устанавливаем пакет ntfs-3g
2. sudo mount -t ntfs-3g /dev/sda1 /mnt/win -o umask=0

вторник, 12 января 2010 г.

Проблема с php_curl.dll

Проблема: после попытки раскомментировать extension=php_curl.dll под апачем выдаётся пара ошибок вида "не найден указанный модуль".
Решение: утащил libeay32.dll и ssleay32.dll в %WINDIR%\system32

пятница, 8 января 2010 г.

Настройка Oracle instant client

1. Ему зачем-то нужны файлы tnsnames.ora (ну, это еще понятно) и sqlnet.ora. При этом ищет он их в директории, указанной в переменной среды TNS_ADMIN. Попытка прописать данную директорию в виде строкового параметра в реестр (HKLM\SOFTWARE\ORACLE\) успехом не увенчалась. Ладно, пусть будет переменная среды.

2. Для правильного отображения русских букв под виндой понадобился строковый параметр HKLM\SOFTWARE\ORACLE\NLS_LANG = RUSSIAN_CIS.CL8MSWIN1251

среда, 6 января 2010 г.

Напильник для rdesktop

rdesktop "из коробки" как-то странно себя ведет - нажатия некторых клавиш обрабатываются совсем не так, как ожидалось. Выход подсказали такой:

Заменить содержимое файлов /usr/share/rdesktop/keymaps/ru и /usr/share/rdesktop/keymaps/en-us одинаково на следущее:

# generated from XKB map ru
include common
map 0x419
grave 0x29
asciitilde 0x29 shift
asciicircum 0x07 shift
backslash 0x2b
bar 0x2b shift
apostrophe 0x28
greater 0x34 shift
less 0x33 shift

После этого для подключения к консоли вполне работает команда:
rdesktop -0 -g 800x540 host:port

вторник, 5 января 2010 г.

Изменение порта RDP

Если вдруг когда-нибудь придет такая мысль (отказаться от 3389), то можно прочитать тут, как это сделать.
Вкратце: поправить ключик HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TerminalServer\WinStations\RDP-Tcp\PortNumber

понедельник, 4 января 2010 г.

Принудительное обновление wsus

к слову сказать, команда wuauclt /detectnow сильно помогает...
Интересный факт про firefox:
Если набрать about:config в адресной строке, то попадаем в настройки.
Но забавно не это, а то, что после какого-то обновления этот браузер перестал запрашивать пользователя-пароль для ntlm-авторизации на прокси. Вылечилось это установкой параметра network.automatic-ntlm-auth.allow-proxies в false.