Monday, December 21, 2009

How to embed Glade XML files into an executable

Ну, есть 2 способа:

  1. Популярный, когда создается relocatable ELF object, который gcc присобачивает к исполняемому файлу. Портабельность метода сомнительна.
  2. No-brainer, когда Glade'овский XML аккуратно запихивается в 1 строку в header file. Строка получается большая.

Всем понятно, что я использую, разумеется, 2-й способ.

Сперва мы пишем нехитрый ruby скрипт glade2c.rb, который читает XML файл и на stdout пишет вот такое:

const char *glade_gui_ui_embedded = ""
"<?xml version=\"1.0\"?>\n"
"<interface>\n"
"  <requires lib=\"gtk+\" version=\"2.16\"/>\n"
[...]
"</interface>\n"
"";

Что есть обещанная длинная строка.

Далее, мы пишем в какой-то из .h файлов нашего проекта:

extern const char *glade_gui_ui_embedded;

и добавляем в Makefile что-то вроде (пример для GNU Make):

GLADE := foobar.glade
GLADE_EMBD := glade_gui_ui_embedded.c

OBJ += $(patsubst %.c,%.o,$(GLADE_EMBD))

$(GLADE_EMBD): $(GLADE)
        ./glade2c.rb $< > $@

То есть, набирая make glade_gui_ui_embedded.c мы получаем сгенерированный .c файл, где определена переменная glade_gui_ui_embedded и:

  • в коде вызываем gtk_builder_add_from_string() вместо привычной gtk_builder_add_from_file();
  • продолжаем независимо от сборки утюжить свой foobar.glade, который автоматически каждый раз при его изменении готовится для embedding.

Хотя лично мне gcc говорит страшное:

glade_gui_ui_embedded.c:439: warning: string length '20359' is greater than the length '4095' ISO C99 compilers are required to support

но, тем не менее, все отлично работает.

Wednesday, November 25, 2009

iTunes and VMware ThinApp

Попытайтесь представить себе, что вы смотрите как отражается свет от поверхности HDD platter:

66 KB

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

иэ... иэ... иэ... ыыыээаАПЧХИи.

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

Именно так, мне кажется, поступает с диском боготворимая iTunes--по крайней мере, та ее версия что работает (huh?) под Windows.

Старательность и тщательность, с какой iTunes загаживает систему в случайных местах, напоминает усердие жл^H^H провинциала, гребущего себе домой кретиноскоп размером с гаражные ворота, хрусталь и картину "Вечер у березы" в венецианской смальтовой раме с мозаикой.

Можно, разумеется, ставить iTunes в VM, но есть еще один способ дополнительно не засорять вашу неуютную Windows.

Application Virtualization

У VMware, например, есть ThinApp, на выходе из которого можно получить завернутый в 2 файла iTunes package, который:

  • переписывается в любое место обычного пользователя (не требует официально установки и какого-либо дополнительного ПО);
  • iTunes все скачанное держит в том же каталоге, что и сидит само;
  • все записи в реестр, любые каталоги (кроме одного)--запрещены и при этом сам iTunes о таких запретах не имеет ни малейшего понятия;
  • перенос каталога с iTunes на другую машину выглядит как копирование 1 каталога: все настройки и проч. сохраняются;

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

Выглядит интересующий нас каталог вот так:

14 KB

Где 6 сотен мегабайт в файле Bonjour.dat + 3 мегабайта iTunes.exe составляют все что нужно конечному пользователю. Каталог Bonjour--это виртуальная файловая система (и единственное место, куда разрешено писать), что рождается после 1-го запуска iTunes.exe.

cmd.exe, iexplore.exe и regedit.exe нужны только для debugging; если пустить, например, cmd.exe тогда можно смотреть на свою реальную файловую систему, на которую "наложена" виртуальная: какой вид есть то, как себе представляет ситуацию в текущий момент аппликация подготовленная ThinApp'ом.

Например, из такого специального cmd.exe:

c:\>dir "c:\Program Files\iTunes"
 Том в устройстве C не имеет метки.
 Серийный номер тома: DC4B-8921

 Содержимое папки c:\Program Files\iTunes

11/24/2009  11:17 AM    <DIR>          .
11/24/2009  11:17 AM    <DIR>          ..
11/12/2009  04:32 PM            59,083 Acknowledgements.rtf
11/24/2009  11:17 AM    <DIR>          CD Configuration
11/12/2009  04:33 PM           722,160 CDDBControlApple.dll
11/12/2009  04:33 PM           648,480 iPodUpdaterExt.dll
11/12/2009  04:33 PM           111,912 ITDetector.ocx
11/12/2009  04:33 PM        14,769,448 iTunes.dll
11/12/2009  04:33 PM        10,358,048 iTunes.exe
11/24/2009  11:17 AM    <DIR>          iTunes.Resources
11/12/2009  04:33 PM           384,800 iTunesAdmin.dll
11/12/2009  04:33 PM           211,232 iTunesHelper.dll
11/12/2009  04:33 PM           141,600 iTunesHelper.exe
11/24/2009  11:17 AM    <DIR>          iTunesHelper.Resources
11/12/2009  04:33 PM           124,192 iTunesMiniPlayer.dll
11/24/2009  11:17 AM    <DIR>          iTunesMiniPlayer.Resources
11/12/2009  04:33 PM           294,688 iTunesOutlookAddIn.dll
11/12/2009  04:33 PM           292,640 iTunesPhotoProcessor.exe
11/24/2009  11:17 AM    <DIR>          Mozilla Plugins
                              12 файлов     28,118,283 байт
                               7 папок  13,800,427,520 байт свободно

То же, но из "настоящего" cmd:

c:\>dir "c:\Program Files\iTunes"
 Том в устройстве C имеет метку Vista
 Серийный номер тома: 9832-7A28

 Содержимое папки c:\Program Files

Файл не найден

How to create an iTunes package

  1. Выбираете OC, под которую предполагается использовать созданный package и делаете clean install ее в VMware Workstation или еще где.

    iTunes здесь имеет особенность: сделанный package в виртуальной XP потом отказался работать на Vista. Приблизительно такой же эффект можно получить, если накатить на XP (с установленным iTunes) Vista и запустить потом iTunes, которая тяжело ругнется и нагло потребует repair.

    (Btw, собранный package под Windows 7 счастливо заработал на Vista.)

  2. Добавляете в VM виртуальный диск, который не зависит от снапшотов (persistent). То есть у вас VM должен иметь 2 диска: на 1-м сидит Windows, а 2-й пока пустой.

  3. Ставите в виртуальную машину ThinApp. Выключаете VM. Создаете Snapshot.

  4. Включаете VM и запускаете утилиту ThinApp Setup Capture.

  5. Сканируете ей систему.

  6. Ставите iTunes. Setup Capture продолжает висеть в памяти, записывая (на 2-й диск VM, который persistent) весь непростительный harm, который вы наносите этой установкой.

  7. Опять сканируете систему с помощью Setup Capture--уже после инсталляции iTunes.

  8. Делаете Revert to Snapshot.

  9. Build'ите package.

  10. Тестируете его и радуетесь. Если что не работает, идете в п.3 (чаще п.8) и так до просветления.

Вся тонкость находится в п.8: как именно построить package, чтобы он а) был безопасен (не писал, куда ему хочется) б) работал.

Документация у ThinApp достаточно приличная, так что упомяну только ключевые моменты.

  • Будьте внимательны к тому, куда пойдут файлы Virtual File System: в каталог с package или куда-то в c:\users\bob\thinapp. Тут дело вкуса.
  • File System Access ставьте в WriteCopy. С режимом Full плюгавый iTunes не разговаривает.
  • Перед сборкой найдите все файлы ##Attributes.ini, в которых есть строчка DirectoryIsolationMode=Merged и поменяйте ее на DirectoryIsolationMode=WriteCopy (таких файлов будет 3 штуки).

FAQ

Q00:

Package у меня выдает при запуске, что "The registry settings used by iTunes for importing and burning CDs and DVDs are missing". Что делать?

A:Если вы пишите DVD посредством iTunes (зачем?)--расстраивайтесь, иначе--игнорируйте.
Q01:

