1

我需要以编程方式将打印机添加到安装了 System V 过滤器的杯子中。现在我正在使用以下代码来创建添加打印机的请求:

pstRequest = ippNew();

pstRequest->request.op.operation_id = CUPS_ADD_PRINTER;
pstRequest->request.any.request_id  = 1;

ippAddString(pstRequest, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "us-ascii");
ippAddString(pstRequest, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, "en");

ippAddString(pstRequest, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser());
ippAddString(pstRequest, IPP_TAG_OPERATION, IPP_TAG_URI, "device-uri", NULL, szUri);
ippAddString(pstRequest, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, szPrinterUri);
ippAddInteger(pstRequest, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state", IPP_PRINTER_IDLE);
ippAddBoolean(pstRequest, IPP_TAG_PRINTER, "printer-is-accepting-jobs", true);

为了交谈:

szUri        = "serial:/dev/pts/12?baud=2400+bits=7+parity=none+flow=none";
szPrinterUri = "ipp://localhost/printers/myptr";

这似乎正确地将打印机添加到 cups 系统,因为我可以使用以下命令向它发送打印:

lp -d myptr test.print

我的第一个想法是将我想用作过滤器的文件复制到/etc/cups/interfaces目录中并调用它myptr。我这样做了,给了它正确的用户、组和权限,但它似乎不起作用。我什至尝试sleep 60在脚本的前面加上 a ,但它从未出现在ps.

我尝试使用lpadmin如下方式添加打印机,它可以正常工作:

lpadmin -h localhost -p myptr2 -v "serial:/dev/pts/12?baud=2400+bits=7+parity=none+flow=none" -i /tmp/my.serial.filter

我必须打电话cupsacceptcupsenable然后,但打印机工作正常,它通过我的过滤器发送打印。 lpadmin正确地将my.serial.filter文件从其中复制/tmp/etc/cups/interfaces命名myptr2,就像我在程序中所做的那样,而且,对于我的一生,我在任何杯子配置文件中都找不到对过滤器的任何引用,这让我觉得我错过了步。尽管如此,myptr2我添加的打印机lpadmin可以正常工作,而myptr我使用 API 添加的打印机在打印时不会通过过滤器进行打印

在我进行的各种 Google 搜索中,我已经阅读了CUPS 实施HTTP 和 IPP API 文档,我最接近的是,在前者中,有一条关于CUPS-Add-Modify的评论-打印机操作显示:

CUPS-Add-Modify-Printer 请求可以选择后跟要用于打印机的 PPD 文件或 System V 接口脚本。“ppd-name”属性使用本地 CUPS PPD 文件覆盖附加到请求末尾的任何文件。

这导致我尝试使用

ippAddString(pstRequest, IPP_TAG_PRINTER, IPP_TAG_NAME, "ppd-name", NULL, szFilter);

将 szFilter 设置为"/tmp/my.serial.filter"and "/etc/cups/interfaces/myptr"(当然,在单独的测试中),但无济于事。

谁能告诉我哪里可能出错了?

4

1 回答 1

1

好的,我从 cups 源代码库中获得了 lpadmin 的源代码,答案比我尝试的要容易得多。显然,我在最初的帖子中没有包含足够的来源。在上面的代码片段之后,我调用了以下代码:

pstHttpServer = httpConnectEncrypt("localhost", ippPort(), cupsEncryption());
pstResponse   = cupsDoFileRequest(pstHttpServer, pstRequest, "/admin/", NULL);
ippDelete(pstResponse);
httpClose(pstHttpServer);

(当然还有适用的错误检查)

我的问题的答案在于我NULL作为第四个参数传递给cupsDoFileRequest. 如上所述,“CUPS-Add-Modify-Printer 请求可以选择后跟 PPD 文件或 System V 接口脚本。” 我没有将两者联系在一起,但那句话是指其中的第四个参数cupsDoFileRequest,如果我放置过滤器的路径,"/tmp/my.serial.filter"请求成功my.serial.filter并被正确复制到/etc/cups/interfacesas 中myptr,之后我的所有打印myptr都通过过滤器符合预期。

因此,最终的解决方案是将pstResponse上面的行更改如下:

pstResponse   = cupsDoFileRequest(pstHttpServer, pstRequest, "/admin/", "/tmp/my.serial.filter");
于 2012-07-19T21:51:38.593 回答