Энтузиаст рассказал, как несколько месяцев назад он запустил справочного бота Daily для команд MS-DOS 6.22.
Сначала он подготовил файл JSON с описаниями и комментариями к командам, в том числе из справочного руководства MS-DOS. Затем энтузиаст написал простой Bash-скрипт, который выбирает случайную команду, извлекает её описание из файла JSON и публикует сообщение через API Mastodon.
Чтобы делать скриншоты в тот момент, когда MS-DOS выполняет запрошенную команду, разработчик создал виртуальную машину с QEMU для запуска команд из файла данных. В этом сценарии QEMU показал хорошую работу благодаря встроенному интерфейсу монитора, который позволит взаимодействовать с виртуальной машиной из хост-системы.
Он начал с создания файла образа, который будет выступать виртуальным жёстким диском для установки MS-DOS:
qemu-img create msdos622.img 512M
Базовая установка MS-DOS 6.22 включает три образа дискет. Первая является загрузочной, и с неё начнется процесс установки. Для удобства энтузиаст назвал образы дискет Disk1.img, Disk2.img и Disk3.img в том же порядке, в котором их будет запрашивать программа установки.
Он выбрал простую виртуальную машину на базе 486 с объёмом оперативной памяти 8 МБ.
qemu-system-i386 -drive format=raw,file=Disk1.img,index=0,if=floppy -drive format=raw,file=msdos622.img,index=0,if=ide -m 8 -cpu 486
После запуска QEMU виртуальная машина загрузилась с образа дискеты Disk1.img и запустила программу установки.
Под руководством установщика энтузиаст разбил виртуальный жёсткий диск на разделы и позволил установщику начать копирование содержимого с образа дискеты на него. После этого программа установки запросила вторую дискету.
Чтобы заменить Disk1.img на Disk2.img в виртуальной машине, разработчик переключился на монитор QEMU, нажав Ctrl+Alt+2 внутри окна QEMU. Замену образа дискеты он выполнил следующей командой:
change floppy0 Disk2.img
Установив новый образ дискеты, энтузиаст снова переключился на виртуальную машину с помощью Ctrl+Alt+1 и продолжил установку.
Как только программа завершила обработку всех трёх дискет, она попросила извлечь последнюю из привода.
Для этого через монитор QEMU нужно ввести команду:
eject floppy0
После перезагрузки система запустилась.
Чтобы подключить монитор QEMU к хост-системе энтузиаст использовал сеть, чтобы отправлять произвольные команды виртуальной машине. Одновременно он переключил виртуальную консоль в текстовый режим, поскольку бот и, следовательно, QEMU работают на сервере без графического интерфейса.
qemu-system-i386 -hda msdos622.img -m 8 -cpu 486 -monitor tcp:localhost:9999,server,nowait -nographic &
Запуск виртуальной машины таким образом предоставляет монитору QEMU доступ к порту 9999 хост-компьютера. Однако команда QEMU sendkey принимает только один символ за раз, поэтому команды DOS нужно разложить на отдельные символы, например, с помощью скрипта sendkeys.awk.
Этот скрипт принимает полные строки и разбивает их на отдельные символы с преобразованием:
$ echo «ver» | awk -f sendkeys.awk | timeout 1 nc localhost 9999 QEMU 8.2.0 monitor — type ‘help’ for more information (qemu) sendkey v (qemu) vsendkey e (qemu) esendkey r (qemu) rsendkey ret (qemu) … MS-DOS Version 6.22 C:>
Для вывода скриншотов энтузиаст задействовал команду screendump через монитор QEMU. Она создаёт растровый файл в формате PPM.
Поскольку в настоящее время этот формат несовместим с большинством веб-приложений, то для конвертации можно использовать утилиту от ImageMagick.
convert ms-dos-vm-screendump.ppm ms-dos-vm-screendump.webp
Файл JSON хранит команды вместе с их описаниями, а каждая запись в файле данных соответствует одному и тому же шаблону:
{ «command»: «SYS», «description»: «Copies MS-DOS system files to a disk’s master boot record.», «verbose_description»: «The SYS command is used to copy MS-DOS system files to a disk’s master boot record (MBR), making it bootable. It’s often used to create bootable system disks for MS-DOS installations.», «show_help»: «yes» },
Каждое сообщение, которое публикует бот, содержит команду, описание и его детали во втором абзаце. Если для параметра show_help установлено значение «да», бот передает параметр /? для command.
Последний шаг заключался в написании простого скрипта, который выбирает команду, запускает виртуальную машину, делает снимок экрана и загружает его через API Mastodon.
Поскольку содержимое файла JSON является динамическим, то энтузиаст проверял длину файла, чтобы увидеть, сколько команд может выбрать скрипт.
После выбора случайной команды отдельные элементы записи JSON объединяются в финальную строку QUOTE, которая содержит полное сообщение:
# Calculate number of entries in json datafile MAXNUMBER=$(jq ‘.[].command’ dosreference.json | wc -l) MAXNUMBER=»$((MAXNUMBER-1))» RANDOMNUMBER=$(shuf -i 0-$MAXNUMBER -n 1) # Fetch random entry from json datafile COMMAND=$(jq -r —argjson randomnumber «${RANDOMNUMBER}» ‘.[$randomnumber].command’ dosreference.json) COMMAND_DESCRIPTION=»$(jq -r —argjson randomnumber «${RANDOMNUMBER}» ‘.[$randomnumber].description’ dosreference.json) nn» COMMAND_VERBOSE_DESCRIPTION=»$(jq -r —argjson randomnumber «${RANDOMNUMBER}» ‘.[$randomnumber].verbose_description’ dosreference.json)» COMMAND_SHOW_HELP=»$(jq -r —argjson randomnumber «${RANDOMNUMBER}» ‘.[$randomnumber].show_help’ dosreference.json)» QUOTE=»status=$(echo «${COMMAND}»: «${COMMAND_DESCRIPTION}»»${COMMAND_VERBOSE_DESCRIPTION}»)» if [ «$COMMAND_SHOW_HELP» = «yes» ]; then COMMAND=»${COMMAND} /?» fi
Затем он запустил виртуальную машину и передал ей команду, созданную на основе вывода JSON. После создания снимка экрана она отключается через монитор и готова к перезапуску при следующем запуске задания cron, ответственного за сценарий.
qemu-system-i386 -hda msdos622.img -m 8 -cpu 486 -monitor tcp:localhost:9999,server,nowait -nographic & sleep 30 # Execute command in VM echo «cls» | awk -f qemu-sendkeys.awk | timeout 1 nc localhost 9999 echo «${COMMAND}» | awk -f qemu-sendkeys.awk | timeout 5 nc localhost 9999 # Create screenshot of VM echo «screendump ms-dos-vm-screendump.ppm» | timeout 1 nc localhost 9999 # Kill VM echo «quit» | timeout 1 nc localhost 9999 convert ms-dos-vm-screendump.ppm ms-dos-vm-screendump.webp
После этого требуется загрузить скриншот в Mastodon, дождаться его обработки и прикрепить к сообщению:
# Upload image to Mastodon MEDIA_ID=$(curl -s -X POST -H «Content-Type: multipart/form-data» https://manitu.social/api/v2/media -H ‘Authorization: Bearer XXXXXXXXXXXXXXXX’ —form file=»@ms-dos-vm-screendump.webp» | jq -r ‘.id’) # Wait for the image to process… sleep 10 # Go! curl -g https://manitu.social/api/v1/statuses -H «Authorization: Bearer XXXXXXXXXXXXXXXX» -F «$QUOTE» -F «media_ids[]=${MEDIA_ID}»
Ранее разработчик Йо Кхэн Мэн написал клиента ChatGPT для MS-DOS и запустил чат-бота из командной строки на своём портативном ПК на базе IBM 5155 с центральным процессором Intel 8088. Клиент ChatGPT работает через сетевое соединение с современным ПК, подключённым к API OpenAI. Исходный код проекта doschgpt доступен на GitHub под открытой лицензией GNU General Public License v3.0.
Источник: habr.com