iTunes запускается через пень-колоду: один раз нормально, а в во второй, процесс itunes.exe набирает в рот памяти и больше ничего не хочет делать.

A:ThinApp имеет утилиту dll_dump.exe, которая покажет PID'ы всех процессов от старых запусков iTunes. Грохните их.

Saturday, November 21, 2009

FreeBSD 8.0 and VMWare Workstation

(For newcomers: есть предыдущие серии.)

Lots of refactoring and cleanup in the code, о которых пишут в news://gmane.comp.emulators.vmware.tools.announce, говорит, с одной стороны, о том что работа кипит, а с другой стороны, как испаряется, вместе с монотонным понижением температуры на улице, мое терпение к open-vm-tools.

Current status

VMware Workstation 6.5.2.
open-vm-tools: 2009.11.17-210370.
% uname -v
FreeBSD 8.0-RC3 #0: Tue Nov 10 07:50:36 UTC 2009 root@almeida.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC

Не работает:

  • hgfs (ядерный модуль, как всегда, вводит guest в панику при попытке монтирования). Это значит, что shared folders не работают.
  • Drag-and-Drop. Несмотря, на его полу-работающее состояние в прошлых open-vm-tools, ничего путного от текущей версии добиться не получилось.

В конце-концов я решил собрать свой вариант порта open-vm-tools, в котором выкинут неработающий мусор и сборка происходит с минимальными dependencies.

В принципе, можно конечно менерно не обновляться (как в FreeBSD 7.2 у меня до сих пор висят open-vm-tools-154848_2 от марта с.г.), но у vmtoolsd в старых версиях, например, течет память и он постепенно пухнет, опухает, тяжело ворочается и становиться неуклюжим.

Что полезного в порту

  • Мелкие утилиты (vmware-toolbox, vmware-rpctool, etc).
  • демон vmtoolsd с plugin'ом для синхронизации времени host<-guest (в комплект входит rc.subr).
  • vmware-user для copy & paste между host и guest. Кроме того, ему запрещено изменять screen resolution в guest (потому что это меня дико раздражало).

Все остальное выкусано. Для сборки нужен только Gtk 2.16. vmware-user должен запускаться где-то в районе ~/.xinitrc.

Скачать порт можно вот тут. Собирать, как обычно, а) распаковав архив куда глаза глядят и б) набрав:

# cd open-vm-tools-minimum
# make install clean

А по окончанию инсталляции, добавить в /etc/rc.conf:

vmware_vmtoolsd_enable=YES

и запустить демон vmtoolsd:

# /usr/local/etc/rc.d/vmware_vmtoolsd start

Btw, если у вас установлены проприетарные vmware tools или версия open-vm-tools из официальных портов FreeBSD, тогда удалите их сперва перед установкой этого порта и вычистите память от загруженных старых ядерных модулей и демонов.

Xorg 7.4

Т.к. драйверы мыши и видеокарты для VMware давно идут вместе c Xorg и есть в портах FreeBSD (x11-drivers/xf86-input-vmmouse и x11-drivers/xf86-video-vmware), все что тут можно посоветовать это:

  1. не давайте свежим иксам говорить с HAL касательно мыши--добавьте в /etc/X11/xorg.conf в секцию ServerLayout:

    Option   "AutoAddDevices" "false"
    

    и в секцию InputDevice для мыши:

    Driver   "vmmouse"
    

    и в /etc/rc.conf:

    moused_port=/dev/psm0
    moused_type=auto
    moused_enable=YES
    moused_flags="-r high"
    

    (после чего наберите:

    # /etc/rc.d/moused restart
    

    в cons25 у вас должен появится работающий курсор, иначе иксы без HAL не поймут где ваша мышь)

    Если вы этого не сделаете--ожидайте хаотчески скачущего курсора и паршивого настроения.

  2. убедитесь, что в секции Device в /etc/X11/xorg.conf стоит правильный драйвер:

    Driver   "vmware"
    
  3. если screen resolution в вашего лэптопа 1280x800, добавьте в секцию Monitor в /etc/X11/xorg.conf:

    HorizSync    1-10000
    VertRefresh  1-10000
    Modeline     "1280x800"  70.00   1280 1312 1344 1376  800 801 804 850
    
  4. поглядеть на минимальный готовый xorg.conf для Xorg 7.4 под FreeBSD 8 можно вот здесь.

(2009-11-22 Update)

Как оказалось, бегемот vmware-user кое как разрешает работать в Unity Mode (a feature that allows seamless integration of applications with the host desktop), ежели у вас имеется Workstation 6.5+. В порт добавилась 1 опция WITH_UNITY. Значит, набирая:

# make WITH_UNITY=1 install clean

можно (запустив vmware-user в иксах) кликнуть в меню Workstation View->Unity и наблюдать чудеса.

Правда, при таком режиме сборки порта, придется забыть про выковыривания из vmware-user пакости в виде измененияя screen resolution в guest, так что мой совет: соберайте без Unity--работает оно в связке Vista <-> FreeLSD 8 отвратительно медленно. Но выглядит, конечно, солидно. Но все-таки медленно. Но зато солидно.

Network and Sound

Тут новостей нет. Без всяких твиков с .vmx-файлами, FreeBSD в Workstation 6.5+ сразу видит сетевую карту как эмо, то есть я хочу сказать, как em0:

% ifconfig em0
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM>
        ether 00:0c:29:a0:8d:b7
        inet 192.168.8.133 netmask 0xffffff00 broadcast 192.168.8.255
        media: Ethernet autoselect (1000baseT <full-duplex>)
        status: active

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

Звук, как и раньше, включается посредством:

# kldload snd_es137x

Пожалуй, на сегодня таки все.

Saturday, November 7, 2009

Quotes from Apprenticeship of Patterns

The book contains 35 apprenticeship patterns (see below), mostly suited for young and/or inexperienced programmers. 8 of them appears to be more or less useful for me, or speaking by the card, 8 of 35 patterns that are worth reading.

N.B.

An apprenticeship pattern attempts to offer guidance to someone working with the craft model on the ways in which they can improve the progress of their career.

Expose Your Ignorance

Show the people who are depending on you that the learning process is part of delivering software. Let them see you grow.

[...]

Software craftsmen build their reputations through strong relationships with their clients and colleagues. Conceding to unspoken pressures and telling people what they want to hear is not a good way to build strong relationships. Tell people the truth. Let them know that you're starting to understand what they want and you're in the process of learning how to give it to them. If you reassure them, reassure them with your ability to learn, not by pretending to know something you don't. In this way, your reputation will be built upon your learning ability rather than what you already know.

The Deep End

Jump in at the deep end. Waiting until you're ready can become a recipe for never doing a thing. So when you're offered a high-profile role or a difficult problem, grasp it with both hands. Growth only happens by taking on the scary jobs and doing things that stretch you.

A Different Road

[...] Ade's mentor [...] described how he went off to a Greek island for six months to become a windsurfing instructor after his first IT job. He found that he liked teaching windsurfing, but it wasn't entirely satisfying because he never got to use his brain. Afterward, it was hard for him to get back into the industry because "most HR people in big companies didn't like it."

Be the Worst

Surround yourself with developers who are better than you. Find a stronger team where you are the weakest member and have room to grow.

[...] as the weakest member of the team, you should be working harder than anyone else. This is because the goal is not to stay the weakest, but to start at the bottom and work your way up.

Reflect As You Work

[...] it is quite easy to repeat the same year of experience 10 times without making significant progress in your abilities. In fact, this sometimes can turn into anti-experience: the phenomenon where every additional year or experience merely reinforces the bad habits you have picked up. This is why your goal should be to become skilled rather than experienced.

Record What You Learn

Try to avoid falling into the trap of just writing down your lessons and forgetting them. Your notebook, blog, or wiki should be a nursery, not a graveyard lessons should be born from this record, rather than going there to die.

Create Feedback Loops

[...] the less skilled you are, the worse you are at assessing the skills of yourself and others.

Dig Deeper

One thing you will learn from trying to apply this pattern is that gaining deep knowledge is hard. This is why most people's knowledge of the computer science that supports software development is a mile wide and an inch thick. It is easier and often more profitable to depend on other people's knowledge of the fundamentals than to spend the extra effort to acquire it yourself. You can tell yourself that you can always learn it when you need it; however, when that day comes you'll need to know everything by the end of the week, but it will take a month just to learn all the prerequisites.

