Files

206 lines
5.7 KiB
Markdown
Raw Permalink Normal View History

<!--
SPDX-FileCopyrightText: 2026 Contributors to cups-kyocera-rastertokpsl-fix
SPDX-License-Identifier: CC0-1.0
-->
# CUPS wrapper для Kyocera `rastertokpsl`
Обёртка для CUPS-фильтра `rastertokpsl`, предназначенная для устранения падений оригинального Kyocera-фильтра при печати заданий с длинными или не-ASCII названиями.
## Проблема
Некоторые версии Kyocera `rastertokpsl` используют фиксированный буфер для обработки названия задания. При передаче длинной строки или строки с кириллицей это может приводить к переполнению буфера и аварийному завершению фильтра:
```text
*** buffer overflow detected ***: terminated
```
В журналах CUPS это может выглядеть примерно так:
```text
PID 30752 (/usr/lib/cups/filter/rastertokpsl) crashed on signal 6
```
В результате задание не печатается, а очередь принтера может перейти в состояние `stopped`.
## Решение
Wrapper перехватывает аргументы CUPS перед запуском оригинального `rastertokpsl`.
Перед передачей названия задания оригинальному фильтру wrapper:
- преобразует UTF-8 в ASCII;
- удаляет неподдерживаемые символы;
- ограничивает длину строки;
- использует `print-job`, если после обработки строка оказалась пустой.
Оригинальный бинарник сохраняется под именем:
```text
/usr/lib/cups/filter/rastertokpsl.real
```
Wrapper устанавливается вместо него:
```text
/usr/lib/cups/filter/rastertokpsl
```
## Установка
Сначала сохраните оригинальный фильтр:
```bash
sudo cp /usr/lib/cups/filter/rastertokpsl \
/usr/lib/cups/filter/rastertokpsl.real
```
Создайте файл wrapper:
```bash
sudo nano /usr/lib/cups/filter/rastertokpsl
```
Содержимое:
```bash
#!/bin/bash
REAL="/usr/lib/cups/filter/rastertokpsl.real"
# Kyocera rastertokpsl uses the following arguments:
# $1 printer
# $2 job-id
# $3 title
# $4 copies
# $5 options
if [ "$#" -ne 5 ]; then
echo "ERROR: rastertokpsl wrapper: expected 5 arguments, got $#" >&2
exit 1
fi
printer="$1"
job_id="$2"
title="$3"
copies="$4"
options="$5"
# Convert the title to ASCII, remove unsupported characters,
# and limit its length to 20 characters.
safe_title="$(
printf '%s' "$title" |
iconv -f UTF-8 -t ASCII//TRANSLIT 2>/dev/null |
LC_ALL=C tr -cd 'A-Za-z0-9' |
tail -c 20
)"
[ -n "$safe_title" ] || safe_title="print-job"
# Pass the raster data through stdin.
exec "$REAL" \
"$printer" \
"$job_id" \
"$safe_title" \
"$copies" \
"$options"
```
Назначьте права:
```bash
sudo chown root:root /usr/lib/cups/filter/rastertokpsl
sudo chmod 755 /usr/lib/cups/filter/rastertokpsl
sudo chmod 755 /usr/lib/cups/filter/rastertokpsl.real
```
Перезапустите CUPS:
```bash
sudo systemctl restart cups
```
## Проверка
Убедитесь, что оригинальный файл является исполняемым бинарником:
```bash
file /usr/lib/cups/filter/rastertokpsl.real
```
Ожидается вывод с `ELF ... executable`.
Проверьте печать обычного задания:
```bash
lp -d PRINTER /tmp/test.pdf
```
Затем проверьте длинное название задания:
```bash
lp -d PRINTER \
-t "Очень длинное кириллическое название задания для проверки" \
/tmp/test.pdf
```
Посмотреть состояние очереди:
```bash
lpstat -p
lpstat -o
```
При необходимости включить подробное логирование CUPS:
```bash
sudo cupsctl --debug-logging
sudo tail -F /var/log/cups/error_log
```
После завершения диагностики:
```bash
sudo cupsctl --no-debug-logging
```
## Восстановление оригинального фильтра
Чтобы удалить wrapper и вернуть оригинальный `rastertokpsl`:
```bash
sudo mv /usr/lib/cups/filter/rastertokpsl.real \
/usr/lib/cups/filter/rastertokpsl
sudo systemctl restart cups
```
## Ограничения
Wrapper рассчитан на конкретный вариант интерфейса Kyocera `rastertokpsl`, использующий пять аргументов:
```text
printer job-id title copies options
```
Размер `20` символов выбран как консервативное ограничение для проблемных версий фильтра. Точный размер внутреннего буфера конкретной версии `rastertokpsl` зависит от драйвера и не определяется самим CUPS.
Перед установкой рекомендуется сохранить исходный бинарник и проверить версию драйвера.
## Структура
Пример структуры репозитория:
```text
cups-kyocera-rastertokpsl-fix/
├── README.md
└── rastertokpsl
```
Файл `rastertokpsl` из репозитория устанавливается в:
```text
/usr/lib/cups/filter/rastertokpsl
```