feat: add Kyocera rastertokpsl CUPS wrapper
This commit is contained in:
@@ -0,0 +1,205 @@
|
|||||||
|
<!--
|
||||||
|
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
|
||||||
|
```
|
||||||
Executable
+40
@@ -0,0 +1,40 @@
|
|||||||
|
#!/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 keep only the last 20 alphanumeric 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"
|
||||||
Reference in New Issue
Block a user