Wednesday, October 28, 2009

SparkBuild, GNU make and Tcl

Eric Melski из Электрической Тучи, вчера написал об утилите, которая подменяет собою gmake и генерирует (в процессе сборки) XML файл, в котором можно потом обнаружить всякую интересную статистику.

Утилита называется SparkBuild и она бесплатна. Не open source, но ее можно свободно использовать для коммерческих проектов.

SparkBuild состоит из 2-х главных компонентов:

  • emake, который (как обещают) и есть drop-in замена GNU Make.
  • sbinsight, который парсит output из emake и рисует графики, таблички и проч.

emake написана на C++ и Boost; sbinsight--это Tcl/Tk 8.5+ (симпатичные виджеты из 8.5 выдают себя моментально). Как используется Тикль в sbinsight--вопрос интересный. Судя по наличию tclKitInit и Mk4tcl в потрохах скомпилированного sbinsight, это разновидность Starpack'а.

В качестве теста, я попробовал собрать Texinfo 4.13 с помощью SparkBuild. Хотя последний распространяется только для Windows и лайнукса, у меня все чудесно заработало на FreeBSD 7.2 и:

% pkg_info | grep ^linux
linux-f8-expat-2.0.1_1 Linux/i386 binary port of Expat XML-parsing library (Linux
linux-f8-fontconfig-2.4.2_1 An XML-based font configuration API for X Windows (Linux Fe
linux-f8-xorg-libs-7.3_3 Xorg libraries (Linux Fedora 8)
linux_base-f8-8_11  Base set of packages needed in Linux mode (for i386/amd64)

Итак.

% pwd
/home/alex/ports/texinfo
% make configure
[...]

% cd work/texinfo-4.13

Теперь наступает самое интересное. Вместо пускания gmake, набираем:

% emake --emake-annodetail=basic,waiting,env | tee anno.xml

И вместо привычного make output, на stdout вылазит гора XML'а, и после конца сборки у нас появляется файл:

% ls -l anno.xml
-rw-r--r--  1 alex  wheel  367670 Oct 28 15:22 anno.xml

Желаю вам успеха в его чтении глазами. В поставке SparkBuild есть Tcl-утилитка anno2log, которая выковыривает из anno.xml то, что писал бы на stdout gmake. То есть, в теории, можно пустить emake вот так:

% emake --emake-annodetail=basic,waiting,env | tee anno.xml | anno2log

На практике, текущая версия anno2log буферизирует stdout, поэтому результат видно только по окончанию сборки.

Чтобы полюбоваться на статистику (то, ради чего), печатаем:

% sbinsight anno.xml &
24 KB

Информация о конкретной target:

7 KB

График симуляции сборки texinfo на кластере:

3 KB

Кластерная сборка, естественно и к несчастью, в SparkBuild не входит, потому что она есть главный продукт Электрической Тучи имени Джона Остераута.

Wednesday, October 14, 2009

Quotes from Coders at Work

4 of 15 interview are good, 8 are brilliant, 1 is totally useless and 2 are boring.

Person Rating
Jamie Zawinski 10
Brad Fitzpatrick 10
Douglas Crockford 9
Brendan Eich 9
Joshua Bloch 8
Joe Armstrong 9
Simon Peyton Jones 5
Peter Norvig 10
Guy Steele 10
Dan Ingalls 6
L Peter Deutsch 10
Ken Thompson 10
Fran Allen 2
Bernie Cosell 10
Donald Knuth 10

Jamie Zawinski

So I write a new [Emacs byte] compiler and Stallman's response is, "I see no need for this change." And I'm like, "What are you talking about? It generates way faster code." Then his next response is, "Okay, uh, send me a diff and explain each line you changed." "Well, I didn't do that--I rewrote it because the old one was crap." That was not OK. The only reason it ever got folded in was because I released it and thousands of people started using it and they loved it and they nagged him for two years and finally he put it in because he was tired of being nagged about it.

[...]

There was actually a point, early on in Netscape, where part of our build process involved running "emacs -batch" to manipulate some file. No one really appreciated that.

Brad Fitzpatrick

Before I had any official job, I got some hosting account. I got kicked off of AOL for writing bots, flooding their chat rooms, and just being annoying. [...] I also wrote a bot to flood their online form to send you a CD. I used every variation of my name, because I didn't want their duplicate suppression to only send me one CD, because they had those 100 free hours, or 5,000 free hours. I submitted this form a couple thousand times and for a week or so the postman would be coming with bundles of CDs wrapped up.

My mom was like, "Damn it, Brad, you're going to get in trouble." I was like, "Eh their fucking fault, right?" Then one day I get a phone call and I actually picked up the phone, which I normally didn't, and it was someone from AOL. They were just screaming at me. "Stop sending us all these form submissions!" I'm not normally this quick and clever, but I just yelled back, "Why are you sending me all this crap? Every day the postman comes! He's dropping off all these CDs!" They're like, "We're so sorry, sir. It won't happen again." Then I used all those and I decorated my dorm room in college with them. I actually still have them in a box in the garage.

Douglas Crockford

I've managed projects where we're up against a deadline and we had people saying, "Yeah, I'm almost done," and then you get the code, and there's nothing there, or it's crap, or whatever, and they're nowhere close to done. In management, those are the experiences you hate the most and I think code reading is the best way of not getting trapped like that.

[...] it [code reading] requires a lot of trust on the part of the team members so there have to be clear rules as to what's in bounds and what's not. If you had a dysfunctional team, you don't want to be doing this, because they'll tear themselves apart. And if you have a dysfunctional team and you're not aware of it, this will reveal it pretty quickly. There's a lot that you can learn, a lot that's revealed by this process. It feels unnatural at first, although once you get into the rhythm of it, it feels extremely natural.

Brendan Eich

I'm secure enough to think I could go do something that was a fine sky castle for myself, but I'm realist enough to know that it would be only for myself and probably not fine for other people. And what's the point? "If I'm only for myself", you know, Hillel the elder, "what am I?" I am not JavaScript. In the early days, it was such a rush job and it was buggy and then there was some Usenet post Jamie Zawinski forwarded me. He said, "They're calling your baby ugly." I have real kids now; I don't have to worry about that.

Joe Armstrong

I think the lack of reusability comes in object-oriented languages, not in functional languages. Because the problem with object-oriented languages is they've got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.

[...]

Are you driven by the problems or by the solutions? I tend to favor the people who say, "I've got this really interesting problem." Then you ask, "What was the most fun project you ever wrote; show me the code for this stuff. How would you solve this problem?" I'm not so hung up on what they know about language X or Y. From what I've seen of programmers, they're either good at all languages or good at none. The guy who s a good C programmer will be good at Erlang--it's an incredibly good predictor.

Peter Norvig

They [NASA] aren't software guys. They say, "Software is this necessary evil. Straight line code, I can sort of understand; if it's got a loop in it, that's kind of iffy. Then if there's a branch statement inside the loop, ooooh, that's getting away from what I can solve with a differential equation in control theory." So they're distrustful.

L Peter Deutsch

So basically that's what I did [Ghostscript]--data structures first. Rough division into modules. My belief is still, if you get the data structures and their invariants right, most of the code will just kind of write itself.

[...]

Seibel: I think Larry Wall described it [Python] as a bowl of oatmeal with fingernail clippings in it.

Deutsch: Well, my description of Perl is something that looks like it came out of the wrong end of a dog. I think Larry Wall has a lot of nerve talking about language design--Perl is an abomination as a language.

Ken Thompson

I've never been a lover of existing code. Code by itself almost rots and it's gotta be rewritten. Even when nothing has changed, for some reason it rots.

[...]

Seibel: I know Google has a policy where every new employee has to get checked out on languages before they're allowed to check code in. Which means you had to get checked out on C.

Thompson: Yeah, I haven't been.

Seibel: You haven't been! You're not allowed to check in code?

Thompson: I'm not allowed to check in code, no.

Seibel: You just haven't gotten around to it, or you have philosophical objections to the Google coding standard?

Thompson: I just haven't done it. I've so far found no need to.

[...]

I would try out the language as it was being developed and make comments on it. It was part of the work atmosphere there [AT&T]. And you'd write something and then the next day it [C++] wouldn't work because the language changed. It was very unstable for a very long period of time. At some point I said, no, no more.

In an interview I said exactly that, that I didn't use it just because it wouldn't stay still for two days in a row. When Stroustrup read the interview he came screaming into my room about how I was undermining him and what I said mattered and I said it was a bad language. I never said it was a bad language. On and on and on. Since then I kind of avoid that kind of stuff.

Bernie Cosell

Programmers are the worst optimizers in the world. They always optimize the part of the code that's most interesting to optimize, and almost never get the part of the code that actually needs optimization. So you get these little nuts of very difficult code that have no point.

Donald Knuth

Like in the parts that I'm writing now, I'm starting out with stuff that's in math journals that is written in jargon that I wouldn't expect very many programmers to ever learn, and I'm trying to dejargonize it to the point where I can at least understand it. I try to give the key ideas and I try to simplify them the best I can, but then what happens is every five pages of my book is somebody's career.

[...]

The first rule of writing is to understand your audience--the better you know your reader the better you can write, of course. The second rule, for technical writing, is say everything twice in complementary ways so that the person who's reading it has a chance to put the ideas into his or her brain in ways that reinforce each other.

[...]

The problem is that coding isn't fun if all you can do is call things out of a library, if you can't write the library yourself. If the job of coding is just to be finding the right combination of parameters, that does fairly obvious things, then who'd want to go into that as a career?

[...]

We already talked about literate programming--that's a radical departure, that I'm viewing myself as an expositor rather than trying to just put together the right instructions. Dijkstra came out with that same evolution. In the end his programs were even more literate than mine in the sense that they didn't even go into the machine. They were only literate.

[...]

I always try things that are at my limit. If I had to go back and write those kinds of programs again, the easier ones, I wouldn't make so many mistakes. But now that I know some more, I'm trying to write harder stuff. So I make mistakes because I'm always operating at my limit. If I only stay in comfortable territory all the time, that's not so much fun.

[...]

So inevitably we're going to have bugs unless we decide we're never going to write anything that stretches our capabilities.

Sunday, October 4, 2009

time value too large/small to represent

После перезагрузки виртуальной машины, в жерле которой мирно крутятся некоторые Tcl CGI скрипты, эти самые скрипты внезапно перестали работать, выплевывая вот такое сообщение:

time value too large/small to represent
    while executing
"::tcl::clock::ConvertLocalToUTC $date[set date {}]  $TZData($timeZone)  $changeover"
    (procedure "::tcl::clock::scanproc'%A, %d %B %Y, %T'c" line 33)

Это была реакция на самую невинную комманду:

clock scan {Monday, 28 September 2009, 22:11:00} -format {%A, %d %B %Y, %T}

Конечно, она замечательно исполняется, если ее попробывать, например в tkcon. В же чем проблема?

Как оказалось, environment variable TZ при старте Apache (еще до login prompt в FreeBSD) не успевает быть установленной--то есть Apache ее inherit, если она есть. А для этого нужно:

# setenv TZ Europe/Kiev
# /usr/local/etc/rc.d/apache22 restart

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

Или, можно, на всякий случай, всегда устанавливать TZ руками в Tcl-скрипте:

set env(TZ) Europe/Kiev

Или, сделать вот такой симлинк:

# ln -s /usr/share/zoneinfo/Europe/Kiev /etc/localtime

Последний способ, по идее, есть самый универсальный.

Monday, July 13, 2009

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

Комментаторы в блоге Торвальдса -- это люди, которые тяжело страдают от отсутствия собственной персоны на superuser.com и поэтому ведут себя так, как будто Линус -- не Линус вовсе, а какая-то девочка из жиже. То есть, им очень хочется что-то посоветовать, но некому.

Какого диаметра нужно иметь сквозное отверстие в голове, чтобы рассказывать Торвальдсу о том, что можно:

  • в Linksys поставить OpenWRT to teach your router some fancy tricks;
  • проверить скорость соединения на speedtest.net;
  • поставить Debian на старый компьютер бабушки и использовать его как router.

Думаю, надо еще побежать напечатать как настраивать firewall, и объяснить на всякий случай, что лайнукс -- это не операционная система, а ядро, а не то пропадет несчастный блоггер Линус почем зря и погрязнет в своем неведении, как Эмпедокл во вражде как причине бытия.

Sunday, July 12, 2009

Июльские новости

Вышла новая версия uraniacast 0.14. Теперь с ней можно автоматически обрабатывать загруженные файлы с подкастов (самое очевидное тут применение: изменение id3v1/id3v2 tags для mp3 и преобразование из ogg в mp3). В остальных виденных мною podcatcher'ов пост обработка либо отсутствует вообще, либо доступна только та, какую предусмотрел автор podcatcher'а (что является, разумеется, отвратительным виндоморонством).

В глюкале uraniacast (арт.нумер 0.14) все сделано иначе. После всех загруженных файлов имеется список тех, кои подлежат внешнему treatment. Обработка опциональна и настраивается для каждой feed индивидуально. В простейшем случаи, внешний обработчик -- это sh-скрипт, возможные параметры которого вы выбираете сами (как? читайте документацию). То есть, сбыточность того, что конкретно можно автоматически сделать с полученным файлом ограничиваются только кривыми руками пользователя.

Так.

Чешутся написать руки об еще какой нибудь ерунде. Вот к примеру, Firefox 3.5. Не понимаю злобных критиков. Хороший релиз. Помню я как-то отчаянно накатал возмущенный пост, как якобы нельзя добиться в Location (URL) Bar fixed-width font в Firefox >= 3. На самом деле можно.

Во-первых, нужно сначала установить default font для всех gtk программ:

% cat /usr/local/share/themes/Raleigh/gtk-2.0/gtkrc
style "user-font" {
        font_name = "Helvetica 9"
}

widget_class "*" style "user-font"

gtk-font-name="Helvetica 9"

Во-вторых, добавить вот это в userChrome.css:

#urlbar {
        font-family: lucidatypewriter !important;
        font-size: 9pt !important;
}

60 KB

У меня тут грохотать начало за окном: будет короткий ливень.

Thursday, June 25, 2009

Жара доводит до ручки

Удивлялся и пялился, как в афишу коза, почему вместо ожидаемой lowercase строки, переменная t становится заполнена непечатным символом 0x01 (SOH):

int cmd_type(const char *raw)
{
    if (raw == NULL) return -1;

    char t[BUFSIZ];
    strncpy(t, raw, sizeof(t)-1);
    t[sizeof(t)-1] = '\0';

    char *p = t;
    while (*p) {
        *p = islower(*p);
        ++p;
    }

    if (strncmp(t, "help", 4) == 0) return P_CMD_HELP;
    ...
}

Распознать наконец, что вместо tolower написал islower понадобилось минут 30. Проклятое киевское лето.

Saturday, June 6, 2009

Broken DNS forwarding in VMware Workstation 6.5.2 with NAT

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

Сначала я подумал что мой Bind в Vista совершил харакири, но это оказалось неправдой -- в Windows резолвер общался с локальным DNS-сервером успешно как и раньше. Затем я решил что вчера совершил что-то настолько глупое с virtual network switches, что утром completely incapable это вспомнить. Короче говоря я, кхм, позорно перезагрузился и о чудо -- UTP пакеты начали бегать в машинах VMware по 53-му порту как вчера.

Успокоившись, я хлопнул крышкой и довольный пошел по своим делам. Если кто-то хочет сделать любого человека абсолютно счастливым -- незаметно сломайте что-нибудь, что раньше у него всегда работало, выждете немного, пока он тяжело страдает, а потом почините ему сломанное. Или сделайте вид, что починили.

Вечером того же дня, который грозил начаться столь неудачно, yours truly smug вернулся домой, открыл лэптоп и... Не знаю как вы догадались, но обнаружил внутри виртуальной машины неспособным себя забрать почту: DNS не работал.

Черт, -- сказал я. То есть, по правде говоря, сказал что-то гораздо хуже.

Маленькое исследование с tcpdump'ом со стороны FreeBSD и с Wireshark'ом со стороны Vista показало что запрос со стороны резолвера доходит до сервера вполне успешно, формируемый ответ сервера идет на вход VMnet8 switch, но отфутболивается от него с ошибкой ICMP host unreachable, а резолвер в guest отваливается по таймауту и отчаянно плачет no servers could be reached.

Самое интересно в этой истории то, что остальные ip-пакеты по любому другому порту ходят как не в чем не бывало и если вы принудительно отключите резолвинг адресов в вашем http proxy, то таки сможете заставить броузер сходить на википидия, например. Если вы помните хотя бы один из ее ip-адресов, hehe. Или даже так: набираем в Vista "nslookup en.wikipedia.org" и используем вручную ответ в спрятанной от пагубного влияния всех DNS на свете (благодаря VMnet8) виртуальной машине. Можно даже звонить из своего кабинета секретарше и спрашивать "Сюзанна, какой там адрес у serverfault.com? Что-что? 69.59.196.213? 2... После последней точки? 212? Да? Спасибо. Кстати, если придет Самоподгаслов за деньгами -- скажи что я буду в его распоряжении за..., нет лучше на следующей неделе.".

Продолжая маленькое исследование и тщетно излопатя весь гугл мы имеем следующее: DNS отрубается после n минут лежания лэптопа в suspend. То есть, если у вас VMware Workstation вертится на обычном desktop pc, который выключается раз в 6 месяцев: вы можете этой проблемы никогда не заметить и сидеть как император Ян-ди в своем Янчжоу, кушать персики, жевать рябчиков и полностью игнорировать все происходящее.

В обратном случаи, единственно решение тут видится в перезапуске (нет, не всей Windows) сервиса VMware NAT Service каждый раз как Windows протирает глаза после suspend. Возникает естественный вопрос: как автоматизировать? Под FreeBSD или Linux такой предмет даже не выносился на повестку дня, настолько решение всем очевидно своею простотой. В Windows мы имеет очередной геморрой.

Можно написать скрипт на чем заблагорассудится, который будет а) в бесконечном цикле ждать когда Windows говорит, что проснулась и б) вызывать 2 команды:

