⌨ Labor omnia vincit ☮

(fun (open-build-service (+ openSUSE stumpWM)))

Posted in Lisp, SuSE [ru] by anaumov on 10.10.2012

Common Lisp – один из диалектов мультипарадигменного языка программирования Lisp. Поддерживает комбинацию процедурного, функционального и объектно-ориентированного программирования. Я начал изучать Lisp именно из-за его истинно функциальной природы. Реализация решений тех или иных задачь при использовании функционального подхода (декларативного программирования) сильно отличается от столь привычного императивного. Его использование очень расширяет горизонты программиста.

Одной из интересных особенностей Lisp-программ является возможность их изменения “на лету”. Это значит, что мне не надо их перекомпилировать или перезапускать интерпретатор. Я просто подключаюсь к запущенному процессу и меняю его поведение, внося изменения в его код. Это делает хакинг на много проще и интересней.

К сожаленью в openSUSE-репозиториях практически нет Lisp-программ. Есть Emacs, но он написан на Emacs Lisp, а это другой диалект с другими правилами. Есть Lisp-интерпретаторы, но вносить изменения в код интерпретатора и следить за изменениями в его поведении все же не столь интересно. Свои первые программы aka “hello world” изменять тоже скучно; хочется работать с большим проектом, чтение кода которого научит тебя новым трюкам этого языка и просто покажет как надо на нем программировать.

Мой выбор остановился на проекте stumpWM. Его не было в репах, так что собирать его предстояло из исходников. Собрать С/C++ или даже Python-проекты с Qt/GTK+ библиотеками не составляет особого труда для большинства из нас, но в мире Lisp все это работает несколько иначе…

Beauty of packaging

StumpWM представляет из себя фреймовый (разбивающий рабочее пространство экрана на взаимно не пересекающиеся прямоугольные области — фреймы) оконный менеджер для X11, написанный на Common Lisp и управляемый главным образом с клавиатуры. Вообще-то я доволен и Fluxbox, но, как я уже сказал, я решил попробовать сломать что-то большое, написанное на Lisp. К тому же интерес вызвало его отсутствие в OBS.
Процесс сборки занял некоторое время из-за поиска, изучения и сборки зависимостей.
Packaging – одна из интереснейших частей хакинга: ты учишь столько нового о внутреннястях и принципах работы программ, которые собираешь. Ты можешь менять её поведение или характер, указывая как именно она должна вести себя при установке, удалении или обновлении. В случае с stumpWM, Lisp открывал новый мир со своими правилами и культурой. Хочешь подключить дополнительные библиотеки к Lisp-проекту? Его интерпретатор не может сделать это сам, как например в случае с Python или при компиляции С/C++. В мире Lisp для этого используется Another System Definition Facility, даже несмотря на то, что эти библиотеки написанны на том же Lisp.
Новыми так же оказались сами библиотеки и принцип их работы. К примеру, нужно использовать протокол X Window System. Для C/C++ проекта это была бы привычная нам всем Xlib. Её же можно использовать и тут, а можно пойти другим путем и, как я и сделал, пересобрать проект с cl-clx. Ну разве не здорово?🙂

Все пакеты, необходимые для запуска stumpWM, собраны и находятся в моем home-проекте.

> osc ls home:Alexander_Naumov:Lisp
asdf
cl-clx
cl-ppcre
common-lisp-controller
dh-lisp
sbcl
stumpwm

> osc ls home:Alexander_Naumov:Lisp stumpwm | grep tar
stumpwm-0.9.7.tar.gz

В процессе сборки всех этих зависимостей я обращался к ML архивам fedora и debian-проектов.

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

Install stumpWM

Итак, если прошлый абзац не отпугнул вас, и вы решили не собирать проект из исходников, а установить мою сборку stumpwm, то… просто подключите Lisp-репозиторий и установить пакет stumpwm. Он потянет за собой остальные пакеты из этого репозитория.

> sudo zypper ar \
http://download.opensuse.org/repositories/home:/Alexander_Naumov:/Lisp/openSUSE_12.1/ \
Lisp
> sudo zypper mr -r Lisp
> sudo zypper in stumpwm

