Всячина. Выпуск 14 (04.04.1999)


Сегодня во "Всячине" рассказ Вита Тимчишина об истории создания FTPIFS -- драйвера, позволяющего работать с FTP-хостом как с локальным диском. На скриншоте справа (62k, сделан Евгением Кулешовым) вы можете увидеть содержимое файлового архива hobbes.nmsu.edu, отображённое в виде дерева прямо на десктоп.


Предыстория

Началось всё летом 1998 года. Програмированием я к тому времени уже занимался достаточно долго, но все больше под Windows на Дельфях клепал базки. Конечно, к тому времени уже был освоен Рекс и написано было много хороших и полезных скриптиков, но хотелось чего-то большего (да и клепание базок порядком надоело).

В первую очередь передо мной встала проблема языка. Лучше всего я владел Паскалем, но оценив ситуацию понял, что под паскаль юнитов не найдешь, а хедеры конвертить мне совсем не хотелось. Поэтому я решил осваивать С.

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

Родилось два варианта. Первый -- SMTP+POP3 сервер. Попроще, чем SendMail, но покруче, чем Inet.Mail. К тому времени я окончательно разочаровался в Inet.Mail'е, а SendMail считал не совсем подходящим для более/менее простых ситуаций. Это должен был бы быть Rexx-based сервер с очень широкой настраиваемостью. Но: Inet.Mail всё-таки закрывал большую часть моих запросов и проект немного отошел на задний план.

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

И вот однажды я зашел на свой любимый канал #OS2russian. Там шло активное обсуждение петиции к автору FileCommander/2 по поводу FTP плагина. Я подумал (и сказал): "А почему бы не сделать лучше -- написать драйвер, который позволит реализовать это system-wide". Так зародилась идея FTPIFS.

Подготовка

Я начал разбираться в вопросе и оказалось, что всё не так уж просто.

Во-первых: DDK (набор для создания драйверов) у меня есть, но об IFS там ни слова.

Во-вторых: Драйвер надо чем-то компилировать, причем в 16-битном режиме. VAC++ такого не умеет.

В-третьих: Судя по всему драйвер не может не то, что к TCP/IP обратиться, но даже файл открыть.

После непродолжительных поисков было найдено описание того, как строить IFS -- ifs.inf (где-то на хоббесах). Также я обнаружил и подписался на список рассылки по драйверам Тимура Таби. В нем всегда готовы тебе помочь. И наконец я нашел серию статей в EDM/2 с описанием как делать IFS, причем с исходными текстами!!! Я выражаю огромную благодарность автору тех статей. В этих же статьях был описан интересный метод разбиения IFS на две части: собственно драйвер и связаная с ним прикладная программа (то, что сейчас называется ftp.ifs и r3comm.exe соответственно).

Для компиляции нашелся MSC 6, который раздается на Веб-узле IBM рядом с DDK, но к сожалению без документации.

Начало

Итак, вроде бы все есть, можно начинать. Но не тут-то было. Исходники оказались расчитаны не на тот компилятор (то ли Watcom C, то ли вообще Borland). "Ладно", - подумал я и взял в руки напильник ;)

После отпиливания и удаления многих частей драйвер собрался, но OS/2 не признала его за IFS. Еще немного работы и он уже загружается, но при попытке усложнения вываливается в трап.

Тогда я подумал и решил, что избран неверный путь. Вместо того, чтобы пилять неподходящие исходники проще написать свои с использованием кусочков из примера. Тут уже дело пошло и через некоторое время мне даже удалось вывести на экран сообщение при загрузке драйвера. Эта была почти что победа!! ;)

Отступление на тему структуры

Думаю, пора рассказать, что же всё-таки представляют из себя драйвера, разделенные на r0 (драйвер) и r3 (прикладная программа) части.

Есть много драйверов, которые либо достаточно сложны, либо не работают напрямую с железом, а реализуют более высокую логику. Такие драйвера удобно писать в "раздвоеном" виде. На то есть несколько причин:

  1. Собственно драйвер значительно упрощается, что важно из-за 16-битной модели (которая имеет свои ограничения) и отладки.
    Отладка драйверов -- дело в высшей степени неприятное. Во-первых, при ошибке программы слетает только программа, а при ошибке драйвера -- вся система. Во-вторых, для отладки драйвера нужно иметь два компьютера и специальный отладчик.
  2. Нехватка функций. Считается, что драйвер будет работать напрямую с 'железом', поэтому в его распоряжении лишь ограниченый набор функций для работы с памятью, прерываниями, потоками. Ни тебе файл открыть, ни DLL загрузить. Во многих случаях это неприемлемо.
В таких случаях драйвер делят на две части:

  1. Простейшая часть, которая работает в режиме драйвера (0 кольцо) и всего лишь передает все запросы второй части. (Или выполняет несложные операции). Дальше я буду называть её 'r0'
  2. Прикладная программа, которая обрабатывает запросы. Дальше я буду называть её 'r3'

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

Создание

Здесь я хотел бы рассказать об основных проблемах, которые возникли в процессе разработки программы:

  1. Описаный выше механизм (именно он был реализован в примерах) работает в синхронном режиме, то есть пока выполняется один запрос, остальные ждут. Мне с моим медленным протоколом это не подходило.
    Я немного поразмышлял и придумал следующий вариант: После получения запроса r3 создает поток на выполнение, а сама идет за следующим. В то же время, когда поток заканчивает обработку, он сам вызывает драйвер и отдает результат.
    Таким образом, я имею синхронное получение запросов и асинхронное возвращение результатов, что позволяет обрабатывать неограниченое количество запросов одновременно.
  2. Глюки ;) Естественно, проект не обошелся без своего набора глюков и неприятностей. К счастью, единственный серьёзный (вызывающий трап системы) глюк в драйвере был обнаружен мной и успешно обезврежен. Сейчас драйверная часть вылизана и не меняется уже несколько месяцев.
  3. Документация. К сожалению, документация по написанию IFS в некоторых местах неполная. Я обошёл это, узнавая о темных моментах из списка рассылки по драйверам Тимура Таби и исходных тестов ext2fs.ifs.
  4. Листинги. FTP очень неплохой протокол по передаче файлов. К сожалению, до сих пор нет единого стандарта на выдачу списка файлов. Поэтому приходится постоянно усложнять процедуру для разбора списков для добавления новых вариантов.

Состояние проекта

На текущий момент проект развивается, последняя версия -- 0.04a, в которой появилось несколько новых полезных функций. Проект оказался нужен и не имеет аналогов (правда, ещё в процессе работы над ним я слышал по крайней мере о двух других подобных проектах и даже пытался объединится с одним из них, но долгое время ничего уже не слышно).

Сейчас я жду новых предложений от пользователей, так как мой список пожеланий потихоньку опустошается. Следующим большим шагом (после полной поддержки чтения/записи) я наметил поддержку набора конфигурируемых пользователем форматов листинга. То есть не нужно будет ждать новой версии FTPIFS для поддержки листинга своего любимого сервера, а просто написать самому (или с моей помощью) файл для его распознавания.

Vit Timchishin


к предыдущему выпуску | к следующему выпуску


Интересные ссылки:
Комментариев к странице: 0 | Добавить комментарий
Домой | Проект ядро Core/2 | Проект OS/4 Download | Новости | Гостевая книга | Подробно обо всем | Нужные программы | Проекты | OS/2 FAQ | Всячина | За и Против | Металлолом | #OS2Russian | RDM/2 | Весёлые картинки | Наша галерея | Доска объявлений | Карта сайта | ПОИСК | ФОРУМ