sc stop "VMware NAT Service"
sc start "VMware NAT Service"

Так? Так, но пускать его придется под Administrator -- если вы просто запихнете вызов скрипта в автозагрузку HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run -- это поможет плохо: либо придется сначала загружаться в аккаутн Administrator'ра, а потом в свой, либо найти утилиту (такие есть), которая позволить оформить вызов скрипта под root'ом без ввода каждый раз пароля.

Обойти это можно написанием daemon'а под Windows (сервиса в их булыжной терминологии), который можно стартовать и останавливать в services.msc. Я сделал иначе: Microsoft имеет wrapper-утилитку srvany.exe, которая может разговаривать с Service Control Manager самостоятельно, позволяя таким образом запускать любую программу как Windows service и не мучиться с тем API.

Готовый WSH-скрипт vmware-nat-fix.js лежит тут. Для его работы нужна srvany.exe, которую можно совершенно свободно взять из Windows Server 2003 Resource Kit Tools.

Используется фикс так: скрипт ложится в любое приличное место и сперва тестируется (под администратором) командой:

>vmware-nat-fix.js /d

Если вам показало окошко с надписью Successfully reloaded "VMware NAT Service" daemon, тогда регистрируйте скрипт как сервис вот такой командой (тоже под администратором):

>vmware-nat-fix.js /install