Если все прошло гладко, то вы должны получить /usr/lib/stumpwm/stumpwm файл. После этого создаем ~/.xinitrc и делаем:

> echo "/usr/lib/stumpwm/stumpwm" >> ~/.xinitrc

Перезагружаем X сеанс (разлогиниваемся и залогиниваемся обратно). После этого должно появиться приглашение “Welcome To the Stump Window Manager”. Выглядит все это примерно вот так (на скриншоте 12.1, но на 12.2 это тоже работает ;)) и для управления действительно не нужна мышь. Это конечно не значит, что ее работа не поддерживается и ей нельзя пользоваться.
Если не понравиться, всегда можно вернуться обратно, просто удалив/отредактировав ~/.xinitrc.

Кстати, по поводу этого файла и автоматическим переключением между окружениями. Была идея сделать процесс полносью автоматизированным, т.е. просто устанавливаем пакет, перезагружаем X, и запускается stumpWM, а после его удаления и перезагрузки X, просто загружается то, что было до него. Я не стал так пока делать, потому что планирую реализовать этот механизм через sysconfig. Редактирование ~/.xinitrc (просто добавление одной строчки или её удаление) меня пока совсем не напрягает. Надеюсь, что и для вас это не будет большой проблемой😉

Just re-eval and GO!

Поведение stumpWM можно менять “на лету”, т.е. для того чтобы увидеть результат изменений, его не придется перезапускать. Способов сделать это есть много, но, к сожаленью, далеко не все пока поддерживаются в стандартной установке openSUSE. Для этого нужно пересобрать еще несколько проектов (на моей машине они собранны из исходников).

Самый простой – перезагрузить конфиг ~/.stumpwmrc. Файла этого после установки в системе нет, но, как и ~/.xinitrc, его можно создать, и настройки из него будут подхваченны stumpwm. Добавим, к примеру, в ~/.stumpwmrc этот код:

