Redirection and subprocess.Popen()
Потерял вчера несколько часов из-за неправильного использования перенаправления в python. Как мы знаем, чтобы запустить новый процесс и прочитать его вывод, в python существует метод Popen() из модуля subprocess. Вот так, к примеру, мы можем прочитать вывод “ls -la“:
#!/usr/bin/env python import subprocess as sp ls = sp.Popen(["ls", "-la"], stdin=sp.PIPE, stdout=sp.PIPE).communicate()[0] print ls
Т.е. аргументы поочереди передаются в качестве первого параметра Popen. Исходя из этой логики, команда с перенаправлением просто должна содержать символ “>” в качестве одного из аргументов. Однако эта фича shell, и в python, как я понял, либо не работет вообще, либо работает как-то совсем по-другому. Притом интерпретатор в этом случае ведет себя тоже достаточно странно: мы не получаем ни сообщений об ошибке, ни вывода команды, которую хотим вызвать.
Чтобы выполнить что-то типа “prog –option < something" мы должны передать это something через communicate() метод:
msg = sp.Popen(["/usr/bin/spamc", "--headers"], stdin=sp.PIPE, stdout=sp.PIPE) (stdout, stderr) = msg.communicate(str(message)) print stdout
В этом случае перенаправление будет выполнено без проблем: мы вызываем прогамму /usr/bin/spamc с параметром –headers и перанаправляем ей message. Message должна быть строкой, поэтому сначала скармливаем ее str().
More power for OpenBSD project
Пару дней назад я разместил информацию о переводе официальной документации OpenBSD на сервере украинского сообщества пользователей OpenBSD. Большое им за это спасибо! Я надеюсь, что это поможет привлечь новых переводчиков, или просто кто-то откликнится и поможет улучшить те переводы, которые у нас уже есть.
Я также зарегистрировал новый IRC-канал на freenode-сервере для русскоязычных пользователей OpenBSD. Если вы интересуетесь или просто используете эту операционную систему, заходите к нам на #openbsd-russian.
Ну и последняя маленькая новость: я закончил перевод OpenSMTPD секции. Добавлен линк с оригинальной index-страницы, что подтверждает отсутствие ошибок в коде наших страниц.
Absolute OpenBSD, 2nd Edition (by Michael W. Lucas)
Yahoooo! В прошлом месяце издательство No Starch Press представило второе издание книги Absolute OpenBSD, UNIX for the Practical Paranoid Михаила Лукаса (Michael W. Lucas), автора Cisco Routers for the Desperate.
Книга представляет из себя OpenBSD руководство, рассчитанное на опытных пользователей UNIX (читатель должен быть хорошо знаком с таким понятием как POSIX, основными командами, а также системой разграничения доступа). Она не показывает читателю что ввести, а вместо этого рассказывает почему и как именно работает та или иная её часть, т.е. хотя книга и включает в себя описание процесса установки и настройки системы, основное её внимание сосредоточено на более глубоких вопросах, а также особенностях, выделяющих её из группы других свободных UNIX-образных систем. Книга также содержит советы по устранению неполадок, справочную информацию о системе и её командах.
Если я не ошибаюсь, первое издание этой книги вообще является первой книгой на английском, посвященной OpenBSD. Она вышла во время релиза 3.4, так что информация бОльшей части книги уже безнадежно устарела. Второе издание является обновлением. Техническим редактором второго издания является Петер Ханстин (Peter Hansteen), автор The Book of PF.
Кстати, сейчас эту книгу можно купить всего за полцены
22.05.13 UPD:
Вчера наконец-то я получил ее. Книга превзошла мои ожидания. Это не просто еще одна книга о UNIX, это книга о конкретном проекте со своей историей и культурой. Очень захватывающее чтиво, несмотря на то, что многое из нее мне уже знакомо.
Test the upcoming openSUSE 12.3 + KDE 4.10 Workspace
Остается месяц до выхода следующей версии нашего любимого дистрибутива. Я хотел бы напомнить всем пользователям KDE, что наши образы можно найти тут. 3 дня назад были пересобраны образы последней openSUSE 12.3 с KDE 4.10 Workspace.
Пожалуйста не поленитесь потратить один вечер и проверить их на своем железе. Следуйте инструкциям на этой странице для записи образа на USB. Как и обычно, о найденных ошибках в KDE вы можете сообщить на bugs.kde.org, или на bugzilla.novell.com в случае проблем в самой openSUSE. Не забывайте, что это live-образы, т.е. настройки не сохраняются между сессиями.
Напомню так же, что в Beta1 был поломан GRUB2, который автоматически добавлял пункты меню для других установленных на компьютере ОС, однако не позволял их загрузить. Я так же жду продвижения в работе над ошибкой в YaST/udev, которая возникает во время установки системы на этапе инициализации оборудования (установщик замирает на отметке в 60%). Не забываем про NetworkManagement и systemd! KDE разработчики просят так же обратить внимание на этот список.
Если у вас возникнут проблемы при отправке сообщения об ошибке (возможно, что вы собираетесь сделать это в первый раз), пожалуйста не стесняйтесь спросить о помощи на одном из форумов, или просто напишите комментарий прям тут. Я буду рад помочь вам.
openSUSE + stumpWM