Если все идет хорошо, получите окошко с надписью Successfully added "VMware NAT Fix" service, иначе -- с ошибкой, где будет написано причину (например, что у вас на то не было прав).

Теперь можно пойти в services.msc чтобы запустить daemon или набрать sc start "VMware NAT Fix", если никуда идти желания нету. Когда daemon начнет тихо жужжать, тестируйте его посредством входа в suspend/hibernate и выхода оттуда. У меня VMnet8 после просыпания Vista и щелчка от vmware-nat-fix.js начинает по-человечески работать примерно через секунд 40 (остается невыясненным, почему не сразу).

Если вы решите перетащить vmware-nat-fix.js в другое приличное место, наберите под администратором:

>vmware-nat-fix.js /uninstall
>vmware-nat-fix.js /install

Чтобы обновить записи в реестре.

Local DNS (2009/07/17 update)

Далее, если вы используете локальный, например, Bind для обзывания виртуальных машин, то будьте внимательны, когда и в какой момент Vista к нему обращается. После множества утомительных манипуляций, единственно работающей конфигурацией (всегда и независимо от состояния и количества (включая 0) подключенных сетей к лэптопу), получилась такая, при которой выполнялись 2 условия:

  • прописывание своего, локального DNS-сервера в свойства каждого (а нет только VMware NAT) рабочего network adapter'а. Иначе Vista будет помнить какой был последний DNS-сервер рабочим и с козлиным упрямством слать запросы к нему, даже когда вы давно вышли за пределы той сети с тем сервером.

  • занесение в %SystemRoot%\System32\drivers\etc\resolv.conf привычного nameserver 127.0.0.1.

Wednesday, May 6, 2009

FreeBSD 7.2 and VMWare Workstation

(For newcomers: есть предыдущие серии.)

Иногда мне кажется, что FreeBSD порт open-vm-tools больше всего похож на стационарный двигатель слесаря-интеллигента Полесова -- все выглядит как настоящее, но не работает.

Файловая система hgfs, для которой хотя написаны и ядерный модуль и монтировщик, все еще являет собой work in progress. Шаг вперед по сравнению с прошлой версией по величине своей таков, что если раньше при попытке монтирования shared folder вы тот час же могли любоваться паникой ядра, то теперь mount_vmhgfs вместе с vmhgfs.ko тщательно стараются соблюдать приличия, в которые вы верите до тех самых пор, пока не пытаетесь что-то прочесть из mount point. Не самый худший вариант, беря во внимание вспоминания о том, что именно раньше в припадке истерии вытворял vmhgfs.ko.

Потери

vmblock.ko, который счастливо перезагружал FreeBSD в прошлом, продолжает радостно делать это в настоящем. Хорошая новость тут состоит в том, что об этом модуле можно забыть, т.к. теперь реализация файловой системы VMBlock переписана с помощью FUSE library. Это означает, что мы сможем, наконец, получить сомнительно долгожданный host<->guest Drag & Drop. Если проявим терпение.

vmware-guestd, который верой и правдой честно служил нам все эти годы, уходит на пенсию. Вместо него мы получаем демон vmtoolsd, который с помощью plugins может в том числе и, синхронизировать время.

В путь

Розсуваєш чіпке гілля чагарників -- і перед тобою несподівано виблискує вода.
-- Михайло Коцюбинський.

(Всяческие предварительные вещи, такие как выбор типа виртуальной сетевой карты или общие места о настройке Xorg -- см. в 1-м эпизоде.)

Последней вещью на свете, которой нужно доверять в нашем случаи -- это подсказке порта, что куда прописать, чтобы якобы получить. На самом деле, после установки open-vm-tools, сделайте следующее:

  1. Убедитесь, что sysctl переменная vfs.usermount имеет значение 1 и пользователь под которым вы работаете состоит в группе operator.

  2. Добавьте в /etc/rc.conf:

    fusefs_enable=YES
    vmware_guestd_enable=NO
    vmware_guest_vmmemctl_enable=YES
    

    и напечатайте:

    # /usr/local/etc/rc.d/vmware-kmod start
    # /usr/local/etc/rc.d/fusefs start
    
  3. Теперь, для запуска vmtoolsd, нахмурьте лоб посерьезнее и наберите:

    # vmtoolsd -n vmsvc -p /usr/local/lib/open-vm-tools/plugins/vmsvc \
        -b /var/run/vmtoolsd.pid
    

    Так вы запустите его с сервисом vmsvc, в котором есть такой полезный plugin, как timeSync. Разумеется, ручное добавление в .vmx файл строчки tools.syncTime = "TRUE" для корректной работы никто не отменял, хотя аналогичного можно добиться запустив:

    % vmware-toolbox-cmd timesync enable

    Если вас беспокоит насколько новый способ синхронизации времени более прожорлив (или наоборот), то удалите ненужные (впрочем, пока этого не делайте) plugins из /usr/local/lib/open-vm-tools/plugins/vmsvc, оставьте только libtimeSync.so вместе c libguestInfo.so и посмотрите что вышло:

    33805 root          1  44    0 20660K  3820K select   0:00  0.00% vmtoolsd

    против старого доброго vmware-guestd:

    33854 root          1  49    0 18124K  2480K select   0:00  0.00% vmware-guestd

    Руками, конечно, запускать каждый раз vmtoolsd довольно скучно, поэтому возьмите себе rc.subr скрипт, положите его в /usr/local/etc/rc.d и добавьте строчку vmtoolsd_enable=YES в /etc/rc.conf.

  4. Если вы установили порт open-vm-tools-nox11 вместо open-vm-tools, можете дальше не читать, иначе продолжайте движение. Помните, что vmblock.ko наконец-то considered harmful? Вместо его кривых рук, нам нужно самим подмонтировать VMBlock file system в некотором укромном месте:

    % mkdir /tmp/vmblock-fuse
    % chmod 777 /tmp/vmblock-fuse
    % vmware-vmblock-fuse /tmp/vmblock-fuse
    

    Эти команды нужно выполнять от regular user, не root, иначе пропадает смысл. Недостаток такого монтирования конкретным пользователем проявится как только другой пользователь попытается посмотреть содержимое /tmp/vmblock-fuse и очень огорчится, потому что у него не окажется на это никаких прав. Это значит, что либо каждому пользователю придется вызывать vmware-vmblock-fuse с каким-нибудь другим каталогом в качестве параметра, либо сделать монтирование 1 раз root'ом с опцией allow_other. Кто помнит, в отличие от Linux, во FreeLSD указывать allow_other для всех FUSE file systems может только root. С /etc/fstab тут у вас ничего не получится, поэтому возьмите rc.subr скрипт, пропишите в /etc/rc.conf vmblock_enable=YES и, немного погодя, убедитесь что regular user может читать /tmp/vmblock-fuse.

  5. Пускайте иксы. (Для Xorg 7.4+ обязательно просмотрите раздел об X11 в Handbook.)

  6. В теории, демон vmtoolsd с сервисом vmusr, должен на вечные времена заменить собою vmware-user и обеспечивать copy/paste между host и guest, управлять Drag & Drop, дружить с VIX API и проч. Одновременно пускать vmware-user и vmtoolsd-с-сервисом-vmusr строжайше запрещено, так что между ими двумя придется выбирать себе только одного компаньона. Если вас не интересует Drag & Drop -- берите vmtoolsd, но этот путь вы прошагаете без меня, поэтому заранее желаю удачи.

    Раньше, в темные времена vmblock.ko, то что мы проделали в п.4 мог исполнять только root, поэтому существовала suid'ная утилита vmware-user-suid-wrapper, которая загружала ядерный модуль vmblock, монтировала vmblock file system, открывала некоторый (о нем ниже) файловый дескриптор для создание/удаления блоков (файлов), делала drop privileges и стартовала vmware-user от обычного пользователя.

    Весь ужасный magic в доставании файлового дескриптора VMBlock file system, заключается в знании на каком файле сделать open(2) с O_WRONLY mode. Если мы назначили точку монтирования в п.4 как /tmp/vmblock-fuse, то искомый файл (при успешном монтировании) будет /tmp/vmblock-fuse/dev. Число полученное при успешном вызове open(2) мы должны передать программе vmware-user в параметре --blockFd. Собственно говоря, именно так мы точно сэмулируем работу vmware-user-suid-wrapper:

    % vmware-user --blockFd `vmware-getblockid /tmp/vmblock-fuse/dev`

    vmware-getblockid -- это простейшая программка, которую вы забираете вот отсюда, компилируете у себя посредством "cc -o vmware-getblockid.c vmware-getblockid" и ложите результат куда-нибудь в PATH.

    Btw, vmtoolsd тоже имеет опцию --blockFd, но как бы вам не хотелось изобразить улыбку чеширского кота, посмотрите сначала в файл services/vmtoolsd/cmdLine.c (из tarball'а с исходным кодом open-vm-tools):

    GOptionEntry clOptions[] = {
    ...
          { "blockFd", '\0', 0, G_OPTION_ARG_INT, &state->ctx.blockFD,
             N_("File descriptor for the VMware blocking fs."), N_("fd") },
    ...
    }
    
    #if !defined(G_PLATFORM_WIN32)
       state->ctx.blockFD = -1;
    #endif
    

    Короче говоря, с vmtoolsd тут каши не сваришь.

  7. Самое время попробовать Drag & Drop and copy/paste. Со вторым у меня проблем не оказалось, а DnD почему-то заработал только из guest в host, обратное перетаскивание сопровождалось вот таким возмущением:

    DnD_RemoveBlock: Cannot delete block on /tmp/VMwareDnD/4cc8fb08/ \
        (Operation not supported)
    DnDRpcInDataFinishCB: could not remove block on /tmp/VMwareDnD/4cc8fb08/
    

    То есть, файл из host оставался лежать в /tmp/VMwareDnD/4cc8fb08, а host в лице Vista на несколько минут запрещал сам себе DnD с VMWare, делая соответствующие внушения тихим голосом.

    Может это было потому, что на тестовой виртуальной машине с FreeBSD 7.2-RC2 с Xorg 7.4 стартовал только twm, а Gnome или KDE отсутствовали. Перетягивание из FreeBSD в Vista файлов я тестировал каким-то x11-fm/emelfm2 -- больше ни для чего мне этот файловый менеджер не нужен.

  8. vmware-user делает одну нехорошую вещь и портит всю курицу в горшке: пытается отвечать VMWare на изменение размеров окна виртуальной машины. Такое поведение напоминает эпитет Geminus у римского Януса. Побороть это нравственное двуличие инструмента как помощника, можно только выкусыванием из vmware-user вызовов Resolution_foobar() в исходном коде.

Urbi et orbi

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

Если вам совсем нечем заняться, сделайте grep в tarball'е c open-vm-tools на функцию RpcOut_sendOne и посмотрите на утилиту vmware-rpctool. Например:

% vmware-rpctool vmx.capability.dnd_version
2

Терпения внимательно рассматривать plugins для vmtoolsd у меня на сегодня закончилось, хотя VIX -- это, вероятно, самое интересное, ради чего стоит вообще так страдать с open-vm-tools. Правда, для самых простых операций, таких как start/suspend никакие VMWare tools внутри виртуальной машины не требуются, а запуск в guest программ посредством VIX API из host есть не более чем детская игрушка, при наличии работающего expect. На этой апофегме, мы, пожалуй, и закончим.

Tuesday, April 7, 2009

Исторический cvsup

Вот сидишь, щелкаешь клювом, и не замечаешь какие вехи проходят мимо. Если вам в ближайшие месяца 2 нужно будет захайрить сисадмина FreeBSD, так вот вам простой тест как отделить спившегося от скуки толстого обормота с торчащими волосами из ушей от минимально адекватного персонажа: спросите кандидата как настроить (для любых целей) pppd.

Как Транзимена изменилась ныне!
Лежит, как щит серебрянный, светла.
Кругом покой. Лишь мирнный плуг в долине
Земле наносит раны без числа.
Тем, где лежали густо их тела,
Разросся лес. И лишь одна примета
Того, что кровь когда-то здесь текла,
Осталась для забывчивого света:
Ручей, журчащий здесь, зовется Сангвинетто.
-- Джордж Гордон Байрон, Паломничество Чайльд Гарольда, IV, 65.

Только не нужно театрально хвататься за сердце: ppp(8) остается, а вместо ушедшего в каталог Attic pppd, сходите на mpd.sourceforge.net и почитайте как весело вы будете жить дальше.

Собирая мир 5 апреля для 8.0-CURRENT у меня все еще было на месте, а сегодня:

pts/0:/usr/src# csup -L 1 /root/standard-supfile
Connected to 212.42.64.9
Updating collection src-all/cvs
[...]
 Delete src/share/man/man4/ppp.4
 Delete src/share/man/man4/sl.4
[...]
 Delete src/sys/net/bsd_comp.c
 Delete src/sys/net/if_ppp.c
 Delete src/sys/net/if_ppp.h
 Delete src/sys/net/if_pppvar.h
 Delete src/sys/net/if_sl.c
 Delete src/sys/net/if_slvar.h
 Delete src/sys/net/ppp_comp.h
 Delete src/sys/net/ppp_deflate.c
 Delete src/sys/net/ppp_tty.c
 Delete src/sys/net/slip.h
[...]
 Delete src/tools/build/options/WITHOUT_SLIP
[...]
 Delete src/usr.sbin/pppd/Makefile
 Delete src/usr.sbin/pppd/RELNOTES
 Delete src/usr.sbin/pppd/auth.c
 Delete src/usr.sbin/pppd/[...]
 Delete src/usr.sbin/sliplogin/Makefile
 Delete src/usr.sbin/sliplogin/pathnames.h
 Delete src/usr.sbin/sliplogin/sliplogin.8
 Delete src/usr.sbin/sliplogin/sliplogin.c
Finished successfully

Если представить себе mascot of FreeBSD, говорящий словами Купринского героя, то эти слова звучали бы так:

Да, господа судьи, я убил pppd и буду впредь повторять свое преступление для всех не-SMP драйверов.
Но напрасно медицинская экспертиза оставила мне лазейку -- я ею не воспользуюсь.

Не менее интересно, сколько лет понадобится собирателем сетевого мусора, чтобы удалить газзилионы страничек "настраиваем point-to-point protocol daemon под freelsd", написанные русскими хакирами-патриотами, учитывая их возмущенный рев "как посмели" и громкие призывы строем возвращаться на 4.11, переходить на Linux и проч.

Saturday, January 31, 2009

Доктор Джекилл и мистер Хайд

Я разгадал тебя: ты самозванец.
Тайком пробрался ты на этот остров,
Чтоб у меня отнять мои владенья.
-- Уильям Шекспир, Буря.

На днях ваш покорный слуга нашел в себе силы поправить для FreeBSD порт одной крохотной утилиты. Заставить себя пришлось, поскольку реацией на попытку использование той версии утилиты, что спрятана в густом сумраке дерева портов, как ягода черники в лесу, было неприличное ее гэпание, если ту пытались пустить на, к примеру, amd64.

Ошибка та была давным давно (чуть ли не год назад) исправлена и новая версия почти что bug free утилиты живет с осени прошлого года на Sourceforge. В портах, разумеется, оставалась ссылка на a) старую версию b) безвинно убиенный (по моей просьбе) аккаунт на unixdev.net.

