2 title: CUPS Programming Manual
3 author: Michael R Sweet
4 copyright: Copyright © 2007-2017 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 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.
46 ## Terms Used in This Document
48 A *Destination* is a printer or print queue that accepts print jobs. A
49 *Print Job* is one or more documents that are processed by a destination
50 using options supplied when creating the job. A *Document* is a file (JPEG
51 image, PDF file, etc.) suitable for printing. An *Option* controls some aspect
52 of printing, such as the media used. *Media* is the sheets or roll that is
53 printed on. An *Attribute* is an option encoded for an Internet Printing
54 Protocol (IPP) request.
57 ## Compiling Programs That Use the CUPS API
59 The CUPS libraries can be used from any C, C++, or Objective C program.
60 The method of compiling against the libraries varies depending on the
61 operating system and installation of CUPS. The following sections show how
62 to compile a simple program (shown below) in two common environments.
64 The following simple program lists the available destinations:
67 #include <cups/cups.h>
69 int print_dest(void *user_data, unsigned flags, cups_dest_t *dest)
72 printf("%s/%s\n", dest->name, dest->instance);
81 cupsEnumDests(CUPS_DEST_FLAGS_NONE, 1000, NULL, 0, 0, print_dest, NULL);
87 ### Compiling with Xcode
89 In Xcode, choose *New Project...* from the *File* menu (or press SHIFT+CMD+N),
90 then select the *Command Line Tool* under the macOS Application project type.
91 Click *Next* and enter a name for the project, for example "firstcups". Click
92 *Next* and choose a project directory. The click *Next* to create the project.
94 In the project window, click on the *Build Phases* group and expand the
95 *Link Binary with Libraries* section. Click *+*, type "libcups" to show the
96 library, and then double-click on `libcups.tbd`.
98 Finally, click on the `main.c` file in the sidebar and copy the example program
99 to the file. Build and run (CMD+R) to see the list of destinations.
102 ### Compiling with GCC
104 From the command-line, create a file called `sample.c` using your favorite
105 editor, copy the example to this file, and save. Then run the following command
106 to compile it with GCC and run it:
108 gcc -o simple `cups-config --cflags` simple.c `cups-config --libs`
111 The `cups-config` command provides the compiler flags (`cups-config --cflags`)
112 and libraries (`cups-config --libs`) needed for the local system.
115 # Working with Destinations
117 Destinations, which in CUPS represent individual printers or classes
118 (collections or pools) of printers, are represented by the `cups_dest_t`
119 structure which includes the name \(`name`), instance \(`instance`, saved
120 options/settings), whether the destination is the default for the user
121 \(`is_default`), and the options and basic information associated with that
122 destination \(`num_options` and `options`).
124 Historically destinations have been manually maintained by the administrator of
125 a system or network, but CUPS also supports dynamic discovery of destinations on
129 ## Finding Available Destinations
131 The `cupsEnumDests` function finds all of the available destinations:
134 cupsEnumDests(unsigned flags, int msec, int *cancel,
135 cups_ptype_t type, cups_ptype_t mask,
136 cups_dest_cb_t cb, void *user_data)
138 The `flags` argument specifies enumeration options, which at present must be
139 `CUPS_DEST_FLAGS_NONE`.
141 The `msec` argument specifies the maximum amount of time that should be used for
142 enumeration in milliseconds - interactive applications should keep this value to
143 5000 or less when run on the main thread.
145 The `cancel` argument points to an integer variable that, when set to a non-zero
146 value, will cause enumeration to stop as soon as possible. It can be `NULL` if
149 The `type` and `mask` arguments are bitfields that allow the caller to filter
150 the destinations based on categories and/or capabilities. The destination's
151 "printer-type" value is masked by the `mask` value and compared to the `type`
152 value when filtering. For example, to only enumerate destinations that are
153 hosted on the local system, pass `CUPS_PRINTER_LOCAL` for the `type` argument
154 and `CUPS_PRINTER_DISCOVERED` for the `mask` argument. The following constants
155 can be used for filtering:
157 - `CUPS_PRINTER_CLASS`: A collection of destinations.
158 - `CUPS_PRINTER_FAX`: A facsimile device.
159 - `CUPS_PRINTER_LOCAL`: A local printer or class. This constant has the value 0
160 (no bits set) and is only used for the `type` argument and is paired with the
161 `CUPS_PRINTER_REMOTE` or `CUPS_PRINTER_DISCOVERED` constant passed in the
163 - `CUPS_PRINTER_REMOTE`: A remote (shared) printer or class.
164 - `CUPS_PRINTER_DISCOVERED`: An available network printer or class.
165 - `CUPS_PRINTER_BW`: Can do B&W printing.
166 - `CUPS_PRINTER_COLOR`: Can do color printing.
167 - `CUPS_PRINTER_DUPLEX`: Can do two-sided printing.
168 - `CUPS_PRINTER_STAPLE`: Can staple output.
169 - `CUPS_PRINTER_COLLATE`: Can quickly collate copies.
170 - `CUPS_PRINTER_PUNCH`: Can punch output.
171 - `CUPS_PRINTER_COVER`: Can cover output.
172 - `CUPS_PRINTER_BIND`: Can bind output.
173 - `CUPS_PRINTER_SORT`: Can sort output (mailboxes, etc.)
174 - `CUPS_PRINTER_SMALL`: Can print on Letter/Legal/A4-size media.
175 - `CUPS_PRINTER_MEDIUM`: Can print on Tabloid/B/C/A3/A2-size media.
176 - `CUPS_PRINTER_LARGE`: Can print on D/E/A1/A0-size media.
177 - `CUPS_PRINTER_VARIABLE`: Can print on rolls and custom-size media.
179 The `cb` argument specifies a function to call for every destination that is
182 typedef int (*cups_dest_cb_t)(void *user_data,
186 The callback function receives a copy of the `user_data` argument along with a
187 bitfield \(`flags`) and the destination that was found. The `flags` argument
188 can have any of the following constant (bit) values set:
190 - `CUPS_DEST_FLAGS_MORE`: There are more destinations coming.
191 - `CUPS_DEST_FLAGS_REMOVED`: The destination has gone away and should be removed
192 from the list of destinations a user can select.
193 - `CUPS_DEST_FLAGS_ERROR`: An error occurred. The reason for the error can be
194 found by calling the `cupsLastError` and/or `cupsLastErrorString` functions.
196 The callback function returns 0 to stop enumeration or 1 to continue.
198 > Note that the callback function will likely be called multiple times for the
199 > same destination, so it is up to the caller to suppress any duplicate
202 The following example shows how to use `cupsEnumDests` to get a filtered array
212 my_dest_cb(my_user_data_t *user_data, unsigned flags,
215 if (flags & CUPS_DEST_FLAGS_REMOVED)
218 * Remove destination from array...
221 user_data->num_dests =
222 cupsRemoveDest(dest->name, dest->instance,
223 user_data->num_dests,
224 &(user_data->dests));
229 * Add destination to array...
232 user_data->num_dests =
233 cupsCopyDest(dest, user_data->num_dests,
234 &(user_data->dests));
241 my_get_dests(cups_ptype_t type, cups_ptype_t mask,
244 my_user_data_t user_data = { 0, NULL };
246 if (!cupsEnumDests(CUPS_DEST_FLAGS_NONE, 1000, NULL, type,
247 mask, (cups_dest_cb_t)my_dest_cb,
251 * An error occurred, free all of the destinations and
255 cupsFreeDests(user_data.num_dests, user_dasta.dests);
263 * Return the destination array...
266 *dests = user_data.dests;
268 return (user_data.num_dests);
272 ## Basic Destination Information
274 The `num_options` and `options` members of the `cups_dest_t` structure provide
275 basic attributes about the destination in addition to the user default options
276 and values for that destination. The following names are predefined for various
277 destination attributes:
279 - "auth-info-required": The type of authentication required for printing to this
280 destination: "none", "username,password", "domain,username,password", or
281 "negotiate" (Kerberos).
282 - "printer-info": The human-readable description of the destination such as "My
284 - "printer-is-accepting-jobs": "true" if the destination is accepting new jobs,
286 - "printer-is-shared": "true" if the destination is being shared with other
287 computers, "false" otherwise.
288 - "printer-location": The human-readable location of the destination such as
290 - "printer-make-and-model": The human-readable make and model of the destination
291 such as "ExampleCorp LaserPrinter 4000 Series".
292 - "printer-state": "3" if the destination is idle, "4" if the destination is
293 printing a job, and "5" if the destination is stopped.
294 - "printer-state-change-time": The UNIX time when the destination entered the
296 - "printer-state-reasons": Additional comma-delimited state keywords for the
297 destination such as "media-tray-empty-error" and "toner-low-warning".
298 - "printer-type": The `cups_ptype_t` value associated with the destination.
299 - "printer-uri-supported": The URI associated with the destination; if not set,
300 this destination was discovered but is not yet setup as a local printer.
302 Use the `cupsGetOption` function to retrieve the value. For example, the
303 following code gets the make and model of a destination:
305 const char *model = cupsGetOption("printer-make-and-model",
310 ## Detailed Destination Information
312 Once a destination has been chosen, the `cupsCopyDestInfo` function can be used
313 to gather detailed information about the destination:
316 cupsCopyDestInfo(http_t *http, cups_dest_t *dest);
318 The `http` argument specifies a connection to the CUPS scheduler and is
319 typically the constant `CUPS_HTTP_DEFAULT`. The `dest` argument specifies the
320 destination to query.
322 The `cups_dinfo_t` structure that is returned contains a snapshot of the
323 supported options and their supported, ready, and default values. It also can
324 report constraints between different options and values, and recommend changes
325 to resolve those constraints.
328 ### Getting Supported Options and Values
330 The `cupsCheckDestSupported` function can be used to test whether a particular
331 option or option and value is supported:
334 cupsCheckDestSupported(http_t *http, cups_dest_t *dest,
339 The `option` argument specifies the name of the option to check. The following
340 constants can be used to check the various standard options:
342 - `CUPS_COPIES`: Controls the number of copies that are produced.
343 - `CUPS_FINISHINGS`: A comma-delimited list of integer constants that control
344 the finishing processes that are applied to the job, including stapling,
345 punching, and folding.
346 - `CUPS_MEDIA`: Controls the media size that is used, typically one of the
347 following: `CUPS_MEDIA_3X5`, `CUPS_MEDIA_4X6`, `CUPS_MEDIA_5X7`,
348 `CUPS_MEDIA_8X10`, `CUPS_MEDIA_A3`, `CUPS_MEDIA_A4`, `CUPS_MEDIA_A5`,
349 `CUPS_MEDIA_A6`, `CUPS_MEDIA_ENV10`, `CUPS_MEDIA_ENVDL`, `CUPS_MEDIA_LEGAL`,
350 `CUPS_MEDIA_LETTER`, `CUPS_MEDIA_PHOTO_L`, `CUPS_MEDIA_SUPERBA3`, or
351 `CUPS_MEDIA_TABLOID`.
352 - `CUPS_MEDIA_SOURCE`: Controls where the media is pulled from, typically either
353 `CUPS_MEDIA_SOURCE_AUTO` or `CUPS_MEDIA_SOURCE_MANUAL`.
354 - `CUPS_MEDIA_TYPE`: Controls the type of media that is used, typically one of
355 the following: `CUPS_MEDIA_TYPE_AUTO`, `CUPS_MEDIA_TYPE_ENVELOPE`,
356 `CUPS_MEDIA_TYPE_LABELS`, `CUPS_MEDIA_TYPE_LETTERHEAD`,
357 `CUPS_MEDIA_TYPE_PHOTO`, `CUPS_MEDIA_TYPE_PHOTO_GLOSSY`,
358 `CUPS_MEDIA_TYPE_PHOTO_MATTE`, `CUPS_MEDIA_TYPE_PLAIN`, or
359 `CUPS_MEDIA_TYPE_TRANSPARENCY`.
360 - `CUPS_NUMBER_UP`: Controls the number of document pages that are placed on
362 - `CUPS_ORIENTATION`: Controls the orientation of document pages placed on the
363 media: `CUPS_ORIENTATION_PORTRAIT` or `CUPS_ORIENTATION_LANDSCAPE`.
364 - `CUPS_PRINT_COLOR_MODE`: Controls whether the output is in color
365 \(`CUPS_PRINT_COLOR_MODE_COLOR`), grayscale
366 \(`CUPS_PRINT_COLOR_MODE_MONOCHROME`), or either
367 \(`CUPS_PRINT_COLOR_MODE_AUTO`).
368 - `CUPS_PRINT_QUALITY`: Controls the generate quality of the output:
369 `CUPS_PRINT_QUALITY_DRAFT`, `CUPS_PRINT_QUALITY_NORMAL`, or
370 `CUPS_PRINT_QUALITY_HIGH`.
371 - `CUPS_SIDES`: Controls whether prints are placed on one or both sides of the
372 media: `CUPS_SIDES_ONE_SIDED`, `CUPS_SIDES_TWO_SIDED_PORTRAIT`, or
373 `CUPS_SIDES_TWO_SIDED_LANDSCAPE`.
375 If the `value` argument is `NULL`, the `cupsCheckDestSupported` function returns
376 whether the option is supported by the destination. Otherwise, the function
377 returns whether the specified value of the option is supported.
379 The `cupsFindDestSupported` function returns the IPP attribute containing the
380 supported values for a given option:
383 cupsFindDestSupported(http_t *http, cups_dest_t *dest,
387 For example, the following code prints the supported finishing processes for a
388 destination, if any, to the standard output:
390 cups_dinfo_t *info = cupsCopyDestInfo(CUPS_HTTP_DEFAULT,
393 if (cupsCheckDestSupported(CUPS_HTTP_DEFAULT, dest, info,
394 CUPS_FINISHINGS, NULL))
396 ipp_attribute_t *finishings =
397 cupsFindDestSupported(CUPS_HTTP_DEFAULT, dest, info,
399 int i, count = ippGetCount(finishings);
401 puts("finishings supported:");
402 for (i = 0; i < count; i ++)
403 printf(" %d\n", ippGetInteger(finishings, i));
406 puts("finishings not supported.");
408 The "job-creation-attributes" option can be queried to get a list of supported
409 options. For example, the following code prints the list of supported options
410 to the standard output:
412 ipp_attribute_t *attrs =
413 cupsFindDestSupported(CUPS_HTTP_DEFAULT, dest, info,
414 "job-creation-attributes");
415 int i, count = ippGetCount(attrs);
417 for (i = 0; i < count; i ++)
418 puts(ippGetString(attrs, i, NULL));
421 ### Getting Default Values
423 There are two sets of default values - user defaults that are available via the
424 `num_options` and `options` members of the `cups_dest_t` structure, and
425 destination defaults that available via the `cups_dinfo_t` structure and the
426 `cupsFindDestDefault` function which returns the IPP attribute containing the
427 default value(s) for a given option:
430 cupsFindDestDefault(http_t *http, cups_dest_t *dest,
434 The user defaults from `cupsGetOption` should always take preference over the
435 destination defaults. For example, the following code prints the default
436 finishings value(s) to the standard output:
438 const char *def_value =
439 cupsGetOption(CUPS_FINISHINGS, dest->num_options,
441 ipp_attribute_t *def_attr =
442 cupsFindDestDefault(CUPS_HTTP_DEFAULT, dest, info,
445 if (def_value != NULL)
447 printf("Default finishings: %s\n", def_value);
451 int i, count = ippGetCount(def_attr);
453 printf("Default finishings: %d",
454 ippGetInteger(def_attr, 0));
455 for (i = 1; i < count; i ++)
456 printf(",%d", ippGetInteger(def_attr, i));
461 ### Getting Ready (Loaded) Values
463 The finishings and media options also support queries for the ready, or loaded,
464 values. For example, a printer may have punch and staple finishers installed
465 but be out of staples - the supported values will list both punch and staple
466 finishing processes but the ready values will only list the punch processes.
467 Similarly, a printer may support hundreds of different sizes of media but only
468 have a single size loaded at any given time - the ready values are limited to
469 the media that is actually in the printer.
471 The `cupsFindDestReady` function finds the IPP attribute containing the ready
472 values for a given option:
475 cupsFindDestReady(http_t *http, cups_dest_t *dest,
476 cups_dinfo_t *dinfo, const char *option);
478 For example, the following code lists the ready finishing processes:
480 ipp_attribute_t *ready_finishings =
481 cupsFindDestReady(CUPS_HTTP_DEFAULT, dest, info,
484 if (ready_finishings != NULL)
486 int i, count = ippGetCount(ready_finishings);
488 puts("finishings ready:");
489 for (i = 0; i < count; i ++)
490 printf(" %d\n", ippGetInteger(ready_finishings, i));
493 puts("no finishings are ready.");
496 ### Media Size Options
498 CUPS provides functions for querying the dimensions and margins for each of the
499 supported media size options. The `cups_size_t` structure is used to describe a
502 typedef struct cups_size_s
506 int bottom, left, right, top;
509 The `width` and `length` members specify the dimensions of the media in
510 hundredths of millimeters (1/2540th of an inch). The `bottom`, `left`, `right`,
511 and `top` members specify the margins of the printable area, also in hundredths
514 The `cupsGetDestMediaByName` and `cupsGetDestMediaBySize` functions lookup the
515 media size information using a standard media size name or dimensions in
516 hundredths of millimeters:
519 cupsGetDestMediaByName(http_t *http, cups_dest_t *dest,
522 unsigned flags, cups_size_t *size);
525 cupsGetDestMediaBySize(http_t *http, cups_dest_t *dest,
527 int width, int length,
528 unsigned flags, cups_size_t *size);
530 The `media`, `width`, and `length` arguments specify the size to lookup. The
531 `flags` argument specifies a bitfield controlling various lookup options:
533 - `CUPS_MEDIA_FLAGS_DEFAULT`: Find the closest size supported by the printer.
534 - `CUPS_MEDIA_FLAGS_BORDERLESS`: Find a borderless size.
535 - `CUPS_MEDIA_FLAGS_DUPLEX`: Find a size compatible with two-sided printing.
536 - `CUPS_MEDIA_FLAGS_EXACT`: Find an exact match for the size.
537 - `CUPS_MEDIA_FLAGS_READY`: If the printer supports media sensing or
538 configuration of the media in each tray/source, find the size amongst the
541 If a matching size is found for the destination, the size information is stored
542 in the structure pointed to by the `size` argument and 1 is returned. Otherwise
545 For example, the following code prints the margins for two-sided printing on US
550 if (cupsGetDestMediaByName(CUPS_HTTP_DEFAULT, dest, info,
552 CUPS_MEDIA_FLAGS_DUPLEX, &size))
554 puts("Margins for duplex US Letter:");
555 printf(" Bottom: %.2fin\n", size.bottom / 2540.0);
556 printf(" Left: %.2fin\n", size.left / 2540.0);
557 printf(" Right: %.2fin\n", size.right / 2540.0);
558 printf(" Top: %.2fin\n", size.top / 2540.0);
561 puts("Margins for duplex US Letter are not available.");
563 You can also enumerate all of the sizes that match a given `flags` value using
564 the `cupsGetDestMediaByIndex` and `cupsGetDestMediaCount` functions:
567 cupsGetDestMediaByIndex(http_t *http, cups_dest_t *dest,
568 cups_dinfo_t *dinfo, int n,
569 unsigned flags, cups_size_t *size);
572 cupsGetDestMediaCount(http_t *http, cups_dest_t *dest,
573 cups_dinfo_t *dinfo, unsigned flags);
575 For example, the following code prints the list of ready media and corresponding
580 int count = cupsGetDestMediaCount(CUPS_HTTP_DEFAULT,
582 CUPS_MEDIA_FLAGS_READY);
584 for (i = 0; i < count; i ++)
586 if (cupsGetDestMediaByIndex(CUPS_HTTP_DEFAULT, dest, info,
587 i, CUPS_MEDIA_FLAGS_READY,
590 printf("%s:\n", size.name);
591 printf(" Width: %.2fin\n", size.width / 2540.0);
592 printf(" Length: %.2fin\n", size.length / 2540.0);
593 printf(" Bottom: %.2fin\n", size.bottom / 2540.0);
594 printf(" Left: %.2fin\n", size.left / 2540.0);
595 printf(" Right: %.2fin\n", size.right / 2540.0);
596 printf(" Top: %.2fin\n", size.top / 2540.0);
600 Finally, the `cupsGetDestMediaDefault` function returns the default media size:
603 cupsGetDestMediaDefault(http_t *http, cups_dest_t *dest,
604 cups_dinfo_t *dinfo, unsigned flags,
608 ### Localizing Options and Values
610 CUPS provides three functions to get localized, human-readable strings in the
611 user's current locale for options and values: `cupsLocalizeDestMedia`,
612 `cupsLocalizeDestOption`, and `cupsLocalizeDestValue`:
615 cupsLocalizeDestMedia(http_t *http, cups_dest_t *dest,
616 cups_dinfo_t *info, unsigned flags,
620 cupsLocalizeDestOption(http_t *http, cups_dest_t *dest,
625 cupsLocalizeDestValue(http_t *http, cups_dest_t *dest,
627 const char *option, const char *value);
630 ## Submitting a Print Job
632 Once you are ready to submit a print job, you create a job using the
633 `cupsCreateDestJob` function:
636 cupsCreateDestJob(http_t *http, cups_dest_t *dest,
637 cups_dinfo_t *info, int *job_id,
638 const char *title, int num_options,
639 cups_option_t *options);
641 The `title` argument specifies a name for the print job such as "My Document".
642 The `num_options` and `options` arguments specify the options for the print
643 job which are allocated using the `cupsAddOption` function.
645 When successful, the job's numeric identifier is stored in the integer pointed
646 to by the `job_id` argument and `IPP_STATUS_OK` is returned. Otherwise, an IPP
647 error status is returned.
649 For example, the following code creates a new job that will print 42 copies of a
650 two-sided US Letter document:
654 cups_option_t *options = NULL;
656 num_options = cupsAddOption(CUPS_COPIES, "42",
657 num_options, &options);
658 num_options = cupsAddOption(CUPS_MEDIA, CUPS_MEDIA_LETTER,
659 num_options, &options);
660 num_options = cupsAddOption(CUPS_SIDES,
661 CUPS_SIDES_TWO_SIDED_PORTRAIT,
662 num_options, &options);
664 if (cupsCreateDestJob(CUPS_HTTP_DEFAULT, dest, info,
665 &job_id, "My Document", num_options,
666 options) == IPP_STATUS_OK)
667 printf("Created job: %d\n", job_id);
669 printf("Unable to create job: %s\n",
670 cupsLastErrorString());
672 Once the job is created, you submit documents for the job using the
673 `cupsStartDestDocument`, `cupsWriteRequestData`, and `cupsFinishDestDocument`
677 cupsStartDestDocument(http_t *http, cups_dest_t *dest,
678 cups_dinfo_t *info, int job_id,
682 cups_option_t *options,
686 cupsWriteRequestData(http_t *http, const char *buffer,
690 cupsFinishDestDocument(http_t *http, cups_dest_t *dest,
693 The `docname` argument specifies the name of the document, typically the
694 original filename. The `format` argument specifies the MIME media type of the
695 document, including the following constants:
697 - `CUPS_FORMAT_JPEG`: "image/jpeg"
698 - `CUPS_FORMAT_PDF`: "application/pdf"
699 - `CUPS_FORMAT_POSTSCRIPT`: "application/postscript"
700 - `CUPS_FORMAT_TEXT`: "text/plain"
702 The `num_options` and `options` arguments specify per-document print options,
703 which at present must be 0 and `NULL`. The `last_document` argument specifies
704 whether this is the last document in the job.
706 For example, the following code submits a PDF file to the job that was just
709 FILE *fp = fopen("filename.pdf", "rb");
713 if (cupsStartDestDocument(CUPS_HTTP_DEFAULT, dest, info,
714 job_id, "filename.pdf", 0, NULL,
715 1) == HTTP_STATUS_CONTINUE)
717 while ((bytes = fread(buffer, 1, sizeof(buffer), fp)) > 0)
718 if (cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer,
719 bytes) != HTTP_STATUS_CONTINUE)
722 if (cupsFinishDestDocument(CUPS_HTTP_DEFAULT, dest,
723 info) == IPP_STATUS_OK)
724 puts("Document send succeeded.");
726 printf("Document send failed: %s\n",
727 cupsLastErrorString());
733 # Sending IPP Requests
735 CUPS provides a rich API for sending IPP requests to the scheduler or printers,
736 typically from management or utility applications whose primary purpose is not
740 ## Connecting to the Scheduler or Printer
742 The connection to the scheduler or printer is represented by the HTTP connection
743 type `http_t`. The `cupsConnectDest` function connects to the scheduler or
744 printer associated with the destination:
747 cupsConnectDest(cups_dest_t *dest, unsigned flags, int msec,
748 int *cancel, char *resource,
749 size_t resourcesize, cups_dest_cb_t cb,
752 The `dest` argument specifies the destination to connect to.
754 The `flags` argument specifies whether you want to connect to the scheduler
755 (`CUPS_DEST_FLAGS_NONE`) or device/printer (`CUPS_DEST_FLAGS_DEVICE`) associated
756 with the destination.
758 The `msec` argument specifies how long you are willing to wait for the
759 connection to be established in milliseconds. Specify a value of `-1` to wait
762 The `cancel` argument specifies the address of an integer variable that can be
763 set to a non-zero value to cancel the connection. Specify a value of `NULL`
764 to not provide a cancel variable.
766 The `resource` and `resourcesize` arguments specify the address and size of a
767 character string array to hold the path to use when sending an IPP request.
769 The `cb` and `user_data` arguments specify a destination callback function that
770 returns 1 to continue connecting or 0 to stop. The destination callback work
771 the same way as the one used for the `cupsEnumDests` function.
773 On success, a HTTP connection is returned that can be used to send IPP requests
774 and get IPP responses.
776 For example, the following code connects to the printer associated with a
777 destination with a 30 second timeout:
780 http_t *http = cupsConnectDest(dest, CUPS_DEST_FLAGS_DEVICE,
781 30000, NULL, resource,
782 sizeof(resource), NULL, NULL);
785 ## Creating an IPP Request
787 IPP requests are represented by the IPP message type `ipp_t` and each IPP
788 attribute in the request is representing using the type `ipp_attribute_t`. Each
789 IPP request includes an operation code (`IPP_OP_CREATE_JOB`,
790 `IPP_OP_GET_PRINTER_ATTRIBUTES`, etc.) and a 32-bit integer identifier.
792 The `ippNewRequest` function creates a new IPP request:
795 ippNewRequest(ipp_op_t op);
797 The `op` argument specifies the IPP operation code for the request. For
798 example, the following code creates an IPP Get-Printer-Attributes request:
800 ipp_t *request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
802 The request identifier is automatically set to a unique value for the current
805 Each IPP request starts with two IPP attributes, "attributes-charset" and
806 "attributes-natural-language", followed by IPP attribute(s) that specify the
807 target of the operation. The `ippNewRequest` automatically adds the correct
808 "attributes-charset" and "attributes-natural-language" attributes, but you must
809 add the target attribute(s). For example, the following code adds the
810 "printer-uri" attribute to the IPP Get-Printer-Attributes request to specify
811 which printer is being queried:
813 const char *printer_uri = cupsGetOption("device-uri",
817 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
818 "printer-uri", NULL, printer_uri);
820 > Note: If we wanted to query the scheduler instead of the device, we would look
821 > up the "printer-uri-supported" option instead of the "device-uri" value.
823 The `ippAddString` function adds the "printer-uri" attribute the the IPP
824 request. The `IPP_TAG_OPERATION` argument specifies that the attribute is part
825 of the operation. The `IPP_TAG_URI` argument specifies that the value is a
826 Universal Resource Identifier (URI) string. The `NULL` argument specifies there
827 is no language (English, French, Japanese, etc.) associated with the string, and
828 the `printer_uri` argument specifies the string value.
830 The IPP Get-Printer-Attributes request also supports an IPP attribute called
831 "requested-attributes" that lists the attributes and values you are interested
832 in. For example, the following code requests the printer state attributes:
834 static const char * const requested_attributes[] =
837 "printer-state-message",
838 "printer-state-reasons"
841 ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
842 "requested-attributes", 3, NULL,
843 requested_attributes);
845 The `ippAddStrings` function adds an attribute with one or more strings, in this
846 case three. The `IPP_TAG_KEYWORD` argument specifies that the strings are
847 keyword values, which are used for attribute names. All strings use the same
848 language (`NULL`), and the attribute will contain the three strings in the
849 array `requested_attributes`.
851 CUPS provides many functions to adding attributes of different types:
853 - `ippAddBoolean` adds a boolean (`IPP_TAG_BOOLEAN`) attribute with one value.
854 - `ippAddInteger` adds an enum (`IPP_TAG_ENUM`) or integer (`IPP_TAG_INTEGER`)
855 attribute with one value.
856 - `ippAddIntegers` adds an enum or integer attribute with one or more values.
857 - `ippAddOctetString` adds an octetString attribute with one value.
858 - `ippAddOutOfBand` adds a admin-defined (`IPP_TAG_ADMINDEFINE`), default
859 (`IPP_TAG_DEFAULT`), delete-attribute (`IPP_TAG_DELETEATTR`), no-value
860 (`IPP_TAG_NOVALUE`), not-settable (`IPP_TAG_NOTSETTABLE`), unknown
861 (`IPP_TAG_UNKNOWN`), or unsupported (`IPP_TAG_UNSUPPORTED_VALUE`) out-of-band
863 - `ippAddRange` adds a rangeOfInteger attribute with one range.
864 - `ippAddRanges` adds a rangeOfInteger attribute with one or more ranges.
865 - `ippAddResolution` adds a resolution attribute with one resolution.
866 - `ippAddResolutions` adds a resolution attribute with one or more resolutions.
867 - `ippAddString` adds a charset (`IPP_TAG_CHARSET`), keyword (`IPP_TAG_KEYWORD`),
868 mimeMediaType (`IPP_TAG_MIMETYPE`), name (`IPP_TAG_NAME` and
869 `IPP_TAG_NAMELANG`), naturalLanguage (`IPP_TAG_NATURAL_LANGUAGE`), text
870 (`IPP_TAG_TEXT` and `IPP_TAG_TEXTLANG`), uri (`IPP_TAG_URI`), or uriScheme
871 (`IPP_TAG_URISCHEME`) attribute with one value.
872 - `ippAddStrings` adds a charset, keyword, mimeMediaType, name, naturalLanguage,
873 text, uri, or uriScheme attribute with one or more values.
876 ## Sending the IPP Request
878 Once you have created the IPP request, you can send it using the
879 `cupsDoRequest` function. For example, the following code sends the IPP
880 Get-Printer-Attributes request to the destination and saves the response:
882 ipp_t *response = cupsDoRequest(http, request, resource);
884 For requests like Send-Document that include a file, the `cupsDoFileRequest`
885 function should be used:
887 ipp_t *response = cupsDoFileRequest(http, request, resource,
890 Both `cupsDoRequest` and `cupsDoFileRequest` free the IPP request. If a valid
891 IPP response is received, it is stored in a new IPP message (`ipp_t`) and
892 returned to the caller. Otherwise `NULL` is returned.
894 The status from the most recent request can be queried using the `cupsLastError`
895 function, for example:
897 if (cupsLastError() >= IPP_STATUS_ERROR_BAD_REQUEST)
902 A human-readable error message is also available using the `cupsLastErrorString`
905 if (cupsLastError() >= IPP_STATUS_ERROR_BAD_REQUEST)
908 printf("Request failed: %s\n", cupsLastErrorString());
912 ## Processing the IPP Response
914 Each response to an IPP request is also an IPP message (`ipp_t`) with its own
915 IPP attributes (`ipp_attribute_t`) that includes a status code (`IPP_STATUS_OK`,
916 `IPP_STATUS_ERROR_BAD_REQUEST`, etc.) and the corresponding 32-bit integer
917 identifier from the request.
919 For example, the following code finds the printer state attributes and prints
922 ipp_attribute_t *attr;
924 if ((attr = ippFindAttribute(response, "printer-state",
925 IPP_TAG_ENUM)) != NULL)
927 printf("printer-state=%s\n",
928 ippEnumString("printer-state", ippGetInteger(attr, 0)));
931 puts("printer-state=unknown");
933 if ((attr = ippFindAttribute(response, "printer-state-message",
934 IPP_TAG_TEXT)) != NULL)
936 printf("printer-state-message=\"%s\"\n",
937 ippGetString(attr, 0, NULL)));
940 if ((attr = ippFindAttribute(response, "printer-state-reasons",
941 IPP_TAG_KEYWORD)) != NULL)
943 int i, count = ippGetCount(attr);
945 puts("printer-state-reasons=");
946 for (i = 0; i < count; i ++)
947 printf(" %s\n", ippGetString(attr, i, NULL)));
950 The `ippGetCount` function returns the number of values in an attribute.
952 The `ippGetInteger` and `ippGetString` functions return a single integer or
953 string value from an attribute.
955 The `ippEnumString` function converts a enum value to its keyword (string)
958 Once you are done using the IPP response message, free it using the `ippDelete`
966 CUPS normally handles authentication through the console. GUI applications
967 should set a password callback using the `cupsSetPasswordCB2` function:
970 cupsSetPasswordCB2(cups_password_cb2_t cb, void *user_data);
972 The password callback will be called when needed and is responsible for setting
973 the current user name using `cupsSetUser` and returning a string:
976 cups_password_cb2(const char *prompt, http_t *http,
977 const char *method, const char *resource,
980 The `prompt` argument is a string from CUPS that should be displayed to the
983 The `http` argument is the connection hosting the request that is being
984 authenticated. The password callback can call the `httpGetField` and
985 `httpGetSubField` functions to look for additional details concerning the
986 authentication challenge.
988 The `method` argument specifies the HTTP method used for the request and is
991 The `resource` argument specifies the path used for the request.
993 The `user_data` argument provides the user data pointer from the
994 `cupsSetPasswordCB2` call.