When you think about GNU/Linux, you probably think about servers or data storage systems. It could be also development machines or maybe desktops (but probably not). For me GNU/Linux was always place for different experiments and also platform on which I can implement my ideas (which often break system). So, today I would like to tell a bit about the Stump Window Manager.
Let’s start by saying that stumpWM is a tiling, keyboard driven X11 Window Manager written entirely in Common Lisp, and Common Lisp is a one of dialects of the Lisp – a family of a multi-paradigm programming languages (supports a combination of procedural, functional, and object-oriented programming paradigms). There are many reasons to use stumpWM. For example, you would like to have benefits of tiling window managers (its tiling windows to use the whole screen and focus on a user experience which is highly keyboard driven operation), or maybe you just want to learn Common Lisp (as we all know, reading the source code of a big professional project is a good idea when you learn a new programming language).
Keep reading this post…
FOSDEM: Coping with wide impact changes in a distribution
Finally published the FOSDEM presentation about changes in a distribution. It’s a very popular topic now. Next release of openSUSE will not have so many new features as, for example, last 2 versions, but in spite of this many users are waiting for changes in the kernel of our distribution (like replacement for an old familiar, established and stable mechanisms (openSUSE is migrating to the use of systemd for the upcoming 12.3 version, given the difficulties that emerged in trying to co-maintain two different init systems (SysV + systemd)) or maybe another just not well tested systems. Some of us are quite closely monitor changes (beta to beta) and are active in the openSUSE-factory and openSUSE-packaging MLs discussions and IRC. They use it as an always up-to-date development and testing platform. For another, who make update after the official release only, this presentation is VERY recommended.
Russian OpenBSD Documentation: FAQ, Packet Filter and OpenSSH
Рад сообщить, что процесс перевода официальной документации OpenBSD не стоит на месте.
Первая хорошая новость: к работе присоединились двое ребят. Дмитрий Гранин теперь работает над переводом PF, а Руслан Гундаков проводит аудит старых файлов и помогает с переводом FAQ. О процессе перевода узнают все больше и больше людей, и, хотя многие считают, что документация на русском языке для такой системы как OpenBSD не нужна, мы все же продолжаем работать.
Второй хорошей новостью является добавление линка на русскоязычный сегмент OpenSSH. Да, это значит, что вся документация о OpenSSH переведена на русский язык, находится в актуальном состоянии (синхронизирована с англоязычными страницами), и html-код страниц не содержит ошибок (например, ссылок в никуда). Там практически нет мануалов или каких-то советов по поводу использования OpenSSH (хорошие OpenSSH-руководства на русском можно найти на opennet.ru). На официальных страницах информация об истории проекта, освещение его в прессе, архив почтовой рассылки и линк на исходники.
Я также обновил страницы, касающиеся перевода, на официальном сервере русскоязычного OpenBSD сообщества. Туда и впредь планирую добавлять информацию, помогающую команде в целом. Пишите мне, если у вас возникли вопросы или вы просто хотите что-то туда добавить.
Но самой главной и интересной новостью для русскоязычных пользователей является оживление FAQ’а. Раньше его перевод можно было найти на obsd.ru, но во-первых портал вот уже как несколько месяцев в оффлайн, а во-вторых, он содержит (содержал) перевод для OpenBSD версии 4.3. Мы проработали весь этот материал (на данный момент 12 из 15 глав), исправили некоторые ошибки/неточности (а некоторые главы решили переписать полностью), обновили его до актуального состояния, т.е. для версии 5.2, и, наконец, оформив материал по правилам и стандартам проекта OpenBSD, загрузили страницы на официальный сервер.
Что такое FAQ, для чего он нужен, и почему это так важно? FAQ представляет из себя документацию об установке, настройке и использовании OpenBSD. 15 глав в доходчивой форме рассказывают нам о работе самых важных компонентах этой операционной системы, а также о проблемах, которые мы можем встретить во время её установки или использования. FAQ не заменит книг по UNIX или man-страниц, вы не научитесь работать в OpenBSD, прочитав только FAQ; он поможет понять проект в целом, а также ответит на вопросы, которые скорее всего возникнут у любого новичка, решившего попробовать эту ОС.
Напомню, что процесс перевода не закончен! Работа продолжается, и нам по-прежднему нужны переводчики. Нам по-прежднему нужна ваша помощь, критика и/или просто поддержка. Исходники, как и прежде, вы можете скачать, используя любой из анонимных CVS серверов:
> cvs -d anoncvs@mirror.osn.de:/cvs get -P www > cd www > cvs -q up -Pd
Внутри русскоязычной команды мы используем git, куда вашим коммитам всегда Добро пожаловать
Не стесняйтесь писать мне, если у вас возникнут какие-либо вопросы, или вы просто захотите принять участие в переводе. Хоть и не так быстро как хотелось бы, но работа продвигается. Мы все ближе и ближе к достижению нашей цели – создание простой в понимании и актуальной/свежей OpenBSD документации на русском языке
“ANSI Common Lisp” Paul Graham
Наверняка многие Lisp’еры вначале изучения этого языка читали статью Побеждая посредственность, в которой Пол Грэм рассказывает о причинах успеха компании Viaweb, основанной им с Робертом Моррисом. Статья безусловно захватывающая. Пол, словно шутя, объясняет, как без особых проблем они обходили конкурентов, подогревая тем самым интерес читателя к Common Lisp.
После прочтения этой статьи задаешься вопросом о книге, по которой можно было бы познакомиться с этим удивительным языком, который Пол сравнивает с секретным оружием. Многим хочется разобраться во вкусностях языка как можно быстрее, поэтому очень популярной книгой среди новичков является Practical Common Lisp. С этой книги начинал и я. В ней делается акцент именно на практическое применение языка. Проблема в том, что, как правило, к ФП приходят уже после изучения нескольких императивных языков, а это два совершенно разных подхода к дизайну программ. Пока вы не научились думать функционально, пользы от использования функциональных языков будет немного. Именно поэтому, параллельно с обучением языку, так важно показывать примеры, написанные в функциональном стиле,
а также рассказывать и сравнивать их с примерами, написанными на императивных языках.
Пол подарил нам не только статью, о которой я упомянул в начале, он также является автором книги “ANSI Common Lisp”. В отличие от Practical Common Lisp, в ней очень хорошо сбалансированн материал и по функциональному подходу, и по знакомству с синтаксисом Common Lisp, т.е. очень хороший вариант для начинающих. Стоит также отметить краткость, простоту и доступность материала, что очень важно, когда речь идет именно о введении в язык.
Я так увлекся рассказом о ФП, что совсем упустил основную идею. В ноябре прошлого года издательство “Символ-Плюс” представило перевод этой книги. 17 лет книга ждала перевода на русский язык. Конечно кто-то скажет, что переводы не нужны, а читать все и вся нужно на языке оригинала. Не буду спорить. Скажу лишь, что я рад, что документации о Lisp и функциональном программировании на русском языке становится все больше
Der Schnoor
Думаю, что многе наслышаны про отношение к старинным постройкам и памятникам архитектуры в Германии. Сегодня оно, пожалуй, одно из самых серьезных в Европе. После второй мировой войны, когда эта страна практически полностью лежала в руинах (разрушение городов до 90%), в сознании немцев еще сильнее укрепилось понимание важности архитектурного наследния, как отражения истории, а также заботы о нем. Продолжая свои коротенькие рассказы о ФРГ мне хотелось бы рассказать об одном очень красивом месте в Бремене, являющимся отличным примером немецкого отношения к старинной архитектуре.
Der Schnoor является одним из старейших кварталов Бремена. Это целая колыбель истории и искусства, предстающая перед нами сегодня в своем первоночальном средневековом виде. Такие кварталы славятся невероятно узкими улицами, пролегающими между кривоватыми невысокими Fachwerkhaus. 100 домов, построенных еще в XV-XVIII веках, занимают участок всего в 2,2 га. Их расположение – это не только одна из причин, почему квартал сохранил свою первоночальную атмосферу, но и причина его названия, которое переводится на русский как “шнур”, т.е. дома словно насажены на шнур, плотно прилегают друг к другу (хотя на этот счет есть и другое мнение).
От духа того времени осталась также и прекрасная традиция присутствия на улице квартала музыкантов, художников и ремесленников, которым на льготных условиях сдаются места на небольших пятачках квартала, где они занимаются своим творчеством, радуя жителей города и туристов. Так повелось с давних времен, когда шноор был деревушкой ремесленников и рыбаков, и эту репутацию квартала власти Бремена берегут. Да, ART это то, за что этот квартал понравится не только любителям романтической архитектуры. Здесь много антикварных магазинов, мастерских местных художников (или это даже скорее небольшие картинные галереи) или просто сувенирных лавочек (поверьте, их ассортимент отличается от того, что вы можете найти в обычном туристическом центре), а также рестораны и старинные таверны с своеобразной атмосферой.
В этом квартале находится самый маленький отель в мире, состоящий всего из… трех комнат. На краю квартала, напротив Balgebrückstraße, возвышается единственная сохранившаяся бывшая монастырская церковь Бремена. Неподалеку находится музей игрушек (Spielzeugmuseum) и театр, которые обязательно дополнят впечатление от прогулки самыми положительными эмоциями.
Несмотря на то, что в Германии я живу уже не первый год, я по-прежднему смотрю на нее глазами туриста. Дело не в том, что я не ощущаю себя частью немецкого общества, но в том, что вновь и вновь эта страна продолжает удивлять меня своей сказочной атмосферой и особенным отношением ко всему, что мне так нравится. И я рад этому
Merry Christmas and Happy New Year
If you read this, it means that you somehow miraculously have survived after an apocalypse, that was scheduled for yesterday. Of course you know that in spite of the end of the world, the role of the Open and Free Software stay the same. Hm… this is the most likely reason that you came to my blog, I guess
And you should be happy not just because have survived this “sad event”, but also because it is only 2 days until Christmas, and Christmas – it’s time for gifts! But again, as we all know, we will receive gifts, only if, first: Santa has also survived after an apocalypse; and second: only those of us who well conducted itself:

In any case, I would like to thank all those with whom we have done some work on Open Source projects. A lot of stuff was done at this year and it was great to work together with you guys. In the next 2 months I’m going to move to Munich where I found a new job and will keep work for the benefit of Free and Open Source Software.
Merry Christmas and Happy New Year! Stay crazy like you are. Never be satisfied, and always push yourself forwards. Belive in yourself. Keep doing the things people say can’t be done (or it makes no sense or something like this). Be ready to try new things. Keep doing Free Software better than before… and don’t forget to have a lot of fun of course
The Qt Project and Digia have released Qt 5.0
The Qt Project is proud to announce the final release of Qt 5. It is the latest version of the Qt C++ UI framework and the foundation for a new way of developing applications, where Qt Quick is in the center of Qt. Qt 5 continues to offer all of the power of native Qt C++ enabling highly sophisticated user experiences, offering applications the full capabilities of OpenGL/OpenGL ES graphics acceleration.
[factory] openSUSE 12.3 :: wrong checksums for Milestone1
Just keep in mind, that we have broken md5 and sha1 checksums for our milestone 1 images right now.
So, don’t use md5 and sha1 files to verify your ISO images. We also have MD5SUMS- and SHA1SUMS-files and they are correct (use they to verify your images).
I remind you that you can check ISO images with md5sum and sha1sum tools.
Happy testing
openSUSE :: Common Lisp Packaging Guide
About week ago Andreas Jaeger started discussion about packaging guidelines change process.
The packaging guidelines regulate all the nitty gritty details of packaging for the openSUSE distribution. There are general rules, rules about legal aspects of a package, about specific package features and about specific package types.
Until now we haven’t official rules for Common Lisp packages. For this reason I created a new page about it: Lisp Packaging Guidelines. You can find there rules and a bit information about Common Lisp packaging related stuff. It is still not official! I would like to invite all of openSUSE packagers and Lisp developers to join discussion about this and find the most interesting, correct, handy and optimal rules for openSUSE distribution (please discuss before change something in wiki).
Common Lisp the Language, 2nd Edition (Guy Steele)
Решил помочь с переводом книги Common Lisp the Language (by Guy Steele). Книга распространяется бесплатно и доступна для чтения в online.
Проект перевода был начат Михаилом Филоненко – Lisp хакером из Минска, который оформил в LaTeX исходники 23 глав книги на русском, и выложил их на github.com (фактически он один перевел почти всю книгу; работа над переводом сейчас – это просто вычитка: поиск опечаток/ошибок/неточностей).
Зачем перевод? Перевод это скучно. Я не раз слышал этот контраргумент. Я занимаюсь переводом многих интересующих меня проектов по нескольким причинам:
- Практика работы с той или иной технологией. В данном случае это git и LaTeX.
- Культура. Free and Open Source cообщество. Альтруизм
- Перевод как способ заставить себя вчитываться по-настоящему внимательно. Читая ту или иную научную документацию, не раз замечал, что, после прочтения нескольких страниц, я не могу пересказать то, о чем только что прочитал. Все вроди бы понятно, но, читая не сосредоточившись, смысл ускользает. Остается уверенность, что материал пройден и понят. Уверенность эта ошибочная

Переводя текст вы вдумываетесь в каждую мысль автора. Пытаетесь сформулировать эту же мысль на другом (как правило – родном) языке, т.е. не повторяете слова при пересказе, а ищите синонимы из другого языка. Переводя абзац за абзадцем, страницу за страницей, выстраивается целая смыславая цепочка из мыслей. Вы пересказываете и записываете каждую мысль, что является залогом понимания и запоминания материала. - Я люблю проекты, которыми занимаюсь. Lisp, openSUSE, OpenBSD… мне просто нравится быть частью этого. Занимаясь этим я постоянно узнаю что-то новое.
Ну и напоследок немного практики на всякий случай для тех, кто ещё захочет помочь. Скачиваем исходники книги:
> git clone --depth 1 https://github.com/filonenko-mikhail/cltl2-doc
Переходим в каталог с исходниками и собираем книгу в PDF:
> cd cltl2-doc > ./rumakepdf.sh
Русский текст в тех же файлах, что и английский. Ориентрироваться какая глава в каком файле: смотрим в online версии название файла. Например, первая глава – Вступление – это файл intro.html, значит её исходники лежат в файле intro.tex. Вторая глава – Типы данных – файл dtypes.tex, и т.д.
Если вы все же решите что-то перевести, свяжитесь заранее со мной или Михаилом.
Yet another method to find PCI vendor and device ID
Первым шагом написания драйвера для PCI устройства является определение его Vendor ID и Device ID. Существует много способов найти их. Кто-то советует смотреть документацию к устройству, более распространенным способом является просто заглянуть в файл include/linux/pci_ids.h. Ок, если я кернел-разработчик, то у меня естественно есть этот файл, а также я могу сделать что-то типа
> /sbin/lspci -n -s 02:00.0 02:00.0 0200: 11ab:4364 (rev 12)
…но что делать, если мне понадобился Vendor ID и Device ID на какой-нибудь, возможно даже не моей машине, где во-первых нет этого файла, а во-вторых мне также нужны Class code, BAR0-BAR5, Subvendor ID и Subdevice ID, которых lspci с ключами -n и -s не показывает?
Информацию об этом можно вытянуть из sysfs (рассматривается случай, если устройство уже зарегистрированно). Пусть это будет, к примеру, Ethernet-карта; cмотрим её адрес:
> /sbin/lspci | grep Ethernet 02:00.0 Ethernet controller: Marvell Technology Group Ltd. 88E8056 PCI-E Gigabit Ethernet Controller 05:04.0 Ethernet controller: Marvell Technology Group Ltd. 88E8001 Gigabit Ethernet Controller
Ок, карт две, с адресами 02:00.0 и 05:04.0 соответсвенно. Более подробно PCI-дерево можно увидеть через тот же lscpi, но с ключем -t (tree).
> /sbin/lspci -t
-[0000:00]-+-00.0
+-01.0-[01]--
+-1a.0
+-1a.1
+-1a.7
+-1b.0
+-1c.0-[04]----00.0
+-1c.4-[03]--+-00.0
| \-00.1
+-1c.5-[02]----00.0
+-1d.0
+-1d.1
+-1d.2
+-1d.7
+-1e.0-[05]--+-03.0
| \-04.0
+-1f.0
+-1f.2
+-1f.3
\-1f.5
Я показываю этот вывод для того, чтобы вам легче было отследить откуда я узнал адрес /sys/devices/pci0000:00/0000:00:1c.5/0000:02:00.0/:
> l /sys/devices/pci0000\:00/0000\:00\:1c.5/0000\:02\:00.0/driver lrwxrwxrwx 1 root root 0 Nov 16 22:04 /sys/devices/pci0000:00/0000:00:1c.5/0000:02:00.0/driver \ -> ../../../../bus/pci/drivers/sky2/
Да, это то устройство, и работает оно под управлением модуля sky2.
Второе висит на skge:
> l /sys/devices/pci0000\:00/0000\:00\:1e.0/0000\:05\:04.0/driver lrwxrwxrwx 1 root root 0 Nov 17 00:12 /sys/devices/pci0000:00/0000:00:1e.0/0000:05:04.0/driver \ -> ../../../../bus/pci/drivers/skge/
Каждое PCI устройство имеет область памяти (256-байт), которая содержит его конфигурацию. Эта информация является ключевым для определения марки и возможности PCI-карт. Находится она в config-файле, в том же каталоге. Прочитать её дамп можно с помощью od:
> od -x /sys/devices/pci0000\:00/0000\:00\:1c.5/0000\:02\:00.0/config 0000000 11ab 4364 0407 0010 0012 0200 0008 0000 0000020 c004 fa7f 0000 0000 8801 0000 0000 0000 0000040 0000 0000 0000 0000 0000 0000 1043 81f8 0000060 0000 fa7c 0048 0000 0000 0000 010a 0000 0000100 0000 01f0 8000 01a0 5001 fe03 2000 1300 0000120 5c03 83fc ffff ffff 0000 0100 e005 0081 0000140 300c fee0 0000 0000 41a1 0000 0000 0000 0000160 0200 0000 0000 0000 0000 0000 0000 0000 0000200 0000 0000 7000 0000 0000 0000 a882 00e8 0000220 0000 0000 0000 0000 0000 0000 0000 0000 *
Первые два бита – это Vendor ID [11ab]. Дальше (смещение 2 бита) – Device ID [4364]. Class code находится со смещением 10 бит [0200]. BAR0 – BAR5 (base address register) со смещением с 16 по 39 бит [c004...0000]. Subvendor ID имеет смещение 44 [1043], и наконец Subdevice ID имеет смещение 46 бит [81f8].
Кстати, зная Vendor и Device ID, мы можем заглянуть на pcidatabase.com и попробовать узнать побольше об этом устройстве:

Пройдя дальше по ссылке я узнал немного о производителе и других его разработках.
check point
Один важный момент, который я хотел бы рассмотреть в конце – это отсутствие информации об устройстве с device ID 4364 в include/linux/pci_ids.h. Как вы видете, там есть лишь vendor ID 11ab. Значит ли это, что карта с этим ID не поддерживается ядром? Нет, карта работает отлично, и ядро находит устройство без каких-либо проблем. Проверить это можно с помощью API ядра: pci_get_device(), которая находит (или не находит) устройство и pci-enable-device(), которая включает его.
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
#define VENDOR_ID 0x11ab
#define DEVICE_ID 0x4364
static int __init pci_start(void)
{
struct pci_dev *pdev;
pdev = pci_get_device(VENDOR_ID, DEVICE_ID, NULL);
if(!pdev)
printk("Device not found\n");
else {
printk("Device found\n");
if(pci_enable_device(pdev)) {
printk("Could not enable the device\n");
return NULL;
}
else
printk("Device enabled\n");
}
return 0;
}
static void __exit pci_exit(void)
{
printk("Bye bye");
}
module_init(pci_start);
module_exit(pci_exit);
MODULE_LICENSE("GPL");
Почему так происходит, я не знаю. Возможно вы, уважаемые мои читатели, сможете подсказать мне это?





leave a comment