То есть, скачать старую версию как бы вообще нельзя. Тяжка доля maintainer'а своих же глюкал, но доля ленивого maintainer'а, уклоняющегося от общественно-полезного труда, тяжка вдвойне.

Кряхтя сполняю send-pr; чуть погодя читаю из GNATS:

Class Changed
From-To:    maintainer-update->change-request
By:         edwin
When:       Wed Jan 28 22:30:16 UTC 2009
Why:        Fix category (submitter is not maintainer)

Что тут сказать? В патче было изменено, кроме всего прочего, 2 вещи: e-mail и спеллинг фамилии (на более классический). Реакция коммитера получилась такая, словно submitter (сиречь моя скромная персона) -- это коварный злодей, злым умыслом исподтишка попытавшийся, будто начинающий карманник в метро, стащить иго maintainer'ства.

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

State Changed
From-To:    feedback->open
By:         beech
When:       Fri Jan 30 05:46:36 UTC 2009
Why:        Submitter is maintainer

State Changed
From-To:    open->closed
By:         beech
When:       Fri Jan 30 06:05:49 UTC 2009
Why:        Committed, Thanks! 

Страшенна нудьга оце с вами, вельмишановнi панi та панове.

Wednesday, January 21, 2009

How to view logs

Один знакомый меня спросил, показывая пальцем в xterm, где был procmail log: "что это за утилита для просмотра логов?". Почему утилита? xterm выглядел вот так:

Многие испытывают мучения либо набирая каждый раз ``tail -f something'' либо открывая кучу терминалов для глядения на log files. Другие пользуют screen и делают с ним разные полезные штуки. Вы тоже можете сварганить себе log viewer за 5 минут.

Что нам понадобится.

  1. Работающий screen.
  2. Отдельный конфигурационный файл для запуска screen в качестве log viewer. Отдельный -- это затем, чтобы не трогать вашу обычную настройку screen'а.
  3. xterm и утилита tail.

% cat ~/.screenrc.logviewer
startup_message off
hardstatus alwayslastline "%-w%{= bw}%50>%n %t%{-}%+w%<"

screen 0 tail -f -F /var/log/messages
title Messages

screen 1 tail -f -F /home/alex/.procmail/log
title procmail

screen 2 tail -f -F /var/log/maillog
title sendmail

#screen 3 tail -f -F /var/log/samba/log.smbd
#title smbd

screen 3 tail -f -F /var/log/news/news.notice
title news.notice

#screen 4 tail -f -F /var/log/auth.log
#title auth

screen 5 tail -f -F /tmp/twit-list.log
title twit-list

select 1

Самое painful тут было родить описание the hardstatus line на птичьем языке, остальное self-explanatory. Теперь пускайте ваш log viewer:

% xterm -title "Log files" -e screen -c ~/.screenrc.logviewer &

Переход между окнами: Ctrl-a n, где n -- номер окна, выход: Ctrl-a \.

8 myths about pr2nntp

Тут в узких кругах пользователей pr2nntp замеченно появления в головах тумана в виде "скопища рiзних думок". Чтобы сдуть его и снять пелену с глаз, пришлось развенчать несколько мифов.

Миф #1: pr2nntp очень сложно настраивать

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

Миф #2: pr2nntp требует INN, а я помню как в университете писал курсовую работу о настройке INN и почти что свихнулся.

Во-первых, не обязательно INN -- сгодится совершенно любой NNTP-сервер, который вы можете дергать за веревочки для создания своих newsgroups.

Во-вторых, последние версии INN для работы с pr2nntp требует 0 (нуль, здесь нет ошибки) каких-либо правок в конфигурации. То есть вы ставите порт news/inn и забываете о его существовании. И не пытайтесь подозревать самих себя, что в таком случаи вы оставляете INN незащищенным для атак извне -- по умолчанию вам будет дано право подключаться к нему только с локальной машины (так что см. файл /usr/local/etc/news/readers.conf, если требуется все совсем иначе).

Миф #3: pr2nntp конвертирует все feeds в plain text, а в моих feeds есть картинки.