(defcommand yast () ()
    "Start YaST"
    (run-or-raise "/sbin/yast2" '(:class "YaST")))

(define-key *root-map* (kbd "y") "yast")

Теперь перезагружаем его командой С-t ; loadrc. Получаем сообщение “rc file loaded successfully”. Это значит, что настройки stumpwm изменены: теперь он будет реагировать на команду С-t y и запускать при этом YaST. Как вы понимаете, это просто пример; вместо YaST можно повесить любой другой процесс – браузер или что-то ещё.

Другим интересным способом является подключение непосредственно к stumpwm и изменение его кода… прямо во время его выполнения. Я расскажу об этом способе поподробнее в следующей статье, когда найду время пересобрать и протестировать еще пару нужных для этого Lisp-пакетов.

15 Responses

Subscribe to comments with RSS.

  1. tuoma said, on 23.10.2012 at 08:33

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

    • Alex said, on 26.10.2012 at 18:33

      Систему разграничения доступа никто не отменял. Ядро как и обычно следит и за файлами и за процессами.

      • tuoma said, on 04.11.2012 at 22:03

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

      • Alex said, on 05.11.2012 at 08:43

        Ядру и не надо знать о содержании файла, оно просто проверяет кто хочет его прочитать/записать/запустить.

      • tuoma said, on 05.11.2012 at 09:19

        В вашем примере манипуляции выполняются с конфигом, который лежит в домашней директории пользователя. На этот файл у пользователя есть права на запись… Легко можно предположить, что этот пользователь в процессе серфинга по инету загружает некоторую программу злоумышленника, которая в свою очередь от имени пользователя правит этот конфиг. Это нереальная ситуация?

      • Michael Filonenko said, on 05.11.2012 at 09:22

        И что дальше происходит?

        Чем это отличается от правки пользовательского конфига любой другой программы?

      • tuoma said, on 05.11.2012 at 11:50

        прочтите пост

      • Alex said, on 05.11.2012 at 13:08

        прочтите пост

        Ок, я постораюсь прояснить. Да, если система была взломана, и от имени этого пользователя теперь можно делать что угодно, например изменить конфиг stumpwm, то да – после перезагрузки конфига, его новая конфигурация, при нажатии того же С-t y, может вместо вызова YaST, к примеру, удалить домашний каталог или сделать еще что-то недоброе.

        Но я не понимаю причем тут Lisp? Если система тем же способом была взломана, и я, к примеру, использую, fluxbox, то точно также можно изменить его меню, и при вызове чего-то обычного из меню (т.е. злоумышленик не добавлял новый пункт в меню, а связал, к примеру, вызов консоли, который там уже был, с командой удаления домашнего каталога) точно также будет удален домашний каталог. Разница лишь в том, что при использовании fluxbox для этого придется перезагружать X, а при использовании stumpwm – перезагрузить его конфиг. Но ведь в обоих случаях мы рассматриваем ситуацию уже после взлома. Какое отношение использование Lisp имеет к безопасности мне по-прежднему не понятно…

      • tuoma said, on 05.11.2012 at 13:43

        хорошо. В таком случае получается, что правка того же конфига, дает такой же результат, как и правка конфига в другом менеджере. Если во fluxbox предусмотреть возможность перезагрузки конфига, то поведение его будет такое же как и описанное вами. В чем тогда преимущество Lisp?

      • Alex said, on 05.11.2012 at 15:18

        В fluxbox не реализовать того, о чем Вы говорите. В Lisp этого даже реализовывать не надо, там это есть по дефолту. И это только одно из его преимуществ…

        Тут речь идет не просто о другом WM, мы тут говорим о философии языка, и о принципах выполнения его кода.

        p.s. Если Вам интересна эта тема, то я советую полистать книги по Lisp и функциональному программированию. После прочтения одной-двух статей по этой теме разобраться и понять это в любом случае не получится.

      • tuoma said, on 05.11.2012 at 19:32

        Касательно примеров с перезагрузкой конфига и добавления хоткеев – это реализуемо. Другой вопрос, если этот пример не отражает того, что вы хотели донести до читателей этим постом. Когда-то давно мне приходилось сталкиваться с функциональным программированием, в рамках лабораторных работ в универе. Головоломка еще та, скажу вам. Это действительно другое мировоззрение что ли… Хотя у меня в дипломе по нему 5🙂
        Но не об этом речь. Просто при прочтении статьи я сделал вывод, что можно менять поведение любого процесса вольным образом, потом при обсуждении выясняется, что не так все красочно, как я себе это представлял. Безусловно, можно обложиться кучей книг, посидеть месяцок и вникнуть в философию языка… и понять, что он тебе не нужен… Хотелось бы понять из статьи зачем все это нужно и какая от него практическая польза.. вот на мой взгляд то, что должен вынести читатель из вашего поста. Лично у меня пока это не получилось…. Возможно мои умственные способности оставляют желать лучшего, но пока я вас не понял.

      • Alex said, on 05.11.2012 at 20:06

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

        Я думаю, что дело не в умственных способностях, а в опыте. Попробуйте добавить в fluxbox (я напомню, что он написан на С++) функцию перезагрузки его поведения “на лету”. Я не говорю, что это невозможно, но Вы попробуйте🙂
        И после того, как добавите эту функцию (или бросите это занятие (в зависимости от того, какое условие наступит раньше)), мы продолжим беседу.

    • tuoma said, on 05.11.2012 at 20:14

      Не понимаю, где вы видите сложность в реализации перезагрузки конфига и хоткеев на С++? Или речь о том, что на Лиспе это сделать проще?

  2. Michael Filonenko said, on 04.11.2012 at 07:56

    С установкой можно проще.

    sudo install sbcl

    # установка лиспового пакетного менеджера
    curl -O http://beta.quicklisp.org/quicklisp.lisp

    sbcl –load quicklisp.lisp
    (quicklisp-quickstart:install)
    (ql:add-to-init-file)

    ;; установка stumpwm
    (ql:quickload “stumpwm”)

    # запуск wm

    sbcl –eval “(ql:quickload “stumpwm”)” –eval “(stumpwm:stumpwm)”

    • Alex said, on 04.11.2012 at 15:15

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


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: