2 title: CUPS Programming Manual
3 author: Michael R Sweet
4 copyright: Copyright © 2007-2019 by Apple Inc. All Rights Reserved.
8 > Please [file issues on Github](https://github.com/apple/cups/issues) to
9 > provide feedback on this document.
14 CUPS provides the "cups" library to talk to the different parts of CUPS and with
15 Internet Printing Protocol (IPP) printers. The "cups" library functions are
16 accessed by including the `<cups/cups.h>` header.
18 CUPS is based on the Internet Printing Protocol ("IPP"), which allows clients
19 (applications) to communicate with a server (the scheduler, printers, etc.) to
20 get a list of destinations, send print jobs, and so forth. You identify which
21 server you want to communicate with using a pointer to the opaque structure
22 `http_t`. The `CUPS_HTTP_DEFAULT` constant can be used when you want to talk to
28 When writing software (other than printer drivers) that uses the "cups" library:
30 - Do not use undocumented or deprecated APIs,
31 - Do not rely on pre-configured printers,
32 - Do not assume that printers support specific features or formats, and
33 - Do not rely on implementation details (PPDs, etc.)
35 CUPS is designed to insulate users and developers from the implementation
36 details of printers and file formats. The goal is to allow an application to
37 supply a print file in a standard format with the user intent ("print four
38 copies, two-sided on A4 media, and staple each copy") and have the printing
39 system manage the printer communication and format conversion needed.
41 Similarly, printer and job management applications can use standard query
42 operations to obtain the status information in a common, generic form and use
43 standard management operations to control the state of those printers and jobs.
47 > CUPS printer drivers necessarily depend on specific file formats and certain
48 > implementation details of the CUPS software. Please consult the Postscript
49 > and raster printer driver developer documentation on
50 > [CUPS.org](https://www.cups.org/documentation.html) for more information.
53 ## Terms Used in This Document
55 A *Destination* is a printer or print queue that accepts print jobs. A
56 *Print Job* is a collection of one or more documents that are processed by a
57 destination using options supplied when creating the job. A *Document* is a
58 file (JPEG image, PDF file, etc.) suitable for printing. An *Option* controls
59 some aspect of printing, such as the media used. *Media* is the sheets or roll
60 that is printed on. An *Attribute* is an option encoded for an Internet
61 Printing Protocol (IPP) request.
64 ## Compiling Programs That Use the CUPS API
66 The CUPS libraries can be used from any C, C++, or Objective C program.
67 The method of compiling against the libraries varies depending on the
68 operating system and installation of CUPS. The following sections show how
69 to compile a simple program (shown below) in two common environments.
71 The following simple program lists the available destinations:
74 #include <cups/cups.h>
76 int print_dest(void *user_data, unsigned flags, cups_dest_t *dest)
79 printf("%s/%s\n", dest->name, dest->instance);
88 cupsEnumDests(CUPS_DEST_FLAGS_NONE, 1000, NULL, 0, 0, print_dest, NULL);
94 ### Compiling with Xcode
96 In Xcode, choose *New Project...* from the *File* menu (or press SHIFT+CMD+N),
97 then select the *Command Line Tool* under the macOS Application project type.
98 Click *Next* and enter a name for the project, for example "firstcups". Click
99 *Next* and choose a project directory. The click *Next* to create the project.
101 In the project window, click on the *Build Phases* group and expand the
102 *Link Binary with Libraries* section. Click *+*, type "libcups" to show the
103 library, and then double-click on `libcups.tbd`.
105 Finally, click on the `main.c` file in the sidebar and copy the example program
106 to the file. Build and run (CMD+R) to see the list of destinations.
109 ### Compiling with GCC
111 From the command-line, create a file called `simple.c` using your favorite
112 editor, copy the example to this file, and save. Then run the following command
113 to compile it with GCC and run it:
115 gcc -o simple `cups-config --cflags` simple.c `cups-config --libs`
118 The `cups-config` command provides the compiler flags (`cups-config --cflags`)
119 and libraries (`cups-config --libs`) needed for the local system.
122 # Working with Destinations
124 Destinations, which in CUPS represent individual printers or classes
125 (collections or pools) of printers, are represented by the `cups_dest_t`
126 structure which includes the name \(`name`), instance \(`instance`, saved
127 options/settings), whether the destination is the default for the user
128 \(`is_default`), and the options and basic information associated with that
129 destination \(`num_options` and `options`).
131 Historically destinations have been manually maintained by the administrator of
132 a system or network, but CUPS also supports dynamic discovery of destinations on
136 ## Finding Available Destinations
138 The `cupsEnumDests` function finds all of the available destinations:
141 cupsEnumDests(unsigned flags, int msec, int *cancel,
142 cups_ptype_t type, cups_ptype_t mask,
143 cups_dest_cb_t cb, void *user_data)
145 The `flags` argument specifies enumeration options, which at present must be
146 `CUPS_DEST_FLAGS_NONE`.
148 The `msec` argument specifies the maximum amount of time that should be used for
149 enumeration in milliseconds - interactive applications should keep this value to
150 5000 or less when run on the main thread.
152 The `cancel` argument points to an integer variable that, when set to a non-zero
153 value, will cause enumeration to stop as soon as possible. It can be `NULL` if
156 The `type` and `mask` arguments are bitfields that allow the caller to filter
157 the destinations based on categories and/or capabilities. The destination's
158 "printer-type" value is masked by the `mask` value and compared to the `type`
159 value when filtering. For example, to only enumerate destinations that are
160 hosted on the local system, pass `CUPS_PRINTER_LOCAL` for the `type` argument
161 and `CUPS_PRINTER_DISCOVERED` for the `mask` argument. The following constants
162 can be used for filtering:
164 - `CUPS_PRINTER_CLASS`: A collection of destinations.
165 - `CUPS_PRINTER_FAX`: A facsimile device.
166 - `CUPS_PRINTER_LOCAL`: A local printer or class. This constant has the value 0
167 (no bits set) and is only used for the `type` argument and is paired with the
168 `CUPS_PRINTER_REMOTE` or `CUPS_PRINTER_DISCOVERED` constant passed in the
170 - `CUPS_PRINTER_REMOTE`: A remote (shared) printer or class.
171 - `CUPS_PRINTER_DISCOVERED`: An available network printer or class.
172 - `CUPS_PRINTER_BW`: Can do B&W printing.
173 - `CUPS_PRINTER_COLOR`: Can do color printing.
174 - `CUPS_PRINTER_DUPLEX`: Can do two-sided printing.
175 - `CUPS_PRINTER_STAPLE`: Can staple output.
176 - `CUPS_PRINTER_COLLATE`: Can quickly collate copies.
177 - `CUPS_PRINTER_PUNCH`: Can punch output.
178 - `CUPS_PRINTER_COVER`: Can cover output.
179 - `CUPS_PRINTER_BIND`: Can bind output.
180 - `CUPS_PRINTER_SORT`: Can sort output (mailboxes, etc.)
181 - `CUPS_PRINTER_SMALL`: Can print on Letter/Legal/A4-size media.
182 - `CUPS_PRINTER_MEDIUM`: Can print on Tabloid/B/C/A3/A2-size media.
183 - `CUPS_PRINTER_LARGE`: Can print on D/E/A1/A0-size media.
184 - `CUPS_PRINTER_VARIABLE`: Can print on rolls and custom-size media.
186 The `cb` argument specifies a function to call for every destination that is
189 typedef int (*cups_dest_cb_t)(void *user_data,
193 The callback function receives a copy of the `user_data` argument along with a
194 bitfield \(`flags`) and the destination that was found. The `flags` argument
195 can have any of the following constant (bit) values set:
197 - `CUPS_DEST_FLAGS_MORE`: There are more destinations coming.
198 - `CUPS_DEST_FLAGS_REMOVED`: The destination has gone away and should be removed
199 from the list of destinations a user can select.
200 - `CUPS_DEST_FLAGS_ERROR`: An error occurred. The reason for the error can be
201 found by calling the `cupsLastError` and/or `cupsLastErrorString` functions.
203 The callback function returns 0 to stop enumeration or 1 to continue.
207 > The callback function will likely be called multiple times for the
208 > same destination, so it is up to the caller to suppress any duplicate
211 The following example shows how to use `cupsEnumDests` to get a filtered array
221 my_dest_cb(my_user_data_t *user_data, unsigned flags,
224 if (flags & CUPS_DEST_FLAGS_REMOVED)
227 * Remove destination from array...
230 user_data->num_dests =
231 cupsRemoveDest(dest->name, dest->instance,
232 user_data->num_dests,
233 &(user_data->dests));
238 * Add destination to array...
241 user_data->num_dests =
242 cupsCopyDest(dest, user_data->num_dests,
243 &(user_data->dests));
250 my_get_dests(cups_ptype_t type, cups_ptype_t mask,
253 my_user_data_t user_data = { 0, NULL };
255 if (!cupsEnumDests(CUPS_DEST_FLAGS_NONE, 1000, NULL, type,
256 mask, (cups_dest_cb_t)my_dest_cb,
260 * An error occurred, free all of the destinations and
264 cupsFreeDests(user_data.num_dests, user_dasta.dests);
272 * Return the destination array...
275 *dests = user_data.dests;
277 return (user_data.num_dests);
281 ## Basic Destination Information
283 The `num_options` and `options` members of the `cups_dest_t` structure provide
284 basic attributes about the destination in addition to the user default options
285 and values for that destination. The following names are predefined for various
286 destination attributes:
288 - "auth-info-required": The type of authentication required for printing to this
289 destination: "none", "username,password", "domain,username,password", or
290 "negotiate" (Kerberos).
291 - "printer-info": The human-readable description of the destination such as "My
293 - "printer-is-accepting-jobs": "true" if the destination is accepting new jobs,
295 - "printer-is-shared": "true" if the destination is being shared with other
296 computers, "false" otherwise.
297 - "printer-location": The human-readable location of the destination such as
299 - "printer-make-and-model": The human-readable make and model of the destination
300 such as "ExampleCorp LaserPrinter 4000 Series".
301 - "printer-state": "3" if the destination is idle, "4" if the destination is
302 printing a job, and "5" if the destination is stopped.
303 - "printer-state-change-time": The UNIX time when the destination entered the
305 - "printer-state-reasons": Additional comma-delimited state keywords for the
306 destination such as "media-tray-empty-error" and "toner-low-warning".
307 - "printer-type": The `cups_ptype_t` value associated with the destination.
308 - "printer-uri-supported": The URI associated with the destination; if not set,
309 this destination was discovered but is not yet setup as a local printer.
311 Use the `cupsGetOption` function to retrieve the value. For example, the
312 following code gets the make and model of a destination:
314 const char *model = cupsGetOption("printer-make-and-model",
319 ## Detailed Destination Information
321 Once a destination has been chosen, the `cupsCopyDestInfo` function can be used
322 to gather detailed information about the destination:
325 cupsCopyDestInfo(http_t *http, cups_dest_t *dest);
327 The `http` argument specifies a connection to the CUPS scheduler and is
328 typically the constant `CUPS_HTTP_DEFAULT`. The `dest` argument specifies the
329 destination to query.
331 The `cups_dinfo_t` structure that is returned contains a snapshot of the
332 supported options and their supported, ready, and default values. It also can
333 report constraints between different options and values, and recommend changes
334 to resolve those constraints.
337 ### Getting Supported Options and Values
339 The `cupsCheckDestSupported` function can be used to test whether a particular
340 option or option and value is supported:
343 cupsCheckDestSupported(http_t *http, cups_dest_t *dest,
348 The `option` argument specifies the name of the option to check. The following
349 constants can be used to check the various standard options:
351 - `CUPS_COPIES`: Controls the number of copies that are produced.
352 - `CUPS_FINISHINGS`: A comma-delimited list of integer constants that control
353 the finishing processes that are applied to the job, including stapling,
354 punching, and folding.
355 - `CUPS_MEDIA`: Controls the media size that is used, typically one of the
356 following: `CUPS_MEDIA_3X5`, `CUPS_MEDIA_4X6`, `CUPS_MEDIA_5X7`,
357 `CUPS_MEDIA_8X10`, `CUPS_MEDIA_A3`, `CUPS_MEDIA_A4`, `CUPS_MEDIA_A5`,
358 `CUPS_MEDIA_A6`, `CUPS_MEDIA_ENV10`, `CUPS_MEDIA_ENVDL`, `CUPS_MEDIA_LEGAL`,
359 `CUPS_MEDIA_LETTER`, `CUPS_MEDIA_PHOTO_L`, `CUPS_MEDIA_SUPERBA3`, or
360 `CUPS_MEDIA_TABLOID`.
361 - `CUPS_MEDIA_SOURCE`: Controls where the media is pulled from, typically either
362 `CUPS_MEDIA_SOURCE_AUTO` or `CUPS_MEDIA_SOURCE_MANUAL`.
363 - `CUPS_MEDIA_TYPE`: Controls the type of media that is used, typically one of
364 the following: `CUPS_MEDIA_TYPE_AUTO`, `CUPS_MEDIA_TYPE_ENVELOPE`,
365 `CUPS_MEDIA_TYPE_LABELS`, `CUPS_MEDIA_TYPE_LETTERHEAD`,
366 `CUPS_MEDIA_TYPE_PHOTO`, `CUPS_MEDIA_TYPE_PHOTO_GLOSSY`,
367 `CUPS_MEDIA_TYPE_PHOTO_MATTE`, `CUPS_MEDIA_TYPE_PLAIN`, or
368 `CUPS_MEDIA_TYPE_TRANSPARENCY`.
369 - `CUPS_NUMBER_UP`: Controls the number of document pages that are placed on
371 - `CUPS_ORIENTATION`: Controls the orientation of document pages placed on the
372 media: `CUPS_ORIENTATION_PORTRAIT` or `CUPS_ORIENTATION_LANDSCAPE`.
373 - `CUPS_PRINT_COLOR_MODE`: Controls whether the output is in color
374 \(`CUPS_PRINT_COLOR_MODE_COLOR`), grayscale
375 \(`CUPS_PRINT_COLOR_MODE_MONOCHROME`), or either
376 \(`CUPS_PRINT_COLOR_MODE_AUTO`).
377 - `CUPS_PRINT_QUALITY`: Controls the generate quality of the output:
378 `CUPS_PRINT_QUALITY_DRAFT`, `CUPS_PRINT_QUALITY_NORMAL`, or
379 `CUPS_PRINT_QUALITY_HIGH`.
380 - `CUPS_SIDES`: Controls whether prints are placed on one or both sides of the
381 media: `CUPS_SIDES_ONE_SIDED`, `CUPS_SIDES_TWO_SIDED_PORTRAIT`, or
382 `CUPS_SIDES_TWO_SIDED_LANDSCAPE`.
384 If the `value` argument is `NULL`, the `cupsCheckDestSupported` function returns
385 whether the option is supported by the destination. Otherwise, the function
386 returns whether the specified value of the option is supported.
388 The `cupsFindDestSupported` function returns the IPP attribute containing the
389 supported values for a given option:
392 cupsFindDestSupported(http_t *http, cups_dest_t *dest,
396 For example, the following code prints the supported finishing processes for a
397 destination, if any, to the standard output:
399 cups_dinfo_t *info = cupsCopyDestInfo(CUPS_HTTP_DEFAULT,
402 if (cupsCheckDestSupported(CUPS_HTTP_DEFAULT, dest, info,
403 CUPS_FINISHINGS, NULL))
405 ipp_attribute_t *finishings =
406 cupsFindDestSupported(CUPS_HTTP_DEFAULT, dest, info,
408 int i, count = ippGetCount(finishings);
410 puts("finishings supported:");
411 for (i = 0; i < count; i ++)
412 printf(" %d\n", ippGetInteger(finishings, i));
415 puts("finishings not supported.");
417 The "job-creation-attributes" option can be queried to get a list of supported
418 options. For example, the following code prints the list of supported options
419 to the standard output:
421 ipp_attribute_t *attrs =
422 cupsFindDestSupported(CUPS_HTTP_DEFAULT, dest, info,
423 "job-creation-attributes");
424 int i, count = ippGetCount(attrs);
426 for (i = 0; i < count; i ++)
427 puts(ippGetString(attrs, i, NULL));
430 ### Getting Default Values
432 There are two sets of default values - user defaults that are available via the
433 `num_options` and `options` members of the `cups_dest_t` structure, and
434 destination defaults that available via the `cups_dinfo_t` structure and the
435 `cupsFindDestDefault` function which returns the IPP attribute containing the
436 default value(s) for a given option:
439 cupsFindDestDefault(http_t *http, cups_dest_t *dest,
443 The user defaults from `cupsGetOption` should always take preference over the
444 destination defaults. For example, the following code prints the default
445 finishings value(s) to the standard output:
447 const char *def_value =
448 cupsGetOption(CUPS_FINISHINGS, dest->num_options,
450 ipp_attribute_t *def_attr =
451 cupsFindDestDefault(CUPS_HTTP_DEFAULT, dest, info,
454 if (def_value != NULL)
456 printf("Default finishings: %s\n", def_value);
460 int i, count = ippGetCount(def_attr);
462 printf("Default finishings: %d",
463 ippGetInteger(def_attr, 0));
464 for (i = 1; i < count; i ++)
465 printf(",%d", ippGetInteger(def_attr, i));
470 ### Getting Ready (Loaded) Values
472 The finishings and media options also support queries for the ready, or loaded,
473 values. For example, a printer may have punch and staple finishers installed
474 but be out of staples - the supported values will list both punch and staple
475 finishing processes but the ready values will only list the punch processes.
476 Similarly, a printer may support hundreds of different sizes of media but only
477 have a single size loaded at any given time - the ready values are limited to
478 the media that is actually in the printer.
480 The `cupsFindDestReady` function finds the IPP attribute containing the ready
481 values for a given option:
484 cupsFindDestReady(http_t *http, cups_dest_t *dest,
485 cups_dinfo_t *dinfo, const char *option);
487 For example, the following code lists the ready finishing processes:
489 ipp_attribute_t *ready_finishings =
490 cupsFindDestReady(CUPS_HTTP_DEFAULT, dest, info,
493 if (ready_finishings != NULL)
495 int i, count = ippGetCount(ready_finishings);
497 puts("finishings ready:");
498 for (i = 0; i < count; i ++)
499 printf(" %d\n", ippGetInteger(ready_finishings, i));
502 puts("no finishings are ready.");
505 ### Media Size Options
507 CUPS provides functions for querying the dimensions and margins for each of the
508 supported media size options. The `cups_size_t` structure is used to describe a
511 typedef struct cups_size_s
515 int bottom, left, right, top;
518 The `width` and `length` members specify the dimensions of the media in
519 hundredths of millimeters (1/2540th of an inch). The `bottom`, `left`, `right`,
520 and `top` members specify the margins of the printable area, also in hundredths
523 The `cupsGetDestMediaByName` and `cupsGetDestMediaBySize` functions lookup the
524 media size information using a standard media size name or dimensions in
525 hundredths of millimeters:
528 cupsGetDestMediaByName(http_t *http, cups_dest_t *dest,
531 unsigned flags, cups_size_t *size);
534 cupsGetDestMediaBySize(http_t *http, cups_dest_t *dest,
536 int width, int length,
537 unsigned flags, cups_size_t *size);
539 The `media`, `width`, and `length` arguments specify the size to lookup. The
540 `flags` argument specifies a bitfield controlling various lookup options:
542 - `CUPS_MEDIA_FLAGS_DEFAULT`: Find the closest size supported by the printer.
543 - `CUPS_MEDIA_FLAGS_BORDERLESS`: Find a borderless size.
544 - `CUPS_MEDIA_FLAGS_DUPLEX`: Find a size compatible with two-sided printing.
545 - `CUPS_MEDIA_FLAGS_EXACT`: Find an exact match for the size.
546 - `CUPS_MEDIA_FLAGS_READY`: If the printer supports media sensing or
547 configuration of the media in each tray/source, find the size amongst the
550 If a matching size is found for the destination, the size information is stored
551 in the structure pointed to by the `size` argument and 1 is returned. Otherwise
554 For example, the following code prints the margins for two-sided printing on US
559 if (cupsGetDestMediaByName(CUPS_HTTP_DEFAULT, dest, info,
561 CUPS_MEDIA_FLAGS_DUPLEX, &size))
563 puts("Margins for duplex US Letter:");
564 printf(" Bottom: %.2fin\n", size.bottom / 2540.0);
565 printf(" Left: %.2fin\n", size.left / 2540.0);
566 printf(" Right: %.2fin\n", size.right / 2540.0);
567 printf(" Top: %.2fin\n", size.top / 2540.0);
570 puts("Margins for duplex US Letter are not available.");
572 You can also enumerate all of the sizes that match a given `flags` value using
573 the `cupsGetDestMediaByIndex` and `cupsGetDestMediaCount` functions:
576 cupsGetDestMediaByIndex(http_t *http, cups_dest_t *dest,
577 cups_dinfo_t *dinfo, int n,
578 unsigned flags, cups_size_t *size);
581 cupsGetDestMediaCount(http_t *http, cups_dest_t *dest,
582 cups_dinfo_t *dinfo, unsigned flags);
584 For example, the following code prints the list of ready media and corresponding
589 int count = cupsGetDestMediaCount(CUPS_HTTP_DEFAULT,
591 CUPS_MEDIA_FLAGS_READY);
593 for (i = 0; i < count; i ++)
595 if (cupsGetDestMediaByIndex(CUPS_HTTP_DEFAULT, dest, info,
596 i, CUPS_MEDIA_FLAGS_READY,
599 printf("%s:\n", size.name);
600 printf(" Width: %.2fin\n", size.width / 2540.0);
601 printf(" Length: %.2fin\n", size.length / 2540.0);
602 printf(" Bottom: %.2fin\n", size.bottom / 2540.0);
603 printf(" Left: %.2fin\n", size.left / 2540.0);
604 printf(" Right: %.2fin\n", size.right / 2540.0);
605 printf(" Top: %.2fin\n", size.top / 2540.0);
609 Finally, the `cupsGetDestMediaDefault` function returns the default media size:
612 cupsGetDestMediaDefault(http_t *http, cups_dest_t *dest,
613 cups_dinfo_t *dinfo, unsigned flags,
617 ### Localizing Options and Values
619 CUPS provides three functions to get localized, human-readable strings in the
620 user's current locale for options and values: `cupsLocalizeDestMedia`,
621 `cupsLocalizeDestOption`, and `cupsLocalizeDestValue`:
624 cupsLocalizeDestMedia(http_t *http, cups_dest_t *dest,
625 cups_dinfo_t *info, unsigned flags,
629 cupsLocalizeDestOption(http_t *http, cups_dest_t *dest,
634 cupsLocalizeDestValue(http_t *http, cups_dest_t *dest,
636 const char *option, const char *value);
639 ## Submitting a Print Job
641 Once you are ready to submit a print job, you create a job using the
642 `cupsCreateDestJob` function:
645 cupsCreateDestJob(http_t *http, cups_dest_t *dest,
646 cups_dinfo_t *info, int *job_id,
647 const char *title, int num_options,
648 cups_option_t *options);
650 The `title` argument specifies a name for the print job such as "My Document".
651 The `num_options` and `options` arguments specify the options for the print
652 job which are allocated using the `cupsAddOption` function.
654 When successful, the job's numeric identifier is stored in the integer pointed
655 to by the `job_id` argument and `IPP_STATUS_OK` is returned. Otherwise, an IPP
656 error status is returned.
658 For example, the following code creates a new job that will print 42 copies of a
659 two-sided US Letter document:
663 cups_option_t *options = NULL;
665 num_options = cupsAddOption(CUPS_COPIES, "42",
666 num_options, &options);
667 num_options = cupsAddOption(CUPS_MEDIA, CUPS_MEDIA_LETTER,
668 num_options, &options);
669 num_options = cupsAddOption(CUPS_SIDES,
670 CUPS_SIDES_TWO_SIDED_PORTRAIT,
671 num_options, &options);
673 if (cupsCreateDestJob(CUPS_HTTP_DEFAULT, dest, info,
674 &job_id, "My Document", num_options,
675 options) == IPP_STATUS_OK)
676 printf("Created job: %d\n", job_id);
678 printf("Unable to create job: %s\n",
679 cupsLastErrorString());
681 Once the job is created, you submit documents for the job using the
682 `cupsStartDestDocument`, `cupsWriteRequestData`, and `cupsFinishDestDocument`
686 cupsStartDestDocument(http_t *http, cups_dest_t *dest,
687 cups_dinfo_t *info, int job_id,
691 cups_option_t *options,
695 cupsWriteRequestData(http_t *http, const char *buffer,
699 cupsFinishDestDocument(http_t *http, cups_dest_t *dest,
702 The `docname` argument specifies the name of the document, typically the
703 original filename. The `format` argument specifies the MIME media type of the
704 document, including the following constants:
706 - `CUPS_FORMAT_JPEG`: "image/jpeg"
707 - `CUPS_FORMAT_PDF`: "application/pdf"
708 - `CUPS_FORMAT_POSTSCRIPT`: "application/postscript"
709 - `CUPS_FORMAT_TEXT`: "text/plain"
711 The `num_options` and `options` arguments specify per-document print options,
712 which at present must be 0 and `NULL`. The `last_document` argument specifies
713 whether this is the last document in the job.
715 For example, the following code submits a PDF file to the job that was just
718 FILE *fp = fopen("filename.pdf", "rb");
722 if (cupsStartDestDocument(CUPS_HTTP_DEFAULT, dest, info,
723 job_id, "filename.pdf", 0, NULL,
724 1) == HTTP_STATUS_CONTINUE)
726 while ((bytes = fread(buffer, 1, sizeof(buffer), fp)) > 0)
727 if (cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer,
728 bytes) != HTTP_STATUS_CONTINUE)
731 if (cupsFinishDestDocument(CUPS_HTTP_DEFAULT, dest,
732 info) == IPP_STATUS_OK)
733 puts("Document send succeeded.");
735 printf("Document send failed: %s\n",
736 cupsLastErrorString());
742 # Sending IPP Requests
744 CUPS provides a rich API for sending IPP requests to the scheduler or printers,
745 typically from management or utility applications whose primary purpose is not
749 ## Connecting to the Scheduler or Printer
751 The connection to the scheduler or printer is represented by the HTTP connection
752 type `http_t`. The `cupsConnectDest` function connects to the scheduler or
753 printer associated with the destination:
756 cupsConnectDest(cups_dest_t *dest, unsigned flags, int msec,
757 int *cancel, char *resource,
758 size_t resourcesize, cups_dest_cb_t cb,
761 The `dest` argument specifies the destination to connect to.
763 The `flags` argument specifies whether you want to connect to the scheduler
764 (`CUPS_DEST_FLAGS_NONE`) or device/printer (`CUPS_DEST_FLAGS_DEVICE`) associated
765 with the destination.
767 The `msec` argument specifies how long you are willing to wait for the
768 connection to be established in milliseconds. Specify a value of `-1` to wait
771 The `cancel` argument specifies the address of an integer variable that can be
772 set to a non-zero value to cancel the connection. Specify a value of `NULL`
773 to not provide a cancel variable.
775 The `resource` and `resourcesize` arguments specify the address and size of a
776 character string array to hold the path to use when sending an IPP request.
778 The `cb` and `user_data` arguments specify a destination callback function that
779 returns 1 to continue connecting or 0 to stop. The destination callback work
780 the same way as the one used for the `cupsEnumDests` function.
782 On success, a HTTP connection is returned that can be used to send IPP requests
783 and get IPP responses.
785 For example, the following code connects to the printer associated with a
786 destination with a 30 second timeout:
789 http_t *http = cupsConnectDest(dest, CUPS_DEST_FLAGS_DEVICE,
790 30000, NULL, resource,
791 sizeof(resource), NULL, NULL);
794 ## Creating an IPP Request
796 IPP requests are represented by the IPP message type `ipp_t` and each IPP
797 attribute in the request is representing using the type `ipp_attribute_t`. Each
798 IPP request includes an operation code (`IPP_OP_CREATE_JOB`,
799 `IPP_OP_GET_PRINTER_ATTRIBUTES`, etc.) and a 32-bit integer identifier.
801 The `ippNewRequest` function creates a new IPP request:
804 ippNewRequest(ipp_op_t op);
806 The `op` argument specifies the IPP operation code for the request. For
807 example, the following code creates an IPP Get-Printer-Attributes request:
809 ipp_t *request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
811 The request identifier is automatically set to a unique value for the current
814 Each IPP request starts with two IPP attributes, "attributes-charset" and
815 "attributes-natural-language", followed by IPP attribute(s) that specify the
816 target of the operation. The `ippNewRequest` automatically adds the correct
817 "attributes-charset" and "attributes-natural-language" attributes, but you must
818 add the target attribute(s). For example, the following code adds the
819 "printer-uri" attribute to the IPP Get-Printer-Attributes request to specify
820 which printer is being queried:
822 const char *printer_uri = cupsGetOption("device-uri",
826 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
827 "printer-uri", NULL, printer_uri);
831 > If we wanted to query the scheduler instead of the device, we would look
832 > up the "printer-uri-supported" option instead of the "device-uri" value.
834 The `ippAddString` function adds the "printer-uri" attribute the the IPP
835 request. The `IPP_TAG_OPERATION` argument specifies that the attribute is part
836 of the operation. The `IPP_TAG_URI` argument specifies that the value is a
837 Universal Resource Identifier (URI) string. The `NULL` argument specifies there
838 is no language (English, French, Japanese, etc.) associated with the string, and
839 the `printer_uri` argument specifies the string value.
841 The IPP Get-Printer-Attributes request also supports an IPP attribute called
842 "requested-attributes" that lists the attributes and values you are interested
843 in. For example, the following code requests the printer state attributes:
845 static const char * const requested_attributes[] =
848 "printer-state-message",
849 "printer-state-reasons"
852 ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
853 "requested-attributes", 3, NULL,
854 requested_attributes);
856 The `ippAddStrings` function adds an attribute with one or more strings, in this
857 case three. The `IPP_TAG_KEYWORD` argument specifies that the strings are
858 keyword values, which are used for attribute names. All strings use the same
859 language (`NULL`), and the attribute will contain the three strings in the
860 array `requested_attributes`.
862 CUPS provides many functions to adding attributes of different types:
864 - `ippAddBoolean` adds a boolean (`IPP_TAG_BOOLEAN`) attribute with one value.
865 - `ippAddInteger` adds an enum (`IPP_TAG_ENUM`) or integer (`IPP_TAG_INTEGER`)
866 attribute with one value.
867 - `ippAddIntegers` adds an enum or integer attribute with one or more values.
868 - `ippAddOctetString` adds an octetString attribute with one value.
869 - `ippAddOutOfBand` adds a admin-defined (`IPP_TAG_ADMINDEFINE`), default
870 (`IPP_TAG_DEFAULT`), delete-attribute (`IPP_TAG_DELETEATTR`), no-value
871 (`IPP_TAG_NOVALUE`), not-settable (`IPP_TAG_NOTSETTABLE`), unknown
872 (`IPP_TAG_UNKNOWN`), or unsupported (`IPP_TAG_UNSUPPORTED_VALUE`) out-of-band
874 - `ippAddRange` adds a rangeOfInteger attribute with one range.
875 - `ippAddRanges` adds a rangeOfInteger attribute with one or more ranges.
876 - `ippAddResolution` adds a resolution attribute with one resolution.
877 - `ippAddResolutions` adds a resolution attribute with one or more resolutions.
878 - `ippAddString` adds a charset (`IPP_TAG_CHARSET`), keyword (`IPP_TAG_KEYWORD`),
879 mimeMediaType (`IPP_TAG_MIMETYPE`), name (`IPP_TAG_NAME` and
880 `IPP_TAG_NAMELANG`), naturalLanguage (`IPP_TAG_NATURAL_LANGUAGE`), text
881 (`IPP_TAG_TEXT` and `IPP_TAG_TEXTLANG`), uri (`IPP_TAG_URI`), or uriScheme
882 (`IPP_TAG_URISCHEME`) attribute with one value.
883 - `ippAddStrings` adds a charset, keyword, mimeMediaType, name, naturalLanguage,
884 text, uri, or uriScheme attribute with one or more values.
887 ## Sending the IPP Request
889 Once you have created the IPP request, you can send it using the
890 `cupsDoRequest` function. For example, the following code sends the IPP
891 Get-Printer-Attributes request to the destination and saves the response:
893 ipp_t *response = cupsDoRequest(http, request, resource);
895 For requests like Send-Document that include a file, the `cupsDoFileRequest`
896 function should be used:
898 ipp_t *response = cupsDoFileRequest(http, request, resource,
901 Both `cupsDoRequest` and `cupsDoFileRequest` free the IPP request. If a valid
902 IPP response is received, it is stored in a new IPP message (`ipp_t`) and
903 returned to the caller. Otherwise `NULL` is returned.
905 The status from the most recent request can be queried using the `cupsLastError`
906 function, for example:
908 if (cupsLastError() >= IPP_STATUS_ERROR_BAD_REQUEST)
913 A human-readable error message is also available using the `cupsLastErrorString`
916 if (cupsLastError() >= IPP_STATUS_ERROR_BAD_REQUEST)
919 printf("Request failed: %s\n", cupsLastErrorString());
923 ## Processing the IPP Response
925 Each response to an IPP request is also an IPP message (`ipp_t`) with its own
926 IPP attributes (`ipp_attribute_t`) that includes a status code (`IPP_STATUS_OK`,
927 `IPP_STATUS_ERROR_BAD_REQUEST`, etc.) and the corresponding 32-bit integer
928 identifier from the request.
930 For example, the following code finds the printer state attributes and prints
933 ipp_attribute_t *attr;
935 if ((attr = ippFindAttribute(response, "printer-state",
936 IPP_TAG_ENUM)) != NULL)
938 printf("printer-state=%s\n",
939 ippEnumString("printer-state", ippGetInteger(attr, 0)));
942 puts("printer-state=unknown");
944 if ((attr = ippFindAttribute(response, "printer-state-message",
945 IPP_TAG_TEXT)) != NULL)
947 printf("printer-state-message=\"%s\"\n",
948 ippGetString(attr, 0, NULL)));
951 if ((attr = ippFindAttribute(response, "printer-state-reasons",
952 IPP_TAG_KEYWORD)) != NULL)
954 int i, count = ippGetCount(attr);
956 puts("printer-state-reasons=");
957 for (i = 0; i < count; i ++)
958 printf(" %s\n", ippGetString(attr, i, NULL)));
961 The `ippGetCount` function returns the number of values in an attribute.
963 The `ippGetInteger` and `ippGetString` functions return a single integer or
964 string value from an attribute.
966 The `ippEnumString` function converts a enum value to its keyword (string)
969 Once you are done using the IPP response message, free it using the `ippDelete`
977 CUPS normally handles authentication through the console. GUI applications
978 should set a password callback using the `cupsSetPasswordCB2` function:
981 cupsSetPasswordCB2(cups_password_cb2_t cb, void *user_data);
983 The password callback will be called when needed and is responsible for setting
984 the current user name using `cupsSetUser` and returning a string:
987 cups_password_cb2(const char *prompt, http_t *http,
988 const char *method, const char *resource,
991 The `prompt` argument is a string from CUPS that should be displayed to the
994 The `http` argument is the connection hosting the request that is being
995 authenticated. The password callback can call the `httpGetField` and
996 `httpGetSubField` functions to look for additional details concerning the
997 authentication challenge.
999 The `method` argument specifies the HTTP method used for the request and is
1002 The `resource` argument specifies the path used for the request.
1004 The `user_data` argument provides the user data pointer from the
1005 `cupsSetPasswordCB2` call.