Видите ли вы изображения или нет, зависит исключительно от вашего news reader. pr2nntp умеет составлять письма с raw версией feed (со всем HTML'ом (выделениями, ссылками на что угодно и проч.)). См. screenshot Microsoft Mail.

Миф #4: pr2nntp написан на каком-то древнем, как египетские пирамиды, скриптовом языке. Мне в школе сказали, что Tcl это не cool, он давно умер, а последним кого видели пишущим на Tcl -- это был какой-то сумасшедший студент, потерявшийся в колонии королевских пингвинов в Антарктиде в начале 90-х, откуда потом, взобравшись на снежный холм, он передавал по радио тусклые, как утро на краю земли, стихи о тщете всего сущего.

Так, все вопросы по языку в comp.lang.tcl. По поводу древности идите на www.tcl.tk.

Миф #5: tDOM и pr2nntp требуют разных версий Tcl (8.4 и 8.5) соответственно.

Wrong.

% pkg_info | egrep 'tcl|tDOM'
tDOM-0.8.2          High performance XML data processing with Tcl
tcl-8.5.6           Tool Command Language
tcl-threads-8.5.6   Tool Command Language

% pkg_info -r tDOM\*
Information for tDOM-0.8.2:

Depends on:
Dependency: tcl-8.5.6
Dependency: tcl-threads-8.5.6

Миф #6: elinks вставляет дурацкое поле по левому краю письма, которое не убирается и всех раздражает. Меня особенно!!!! :(((((((

Запустите elinks, нажмите 'o', зайдите в Document->Browsing->Horizontal text margin и поставьте в поле value число 0. Не забудьте сохранить правки.

Миф #7: Мой wget качает и качает все feeds каждый раз заново, а вот FirstRateFooBarRSSreader (buy 2 get 1 for free) -- нет.

Прочтите в документации раздел 2.2 File downloader. Если лень самому возится с puf, скачайте готовый порт. (Update 2009-01-30: или пользуйте стандартный fetch(1) из FreeLSD 7.1, где он, наконец, начал по божески работать в конструкции fetch -mad -o %f %u).

Миф #8: Вот у меня есть несколько feeds, которые редко обновляются и гадкий pr2nntp каждый раз их скармливает целиком INN, а мои пометки на письмах "как прочитанные" испаряются. Так нельзя, я щетаю.

Дело отнюдь не в pr2nntp. Просто у вас за период между обновлением таких feeds проходит столько времени, что INN успевает удалять старые письма в newsgroup, а вы (посредством pr2nntp) отдаете их INN вместе с новыми.

Tuesday, January 20, 2009

screen and libutempter

Совсем внезапно обнаружилось неприятное поведение screen 4.0.3: если xterm у нас собран с поддержкой libutempter, то собрать порт screen на этой же машине не получится (оно валится на этапе configure с совершенно идиотским ``error: Can't run the compiler - internal error. Sorry.''; скучные подробности опускаю -- они ясно видны в config.log). Решением есть 2 варианта:

  1. Временно сделать pkg_delete libutempter\*, собрать порт screen, поставить libutempter обратно.
  2. Отрубить libutempter от xterm (заодно вместе с luit, если хотите иметь человеческую поддержку локали koi8) и снести libutempter.

Второй способ мне нравится больше.

Monday, January 12, 2009

FreeBSD 7.1 and VMware Workstation

(2009/05/07 Update: 3-й эпизод см. тут.)

Полного погружения с open-vm-tools не получилось. Хотя, с другой стороны, максимальный минимализм все-таки преодолен. То есть, если раньше из комплекса tools идущих с VMware Workstation использовалась ровно 1: vmware-guestd (попробуйте догадаться для каких сложных вещей!), то с любознательным щупаньем одновременно свежей FreeLSD 7.1 и не очень свежих open-vm-tools (в портах есть только летняя версия) добавилась insane возможность: содержимое X Primary стало отображаться в Windows clipboard (и наоборот).

(голосом офисного морона): Новые технологии в действии!

Стартовые условия остались прежними. Разница в версии FreeBSD и использовании open-vm-tools вместо идущих проприетарных tools с VMware Workstation.

Порт open-vm-tools ставит, среди прочей чепухи, 1 демон, 4 ядерных модуля и 1 Очень Полезную Программу (о ней в самом конце заметки). 1 из модулей бессмыслен по условиям задачи -- vmxnet.ko; vmmemctl.ko выполняет роль мебели или даже настенной лепки; vmblock.ko и vmhgfs.ko -- это те 2 штуки, которые якобы дают использовать Drag and Drop и shared folders соответственно.

Кто дал тебе имя
Малышка из квартала Симмати?
Зачем так искусно
Губами ласкаешь коралл?
О бездна блаженства!
-- Рубоко Шо, Время Цикад

Автор порта почему-то прописал в /usr/local/etc/rc.d/vmware-guestd вот такое:

[ -z "$vmware_guestd_enable" ] && vmware_guestd_enable="YES"

Это значит, что вам не нужно ничего добавлять в /etc/rc.conf чтобы vmware-guestd стал во тьме ram бегать за цикадами. Зато нужно (это было правдой и раньше, но ваш покорный слуга об этом самым подлым образом хранил молчание) добавить в .vmx файл виртуальной машины строчку:

tools.syncTime = "TRUE"

Иначе время никто не будет синхронизировать (точные сведения из tarball'а см. в guestd/toolsDaemon.c и lib/include/vm_app.h). Это также означает что для минималистической задачи (иметь условно точные 1 раз в минуту часы и ничего более от open-vm-tools), можно собирать порт open-vm-tools-nox11, чтобы не мышеелозить по вкладкам vmware-toolbox.

Btw, vmware-guestd разжирел на свободных харчах и начал предъявлять нахальные требования к ресурсам:

% top | grep guestd
  649 root          1  96    0 18116K   640K select   0:20  0.00%  vmware-guestd

в тоже время когда закрытый предшественник:

% top | grep guestd
  665 root          1  96    0  1620K   308K select   3:49  0.00%  vmware-guestd

[...] африканские слоны и вообще не могут сравнится
с индийскими даже и при равной численности -- последние
далеко превосходят их и размерами, и боевым духом.
-- Тит Ливий, История Рима от основания города, XXXVII, 39, 13

Экзотика, которой являются кернельные модули vmblock.ko и vmhgfs.ko напоминают мне боевых слонов. При первом взгляде они поражают воображение свои видом, а их наездники смотрят на окружающих с тем особенным интересом, который присущ человеку рассматривающему на корточках муравейник в лесу.

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

Как и для всякой экзотики, интерес к vmblock.ko и vmhgfs.ko угасает, когда пытаешься заставить их делать что-то более полезное, чем таємниче виблискування из output команды kldstat.

Drag and Drop между host & guest реализован так: vmblock.ko -- это драйвер "блокирующей" файловой системы. Предполагается, что искомый файл, перед тем как переедет на новое место жительства, сначала попадет в temporally directory (обычно /tmp/VMwareDnD), откуда принимающая программа не получит его (он будет для нее "блокирован") до тех пор, пока тот не перепишется в нее полностью. Принимающая сторона ничего не знает об temporally directory -- она читает смонтированный каталог с симлинками (во FreeBSD это как бы /var/run/vmblock), думая, что они (симлинки) и есть нужный ей файлы, о которых она пролила столько слез.

Хороший пример, как пользовать vmblock filesystem, можно прочесть в патче Chris'a Malley к ядру Linux 2.6.27.

У vmblock есть свои проблемы идеологического свойства (например, такой факт, что реализация этой файловой системы сделана как модуль ядра, а не современным методом Filesystem in Userspace (FUSE)), но в любом случаи, вся эта красота разбивается при попытке монтирования ее в FreeLSD 7.1.

Для еще пущего нагнетания сообщим, что смонтировать ее командой mount вообще не получится, ибо просто нечем монтировать, как вежливо сообщил по этому поводу Ryan Beasley: Unfortunately a standalone mounter for vmblock on FreeBSD was never written. Mounting was embedded in the vmware-user setuid wrapper. А этот самый vmware-user setuid wrapper вообще исключен из состава порта.

Я, как и советовали, полез в vmware-user-suid-wrapper/wrapper-freebsd.c, поправил путь к vmblock.ko в LoadVMBlock(), пересобрал, запустил vmware-user-suid-wrapper в предвкушении и радости появления смонтированного каталога /var/run/vmblock, с чувством схожим на проявления счастья у моей кошки, когда я ей варю рыбу. К несчастью, ожидания накрылись медным тазом, который больше известен под названием паника ядра:

Красиво, правда? Ровно такая же реакция наблюдается при запуске mount_vmhgfs для монтирования shared foldes. Какую из этого можно извлечь мораль? Только ту, что для порта open-vm-tools у вас в /etc/rc.conf должна быть 1 (одна) строчка:

vmware_guest_vmmemctl_enable=YES

Остальное будет ждать лучших времен. Может причина поведения vmblock.ko и vmhgfs.ko есть та, что у меня не самая последняя версия WMware Workstation, а может потому, что не были проведены священные ауспиции и в Workstation многое запуталось и пришло в беспорядок, или потому, что погода нынче такая, когда после утренней пробежки тащишься в парадном синий как лазурит, а под душем чувствуешь себя будто только что поплававший в обществе косатки ниже 60 параллели и вытащенный из воды проплывавшим мимо кораблем со шведскими туристами.

The last tip for today: запустите vmware-user из под иксов, to enable copy and paste to and from your virtual machine, не забыв предварительно поставить галочку в Settings->Options->Guest Isolation вашей виртуальной машины. vmware-user хоть и грязно выругается на невозможность to initialize blocking driver, но для copy and paste дармоедствующий модуль vmblock.ko не требуется.